From bd6ba89e96955d80b8f269d0c0d97381690b9b7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 26 Jan 2024 17:21:01 +0000 Subject: [PATCH 001/394] removed ephemera usage from nym-api --- Cargo.lock | 1087 +---------------------- Cargo.toml | 2 +- nym-api/Cargo.toml | 18 +- nym-api/src/epoch_operations/helpers.rs | 2 +- nym-api/src/epoch_operations/mod.rs | 11 - nym-api/src/main.rs | 37 +- nym-api/src/node_describe_cache/mod.rs | 2 +- nym-api/src/support/config/mod.rs | 41 - nym-api/src/support/nyxd/mod.rs | 41 +- 9 files changed, 63 insertions(+), 1178 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c221eb6583..b6bcd3cd86 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,185 +8,6 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -[[package]] -name = "actix-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" -dependencies = [ - "bitflags 1.3.2", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite 0.2.13", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-http" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash 0.8.3", - "base64 0.21.4", - "bitflags 2.4.1", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite 0.2.13", - "rand 0.8.5", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn 2.0.38", -] - -[[package]] -name = "actix-router" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" -dependencies = [ - "bytestring", - "http", - "regex", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.4", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "actix-web" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash 0.8.3", - "bytes", - "bytestring", - "cfg-if", - "cookie 0.16.2", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite 0.2.13", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.5.4", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "addr" version = "0.15.6" @@ -342,7 +163,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.10", "once_cell", "version_check", ] @@ -356,21 +176,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.16" @@ -469,9 +274,6 @@ name = "anyhow" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" -dependencies = [ - "backtrace", -] [[package]] name = "arc-swap" @@ -491,12 +293,6 @@ dependencies = [ "password-hash", ] -[[package]] -name = "array-bytes" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" - [[package]] name = "arrayref" version = "0.3.7" @@ -582,12 +378,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - [[package]] name = "async-channel" version = "1.9.0" @@ -1022,27 +812,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" -[[package]] -name = "brotli" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bs58" version = "0.4.0" @@ -1101,15 +870,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bytestring" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" -dependencies = [ - "bytes", -] - [[package]] name = "camino" version = "1.1.6" @@ -1503,20 +1263,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "config" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" -dependencies = [ - "async-trait", - "lazy_static", - "nom", - "pathdiff", - "serde", - "toml 0.5.11", -] - [[package]] name = "console-api" version = "0.5.0" @@ -1601,23 +1347,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "cookie" version = "0.17.0" @@ -1957,12 +1686,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -2109,7 +1832,6 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", "fiat-crypto", "platforms", "rustc_version 0.4.0", @@ -2501,19 +2223,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - [[package]] name = "devise" version = "0.4.1" @@ -2754,20 +2463,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ed25519-dalek" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" -dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.3", - "rand_core 0.6.4", - "serde", - "sha2 0.10.8", - "zeroize", -] - [[package]] name = "ed25519-zebra" version = "3.1.0" @@ -2884,55 +2579,6 @@ dependencies = [ "url", ] -[[package]] -name = "ephemera" -version = "0.1.0" -dependencies = [ - "actix-web", - "anyhow", - "array-bytes", - "assert_matches", - "async-trait", - "asynchronous-codec", - "blake2 0.10.6", - "bs58 0.4.0", - "bytes", - "cfg-if", - "chrono", - "clap 4.4.7", - "config", - "digest 0.10.7", - "dirs 5.0.1", - "enum-as-inner", - "futures", - "futures-util", - "lazy_static", - "libp2p 0.51.3", - "libp2p-identity", - "log", - "lru 0.10.1", - "nym-config", - "nym-ephemera-common", - "nym-task", - "pretty_env_logger", - "rand 0.8.5", - "refinery", - "reqwest", - "rusqlite", - "serde", - "serde_derive", - "serde_json", - "thiserror", - "tokio", - "tokio-tungstenite", - "tokio-util", - "toml 0.7.8", - "unsigned-varint", - "utoipa", - "utoipa-swagger-ui", - "uuid 1.5.0", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -3055,18 +2701,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" version = "1.9.0" @@ -3613,15 +3247,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.6", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -3650,15 +3275,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "hashlink" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" -dependencies = [ - "hashbrown 0.11.2", -] - [[package]] name = "hashlink" version = "0.8.4" @@ -4409,12 +4025,6 @@ dependencies = [ "static_assertions", ] -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.4.0" @@ -4505,80 +4115,25 @@ dependencies = [ "futures-timer", "getrandom 0.2.10", "instant", - "libp2p-core 0.39.0", - "libp2p-dns 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-gossipsub 0.44.0", + "libp2p-core", + "libp2p-dns", + "libp2p-gossipsub", "libp2p-identify", - "libp2p-mdns 0.43.0", - "libp2p-metrics 0.12.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-mdns", + "libp2p-metrics", "libp2p-mplex", - "libp2p-noise 0.42.0", + "libp2p-noise", "libp2p-ping", - "libp2p-quic 0.7.0-alpha.2", - "libp2p-swarm 0.42.0", - "libp2p-tcp 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-webrtc 0.4.0-alpha.2", + "libp2p-quic", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-webrtc", "libp2p-websocket", - "libp2p-yamux 0.43.0", - "multiaddr 0.17.0", + "libp2p-yamux", + "multiaddr", "pin-project", ] -[[package]] -name = "libp2p" -version = "0.51.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" -dependencies = [ - "bytes", - "futures", - "futures-timer", - "getrandom 0.2.10", - "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core 0.39.2", - "libp2p-dns 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-gossipsub 0.44.4", - "libp2p-identity", - "libp2p-kad", - "libp2p-mdns 0.43.1", - "libp2p-metrics 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.42.2", - "libp2p-quic 0.7.0-alpha.3", - "libp2p-request-response", - "libp2p-swarm 0.42.2", - "libp2p-tcp 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-webrtc 0.4.0-alpha.4", - "libp2p-yamux 0.43.1", - "multiaddr 0.17.1", - "pin-project", -] - -[[package]] -name = "libp2p-allow-block-list" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "void", -] - -[[package]] -name = "libp2p-connection-limits" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "void", -] - [[package]] name = "libp2p-core" version = "0.39.0" @@ -4586,23 +4141,23 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "asn1_der", "bs58 0.4.0", - "ed25519-dalek 1.0.1", + "ed25519-dalek", "either", "fnv", "futures", "futures-timer", "instant", "log", - "multiaddr 0.17.0", + "multiaddr", "multihash", - "multistream-select 0.12.1 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "multistream-select", "once_cell", "parking_lot 0.12.1", "pin-project", "prost 0.11.9", "prost-build", "rand 0.8.5", - "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "rw-stream-sink", "sec1 0.3.0", "sha2 0.10.8", "smallvec", @@ -4612,56 +4167,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "libp2p-core" -version = "0.39.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1df63c0b582aa434fb09b2d86897fa2b419ffeccf934b36f87fcedc8e835c2" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-identity", - "log", - "multiaddr 0.17.1", - "multihash", - "multistream-select 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", - "parking_lot 0.12.1", - "pin-project", - "quick-protobuf", - "rand 0.8.5", - "rw-stream-sink 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde", - "smallvec", - "thiserror", - "unsigned-varint", - "void", -] - -[[package]] -name = "libp2p-dns" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" -dependencies = [ - "futures", - "libp2p-core 0.39.2", - "log", - "parking_lot 0.12.1", - "smallvec", - "trust-dns-resolver", -] - [[package]] name = "libp2p-dns" version = "0.39.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "parking_lot 0.12.1", "smallvec", @@ -4681,8 +4193,8 @@ dependencies = [ "futures", "hex_fmt", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "prometheus-client", "prost 0.11.9", @@ -4697,39 +4209,6 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "libp2p-gossipsub" -version = "0.44.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" -dependencies = [ - "asynchronous-codec", - "base64 0.21.4", - "byteorder", - "bytes", - "either", - "fnv", - "futures", - "hex_fmt", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "regex", - "serde", - "sha2 0.10.8", - "smallvec", - "thiserror", - "unsigned-varint", - "void", - "wasm-timer", -] - [[package]] name = "libp2p-identify" version = "0.42.0" @@ -4739,10 +4218,10 @@ dependencies = [ "either", "futures", "futures-timer", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", - "lru 0.9.0", + "lru", "prost 0.11.9", "prost-build", "prost-codec", @@ -4751,54 +4230,6 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-identity" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" -dependencies = [ - "bs58 0.4.0", - "ed25519-dalek 2.0.0", - "log", - "multiaddr 0.17.1", - "multihash", - "quick-protobuf", - "rand 0.8.5", - "serde", - "sha2 0.10.8", - "thiserror", - "zeroize", -] - -[[package]] -name = "libp2p-kad" -version = "0.43.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" -dependencies = [ - "arrayvec", - "asynchronous-codec", - "bytes", - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "quick-protobuf", - "rand 0.8.5", - "serde", - "sha2 0.10.8", - "smallvec", - "thiserror", - "uint", - "unsigned-varint", - "void", -] - [[package]] name = "libp2p-mdns" version = "0.43.0" @@ -4807,8 +4238,8 @@ dependencies = [ "data-encoding", "futures", "if-watch", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "rand 0.8.5", "smallvec", @@ -4818,50 +4249,16 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-mdns" -version = "0.43.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19983e1f949f979a928f2c603de1cf180cc0dc23e4ac93a62651ccb18341460b" -dependencies = [ - "data-encoding", - "futures", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "rand 0.8.5", - "smallvec", - "socket2 0.4.9", - "tokio", - "trust-dns-proto", - "void", -] - -[[package]] -name = "libp2p-metrics" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-gossipsub 0.44.4", - "libp2p-kad", - "libp2p-swarm 0.42.2", - "prometheus-client", -] - [[package]] name = "libp2p-metrics" version = "0.12.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ - "libp2p-core 0.39.0", - "libp2p-gossipsub 0.44.0", + "libp2p-core", + "libp2p-gossipsub", "libp2p-identify", "libp2p-ping", - "libp2p-swarm 0.42.0", + "libp2p-swarm", "prometheus-client", ] @@ -4873,7 +4270,7 @@ dependencies = [ "asynchronous-codec", "bytes", "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "nohash-hasher", "parking_lot 0.12.1", @@ -4890,7 +4287,7 @@ dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "once_cell", "prost 0.11.9", @@ -4904,29 +4301,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "libp2p-noise" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" -dependencies = [ - "bytes", - "curve25519-dalek 3.2.0", - "futures", - "libp2p-core 0.39.2", - "libp2p-identity", - "log", - "once_cell", - "quick-protobuf", - "rand 0.8.5", - "sha2 0.10.8", - "snow", - "static_assertions", - "thiserror", - "x25519-dalek 1.1.1", - "zeroize", -] - [[package]] name = "libp2p-ping" version = "0.42.0" @@ -4936,8 +4310,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "rand 0.8.5", "void", @@ -4952,8 +4326,8 @@ dependencies = [ "futures", "futures-timer", "if-watch", - "libp2p-core 0.39.0", - "libp2p-tls 0.1.0-alpha.2", + "libp2p-core", + "libp2p-tls", "log", "parking_lot 0.12.1", "quinn-proto", @@ -4963,44 +4337,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "libp2p-quic" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b26abd81cd2398382a1edfe739b539775be8a90fa6914f39b2ab49571ec735" -dependencies = [ - "bytes", - "futures", - "futures-timer", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-tls 0.1.0", - "log", - "parking_lot 0.12.1", - "quinn-proto", - "rand 0.8.5", - "rustls 0.20.9", - "thiserror", - "tokio", -] - -[[package]] -name = "libp2p-request-response" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffdb374267d42dc5ed5bc53f6e601d4a64ac5964779c6e40bb9e4f14c1e30d5" -dependencies = [ - "async-trait", - "futures", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "rand 0.8.5", - "smallvec", -] - [[package]] name = "libp2p-swarm" version = "0.42.0" @@ -5011,8 +4347,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm-derive 0.32.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-core", + "libp2p-swarm-derive", "log", "rand 0.8.5", "smallvec", @@ -5020,38 +4356,6 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-swarm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903b3d592d7694e56204d211f29d31bc004be99386644ba8731fc3e3ef27b296" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm-derive 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log", - "rand 0.8.5", - "smallvec", - "tokio", - "void", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" -dependencies = [ - "heck 0.4.1", - "quote", - "syn 1.0.109", -] - [[package]] name = "libp2p-swarm-derive" version = "0.32.0" @@ -5062,22 +4366,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "libp2p-tcp" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d33698596d7722d85d3ab0c86c2c322254fce1241e91208e3679b4eb3026cf" -dependencies = [ - "futures", - "futures-timer", - "if-watch", - "libc", - "libp2p-core 0.39.2", - "log", - "socket2 0.4.9", - "tokio", -] - [[package]] name = "libp2p-tcp" version = "0.39.0" @@ -5087,7 +4375,7 @@ dependencies = [ "futures-timer", "if-watch", "libc", - "libp2p-core 0.39.0", + "libp2p-core", "log", "socket2 0.4.9", "tokio", @@ -5100,26 +4388,7 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "futures", "futures-rustls", - "libp2p-core 0.39.0", - "rcgen 0.10.0", - "ring 0.16.20", - "rustls 0.20.9", - "thiserror", - "webpki 0.22.4", - "x509-parser 0.14.0", - "yasna", -] - -[[package]] -name = "libp2p-tls" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" -dependencies = [ - "futures", - "futures-rustls", - "libp2p-core 0.39.2", - "libp2p-identity", + "libp2p-core", "rcgen 0.10.0", "ring 0.16.20", "rustls 0.20.9", @@ -5141,8 +4410,8 @@ dependencies = [ "futures-timer", "hex", "if-watch", - "libp2p-core 0.39.0", - "libp2p-noise 0.42.0", + "libp2p-core", + "libp2p-noise", "log", "multihash", "prost 0.11.9", @@ -5159,37 +4428,6 @@ dependencies = [ "webrtc", ] -[[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-noise 0.42.2", - "log", - "multihash", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -5198,11 +4436,11 @@ dependencies = [ "either", "futures", "futures-rustls", - "libp2p-core 0.39.0", + "libp2p-core", "log", "parking_lot 0.12.1", "quicksink", - "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "rw-stream-sink", "soketto", "url", "webpki-roots 0.22.6", @@ -5214,20 +4452,7 @@ version = "0.43.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core 0.39.0", - "log", - "thiserror", - "yamux", -] - -[[package]] -name = "libp2p-yamux" -version = "0.43.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" -dependencies = [ - "futures", - "libp2p-core 0.39.2", + "libp2p-core", "log", "thiserror", "yamux", @@ -5300,23 +4525,6 @@ dependencies = [ "keystream", ] -[[package]] -name = "local-channel" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" - [[package]] name = "lock_api" version = "0.4.11" @@ -5357,15 +4565,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "lru" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" -dependencies = [ - "hashbrown 0.13.2", -] - [[package]] name = "lru-cache" version = "0.1.2" @@ -5569,25 +4768,6 @@ dependencies = [ "url", ] -[[package]] -name = "multiaddr" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "log", - "multibase", - "multihash", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint", - "url", -] - [[package]] name = "multibase" version = "0.9.1" @@ -5608,8 +4788,6 @@ dependencies = [ "core2", "digest 0.10.7", "multihash-derive", - "serde", - "serde-big-array", "sha2 0.10.8", "unsigned-varint", ] @@ -5634,20 +4812,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "multistream-select" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" -dependencies = [ - "bytes", - "futures", - "log", - "pin-project", - "smallvec", - "unsigned-varint", -] - [[package]] name = "multistream-select" version = "0.12.1" @@ -5953,14 +5117,11 @@ dependencies = [ name = "nym-api" version = "1.1.34" dependencies = [ - "actix-web", "anyhow", - "array-bytes", "async-trait", "bip39", "bs58 0.4.0", "cfg-if", - "chrono", "clap 4.4.7", "console-subscriber", "cosmwasm-std", @@ -5969,9 +5130,7 @@ dependencies = [ "cw3", "cw4", "dirs 4.0.0", - "ephemera", "futures", - "futures-util", "getset", "humantime-serde", "itertools 0.12.0", @@ -5990,7 +5149,6 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-dkg", - "nym-ephemera-common", "nym-gateway-client", "nym-inclusion-probability", "nym-mixnet-contract-common", @@ -6015,18 +5173,15 @@ dependencies = [ "rocket_okapi", "schemars", "serde", - "serde_derive", "serde_json", "sqlx", "tap", - "tempfile", "thiserror", "time", "tokio", "tokio-stream", "ts-rs", "url", - "uuid 1.5.0", "zeroize", ] @@ -6430,7 +5585,7 @@ dependencies = [ "cipher 0.4.4", "ctr 0.9.2", "digest 0.10.7", - "ed25519-dalek 1.0.1", + "ed25519-dalek", "generic-array 0.14.7", "hkdf 0.12.3", "hmac 0.12.1", @@ -7085,7 +6240,7 @@ dependencies = [ "hex", "http", "httpcodec", - "libp2p 0.51.0", + "libp2p", "log", "nym-bandwidth-controller", "nym-bin-common", @@ -8623,28 +7778,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quick-protobuf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" -dependencies = [ - "byteorder", -] - -[[package]] -name = "quick-protobuf-codec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1693116345026436eb2f10b677806169c1a1260c1c60eaaffe3fb5a29ae23d8b" -dependencies = [ - "asynchronous-codec", - "bytes", - "quick-protobuf", - "thiserror", - "unsigned-varint", -] - [[package]] name = "quicksink" version = "0.1.2" @@ -9006,50 +8139,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "refinery" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529664dbccc0a296947615c997a857912d72d1c44be1fafb7bae54ecfa7a8c24" -dependencies = [ - "refinery-core", - "refinery-macros", -] - -[[package]] -name = "refinery-core" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e895cb870cf06e92318cbbeb701f274d022d5ca87a16fa8244e291cd035ef954" -dependencies = [ - "async-trait", - "cfg-if", - "lazy_static", - "log", - "regex", - "rusqlite", - "serde", - "siphasher", - "thiserror", - "time", - "toml 0.7.8", - "url", - "walkdir", -] - -[[package]] -name = "refinery-macros" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123e8b80f8010c3ae38330c81e76938fc7adf6cdbfbaad20295bb8c22718b4f1" -dependencies = [ - "proc-macro2", - "quote", - "refinery-core", - "regex", - "syn 2.0.38", -] - [[package]] name = "regex" version = "1.10.2" @@ -9285,7 +8374,7 @@ version = "0.5.0-rc.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "936012c99162a03a67f37f9836d5f938f662e26f2717809761a9ac46432090f4" dependencies = [ - "cookie 0.17.0", + "cookie", "either", "futures", "http", @@ -9375,21 +8464,6 @@ dependencies = [ "webrtc-util", ] -[[package]] -name = "rusqlite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink 0.7.0", - "libsqlite3-sys", - "memchr", - "smallvec", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -9565,17 +8639,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" -[[package]] -name = "rw-stream-sink" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" -dependencies = [ - "futures", - "pin-project", - "static_assertions", -] - [[package]] name = "rw-stream-sink" version = "0.3.0" @@ -9823,15 +8886,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-big-array" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" -dependencies = [ - "serde", -] - [[package]] name = "serde-json-wasm" version = "0.5.0" @@ -10111,12 +9165,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "siphasher" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe" - [[package]] name = "slab" version = "0.4.9" @@ -10344,7 +9392,7 @@ dependencies = [ "futures-executor", "futures-intrusive", "futures-util", - "hashlink 0.8.4", + "hashlink", "hex", "indexmap 1.9.3", "itoa", @@ -11547,18 +10595,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uncased" version = "0.9.9" @@ -11776,7 +10812,6 @@ version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653" dependencies = [ - "actix-web", "axum", "mime_guess", "regex", @@ -11800,7 +10835,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "getrandom 0.2.10", - "serde", "wasm-bindgen", ] @@ -12726,32 +11760,3 @@ dependencies = [ "crossbeam-utils", "flate2", ] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] diff --git a/Cargo.toml b/Cargo.toml index bedb046d5b..a70bcda08c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,7 +33,7 @@ members = [ "common/cosmwasm-smart-contracts/coconut-bandwidth-contract", "common/cosmwasm-smart-contracts/coconut-dkg", "common/cosmwasm-smart-contracts/contracts-common", - "common/cosmwasm-smart-contracts/ephemera", +# "common/cosmwasm-smart-contracts/ephemera", "common/cosmwasm-smart-contracts/group-contract", "common/cosmwasm-smart-contracts/mixnet-contract", "common/cosmwasm-smart-contracts/multisig-contract", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 3b19c6215b..7e9ac252ea 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -66,21 +66,21 @@ schemars = { workspace = true, features = ["preserve_order"] } zeroize = { workspace = true } ## ephemera-specific -actix-web = "4" -array-bytes = "6.0.0" -chrono = { version = "0.4.24", default-features = false, features = ["clock"] } -futures-util = "0.3.25" -serde_derive = "1.0.149" -tempfile = "3.3.0" -uuid = { version = "1.3.0", features = ["serde", "v4"] } +#actix-web = "4" +#array-bytes = "6.0.0" +#chrono = { version = "0.4.24", default-features = false, features = ["clock"] } +#futures-util = "0.3.25" +#serde_derive = "1.0.149" +#tempfile = "3.3.0" +#uuid = { version = "1.3.0", features = ["serde", "v4"] } ## internal -ephemera = { path = "../ephemera" } +#ephemera = { path = "../ephemera" } nym-bandwidth-controller = { path = "../common/bandwidth-controller" } nym-coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" } nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" } nym-coconut-interface = { path = "../common/coconut-interface" } -nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } +#nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } nym-config = { path = "../common/config" } cosmwasm-std = { workspace = true } nym-credential-storage = { path = "../common/credential-storage" } diff --git a/nym-api/src/epoch_operations/helpers.rs b/nym-api/src/epoch_operations/helpers.rs index 4724f14361..61ea0defeb 100644 --- a/nym-api/src/epoch_operations/helpers.rs +++ b/nym-api/src/epoch_operations/helpers.rs @@ -5,7 +5,7 @@ use crate::epoch_operations::RewardedSetUpdater; use cosmwasm_std::{Decimal, Fraction}; use nym_mixnet_contract_common::reward_params::Performance; use nym_mixnet_contract_common::{ExecuteMsg, Interval, MixId}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Serialize, Deserialize)] pub(crate) struct MixnodeWithPerformance { diff --git a/nym-api/src/epoch_operations/mod.rs b/nym-api/src/epoch_operations/mod.rs index 7f5afbfc9e..7bb3116086 100644 --- a/nym-api/src/epoch_operations/mod.rs +++ b/nym-api/src/epoch_operations/mod.rs @@ -12,7 +12,6 @@ // 3. Eventually this whole procedure is going to get expanded to allow for distribution of rewarded set generation // and hence this might be a good place for it. -use crate::ephemera::reward::{EpochOperations, RewardManager}; use crate::node_status_api::ONE_DAY; use crate::nym_contract_cache::cache::NymContractCache; use crate::support::nyxd::Client; @@ -33,7 +32,6 @@ mod rewarding; mod transition_beginning; pub struct RewardedSetUpdater { - ephemera_reward_manager: Option, nyxd_client: Client, nym_contract_cache: NymContractCache, storage: NymApiStorage, @@ -47,13 +45,11 @@ impl RewardedSetUpdater { } pub(crate) fn new( - ephemera_reward_manager: Option, nyxd_client: Client, nym_contract_cache: NymContractCache, storage: NymApiStorage, ) -> Self { RewardedSetUpdater { - ephemera_reward_manager, nyxd_client, nym_contract_cache, storage, @@ -92,11 +88,6 @@ impl RewardedSetUpdater { /// 8. the whole process repeats once the new epoch finishes async fn perform_epoch_operations(&mut self, interval: Interval) -> Result<(), RewardingError> { let mut rewards = self.nodes_to_reward(interval).await; - if let Some(ephemera_reward_manager) = self.ephemera_reward_manager.as_mut() { - rewards = ephemera_reward_manager - .perform_epoch_operations(rewards) - .await?; - } rewards.sort_by_key(|a| a.mix_id); log::info!("The current epoch has finished."); @@ -274,14 +265,12 @@ impl RewardedSetUpdater { } pub(crate) fn start( - ephemera_reward_manager: Option, nyxd_client: Client, nym_contract_cache: &NymContractCache, storage: &NymApiStorage, shutdown: &TaskManager, ) { let mut rewarded_set_updater = RewardedSetUpdater::new( - ephemera_reward_manager, nyxd_client, nym_contract_cache.to_owned(), storage.to_owned(), diff --git a/nym-api/src/main.rs b/nym-api/src/main.rs index e28d0ad37e..3e55335ead 100644 --- a/nym-api/src/main.rs +++ b/nym-api/src/main.rs @@ -13,7 +13,6 @@ use crate::support::cli; use crate::support::config::Config; use crate::support::storage; use crate::support::storage::NymApiStorage; -use ::ephemera::configuration::Configuration as EphemeraConfiguration; use ::nym_config::defaults::setup_env; use anyhow::Result; use circulating_supply_api::cache::CirculatingSupplyCache; @@ -30,7 +29,6 @@ use support::{http, nyxd}; mod circulating_supply_api; mod coconut; -mod ephemera; mod epoch_operations; pub(crate) mod network; mod network_monitor; @@ -146,33 +144,6 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result // and then only start the uptime updater (and the monitor itself, duh) // if the monitoring if it's enabled if config.network_monitor.enabled { - let ephemera_config = - match EphemeraConfiguration::try_load(config.get_ephemera_config_path()) { - Ok(c) => c, - Err(_) => { - config - .get_ephemera_args() - .cmd - .clone() - .execute(Some(&config.get_id())); - EphemeraConfiguration::try_load(config.get_ephemera_config_path()) - .expect("Config file should be created now") - } - }; - let ephemera_reward_manager = if config.ephemera.enabled { - Some( - ephemera::application::NymApi::run( - config.get_ephemera_args().clone(), - ephemera_config, - nyxd_client.clone(), - &shutdown, - ) - .await?, - ) - } else { - None - }; - // if network monitor is enabled, the storage MUST BE available let storage = maybe_storage.unwrap(); @@ -190,13 +161,7 @@ async fn start_nym_api_tasks(config: Config) -> anyhow::Result // start 'rewarding' if its enabled if config.rewarding.enabled { epoch_operations::ensure_rewarding_permission(&nyxd_client).await?; - RewardedSetUpdater::start( - ephemera_reward_manager, - nyxd_client, - nym_contract_cache_state, - storage, - &shutdown, - ); + RewardedSetUpdater::start(nyxd_client, nym_contract_cache_state, storage, &shutdown); } } diff --git a/nym-api/src/node_describe_cache/mod.rs b/nym-api/src/node_describe_cache/mod.rs index 21b621f428..ded2fa7454 100644 --- a/nym-api/src/node_describe_cache/mod.rs +++ b/nym-api/src/node_describe_cache/mod.rs @@ -6,7 +6,7 @@ use crate::support::caching::cache::{SharedCache, UninitialisedCache}; use crate::support::caching::refresher::{CacheItemProvider, CacheRefresher}; use crate::support::config; use crate::support::config::DEFAULT_NODE_DESCRIBE_BATCH_SIZE; -use futures_util::{stream, StreamExt}; +use futures::{stream, StreamExt}; use nym_api_requests::models::{ IpPacketRouterDetails, NetworkRequesterDetails, NymNodeDescription, }; diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index 8d71b43fd6..ca2eb1328c 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -106,8 +106,6 @@ pub struct Config { pub rewarding: Rewarding, pub coconut_signer: CoconutSigner, - - pub ephemera: Ephemera, } impl NymConfigTemplate for Config { @@ -127,7 +125,6 @@ impl Config { circulating_supply_cacher: Default::default(), rewarding: Default::default(), coconut_signer: CoconutSigner::new_default(id.as_ref()), - ephemera: Ephemera::new_default(id.as_ref()), } } @@ -142,10 +139,6 @@ impl Config { bail!("can't enable coconut signer without providing a mnemonic") } - if !can_sign && self.ephemera.enabled { - bail!("can't enable ephemera without providing a mnemonic") - } - Ok(()) } @@ -223,10 +216,6 @@ impl Config { } } - pub fn get_id(&self) -> String { - self.base.id.clone() - } - pub fn get_nyxd_url(&self) -> Url { self.base.local_validator.clone() } @@ -234,14 +223,6 @@ impl Config { pub fn get_mnemonic(&self) -> Option<&bip39::Mnemonic> { self.base.mnemonic.as_ref() } - - pub fn get_ephemera_args(&self) -> &crate::ephemera::Args { - &self.ephemera.args - } - - pub fn get_ephemera_config_path(&self) -> PathBuf { - self.ephemera.args.ephemera_config.clone() - } } // we only really care about the mnemonic being zeroized @@ -558,25 +539,3 @@ impl Default for CoconutSignerDebug { } } } - -#[derive(Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -#[serde(default)] -pub struct Ephemera { - pub enabled: bool, - args: crate::ephemera::Args, -} - -impl Ephemera { - fn new_default(id: &str) -> Self { - Ephemera { - enabled: false, - args: crate::ephemera::Args { - ephemera_config: ephemera::configuration::Configuration::ephemera_config_file_home( - Some(id), - ) - .unwrap(), - ..Default::default() - }, - } - } -} diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 452f93569f..21e0689552 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -18,8 +18,6 @@ use nym_coconut_dkg_common::{ }; use nym_config::defaults::{ChainDetails, NymNetworkDetails}; use nym_contracts_common::dealings::ContractSafeBytes; -use nym_ephemera_common::msg::QueryMsg as EphemeraQueryMsg; -use nym_ephemera_common::types::JsonPeerInfo; use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::reward_params::RewardingParams; @@ -33,11 +31,10 @@ use nym_validator_client::nyxd::contract_traits::{NameServiceQueryClient, PagedD use nym_validator_client::nyxd::error::NyxdError; use nym_validator_client::nyxd::{ contract_traits::{ - CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, EphemeraQueryClient, - EphemeraSigningClient, GroupQueryClient, MixnetQueryClient, MixnetSigningClient, - MultisigQueryClient, MultisigSigningClient, NymContractsProvider, PagedEphemeraQueryClient, - PagedMixnetQueryClient, PagedMultisigQueryClient, PagedVestingQueryClient, - SpDirectoryQueryClient, + CoconutBandwidthQueryClient, DkgQueryClient, DkgSigningClient, GroupQueryClient, + MixnetQueryClient, MixnetSigningClient, MultisigQueryClient, MultisigSigningClient, + NymContractsProvider, PagedMixnetQueryClient, PagedMultisigQueryClient, + PagedVestingQueryClient, SpDirectoryQueryClient, }, cosmwasm_client::types::ExecuteResult, CosmWasmClient, Fee, @@ -477,23 +474,6 @@ impl crate::coconut::client::Client for Client { } } -#[async_trait] -impl crate::ephemera::client::Client for Client { - async fn get_ephemera_peers(&self) -> crate::ephemera::error::Result> { - Ok(nyxd_query!(self, get_all_ephemera_peers().await?)) - } - - async fn register_ephemera_peer( - &self, - peer_info: JsonPeerInfo, - ) -> crate::ephemera::error::Result { - Ok(nyxd_signing!( - self, - register_as_peer(peer_info, None).await? - )) - } -} - #[async_trait] impl DkgQueryClient for Client { async fn query_dkg_contract(&self, query: DkgQueryMsg) -> std::result::Result @@ -504,19 +484,6 @@ impl DkgQueryClient for Client { } } -#[async_trait] -impl EphemeraQueryClient for Client { - async fn query_ephemera_contract( - &self, - query: EphemeraQueryMsg, - ) -> std::result::Result - where - for<'a> T: Deserialize<'a>, - { - nyxd_query!(self, query_ephemera_contract(query).await) - } -} - #[async_trait] impl SpDirectoryQueryClient for Client { async fn query_service_provider_contract( From 339c6c6d247ab6714e2eab485d4ce5da71b163a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 26 Jan 2024 17:21:24 +0000 Subject: [PATCH 002/394] finally using the correct feature in nym-node for utoipa --- nym-node/Cargo.toml | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 77a7125c9c..745be5d884 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -37,12 +37,7 @@ mime = "0.3.17" hyper = { workspace = true } tower = { version = "0.4.13" } tower-http = { version = "0.4.4", features = ["fs"] } - -# `actix_extras`? what the hell? -# hear me out first! -# we can't use `axum_extras` because of freaking ephemera that depends on `actix_extras`. -# however, it seems that pulling in `actix_extras` pulls in just enough shared features to improve `IntoParams` for our Query attributes -utoipa = { workspace = true, features = ["actix_extras"] } # can't use `"axum_extras"` feature because ephemera uses `"actix_extras"` -.-' +utoipa = { workspace = true, features = ["axum_extras"] } utoipa-swagger-ui = { workspace = true, features = ["axum"] } # if we ever wanted redoc/rapidoc bridges: From 148db2f350cc3392dcb6095220ddc2395e6d16ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 14:38:02 +0000 Subject: [PATCH 003/394] replaced uses of 'serde_derive' with 'serde' --- nym-api/src/coconut/dkg/state/dealing_exchange.rs | 2 +- nym-api/src/coconut/dkg/state/in_progress.rs | 2 +- nym-api/src/coconut/dkg/state/key_derivation.rs | 2 +- nym-api/src/coconut/dkg/state/key_finalization.rs | 2 +- nym-api/src/coconut/dkg/state/key_validation.rs | 2 +- nym-api/src/coconut/dkg/state/registration.rs | 2 +- nym-api/src/ephemera/mod.rs | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/nym-api/src/coconut/dkg/state/dealing_exchange.rs b/nym-api/src/coconut/dkg/state/dealing_exchange.rs index 9721de86fd..02a0ff1dd2 100644 --- a/nym-api/src/coconut/dkg/state/dealing_exchange.rs +++ b/nym-api/src/coconut/dkg/state/dealing_exchange.rs @@ -5,7 +5,7 @@ use super::serde_helpers::generated_dealings; use crate::coconut::dkg::state::DkgParticipant; use nym_coconut_dkg_common::types::DealingIndex; use nym_dkg::{Dealing, NodeIndex}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; #[derive(Debug, Clone, Default, Serialize, Deserialize)] diff --git a/nym-api/src/coconut/dkg/state/in_progress.rs b/nym-api/src/coconut/dkg/state/in_progress.rs index 7cca1d1c2c..ab6bc15353 100644 --- a/nym-api/src/coconut/dkg/state/in_progress.rs +++ b/nym-api/src/coconut/dkg/state/in_progress.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] diff --git a/nym-api/src/coconut/dkg/state/key_derivation.rs b/nym-api/src/coconut/dkg/state/key_derivation.rs index 43eb72f61c..51f43174ee 100644 --- a/nym-api/src/coconut/dkg/state/key_derivation.rs +++ b/nym-api/src/coconut/dkg/state/key_derivation.rs @@ -5,7 +5,7 @@ use super::serde_helpers::recovered_keys; use cosmwasm_std::Addr; use nym_coconut_dkg_common::types::{DealingIndex, EpochId}; use nym_dkg::{G2Projective, NodeIndex, RecoveredVerificationKeys, Threshold}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::collections::{BTreeMap, HashMap}; use thiserror::Error; diff --git a/nym-api/src/coconut/dkg/state/key_finalization.rs b/nym-api/src/coconut/dkg/state/key_finalization.rs index 625bcf706b..ec7b74d7a3 100644 --- a/nym-api/src/coconut/dkg/state/key_finalization.rs +++ b/nym-api/src/coconut/dkg/state/key_finalization.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Copy, Default, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] diff --git a/nym-api/src/coconut/dkg/state/key_validation.rs b/nym-api/src/coconut/dkg/state/key_validation.rs index 473a39556e..828e40a480 100644 --- a/nym-api/src/coconut/dkg/state/key_validation.rs +++ b/nym-api/src/coconut/dkg/state/key_validation.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; type ProposalId = u64; diff --git a/nym-api/src/coconut/dkg/state/registration.rs b/nym-api/src/coconut/dkg/state/registration.rs index dbcde9cbbd..8391cebeed 100644 --- a/nym-api/src/coconut/dkg/state/registration.rs +++ b/nym-api/src/coconut/dkg/state/registration.rs @@ -7,7 +7,7 @@ use nym_coconut_dkg_common::dealer::DealerDetails; use nym_coconut_dkg_common::types::EncodedBTEPublicKeyWithProof; use nym_dkg::bte::PublicKeyWithProof; use nym_dkg::{bte, NodeIndex}; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use thiserror::Error; #[derive(Clone, Deserialize, Debug, Serialize)] diff --git a/nym-api/src/ephemera/mod.rs b/nym-api/src/ephemera/mod.rs index f9134e7e46..6ad6f98cb9 100644 --- a/nym-api/src/ephemera/mod.rs +++ b/nym-api/src/ephemera/mod.rs @@ -5,7 +5,7 @@ extern crate core; use clap::Parser; use ephemera::cli::init::Cmd; -use serde_derive::{Deserialize, Serialize}; +use serde::{Deserialize, Serialize}; use std::path::PathBuf; pub(crate) mod application; From a8e520d13bdbf9c9f56f010d5c204ae8840b29a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 14:38:43 +0000 Subject: [PATCH 004/394] removed unused import --- nym-api/src/support/nyxd/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index d14b395a77..d583669fe9 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -23,7 +23,7 @@ use nym_coconut_dkg_common::{ verification_key::{ContractVKShare, VerificationKeyShare}, }; use nym_config::defaults::{ChainDetails, NymNetworkDetails}; -use nym_contracts_common::dealings::ContractSafeBytes; + use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::reward_params::RewardingParams; From ccb4d7fd5e9cae80c78672cb05f2cabcd97c060b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 14:40:24 +0000 Subject: [PATCH 005/394] comment regarding removal of ephemera --- nym-api/src/ephemera/mod.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/nym-api/src/ephemera/mod.rs b/nym-api/src/ephemera/mod.rs index 6ad6f98cb9..e6075e79d5 100644 --- a/nym-api/src/ephemera/mod.rs +++ b/nym-api/src/ephemera/mod.rs @@ -1,6 +1,9 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +// while those files are completely unused now, I'm going to leave them here for future reference once we decide to revive the project to have a starting point +// but whoever picks it up: you are forbidden from trying to use actix + extern crate core; use clap::Parser; From 3ecd2af216a71b9c55b1b75730fe5a3126ed1f0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 17:14:25 +0000 Subject: [PATCH 006/394] fixed test imports --- Cargo.lock | 1 + nym-api/Cargo.toml | 2 +- nym-connect/desktop/Cargo.lock | 15 +++++++++++++++ nym-wallet/Cargo.lock | 8 ++++++++ 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Cargo.lock b/Cargo.lock index 4ea6cda51d..3c1f017dc3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5241,6 +5241,7 @@ dependencies = [ "sha2 0.9.9", "sqlx", "tap", + "tempfile", "thiserror", "time", "tokio", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 20f5cf0e76..579a98d991 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -71,7 +71,6 @@ zeroize = { workspace = true } #chrono = { version = "0.4.24", default-features = false, features = ["clock"] } #futures-util = "0.3.25" #serde_derive = "1.0.149" -#tempfile = "3.3.0" #uuid = { version = "1.3.0", features = ["serde", "v4"] } ## internal @@ -123,6 +122,7 @@ sqlx = { workspace = true, features = [ ] } [dev-dependencies] +tempfile = "3.3.0" cw3 = { workspace = true } cw-utils = { workspace = true } rand_chacha = "0.3" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index d1249c0e25..e3e8cf14c3 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -958,6 +958,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +[[package]] +name = "const-str" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" + [[package]] name = "constant_time_eq" version = "0.3.0" @@ -3722,6 +3728,7 @@ dependencies = [ "clap", "clap_complete", "clap_complete_fig", + "const-str", "log", "pretty_env_logger", "schemars", @@ -3762,6 +3769,7 @@ dependencies = [ "serde", "serde_json", "sha2 0.10.8", + "si-scale", "sqlx", "tap", "thiserror", @@ -4138,6 +4146,7 @@ dependencies = [ "cfg-if", "dotenvy", "hex-literal", + "log", "once_cell", "schemars", "serde", @@ -6221,6 +6230,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "si-scale" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44beb68bf488343b13ddbd74d1d5d5e6559a58b6dfaee74eb8d5ed4f7ed7666f" + [[package]] name = "signal-hook" version = "0.3.17" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 2209e5d647..93c8462986 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -750,6 +750,12 @@ version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" +[[package]] +name = "const-str" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aca749d3d3f5b87a0d6100509879f9cf486ab510803a4a4e1001da1ff61c2bd6" + [[package]] name = "convert_case" version = "0.4.0" @@ -3109,6 +3115,7 @@ dependencies = [ "clap", "clap_complete", "clap_complete_fig", + "const-str", "log", "pretty_env_logger", "schemars", @@ -3317,6 +3324,7 @@ dependencies = [ "cfg-if", "dotenvy", "hex-literal", + "log", "once_cell", "schemars", "serde", From c2aba223b886a49975300a33251fff4949e8ef3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Wed, 10 Jan 2024 15:36:46 +0100 Subject: [PATCH 007/394] Add openssl to cargo deny ban --- deny.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/deny.toml b/deny.toml index 94bd758e59..812b1e6e1d 100644 --- a/deny.toml +++ b/deny.toml @@ -217,6 +217,7 @@ deny = [ # Wrapper crates can optionally be specified to allow the crate when it # is a direct dependency of the otherwise banned crate #{ name = "ansi_term", version = "=0.11.0", wrappers = [] }, + { name = "openssl"}, ] # List of features to allow/deny From 279fea9a0bf3004828b0e5d091d067d8ab14c5e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 18 Jan 2024 10:19:18 +0100 Subject: [PATCH 008/394] Switch reqwest to rustls --- Cargo.lock | 17 +---------------- Cargo.toml | 2 +- ephemera/Cargo.toml | 2 +- 3 files changed, 3 insertions(+), 18 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 86956f7f10..d51ef2feb6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3597,19 +3597,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "hyper-tls" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" -dependencies = [ - "bytes", - "hyper", - "native-tls", - "tokio", - "tokio-native-tls", -] - [[package]] name = "iana-time-zone" version = "0.1.58" @@ -8281,12 +8268,10 @@ dependencies = [ "http-body", "hyper", "hyper-rustls", - "hyper-tls", "ipnet", "js-sys", "log", "mime", - "native-tls", "once_cell", "percent-encoding", "pin-project-lite 0.2.13", @@ -8298,7 +8283,6 @@ dependencies = [ "serde_urlencoded", "system-configuration", "tokio", - "tokio-native-tls", "tokio-rustls 0.24.1", "tokio-socks", "tokio-util", @@ -8308,6 +8292,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots 0.25.2", "winreg", ] diff --git a/Cargo.toml b/Cargo.toml index a70bcda08c..efc9217527 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -158,7 +158,7 @@ log = "0.4" once_cell = "1.7.2" parking_lot = "0.12.1" rand = "0.8.5" -reqwest = "0.11.22" +reqwest = { version = "0.11.22", default_features = false, features = ["rustls-tls"] } schemars = "0.8.1" serde = "1.0.152" serde_json = "1.0.91" diff --git a/ephemera/Cargo.toml b/ephemera/Cargo.toml index 6221421aab..f8e963f5b7 100644 --- a/ephemera/Cargo.toml +++ b/ephemera/Cargo.toml @@ -37,7 +37,7 @@ nym-config = { path = "../common/config" } nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } pretty_env_logger = "0.4" refinery = { version = "0.8.7", features = ["rusqlite"], optional = true } -reqwest = { version = "0.11.22", features = ["json"] } +reqwest = { version = "0.11.22", default_features = false, features = ["rustls-tls", "json"] } # Rocksdb kills compilation times and we're not currently using it. The reason # we comment it out is that rust-analyzer runs with --all-features #rocksdb = { version = "0.21.0", optional = true } From e99b04f1c663416c63854deb9cc68c49ef1aa60e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 18 Jan 2024 10:19:42 +0100 Subject: [PATCH 009/394] Remove explicit openssl dependency --- Cargo.lock | 12 ------------ common/client-libs/validator-client/Cargo.toml | 3 +-- sdk/lib/socks5-listener/Cargo.toml | 1 - 3 files changed, 1 insertion(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d51ef2feb6..c77ac80692 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6450,7 +6450,6 @@ dependencies = [ "nym-credential-storage", "nym-crypto", "nym-socks5-client-core", - "openssl", "rand 0.7.3", "safer-ffi", "serde", @@ -6782,7 +6781,6 @@ dependencies = [ "nym-network-defaults", "nym-service-provider-directory-common", "nym-vesting-contract-common", - "openssl", "prost 0.12.1", "reqwest", "serde", @@ -7044,15 +7042,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "300.1.5+3.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.98" @@ -7061,7 +7050,6 @@ checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 5e778b4cb2..5325428da2 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -31,7 +31,6 @@ log = { workspace = true } url = { workspace = true, features = ["serde"] } tokio = { workspace = true, features = ["sync", "time"] } futures = { workspace = true } -openssl = { version = "^0.10.55", features = ["vendored"], optional = true } nym-coconut-interface = { path = "../../coconut-interface" } nym-network-defaults = { path = "../../network-defaults" } @@ -90,7 +89,7 @@ required-features = ["http-client"] [features] default = ["http-client"] -http-client = ["cosmrs/rpc", "openssl"] +http-client = ["cosmrs/rpc"] generate-ts = [] contract-testing = ["nym-mixnet-contract-common/contract-testing"] diff --git a/sdk/lib/socks5-listener/Cargo.toml b/sdk/lib/socks5-listener/Cargo.toml index a3355fe3c6..425154a5cb 100644 --- a/sdk/lib/socks5-listener/Cargo.toml +++ b/sdk/lib/socks5-listener/Cargo.toml @@ -23,7 +23,6 @@ nym-config-common = { path = "../../../common/config", package = "nym-config" } nym-credential-storage = { path = "../../../common/credential-storage" } nym-crypto = { path = "../../../common/crypto" } nym-socks5-client-core = { path = "../../../common/socks5-client-core", default-features = false } -openssl = { version = "^0.10.55", features = ["vendored"] } serde = { workspace = true } tokio = { workspace = true, features = ["sync", "time"] } log = "0.4.17" From 30754a7a4a19430227cb6ab449f789faeb304d18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 18 Jan 2024 10:20:10 +0100 Subject: [PATCH 010/394] Switch tungstenite to rustls --- Cargo.lock | 14 +------------- Cargo.toml | 4 ++-- common/client-libs/gateway-client/Cargo.toml | 2 +- 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c77ac80692..169cbaed76 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10059,16 +10059,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "tokio-native-tls" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" -dependencies = [ - "native-tls", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.23.4" @@ -10147,9 +10137,8 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "native-tls", + "rustls 0.21.7", "tokio", - "tokio-native-tls", "tungstenite", ] @@ -10602,7 +10591,6 @@ dependencies = [ "http", "httparse", "log", - "native-tls", "rand 0.8.5", "rustls 0.21.7", "sha1", diff --git a/Cargo.toml b/Cargo.toml index efc9217527..bdfbdd850e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -168,9 +168,9 @@ time = "0.3.30" thiserror = "1.0.48" tokio = "1.33.0" tokio-util = "0.7.10" -tokio-tungstenite = "0.20.1" +tokio-tungstenite = { version = "0.20.1", features = ["rustls"] } tracing = "0.1.37" -tungstenite = { version = "0.20.1", default-features = false } +tungstenite = { version = "0.20.1", default-features = false, features = ["rustls"] } ts-rs = "7.0.0" utoipa = "3.5.0" utoipa-swagger-ui = "3.1.5" diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 75f56fd7c0..67297687e4 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -48,7 +48,7 @@ features = ["net", "sync", "time"] workspace = true # the choice of this particular tls feature was arbitrary; # if you reckon a different one would be more appropriate, feel free to change it -features = ["native-tls"] +# features = ["native-tls"] # wasm-only dependencies [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen] From 412b7b9898469689836f07d89161af9d7571e430 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Mon, 5 Feb 2024 10:05:55 +0100 Subject: [PATCH 011/394] Remove sdk-version-bump from main workspace temporarily In the upcoming cargo-edit version then the dependency on ureq is dropped and also the implicit dependency on openssl --- Cargo.lock | 386 +---------------------------------------------------- Cargo.toml | 2 +- 2 files changed, 5 insertions(+), 383 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 169cbaed76..5b1cd3706b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -870,69 +870,6 @@ dependencies = [ "serde", ] -[[package]] -name = "camino" -version = "1.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo-edit" -version = "0.11.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f769ab9e8c1652d78dd0b3ec59cdaa1e2bcb3b6b39f6681b256abcdbe101cc14" -dependencies = [ - "anyhow", - "cargo_metadata", - "clap 4.4.7", - "concolor-control", - "crates-index", - "dirs-next", - "dunce", - "env_proxy", - "git2", - "hex", - "indexmap 1.9.3", - "native-tls", - "pathdiff", - "regex", - "semver 1.0.20", - "serde", - "serde_derive", - "serde_json", - "subprocess", - "termcolor", - "toml_edit 0.16.2", - "ureq", - "url", -] - -[[package]] -name = "cargo-platform" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12024c4645c97566567129c204f65d5815a8c9aecf30fcbe682b2fe034996d36" -dependencies = [ - "serde", -] - -[[package]] -name = "cargo_metadata" -version = "0.15.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" -dependencies = [ - "camino", - "cargo-platform", - "semver 1.0.20", - "serde", - "serde_json", - "thiserror", -] - [[package]] name = "cast" version = "0.3.0" @@ -951,7 +888,6 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "jobserver", "libc", ] @@ -1140,7 +1076,6 @@ dependencies = [ "anstyle", "clap_lex 0.6.0", "strsim", - "terminal_size", ] [[package]] @@ -1237,23 +1172,6 @@ dependencies = [ "unicode-width", ] -[[package]] -name = "concolor-control" -version = "0.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7104119c2f80d887239879d0c50e033cd40eac9a3f3561e0684ba7d5d654f4da" -dependencies = [ - "atty", - "bitflags 1.3.2", - "concolor-query", -] - -[[package]] -name = "concolor-query" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad159cc964ac8f9d407cbc0aa44b02436c054b541f2b4b5f06972e1efdc54bc7" - [[package]] name = "concurrent-queue" version = "2.3.0" @@ -1527,27 +1445,6 @@ dependencies = [ "libc", ] -[[package]] -name = "crates-index" -version = "0.18.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "599f67b56f40863598cb30450427049935d05de2e36c61d33c050f04d7ec8cf2" -dependencies = [ - "git2", - "hex", - "home", - "memchr", - "num_cpus", - "rayon", - "rustc-hash", - "semver 1.0.20", - "serde", - "serde_derive", - "serde_json", - "smartstring", - "toml 0.5.11", -] - [[package]] name = "crc" version = "3.0.1" @@ -2341,16 +2238,6 @@ dependencies = [ "dirs-sys 0.4.1", ] -[[package]] -name = "dirs-next" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1" -dependencies = [ - "cfg-if", - "dirs-sys-next", -] - [[package]] name = "dirs-sys" version = "0.3.7" @@ -2374,17 +2261,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "dirs-sys-next" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - [[package]] name = "displaydoc" version = "0.2.4" @@ -2414,12 +2290,6 @@ version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dcbb2bf8e87535c23f7a8a321e364ce21462d0ff10cb6407820e8e96dfff6653" -[[package]] -name = "dunce" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56ce8c6da7551ec6c462cbaf3bfbc75131ebbfa1c944aeaa9dab51ca1c5f0c3b" - [[package]] name = "dyn-clone" version = "1.0.14" @@ -2606,16 +2476,6 @@ dependencies = [ "regex", ] -[[package]] -name = "env_proxy" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a5019be18538406a43b5419a5501461f0c8b49ea7dfda0cfc32f4e51fc44be1" -dependencies = [ - "log", - "url", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -2857,21 +2717,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" -dependencies = [ - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-shared" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" - [[package]] name = "form_urlencoded" version = "1.2.0" @@ -3156,21 +3001,6 @@ version = "0.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6fb8d784f27acf97159b40fc4db5ecd8aa23b9ad5ef69cdd136d3bc80665f0c0" -[[package]] -name = "git2" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" -dependencies = [ - "bitflags 1.3.2", - "libc", - "libgit2-sys", - "log", - "openssl-probe", - "openssl-sys", - "url", -] - [[package]] name = "glob" version = "0.3.1" @@ -3372,9 +3202,6 @@ name = "hex" version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" -dependencies = [ - "serde", -] [[package]] name = "hex-literal" @@ -3998,15 +3825,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.64" @@ -4056,15 +3874,6 @@ dependencies = [ "libc", ] -[[package]] -name = "kstring" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747" -dependencies = [ - "static_assertions", -] - [[package]] name = "lazy_static" version = "1.4.0" @@ -4125,20 +3934,6 @@ version = "0.2.149" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" -[[package]] -name = "libgit2-sys" -version = "0.13.5+1.4.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" -dependencies = [ - "cc", - "libc", - "libssh2-sys", - "libz-sys", - "openssl-sys", - "pkg-config", -] - [[package]] name = "libm" version = "0.2.8" @@ -4509,20 +4304,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "libssh2-sys" -version = "0.2.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b094a36eb4b8b8c8a7b4b8ae43b2944502be3e59cd87687595cf6b0a71b3f4ca" -dependencies = [ - "cc", - "libc", - "libz-sys", - "openssl-sys", - "pkg-config", - "vcpkg", -] - [[package]] name = "libz-sys" version = "1.1.12" @@ -4865,24 +4646,6 @@ dependencies = [ "unsigned-varint", ] -[[package]] -name = "native-tls" -version = "0.2.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" -dependencies = [ - "lazy_static", - "libc", - "log", - "openssl", - "openssl-probe", - "openssl-sys", - "schannel", - "security-framework", - "security-framework-sys", - "tempfile", -] - [[package]] name = "netlink-packet-core" version = "0.4.2" @@ -5055,15 +4818,6 @@ dependencies = [ "minimal-lexical", ] -[[package]] -name = "nom8" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8" -dependencies = [ - "memchr", -] - [[package]] name = "notify" version = "5.2.0" @@ -7010,32 +6764,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" -[[package]] -name = "openssl" -version = "0.10.62" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" -dependencies = [ - "bitflags 2.4.1", - "cfg-if", - "foreign-types", - "libc", - "once_cell", - "openssl-macros", - "openssl-sys", -] - -[[package]] -name = "openssl-macros" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "openssl-probe" version = "0.1.5" @@ -7273,12 +7001,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "pbkdf2" version = "0.12.2" @@ -8816,18 +8538,6 @@ dependencies = [ "untrusted 0.7.1", ] -[[package]] -name = "sdk-version-bump" -version = "0.1.0" -dependencies = [ - "anyhow", - "cargo-edit", - "clap 4.4.7", - "semver 1.0.20", - "serde", - "serde_json", -] - [[package]] name = "sdp" version = "0.5.3" @@ -8914,9 +8624,6 @@ name = "semver" version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" -dependencies = [ - "serde", -] [[package]] name = "semver-parser" @@ -9247,18 +8954,6 @@ version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" -[[package]] -name = "smartstring" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29" -dependencies = [ - "autocfg 1.1.0", - "serde", - "static_assertions", - "version_check", -] - [[package]] name = "snafu" version = "0.7.5" @@ -9318,17 +9013,6 @@ dependencies = [ "windows-sys 0.48.0", ] -[[package]] -name = "socks" -version = "0.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0c3dbbd9ae980613c6dd8e28a9407b50509d3803b57624d5dfe8315218cd58b" -dependencies = [ - "byteorder", - "libc", - "winapi", -] - [[package]] name = "soketto" version = "0.7.1" @@ -9636,16 +9320,6 @@ dependencies = [ "webrtc-util", ] -[[package]] -name = "subprocess" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2e86926081dda636c546d8c5e641661049d7562a68f5488be4a1f7f66f6086" -dependencies = [ - "libc", - "winapi", -] - [[package]] name = "substring" version = "1.4.5" @@ -9893,16 +9567,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "terminal_size" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7" -dependencies = [ - "rustix 0.38.19", - "windows-sys 0.48.0", -] - [[package]] name = "textwrap" version = "0.16.0" @@ -10177,7 +9841,7 @@ checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime", "toml_edit 0.19.15", ] @@ -10189,19 +9853,10 @@ checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" dependencies = [ "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime", "toml_edit 0.20.2", ] -[[package]] -name = "toml_datetime" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5" -dependencies = [ - "serde", -] - [[package]] name = "toml_datetime" version = "0.6.3" @@ -10211,20 +9866,6 @@ dependencies = [ "serde", ] -[[package]] -name = "toml_edit" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dd30deba9a1cd7153c22aecf93e86df639e7b81c622b0af8d9255e989991a7b7" -dependencies = [ - "indexmap 1.9.3", - "itertools 0.10.5", - "kstring", - "nom8", - "serde", - "toml_datetime 0.5.1", -] - [[package]] name = "toml_edit" version = "0.19.15" @@ -10234,7 +9875,7 @@ dependencies = [ "indexmap 2.0.2", "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime", "winnow", ] @@ -10247,7 +9888,7 @@ dependencies = [ "indexmap 2.0.2", "serde", "serde_spanned", - "toml_datetime 0.6.3", + "toml_datetime", "winnow", ] @@ -10776,25 +10417,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0976c77def3f1f75c4ef892a292c31c0bbe9e3d0702c63044d7c76db298171a3" -[[package]] -name = "ureq" -version = "2.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5ccd538d4a604753ebc2f17cd9946e89b77bf87f6a8e2309667c6f2e87855e3" -dependencies = [ - "base64 0.21.4", - "log", - "native-tls", - "once_cell", - "rustls 0.21.7", - "rustls-webpki", - "serde", - "serde_json", - "socks", - "url", - "webpki-roots 0.25.2", -] - [[package]] name = "url" version = "2.4.1" diff --git a/Cargo.toml b/Cargo.toml index bdfbdd850e..305be5b37b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -104,7 +104,7 @@ members = [ "nym-outfox", "nym-validator-rewarder", "tools/internal/ssl-inject", - "tools/internal/sdk-version-bump", + # "tools/internal/sdk-version-bump", "tools/nym-cli", "tools/nym-nr-query", "tools/nymvisor", From b03d7373939bf2ca885f3367bdeb973910898add Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 12:03:06 +0000 Subject: [PATCH 012/394] making sure to stop nym-rewarder if nyxd scraper has terminated --- common/nyxd-scraper/src/scraper/mod.rs | 10 +++++++- common/nyxd-scraper/src/scraper/subscriber.rs | 2 +- nym-connect/desktop/Cargo.lock | 25 ++++++++----------- nym-validator-rewarder/src/rewarder/mod.rs | 24 +++++++++++++----- nym-wallet/Cargo.lock | 18 ++++++------- 5 files changed, 45 insertions(+), 34 deletions(-) diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index f417318227..b7d4846c66 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -201,10 +201,18 @@ impl NyxdScraper { } pub async fn stop(self) { - info!("stopping the chain scrapper"); + info!("stopping the chain scraper"); assert!(self.task_tracker.is_closed()); self.cancel_token.cancel(); self.task_tracker.wait().await } + + pub fn cancel_token(&self) -> CancellationToken { + self.cancel_token.clone() + } + + pub fn is_cancelled(&self) -> bool { + self.cancel_token.is_cancelled() + } } diff --git a/common/nyxd-scraper/src/scraper/subscriber.rs b/common/nyxd-scraper/src/scraper/subscriber.rs index 6e9fd3e85d..a6d0d67b87 100644 --- a/common/nyxd-scraper/src/scraper/subscriber.rs +++ b/common/nyxd-scraper/src/scraper/subscriber.rs @@ -120,7 +120,7 @@ pub async fn run_websocket_driver(driver: WebSocketClientDriver, cancel: Cancell Ok(_) => info!("our websocket driver has finished execution"), Err(err) => { // TODO: in the future just attempt to reconnect - error!("our websocket driver has errored out: {err}") + error!("our websocket driver has errored out: {err}"); } } cancel.cancel() diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index e3e8cf14c3..c284610844 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4513,7 +4513,6 @@ dependencies = [ "nym-network-defaults", "nym-service-provider-directory-common", "nym-vesting-contract-common", - "openssl", "prost", "reqwest", "serde", @@ -4660,15 +4659,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "111.27.0+1.1.1v" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.91" @@ -4677,7 +4667,6 @@ checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -5518,6 +5507,7 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", + "webpki-roots 0.25.4", "winreg 0.50.0", ] @@ -6473,7 +6463,7 @@ dependencies = [ "thiserror", "tokio-stream", "url", - "webpki-roots", + "webpki-roots 0.22.6", ] [[package]] @@ -7262,9 +7252,8 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "native-tls", + "rustls 0.21.7", "tokio", - "tokio-native-tls", "tungstenite", ] @@ -7444,8 +7433,8 @@ dependencies = [ "http", "httparse", "log", - "native-tls", "rand 0.8.5", + "rustls 0.21.7", "sha1", "thiserror", "url", @@ -7889,6 +7878,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webview2-com" version = "0.19.1" diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 216ee8eee8..a91ed0f903 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2023 - Nym Technologies SA +// Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only use crate::config::Config; @@ -10,13 +10,15 @@ use crate::rewarder::credential_issuance::CredentialIssuance; use crate::rewarder::epoch::Epoch; use crate::rewarder::nyxd_client::NyxdClient; use crate::rewarder::storage::RewarderStorage; +use futures::future::{FusedFuture, OptionFuture}; +use futures::FutureExt; use nym_task::TaskManager; use nym_validator_client::nyxd::{AccountId, Coin, Hash}; use nyxd_scraper::NyxdScraper; use std::ops::Add; use tokio::pin; use tokio::time::{interval_at, Instant}; -use tracing::{error, info, instrument}; +use tracing::{error, info, instrument, warn}; mod block_signing; mod credential_issuance; @@ -263,10 +265,16 @@ impl Rewarder { ); } - if let Some(epoch_signing) = &self.epoch_signing { - epoch_signing.nyxd_scraper.start().await?; - epoch_signing.nyxd_scraper.wait_for_startup_sync().await; - } + let mut scraper_cancellation: OptionFuture<_> = + if let Some(epoch_signing) = &self.epoch_signing { + let cancellation_token = epoch_signing.nyxd_scraper.cancel_token(); + epoch_signing.nyxd_scraper.start().await?; + epoch_signing.nyxd_scraper.wait_for_startup_sync().await; + Some(Box::pin(async move { cancellation_token.cancelled().await }).fuse()) + } else { + None + } + .into(); let until_end = self.current_epoch.until_end(); @@ -292,6 +300,10 @@ impl Rewarder { } break; } + _ = &mut scraper_cancellation, if !scraper_cancellation.is_terminated() => { + warn!("the nyxd scraper has been cancelled"); + break + } _ = epoch_ticker.tick() => self.handle_epoch_end().await } } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 93c8462986..a197456fb9 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3454,7 +3454,6 @@ dependencies = [ "nym-network-defaults", "nym-service-provider-directory-common", "nym-vesting-contract-common", - "openssl", "prost", "reqwest", "serde", @@ -3686,15 +3685,6 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" -[[package]] -name = "openssl-src" -version = "111.27.0+1.1.1v" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e8f197c82d7511c5b014030c9b1efeda40d7d5f99d23b4ceed3524a5e63f02" -dependencies = [ - "cc", -] - [[package]] name = "openssl-sys" version = "0.9.91" @@ -3703,7 +3693,6 @@ checksum = "866b5f16f90776b9bb8dc1e1802ac6f0513de3a7a7465867bfbc563dc737faac" dependencies = [ "cc", "libc", - "openssl-src", "pkg-config", "vcpkg", ] @@ -4454,6 +4443,7 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", + "webpki-roots", "winreg", ] @@ -6270,6 +6260,12 @@ dependencies = [ "system-deps 6.1.1", ] +[[package]] +name = "webpki-roots" +version = "0.25.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" + [[package]] name = "webview2-com" version = "0.19.1" From f1c5e8bdc060585232cb933f3c5cc6d68a1017de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 14:41:57 +0000 Subject: [PATCH 013/394] attempt to re-create websocket creation on failure --- Cargo.lock | 1 + common/nyxd-scraper/Cargo.toml | 1 + common/nyxd-scraper/src/error.rs | 2 +- common/nyxd-scraper/src/scraper/mod.rs | 29 +--- common/nyxd-scraper/src/scraper/subscriber.rs | 144 ++++++++++++++++-- nym-validator-rewarder/src/rewarder/mod.rs | 4 + 6 files changed, 143 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b1cd3706b..f19ad60c21 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6694,6 +6694,7 @@ dependencies = [ "tendermint", "tendermint-rpc", "thiserror", + "time", "tokio", "tokio-stream", "tokio-util", diff --git a/common/nyxd-scraper/Cargo.toml b/common/nyxd-scraper/Cargo.toml index 772ab8e7b3..858f89512b 100644 --- a/common/nyxd-scraper/Cargo.toml +++ b/common/nyxd-scraper/Cargo.toml @@ -21,6 +21,7 @@ sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros tendermint.workspace = true tendermint-rpc = { workspace = true, features = ["websocket-client", "http-client"] } thiserror.workspace = true +time = { workspace = true } tokio = { workspace = true, features = ["full"] } tokio-stream = "0.1.14" tokio-util = { version = "0.7.10", features = ["rt"]} diff --git a/common/nyxd-scraper/src/error.rs b/common/nyxd-scraper/src/error.rs index dec4fb26e9..daefd92ff4 100644 --- a/common/nyxd-scraper/src/error.rs +++ b/common/nyxd-scraper/src/error.rs @@ -84,7 +84,7 @@ pub enum ScraperError { EmptyBlockData { query: String }, #[error("reached maximum number of allowed errors for subscription events")] - MaximumSubscriptionFailures, + MaximumWebSocketFailures, #[error("failed to begin storage tx: {source}")] StorageTxBeginFailure { diff --git a/common/nyxd-scraper/src/scraper/mod.rs b/common/nyxd-scraper/src/scraper/mod.rs index b7d4846c66..c6c668e41d 100644 --- a/common/nyxd-scraper/src/scraper/mod.rs +++ b/common/nyxd-scraper/src/scraper/mod.rs @@ -6,11 +6,10 @@ use crate::block_requester::BlockRequester; use crate::error::ScraperError; use crate::modules::{BlockModule, MsgModule, TxModule}; use crate::rpc_client::RpcClient; -use crate::scraper::subscriber::{run_websocket_driver, ChainSubscriber}; +use crate::scraper::subscriber::ChainSubscriber; use crate::storage::ScraperStorage; use std::path::PathBuf; use std::sync::Arc; -use tendermint_rpc::WebSocketClientDriver; use tokio::sync::mpsc::{channel, unbounded_channel}; use tokio::sync::Notify; use tokio_util::sync::CancellationToken; @@ -67,20 +66,15 @@ impl NyxdScraperBuilder { block_processor.set_tx_modules(self.tx_modules); block_processor.set_msg_modules(self.msg_modules); - let mut chain_subscriber = ChainSubscriber::new( + let chain_subscriber = ChainSubscriber::new( &scraper.config.websocket_url, scraper.cancel_token.clone(), + scraper.task_tracker.clone(), processing_tx, ) .await?; - let ws_driver = chain_subscriber.ws_driver(); - scraper.start_tasks( - block_requester, - block_processor, - chain_subscriber, - ws_driver, - ); + scraper.start_tasks(block_requester, block_processor, chain_subscriber); Ok(scraper) } @@ -141,7 +135,6 @@ impl NyxdScraper { mut block_requester: BlockRequester, mut block_processor: BlockProcessor, mut chain_subscriber: ChainSubscriber, - ws_driver: WebSocketClientDriver, ) { self.task_tracker .spawn(async move { block_requester.run().await }); @@ -149,8 +142,7 @@ impl NyxdScraper { .spawn(async move { block_processor.run().await }); self.task_tracker .spawn(async move { chain_subscriber.run().await }); - self.task_tracker - .spawn(run_websocket_driver(ws_driver, self.cancel_token.clone())); + self.task_tracker.close(); } @@ -176,21 +168,16 @@ impl NyxdScraper { rpc_client, ) .await?; - let mut chain_subscriber = ChainSubscriber::new( + let chain_subscriber = ChainSubscriber::new( &self.config.websocket_url, self.cancel_token.clone(), + self.task_tracker.clone(), processing_tx, ) .await?; - let ws_driver = chain_subscriber.ws_driver(); // spawn them - self.start_tasks( - block_requester, - block_processor, - chain_subscriber, - ws_driver, - ); + self.start_tasks(block_requester, block_processor, chain_subscriber); Ok(()) } diff --git a/common/nyxd-scraper/src/scraper/subscriber.rs b/common/nyxd-scraper/src/scraper/subscriber.rs index a6d0d67b87..461d362eb5 100644 --- a/common/nyxd-scraper/src/scraper/subscriber.rs +++ b/common/nyxd-scraper/src/scraper/subscriber.rs @@ -6,18 +6,25 @@ use crate::error::ScraperError; use tendermint_rpc::event::Event; use tendermint_rpc::query::EventType; use tendermint_rpc::{SubscriptionClient, WebSocketClient, WebSocketClientDriver}; +use time::{Duration, OffsetDateTime}; use tokio::sync::mpsc::UnboundedSender; use tokio_stream::StreamExt; use tokio_util::sync::CancellationToken; +use tokio_util::task::TaskTracker; use tracing::{error, info, warn}; use url::Url; const MAX_FAILURES: usize = 10; +const MAX_RECONNECTION_ATTEMPTS: usize = 8; +const SOCKET_FAILURE_RESET: Duration = Duration::hours(2); pub struct ChainSubscriber { cancel: CancellationToken, + task_tracker: TaskTracker, + block_sender: UnboundedSender, + websocket_endpoint: Url, websocket_client: WebSocketClient, websocket_driver: Option, } @@ -26,6 +33,7 @@ impl ChainSubscriber { pub async fn new( websocket_endpoint: &Url, cancel: CancellationToken, + task_tracker: TaskTracker, block_sender: UnboundedSender, ) -> Result { // sure, we could have just used websocket client entirely, but let's keep the logic for @@ -39,7 +47,9 @@ impl ChainSubscriber { Ok(ChainSubscriber { cancel, + task_tracker, block_sender, + websocket_endpoint: websocket_endpoint.clone(), websocket_client: client, websocket_driver: Some(driver), }) @@ -53,8 +63,48 @@ impl ChainSubscriber { Ok(()) } - pub(crate) async fn run(&mut self) -> Result<(), ScraperError> { - let _drop_guard = self.cancel.clone().drop_guard(); + async fn remake_connection(&mut self) -> Result<(), ScraperError> { + info!( + "attempting to reestablish connection to {}", + self.websocket_endpoint + ); + + let (client, driver) = WebSocketClient::new(self.websocket_endpoint.as_str()) + .await + .map_err(|source| ScraperError::WebSocketConnectionFailure { + url: self.websocket_endpoint.to_string(), + source, + })?; + self.websocket_client = client; + self.websocket_driver = Some(driver); + + info!( + "managed to reestablish the websocket connection to {}", + self.websocket_endpoint + ); + Ok(()) + } + + /// Returns whether the method exited due to the cancellation + async fn run_chain_subscription(&mut self) -> Result { + let Some(ws_driver) = self.websocket_driver.take() else { + error!("the websocket driver hasn't been created - we probably failed to establish the connection"); + return Ok(false); + }; + + let driver_cancel = CancellationToken::new(); + let _driver_guard = driver_cancel.clone().drop_guard(); + + // spawn the websocket driver task + let driver_handle = { + self.task_tracker.reopen(); + let handle = self + .task_tracker + .spawn(run_websocket_driver(ws_driver, driver_cancel)); + self.task_tracker.close(); + handle + }; + tokio::pin!(driver_handle); info!("creating chain subscription"); let mut subs = self @@ -70,12 +120,17 @@ impl ChainSubscriber { tokio::select! { _ = self.cancel.cancelled() => { info!("received cancellation token"); - break + // note: `_driver_guard` will get dropped here thus causing cancellation of the driver task + return Ok(true) + } + _ = &mut driver_handle => { + error!("our websocket driver has finished execution"); + return Ok(self.cancel.is_cancelled()) } maybe_event = subs.next() => { let Some(maybe_event) = maybe_event else { warn!("stopped receiving new events"); - break; + return Ok(false) }; match maybe_event { Ok(event) => { @@ -92,38 +147,95 @@ impl ChainSubscriber { } } if failures >= MAX_FAILURES { - // note: the drop_guard will get dropped and thus cause a shutdown - return Err(ScraperError::MaximumSubscriptionFailures); + return Ok(false) } } } } - Ok(()) } - pub(crate) fn ws_driver(&mut self) -> WebSocketClientDriver { - #[allow(clippy::expect_used)] - self.websocket_driver - .take() - .expect("websocket driver has already been started!") + async fn websocket_backoff(&mut self, failure_count: usize) -> bool { + const MINIMUM_WAIT_MS: u64 = 10_000; + const INCREMENTAL_WAIT_MS: u64 = 30_000; + + let backoff_duration_ms = MINIMUM_WAIT_MS + INCREMENTAL_WAIT_MS * failure_count as u64; + info!("going to wait {backoff_duration_ms} ms before re-attempting the reconnection"); + + tokio::select! { + _ = self.cancel.cancelled() => { + info!("received cancellation token"); + true + } + _ = tokio::time::sleep(std::time::Duration::from_millis(backoff_duration_ms)) => false, + } + } + + pub(crate) async fn run(&mut self) -> Result<(), ScraperError> { + let _drop_guard = self.cancel.clone().drop_guard(); + let mut socket_failures = 0; + let mut last_failure = OffsetDateTime::now_utc(); + + loop { + if self.cancel.is_cancelled() { + return Ok(()); + } + + match self.run_chain_subscription().await { + Ok(cancelled) => { + if cancelled { + // we're in the middle of a shutdown + return Ok(()); + } + socket_failures += 1; + } + Err(err) => { + error!("failed to create chain subscription: {err}"); + socket_failures += 1; + } + } + + warn!("current socket failure count: {socket_failures}. the last failure was at {last_failure}"); + + let now = OffsetDateTime::now_utc(); + + // if it's been a while since the last failure, reset the count + if now - last_failure > SOCKET_FAILURE_RESET { + warn!("resetting the failure count to 1"); + socket_failures = 1; + } + last_failure = now; + + if socket_failures >= MAX_RECONNECTION_ATTEMPTS { + error!("reached the maximum allowed failure count"); + return Err(ScraperError::MaximumWebSocketFailures); + } + + // BACKOFF + let cancelled = self.websocket_backoff(socket_failures).await; + if cancelled { + return Ok(()); + } + + if let Err(err) = self.remake_connection().await { + error!("failed to re-establish the websocket connection: {err}"); + } + } } } -pub async fn run_websocket_driver(driver: WebSocketClientDriver, cancel: CancellationToken) { +pub async fn run_websocket_driver(driver: WebSocketClientDriver, driver_cancel: CancellationToken) { info!("starting websocket driver"); tokio::select! { - _ = cancel.cancelled() => { + _ = driver_cancel.cancelled() => { info!("received cancellation token") } res = driver.run() => { match res { Ok(_) => info!("our websocket driver has finished execution"), Err(err) => { - // TODO: in the future just attempt to reconnect error!("our websocket driver has errored out: {err}"); } } - cancel.cancel() } } } diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a91ed0f903..56c743769a 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -95,6 +95,10 @@ impl Rewarder { return Err(NymRewarderError::EmptyBlockSigningWhitelist); } + if config.block_signing.monitor_only { + info!("the block signing rewarding is running in monitor only mode"); + } + let nyxd_scraper = NyxdScraper::new(config.scraper_config()).await?; Some(EpochSigning { From f0361a200b4a71db3c1b2f6f86573a47836a13e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 15:20:36 +0000 Subject: [PATCH 014/394] log errors on failing to determine rewarding amounts and advance epochs regardless --- nym-validator-rewarder/src/rewarder/mod.rs | 68 +++--- .../src/rewarder/storage/manager.rs | 6 +- .../src/rewarder/storage/mod.rs | 197 ++++++++++-------- 3 files changed, 158 insertions(+), 113 deletions(-) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 56c743769a..a5e8c9353d 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -28,10 +28,15 @@ mod nyxd_client; mod storage; mod tasks; +pub struct RewardingResult { + pub total_spent: Coin, + pub rewarding_tx: Hash, +} + pub struct EpochRewards { pub epoch: Epoch, - pub signing: Option, - pub credentials: Option, + pub signing: Result, NymRewarderError>, + pub credentials: Result, NymRewarderError>, pub total_budget: Coin, pub signing_budget: Coin, @@ -39,10 +44,10 @@ pub struct EpochRewards { } impl EpochRewards { - pub fn amounts(&self) -> Vec<(AccountId, Vec)> { + pub fn amounts(&self) -> Result)>, NymRewarderError> { let mut amounts = Vec::new(); - if let Some(signing) = &self.signing { + if let Ok(Some(signing)) = &self.signing { for (account, signing_amount) in signing.rewarding_amounts(&self.signing_budget) { if signing_amount[0].amount != 0 { amounts.push((account, signing_amount)) @@ -50,7 +55,7 @@ impl EpochRewards { } } - if let Some(credentials) = &self.credentials { + if let Ok(Some(credentials)) = &self.credentials { for (account, credential_amount) in credentials.rewarding_amounts(&self.credentials_budget) { @@ -60,7 +65,7 @@ impl EpochRewards { } } - amounts + Ok(amounts) } } @@ -185,7 +190,7 @@ impl Rewarder { .transpose() } - async fn determine_epoch_rewards(&mut self) -> Result { + async fn determine_epoch_rewards(&mut self) -> EpochRewards { let epoch_budget = self.config.rewarding.epoch_budget.clone(); let denom = &epoch_budget.denom; let signing_budget = Coin::new( @@ -197,17 +202,17 @@ impl Rewarder { denom, ); - let signing_rewards = self.calculate_block_signing_rewards().await?; - let credential_rewards = self.calculate_credential_rewards().await?; + let signing_rewards = self.calculate_block_signing_rewards().await; + let credential_rewards = self.calculate_credential_rewards().await; - Ok(EpochRewards { + EpochRewards { epoch: self.current_epoch, signing: signing_rewards, credentials: credential_rewards, total_budget: epoch_budget.clone(), signing_budget, credentials_budget, - }) + } } #[instrument(skip(self))] @@ -226,33 +231,42 @@ impl Rewarder { .await } - async fn handle_epoch_end(&mut self) { - info!("handling the epoch end"); - - let rewards = match self.determine_epoch_rewards().await { - Ok(rewards) => rewards, - Err(err) => { - error!("failed to determine epoch rewards: {err}"); - return; - } - }; - - let rewarding_amounts = rewards.amounts(); + async fn calculate_and_send_epoch_rewards( + &mut self, + rewards: &EpochRewards, + ) -> Result { + let rewarding_amounts = rewards.amounts()?; let total_spent = total_spent( &rewarding_amounts, &self.config.rewarding.epoch_budget.denom, ); - let rewarding_result = self.send_rewards(rewarding_amounts).await; + let rewarding_tx = self.send_rewards(rewarding_amounts).await?; + + Ok(RewardingResult { + total_spent, + rewarding_tx, + }) + } + + async fn handle_epoch_end(&mut self) { + info!("handling the epoch end"); + self.current_epoch = self.current_epoch.next(); + + let base_rewards = self.determine_epoch_rewards().await; + + let rewarding_result = self + .calculate_and_send_epoch_rewards(&base_rewards) + .await + .inspect_err(|err| error!("failed to determine and send epoch_rewards: {err}")); + if let Err(err) = self .storage - .save_rewarding_information(rewards, total_spent, rewarding_result) + .save_rewarding_information(base_rewards, rewarding_result) .await { error!("failed to persist rewarding information: {err}") } - - self.current_epoch = self.current_epoch.next(); } pub async fn run(mut self) -> Result<(), NymRewarderError> { diff --git a/nym-validator-rewarder/src/rewarder/storage/manager.rs b/nym-validator-rewarder/src/rewarder/storage/manager.rs index b8f84bbd18..1eb9e985cf 100644 --- a/nym-validator-rewarder/src/rewarder/storage/manager.rs +++ b/nym-validator-rewarder/src/rewarder/storage/manager.rs @@ -114,9 +114,9 @@ impl StorageManager { pub(crate) async fn insert_rewarding_epoch_credential_issuance( &self, epoch: i64, - starting_dkg_epoch: u32, - ending_dkg_epoch: u32, - total_issued_partial_credentials: u32, + starting_dkg_epoch: i64, + ending_dkg_epoch: i64, + total_issued_partial_credentials: i64, budget: String, ) -> Result<(), sqlx::Error> { sqlx::query!( diff --git a/nym-validator-rewarder/src/rewarder/storage/mod.rs b/nym-validator-rewarder/src/rewarder/storage/mod.rs index 0c35fb0400..dd5e8f68a7 100644 --- a/nym-validator-rewarder/src/rewarder/storage/mod.rs +++ b/nym-validator-rewarder/src/rewarder/storage/mod.rs @@ -4,8 +4,8 @@ use crate::error::NymRewarderError; use crate::rewarder::epoch::Epoch; use crate::rewarder::storage::manager::StorageManager; -use crate::rewarder::EpochRewards; -use nym_validator_client::nyxd::{Coin, Hash}; +use crate::rewarder::{EpochRewards, RewardingResult}; +use nym_validator_client::nyxd::Coin; use sqlx::ConnectOptions; use std::fmt::Debug; use std::path::Path; @@ -55,20 +55,45 @@ impl RewarderStorage { Ok(self.manager.load_last_rewarding_epoch().await?) } + async fn insert_failed_rewarding_epoch_block_signing( + &self, + epoch: i64, + budget: &Coin, + ) -> Result<(), NymRewarderError> { + Ok(self + .manager + .insert_rewarding_epoch_block_signing(epoch, -1, -1, budget.to_string()) + .await?) + } + + async fn insert_failed_rewarding_epoch_credential_issuance( + &self, + epoch: i64, + budget: &Coin, + ) -> Result<(), NymRewarderError> { + Ok(self + .manager + .insert_rewarding_epoch_credential_issuance(epoch, -1, -1, -1, budget.to_string()) + .await?) + } + pub(crate) async fn save_rewarding_information( &self, reward: EpochRewards, - total_spent: Coin, - rewarding_tx: Result, + rewarding_result: Result, // total_spent: Coin, + // rewarding_tx: Result, ) -> Result<(), NymRewarderError> { info!("persisting reward details"); - let (reward_tx, reward_err) = match rewarding_tx { - Ok(hash) => (Some(hash.to_string()), None), - Err(err) => (None, Some(err.to_string())), + let denom = &reward.total_budget.denom; + + let (reward_tx, total_spent, reward_err) = match rewarding_result { + Ok(res) => (Some(res.rewarding_tx.to_string()), res.total_spent, None), + Err(err) => (None, Coin::new(0, denom), Some(err.to_string())), }; let epoch_id = reward.epoch.id; + // general epoch info self.manager .insert_rewarding_epoch( reward.epoch, @@ -79,89 +104,95 @@ impl RewarderStorage { ) .await?; - self.manager - .insert_rewarding_epoch_block_signing( - epoch_id, - reward - .signing - .as_ref() - .map(|s| s.total_voting_power_at_epoch_start) - .unwrap_or_default(), - reward - .signing - .as_ref() - .map(|s| s.blocks) - .unwrap_or_default(), - reward.signing_budget.to_string(), - ) - .await?; - - if let Some(signing) = reward.signing { - for validator in signing.validators { - let reward_amount = validator.reward_amount(&reward.signing_budget).to_string(); - self.manager - .insert_rewarding_epoch_block_signing_reward( - epoch_id, - validator.validator.consensus_address, - validator.operator_account.to_string(), - validator.whitelisted, - reward_amount, - validator.voting_power_at_epoch_start, - validator.voting_power_ratio.to_string(), - validator.signed_blocks, - validator.ratio_signed.to_string(), - ) - .await?; + // block signing info + if let Ok(block_signing) = reward.signing { + self.manager + .insert_rewarding_epoch_block_signing( + epoch_id, + block_signing + .as_ref() + .map(|s| s.total_voting_power_at_epoch_start) + .unwrap_or_default(), + block_signing.as_ref().map(|s| s.blocks).unwrap_or_default(), + reward.signing_budget.to_string(), + ) + .await?; + if let Some(signing) = block_signing { + for validator in signing.validators { + let reward_amount = validator.reward_amount(&reward.signing_budget).to_string(); + self.manager + .insert_rewarding_epoch_block_signing_reward( + epoch_id, + validator.validator.consensus_address, + validator.operator_account.to_string(), + validator.whitelisted, + reward_amount, + validator.voting_power_at_epoch_start, + validator.voting_power_ratio.to_string(), + validator.signed_blocks, + validator.ratio_signed.to_string(), + ) + .await?; + } } + } else { + self.insert_failed_rewarding_epoch_block_signing(epoch_id, &reward.signing_budget) + .await?; } - // safety: we must have at least a single value here - #[allow(clippy::unwrap_used)] - let dkg_epoch_start = reward - .credentials - .as_ref() - .and_then(|c| c.dkg_epochs.first().copied()) - .unwrap_or_default(); - #[allow(clippy::unwrap_used)] - let dkg_epoch_end = reward - .credentials - .as_ref() - .and_then(|c| c.dkg_epochs.last().copied()) - .unwrap_or_default(); + // credential info + if let Ok(credential_issuance) = reward.credentials { + // safety: we must have at least a single value here + #[allow(clippy::unwrap_used)] + let dkg_epoch_start = credential_issuance + .as_ref() + .and_then(|c| c.dkg_epochs.first().copied()) + .unwrap_or_default() as i64; + #[allow(clippy::unwrap_used)] + let dkg_epoch_end = credential_issuance + .as_ref() + .and_then(|c| c.dkg_epochs.last().copied()) + .unwrap_or_default() as i64; - self.manager - .insert_rewarding_epoch_credential_issuance( + self.manager + .insert_rewarding_epoch_credential_issuance( + epoch_id, + dkg_epoch_start, + dkg_epoch_end, + credential_issuance + .as_ref() + .map(|c| c.total_issued_partial_credentials) + .unwrap_or_default() as i64, + reward.credentials_budget.to_string(), + ) + .await?; + + if let Some(credentials) = credential_issuance { + for api_runner in credentials.api_runners { + let reward_amount = api_runner + .reward_amount(&reward.credentials_budget) + .to_string(); + + self.manager + .insert_rewarding_epoch_credential_issuance_reward( + epoch_id, + api_runner.runner_account.to_string(), + api_runner.whitelisted, + reward_amount, + api_runner.api_runner, + api_runner.issued_credentials, + api_runner.issued_ratio.to_string(), + api_runner.validated_credentials, + ) + .await?; + } + } + } else { + self.insert_failed_rewarding_epoch_credential_issuance( epoch_id, - dkg_epoch_start, - dkg_epoch_end, - reward - .credentials - .as_ref() - .map(|c| c.total_issued_partial_credentials) - .unwrap_or_default(), - reward.credentials_budget.to_string(), + &reward.credentials_budget, ) .await?; - - if let Some(credentials) = reward.credentials { - for api_runner in credentials.api_runners { - let reward_amount = api_runner - .reward_amount(&reward.credentials_budget) - .to_string(); - - self.manager - .insert_rewarding_epoch_credential_issuance_reward( - epoch_id, - api_runner.runner_account.to_string(), - api_runner.whitelisted, - reward_amount, - api_runner.api_runner, - api_runner.issued_credentials, - api_runner.issued_ratio.to_string(), - api_runner.validated_credentials, - ) - .await?; - } } Ok(()) From 0b6cb236d8a7b7225f7bda5eac23ee7a282f2f76 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 15:22:03 +0000 Subject: [PATCH 015/394] allow running in monitor only mode without any tokens --- nym-validator-rewarder/src/rewarder/mod.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index a5e8c9353d..50736c9020 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -126,7 +126,9 @@ impl Rewarder { None }; - if config.issuance_monitor.enabled || config.block_signing.enabled { + if config.issuance_monitor.enabled + || (config.block_signing.enabled && !config.block_signing.monitor_only) + { let balance = nyxd_client .balance(&config.rewarding.epoch_budget.denom) .await?; From d7255374de45cd1c935ebb4295d6b757f8162f27 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 17:41:07 +0000 Subject: [PATCH 016/394] fixed nym-api config template --- nym-api/src/support/config/template.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/nym-api/src/support/config/template.rs b/nym-api/src/support/config/template.rs index 927fe065c2..170cc73ba3 100644 --- a/nym-api/src/support/config/template.rs +++ b/nym-api/src/support/config/template.rs @@ -127,12 +127,4 @@ decryption_key_path = '{{ coconut_signer.storage_paths.decryption_key_path }}' # Path to the dkg dealer public key with proof public_key_with_proof_path = '{{ coconut_signer.storage_paths.public_key_with_proof_path }}' -[ephemera] - -enabled = {{ ephemera.enabled }} - -[ephemera.args] - -ephemera_config = '{{ ephemera.args.ephemera_config }}' - "#; From 536b892c914fc455de5c6a33051b565cdf99a35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 08:49:08 +0000 Subject: [PATCH 017/394] fixed epoch id being advanced at wrong point --- nym-validator-rewarder/src/rewarder/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index 50736c9020..b647522c46 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -253,8 +253,6 @@ impl Rewarder { async fn handle_epoch_end(&mut self) { info!("handling the epoch end"); - self.current_epoch = self.current_epoch.next(); - let base_rewards = self.determine_epoch_rewards().await; let rewarding_result = self @@ -269,6 +267,8 @@ impl Rewarder { { error!("failed to persist rewarding information: {err}") } + + self.current_epoch = self.current_epoch.next(); } pub async fn run(mut self) -> Result<(), NymRewarderError> { From e8f6d6e55d2e7dc867540801d9229d30d540539d Mon Sep 17 00:00:00 2001 From: mx <33262279+mfahampshire@users.noreply.github.com> Date: Wed, 14 Feb 2024 08:59:19 +0000 Subject: [PATCH 018/394] fixed theme bug? (#4401) Co-authored-by: mfahampshire --- documentation/dev-portal/book.toml | 2 +- .../dev-portal/nym_themes/css/chrome.css | 2 +- .../dev-portal/nym_themes/css/variables.css | 2 +- .../dev-portal/nym_themes/custom.css | 4 +- documentation/dev-portal/nym_themes/index.hbs | 6 +- .../dev-portal/nym_themes/index.hbs.bak | 370 ------------------ .../dev-portal/nym_themes/pagetoc.css | 106 ++--- .../dev-portal/nym_themes/pagetoc.js | 154 +++----- documentation/docs/book.toml | 1 + documentation/docs/nym_themes/css/chrome.css | 2 +- .../docs/nym_themes/css/variables.css | 2 +- documentation/docs/nym_themes/index.hbs | 6 +- documentation/docs/nym_themes/index.hbs.bak | 370 ------------------ documentation/docs/nym_themes/pagetoc.css | 106 ++--- documentation/docs/nym_themes/pagetoc.js | 154 +++----- .../operators/nym_themes/css/chrome.css | 2 +- .../operators/nym_themes/css/variables.css | 2 +- documentation/operators/nym_themes/index.hbs | 6 +- .../operators/nym_themes/index.hbs.bak | 370 ------------------ .../operators/nym_themes/pagetoc.css | 106 ++--- documentation/operators/nym_themes/pagetoc.js | 154 +++----- 21 files changed, 259 insertions(+), 1668 deletions(-) delete mode 100644 documentation/dev-portal/nym_themes/index.hbs.bak delete mode 100644 documentation/docs/nym_themes/index.hbs.bak delete mode 100644 documentation/operators/nym_themes/index.hbs.bak diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index d36c694e22..6c944bd37d 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -20,7 +20,7 @@ content-main-margin-left = "5%" content-main-margin-right = "5%" root-font-size = "70%" # DO NOT CHANGE or you might overwrite the custom hbs file -turn-off = true +turn-off = false [preprocessor.admonish] command = "mdbook-admonish" diff --git a/documentation/dev-portal/nym_themes/css/chrome.css b/documentation/dev-portal/nym_themes/css/chrome.css index a0e30b81ff..e16262342c 100644 --- a/documentation/dev-portal/nym_themes/css/chrome.css +++ b/documentation/dev-portal/nym_themes/css/chrome.css @@ -396,7 +396,7 @@ ul#searchresults span.teaser em { top: 0; bottom: 0; width: var(--sidebar-width); - font-size: 0.85em; + font-size: 1em; box-sizing: border-box; -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain; diff --git a/documentation/dev-portal/nym_themes/css/variables.css b/documentation/dev-portal/nym_themes/css/variables.css index 51b94cfc5a..93de90cb02 100644 --- a/documentation/dev-portal/nym_themes/css/variables.css +++ b/documentation/dev-portal/nym_themes/css/variables.css @@ -6,7 +6,7 @@ --sidebar-resize-indicator-width: 8px; --sidebar-resize-indicator-space: 2px; --page-padding: 15px; - --content-max-width: 80%; + --content-max-width: 70%; --menu-bar-height: 40px; --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ diff --git a/documentation/dev-portal/nym_themes/custom.css b/documentation/dev-portal/nym_themes/custom.css index 35840fabec..8005eb68df 100644 --- a/documentation/dev-portal/nym_themes/custom.css +++ b/documentation/dev-portal/nym_themes/custom.css @@ -32,7 +32,6 @@ position: absolute; left: 50%; } - .menu-bar .a:hover, /*necessary because of ^*/ @@ -45,10 +44,11 @@ select { font-size: 16px; } + + footer { font-size: 0.8em; text-align: center; border-top: 1px solid black; padding: 5px 0; } - diff --git a/documentation/dev-portal/nym_themes/index.hbs b/documentation/dev-portal/nym_themes/index.hbs index b8115558e3..505111d5b9 100644 --- a/documentation/dev-portal/nym_themes/index.hbs +++ b/documentation/dev-portal/nym_themes/index.hbs @@ -259,12 +259,12 @@
-
- {{{ content }}} -
+
+ {{{ content }}} +
diff --git a/documentation/dev-portal/nym_themes/index.hbs.bak b/documentation/dev-portal/nym_themes/index.hbs.bak deleted file mode 100644 index d2a64dbc97..0000000000 --- a/documentation/dev-portal/nym_themes/index.hbs.bak +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - {{ title }} - {{#if is_print }} - - {{/if}} - {{#if base_url}} - - {{/if}} - - - - {{> head}} - - - - - - {{#if favicon_svg}} - - {{/if}} - {{#if favicon_png}} - - {{/if}} - - - - {{#if print_enable}} - - {{/if}} - - - - {{#if copy_fonts}} - - {{/if}} - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - - -
- - - - - - - - - - - - - - - - - - - -
- -
- {{> header}} - - - - {{#if search_enabled}} - - {{/if}} - - - - -
-
-
-
- {{{ content }}} -
-
- -
-
-
- - -
-
- - - -
- - {{#if live_reload_endpoint}} - - - {{/if}} - - {{#if playground_line_numbers}} - - {{/if}} - - {{#if playground_copyable}} - - {{/if}} - - {{#if playground_js}} - - - - - - {{/if}} - - {{#if search_js}} - - - - {{/if}} - - - - - - - {{#each additional_js}} - - {{/each}} - - {{#if is_print}} - {{#if mathjax_support}} - - {{else}} - - {{/if}} - {{/if}} - - -
- - diff --git a/documentation/dev-portal/nym_themes/pagetoc.css b/documentation/dev-portal/nym_themes/pagetoc.css index 651572ce55..a68e5b8e21 100644 --- a/documentation/dev-portal/nym_themes/pagetoc.css +++ b/documentation/dev-portal/nym_themes/pagetoc.css @@ -1,101 +1,47 @@ -:root { - --toc-width: 270px; - --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); -} - -.nav-chapters { - /* adjust width of buttons that bring to the previous or the next page */ - min-width: 50px; -} - -.previous { - /* - adjust the space between the left sidebar or the left side of the screen - and the button that leads to the previous page - */ - margin-left: var(--page-padding); -} - -@media only screen { - main { - display: flex; - } - - @media (max-width: 1179px) { - .sidebar-hidden .sidetoc { - display: none; - } - } - - @media (max-width: 1439px) { - .sidebar-visible .sidetoc { - display: none; - } - } - - @media (1180px <= width <= 1439px) { - .sidebar-hidden main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - @media (1440px <= width <= 1700px) { - .sidebar-visible main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - .content-wrap { - overflow-y: auto; - width: 100%; - } +/* src: https://github.com/JorelAli/mdBook-pagetoc */ +@media only screen and (max-width:1439px) { .sidetoc { - margin-top: 20px; - margin-left: 10px; + display: none; + } +} + +@media only screen and (min-width:1440px) { + main { + position: relative; + } + .sidetoc { + margin-left: auto; margin-right: auto; + /* left: calc(90% + (var(--content-min-width))/4 - 110px); */ + left: 101%; + position: absolute; + font-size: var(--pagetoc-fontsize); } .pagetoc { position: fixed; - /* adjust TOC width */ - width: var(--toc-width); - height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); - overflow: auto; + width: var(--pagetoc-width); } .pagetoc a { border-left: 1px solid var(--sidebar-bg); - color: var(--fg) !important; + /* color: var(--fg); */ + /* color: var(--sidebar-fg); */ + color: var(--links); display: block; padding-bottom: 5px; padding-top: 5px; padding-left: 10px; text-align: left; text-decoration: none; + font-weight: normal; + background: var(--sidebar-bg); } .pagetoc a:hover, .pagetoc a.active { background: var(--sidebar-bg); - color: var(--sidebar-fg) !important; - } - .pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-fg); - } - .pagetoc .pagetoc-H2 { - padding-left: 20px; - } - .pagetoc .pagetoc-H3 { - padding-left: 40px; - } - .pagetoc .pagetoc-H4 { - padding-left: 60px; - } -} - -@media print { - .sidetoc { - display: none; + /* color: var(--sidebar-fg); */ + color: var(--sidebar-active); + font-weight: bold; + font-size: var(--pagetoc-fontsize); } } diff --git a/documentation/dev-portal/nym_themes/pagetoc.js b/documentation/dev-portal/nym_themes/pagetoc.js index 490d9e4c31..b11052427e 100644 --- a/documentation/dev-portal/nym_themes/pagetoc.js +++ b/documentation/dev-portal/nym_themes/pagetoc.js @@ -1,114 +1,68 @@ -function forEach(elems, fun) { - Array.prototype.forEach.call(elems, fun); -} - -function getPagetoc(){ - return document.getElementsByClassName("pagetoc")[0] -} - -function getPagetocElems() { - return getPagetoc().children; -} - -function getHeaders(){ - return document.getElementsByClassName("header") -} +// src: https://github.com/JorelAli/mdBook-pagetoc // Un-active everything when you click it -function forPagetocElem(fun) { - forEach(getPagetocElems(), fun); -} - -function getRect(element) { - return element.getBoundingClientRect(); -} - -function overflowTop(container, element) { - return getRect(container).top - getRect(element).top; -} - -function overflowBottom(container, element) { - return getRect(container).bottom - getRect(element).bottom; -} - -var activeHref = location.href; - -var updateFunction = function (elem = undefined) { - var id = elem; - - if (!id && location.href != activeHref) { - activeHref = location.href; - forPagetocElem(function (el) { - if (el.href === activeHref) { - id = el; - } +Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.addEventHandler("click", function() { + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); + el.classList.add("active"); }); - } +}); - if (!id) { - var elements = getHeaders(); - let margin = window.innerHeight / 3; +var updateFunction = function() { - forEach(elements, function (el, i, arr) { - if (!id && getRect(el).top >= 0) { - if (getRect(el).top < margin) { - id = el; - } else { - id = arr[Math.max(0, i - 1)]; + var id; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + if (window.pageYOffset >= el.offsetTop) { + id = el; } - } - // a very long last section - // its heading is over the screen - if (!id && i == arr.length - 1) { - id = el - } }); - } - forPagetocElem(function (el) { - el.classList.remove("active"); - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); - if (!id) return; - - forPagetocElem(function (el) { - if (id.href.localeCompare(el.href) == 0) { - el.classList.add("active"); - let pagetoc = getPagetoc(); - if (overflowTop(pagetoc, el) > 0) { - pagetoc.scrollTop = el.offsetTop; - } - if (overflowBottom(pagetoc, el) < 0) { - pagetoc.scrollTop -= overflowBottom(pagetoc, el); - } - } - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + if (id.href.localeCompare(el.href) == 0) { + el.classList.add("active"); + } + }); }; -let elements = getHeaders(); +// Populate sidebar on load +window.addEventListener('load', function() { + var pagetoc = document.getElementsByClassName("pagetoc")[0]; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + var link = document.createElement("a"); -if (elements.length > 1) { - // Populate sidebar on load - window.addEventListener("load", function () { - var pagetoc = getPagetoc(); - var elements = getHeaders(); - forEach(elements, function (el) { - var link = document.createElement("a"); - link.appendChild(document.createTextNode(el.text)); - link.href = el.hash; - link.classList.add("pagetoc-" + el.parentElement.tagName); - pagetoc.appendChild(link); - link.onclick = function () { - updateFunction(link); - }; + // Indent shows hierarchy + var indent = ""; + switch (el.parentElement.tagName) { + case "H2": + indent = "20px"; + break; + case "H3": + indent = "40px"; + break; + case "H4": + indent = "60px"; + break; + default: + break; + } + + link.appendChild(document.createTextNode(el.text)); + link.style.paddingLeft = indent; + link.href = el.href; + pagetoc.appendChild(link); }); - updateFunction(); - }); + updateFunction.call(); +}); - // Handle active elements on scroll - window.addEventListener("scroll", function () { - updateFunction(); - }); -} else { - document.getElementsByClassName("sidetoc")[0].remove(); -} + + +// Handle active elements on scroll +window.addEventListener("scroll", updateFunction); diff --git a/documentation/docs/book.toml b/documentation/docs/book.toml index 0f2732e7f3..33505cb707 100644 --- a/documentation/docs/book.toml +++ b/documentation/docs/book.toml @@ -14,6 +14,7 @@ edition = "2018" ################# [preprocessor.theme] +pagetoc = true sidebar-width = "280px" content-max-width = "70%" content-main-margin-left = "5%" diff --git a/documentation/docs/nym_themes/css/chrome.css b/documentation/docs/nym_themes/css/chrome.css index a0e30b81ff..e16262342c 100644 --- a/documentation/docs/nym_themes/css/chrome.css +++ b/documentation/docs/nym_themes/css/chrome.css @@ -396,7 +396,7 @@ ul#searchresults span.teaser em { top: 0; bottom: 0; width: var(--sidebar-width); - font-size: 0.85em; + font-size: 1em; box-sizing: border-box; -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain; diff --git a/documentation/docs/nym_themes/css/variables.css b/documentation/docs/nym_themes/css/variables.css index 51b94cfc5a..93de90cb02 100644 --- a/documentation/docs/nym_themes/css/variables.css +++ b/documentation/docs/nym_themes/css/variables.css @@ -6,7 +6,7 @@ --sidebar-resize-indicator-width: 8px; --sidebar-resize-indicator-space: 2px; --page-padding: 15px; - --content-max-width: 80%; + --content-max-width: 70%; --menu-bar-height: 40px; --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ diff --git a/documentation/docs/nym_themes/index.hbs b/documentation/docs/nym_themes/index.hbs index b8115558e3..505111d5b9 100644 --- a/documentation/docs/nym_themes/index.hbs +++ b/documentation/docs/nym_themes/index.hbs @@ -259,12 +259,12 @@
-
- {{{ content }}} -
+
+ {{{ content }}} +
diff --git a/documentation/docs/nym_themes/index.hbs.bak b/documentation/docs/nym_themes/index.hbs.bak deleted file mode 100644 index d2a64dbc97..0000000000 --- a/documentation/docs/nym_themes/index.hbs.bak +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - {{ title }} - {{#if is_print }} - - {{/if}} - {{#if base_url}} - - {{/if}} - - - - {{> head}} - - - - - - {{#if favicon_svg}} - - {{/if}} - {{#if favicon_png}} - - {{/if}} - - - - {{#if print_enable}} - - {{/if}} - - - - {{#if copy_fonts}} - - {{/if}} - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - - -
- - - - - - - - - - - - - - - - - - - -
- -
- {{> header}} - - - - {{#if search_enabled}} - - {{/if}} - - - - -
-
-
-
- {{{ content }}} -
-
- -
-
-
- - -
-
- - - -
- - {{#if live_reload_endpoint}} - - - {{/if}} - - {{#if playground_line_numbers}} - - {{/if}} - - {{#if playground_copyable}} - - {{/if}} - - {{#if playground_js}} - - - - - - {{/if}} - - {{#if search_js}} - - - - {{/if}} - - - - - - - {{#each additional_js}} - - {{/each}} - - {{#if is_print}} - {{#if mathjax_support}} - - {{else}} - - {{/if}} - {{/if}} - - -
- - diff --git a/documentation/docs/nym_themes/pagetoc.css b/documentation/docs/nym_themes/pagetoc.css index 651572ce55..a68e5b8e21 100644 --- a/documentation/docs/nym_themes/pagetoc.css +++ b/documentation/docs/nym_themes/pagetoc.css @@ -1,101 +1,47 @@ -:root { - --toc-width: 270px; - --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); -} - -.nav-chapters { - /* adjust width of buttons that bring to the previous or the next page */ - min-width: 50px; -} - -.previous { - /* - adjust the space between the left sidebar or the left side of the screen - and the button that leads to the previous page - */ - margin-left: var(--page-padding); -} - -@media only screen { - main { - display: flex; - } - - @media (max-width: 1179px) { - .sidebar-hidden .sidetoc { - display: none; - } - } - - @media (max-width: 1439px) { - .sidebar-visible .sidetoc { - display: none; - } - } - - @media (1180px <= width <= 1439px) { - .sidebar-hidden main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - @media (1440px <= width <= 1700px) { - .sidebar-visible main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - .content-wrap { - overflow-y: auto; - width: 100%; - } +/* src: https://github.com/JorelAli/mdBook-pagetoc */ +@media only screen and (max-width:1439px) { .sidetoc { - margin-top: 20px; - margin-left: 10px; + display: none; + } +} + +@media only screen and (min-width:1440px) { + main { + position: relative; + } + .sidetoc { + margin-left: auto; margin-right: auto; + /* left: calc(90% + (var(--content-min-width))/4 - 110px); */ + left: 101%; + position: absolute; + font-size: var(--pagetoc-fontsize); } .pagetoc { position: fixed; - /* adjust TOC width */ - width: var(--toc-width); - height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); - overflow: auto; + width: var(--pagetoc-width); } .pagetoc a { border-left: 1px solid var(--sidebar-bg); - color: var(--fg) !important; + /* color: var(--fg); */ + /* color: var(--sidebar-fg); */ + color: var(--links); display: block; padding-bottom: 5px; padding-top: 5px; padding-left: 10px; text-align: left; text-decoration: none; + font-weight: normal; + background: var(--sidebar-bg); } .pagetoc a:hover, .pagetoc a.active { background: var(--sidebar-bg); - color: var(--sidebar-fg) !important; - } - .pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-fg); - } - .pagetoc .pagetoc-H2 { - padding-left: 20px; - } - .pagetoc .pagetoc-H3 { - padding-left: 40px; - } - .pagetoc .pagetoc-H4 { - padding-left: 60px; - } -} - -@media print { - .sidetoc { - display: none; + /* color: var(--sidebar-fg); */ + color: var(--sidebar-active); + font-weight: bold; + font-size: var(--pagetoc-fontsize); } } diff --git a/documentation/docs/nym_themes/pagetoc.js b/documentation/docs/nym_themes/pagetoc.js index 490d9e4c31..b11052427e 100644 --- a/documentation/docs/nym_themes/pagetoc.js +++ b/documentation/docs/nym_themes/pagetoc.js @@ -1,114 +1,68 @@ -function forEach(elems, fun) { - Array.prototype.forEach.call(elems, fun); -} - -function getPagetoc(){ - return document.getElementsByClassName("pagetoc")[0] -} - -function getPagetocElems() { - return getPagetoc().children; -} - -function getHeaders(){ - return document.getElementsByClassName("header") -} +// src: https://github.com/JorelAli/mdBook-pagetoc // Un-active everything when you click it -function forPagetocElem(fun) { - forEach(getPagetocElems(), fun); -} - -function getRect(element) { - return element.getBoundingClientRect(); -} - -function overflowTop(container, element) { - return getRect(container).top - getRect(element).top; -} - -function overflowBottom(container, element) { - return getRect(container).bottom - getRect(element).bottom; -} - -var activeHref = location.href; - -var updateFunction = function (elem = undefined) { - var id = elem; - - if (!id && location.href != activeHref) { - activeHref = location.href; - forPagetocElem(function (el) { - if (el.href === activeHref) { - id = el; - } +Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.addEventHandler("click", function() { + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); + el.classList.add("active"); }); - } +}); - if (!id) { - var elements = getHeaders(); - let margin = window.innerHeight / 3; +var updateFunction = function() { - forEach(elements, function (el, i, arr) { - if (!id && getRect(el).top >= 0) { - if (getRect(el).top < margin) { - id = el; - } else { - id = arr[Math.max(0, i - 1)]; + var id; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + if (window.pageYOffset >= el.offsetTop) { + id = el; } - } - // a very long last section - // its heading is over the screen - if (!id && i == arr.length - 1) { - id = el - } }); - } - forPagetocElem(function (el) { - el.classList.remove("active"); - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); - if (!id) return; - - forPagetocElem(function (el) { - if (id.href.localeCompare(el.href) == 0) { - el.classList.add("active"); - let pagetoc = getPagetoc(); - if (overflowTop(pagetoc, el) > 0) { - pagetoc.scrollTop = el.offsetTop; - } - if (overflowBottom(pagetoc, el) < 0) { - pagetoc.scrollTop -= overflowBottom(pagetoc, el); - } - } - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + if (id.href.localeCompare(el.href) == 0) { + el.classList.add("active"); + } + }); }; -let elements = getHeaders(); +// Populate sidebar on load +window.addEventListener('load', function() { + var pagetoc = document.getElementsByClassName("pagetoc")[0]; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + var link = document.createElement("a"); -if (elements.length > 1) { - // Populate sidebar on load - window.addEventListener("load", function () { - var pagetoc = getPagetoc(); - var elements = getHeaders(); - forEach(elements, function (el) { - var link = document.createElement("a"); - link.appendChild(document.createTextNode(el.text)); - link.href = el.hash; - link.classList.add("pagetoc-" + el.parentElement.tagName); - pagetoc.appendChild(link); - link.onclick = function () { - updateFunction(link); - }; + // Indent shows hierarchy + var indent = ""; + switch (el.parentElement.tagName) { + case "H2": + indent = "20px"; + break; + case "H3": + indent = "40px"; + break; + case "H4": + indent = "60px"; + break; + default: + break; + } + + link.appendChild(document.createTextNode(el.text)); + link.style.paddingLeft = indent; + link.href = el.href; + pagetoc.appendChild(link); }); - updateFunction(); - }); + updateFunction.call(); +}); - // Handle active elements on scroll - window.addEventListener("scroll", function () { - updateFunction(); - }); -} else { - document.getElementsByClassName("sidetoc")[0].remove(); -} + + +// Handle active elements on scroll +window.addEventListener("scroll", updateFunction); diff --git a/documentation/operators/nym_themes/css/chrome.css b/documentation/operators/nym_themes/css/chrome.css index a0e30b81ff..e16262342c 100644 --- a/documentation/operators/nym_themes/css/chrome.css +++ b/documentation/operators/nym_themes/css/chrome.css @@ -396,7 +396,7 @@ ul#searchresults span.teaser em { top: 0; bottom: 0; width: var(--sidebar-width); - font-size: 0.85em; + font-size: 1em; box-sizing: border-box; -webkit-overflow-scrolling: touch; overscroll-behavior-y: contain; diff --git a/documentation/operators/nym_themes/css/variables.css b/documentation/operators/nym_themes/css/variables.css index 51b94cfc5a..93de90cb02 100644 --- a/documentation/operators/nym_themes/css/variables.css +++ b/documentation/operators/nym_themes/css/variables.css @@ -6,7 +6,7 @@ --sidebar-resize-indicator-width: 8px; --sidebar-resize-indicator-space: 2px; --page-padding: 15px; - --content-max-width: 80%; + --content-max-width: 70%; --menu-bar-height: 40px; --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ diff --git a/documentation/operators/nym_themes/index.hbs b/documentation/operators/nym_themes/index.hbs index b8115558e3..505111d5b9 100644 --- a/documentation/operators/nym_themes/index.hbs +++ b/documentation/operators/nym_themes/index.hbs @@ -259,12 +259,12 @@
-
- {{{ content }}} -
+
+ {{{ content }}} +
diff --git a/documentation/operators/nym_themes/index.hbs.bak b/documentation/operators/nym_themes/index.hbs.bak deleted file mode 100644 index d2a64dbc97..0000000000 --- a/documentation/operators/nym_themes/index.hbs.bak +++ /dev/null @@ -1,370 +0,0 @@ - - - - - - {{ title }} - {{#if is_print }} - - {{/if}} - {{#if base_url}} - - {{/if}} - - - - {{> head}} - - - - - - {{#if favicon_svg}} - - {{/if}} - {{#if favicon_png}} - - {{/if}} - - - - {{#if print_enable}} - - {{/if}} - - - - {{#if copy_fonts}} - - {{/if}} - - - - - - - - {{#each additional_css}} - - {{/each}} - - {{#if mathjax_support}} - - - {{/if}} - - -
- - - - - - - - - - - - - - - - - - - -
- -
- {{> header}} - - - - {{#if search_enabled}} - - {{/if}} - - - - -
-
-
-
- {{{ content }}} -
-
- -
-
-
- - -
-
- - - -
- - {{#if live_reload_endpoint}} - - - {{/if}} - - {{#if playground_line_numbers}} - - {{/if}} - - {{#if playground_copyable}} - - {{/if}} - - {{#if playground_js}} - - - - - - {{/if}} - - {{#if search_js}} - - - - {{/if}} - - - - - - - {{#each additional_js}} - - {{/each}} - - {{#if is_print}} - {{#if mathjax_support}} - - {{else}} - - {{/if}} - {{/if}} - - -
- - diff --git a/documentation/operators/nym_themes/pagetoc.css b/documentation/operators/nym_themes/pagetoc.css index 651572ce55..a68e5b8e21 100644 --- a/documentation/operators/nym_themes/pagetoc.css +++ b/documentation/operators/nym_themes/pagetoc.css @@ -1,101 +1,47 @@ -:root { - --toc-width: 270px; - --center-content-toc-shift: calc(-1 * var(--toc-width) / 2); -} - -.nav-chapters { - /* adjust width of buttons that bring to the previous or the next page */ - min-width: 50px; -} - -.previous { - /* - adjust the space between the left sidebar or the left side of the screen - and the button that leads to the previous page - */ - margin-left: var(--page-padding); -} - -@media only screen { - main { - display: flex; - } - - @media (max-width: 1179px) { - .sidebar-hidden .sidetoc { - display: none; - } - } - - @media (max-width: 1439px) { - .sidebar-visible .sidetoc { - display: none; - } - } - - @media (1180px <= width <= 1439px) { - .sidebar-hidden main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - @media (1440px <= width <= 1700px) { - .sidebar-visible main { - position: relative; - left: var(--center-content-toc-shift); - } - } - - .content-wrap { - overflow-y: auto; - width: 100%; - } +/* src: https://github.com/JorelAli/mdBook-pagetoc */ +@media only screen and (max-width:1439px) { .sidetoc { - margin-top: 20px; - margin-left: 10px; + display: none; + } +} + +@media only screen and (min-width:1440px) { + main { + position: relative; + } + .sidetoc { + margin-left: auto; margin-right: auto; + /* left: calc(90% + (var(--content-min-width))/4 - 110px); */ + left: 101%; + position: absolute; + font-size: var(--pagetoc-fontsize); } .pagetoc { position: fixed; - /* adjust TOC width */ - width: var(--toc-width); - height: calc(100vh - var(--menu-bar-height) - 0.67em * 4); - overflow: auto; + width: var(--pagetoc-width); } .pagetoc a { border-left: 1px solid var(--sidebar-bg); - color: var(--fg) !important; + /* color: var(--fg); */ + /* color: var(--sidebar-fg); */ + color: var(--links); display: block; padding-bottom: 5px; padding-top: 5px; padding-left: 10px; text-align: left; text-decoration: none; + font-weight: normal; + background: var(--sidebar-bg); } .pagetoc a:hover, .pagetoc a.active { background: var(--sidebar-bg); - color: var(--sidebar-fg) !important; - } - .pagetoc .active { - background: var(--sidebar-bg); - color: var(--sidebar-fg); - } - .pagetoc .pagetoc-H2 { - padding-left: 20px; - } - .pagetoc .pagetoc-H3 { - padding-left: 40px; - } - .pagetoc .pagetoc-H4 { - padding-left: 60px; - } -} - -@media print { - .sidetoc { - display: none; + /* color: var(--sidebar-fg); */ + color: var(--sidebar-active); + font-weight: bold; + font-size: var(--pagetoc-fontsize); } } diff --git a/documentation/operators/nym_themes/pagetoc.js b/documentation/operators/nym_themes/pagetoc.js index 490d9e4c31..b11052427e 100644 --- a/documentation/operators/nym_themes/pagetoc.js +++ b/documentation/operators/nym_themes/pagetoc.js @@ -1,114 +1,68 @@ -function forEach(elems, fun) { - Array.prototype.forEach.call(elems, fun); -} - -function getPagetoc(){ - return document.getElementsByClassName("pagetoc")[0] -} - -function getPagetocElems() { - return getPagetoc().children; -} - -function getHeaders(){ - return document.getElementsByClassName("header") -} +// src: https://github.com/JorelAli/mdBook-pagetoc // Un-active everything when you click it -function forPagetocElem(fun) { - forEach(getPagetocElems(), fun); -} - -function getRect(element) { - return element.getBoundingClientRect(); -} - -function overflowTop(container, element) { - return getRect(container).top - getRect(element).top; -} - -function overflowBottom(container, element) { - return getRect(container).bottom - getRect(element).bottom; -} - -var activeHref = location.href; - -var updateFunction = function (elem = undefined) { - var id = elem; - - if (!id && location.href != activeHref) { - activeHref = location.href; - forPagetocElem(function (el) { - if (el.href === activeHref) { - id = el; - } +Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.addEventHandler("click", function() { + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); + el.classList.add("active"); }); - } +}); - if (!id) { - var elements = getHeaders(); - let margin = window.innerHeight / 3; +var updateFunction = function() { - forEach(elements, function (el, i, arr) { - if (!id && getRect(el).top >= 0) { - if (getRect(el).top < margin) { - id = el; - } else { - id = arr[Math.max(0, i - 1)]; + var id; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + if (window.pageYOffset >= el.offsetTop) { + id = el; } - } - // a very long last section - // its heading is over the screen - if (!id && i == arr.length - 1) { - id = el - } }); - } - forPagetocElem(function (el) { - el.classList.remove("active"); - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + el.classList.remove("active"); + }); - if (!id) return; - - forPagetocElem(function (el) { - if (id.href.localeCompare(el.href) == 0) { - el.classList.add("active"); - let pagetoc = getPagetoc(); - if (overflowTop(pagetoc, el) > 0) { - pagetoc.scrollTop = el.offsetTop; - } - if (overflowBottom(pagetoc, el) < 0) { - pagetoc.scrollTop -= overflowBottom(pagetoc, el); - } - } - }); + Array.prototype.forEach.call(document.getElementsByClassName("pagetoc")[0].children, function(el, i) { + if (id.href.localeCompare(el.href) == 0) { + el.classList.add("active"); + } + }); }; -let elements = getHeaders(); +// Populate sidebar on load +window.addEventListener('load', function() { + var pagetoc = document.getElementsByClassName("pagetoc")[0]; + var elements = document.getElementsByClassName("header"); + Array.prototype.forEach.call(elements, function(el, i) { + var link = document.createElement("a"); -if (elements.length > 1) { - // Populate sidebar on load - window.addEventListener("load", function () { - var pagetoc = getPagetoc(); - var elements = getHeaders(); - forEach(elements, function (el) { - var link = document.createElement("a"); - link.appendChild(document.createTextNode(el.text)); - link.href = el.hash; - link.classList.add("pagetoc-" + el.parentElement.tagName); - pagetoc.appendChild(link); - link.onclick = function () { - updateFunction(link); - }; + // Indent shows hierarchy + var indent = ""; + switch (el.parentElement.tagName) { + case "H2": + indent = "20px"; + break; + case "H3": + indent = "40px"; + break; + case "H4": + indent = "60px"; + break; + default: + break; + } + + link.appendChild(document.createTextNode(el.text)); + link.style.paddingLeft = indent; + link.href = el.href; + pagetoc.appendChild(link); }); - updateFunction(); - }); + updateFunction.call(); +}); - // Handle active elements on scroll - window.addEventListener("scroll", function () { - updateFunction(); - }); -} else { - document.getElementsByClassName("sidetoc")[0].remove(); -} + + +// Handle active elements on scroll +window.addEventListener("scroll", updateFunction); From e86419540cac25ae6693aa75cbd0b947a80c2af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 15:34:57 +0000 Subject: [PATCH 019/394] don't try to send empty rewarding txs --- nym-validator-rewarder/src/error.rs | 3 +++ nym-validator-rewarder/src/rewarder/mod.rs | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/nym-validator-rewarder/src/error.rs b/nym-validator-rewarder/src/error.rs index 3d00f0324d..2c78e61fbb 100644 --- a/nym-validator-rewarder/src/error.rs +++ b/nym-validator-rewarder/src/error.rs @@ -163,6 +163,9 @@ pub enum NymRewarderError { #[error("credential issuance rewarding is enabled, but the validator whitelist is empty")] EmptyCredentialIssuanceWhitelist, + + #[error("there were no validators to reward in this epoch")] + NoValidatorsToReward, } #[derive(Debug)] diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index b647522c46..c0c8174175 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -227,6 +227,11 @@ impl Rewarder { return Ok(Hash::Sha256([0u8; 32])); } + if amounts.is_empty() { + warn!("no rewards to send"); + return Err(NymRewarderError::NoValidatorsToReward); + } + info!("sending rewards"); self.nyxd_client .send_rewards(self.current_epoch, amounts) From 2c65460164a8a6f6d790162cbbdceef5991ac280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 16:09:33 +0000 Subject: [PATCH 020/394] additional logs --- nym-validator-rewarder/src/rewarder/block_signing/mod.rs | 9 ++++++++- .../src/rewarder/block_signing/types.rs | 1 + 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs index b87c6efaef..b443364641 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/mod.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/mod.rs @@ -11,7 +11,7 @@ use nyxd_scraper::NyxdScraper; use std::cmp::min; use std::collections::HashMap; use std::ops::Range; -use tracing::{debug, info, warn}; +use tracing::{debug, info, trace, warn}; pub(crate) mod types; @@ -28,6 +28,7 @@ impl EpochSigning { height_range: Range, ) -> Result, NymRewarderError> { for height in height_range { + trace!("attempting to get precommit for {address} at height {height}"); if let Some(precommit) = self .nyxd_scraper .storage @@ -87,6 +88,8 @@ impl EpochSigning { ); let validators = self.nyxd_scraper.storage.get_all_known_validators().await?; + debug!("retrieved {} known validators", validators.len()); + let epoch_start = current_epoch.start_time; let epoch_end = current_epoch.end_time; let first_block = self @@ -111,10 +114,14 @@ impl EpochSigning { // for each validator, with a valid voting power, get number of signed blocks in the rewarding epoch for validator in validators { + let addr = &validator.consensus_address; + debug!("getting voting power and signed blocks of {addr}"); + let Some(vp) = self .get_voting_power(&validator.consensus_address, vp_range.clone()) .await? else { + warn!("failed to obtain voting power of {addr}"); continue; }; diff --git a/nym-validator-rewarder/src/rewarder/block_signing/types.rs b/nym-validator-rewarder/src/rewarder/block_signing/types.rs index 8cf31a5ba5..ebdb24432f 100644 --- a/nym-validator-rewarder/src/rewarder/block_signing/types.rs +++ b/nym-validator-rewarder/src/rewarder/block_signing/types.rs @@ -53,6 +53,7 @@ pub struct EpochSigningResults { pub validators: Vec, } +#[derive(Debug)] pub struct RawValidatorResult { pub signed_blocks: i32, pub voting_power: i64, From 0b46e5b75327e5bd241450996ff611880179e731 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 16:36:37 +0000 Subject: [PATCH 021/394] improved startup log regarding the epoch --- nym-validator-rewarder/src/rewarder/mod.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/nym-validator-rewarder/src/rewarder/mod.rs b/nym-validator-rewarder/src/rewarder/mod.rs index c0c8174175..5d813a11f0 100644 --- a/nym-validator-rewarder/src/rewarder/mod.rs +++ b/nym-validator-rewarder/src/rewarder/mod.rs @@ -304,7 +304,8 @@ impl Rewarder { let until_end = self.current_epoch.until_end(); info!( - "the first epoch will finish in {} secs", + "the initial epoch (id: {}) will finish in {} secs", + self.current_epoch.id, until_end.as_secs() ); let mut epoch_ticker = interval_at( From b6d5f780d2d06397d9ce2c4d137f685549acadd1 Mon Sep 17 00:00:00 2001 From: Stefano Piermatteo Date: Thu, 15 Feb 2024 08:40:36 +0100 Subject: [PATCH 022/394] [DOC]: Add landing page howto (#4378) * add html snippet * add reverse proxy * fix typos fix variables conventions fix markdown * add Avril 14th sentence * fix syntax --- .../operators/src/legal/landing-pages.md | 360 ++++++++++++++++++ 1 file changed, 360 insertions(+) diff --git a/documentation/operators/src/legal/landing-pages.md b/documentation/operators/src/legal/landing-pages.md index a03546919e..5316fdbbc6 100644 --- a/documentation/operators/src/legal/landing-pages.md +++ b/documentation/operators/src/legal/landing-pages.md @@ -7,3 +7,363 @@ The entire content of this page is under [Creative Commons Attribution 4.0 Inter > Nym Node operators are invited to add their legal findings and suggestions directly through [pull requests](add-content.md). Exit Gateway landing page is a great and transparent way to prevent possible troubles by providing people with basic facts, links to laws and regulations on a given topic as well as operator's contact info. To inspire each other we share some examples how Nym community handled this issue below. + +## Avril 14th Exit Gateways + +The following snippet needs be modified as described below according to the public identity that you may want to show on this public notice, i.e. your graphics and your email. +It would allow you to serve it as a landing page resembling the one proposed by [Tor](https://gitlab.torproject.org/tpo/core/tor/-/raw/HEAD/contrib/operator-tools/tor-exit-notice.html) but with all the changes needed to adhere to the Nym's operators case. + +[Avril 14th](https://avril14th.org/) is a team of professionals and optimistic realists eager to contribute to a future of privacy, decentralization and connectivity. + +When done with the customization needs as described below, you'll need to upload the file and reference it as the `landing_page_assets_path` on the `[http]` section of the config.toml file: +``` +landing_page_assets_path = '' +``` + +### HTML file customization + +- add your favicon logo on the line: +``` + +``` + +and your header logo on the line: +``` + +``` + +by either setting the URl to the image (if you're hosting it publicly, i.e. on your web server) +``` +href="" +``` +and +``` +src="" + +``` +**or** by adding the image inline as base64 encoded image +``` +href="href="data:image/x-icon;base64,AAABAAMA...."" +``` +and +``` +src="href="data:image/x-icon;base64,AAABAAMA...."" +``` + + +- add the email address you're willing to use for being contacted. +``` +maintainer +``` + +- If you're running the node within the US check the sections marked as FIXME, add your DNS name and uncomment those. +*** + +```html + + + + +This is a NYM Exit Gateway + + + + + + +
+

This is a NYM Exit Gateway

+

+ +

+ +

+You are most likely accessing this website because you've had some issue with +the traffic coming from this IP. This router is part of the NYM project, which is +dedicated to create outstanding +privacy software that is legally compliant without sacrificing integrity or +having any backdoors. +This router IP should be generating no other traffic, unless it has been +compromised.

+ +

+The Nym mixnet is operated by a decentralised community of node operators +and stakers. The Nym mixnet is trustless, meaning that no parts of the system +nor its operators have access to information that might compromise the privacy +of users. Nym software enacts a strict principle of data minimisation and has +no back doors. The Nym mixnet works by encrypting packets in several layers +and relaying those through a multi-layered network called a mixnet, eventually +letting the traffic exit the Nym mixnet through an exit gateway like this one. +This design makes it very hard for a service to know which user is connecting to it, +since it can only see the IP-address of the Nym exit gateway:

+ +

+ +Illustration showing how a user might connect to a service through the Nym network. The user first sends their data through three daisy-chained encrypted Nym nodes that exist on three different continents. Then the last Nym node in the chain connects to the target service over the normal internet. + + + + + + + + + + + + + + + + + + + + + +The user +This server +Your service +Nym network link +Unencrypted link + + + + + + +

+ +

+Read more about how Nym works.

+ +

+Nym relies on a growing ecosystem of users, developers and researcher partners +aligned with the mission to make sure Nym software is running, remains usable +and solves real problems. While Nym is not designed for malicious computer +users, it is true that they can use the network for malicious ends. This +is largely because criminals and hackers have significantly better access to +privacy and anonymity than do the regular users whom they prey upon. Criminals +can and do build, sell, and trade far larger and more powerful networks than +Nym on a daily basis. Thus, in the mind of this operator, the social need for +easily accessible censorship-resistant private, anonymous communication trumps +the risk of unskilled bad actors, who are almost always more easily uncovered +by traditional police work than by extensive monitoring and surveillance anyway.

+ +

+In terms of applicable law, the best way to understand Nym is to consider it a +network of routers operating as common carriers, much like the Internet +backbone. However, unlike the Internet backbone routers, Nym mixnodes do not +contain identifiable routing information about the source of a packet and do +mix the user internet traffic with that of other users, making communications +private and protecting not just the user content but the metadata +(user's IP address, who the user talks to, when, where, from what device and +more) and no single Nym node can determine both the origin and destination +of a given transmission.

+ +

+As such, there is little the operator of this Exit Gateway can do to help you +track the connection further. This Exit Gateway maintains no logs of any of the +Nym mixnet traffic, so there is little that can be done to trace either legitimate or +illegitimate traffic (or to filter one from the other). Attempts to +seize this router will accomplish nothing.

+ + + + + + +

To decentralise and enable privacy for a broad range of services, this +Exit Gateway adopts an Exit Policy +in accordance with the Tor Null ‘deny’ list +and the Tor reduced policy, +which are two established safeguards. +

+ +

+That being said, if you still have a complaint about the router, you may email the + maintainer. If complaints are related + to a particular service that is being abused, the maintainer will submit that to the + NYM Operators Community in order to add it to the Exit Policy cited above. +If approved, that would prevent this router from allowing that traffic to exit through it. +That can be done only on an IP+destination port basis, however. Common P2P ports are already blocked.

+ +

+You also have the option of blocking this IP address and others on the Nym network if you so desire. + The Nym project provides a + web service to fetch a list of all IP addresses of Nym Gateway Exit nodes that allow exiting to a +specified IP:port combination. Please be considerate when using these options.

+ +
+ + +``` +*** +### Reverse proxy +You may set up a [reverse proxy](https://www.nginx.com/resources/glossary/reverse-proxy-server/) in order to serve this landing page with proper SSL and DNS management, i.e. to resolve it to https://nym-exit. or https://nym-readme.. + +The following assumes that you're owning a domain and that you've already set the Let's Encrypt certificates on your hosting, and you've copied those on your Gateway, i.e. copy the two Let's Encript pem files on your Gateway's home folder. +Else you may obtain a Let's Encrypt certificate using a -[-certonly procedure](https://eff-certbot.readthedocs.io/en/latest/using.html#getting-certificates-and-choosing-plugins). + +``` +sudo apt install nginx +``` +If you're running your Gateway (you should...) exposing only the needed ports as listed [here](https://nymtech.net/operators/nodes/maintenance.html?highlight=port#ports), you need to add the Nginx service to your ufw configuration: +``` +sudo ufw app list +sudo ufw allow 'Nginx Full' +sudo ufw reload +``` +Disable the default Nginx landing page +``` +sudo systemctl status nginx +sudo unlink /etc/nginx/sites-enabled/default +sudo systemctl restart nginx +``` +Add your endpoint configuration to Nginx changing occurrencies below with your domain name, including the top-level domain, i.e. *avril4th.org* + +``` +sudo nano /etc/nginx/sites-available/nym-exit. +``` + +``` +server { + listen 443 ssl http2; + listen [::]:443 ssl http2; + + server_name nym-exit.; + + ssl_certificate /fullchain.pem; + ssl_certificate_key /privkey.pem; + + access_log /var/log/nginx/access.log; + error_log /var/log/nginx/error.log; + + location / { + proxy_pass http://127.0.0.1:8080; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header Host $host; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} + +server { + listen 80; + listen [::]:80; + + if ($host = nym-exit.) { + return 301 https://$host$request_uri; + } + + server_name www.; + + return 301 https://$request_uri; +} +``` + +``` +sudo ln -s /etc/nginx/sites-available/nym-exit. /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl restart nginx +``` + +When done with the customization needs as described below, you'll need to upload the file and reference it as the 'landing_page_assets_path' on the '[http]' section of the config.toml file that you'll find in the .nym folder, +``` +nano ${HOME}/.nym/gateways//config/config.toml +``` +change +``` +landing_page_assets_path = '' +``` + +If you're running the Gateway as a service as described [here](https://nymtech.net/operators/nodes/maintenance.html#systemd) and [here](https://nymtech.net/operators/nodes/maintenance.html#following-steps-for-nym-nodes-running-as-systemd-service) you may just restart your service +``` +service nym-gateway stop +service nym-gateway start +``` +and check for the page being served either checking the service logs +``` +sudo journalctl -u nym-gateway.service | grep 8080 +``` +where you should read out +``` +... Started NymNodeHTTPServer on 0.0.0.0:8080 +``` +or just point your browser to the URI which you set above, such as https://nym-exit. \ No newline at end of file From ecc47cd41832f929484f0d221922abb05e27e695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Thu, 15 Feb 2024 16:06:09 +0100 Subject: [PATCH 023/394] cargo update -p rustls@0.21.7 (#4404) --- Cargo.lock | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5b1cd3706b..0b602f6a58 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3407,7 +3407,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.7", + "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", ] @@ -7985,7 +7985,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-native-certs", "rustls-pemfile", "serde", @@ -8370,12 +8370,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.16.20", + "ring 0.17.4", "rustls-webpki", "sct 0.7.0", ] @@ -8403,12 +8403,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.4", + "untrusted 0.9.0", ] [[package]] @@ -9740,7 +9740,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.10", "tokio", ] @@ -9801,7 +9801,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", + "rustls 0.21.10", "tokio", "tungstenite", ] @@ -10233,7 +10233,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.7", + "rustls 0.21.10", "sha1", "thiserror", "url", From eab7eb03c7c3690e640e742bdd170c4c028fd3b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 16:35:55 +0000 Subject: [PATCH 024/394] reduced tick rate logging --- nym-api/src/coconut/dkg/controller/mod.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/nym-api/src/coconut/dkg/controller/mod.rs b/nym-api/src/coconut/dkg/controller/mod.rs index 8ddac1e80c..fec729e466 100644 --- a/nym-api/src/coconut/dkg/controller/mod.rs +++ b/nym-api/src/coconut/dkg/controller/mod.rs @@ -248,6 +248,14 @@ impl DkgController { Ok(()) } + fn reduced_tick_rate(&self, tick_duration: time::Duration) -> bool { + // make sure to not trigger warnings if say the target rate is 10s, but our last tick took `9s999ms785µs321ns` + // check for 95% of polling rate, so in that case if its below 9s500ms + let target_nanos = self.polling_rate.as_nanos(); + let min = time::Duration::nanoseconds(((target_nanos * 95) / 100) as i64); + tick_duration < min + } + pub(crate) async fn run(mut self, mut shutdown: TaskClient) { let mut interval = interval(self.polling_rate); @@ -263,7 +271,7 @@ impl DkgController { let tick_duration = now - last_polled; last_polled = now; - if tick_duration < self.polling_rate { + if self.reduced_tick_rate(tick_duration) { warn!("it seems the process is running behind. The current tick rate is lower than the polling rate. rate: {:?}, current tick: {}, previous tick: {}", self.polling_rate, tick_duration, last_tick_duration); last_tick_duration = tick_duration; continue From d2c77d7f64fca679f2d419eb1e5890edb573ed03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 11:15:51 +0000 Subject: [PATCH 025/394] integration test for failed DKG redoing --- contracts/Cargo.lock | 3 + contracts/coconut-test/Cargo.toml | 4 + contracts/coconut-test/src/helpers.rs | 10 +- .../src/redoing_upon_threshold.rs | 29 ++ contracts/coconut-test/src/test_wrapper.rs | 418 ++++++++++++++++++ contracts/coconut-test/src/tests.rs | 2 + 6 files changed, 457 insertions(+), 9 deletions(-) create mode 100644 contracts/coconut-test/src/redoing_upon_threshold.rs create mode 100644 contracts/coconut-test/src/test_wrapper.rs diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index bcd4743994..fdab88b8b7 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -178,6 +178,7 @@ dependencies = [ name = "coconut-test" version = "0.1.0" dependencies = [ + "bs58", "cosmwasm-std", "cosmwasm-storage", "cw-controllers", @@ -194,8 +195,10 @@ dependencies = [ "nym-coconut-dkg-common", "nym-group-contract-common", "nym-multisig-contract-common", + "rand_chacha 0.2.2", "schemars", "serde", + "subtle-encoding", "thiserror", ] diff --git a/contracts/coconut-test/Cargo.toml b/contracts/coconut-test/Cargo.toml index b7497b060b..22475dda1f 100644 --- a/contracts/coconut-test/Cargo.toml +++ b/contracts/coconut-test/Cargo.toml @@ -20,6 +20,8 @@ cw-storage-plus = { workspace = true } cw-controllers = { workspace = true } cw-utils = { workspace = true } +subtle-encoding = { version = "0.5", features = ["bech32-preview"] } +bs58 = "0.4.0" schemars = "0.8" serde = { version = "1.0.103", default-features = false, features = ["derive"] } thiserror = { workspace = true } @@ -30,6 +32,8 @@ cw-multi-test = { workspace = true } cw3-flex-multisig = { path = "../multisig/cw3-flex-multisig" } cw4-group = { path = "../multisig/cw4-group" } +rand_chacha = "0.2" + [[test]] name = "coconut-test" path = "src/tests.rs" diff --git a/contracts/coconut-test/src/helpers.rs b/contracts/coconut-test/src/helpers.rs index e0f667612d..df67e9c311 100644 --- a/contracts/coconut-test/src/helpers.rs +++ b/contracts/coconut-test/src/helpers.rs @@ -21,14 +21,6 @@ pub struct MigrateMsg { pub coconut_dkg_address: String, } -#[entry_point] -pub fn migrate(deps: DepsMut<'_>, _env: Env, msg: MigrateMsg) -> Result { - let mut cfg = CONFIG.load(deps.storage)?; - cfg.coconut_bandwidth_addr = deps.api.addr_validate(&msg.coconut_bandwidth_address)?; - CONFIG.save(deps.storage, &cfg)?; - Ok(Default::default()) -} - pub fn mock_app(init_funds: &[Coin]) -> App { AppBuilder::new().build(|router, _, storage| { router @@ -65,7 +57,7 @@ pub fn contract_multisig() -> Box> { cw3_flex_multisig::contract::instantiate, cw3_flex_multisig::contract::query, ) - .with_migrate(migrate); + .with_migrate(cw3_flex_multisig::contract::migrate); Box::new(contract) } diff --git a/contracts/coconut-test/src/redoing_upon_threshold.rs b/contracts/coconut-test/src/redoing_upon_threshold.rs new file mode 100644 index 0000000000..8e196453fe --- /dev/null +++ b/contracts/coconut-test/src/redoing_upon_threshold.rs @@ -0,0 +1,29 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::test_wrapper::TestSetup; +use nym_coconut_dkg_common::types::EpochState; + +#[test] +fn adding_enough_members_causes_dkg_redoing() { + let mut test = TestSetup::new(); + + let member1 = test.add_mock_group_member(None); + let member2 = test.add_mock_group_member(None); + + test.begin_dkg(); + test.full_dummy_dkg(vec![member1, member2], false); + + let member3 = test.add_mock_group_member(None); + let member4 = test.add_mock_group_member(None); + let member5 = test.add_mock_group_member(None); + + test.skip_to_dkg_state_end(); + test.unchecked_advance_dkg_epoch(); + + let epoch = test.epoch(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); +} diff --git a/contracts/coconut-test/src/test_wrapper.rs b/contracts/coconut-test/src/test_wrapper.rs new file mode 100644 index 0000000000..f69dd0737c --- /dev/null +++ b/contracts/coconut-test/src/test_wrapper.rs @@ -0,0 +1,418 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::helpers::{contract_bandwidth, contract_dkg, contract_group, contract_multisig}; +use cosmwasm_std::testing::mock_dependencies; +use cosmwasm_std::{coins, Addr, Api, CanonicalAddr}; +use cw3::{Cw3Contract, ProposalListResponse, Status, Vote}; +use cw4::{Cw4Contract, Member}; +use cw_multi_test::{App, AppBuilder, Executor}; +use cw_utils::{Duration, Threshold}; +use nym_coconut_bandwidth_contract_common::msg::InstantiateMsg as BandwidthInstantiateMsg; +use nym_coconut_dkg_common::dealing::{chunk_dealing, DealingChunkInfo, MAX_DEALING_CHUNK_SIZE}; +use nym_coconut_dkg_common::msg::ExecuteMsg as DkgExecuteMsg; +use nym_coconut_dkg_common::msg::InstantiateMsg as DkgInstantiateMsg; +use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; +use nym_coconut_dkg_common::types::{Epoch, State}; +use nym_group_contract_common::msg::InstantiateMsg as GroupInstantiateMsg; +use nym_multisig_contract_common::msg::InstantiateMsg as MultisigInstantiateMsg; +use nym_multisig_contract_common::msg::MigrateMsg as MultisigMigrateMsg; +use rand_chacha::rand_core::{RngCore, SeedableRng}; +use rand_chacha::ChaCha20Rng; +use subtle_encoding::bech32; + +pub const PREFIX: &str = "n"; +pub const TEST_DENOM: &str = "unym"; + +pub const BANDWIDTH_POOL: &str = "pool"; + +pub const BLOCK_TIME_SECS: u64 = 6; + +pub fn test_rng() -> ChaCha20Rng { + let dummy_seed = [42u8; 32]; + ChaCha20Rng::from_seed(dummy_seed) +} + +pub fn random_address(rng: &mut ChaCha20Rng) -> Addr { + let mut bytes = [0u8; 32]; + rng.fill_bytes(&mut bytes); + + Addr::unchecked(bech32::encode(PREFIX, bytes)) +} + +pub struct TestSetup { + pub app: App, + pub rng: ChaCha20Rng, + pub global_admin: Addr, + + pub multisig_contract: Cw3Contract, + pub group_contract: Cw4Contract, + pub dkg_contract: Addr, + pub bandwidth_contract: Addr, +} + +impl TestSetup { + pub fn new() -> Self { + let mut rng = test_rng(); + + let global_admin = random_address(&mut rng); + let mut app = AppBuilder::new().build(|router, _, storage| { + router + .bank + .init_balance(storage, &global_admin, coins(1000000000000000, TEST_DENOM)) + .unwrap(); + }); + + let group_id = app.store_code(contract_group()); + let multisig_id = app.store_code(contract_multisig()); + let bandwidth_id = app.store_code(contract_bandwidth()); + let dkg_id = app.store_code(contract_dkg()); + + // 1. init group contract + let group_contract = app + .instantiate_contract( + group_id, + global_admin.clone(), + &GroupInstantiateMsg { + admin: Some(global_admin.to_string()), + members: vec![], + }, + &[], + "group contract", + Some(global_admin.to_string()), + ) + .unwrap(); + + // 2. init multisig contract + let multisig_contract = app + .instantiate_contract( + multisig_id, + global_admin.clone(), + &MultisigInstantiateMsg { + group_addr: group_contract.to_string(), + coconut_bandwidth_contract_address: group_contract.to_string(), + coconut_dkg_contract_address: group_contract.to_string(), + threshold: Threshold::AbsolutePercentage { + percentage: "0.67".parse().unwrap(), + }, + max_voting_period: Duration::Time(3600), + executor: None, + proposal_deposit: None, + }, + &[], + "multisig contract", + Some(global_admin.to_string()), + ) + .unwrap(); + + // 3. init bandwidth contract + let bandwidth_contract = app + .instantiate_contract( + bandwidth_id, + global_admin.clone(), + &BandwidthInstantiateMsg { + multisig_addr: multisig_contract.to_string(), + pool_addr: BANDWIDTH_POOL.to_string(), + mix_denom: TEST_DENOM.to_string(), + }, + &[], + "bandwidth contract", + Some(global_admin.to_string()), + ) + .unwrap(); + + // 4. init dkg contract + let dkg_contract = app + .instantiate_contract( + dkg_id, + global_admin.clone(), + &DkgInstantiateMsg { + group_addr: group_contract.to_string(), + multisig_addr: multisig_contract.to_string(), + time_configuration: None, + mix_denom: TEST_DENOM.to_string(), + key_size: 5, + }, + &[], + "dkg contract", + Some(global_admin.to_string()), + ) + .unwrap(); + + // 5.migrate multisig contract with addresses of bandwidth and dkg contracts + app.migrate_contract( + global_admin.clone(), + multisig_contract.clone(), + &MultisigMigrateMsg { + coconut_bandwidth_address: bandwidth_contract.to_string(), + coconut_dkg_address: dkg_contract.to_string(), + }, + multisig_id, + ) + .unwrap(); + + TestSetup { + app, + rng, + global_admin, + multisig_contract: Cw3Contract(multisig_contract), + group_contract: Cw4Contract(group_contract), + dkg_contract, + bandwidth_contract, + } + } + + pub fn random_address(&mut self) -> Addr { + random_address(&mut self.rng) + } + + pub fn next_block(&mut self) { + self.app.update_block(|block| { + block.height += 1; + block.time = block.time.plus_seconds(BLOCK_TIME_SECS); + }) + } + + // if we ever want to expand those tests, those queries should be moved to contract specific structs + // (kinda like what cw4 has) + pub fn dkg_state(&self) -> State { + self.app + .wrap() + .query_wasm_smart(&self.dkg_contract, &DkgQueryMsg::GetState {}) + .unwrap() + } + + pub fn epoch(&self) -> Epoch { + self.app + .wrap() + .query_wasm_smart(&self.dkg_contract, &DkgQueryMsg::GetCurrentEpochState {}) + .unwrap() + } + + // TODO: this will not go beyond first page + pub fn all_proposals(&self) -> ProposalListResponse { + self.app + .wrap() + .query_wasm_smart( + &self.multisig_contract.0, + &nym_multisig_contract_common::msg::QueryMsg::ListProposals { + start_after: None, + limit: None, + }, + ) + .unwrap() + } + + pub fn admin(&self) -> Addr { + self.global_admin.clone() + } + + pub fn add_mock_group_member(&mut self, weight: Option) -> Addr { + let member_addr = self.random_address(); + let weight = weight.unwrap_or(10); + + self.app + .execute_contract( + self.admin(), + self.group_contract.addr(), + &nym_group_contract_common::msg::ExecuteMsg::UpdateMembers { + remove: vec![], + add: vec![Member { + addr: member_addr.to_string(), + weight, + }], + }, + &[], + ) + .unwrap(); + + member_addr + } + + pub fn begin_dkg(&mut self) { + self.app + .execute_contract( + self.admin(), + self.dkg_contract.clone(), + &DkgExecuteMsg::InitiateDkg {}, + &[], + ) + .unwrap(); + } + + pub fn skip_to_dkg_state_end(&mut self) { + let epoch = self.epoch(); + + self.app.update_block(|block| { + block.height += 42; + if let Some(finish_timestamp) = epoch.finish_timestamp { + block.time = finish_timestamp.plus_seconds(BLOCK_TIME_SECS); + } else { + block.time = block.time.plus_seconds(BLOCK_TIME_SECS) + } + }); + } + + pub fn advance_dkg_epoch(&mut self) { + self.skip_to_dkg_state_end(); + self.unchecked_advance_dkg_epoch(); + } + + pub fn unchecked_advance_dkg_epoch(&mut self) { + self.app + .execute_contract( + self.admin(), + self.dkg_contract.clone(), + &DkgExecuteMsg::AdvanceEpochState {}, + &[], + ) + .unwrap(); + } + + pub fn submit_dummy_dkg_keys(&mut self, member: &Addr, resharing: bool) { + let mut bte_key_with_proof = [0u8; 32]; + self.rng.fill_bytes(&mut bte_key_with_proof); + let bte_key_with_proof = bs58::encode(&bte_key_with_proof).into_string(); + + let mut identity_key = [0u8; 32]; + self.rng.fill_bytes(&mut identity_key); + let identity_key = bs58::encode(&identity_key).into_string(); + + let mut announce_address = [0u8; 16]; + self.rng.fill_bytes(&mut announce_address); + let announce_address = bs58::encode(&announce_address).into_string(); + + self.app + .execute_contract( + member.clone(), + self.dkg_contract.clone(), + &DkgExecuteMsg::RegisterDealer { + bte_key_with_proof, + identity_key, + announce_address, + resharing, + }, + &[], + ) + .unwrap(); + } + + pub fn submit_dummy_dealings(&mut self, member: &Addr, resharing: bool) { + let dealings = self.dkg_state().key_size; + + for dealing_index in 0..dealings { + let mut dealing_bytes = vec![0u8; 5000]; + self.rng.fill_bytes(&mut dealing_bytes); + + let chunks = DealingChunkInfo::construct(dealing_bytes.len(), MAX_DEALING_CHUNK_SIZE); + self.app + .execute_contract( + member.clone(), + self.dkg_contract.clone(), + &DkgExecuteMsg::CommitDealingsMetadata { + dealing_index, + chunks, + resharing, + }, + &[], + ) + .unwrap(); + self.next_block(); + + let chunks = chunk_dealing(dealing_index, dealing_bytes, MAX_DEALING_CHUNK_SIZE); + for (_, chunk) in chunks { + self.app + .execute_contract( + member.clone(), + self.dkg_contract.clone(), + &DkgExecuteMsg::CommitDealingsChunk { chunk, resharing }, + &[], + ) + .unwrap(); + self.next_block(); + } + } + } + + pub fn submit_dummy_vk_key(&mut self, member: &Addr, resharing: bool) { + let mut derived_vk = vec![0u8; 256]; + self.rng.fill_bytes(&mut derived_vk); + + let share = bs58::encode(&derived_vk).into_string(); + + self.app + .execute_contract( + member.clone(), + self.dkg_contract.clone(), + &DkgExecuteMsg::CommitVerificationKeyShare { share, resharing }, + &[], + ) + .unwrap(); + } + + pub fn validate_dummy_keys(&mut self, member: &Addr) { + for proposal in self.all_proposals().proposals { + if proposal.status == Status::Open { + self.app + .execute_contract( + member.clone(), + self.multisig_contract.addr(), + &nym_multisig_contract_common::msg::ExecuteMsg::Vote { + proposal_id: proposal.id, + vote: Vote::Yes, + }, + &[], + ) + .unwrap(); + } + } + } + + pub fn finalize_dummy_dkg(&mut self) { + for proposal in self.all_proposals().proposals { + assert_eq!(proposal.status, Status::Passed); + + self.app + .execute_contract( + self.admin(), + self.multisig_contract.addr(), + &nym_multisig_contract_common::msg::ExecuteMsg::Execute { + proposal_id: proposal.id, + }, + &[], + ) + .unwrap(); + } + } + + pub fn full_dummy_dkg(&mut self, members: Vec, resharing: bool) { + for member in &members { + self.submit_dummy_dkg_keys(member, resharing); + self.next_block(); + } + self.advance_dkg_epoch(); + + for member in &members { + self.submit_dummy_dealings(member, resharing); + self.next_block(); + } + self.advance_dkg_epoch(); + + for member in &members { + self.submit_dummy_vk_key(member, resharing); + self.next_block(); + } + self.advance_dkg_epoch(); + + for member in &members { + self.validate_dummy_keys(member); + self.next_block(); + } + self.advance_dkg_epoch(); + + self.finalize_dummy_dkg(); + self.next_block(); + + self.advance_dkg_epoch(); + } +} diff --git a/contracts/coconut-test/src/tests.rs b/contracts/coconut-test/src/tests.rs index 2ba5f4b2e8..3ad7c1bd64 100644 --- a/contracts/coconut-test/src/tests.rs +++ b/contracts/coconut-test/src/tests.rs @@ -3,5 +3,7 @@ mod deposit_and_release; mod helpers; +mod redoing_upon_threshold; mod spend_credential_creates_proposal; mod submit_vk_creates_proposal; +mod test_wrapper; From 629081b5ec77956347d102d68afdc7e5e32c2380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 14 Feb 2024 14:09:03 +0000 Subject: [PATCH 026/394] fixed reset mode not being triggered when enough parties left --- contracts/coconut-dkg/src/epoch_state/transactions.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/coconut-dkg/src/epoch_state/transactions.rs b/contracts/coconut-dkg/src/epoch_state/transactions.rs index 0f06bb381c..6ea62b8251 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions.rs @@ -151,7 +151,7 @@ pub(crate) fn advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result Date: Wed, 14 Feb 2024 14:31:46 +0000 Subject: [PATCH 027/394] moved epoch advancement logic into separate file --- .../coconut-dkg/src/types.rs | 8 +- common/credential-utils/src/utils.rs | 2 +- contracts/coconut-dkg/src/contract.rs | 4 +- .../coconut-dkg/src/dealers/transactions.rs | 4 +- .../coconut-dkg/src/dealings/transactions.rs | 4 +- .../coconut-dkg/src/epoch_state/queries.rs | 4 +- .../transactions/advance_epoch_state.rs | 449 ++++++++++++++++++ .../{transactions.rs => transactions/mod.rs} | 443 +---------------- .../coconut-dkg/src/support/tests/helpers.rs | 1 + .../verification_key_shares/transactions.rs | 26 +- .../src/redoing_upon_threshold.rs | 29 -- .../coconut-test/src/reset_upon_threshold.rs | 65 +++ contracts/coconut-test/src/test_wrapper.rs | 16 +- contracts/coconut-test/src/tests.rs | 2 +- nym-api/src/coconut/comm.rs | 2 +- nym-api/src/coconut/dkg/controller/mod.rs | 2 +- 16 files changed, 575 insertions(+), 486 deletions(-) create mode 100644 contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs rename contracts/coconut-dkg/src/epoch_state/{transactions.rs => transactions/mod.rs} (51%) delete mode 100644 contracts/coconut-test/src/redoing_upon_threshold.rs create mode 100644 contracts/coconut-test/src/reset_upon_threshold.rs diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index c68c1f9515..329c7408b4 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -93,7 +93,9 @@ pub struct Epoch { pub state: EpochState, pub epoch_id: EpochId, pub time_configuration: TimeConfiguration, - pub finish_timestamp: Option, + + #[serde(alias = "finish_timestamp")] + pub deadline: Option, } impl Epoch { @@ -126,12 +128,12 @@ impl Epoch { state, epoch_id, time_configuration, - finish_timestamp: duration.map(|d| current_timestamp.plus_seconds(d)), + deadline: duration.map(|d| current_timestamp.plus_seconds(d)), } } pub fn final_timestamp_secs(&self) -> Option { - let mut finish = self.finish_timestamp?.seconds(); + let mut finish = self.deadline?.seconds(); let time_configuration = self.time_configuration; let mut curr_epoch_state = self.state; while let Some(state) = curr_epoch_state.next() { diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index c937d48fc3..e1e7c09850 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -91,7 +91,7 @@ where .as_secs(); if epoch.state.is_final() { - if let Some(finish_timestamp) = epoch.finish_timestamp { + if let Some(finish_timestamp) = epoch.deadline { if current_timestamp_secs + SAFETY_BUFFER_SECS >= finish_timestamp.seconds() { info!("In the next {} minute(s), a transition will take place in the coconut system. Deposits should be halted in this time for safety reasons.", SAFETY_BUFFER_SECS / 60); exit(0); diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index 1ab567d59c..9937ff820a 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -15,7 +15,7 @@ use crate::epoch_state::queries::{ }; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{ - advance_epoch_state, try_initiate_dkg, try_surpassed_threshold, + try_advance_epoch_state, try_initiate_dkg, try_surpassed_threshold, }; use crate::error::ContractError; use crate::state::queries::query_state; @@ -118,7 +118,7 @@ pub fn execute( try_verify_verification_key_share(deps, info, owner, resharing) } ExecuteMsg::SurpassedThreshold {} => try_surpassed_threshold(deps, env), - ExecuteMsg::AdvanceEpochState {} => advance_epoch_state(deps, env), + ExecuteMsg::AdvanceEpochState {} => try_advance_epoch_state(deps, env), } } diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index 7c47f655d4..8e974379a3 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -81,7 +81,7 @@ pub fn try_add_dealer( pub(crate) mod tests { use super::*; use crate::dealers::storage::current_dealers; - use crate::epoch_state::transactions::{advance_epoch_state, try_initiate_dkg}; + use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; use crate::support::tests::fixtures::dealer_details_fixture; use crate::support::tests::helpers; use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS, GROUP_MEMBERS}; @@ -156,7 +156,7 @@ pub(crate) mod tests { .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); add_fixture_dealer(deps.as_mut()); - advance_epoch_state(deps.as_mut(), env).unwrap(); + try_advance_epoch_state(deps.as_mut(), env).unwrap(); let ret = try_add_dealer( deps.as_mut(), diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index 07b2298bb9..e64c4d575c 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -206,7 +206,7 @@ pub fn try_commit_dealings_chunk( pub(crate) mod tests { use super::*; use crate::epoch_state::storage::CURRENT_EPOCH; - use crate::epoch_state::transactions::{advance_epoch_state, try_initiate_dkg}; + use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; use crate::support::tests::fixtures::{ dealer_details_fixture, dealing_metadata_fixture, partial_dealing_fixture, }; @@ -250,7 +250,7 @@ pub(crate) mod tests { .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); add_fixture_dealer(deps.as_mut()); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let ret = try_commit_dealings_chunk( deps.as_mut(), diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 6c07c65629..b4dc6cd310 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -37,7 +37,7 @@ pub(crate) mod test { let mut deps = init_contract(); let epoch = query_current_epoch(deps.as_mut().storage).unwrap(); assert_eq!(epoch.state, EpochState::WaitingInitialisation); - assert_eq!(epoch.finish_timestamp, None); + assert_eq!(epoch.deadline, None); let env = mock_env(); try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); @@ -48,7 +48,7 @@ pub(crate) mod test { EpochState::PublicKeySubmission { resharing: false } ); assert_eq!( - epoch.finish_timestamp.unwrap(), + epoch.deadline.unwrap(), env.block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs) diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs new file mode 100644 index 0000000000..9aeceb8fe1 --- /dev/null +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -0,0 +1,449 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::dealers::storage::current_dealers; +use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRESHOLD}; +use crate::epoch_state::transactions::{ + dealers_eq_members, replacement_threshold_surpassed, reset_dkg_state, +}; +use crate::error::ContractError; +use crate::state::storage::STATE; +use crate::verification_key_shares::storage::verified_dealers; +use cosmwasm_std::{Addr, DepsMut, Env, Order, Response}; +use nym_coconut_dkg_common::types::{Epoch, EpochState, InitialReplacementData}; + +pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result { + let current_epoch = CURRENT_EPOCH.load(deps.storage)?; + if current_epoch.state == EpochState::WaitingInitialisation { + return Err(ContractError::WaitingInitialisation); + } + + if let Some(finish_timestamp) = current_epoch.deadline { + if finish_timestamp > env.block.time { + return Err(ContractError::EarlyEpochStateAdvancement( + finish_timestamp + .minus_seconds(env.block.time.seconds()) + .seconds(), + )); + } + } + + let next_epoch = if let Some(state) = current_epoch.state.next() { + // We are during DKG process + let mut new_state = state; + if let EpochState::DealingExchange { .. } = state { + let current_dealers = current_dealers() + .keys(deps.storage, None, None, Order::Ascending) + .collect::, _>>()?; + let group_members = + STATE + .load(deps.storage)? + .group_addr + .list_members(&deps.querier, None, None)?; + if current_dealers.len() < group_members.len() { + // If not all group members registered yet, we just stay in the same state until + // they either register or they get kicked out of the group + new_state = current_epoch.state; + } else { + // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; + let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; + THRESHOLD.save(deps.storage, &threshold)?; + } + }; + Epoch::new( + new_state, + current_epoch.epoch_id, + current_epoch.time_configuration, + env.block.time, + ) + } else if dealers_eq_members(&deps)? { + // The dealer set hasn't changed, so we only extend the finish timestamp + // The epoch remains the same, as we use it as key for storing VKs + + // TODO: change that behaviour in the following PR + Epoch::new( + current_epoch.state, + current_epoch.epoch_id, + current_epoch.time_configuration, + env.block.time, + ) + } else { + // Dealer set changed, we need to redo DKG... + let state = if replacement_threshold_surpassed(&deps)? { + // ... in reset mode + INITIAL_REPLACEMENT_DATA.remove(deps.storage); + EpochState::PublicKeySubmission { resharing: false } + } else { + // ... in reshare mode + if INITIAL_REPLACEMENT_DATA.may_load(deps.storage)?.is_some() { + INITIAL_REPLACEMENT_DATA.update::<_, ContractError>(deps.storage, |mut data| { + // TODO: FIXME: for second reshare the added set of dealers won't be allowed to participate + data.initial_height = env.block.height; + Ok(data) + })?; + } else { + let replacement_data = InitialReplacementData { + initial_dealers: verified_dealers(deps.storage)?, + initial_height: env.block.height, + }; + INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; + } + + EpochState::PublicKeySubmission { resharing: true } + }; + reset_dkg_state(deps.storage)?; + Epoch::new( + state, + current_epoch.epoch_id + 1, + current_epoch.time_configuration, + env.block.time, + ) + }; + CURRENT_EPOCH.save(deps.storage, &next_epoch)?; + + Ok(Response::default()) +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::dealers::storage::past_dealers; + use crate::epoch_state::transactions::try_initiate_dkg; + use crate::error::ContractError::EarlyEpochStateAdvancement; + use crate::support::tests::fixtures::{dealer_details_fixture, vk_share_fixture}; + use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS, GROUP_MEMBERS}; + use crate::verification_key_shares::storage::vk_shares; + use cosmwasm_std::testing::{mock_env, mock_info}; + use cw4::Member; + use nym_coconut_dkg_common::types::TimeConfiguration; + + #[test] + fn advance_state() { + let mut deps = init_contract(); + let mut env = mock_env(); + + { + let mut group = GROUP_MEMBERS.lock().unwrap(); + + group.push(( + Member { + addr: "owner1".to_string(), + weight: 10, + }, + 1, + )); + group.push(( + Member { + addr: "owner2".to_string(), + weight: 10, + }, + 1, + )); + group.push(( + Member { + addr: "owner3".to_string(), + weight: 10, + }, + 1, + )); + group.push(( + Member { + addr: "owner4".to_string(), + weight: 10, + }, + 1, + )); + } + + // can't advance the state if dkg hasn't been initiated + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + ContractError::WaitingInitialisation + ); + + try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); + + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); + assert_eq!( + epoch.deadline.unwrap(), + env.block + .time + .plus_seconds(epoch.time_configuration.public_key_submission_time_secs) + ); + + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.public_key_submission_time_secs - 1); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(1) + ); + + env.block.time = env.block.time.plus_seconds(1); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); + + // setup dealer details + let all_shares: [_; 4] = + std::array::from_fn(|i| vk_share_fixture(&format!("owner{}", i + 1), 0)); + for share in all_shares.iter() { + vk_shares() + .save(deps.as_mut().storage, (&share.owner, 0), share) + .unwrap(); + } + let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); + for details in all_details.iter() { + current_dealers() + .save(deps.as_mut().storage, &details.address, details) + .unwrap(); + } + + assert!(INITIAL_REPLACEMENT_DATA + .may_load(&deps.storage) + .unwrap() + .is_none()); + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.public_key_submission_time_secs); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::DealingExchange { resharing: false } + ); + assert_eq!( + epoch.deadline.unwrap(), + env.block + .time + .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs) + ); + + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs - 2); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(2) + ); + + env.block.time = env.block.time.plus_seconds(3); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::VerificationKeySubmission { resharing: false } + ); + assert_eq!( + epoch.deadline.unwrap(), + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_submission_time_secs + ) + ); + + env.block.time = env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_submission_time_secs + - 2, + ); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(2) + ); + + env.block.time = env.block.time.plus_seconds(3); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::VerificationKeyValidation { resharing: false } + ); + assert_eq!( + epoch.deadline.unwrap(), + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_validation_time_secs + ) + ); + + env.block.time = env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_validation_time_secs + - 3, + ); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(3) + ); + + env.block.time = env.block.time.plus_seconds(3); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!( + epoch.state, + EpochState::VerificationKeyFinalization { resharing: false } + ); + assert_eq!( + epoch.deadline.unwrap(), + env.block.time.plus_seconds( + epoch + .time_configuration + .verification_key_finalization_time_secs + ) + ); + + env.block.time = env + .block + .time + .plus_seconds(TimeConfiguration::default().verification_key_finalization_time_secs - 1); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(1) + ); + + env.block.time = env.block.time.plus_seconds(1); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + assert_eq!(epoch.state, EpochState::InProgress); + assert_eq!( + epoch.deadline.unwrap(), + env.block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs) + ); + + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs - 100); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(100) + ); + + env.block.time = env.block.time.plus_seconds(50); + assert_eq!( + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), + EarlyEpochStateAdvancement(50) + ); + + // Group hasn't changed, so we remain in the same epoch, with updated finish timestamp + env.block.time = env.block.time.plus_seconds(100); + let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + let expected_epoch = Epoch::new( + EpochState::InProgress, + prev_epoch.epoch_id, + prev_epoch.time_configuration, + env.block.time, + ); + assert_eq!(curr_epoch, expected_epoch); + + // Group changed slightly, so re-run dkg in reshare mode + *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = ( + Member { + addr: "owner5".to_string(), + weight: 10, + }, + 1, + ); + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs); + let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + let expected_epoch = Epoch::new( + EpochState::PublicKeySubmission { resharing: true }, + prev_epoch.epoch_id + 1, + prev_epoch.time_configuration, + env.block.time, + ); + assert_eq!(curr_epoch, expected_epoch); + assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); + let replacement_data = INITIAL_REPLACEMENT_DATA.load(&deps.storage).unwrap(); + let expected_replacement_data = InitialReplacementData { + initial_dealers: all_details.iter().map(|d| d.address.clone()).collect(), + initial_height: 12345, + }; + assert_eq!(replacement_data, expected_replacement_data); + + let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 2)); + for details in all_details.iter() { + past_dealers() + .remove(deps.as_mut().storage, &details.address) + .unwrap(); + current_dealers() + .save(deps.as_mut().storage, &details.address, details) + .unwrap(); + } + for times in [ + epoch.time_configuration.public_key_submission_time_secs, + epoch.time_configuration.dealing_exchange_time_secs, + epoch + .time_configuration + .verification_key_submission_time_secs, + epoch + .time_configuration + .verification_key_validation_time_secs, + epoch + .time_configuration + .verification_key_finalization_time_secs, + ] { + env.block.time = env.block.time.plus_seconds(times); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + } + + let all_shares: [_; 4] = std::array::from_fn(|i| { + let mut share = vk_share_fixture(&format!("owner{}", i + 1), 1); + share.verified = i % 2 == 0; + share + }); + for share in all_shares.iter() { + vk_shares() + .save(deps.as_mut().storage, (&share.owner, 0), share) + .unwrap(); + } + + // Group changed even more, surpassing threshold, so re-run dkg in reset mode + *GROUP_MEMBERS.lock().unwrap().last_mut().unwrap() = ( + Member { + addr: "owner6".to_string(), + weight: 10, + }, + 1, + ); + env.block.time = env + .block + .time + .plus_seconds(epoch.time_configuration.in_progress_time_secs); + let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); + let expected_epoch = Epoch::new( + EpochState::PublicKeySubmission { resharing: true }, + prev_epoch.epoch_id + 1, + prev_epoch.time_configuration, + env.block.time, + ); + assert_eq!(curr_epoch, expected_epoch); + assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); + } +} diff --git a/contracts/coconut-dkg/src/epoch_state/transactions.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs similarity index 51% rename from contracts/coconut-dkg/src/epoch_state/transactions.rs rename to contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index 6ea62b8251..69c93fa7ac 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -2,13 +2,17 @@ // SPDX-License-Identifier: Apache-2.0 use crate::dealers::storage::{current_dealers, past_dealers}; -use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRESHOLD}; +use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; use crate::state::storage::{DKG_ADMIN, STATE}; use crate::verification_key_shares::storage::verified_dealers; use cosmwasm_std::{Addr, Deps, DepsMut, Env, MessageInfo, Order, Response, Storage}; -use nym_coconut_dkg_common::types::{Epoch, EpochState, InitialReplacementData}; +use nym_coconut_dkg_common::types::{Epoch, EpochState}; + +pub use advance_epoch_state::try_advance_epoch_state; + +pub mod advance_epoch_state; fn reset_dkg_state(storage: &mut dyn Storage) -> Result<(), ContractError> { THRESHOLD.remove(storage); @@ -91,98 +95,6 @@ pub(crate) fn try_initiate_dkg( Ok(Response::default()) } -pub(crate) fn advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result { - let current_epoch = CURRENT_EPOCH.load(deps.storage)?; - if current_epoch.state == EpochState::WaitingInitialisation { - return Err(ContractError::WaitingInitialisation); - } - - if let Some(finish_timestamp) = current_epoch.finish_timestamp { - if finish_timestamp > env.block.time { - return Err(ContractError::EarlyEpochStateAdvancement( - finish_timestamp - .minus_seconds(env.block.time.seconds()) - .seconds(), - )); - } - } - - let next_epoch = if let Some(state) = current_epoch.state.next() { - // We are during DKG process - let mut new_state = state; - if let EpochState::DealingExchange { .. } = state { - let current_dealers = current_dealers() - .keys(deps.storage, None, None, Order::Ascending) - .collect::, _>>()?; - let group_members = - STATE - .load(deps.storage)? - .group_addr - .list_members(&deps.querier, None, None)?; - if current_dealers.len() < group_members.len() { - // If not all group members registered yet, we just stay in the same state until - // they either register or they get kicked out of the group - new_state = current_epoch.state; - } else { - // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; - let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; - THRESHOLD.save(deps.storage, &threshold)?; - } - }; - Epoch::new( - new_state, - current_epoch.epoch_id, - current_epoch.time_configuration, - env.block.time, - ) - } else if dealers_eq_members(&deps)? { - // The dealer set hasn't changed, so we only extend the finish timestamp - // The epoch remains the same, as we use it as key for storing VKs - - // TODO: change that behaviour in the following PR - Epoch::new( - current_epoch.state, - current_epoch.epoch_id, - current_epoch.time_configuration, - env.block.time, - ) - } else { - // Dealer set changed, we need to redo DKG... - let state = if replacement_threshold_surpassed(&deps)? { - // ... in reset mode - INITIAL_REPLACEMENT_DATA.remove(deps.storage); - EpochState::PublicKeySubmission { resharing: false } - } else { - // ... in reshare mode - if INITIAL_REPLACEMENT_DATA.may_load(deps.storage)?.is_some() { - INITIAL_REPLACEMENT_DATA.update::<_, ContractError>(deps.storage, |mut data| { - // TODO: FIXME: for second reshare the added set of dealers won't be allowed to participate - data.initial_height = env.block.height; - Ok(data) - })?; - } else { - let replacement_data = InitialReplacementData { - initial_dealers: verified_dealers(deps.storage)?, - initial_height: env.block.height, - }; - INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; - } - - EpochState::PublicKeySubmission { resharing: true } - }; - reset_dkg_state(deps.storage)?; - Epoch::new( - state, - current_epoch.epoch_id + 1, - current_epoch.time_configuration, - env.block.time, - ) - }; - CURRENT_EPOCH.save(deps.storage, &next_epoch)?; - - Ok(Response::default()) -} - pub(crate) fn try_surpassed_threshold( deps: DepsMut<'_>, env: Env, @@ -209,7 +121,8 @@ pub(crate) fn try_surpassed_threshold( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::error::ContractError::EarlyEpochStateAdvancement; + use crate::epoch_state::storage::INITIAL_REPLACEMENT_DATA; + use crate::epoch_state::transactions::advance_epoch_state::try_advance_epoch_state; use crate::support::tests::fixtures::{dealer_details_fixture, vk_share_fixture}; use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS, GROUP_MEMBERS}; use crate::verification_key_shares::storage::vk_shares; @@ -217,7 +130,9 @@ pub(crate) mod tests { use cosmwasm_std::Addr; use cw4::Member; use cw_controllers::AdminError; - use nym_coconut_dkg_common::types::{DealerDetails, EpochState, TimeConfiguration}; + use nym_coconut_dkg_common::types::{ + DealerDetails, EpochState, InitialReplacementData, TimeConfiguration, + }; use rusty_fork::rusty_fork_test; // Because of the global variable handling group, we need individual process for each test @@ -378,335 +293,7 @@ pub(crate) mod tests { } } - #[test] - fn advance_state() { - let mut deps = init_contract(); - let mut env = mock_env(); - { - let mut group = GROUP_MEMBERS.lock().unwrap(); - - group.push(( - Member { - addr: "owner1".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner2".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner3".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner4".to_string(), - weight: 10, - }, - 1, - )); - } - - // can't advance the state if dkg hasn't been initiated - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - ContractError::WaitingInitialisation - ); - - try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); - - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block - .time - .plus_seconds(epoch.time_configuration.public_key_submission_time_secs) - ); - - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.public_key_submission_time_secs - 1); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(1) - ); - - env.block.time = env.block.time.plus_seconds(1); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); - - // setup dealer details - let all_shares: [_; 4] = - std::array::from_fn(|i| vk_share_fixture(&format!("owner{}", i + 1), 0)); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), share) - .unwrap(); - } - let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); - for details in all_details.iter() { - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } - - assert!(INITIAL_REPLACEMENT_DATA - .may_load(&deps.storage) - .unwrap() - .is_none()); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::DealingExchange { resharing: false } - ); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block - .time - .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs) - ); - - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.dealing_exchange_time_secs - 2); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(2) - ); - - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::VerificationKeySubmission { resharing: false } - ); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_submission_time_secs - ) - ); - - env.block.time = env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_submission_time_secs - - 2, - ); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(2) - ); - - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::VerificationKeyValidation { resharing: false } - ); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_validation_time_secs - ) - ); - - env.block.time = env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_validation_time_secs - - 3, - ); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(3) - ); - - env.block.time = env.block.time.plus_seconds(3); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::VerificationKeyFinalization { resharing: false } - ); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block.time.plus_seconds( - epoch - .time_configuration - .verification_key_finalization_time_secs - ) - ); - - env.block.time = env - .block - .time - .plus_seconds(TimeConfiguration::default().verification_key_finalization_time_secs - 1); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(1) - ); - - env.block.time = env.block.time.plus_seconds(1); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!(epoch.state, EpochState::InProgress); - assert_eq!( - epoch.finish_timestamp.unwrap(), - env.block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs) - ); - - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs - 100); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(100) - ); - - env.block.time = env.block.time.plus_seconds(50); - assert_eq!( - advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), - EarlyEpochStateAdvancement(50) - ); - - // Group hasn't changed, so we remain in the same epoch, with updated finish timestamp - env.block.time = env.block.time.plus_seconds(100); - let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - let expected_epoch = Epoch::new( - EpochState::InProgress, - prev_epoch.epoch_id, - prev_epoch.time_configuration, - env.block.time, - ); - assert_eq!(curr_epoch, expected_epoch); - - // Group changed slightly, so re-run dkg in reshare mode - *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = ( - Member { - addr: "owner5".to_string(), - weight: 10, - }, - 1, - ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs); - let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - let expected_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: true }, - prev_epoch.epoch_id + 1, - prev_epoch.time_configuration, - env.block.time, - ); - assert_eq!(curr_epoch, expected_epoch); - assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); - let replacement_data = INITIAL_REPLACEMENT_DATA.load(&deps.storage).unwrap(); - let expected_replacement_data = InitialReplacementData { - initial_dealers: all_details.iter().map(|d| d.address.clone()).collect(), - initial_height: 12345, - }; - assert_eq!(replacement_data, expected_replacement_data); - - let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 2)); - for details in all_details.iter() { - past_dealers() - .remove(deps.as_mut().storage, &details.address) - .unwrap(); - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } - for times in [ - epoch.time_configuration.public_key_submission_time_secs, - epoch.time_configuration.dealing_exchange_time_secs, - epoch - .time_configuration - .verification_key_submission_time_secs, - epoch - .time_configuration - .verification_key_validation_time_secs, - epoch - .time_configuration - .verification_key_finalization_time_secs, - ] { - env.block.time = env.block.time.plus_seconds(times); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - } - - let all_shares: [_; 4] = std::array::from_fn(|i| { - let mut share = vk_share_fixture(&format!("owner{}", i + 1), 1); - share.verified = i % 2 == 0; - share - }); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), share) - .unwrap(); - } - - // Group changed even more, surpassing threshold, so re-run dkg in reset mode - *GROUP_MEMBERS.lock().unwrap().last_mut().unwrap() = ( - Member { - addr: "owner6".to_string(), - weight: 10, - }, - 1, - ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs); - let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - let expected_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: true }, - prev_epoch.epoch_id + 1, - prev_epoch.time_configuration, - env.block.time, - ); - assert_eq!(curr_epoch, expected_epoch); - assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); - } #[test] fn surpass_threshold() { @@ -779,7 +366,7 @@ pub(crate) mod tests { time_configuration.verification_key_finalization_time_secs, ] { env.block.time = env.block.time.plus_seconds(times); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); } let curr_epoch = CURRENT_EPOCH.load(&deps.storage).unwrap(); assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); @@ -829,7 +416,7 @@ pub(crate) mod tests { let env = mock_env(); let initial_epoch_info = CURRENT_EPOCH.load(&deps.storage).unwrap(); - assert!(initial_epoch_info.finish_timestamp.is_none()); + assert!(initial_epoch_info.deadline.is_none()); // can only be executed by the admin let res = try_initiate_dkg(deps.as_mut(), env.clone(), mock_info("not an admin", &[])) @@ -856,7 +443,7 @@ pub(crate) mod tests { initial_epoch_info.time_configuration ); assert_eq!( - epoch.finish_timestamp.unwrap(), + epoch.deadline.unwrap(), env.block .time .plus_seconds(epoch.time_configuration.public_key_submission_time_secs) @@ -921,7 +508,7 @@ pub(crate) mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env).unwrap(); + try_advance_epoch_state(deps.as_mut(), env).unwrap(); assert_eq!( THRESHOLD.may_load(deps.as_mut().storage).unwrap().unwrap(), 67 diff --git a/contracts/coconut-dkg/src/support/tests/helpers.rs b/contracts/coconut-dkg/src/support/tests/helpers.rs index b6b241dd4a..5117c76841 100644 --- a/contracts/coconut-dkg/src/support/tests/helpers.rs +++ b/contracts/coconut-dkg/src/support/tests/helpers.rs @@ -20,6 +20,7 @@ pub const ADMIN_ADDRESS: &str = "admin address"; pub const GROUP_CONTRACT: &str = "group contract address"; pub const MULTISIG_CONTRACT: &str = "multisig contract address"; +// wtf, why is this a thing? pub(crate) static GROUP_MEMBERS: Mutex> = Mutex::new(Vec::new()); pub fn add_fixture_dealer(deps: DepsMut<'_>) { diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index 8ff202ec04..583d8c5533 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -94,7 +94,7 @@ pub fn try_verify_verification_key_share( #[cfg(test)] mod tests { use super::*; - use crate::epoch_state::transactions::{advance_epoch_state, try_initiate_dkg}; + use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; use crate::support::tests::helpers; use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS, MULTISIG_CONTRACT}; use cosmwasm_std::testing::{mock_env, mock_info}; @@ -117,12 +117,12 @@ mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().dealing_exchange_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let dealer = Addr::unchecked("requester"); let announce_address = String::from("localhost"); let dealer_details = DealerDetails { @@ -182,12 +182,12 @@ mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().dealing_exchange_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let ret = try_commit_verification_key_share( deps.as_mut(), env.clone(), @@ -256,22 +256,22 @@ mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().dealing_exchange_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().verification_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().verification_key_validation_time_secs); - advance_epoch_state(deps.as_mut(), env).unwrap(); + try_advance_epoch_state(deps.as_mut(), env).unwrap(); let ret = try_verify_verification_key_share(deps.as_mut(), info, owner.clone(), false) .unwrap_err(); @@ -304,12 +304,12 @@ mod tests { .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().dealing_exchange_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let dealer_details = DealerDetails { address: Addr::unchecked(&owner), @@ -331,12 +331,12 @@ mod tests { .block .time .plus_seconds(TimeConfiguration::default().verification_key_submission_time_secs); - advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); + try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().verification_key_validation_time_secs); - advance_epoch_state(deps.as_mut(), env).unwrap(); + try_advance_epoch_state(deps.as_mut(), env).unwrap(); try_verify_verification_key_share(deps.as_mut(), multisig_info, owner, false).unwrap(); } diff --git a/contracts/coconut-test/src/redoing_upon_threshold.rs b/contracts/coconut-test/src/redoing_upon_threshold.rs deleted file mode 100644 index 8e196453fe..0000000000 --- a/contracts/coconut-test/src/redoing_upon_threshold.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::test_wrapper::TestSetup; -use nym_coconut_dkg_common::types::EpochState; - -#[test] -fn adding_enough_members_causes_dkg_redoing() { - let mut test = TestSetup::new(); - - let member1 = test.add_mock_group_member(None); - let member2 = test.add_mock_group_member(None); - - test.begin_dkg(); - test.full_dummy_dkg(vec![member1, member2], false); - - let member3 = test.add_mock_group_member(None); - let member4 = test.add_mock_group_member(None); - let member5 = test.add_mock_group_member(None); - - test.skip_to_dkg_state_end(); - test.unchecked_advance_dkg_epoch(); - - let epoch = test.epoch(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); -} diff --git a/contracts/coconut-test/src/reset_upon_threshold.rs b/contracts/coconut-test/src/reset_upon_threshold.rs new file mode 100644 index 0000000000..a36597f666 --- /dev/null +++ b/contracts/coconut-test/src/reset_upon_threshold.rs @@ -0,0 +1,65 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::test_wrapper::TestSetup; +use nym_coconut_dkg_common::types::EpochState; + +#[test] +fn removing_enough_members_causes_dkg_reset() { + let mut test = TestSetup::new(); + + let member1 = test.add_mock_group_member(None); + let member2 = test.add_mock_group_member(None); + let member3 = test.add_mock_group_member(None); + let member4 = test.add_mock_group_member(None); + let member5 = test.add_mock_group_member(None); + + test.begin_dkg(); + test.full_dummy_dkg( + vec![ + member1, + member2, + member3.clone(), + member4.clone(), + member5.clone(), + ], + false, + ); + + test.remove_group_member(&member3); + test.remove_group_member(&member4); + test.remove_group_member(&member5); + + test.skip_to_dkg_state_end(); + test.unchecked_advance_dkg_epoch(); + + let epoch = test.epoch(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); +} + +#[test] +fn adding_enough_members_causes_dkg_reset() { + let mut test = TestSetup::new(); + + let member1 = test.add_mock_group_member(None); + let member2 = test.add_mock_group_member(None); + + test.begin_dkg(); + test.full_dummy_dkg(vec![member1, member2], false); + + let _member3 = test.add_mock_group_member(None); + let _member4 = test.add_mock_group_member(None); + let _member5 = test.add_mock_group_member(None); + + test.skip_to_dkg_state_end(); + test.unchecked_advance_dkg_epoch(); + + let epoch = test.epoch(); + assert_eq!( + epoch.state, + EpochState::PublicKeySubmission { resharing: false } + ); +} diff --git a/contracts/coconut-test/src/test_wrapper.rs b/contracts/coconut-test/src/test_wrapper.rs index f69dd0737c..975fdb531c 100644 --- a/contracts/coconut-test/src/test_wrapper.rs +++ b/contracts/coconut-test/src/test_wrapper.rs @@ -207,6 +207,20 @@ impl TestSetup { self.global_admin.clone() } + pub fn remove_group_member(&mut self, addr: &Addr) { + self.app + .execute_contract( + self.admin(), + self.group_contract.addr(), + &nym_group_contract_common::msg::ExecuteMsg::UpdateMembers { + remove: vec![addr.to_string()], + add: vec![], + }, + &[], + ) + .unwrap(); + } + pub fn add_mock_group_member(&mut self, weight: Option) -> Addr { let member_addr = self.random_address(); let weight = weight.unwrap_or(10); @@ -245,7 +259,7 @@ impl TestSetup { self.app.update_block(|block| { block.height += 42; - if let Some(finish_timestamp) = epoch.finish_timestamp { + if let Some(finish_timestamp) = epoch.deadline { block.time = finish_timestamp.plus_seconds(BLOCK_TIME_SECS); } else { block.time = block.time.plus_seconds(BLOCK_TIME_SECS) diff --git a/contracts/coconut-test/src/tests.rs b/contracts/coconut-test/src/tests.rs index 3ad7c1bd64..4c1310dbb8 100644 --- a/contracts/coconut-test/src/tests.rs +++ b/contracts/coconut-test/src/tests.rs @@ -3,7 +3,7 @@ mod deposit_and_release; mod helpers; -mod redoing_upon_threshold; +mod reset_upon_threshold; mod spend_credential_creates_proposal; mod submit_vk_creates_proposal; mod test_wrapper; diff --git a/nym-api/src/coconut/comm.rs b/nym-api/src/coconut/comm.rs index 6f8a82a462..0cb84fc894 100644 --- a/nym-api/src/coconut/comm.rs +++ b/nym-api/src/coconut/comm.rs @@ -43,7 +43,7 @@ impl CachedEpoch { async fn update(&mut self, epoch: Epoch) -> Result<()> { let now = OffsetDateTime::now_utc(); - let validity_duration = if let Some(epoch_finish) = epoch.finish_timestamp { + let validity_duration = if let Some(epoch_finish) = epoch.deadline { let state_end = OffsetDateTime::from_unix_timestamp(epoch_finish.seconds() as i64).unwrap(); let until_epoch_state_end = state_end - now; diff --git a/nym-api/src/coconut/dkg/controller/mod.rs b/nym-api/src/coconut/dkg/controller/mod.rs index fec729e466..8393b52770 100644 --- a/nym-api/src/coconut/dkg/controller/mod.rs +++ b/nym-api/src/coconut/dkg/controller/mod.rs @@ -236,7 +236,7 @@ impl DkgController { // add a bit of variance so that all apis wouldn't attempt to trigger it at the same time let variance = self.rng.gen_range(0..=60); - if let Some(epoch_finish) = epoch.finish_timestamp { + if let Some(epoch_finish) = epoch.deadline { let now = OffsetDateTime::now_utc(); if now.unix_timestamp() > epoch_finish.seconds() as i64 + variance { // TODO: make sure to not overload validator in case its running slow From 29edc8799afa789bddab5ba5f328a1a5d470bf86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 10:56:01 +0000 Subject: [PATCH 028/394] dkg reset/resharing triggered by admin messages instead --- .../coconut-dkg/src/dealer.rs | 7 + .../coconut-dkg/src/msg.rs | 4 + .../coconut-dkg/src/types.rs | 20 +- contracts/coconut-dkg/src/contract.rs | 5 +- contracts/coconut-dkg/src/dealers/storage.rs | 10 +- .../coconut-dkg/src/dealers/transactions.rs | 9 +- contracts/coconut-dkg/src/dealings/storage.rs | 3 +- .../coconut-dkg/src/epoch_state/storage.rs | 2 + .../transactions/advance_epoch_state.rs | 185 +++++++++++------- .../src/epoch_state/transactions/mod.rs | 60 ++++++ .../coconut-dkg/src/epoch_state/utils.rs | 116 ++++++++++- contracts/coconut-dkg/src/error.rs | 9 + contracts/coconut-dkg/src/lib.rs | 4 + .../src/verification_key_shares/storage.rs | 22 ++- 14 files changed, 372 insertions(+), 84 deletions(-) diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs index 7ee3f91eba..c9dce74993 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs @@ -14,6 +14,13 @@ pub struct DealerDetails { pub assigned_index: NodeIndex, } +#[cw_serde] +pub struct DealerRegistrationDetails { + pub bte_public_key_with_proof: EncodedBTEPublicKeyWithProof, + pub ed25519_identity: String, + pub announce_address: String, +} + #[cw_serde] #[derive(Copy)] pub enum DealerType { diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index e677efd80f..cd18a23efb 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -69,6 +69,10 @@ pub enum ExecuteMsg { SurpassedThreshold {}, AdvanceEpochState {}, + + TriggerReset {}, + + TriggerResharing {}, } #[cw_serde] diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index 329c7408b4..38632bf3a3 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -5,7 +5,7 @@ use cosmwasm_schema::cw_serde; use std::fmt::{Display, Formatter}; use std::str::FromStr; -pub use crate::dealer::{DealerDetails, PagedDealerResponse}; +pub use crate::dealer::{DealerDetails, DealerRegistrationDetails, PagedDealerResponse}; pub use contracts_common::dealings::ContractSafeBytes; pub use cosmwasm_std::{Addr, Coin, Timestamp}; pub use cw4::Cw4Contract; @@ -87,11 +87,28 @@ pub struct State { pub key_size: u32, } +#[cw_serde] +#[derive(Copy, Default)] +pub struct StateProgress { + // ideally we want to have here all group members + pub registered_dealers: u32, + + // we expect registered_dealers * state.key_size number of dealings here (each dealer has to submit key_size number of dealings) + pub submitted_dealings: u32, + + // we expect registered_dealers number of keys here + pub submitted_key_shares: u32, + + // we expect submitted_key_shares number of verified keys here + pub verified_keys: u32, +} + #[cw_serde] #[derive(Copy, Default)] pub struct Epoch { pub state: EpochState, pub epoch_id: EpochId, + pub state_progress: StateProgress, pub time_configuration: TimeConfiguration, #[serde(alias = "finish_timestamp")] @@ -127,6 +144,7 @@ impl Epoch { Epoch { state, epoch_id, + state_progress: Default::default(), time_configuration, deadline: duration.map(|d| current_timestamp.plus_seconds(d)), } diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index 9937ff820a..b01e6828ba 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -15,7 +15,8 @@ use crate::epoch_state::queries::{ }; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{ - try_advance_epoch_state, try_initiate_dkg, try_surpassed_threshold, + try_advance_epoch_state, try_initiate_dkg, try_surpassed_threshold, try_trigger_reset, + try_trigger_resharing, }; use crate::error::ContractError; use crate::state::queries::query_state; @@ -119,6 +120,8 @@ pub fn execute( } ExecuteMsg::SurpassedThreshold {} => try_surpassed_threshold(deps, env), ExecuteMsg::AdvanceEpochState {} => try_advance_epoch_state(deps, env), + ExecuteMsg::TriggerReset {} => try_trigger_reset(deps, env, info), + ExecuteMsg::TriggerResharing {} => try_trigger_resharing(deps, env, info), } } diff --git a/contracts/coconut-dkg/src/dealers/storage.rs b/contracts/coconut-dkg/src/dealers/storage.rs index b6c2c1f8bb..3204a0c2f6 100644 --- a/contracts/coconut-dkg/src/dealers/storage.rs +++ b/contracts/coconut-dkg/src/dealers/storage.rs @@ -1,9 +1,10 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::Dealer; use cosmwasm_std::{Addr, StdResult, Storage}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Item, UniqueIndex}; -use nym_coconut_dkg_common::types::{DealerDetails, NodeIndex}; +use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; +use nym_coconut_dkg_common::types::{DealerDetails, DealerRegistrationDetails, EpochId, NodeIndex}; const CURRENT_DEALERS_PK: &str = "crd"; const PAST_DEALERS_PK: &str = "ptd"; @@ -14,6 +15,11 @@ pub(crate) const DEALERS_PAGE_DEFAULT_LIMIT: u32 = 50; pub(crate) const NODE_INDEX_COUNTER: Item = Item::new("node_index_counter"); +// TODO: +pub(crate) const DEALERS_INDICES: Map = Map::new("dealer_index"); +pub(crate) const EPOCH_DEALERS_MAP: Map<(EpochId, Dealer), DealerRegistrationDetails> = + Map::new("epoch_dealers"); + pub(crate) type IndexedDealersMap<'a> = IndexedMap<'a, &'a Addr, DealerDetails, DealersIndex<'a>>; pub(crate) struct DealersIndex<'a> { diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index 8e974379a3..01507b3dce 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -2,11 +2,11 @@ // SPDX-License-Identifier: Apache-2.0 use crate::dealers::storage as dealers_storage; -use crate::epoch_state::storage::INITIAL_REPLACEMENT_DATA; +use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA}; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; use crate::state::storage::STATE; -use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response}; +use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response, StdResult}; use nym_coconut_dkg_common::types::{DealerDetails, EncodedBTEPublicKeyWithProof, EpochState}; // currently we only require that @@ -73,6 +73,11 @@ pub fn try_add_dealer( assigned_index: node_index, }; dealers_storage::current_dealers().save(deps.storage, &info.sender, &dealer_details)?; + CURRENT_EPOCH.update(deps.storage, |epoch| -> StdResult<_> { + let mut updated_epoch = epoch; + updated_epoch.state_progress.registered_dealers += 1; + Ok(updated_epoch) + })?; Ok(Response::new().add_attribute("node_index", node_index.to_string())) } diff --git a/contracts/coconut-dkg/src/dealings/storage.rs b/contracts/coconut-dkg/src/dealings/storage.rs index 2f242741e7..187d84bc6e 100644 --- a/contracts/coconut-dkg/src/dealings/storage.rs +++ b/contracts/coconut-dkg/src/dealings/storage.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::ContractError; +use crate::Dealer; use cosmwasm_std::{Addr, Storage}; use cw_storage_plus::{Key, Map, Path, PrimaryKey}; use nym_coconut_dkg_common::dealing::{DealingMetadata, PartialContractDealing}; @@ -9,8 +10,6 @@ use nym_coconut_dkg_common::types::{ ChunkIndex, ContractSafeBytes, DealingIndex, EpochId, PartialContractDealingData, }; -type Dealer<'a> = &'a Addr; - /// Metadata for a dealing for given `EpochId`, submitted by particular `Dealer` for given `DealingIndex`. pub(crate) const DEALINGS_METADATA: Map<(EpochId, Dealer, DealingIndex), DealingMetadata> = Map::new("dealings_metadata"); diff --git a/contracts/coconut-dkg/src/epoch_state/storage.rs b/contracts/coconut-dkg/src/epoch_state/storage.rs index d146f5894a..36d3b7bd91 100644 --- a/contracts/coconut-dkg/src/epoch_state/storage.rs +++ b/contracts/coconut-dkg/src/epoch_state/storage.rs @@ -6,5 +6,7 @@ use nym_coconut_dkg_common::types::{Epoch, InitialReplacementData}; pub(crate) const CURRENT_EPOCH: Item<'_, Epoch> = Item::new("current_epoch"); pub const THRESHOLD: Item = Item::new("threshold"); + +#[deprecated] pub const INITIAL_REPLACEMENT_DATA: Item = Item::new("initial_replacement_data"); diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs index 9aeceb8fe1..f3384e84e6 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -6,18 +6,28 @@ use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRES use crate::epoch_state::transactions::{ dealers_eq_members, replacement_threshold_surpassed, reset_dkg_state, }; +use crate::epoch_state::utils::{check_state_completion, needs_reset, needs_resharing}; use crate::error::ContractError; use crate::state::storage::STATE; use crate::verification_key_shares::storage::verified_dealers; -use cosmwasm_std::{Addr, DepsMut, Env, Order, Response}; +use cosmwasm_std::{Addr, Deps, DepsMut, Env, Order, Response}; use nym_coconut_dkg_common::types::{Epoch, EpochState, InitialReplacementData}; -pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result { - let current_epoch = CURRENT_EPOCH.load(deps.storage)?; +fn ensure_can_advance_state( + deps: Deps<'_>, + env: &Env, + current_epoch: &Epoch, +) -> Result<(), ContractError> { if current_epoch.state == EpochState::WaitingInitialisation { return Err(ContractError::WaitingInitialisation); } + // check if we completed the state, so we could short circuit the deadline + if check_state_completion(deps.storage, current_epoch)? { + return Ok(()); + } + + // otherwise fallback to the deadline if let Some(finish_timestamp) = current_epoch.deadline { if finish_timestamp > env.block.time { return Err(ContractError::EarlyEpochStateAdvancement( @@ -28,80 +38,111 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result, _>>()?; - let group_members = - STATE - .load(deps.storage)? - .group_addr - .list_members(&deps.querier, None, None)?; - if current_dealers.len() < group_members.len() { - // If not all group members registered yet, we just stay in the same state until - // they either register or they get kicked out of the group - new_state = current_epoch.state; - } else { - // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; - let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; - THRESHOLD.save(deps.storage, &threshold)?; - } - }; - Epoch::new( - new_state, - current_epoch.epoch_id, - current_epoch.time_configuration, - env.block.time, - ) - } else if dealers_eq_members(&deps)? { - // The dealer set hasn't changed, so we only extend the finish timestamp - // The epoch remains the same, as we use it as key for storing VKs + Ok(()) +} - // TODO: change that behaviour in the following PR - Epoch::new( - current_epoch.state, - current_epoch.epoch_id, - current_epoch.time_configuration, - env.block.time, - ) - } else { - // Dealer set changed, we need to redo DKG... - let state = if replacement_threshold_surpassed(&deps)? { - // ... in reset mode - INITIAL_REPLACEMENT_DATA.remove(deps.storage); - EpochState::PublicKeySubmission { resharing: false } - } else { - // ... in reshare mode - if INITIAL_REPLACEMENT_DATA.may_load(deps.storage)?.is_some() { - INITIAL_REPLACEMENT_DATA.update::<_, ContractError>(deps.storage, |mut data| { - // TODO: FIXME: for second reshare the added set of dealers won't be allowed to participate - data.initial_height = env.block.height; - Ok(data) - })?; - } else { - let replacement_data = InitialReplacementData { - initial_dealers: verified_dealers(deps.storage)?, - initial_height: env.block.height, - }; - INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; - } +pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result { + // TODO: the only case where this can retrigger itself is when insufficient number of parties completed it, i.e. we don't have threshold - EpochState::PublicKeySubmission { resharing: true } - }; - reset_dkg_state(deps.storage)?; - Epoch::new( - state, - current_epoch.epoch_id + 1, - current_epoch.time_configuration, - env.block.time, - ) + let current_epoch = CURRENT_EPOCH.load(deps.storage)?; + + // checks whether the given phase has either completed or reached its deadline + ensure_can_advance_state(deps.as_ref(), &env, ¤t_epoch)?; + + let next_state = match current_epoch.state.next() { + Some(next_state) => next_state, + None => { + debug_assert!(current_epoch.state.is_in_progress()); + // TODO: that's for the future because it will involve more changes in the other bits of the codebase + // but change epoch_id upon extending time of the "in progress" phase and instead store a map of + // [current_epoch_id => epoch_id_of_keys_creation] for key retrieval + EpochState::InProgress + } }; + + // update the epoch state + let mut next_epoch = current_epoch; + next_epoch.state = next_state; CURRENT_EPOCH.save(deps.storage, &next_epoch)?; - Ok(Response::default()) + Ok(Response::new()) + + // + // + // let next_epoch = if let Some(state) = current_epoch.state.next() { + // // We are during DKG process + // let mut new_state = state; + // if let EpochState::DealingExchange { .. } = state { + // let current_dealers = current_dealers() + // .keys(deps.storage, None, None, Order::Ascending) + // .collect::, _>>()?; + // let group_members = + // STATE + // .load(deps.storage)? + // .group_addr + // .list_members(&deps.querier, None, None)?; + // if current_dealers.len() < group_members.len() { + // // If not all group members registered yet, we just stay in the same state until + // // they either register or they get kicked out of the group + // new_state = current_epoch.state; + // } else { + // // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; + // let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; + // THRESHOLD.save(deps.storage, &threshold)?; + // } + // }; + // Epoch::new( + // new_state, + // current_epoch.epoch_id, + // current_epoch.time_configuration, + // env.block.time, + // ) + // } else if dealers_eq_members(&deps)? { + // // The dealer set hasn't changed, so we only extend the finish timestamp + // // The epoch remains the same, as we use it as key for storing VKs + // + // // TODO: change that behaviour in the following PR + // Epoch::new( + // current_epoch.state, + // current_epoch.epoch_id, + // current_epoch.time_configuration, + // env.block.time, + // ) + // } else { + // // Dealer set changed, we need to redo DKG... + // let state = if replacement_threshold_surpassed(&deps)? { + // // ... in reset mode + // INITIAL_REPLACEMENT_DATA.remove(deps.storage); + // EpochState::PublicKeySubmission { resharing: false } + // } else { + // // ... in reshare mode + // if INITIAL_REPLACEMENT_DATA.may_load(deps.storage)?.is_some() { + // INITIAL_REPLACEMENT_DATA.update::<_, ContractError>(deps.storage, |mut data| { + // // TODO: FIXME: for second reshare the added set of dealers won't be allowed to participate + // data.initial_height = env.block.height; + // Ok(data) + // })?; + // } else { + // let replacement_data = InitialReplacementData { + // initial_dealers: verified_dealers(deps.storage)?, + // initial_height: env.block.height, + // }; + // INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; + // } + // + // EpochState::PublicKeySubmission { resharing: true } + // }; + // reset_dkg_state(deps.storage)?; + // Epoch::new( + // state, + // current_epoch.epoch_id + 1, + // current_epoch.time_configuration, + // env.block.time, + // ) + // }; + // CURRENT_EPOCH.save(deps.storage, &next_epoch)?; + // + // Ok(Response::default()) } #[cfg(test)] diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index 69c93fa7ac..4b5a087dda 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -8,6 +8,7 @@ use crate::error::ContractError; use crate::state::storage::{DKG_ADMIN, STATE}; use crate::verification_key_shares::storage::verified_dealers; use cosmwasm_std::{Addr, Deps, DepsMut, Env, MessageInfo, Order, Response, Storage}; +use cw4::Member; use nym_coconut_dkg_common::types::{Epoch, EpochState}; pub use advance_epoch_state::try_advance_epoch_state; @@ -16,6 +17,8 @@ pub mod advance_epoch_state; fn reset_dkg_state(storage: &mut dyn Storage) -> Result<(), ContractError> { THRESHOLD.remove(storage); + + // TODO: unbounded query. to be removed be preserving dealer details and changing storage structure let dealers: Vec<_> = current_dealers() .keys(storage, None, None, Order::Ascending) .collect::>()?; @@ -46,6 +49,7 @@ fn dealers_still_active( Ok(still_active) } +#[deprecated] fn dealers_eq_members(deps: &DepsMut<'_>) -> Result { let verified_dealers = verified_dealers(deps.storage)?; let all_dealers = verified_dealers.len(); @@ -118,6 +122,62 @@ pub(crate) fn try_surpassed_threshold( Ok(Response::default()) } +pub(crate) fn try_trigger_reset( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, +) -> Result { + // only the admin is allowed to trigger DKG reset + DKG_ADMIN.assert_admin(deps.as_ref(), &info.sender)?; + let current_epoch = CURRENT_EPOCH.load(deps.storage)?; + + // only allow reset when the DKG exchange isn't in progress + if !current_epoch.state.is_in_progress() { + return Err(ContractError::CantReshareDuringExchange); + } + + let next_epoch = Epoch::new( + EpochState::PublicKeySubmission { resharing: false }, + current_epoch.epoch_id + 1, + current_epoch.time_configuration, + env.block.time, + ); + CURRENT_EPOCH.save(deps.storage, &next_epoch)?; + + // TODO: remove + reset_dkg_state(deps.storage)?; + + Ok(Response::default()) +} + +pub(crate) fn try_trigger_resharing( + deps: DepsMut<'_>, + env: Env, + info: MessageInfo, +) -> Result { + // only the admin is allowed to trigger DKG resharing + DKG_ADMIN.assert_admin(deps.as_ref(), &info.sender)?; + let current_epoch = CURRENT_EPOCH.load(deps.storage)?; + + // only allow resharing when the DKG exchange isn't in progress + if !current_epoch.state.is_in_progress() { + return Err(ContractError::CantReshareDuringExchange); + } + + let next_epoch = Epoch::new( + EpochState::PublicKeySubmission { resharing: true }, + current_epoch.epoch_id + 1, + current_epoch.time_configuration, + env.block.time, + ); + CURRENT_EPOCH.save(deps.storage, &next_epoch)?; + + // TODO: remove + reset_dkg_state(deps.storage)?; + + Ok(Response::default()) +} + #[cfg(test)] pub(crate) mod tests { use super::*; diff --git a/contracts/coconut-dkg/src/epoch_state/utils.rs b/contracts/coconut-dkg/src/epoch_state/utils.rs index 927f857877..be69318e49 100644 --- a/contracts/coconut-dkg/src/epoch_state/utils.rs +++ b/contracts/coconut-dkg/src/epoch_state/utils.rs @@ -1,10 +1,120 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::epoch_state::storage::CURRENT_EPOCH; use crate::error::ContractError; -use cosmwasm_std::Storage; -use nym_coconut_dkg_common::types::EpochState; +use crate::state::storage::STATE; +use crate::verification_key_shares::storage::{dealers, verified_dealers}; +use cosmwasm_std::{Addr, Deps, StdResult, Storage}; +use cw4::Member; +use nym_coconut_dkg_common::types::{Epoch, EpochState}; + +fn all_group_members(deps: &Deps) -> Result, ContractError> { + // the maximum limit for members queries is 30. + // if we're ever thinking of going beyond it, we should fix it properly + // by the DKG contract owning the group contract (i.e. init inside init) + // and proxying all member changes and thus memoizing the members. + // alternatively by adding hooks to the contract to inform us about any changes + let members = + STATE + .load(deps.storage)? + .group_addr + .list_members(&deps.querier, None, Some(30))?; + + // if we're at the limit... + if members.len() == 30 { + return Err(ContractError::PossiblyIncompleteGroupMembersQuery); + } + + Ok(members) +} + +// check if we completed the state, so we could short circuit the deadline +pub(crate) fn check_state_completion( + storage: &dyn Storage, + epoch: &Epoch, +) -> Result { + let contract_state = STATE.load(storage)?; + + match epoch.state { + EpochState::WaitingInitialisation => Ok(false), + // to check this one we'd need to query for all group members, but we can't rely on this + EpochState::PublicKeySubmission { .. } => Ok(false), + + // if every dealer has submitted all dealings, we're done + EpochState::DealingExchange { .. } => { + let expected_dealings = + contract_state.key_size * epoch.state_progress.registered_dealers; + Ok(expected_dealings == epoch.state_progress.submitted_dealings) + } + + // if every dealer has submitted its partial key, we're done + EpochState::VerificationKeySubmission { .. } => Ok(epoch + .state_progress + .submitted_key_shares + == epoch.state_progress.registered_dealers), + + // no short-circuiting this one since the voting is happening in the multisig contract + EpochState::VerificationKeyValidation { .. } => Ok(false), + + // if every submitted partial key has been verified, we're done + EpochState::VerificationKeyFinalization { .. } => { + Ok(epoch.state_progress.verified_keys == epoch.state_progress.submitted_key_shares) + } + EpochState::InProgress => Ok(false), + } +} + +/// Checks whether the DKG needs to undergo full reset. +/// This is determined by whether the initial set of validator changed by more than a threshold number +/// of parties joining or leaving. +pub(crate) fn needs_reset(deps: Deps) -> Result { + let current_state = CURRENT_EPOCH.load(deps.storage)?.state; + + // there is a theoretical edge case where we add/remove an extra member during an in-progress exchange + // thus possibly needing reset immediately after it's done. an optimization would be to just scrap it and start it over + // but since members are added manually, we don't have to worry about it too much for now. + if !current_state.is_in_progress() { + return Err(ContractError::CantResetDuringExchange); + } + + let group_members = all_group_members(&deps)?; + + // below threshold => must reset since we can't do anything + + todo!() +} + +/// Checks whether the DKG needs to undergo resharing. +/// This is determined by whether any new group members has joined the associated group contract +pub(crate) fn needs_resharing(deps: Deps) -> Result { + let current_state = CURRENT_EPOCH.load(deps.storage)?.state; + + // there is a theoretical edge case where we add an extra member during an in-progress exchange + // thus needing resharing immediately after it's done. an optimization would be to just scrap it and start it over + // but since members are added manually, we don't have to worry about it too much for now. + if !current_state.is_in_progress() { + return Err(ContractError::CantReshareDuringExchange); + } + + // TODO: we need cw4 hooks here to resolve those expensive queries + let group_members = all_group_members(&deps)?; + let epoch_dealers = dealers(deps.storage)?; + + // if somebody has been a dealer, but hasn't been verified, tough luck + // we only allow for resharing for new members + + // check if we have any new members + for member in group_members { + if !epoch_dealers.contains_key(&Addr::unchecked(member.addr)) { + return Ok(true); + } + } + + // TODO: something about reset here + + Ok(false) +} pub(crate) fn check_epoch_state( storage: &dyn Storage, diff --git a/contracts/coconut-dkg/src/error.rs b/contracts/coconut-dkg/src/error.rs index af28f920b7..743f3b80df 100644 --- a/contracts/coconut-dkg/src/error.rs +++ b/contracts/coconut-dkg/src/error.rs @@ -136,4 +136,13 @@ pub enum ContractError { value: String, error_message: String, }, + + #[error("cannot perform DKG reset during an ongoing exchange")] + CantResetDuringExchange, + + #[error("cannot perform DKG resharing during an ongoing exchange")] + CantReshareDuringExchange, + + #[error("retrieved the maximum allowed number of cw4 members. for more the contracts have to be refactored")] + PossiblyIncompleteGroupMembersQuery, } diff --git a/contracts/coconut-dkg/src/lib.rs b/contracts/coconut-dkg/src/lib.rs index de93fa7b92..ca3cf4898a 100644 --- a/contracts/coconut-dkg/src/lib.rs +++ b/contracts/coconut-dkg/src/lib.rs @@ -1,6 +1,10 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use cosmwasm_std::Addr; + +pub(crate) type Dealer<'a> = &'a Addr; + mod constants; pub mod contract; mod dealers; diff --git a/contracts/coconut-dkg/src/verification_key_shares/storage.rs b/contracts/coconut-dkg/src/verification_key_shares/storage.rs index 7c65518df4..0951069e95 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/storage.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/storage.rs @@ -4,10 +4,11 @@ use crate::constants::{VK_SHARES_EPOCH_ID_IDX_NAMESPACE, VK_SHARES_PK_NAMESPACE}; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::error::ContractError; -use cosmwasm_std::{Addr, Order, Storage}; +use cosmwasm_std::{Addr, Order, StdResult, Storage}; use cw_storage_plus::{Index, IndexList, IndexedMap, MultiIndex}; use nym_coconut_dkg_common::types::EpochId; use nym_coconut_dkg_common::verification_key::ContractVKShare; +use std::collections::HashMap; pub(crate) const VERIFICATION_KEY_SHARES_PAGE_MAX_LIMIT: u32 = 75; pub(crate) const VERIFICATION_KEY_SHARES_PAGE_DEFAULT_LIMIT: u32 = 50; @@ -36,6 +37,10 @@ pub(crate) fn vk_shares<'a>() -> IndexedMap<'a, VKShareKey<'a>, ContractVKShare, IndexedMap::new(VK_SHARES_PK_NAMESPACE, indexes) } +// TODO: this is a ticking time bomb and will cause us headache when we start running out of gas... again... +// not sure how to fix it yet... +// maybe by completely removing it by relying on cw4 hooks? +#[deprecated] pub(crate) fn verified_dealers(storage: &dyn Storage) -> Result, ContractError> { let epoch_id = CURRENT_EPOCH.load(storage)?.epoch_id; Ok(vk_shares() @@ -53,3 +58,18 @@ pub(crate) fn verified_dealers(storage: &dyn Storage) -> Result, Contr }) .collect()) } + +// TODO: this is a ticking time bomb and will cause us headache when we start running out of gas... again... +// not sure how to fix it yet... +// maybe by completely removing it by relying on cw4 hooks? +pub(crate) fn dealers(storage: &dyn Storage) -> Result, ContractError> { + let epoch_id = CURRENT_EPOCH.load(storage)?.epoch_id; + + Ok(vk_shares() + .idx + .epoch_id + .prefix(epoch_id) + .range(storage, None, None, Order::Ascending) + .map(|maybe_share| maybe_share.map(|(_, v)| (v.owner, v.verified))) + .collect::>()?) +} From 27554f52e350a00a69131a175b77ea7989d53fb9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 11:47:17 +0000 Subject: [PATCH 029/394] revamped dealers storage structure (for txs) --- .../nyxd/contract_traits/dkg_query_client.rs | 4 +- .../coconut-dkg/src/msg.rs | 3 +- .../coconut-dkg/src/types.rs | 6 -- contracts/coconut-dkg/src/contract.rs | 15 ++- contracts/coconut-dkg/src/dealers/queries.rs | 82 +++++++------- contracts/coconut-dkg/src/dealers/storage.rs | 99 ++++++++++++----- .../coconut-dkg/src/dealers/transactions.rs | 65 ++++------- contracts/coconut-dkg/src/dealings/storage.rs | 2 +- .../coconut-dkg/src/dealings/transactions.rs | 38 +++---- .../coconut-dkg/src/epoch_state/queries.rs | 10 +- .../coconut-dkg/src/epoch_state/storage.rs | 6 +- .../transactions/advance_epoch_state.rs | 102 +++--------------- .../src/epoch_state/transactions/mod.rs | 98 +++-------------- .../coconut-dkg/src/epoch_state/utils.rs | 75 +------------ contracts/coconut-dkg/src/error.rs | 4 +- .../src/verification_key_shares/storage.rs | 46 +------- .../verification_key_shares/transactions.rs | 8 +- 17 files changed, 201 insertions(+), 462 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index 5a3c019396..80cac432c9 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -17,9 +17,7 @@ pub use nym_coconut_dkg_common::{ DealingMetadataResponse, DealingStatusResponse, }, msg::QueryMsg as DkgQueryMsg, - types::{ - DealerDetails, DealingIndex, Epoch, EpochId, EpochState, InitialReplacementData, State, - }, + types::{DealerDetails, DealingIndex, Epoch, EpochId, EpochState, State}, verification_key::{ContractVKShare, PagedVKSharesResponse, VkShareResponse}, }; diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index cd18a23efb..d8a35d9ef3 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -16,7 +16,7 @@ use crate::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, DealingMetadataResponse, DealingStatusResponse, }, - types::{Epoch, InitialReplacementData, State}, + types::{Epoch, State}, verification_key::{PagedVKSharesResponse, VkShareResponse}, }; #[cfg(feature = "schema")] @@ -53,7 +53,6 @@ pub enum ExecuteMsg { CommitDealingsChunk { chunk: PartialContractDealing, - resharing: bool, }, CommitVerificationKeyShare { diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index 38632bf3a3..bd0f1d4e1a 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -21,12 +21,6 @@ pub type DealingIndex = u32; pub type ChunkIndex = u16; pub type PartialContractDealingData = ContractSafeBytes; -#[cw_serde] -pub struct InitialReplacementData { - pub initial_dealers: Vec, - pub initial_height: u64, -} - #[cw_serde] #[derive(Copy)] pub struct TimeConfiguration { diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index b01e6828ba..02189255bb 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -10,13 +10,10 @@ use crate::dealings::queries::{ query_dealing_metadata, query_dealing_status, }; use crate::dealings::transactions::{try_commit_dealings_chunk, try_submit_dealings_metadata}; -use crate::epoch_state::queries::{ - query_current_epoch, query_current_epoch_threshold, query_initial_dealers, -}; +use crate::epoch_state::queries::{query_current_epoch, query_current_epoch_threshold}; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{ - try_advance_epoch_state, try_initiate_dkg, try_surpassed_threshold, try_trigger_reset, - try_trigger_resharing, + try_advance_epoch_state, try_initiate_dkg, try_trigger_reset, try_trigger_resharing, }; use crate::error::ContractError; use crate::state::queries::query_state; @@ -109,8 +106,8 @@ pub fn execute( chunks, resharing, } => try_submit_dealings_metadata(deps, info, dealing_index, chunks, resharing), - ExecuteMsg::CommitDealingsChunk { chunk, resharing } => { - try_commit_dealings_chunk(deps, env, info, chunk, resharing) + ExecuteMsg::CommitDealingsChunk { chunk } => { + try_commit_dealings_chunk(deps, env, info, chunk) } ExecuteMsg::CommitVerificationKeyShare { share, resharing } => { try_commit_verification_key_share(deps, env, info, share, resharing) @@ -118,7 +115,7 @@ pub fn execute( ExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => { try_verify_verification_key_share(deps, info, owner, resharing) } - ExecuteMsg::SurpassedThreshold {} => try_surpassed_threshold(deps, env), + ExecuteMsg::SurpassedThreshold {} => todo!(), ExecuteMsg::AdvanceEpochState {} => try_advance_epoch_state(deps, env), ExecuteMsg::TriggerReset {} => try_trigger_reset(deps, env, info), ExecuteMsg::TriggerResharing {} => try_trigger_resharing(deps, env, info), @@ -133,7 +130,7 @@ pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { to_binary(&query_current_epoch_threshold(deps.storage)?)? } - QueryMsg::GetInitialDealers {} => to_binary(&query_initial_dealers(deps.storage)?)?, + QueryMsg::GetInitialDealers {} => todo!(), QueryMsg::GetDealerDetails { dealer_address } => { to_binary(&query_dealer_details(deps, dealer_address)?)? } diff --git a/contracts/coconut-dkg/src/dealers/queries.rs b/contracts/coconut-dkg/src/dealers/queries.rs index f7ef4209c1..c7117f926c 100644 --- a/contracts/coconut-dkg/src/dealers/queries.rs +++ b/contracts/coconut-dkg/src/dealers/queries.rs @@ -1,53 +1,55 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage::{self, IndexedDealersMap}; +use crate::dealers::storage::{self}; use cosmwasm_std::{Deps, Order, StdResult}; use cw_storage_plus::Bound; use nym_coconut_dkg_common::dealer::{DealerDetailsResponse, DealerType, PagedDealerResponse}; -fn query_dealers( - deps: Deps<'_>, - start_after: Option, - limit: Option, - underlying_map: &IndexedDealersMap<'_>, -) -> StdResult { - let limit = limit - .unwrap_or(storage::DEALERS_PAGE_DEFAULT_LIMIT) - .min(storage::DEALERS_PAGE_MAX_LIMIT) as usize; - - let addr = start_after - .map(|addr| deps.api.addr_validate(&addr)) - .transpose()?; - - let start = addr.as_ref().map(Bound::exclusive); - - let dealers = underlying_map - .range(deps.storage, start, None, Order::Ascending) - .take(limit) - .map(|res| res.map(|item| item.1)) - .collect::>>()?; - - let start_next_after = dealers.last().map(|dealer| dealer.address.clone()); - - Ok(PagedDealerResponse::new(dealers, limit, start_next_after)) -} +// fn query_dealers( +// deps: Deps<'_>, +// start_after: Option, +// limit: Option, +// underlying_map: &IndexedDealersMap<'_>, +// ) -> StdResult { +// let limit = limit +// .unwrap_or(storage::DEALERS_PAGE_DEFAULT_LIMIT) +// .min(storage::DEALERS_PAGE_MAX_LIMIT) as usize; +// +// let addr = start_after +// .map(|addr| deps.api.addr_validate(&addr)) +// .transpose()?; +// +// let start = addr.as_ref().map(Bound::exclusive); +// +// let dealers = underlying_map +// .range(deps.storage, start, None, Order::Ascending) +// .take(limit) +// .map(|res| res.map(|item| item.1)) +// .collect::>>()?; +// +// let start_next_after = dealers.last().map(|dealer| dealer.address.clone()); +// +// Ok(PagedDealerResponse::new(dealers, limit, start_next_after)) +// } pub fn query_dealer_details( deps: Deps<'_>, dealer_address: String, ) -> StdResult { let addr = deps.api.addr_validate(&dealer_address)?; - if let Some(current) = storage::current_dealers().may_load(deps.storage, &addr)? { - return Ok(DealerDetailsResponse::new( - Some(current), - DealerType::Current, - )); - } - if let Some(past) = storage::past_dealers().may_load(deps.storage, &addr)? { - return Ok(DealerDetailsResponse::new(Some(past), DealerType::Past)); - } - Ok(DealerDetailsResponse::new(None, DealerType::Unknown)) + + todo!() + // if let Some(current) = storage::current_dealers().may_load(deps.storage, &addr)? { + // return Ok(DealerDetailsResponse::new( + // Some(current), + // DealerType::Current, + // )); + // } + // if let Some(past) = storage::past_dealers().may_load(deps.storage, &addr)? { + // return Ok(DealerDetailsResponse::new(Some(past), DealerType::Past)); + // } + // Ok(DealerDetailsResponse::new(None, DealerType::Unknown)) } pub fn query_current_dealers_paged( @@ -55,7 +57,8 @@ pub fn query_current_dealers_paged( start_after: Option, limit: Option, ) -> StdResult { - query_dealers(deps, start_after, limit, &storage::current_dealers()) + todo!() + // query_dealers(deps, start_after, limit, &storage::current_dealers()) } pub fn query_past_dealers_paged( @@ -63,7 +66,8 @@ pub fn query_past_dealers_paged( start_after: Option, limit: Option, ) -> StdResult { - query_dealers(deps, start_after, limit, &storage::past_dealers()) + todo!() + // query_dealers(deps, start_after, limit, &storage::past_dealers()) } #[cfg(test)] diff --git a/contracts/coconut-dkg/src/dealers/storage.rs b/contracts/coconut-dkg/src/dealers/storage.rs index 3204a0c2f6..3f0ecc18ac 100644 --- a/contracts/coconut-dkg/src/dealers/storage.rs +++ b/contracts/coconut-dkg/src/dealers/storage.rs @@ -1,50 +1,95 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::error::ContractError; use crate::Dealer; use cosmwasm_std::{Addr, StdResult, Storage}; use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; use nym_coconut_dkg_common::types::{DealerDetails, DealerRegistrationDetails, EpochId, NodeIndex}; -const CURRENT_DEALERS_PK: &str = "crd"; -const PAST_DEALERS_PK: &str = "ptd"; -const DEALERS_NODE_INDEX_IDX_NAMESPACE: &str = "dni"; - -pub(crate) const DEALERS_PAGE_MAX_LIMIT: u32 = 75; -pub(crate) const DEALERS_PAGE_DEFAULT_LIMIT: u32 = 50; +pub(crate) const DEALERS_PAGE_MAX_LIMIT: u32 = 50; +pub(crate) const DEALERS_PAGE_DEFAULT_LIMIT: u32 = 20; pub(crate) const NODE_INDEX_COUNTER: Item = Item::new("node_index_counter"); -// TODO: pub(crate) const DEALERS_INDICES: Map = Map::new("dealer_index"); + pub(crate) const EPOCH_DEALERS_MAP: Map<(EpochId, Dealer), DealerRegistrationDetails> = Map::new("epoch_dealers"); -pub(crate) type IndexedDealersMap<'a> = IndexedMap<'a, &'a Addr, DealerDetails, DealersIndex<'a>>; - -pub(crate) struct DealersIndex<'a> { - pub(crate) node_index: UniqueIndex<'a, NodeIndex, DealerDetails>, -} - -impl<'a> IndexList for DealersIndex<'a> { - fn get_indexes(&'_ self) -> Box> + '_> { - let v: Vec<&dyn Index> = vec![&self.node_index]; - Box::new(v.into_iter()) +/// Attempts to retrieve a pre-assign node index associated with given dealer. +/// If one doesn't exist, a new one is assigned. +pub(crate) fn get_or_assign_index( + storage: &mut dyn Storage, + dealer: Dealer, +) -> StdResult { + if let Some(index) = DEALERS_INDICES.may_load(storage, dealer)? { + return Ok(index); } + let index = next_node_index(storage)?; + DEALERS_INDICES.save(storage, dealer, &index)?; + Ok(index) } -pub(crate) fn current_dealers<'a>() -> IndexedDealersMap<'a> { - let indexes = DealersIndex { - node_index: UniqueIndex::new(|d| d.assigned_index, DEALERS_NODE_INDEX_IDX_NAMESPACE), - }; - IndexedMap::new(CURRENT_DEALERS_PK, indexes) +pub(crate) fn save_dealer_details_if_not_a_dealer( + storage: &mut dyn Storage, + dealer: Dealer, + epoch_id: EpochId, + details: DealerRegistrationDetails, +) -> Result<(), ContractError> { + if EPOCH_DEALERS_MAP.has(storage, (epoch_id, dealer)) { + return Err(ContractError::AlreadyADealer); + } + EPOCH_DEALERS_MAP.save(storage, (epoch_id, dealer), &details)?; + Ok(()) } -pub(crate) fn past_dealers<'a>() -> IndexedDealersMap<'a> { - let indexes = DealersIndex { - node_index: UniqueIndex::new(|d| d.assigned_index, DEALERS_NODE_INDEX_IDX_NAMESPACE), - }; - IndexedMap::new(PAST_DEALERS_PK, indexes) +pub(crate) fn ensure_dealer( + storage: &dyn Storage, + dealer: Dealer, + epoch_id: EpochId, +) -> Result<(), ContractError> { + if !EPOCH_DEALERS_MAP.has(storage, (epoch_id, dealer)) { + return Err(ContractError::NotADealer { epoch_id }); + } + Ok(()) +} + +// note: `epoch_id` is provided purely for the error message. it has nothing to do with storage retrieval +pub(crate) fn get_dealer_index( + storage: &dyn Storage, + dealer: Dealer, + epoch_id: EpochId, +) -> Result { + DEALERS_INDICES + .may_load(storage, dealer)? + .ok_or(ContractError::NotADealer { epoch_id }) +} + +pub(crate) fn get_registration_details( + storage: &dyn Storage, + dealer: Dealer, + epoch_id: EpochId, +) -> Result { + EPOCH_DEALERS_MAP + .may_load(storage, (epoch_id, dealer))? + .ok_or(ContractError::NotADealer { epoch_id }) +} + +pub(crate) fn get_dealer_details( + storage: &dyn Storage, + dealer: Dealer, + epoch_id: EpochId, +) -> Result { + let registration_details = get_registration_details(storage, dealer, epoch_id)?; + let assigned_index = get_dealer_index(storage, dealer, epoch_id)?; + Ok(DealerDetails { + address: dealer.to_owned(), + bte_public_key_with_proof: registration_details.bte_public_key_with_proof, + ed25519_identity: registration_details.ed25519_identity, + announce_address: registration_details.announce_address, + assigned_index, + }) } pub(crate) fn next_node_index(store: &mut dyn Storage) -> StdResult { diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index 01507b3dce..fe851df5b6 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -1,34 +1,22 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage as dealers_storage; -use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA}; +use crate::dealers::storage::{get_or_assign_index, save_dealer_details_if_not_a_dealer}; +use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; use crate::state::storage::STATE; -use cosmwasm_std::{Addr, DepsMut, MessageInfo, Response, StdResult}; -use nym_coconut_dkg_common::types::{DealerDetails, EncodedBTEPublicKeyWithProof, EpochState}; +use crate::Dealer; +use cosmwasm_std::{Deps, DepsMut, MessageInfo, Response, StdResult}; +use nym_coconut_dkg_common::dealer::DealerRegistrationDetails; +use nym_coconut_dkg_common::types::{EncodedBTEPublicKeyWithProof, EpochState}; -// currently we only require that -// a) it's part of the signer group -// b) it isn't already a dealer -fn verify_dealer(deps: DepsMut<'_>, dealer: &Addr, resharing: bool) -> Result<(), ContractError> { - if dealers_storage::current_dealers() - .may_load(deps.storage, dealer)? - .is_some() - { - return Err(ContractError::AlreadyADealer); - } +fn ensure_group_member(deps: Deps, dealer: Dealer) -> Result<(), ContractError> { let state = STATE.load(deps.storage)?; - let height = if resharing { - Some(INITIAL_REPLACEMENT_DATA.load(deps.storage)?.initial_height) - } else { - None - }; state .group_addr - .is_voting_member(&deps.querier, dealer, height)? + .is_voting_member(&deps.querier, dealer, None)? .ok_or(ContractError::Unauthorized {})?; Ok(()) @@ -37,42 +25,35 @@ fn verify_dealer(deps: DepsMut<'_>, dealer: &Addr, resharing: bool) -> Result<() // future optimisation: // for a recurring dealer just let it refresh the keys without having to do all the storage operations pub fn try_add_dealer( - mut deps: DepsMut<'_>, + deps: DepsMut<'_>, info: MessageInfo, bte_key_with_proof: EncodedBTEPublicKeyWithProof, identity_key: String, announce_address: String, resharing: bool, ) -> Result { + let epoch = CURRENT_EPOCH.load(deps.storage)?; check_epoch_state(deps.storage, EpochState::PublicKeySubmission { resharing })?; - verify_dealer(deps.branch(), &info.sender, resharing)?; + // make sure this potential dealer actually belong to the group + ensure_group_member(deps.as_ref(), &info.sender)?; - // if it was already a dealer in the past, assign the same node index - let node_index = if let Some(prior_details) = - dealers_storage::past_dealers().may_load(deps.storage, &info.sender)? - { - // since this dealer is going to become active now, remove it from the past dealers - dealers_storage::past_dealers().replace( - deps.storage, - &info.sender, - None, - Some(&prior_details), - )?; - prior_details.assigned_index - } else { - dealers_storage::next_node_index(deps.storage)? - }; + let node_index = get_or_assign_index(deps.storage, &info.sender)?; - // save the dealer into the storage - let dealer_details = DealerDetails { - address: info.sender.clone(), + // save the dealer into the storage (if it hasn't already been saved) + let dealer_details = DealerRegistrationDetails { bte_public_key_with_proof: bte_key_with_proof, ed25519_identity: identity_key, announce_address, - assigned_index: node_index, }; - dealers_storage::current_dealers().save(deps.storage, &info.sender, &dealer_details)?; + save_dealer_details_if_not_a_dealer( + deps.storage, + &info.sender, + epoch.epoch_id, + dealer_details, + )?; + + // increment the number of registered dealers CURRENT_EPOCH.update(deps.storage, |epoch| -> StdResult<_> { let mut updated_epoch = epoch; updated_epoch.state_progress.registered_dealers += 1; diff --git a/contracts/coconut-dkg/src/dealings/storage.rs b/contracts/coconut-dkg/src/dealings/storage.rs index 187d84bc6e..bfa92722a4 100644 --- a/contracts/coconut-dkg/src/dealings/storage.rs +++ b/contracts/coconut-dkg/src/dealings/storage.rs @@ -3,7 +3,7 @@ use crate::error::ContractError; use crate::Dealer; -use cosmwasm_std::{Addr, Storage}; +use cosmwasm_std::Storage; use cw_storage_plus::{Key, Map, Path, PrimaryKey}; use nym_coconut_dkg_common::dealing::{DealingMetadata, PartialContractDealing}; use nym_coconut_dkg_common::types::{ diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index e64c4d575c..467ee46eba 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -1,11 +1,11 @@ // Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage as dealers_storage; +use crate::dealers::storage::ensure_dealer; use crate::dealings::storage::{ metadata_exists, must_read_metadata, store_metadata, StoredDealing, }; -use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA}; +use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; use crate::state::storage::STATE; @@ -13,31 +13,25 @@ use cosmwasm_std::{Addr, DepsMut, Env, MessageInfo, Response, Storage}; use nym_coconut_dkg_common::dealing::{ DealingChunkInfo, DealingMetadata, PartialContractDealing, MAX_DEALING_CHUNKS, }; -use nym_coconut_dkg_common::types::{ChunkIndex, DealingIndex, EpochState}; +use nym_coconut_dkg_common::types::{ChunkIndex, DealingIndex, EpochId, EpochState}; // make sure the epoch is in the dealing exchange and the message sender is a valid dealer for this epoch fn ensure_permission( storage: &dyn Storage, sender: &Addr, + current_epoch_id: EpochId, resharing: bool, ) -> Result<(), ContractError> { check_epoch_state(storage, EpochState::DealingExchange { resharing })?; - // ensure the sender is a dealer - if dealers_storage::current_dealers() - .may_load(storage, sender)? - .is_none() - { - return Err(ContractError::NotADealer); - } - if resharing - && !INITIAL_REPLACEMENT_DATA - .load(storage)? - .initial_dealers - .contains(sender) - { - return Err(ContractError::NotAnInitialDealer); + // ensure the sender is a dealer for this epoch + ensure_dealer(storage, sender, current_epoch_id)?; + + // if we're in resharing, make sure this sender has also been a dealer in the previous epoch + if resharing { + ensure_dealer(storage, sender, current_epoch_id.saturating_sub(1))?; } + Ok(()) } @@ -48,10 +42,10 @@ pub fn try_submit_dealings_metadata( chunks: Vec, resharing: bool, ) -> Result { - ensure_permission(deps.storage, &info.sender, resharing)?; - - let state = STATE.load(deps.storage)?; let epoch = CURRENT_EPOCH.load(deps.storage)?; + let state = STATE.load(deps.storage)?; + + ensure_permission(deps.storage, &info.sender, epoch.epoch_id, resharing)?; // don't allow overwriting existing metadata if metadata_exists(deps.storage, epoch.epoch_id, &info.sender, dealing_index) { @@ -139,9 +133,9 @@ pub fn try_commit_dealings_chunk( env: Env, info: MessageInfo, chunk: PartialContractDealing, - resharing: bool, ) -> Result { - ensure_permission(deps.storage, &info.sender, resharing)?; + // note: checking permissions is implicit as if the metadata exists, + // the sender must have been allowed to submit it let epoch = CURRENT_EPOCH.load(deps.storage)?; diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index b4dc6cd310..9a748385bb 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -1,10 +1,10 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRESHOLD}; +use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; use crate::error::ContractError; use cosmwasm_std::Storage; -use nym_coconut_dkg_common::types::{Epoch, InitialReplacementData}; +use nym_coconut_dkg_common::types::Epoch; pub(crate) fn query_current_epoch(storage: &dyn Storage) -> Result { CURRENT_EPOCH @@ -18,12 +18,6 @@ pub(crate) fn query_current_epoch_threshold( Ok(THRESHOLD.may_load(storage)?) } -pub(crate) fn query_initial_dealers( - storage: &dyn Storage, -) -> Result, ContractError> { - Ok(INITIAL_REPLACEMENT_DATA.may_load(storage)?) -} - #[cfg(test)] pub(crate) mod test { use super::*; diff --git a/contracts/coconut-dkg/src/epoch_state/storage.rs b/contracts/coconut-dkg/src/epoch_state/storage.rs index 36d3b7bd91..56c80fac2d 100644 --- a/contracts/coconut-dkg/src/epoch_state/storage.rs +++ b/contracts/coconut-dkg/src/epoch_state/storage.rs @@ -2,11 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use cw_storage_plus::Item; -use nym_coconut_dkg_common::types::{Epoch, InitialReplacementData}; +use nym_coconut_dkg_common::types::Epoch; pub(crate) const CURRENT_EPOCH: Item<'_, Epoch> = Item::new("current_epoch"); pub const THRESHOLD: Item = Item::new("threshold"); - -#[deprecated] -pub const INITIAL_REPLACEMENT_DATA: Item = - Item::new("initial_replacement_data"); diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs index f3384e84e6..715a6e5656 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -1,17 +1,11 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage::current_dealers; -use crate::epoch_state::storage::{CURRENT_EPOCH, INITIAL_REPLACEMENT_DATA, THRESHOLD}; -use crate::epoch_state::transactions::{ - dealers_eq_members, replacement_threshold_surpassed, reset_dkg_state, -}; -use crate::epoch_state::utils::{check_state_completion, needs_reset, needs_resharing}; +use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; +use crate::epoch_state::utils::check_state_completion; use crate::error::ContractError; -use crate::state::storage::STATE; -use crate::verification_key_shares::storage::verified_dealers; -use cosmwasm_std::{Addr, Deps, DepsMut, Env, Order, Response}; -use nym_coconut_dkg_common::types::{Epoch, EpochState, InitialReplacementData}; +use cosmwasm_std::{Deps, DepsMut, Env, Response}; +use nym_coconut_dkg_common::types::{Epoch, EpochState}; fn ensure_can_advance_state( deps: Deps<'_>, @@ -49,7 +43,7 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result next_state, None => { debug_assert!(current_epoch.state.is_in_progress()); @@ -60,89 +54,21 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result, _>>()?; - // let group_members = - // STATE - // .load(deps.storage)? - // .group_addr - // .list_members(&deps.querier, None, None)?; - // if current_dealers.len() < group_members.len() { - // // If not all group members registered yet, we just stay in the same state until - // // they either register or they get kicked out of the group - // new_state = current_epoch.state; - // } else { - // // note: ceiling in integer division can be achieved via q = (x + y - 1) / y; - // let threshold = (2 * current_dealers.len() as u64 + 3 - 1) / 3; - // THRESHOLD.save(deps.storage, &threshold)?; - // } - // }; - // Epoch::new( - // new_state, - // current_epoch.epoch_id, - // current_epoch.time_configuration, - // env.block.time, - // ) - // } else if dealers_eq_members(&deps)? { - // // The dealer set hasn't changed, so we only extend the finish timestamp - // // The epoch remains the same, as we use it as key for storing VKs - // - // // TODO: change that behaviour in the following PR - // Epoch::new( - // current_epoch.state, - // current_epoch.epoch_id, - // current_epoch.time_configuration, - // env.block.time, - // ) - // } else { - // // Dealer set changed, we need to redo DKG... - // let state = if replacement_threshold_surpassed(&deps)? { - // // ... in reset mode - // INITIAL_REPLACEMENT_DATA.remove(deps.storage); - // EpochState::PublicKeySubmission { resharing: false } - // } else { - // // ... in reshare mode - // if INITIAL_REPLACEMENT_DATA.may_load(deps.storage)?.is_some() { - // INITIAL_REPLACEMENT_DATA.update::<_, ContractError>(deps.storage, |mut data| { - // // TODO: FIXME: for second reshare the added set of dealers won't be allowed to participate - // data.initial_height = env.block.height; - // Ok(data) - // })?; - // } else { - // let replacement_data = InitialReplacementData { - // initial_dealers: verified_dealers(deps.storage)?, - // initial_height: env.block.height, - // }; - // INITIAL_REPLACEMENT_DATA.save(deps.storage, &replacement_data)?; - // } - // - // EpochState::PublicKeySubmission { resharing: true } - // }; - // reset_dkg_state(deps.storage)?; - // Epoch::new( - // state, - // current_epoch.epoch_id + 1, - // current_epoch.time_configuration, - // env.block.time, - // ) - // }; - // CURRENT_EPOCH.save(deps.storage, &next_epoch)?; - // - // Ok(Response::default()) } #[cfg(test)] diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index 4b5a087dda..abcb78a21e 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -1,14 +1,10 @@ // Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage::{current_dealers, past_dealers}; use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; -use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; -use crate::state::storage::{DKG_ADMIN, STATE}; -use crate::verification_key_shares::storage::verified_dealers; -use cosmwasm_std::{Addr, Deps, DepsMut, Env, MessageInfo, Order, Response, Storage}; -use cw4::Member; +use crate::state::storage::DKG_ADMIN; +use cosmwasm_std::{DepsMut, Env, MessageInfo, Order, Response, Storage}; use nym_coconut_dkg_common::types::{Epoch, EpochState}; pub use advance_epoch_state::try_advance_epoch_state; @@ -18,66 +14,19 @@ pub mod advance_epoch_state; fn reset_dkg_state(storage: &mut dyn Storage) -> Result<(), ContractError> { THRESHOLD.remove(storage); - // TODO: unbounded query. to be removed be preserving dealer details and changing storage structure - let dealers: Vec<_> = current_dealers() - .keys(storage, None, None, Order::Ascending) - .collect::>()?; - - for dealer_addr in dealers { - let details = current_dealers().load(storage, &dealer_addr)?; - current_dealers().remove(storage, &dealer_addr)?; - past_dealers().save(storage, &dealer_addr, &details)?; - } + // // TODO: unbounded query. to be removed be preserving dealer details and changing storage structure + // let dealers: Vec<_> = current_dealers() + // .keys(storage, None, None, Order::Ascending) + // .collect::>()?; + // + // for dealer_addr in dealers { + // let details = current_dealers().load(storage, &dealer_addr)?; + // current_dealers().remove(storage, &dealer_addr)?; + // past_dealers().save(storage, &dealer_addr, &details)?; + // } Ok(()) } -fn dealers_still_active( - deps: &Deps<'_>, - dealers: impl Iterator, -) -> Result { - let state = STATE.load(deps.storage)?; - let mut still_active = 0; - for dealer_addr in dealers { - if state - .group_addr - .is_voting_member(&deps.querier, &dealer_addr, None)? - .is_some() - { - still_active += 1; - } - } - Ok(still_active) -} - -#[deprecated] -fn dealers_eq_members(deps: &DepsMut<'_>) -> Result { - let verified_dealers = verified_dealers(deps.storage)?; - let all_dealers = verified_dealers.len(); - let dealers_still_active = dealers_still_active(&deps.as_ref(), verified_dealers.into_iter())?; - let group_members = STATE - .load(deps.storage)? - .group_addr - .list_members(&deps.querier, None, None)? - .len(); - - Ok(dealers_still_active == all_dealers && all_dealers == group_members) -} - -fn replacement_threshold_surpassed(deps: &DepsMut<'_>) -> Result { - let threshold = THRESHOLD.load(deps.storage)? as usize; - let initial_dealers = verified_dealers(deps.storage)?; - if initial_dealers.is_empty() { - // possibly failed DKG, just reset and start again - return Ok(true); - } - let initial_dealer_count = initial_dealers.len(); - let replacement_threshold = threshold - (initial_dealers.len() + 2 - 1) / 2 + 1; - let removed_dealer_count = - initial_dealer_count - dealers_still_active(&deps.as_ref(), initial_dealers.into_iter())?; - - Ok(removed_dealer_count >= replacement_threshold) -} - pub(crate) fn try_initiate_dkg( deps: DepsMut<'_>, env: Env, @@ -99,29 +48,6 @@ pub(crate) fn try_initiate_dkg( Ok(Response::default()) } -pub(crate) fn try_surpassed_threshold( - deps: DepsMut<'_>, - env: Env, -) -> Result { - check_epoch_state(deps.storage, EpochState::InProgress)?; - - let threshold = THRESHOLD.load(deps.storage)?; - let dealers = verified_dealers(deps.storage)?; - if dealers_still_active(&deps.as_ref(), dealers.into_iter())? < threshold as usize { - reset_dkg_state(deps.storage)?; - CURRENT_EPOCH.update::<_, ContractError>(deps.storage, |epoch| { - Ok(Epoch::new( - EpochState::default(), - epoch.epoch_id + 1, - epoch.time_configuration, - env.block.time, - )) - })?; - } - - Ok(Response::default()) -} - pub(crate) fn try_trigger_reset( deps: DepsMut<'_>, env: Env, diff --git a/contracts/coconut-dkg/src/epoch_state/utils.rs b/contracts/coconut-dkg/src/epoch_state/utils.rs index be69318e49..3e712c431d 100644 --- a/contracts/coconut-dkg/src/epoch_state/utils.rs +++ b/contracts/coconut-dkg/src/epoch_state/utils.rs @@ -4,31 +4,9 @@ use crate::epoch_state::storage::CURRENT_EPOCH; use crate::error::ContractError; use crate::state::storage::STATE; -use crate::verification_key_shares::storage::{dealers, verified_dealers}; -use cosmwasm_std::{Addr, Deps, StdResult, Storage}; -use cw4::Member; +use cosmwasm_std::Storage; use nym_coconut_dkg_common::types::{Epoch, EpochState}; -fn all_group_members(deps: &Deps) -> Result, ContractError> { - // the maximum limit for members queries is 30. - // if we're ever thinking of going beyond it, we should fix it properly - // by the DKG contract owning the group contract (i.e. init inside init) - // and proxying all member changes and thus memoizing the members. - // alternatively by adding hooks to the contract to inform us about any changes - let members = - STATE - .load(deps.storage)? - .group_addr - .list_members(&deps.querier, None, Some(30))?; - - // if we're at the limit... - if members.len() == 30 { - return Err(ContractError::PossiblyIncompleteGroupMembersQuery); - } - - Ok(members) -} - // check if we completed the state, so we could short circuit the deadline pub(crate) fn check_state_completion( storage: &dyn Storage, @@ -65,57 +43,6 @@ pub(crate) fn check_state_completion( } } -/// Checks whether the DKG needs to undergo full reset. -/// This is determined by whether the initial set of validator changed by more than a threshold number -/// of parties joining or leaving. -pub(crate) fn needs_reset(deps: Deps) -> Result { - let current_state = CURRENT_EPOCH.load(deps.storage)?.state; - - // there is a theoretical edge case where we add/remove an extra member during an in-progress exchange - // thus possibly needing reset immediately after it's done. an optimization would be to just scrap it and start it over - // but since members are added manually, we don't have to worry about it too much for now. - if !current_state.is_in_progress() { - return Err(ContractError::CantResetDuringExchange); - } - - let group_members = all_group_members(&deps)?; - - // below threshold => must reset since we can't do anything - - todo!() -} - -/// Checks whether the DKG needs to undergo resharing. -/// This is determined by whether any new group members has joined the associated group contract -pub(crate) fn needs_resharing(deps: Deps) -> Result { - let current_state = CURRENT_EPOCH.load(deps.storage)?.state; - - // there is a theoretical edge case where we add an extra member during an in-progress exchange - // thus needing resharing immediately after it's done. an optimization would be to just scrap it and start it over - // but since members are added manually, we don't have to worry about it too much for now. - if !current_state.is_in_progress() { - return Err(ContractError::CantReshareDuringExchange); - } - - // TODO: we need cw4 hooks here to resolve those expensive queries - let group_members = all_group_members(&deps)?; - let epoch_dealers = dealers(deps.storage)?; - - // if somebody has been a dealer, but hasn't been verified, tough luck - // we only allow for resharing for new members - - // check if we have any new members - for member in group_members { - if !epoch_dealers.contains_key(&Addr::unchecked(member.addr)) { - return Ok(true); - } - } - - // TODO: something about reset here - - Ok(false) -} - pub(crate) fn check_epoch_state( storage: &dyn Storage, against: EpochState, diff --git a/contracts/coconut-dkg/src/error.rs b/contracts/coconut-dkg/src/error.rs index 743f3b80df..f7952deedc 100644 --- a/contracts/coconut-dkg/src/error.rs +++ b/contracts/coconut-dkg/src/error.rs @@ -45,8 +45,8 @@ pub enum ContractError { expected_state: String, }, - #[error("This sender is not a dealer for the current epoch")] - NotADealer, + #[error("This sender is not a dealer for epoch {epoch_id}")] + NotADealer { epoch_id: EpochId }, #[error("This sender is not a dealer for the current resharing epoch")] NotAnInitialDealer, diff --git a/contracts/coconut-dkg/src/verification_key_shares/storage.rs b/contracts/coconut-dkg/src/verification_key_shares/storage.rs index 0951069e95..a2c626af5b 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/storage.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/storage.rs @@ -2,16 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 use crate::constants::{VK_SHARES_EPOCH_ID_IDX_NAMESPACE, VK_SHARES_PK_NAMESPACE}; -use crate::epoch_state::storage::CURRENT_EPOCH; -use crate::error::ContractError; -use cosmwasm_std::{Addr, Order, StdResult, Storage}; +use cosmwasm_std::Addr; use cw_storage_plus::{Index, IndexList, IndexedMap, MultiIndex}; use nym_coconut_dkg_common::types::EpochId; use nym_coconut_dkg_common::verification_key::ContractVKShare; -use std::collections::HashMap; -pub(crate) const VERIFICATION_KEY_SHARES_PAGE_MAX_LIMIT: u32 = 75; -pub(crate) const VERIFICATION_KEY_SHARES_PAGE_DEFAULT_LIMIT: u32 = 50; +pub(crate) const VERIFICATION_KEY_SHARES_PAGE_MAX_LIMIT: u32 = 30; +pub(crate) const VERIFICATION_KEY_SHARES_PAGE_DEFAULT_LIMIT: u32 = 10; type VKShareKey<'a> = (&'a Addr, EpochId); @@ -36,40 +33,3 @@ pub(crate) fn vk_shares<'a>() -> IndexedMap<'a, VKShareKey<'a>, ContractVKShare, }; IndexedMap::new(VK_SHARES_PK_NAMESPACE, indexes) } - -// TODO: this is a ticking time bomb and will cause us headache when we start running out of gas... again... -// not sure how to fix it yet... -// maybe by completely removing it by relying on cw4 hooks? -#[deprecated] -pub(crate) fn verified_dealers(storage: &dyn Storage) -> Result, ContractError> { - let epoch_id = CURRENT_EPOCH.load(storage)?.epoch_id; - Ok(vk_shares() - .idx - .epoch_id - .prefix(epoch_id) - .range(storage, None, None, Order::Ascending) - .flatten() - .filter_map(|(_, share)| { - if share.verified { - Some(share.owner) - } else { - None - } - }) - .collect()) -} - -// TODO: this is a ticking time bomb and will cause us headache when we start running out of gas... again... -// not sure how to fix it yet... -// maybe by completely removing it by relying on cw4 hooks? -pub(crate) fn dealers(storage: &dyn Storage) -> Result, ContractError> { - let epoch_id = CURRENT_EPOCH.load(storage)?.epoch_id; - - Ok(vk_shares() - .idx - .epoch_id - .prefix(epoch_id) - .range(storage, None, None, Order::Ascending) - .map(|maybe_share| maybe_share.map(|(_, v)| (v.owner, v.verified))) - .collect::>()?) -} diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index 583d8c5533..5c683a7690 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::constants::BLOCK_TIME_FOR_VERIFICATION_SECS; -use crate::dealers::storage as dealers_storage; +use crate::dealers::storage::get_dealer_details; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; @@ -25,11 +25,9 @@ pub fn try_commit_verification_key_share( deps.storage, EpochState::VerificationKeySubmission { resharing }, )?; - // ensure the sender is a dealer - let details = dealers_storage::current_dealers() - .load(deps.storage, &info.sender) - .map_err(|_| ContractError::NotADealer)?; let epoch_id = CURRENT_EPOCH.load(deps.storage)?.epoch_id; + + let details = get_dealer_details(deps.storage, &info.sender, epoch_id)?; if vk_shares() .may_load(deps.storage, (&info.sender, epoch_id))? .is_some() From 45686f7ca6c8848862b69bf37ae99ab2073a814c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 12:15:40 +0000 Subject: [PATCH 030/394] queries --- .../coconut-dkg/src/dealer.rs | 23 ++- .../coconut-dkg/src/msg.rs | 9 +- contracts/coconut-dkg/src/contract.rs | 7 +- contracts/coconut-dkg/src/dealers/queries.rs | 138 +++++++++++------- contracts/coconut-dkg/src/dealers/storage.rs | 11 +- .../src/epoch_state/transactions/mod.rs | 18 +-- 6 files changed, 125 insertions(+), 81 deletions(-) diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs index c9dce74993..3677d67dcd 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs @@ -24,14 +24,14 @@ pub struct DealerRegistrationDetails { #[cw_serde] #[derive(Copy)] pub enum DealerType { - Current, - Past, + Current { assigned_index: NodeIndex }, + Past { assigned_index: NodeIndex }, Unknown, } impl DealerType { pub fn is_current(&self) -> bool { - matches!(&self, DealerType::Current) + matches!(&self, DealerType::Current { .. }) } } @@ -72,3 +72,20 @@ impl PagedDealerResponse { } } } + +#[cw_serde] +pub struct PagedDealerIndexResponse { + pub indices: Vec<(Addr, NodeIndex)>, + + /// Field indicating paging information for the following queries if the caller wishes to get further entries. + pub start_next_after: Option, +} + +impl PagedDealerIndexResponse { + pub fn new(indices: Vec<(Addr, NodeIndex)>, start_next_after: Option) -> Self { + PagedDealerIndexResponse { + indices, + start_next_after, + } + } +} diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index d8a35d9ef3..b048eb5f7d 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -11,7 +11,7 @@ use cosmwasm_schema::cw_serde; #[cfg(feature = "schema")] use crate::{ - dealer::{DealerDetailsResponse, PagedDealerResponse}, + dealer::{DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse}, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, DealingMetadataResponse, DealingStatusResponse, @@ -86,9 +86,6 @@ pub enum QueryMsg { #[cfg_attr(feature = "schema", returns(u64))] GetCurrentEpochThreshold {}, - #[cfg_attr(feature = "schema", returns(Option))] - GetInitialDealers {}, - #[cfg_attr(feature = "schema", returns(DealerDetailsResponse))] GetDealerDetails { dealer_address: String }, @@ -98,8 +95,8 @@ pub enum QueryMsg { start_after: Option, }, - #[cfg_attr(feature = "schema", returns(PagedDealerResponse))] - GetPastDealers { + #[cfg_attr(feature = "schema", returns(PagedDealerIndexResponse))] + GetDealerIndices { limit: Option, start_after: Option, }, diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index 02189255bb..b8c5339ba8 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::dealers::queries::{ - query_current_dealers_paged, query_dealer_details, query_past_dealers_paged, + query_current_dealers_paged, query_dealer_details, query_dealers_indices_paged, }; use crate::dealers::transactions::try_add_dealer; use crate::dealings::queries::{ @@ -130,15 +130,14 @@ pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { to_binary(&query_current_epoch_threshold(deps.storage)?)? } - QueryMsg::GetInitialDealers {} => todo!(), QueryMsg::GetDealerDetails { dealer_address } => { to_binary(&query_dealer_details(deps, dealer_address)?)? } QueryMsg::GetCurrentDealers { limit, start_after } => { to_binary(&query_current_dealers_paged(deps, start_after, limit)?)? } - QueryMsg::GetPastDealers { limit, start_after } => { - to_binary(&query_past_dealers_paged(deps, start_after, limit)?)? + QueryMsg::GetDealerIndices { limit, start_after } => { + to_binary(&query_dealers_indices_paged(deps, start_after, limit)?)? } QueryMsg::GetDealingsMetadata { epoch_id, diff --git a/contracts/coconut-dkg/src/dealers/queries.rs b/contracts/coconut-dkg/src/dealers/queries.rs index c7117f926c..3bf0aa28f0 100644 --- a/contracts/coconut-dkg/src/dealers/queries.rs +++ b/contracts/coconut-dkg/src/dealers/queries.rs @@ -1,55 +1,66 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage::{self}; +use crate::dealers::storage::{ + self, get_dealer_details, get_dealer_index, DEALERS_INDICES, EPOCH_DEALERS_MAP, +}; +use crate::epoch_state::storage::CURRENT_EPOCH; use cosmwasm_std::{Deps, Order, StdResult}; use cw_storage_plus::Bound; -use nym_coconut_dkg_common::dealer::{DealerDetailsResponse, DealerType, PagedDealerResponse}; - -// fn query_dealers( -// deps: Deps<'_>, -// start_after: Option, -// limit: Option, -// underlying_map: &IndexedDealersMap<'_>, -// ) -> StdResult { -// let limit = limit -// .unwrap_or(storage::DEALERS_PAGE_DEFAULT_LIMIT) -// .min(storage::DEALERS_PAGE_MAX_LIMIT) as usize; -// -// let addr = start_after -// .map(|addr| deps.api.addr_validate(&addr)) -// .transpose()?; -// -// let start = addr.as_ref().map(Bound::exclusive); -// -// let dealers = underlying_map -// .range(deps.storage, start, None, Order::Ascending) -// .take(limit) -// .map(|res| res.map(|item| item.1)) -// .collect::>>()?; -// -// let start_next_after = dealers.last().map(|dealer| dealer.address.clone()); -// -// Ok(PagedDealerResponse::new(dealers, limit, start_next_after)) -// } +use nym_coconut_dkg_common::dealer::{ + DealerDetailsResponse, DealerType, PagedDealerIndexResponse, PagedDealerResponse, +}; +use nym_coconut_dkg_common::types::DealerDetails; pub fn query_dealer_details( deps: Deps<'_>, dealer_address: String, ) -> StdResult { let addr = deps.api.addr_validate(&dealer_address)?; + let current_epoch_id = CURRENT_EPOCH.load(deps.storage)?.epoch_id; - todo!() - // if let Some(current) = storage::current_dealers().may_load(deps.storage, &addr)? { - // return Ok(DealerDetailsResponse::new( - // Some(current), - // DealerType::Current, - // )); - // } - // if let Some(past) = storage::past_dealers().may_load(deps.storage, &addr)? { - // return Ok(DealerDetailsResponse::new(Some(past), DealerType::Past)); - // } - // Ok(DealerDetailsResponse::new(None, DealerType::Unknown)) + // if the address has registration data for the current epoch, it means it's an active dealer + if let Ok(dealer_details) = get_dealer_details(deps.storage, &addr, current_epoch_id) { + let assigned_index = dealer_details.assigned_index; + return Ok(DealerDetailsResponse::new( + Some(dealer_details), + DealerType::Current { assigned_index }, + )); + } + + // and if has had an assigned index it must have been a dealer at some point in the past + if let Ok(assigned_index) = get_dealer_index(deps.storage, &addr, current_epoch_id) { + return Ok(DealerDetailsResponse::new( + None, + DealerType::Past { assigned_index }, + )); + } + + Ok(DealerDetailsResponse::new(None, DealerType::Unknown)) +} + +pub fn query_dealers_indices_paged( + deps: Deps<'_>, + start_after: Option, + limit: Option, +) -> StdResult { + let limit = limit + .unwrap_or(storage::DEALER_INDICES_PAGE_DEFAULT_LIMIT) + .min(storage::DEALER_INDICES_PAGE_MAX_LIMIT) as usize; + let addr = start_after + .map(|addr| deps.api.addr_validate(&addr)) + .transpose()?; + + let start = addr.as_ref().map(Bound::exclusive); + + let dealers = DEALERS_INDICES + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .collect::>>()?; + + let start_next_after = dealers.last().map(|dealer| dealer.0.clone()); + + Ok(PagedDealerIndexResponse::new(dealers, start_next_after)) } pub fn query_current_dealers_paged( @@ -57,17 +68,42 @@ pub fn query_current_dealers_paged( start_after: Option, limit: Option, ) -> StdResult { - todo!() - // query_dealers(deps, start_after, limit, &storage::current_dealers()) -} + let limit = limit + .unwrap_or(storage::DEALERS_PAGE_DEFAULT_LIMIT) + .min(storage::DEALERS_PAGE_MAX_LIMIT) as usize; + let addr = start_after + .map(|addr| deps.api.addr_validate(&addr)) + .transpose()?; -pub fn query_past_dealers_paged( - deps: Deps<'_>, - start_after: Option, - limit: Option, -) -> StdResult { - todo!() - // query_dealers(deps, start_after, limit, &storage::past_dealers()) + let start = addr.as_ref().map(Bound::exclusive); + + let current_epoch_id = CURRENT_EPOCH.load(deps.storage)?.epoch_id; + + let dealers = EPOCH_DEALERS_MAP + .prefix(current_epoch_id) + .range(deps.storage, start, None, Order::Ascending) + .take(limit) + .map(|res| { + res.map(|(address, details)| { + // SAFETY: if we have DealerRegistrationDetails saved, it means we MUST also have its node index + // otherwise some serious invariants have been broken in the contract, and we're in trouble + #[allow(clippy::expect_used)] + let assigned_index = get_dealer_index(deps.storage, &address, current_epoch_id) + .expect("could not retrieve dealer index for a registered dealer"); + + DealerDetails { + address, + bte_public_key_with_proof: details.bte_public_key_with_proof, + ed25519_identity: details.ed25519_identity, + announce_address: details.announce_address, + assigned_index, + } + }) + }) + .collect::>>()?; + let start_next_after = dealers.last().map(|dealer| dealer.address.clone()); + + Ok(PagedDealerResponse::new(dealers, limit, start_next_after)) } #[cfg(test)] diff --git a/contracts/coconut-dkg/src/dealers/storage.rs b/contracts/coconut-dkg/src/dealers/storage.rs index 3f0ecc18ac..979218b3ed 100644 --- a/contracts/coconut-dkg/src/dealers/storage.rs +++ b/contracts/coconut-dkg/src/dealers/storage.rs @@ -3,12 +3,15 @@ use crate::error::ContractError; use crate::Dealer; -use cosmwasm_std::{Addr, StdResult, Storage}; -use cw_storage_plus::{Index, IndexList, IndexedMap, Item, Map, UniqueIndex}; +use cosmwasm_std::{StdResult, Storage}; +use cw_storage_plus::{Item, Map}; use nym_coconut_dkg_common::types::{DealerDetails, DealerRegistrationDetails, EpochId, NodeIndex}; -pub(crate) const DEALERS_PAGE_MAX_LIMIT: u32 = 50; -pub(crate) const DEALERS_PAGE_DEFAULT_LIMIT: u32 = 20; +pub(crate) const DEALER_INDICES_PAGE_MAX_LIMIT: u32 = 80; +pub(crate) const DEALER_INDICES_PAGE_DEFAULT_LIMIT: u32 = 40; + +pub(crate) const DEALERS_PAGE_MAX_LIMIT: u32 = 25; +pub(crate) const DEALERS_PAGE_DEFAULT_LIMIT: u32 = 10; pub(crate) const NODE_INDEX_COUNTER: Item = Item::new("node_index_counter"); diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index abcb78a21e..1a99b8a863 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -4,7 +4,7 @@ use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; use crate::error::ContractError; use crate::state::storage::DKG_ADMIN; -use cosmwasm_std::{DepsMut, Env, MessageInfo, Order, Response, Storage}; +use cosmwasm_std::{DepsMut, Env, MessageInfo, Response, Storage}; use nym_coconut_dkg_common::types::{Epoch, EpochState}; pub use advance_epoch_state::try_advance_epoch_state; @@ -14,16 +14,10 @@ pub mod advance_epoch_state; fn reset_dkg_state(storage: &mut dyn Storage) -> Result<(), ContractError> { THRESHOLD.remove(storage); - // // TODO: unbounded query. to be removed be preserving dealer details and changing storage structure - // let dealers: Vec<_> = current_dealers() - // .keys(storage, None, None, Order::Ascending) - // .collect::>()?; - // - // for dealer_addr in dealers { - // let details = current_dealers().load(storage, &dealer_addr)?; - // current_dealers().remove(storage, &dealer_addr)?; - // past_dealers().save(storage, &dealer_addr, &details)?; - // } + // dealings are preserved in the storage and saved per epoch, so we don't have to do anything about them + // the same is true for dealer details + // and epoch progress is reset when new struct is constructed + Ok(()) } @@ -70,7 +64,6 @@ pub(crate) fn try_trigger_reset( ); CURRENT_EPOCH.save(deps.storage, &next_epoch)?; - // TODO: remove reset_dkg_state(deps.storage)?; Ok(Response::default()) @@ -98,7 +91,6 @@ pub(crate) fn try_trigger_resharing( ); CURRENT_EPOCH.save(deps.storage, &next_epoch)?; - // TODO: remove reset_dkg_state(deps.storage)?; Ok(Response::default()) From ad2552ec78fbdcae1a5333f0e0378dca59af2e2f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 12:17:06 +0000 Subject: [PATCH 031/394] schema --- .../coconut-dkg/schema/nym-coconut-dkg.json | 310 ++++++++++-------- contracts/coconut-dkg/schema/raw/execute.json | 32 +- contracts/coconut-dkg/schema/raw/query.json | 17 +- .../response_to_get_current_epoch_state.json | 48 ++- .../raw/response_to_get_dealer_details.json | 58 +++- .../raw/response_to_get_dealer_indices.json | 46 +++ 6 files changed, 340 insertions(+), 171 deletions(-) create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_dealer_indices.json diff --git a/contracts/coconut-dkg/schema/nym-coconut-dkg.json b/contracts/coconut-dkg/schema/nym-coconut-dkg.json index f578fd1bc9..e6fca1f892 100644 --- a/contracts/coconut-dkg/schema/nym-coconut-dkg.json +++ b/contracts/coconut-dkg/schema/nym-coconut-dkg.json @@ -180,15 +180,11 @@ "commit_dealings_chunk": { "type": "object", "required": [ - "chunk", - "resharing" + "chunk" ], "properties": { "chunk": { "$ref": "#/definitions/PartialContractDealing" - }, - "resharing": { - "type": "boolean" } }, "additionalProperties": false @@ -271,6 +267,32 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "trigger_reset" + ], + "properties": { + "trigger_reset": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "trigger_resharing" + ], + "properties": { + "trigger_resharing": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { @@ -365,19 +387,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "get_initial_dealers" - ], - "properties": { - "get_initial_dealers": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -431,10 +440,10 @@ { "type": "object", "required": [ - "get_past_dealers" + "get_dealer_indices" ], "properties": { - "get_past_dealers": { + "get_dealer_indices": { "type": "object", "properties": { "limit": { @@ -813,15 +822,11 @@ "required": [ "epoch_id", "state", + "state_progress", "time_configuration" ], "properties": { - "epoch_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "finish_timestamp": { + "deadline": { "anyOf": [ { "$ref": "#/definitions/Timestamp" @@ -831,9 +836,17 @@ } ] }, + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, "state": { "$ref": "#/definitions/EpochState" }, + "state_progress": { + "$ref": "#/definitions/StateProgress" + }, "time_configuration": { "$ref": "#/definitions/TimeConfiguration" } @@ -956,6 +969,38 @@ } ] }, + "StateProgress": { + "type": "object", + "required": [ + "registered_dealers", + "submitted_dealings", + "submitted_key_shares", + "verified_keys" + ], + "properties": { + "registered_dealers": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_dealings": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_key_shares": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "verified_keys": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, "TimeConfiguration": { "type": "object", "required": [ @@ -1154,15 +1199,109 @@ "additionalProperties": false }, "DealerType": { - "type": "string", - "enum": [ - "current", - "past", - "unknown" + "oneOf": [ + { + "type": "string", + "enum": [ + "unknown" + ] + }, + { + "type": "object", + "required": [ + "current" + ], + "properties": { + "current": { + "type": "object", + "required": [ + "assigned_index" + ], + "properties": { + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "past" + ], + "properties": { + "past": { + "type": "object", + "required": [ + "assigned_index" + ], + "properties": { + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } ] } } }, + "get_dealer_indices": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerIndexResponse", + "type": "object", + "required": [ + "indices" + ], + "properties": { + "indices": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } + }, "get_dealing_chunk": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "DealingChunkResponse", @@ -1455,115 +1594,6 @@ } } }, - "get_initial_dealers": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "Nullable_InitialReplacementData", - "anyOf": [ - { - "$ref": "#/definitions/InitialReplacementData" - }, - { - "type": "null" - } - ], - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "InitialReplacementData": { - "type": "object", - "required": [ - "initial_dealers", - "initial_height" - ], - "properties": { - "initial_dealers": { - "type": "array", - "items": { - "$ref": "#/definitions/Addr" - } - }, - "initial_height": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - } - }, - "additionalProperties": false - } - } - }, - "get_past_dealers": { - "$schema": "http://json-schema.org/draft-07/schema#", - "title": "PagedDealerResponse", - "type": "object", - "required": [ - "dealers", - "per_page" - ], - "properties": { - "dealers": { - "type": "array", - "items": { - "$ref": "#/definitions/DealerDetails" - } - }, - "per_page": { - "type": "integer", - "format": "uint", - "minimum": 0.0 - }, - "start_next_after": { - "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", - "anyOf": [ - { - "$ref": "#/definitions/Addr" - }, - { - "type": "null" - } - ] - } - }, - "additionalProperties": false, - "definitions": { - "Addr": { - "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", - "type": "string" - }, - "DealerDetails": { - "type": "object", - "required": [ - "address", - "announce_address", - "assigned_index", - "bte_public_key_with_proof", - "ed25519_identity" - ], - "properties": { - "address": { - "$ref": "#/definitions/Addr" - }, - "announce_address": { - "type": "string" - }, - "assigned_index": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "bte_public_key_with_proof": { - "type": "string" - }, - "ed25519_identity": { - "type": "string" - } - }, - "additionalProperties": false - } - } - }, "get_state": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "State", diff --git a/contracts/coconut-dkg/schema/raw/execute.json b/contracts/coconut-dkg/schema/raw/execute.json index a576df2219..b1395d8c2e 100644 --- a/contracts/coconut-dkg/schema/raw/execute.json +++ b/contracts/coconut-dkg/schema/raw/execute.json @@ -91,15 +91,11 @@ "commit_dealings_chunk": { "type": "object", "required": [ - "chunk", - "resharing" + "chunk" ], "properties": { "chunk": { "$ref": "#/definitions/PartialContractDealing" - }, - "resharing": { - "type": "boolean" } }, "additionalProperties": false @@ -182,6 +178,32 @@ } }, "additionalProperties": false + }, + { + "type": "object", + "required": [ + "trigger_reset" + ], + "properties": { + "trigger_reset": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "trigger_resharing" + ], + "properties": { + "trigger_resharing": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false } ], "definitions": { diff --git a/contracts/coconut-dkg/schema/raw/query.json b/contracts/coconut-dkg/schema/raw/query.json index 96f50233dd..d55ad0769c 100644 --- a/contracts/coconut-dkg/schema/raw/query.json +++ b/contracts/coconut-dkg/schema/raw/query.json @@ -41,19 +41,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "get_initial_dealers" - ], - "properties": { - "get_initial_dealers": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -107,10 +94,10 @@ { "type": "object", "required": [ - "get_past_dealers" + "get_dealer_indices" ], "properties": { - "get_past_dealers": { + "get_dealer_indices": { "type": "object", "properties": { "limit": { diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json index 3f4a9df103..251d4c7e01 100644 --- a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json +++ b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json @@ -5,15 +5,11 @@ "required": [ "epoch_id", "state", + "state_progress", "time_configuration" ], "properties": { - "epoch_id": { - "type": "integer", - "format": "uint64", - "minimum": 0.0 - }, - "finish_timestamp": { + "deadline": { "anyOf": [ { "$ref": "#/definitions/Timestamp" @@ -23,9 +19,17 @@ } ] }, + "epoch_id": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + }, "state": { "$ref": "#/definitions/EpochState" }, + "state_progress": { + "$ref": "#/definitions/StateProgress" + }, "time_configuration": { "$ref": "#/definitions/TimeConfiguration" } @@ -148,6 +152,38 @@ } ] }, + "StateProgress": { + "type": "object", + "required": [ + "registered_dealers", + "submitted_dealings", + "submitted_key_shares", + "verified_keys" + ], + "properties": { + "registered_dealers": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_dealings": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_key_shares": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "verified_keys": { + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, "TimeConfiguration": { "type": "object", "required": [ diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json index 776cfefbc1..0590e2802f 100644 --- a/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json +++ b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_details.json @@ -57,11 +57,59 @@ "additionalProperties": false }, "DealerType": { - "type": "string", - "enum": [ - "current", - "past", - "unknown" + "oneOf": [ + { + "type": "string", + "enum": [ + "unknown" + ] + }, + { + "type": "object", + "required": [ + "current" + ], + "properties": { + "current": { + "type": "object", + "required": [ + "assigned_index" + ], + "properties": { + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "past" + ], + "properties": { + "past": { + "type": "object", + "required": [ + "assigned_index" + ], + "properties": { + "assigned_index": { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } ] } } diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_dealer_indices.json b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_indices.json new file mode 100644 index 0000000000..2d8e0c8763 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_dealer_indices.json @@ -0,0 +1,46 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "PagedDealerIndexResponse", + "type": "object", + "required": [ + "indices" + ], + "properties": { + "indices": { + "type": "array", + "items": { + "type": "array", + "items": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "integer", + "format": "uint64", + "minimum": 0.0 + } + ], + "maxItems": 2, + "minItems": 2 + } + }, + "start_next_after": { + "description": "Field indicating paging information for the following queries if the caller wishes to get further entries.", + "anyOf": [ + { + "$ref": "#/definitions/Addr" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "Addr": { + "description": "A human readable address.\n\nIn Cosmos, this is typically bech32 encoded. But for multi-chain smart contracts no assumptions should be made other than being UTF-8 encoded and of reasonable length.\n\nThis type represents a validated address. It can be created in the following ways 1. Use `Addr::unchecked(input)` 2. Use `let checked: Addr = deps.api.addr_validate(input)?` 3. Use `let checked: Addr = deps.api.addr_humanize(canonical_addr)?` 4. Deserialize from JSON. This must only be done from JSON that was validated before such as a contract's state. `Addr` must not be used in messages sent by the user because this would result in unvalidated instances.\n\nThis type is immutable. If you really need to mutate it (Really? Are you sure?), create a mutable copy using `let mut mutable = Addr::to_string()` and operate on that `String` instance.", + "type": "string" + } + } +} From 914b8a6dc231625203e007976cc39389cef0336f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 12:20:05 +0000 Subject: [PATCH 032/394] updated the validator client --- .../nyxd/contract_traits/dkg_query_client.rs | 25 ++++++++----------- .../contract_traits/dkg_signing_client.rs | 3 +-- 2 files changed, 11 insertions(+), 17 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index 80cac432c9..978a585ce4 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -7,11 +7,12 @@ use crate::nyxd::error::NyxdError; use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; -use nym_coconut_dkg_common::types::ChunkIndex; +use cosmwasm_std::Addr; +use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex}; use serde::Deserialize; pub use nym_coconut_dkg_common::{ - dealer::{DealerDetailsResponse, PagedDealerResponse}, + dealer::{DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse}, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, DealingMetadataResponse, DealingStatusResponse, @@ -43,11 +44,6 @@ pub trait DkgQueryClient { self.query_dkg_contract(request).await } - async fn get_initial_dealers(&self) -> Result, NyxdError> { - let request = DkgQueryMsg::GetInitialDealers {}; - self.query_dkg_contract(request).await - } - async fn get_dealer_details( &self, address: &AccountId, @@ -67,12 +63,12 @@ pub trait DkgQueryClient { self.query_dkg_contract(request).await } - async fn get_past_dealers_paged( + async fn get_dealer_indices_paged( &self, start_after: Option, limit: Option, - ) -> Result { - let request = DkgQueryMsg::GetPastDealers { start_after, limit }; + ) -> Result { + let request = DkgQueryMsg::GetDealerIndices { start_after, limit }; self.query_dkg_contract(request).await } @@ -188,8 +184,8 @@ pub trait PagedDkgQueryClient: DkgQueryClient { collect_paged!(self, get_current_dealers_paged, dealers) } - async fn get_all_past_dealers(&self) -> Result, NyxdError> { - collect_paged!(self, get_past_dealers_paged, dealers) + async fn get_all_dealer_indices(&self) -> Result, NyxdError> { + collect_paged!(self, get_dealer_indices_paged, indices) } async fn get_all_verification_key_shares( @@ -239,15 +235,14 @@ mod tests { DkgQueryMsg::GetCurrentEpochThreshold {} => { client.get_current_epoch_threshold().ignore() } - DkgQueryMsg::GetInitialDealers {} => client.get_initial_dealers().ignore(), DkgQueryMsg::GetDealerDetails { dealer_address } => client .get_dealer_details(&dealer_address.parse().unwrap()) .ignore(), DkgQueryMsg::GetCurrentDealers { limit, start_after } => client .get_current_dealers_paged(start_after, limit) .ignore(), - DkgQueryMsg::GetPastDealers { limit, start_after } => { - client.get_past_dealers_paged(start_after, limit).ignore() + DkgQueryMsg::GetDealerIndices { limit, start_after } => { + client.get_dealer_indices_paged(start_after, limit).ignore() } DkgQueryMsg::GetDealingStatus { epoch_id, diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index 47b4a3d256..a1249070cc 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -85,10 +85,9 @@ pub trait DkgSigningClient { async fn submit_dealing_chunk( &self, chunk: PartialContractDealing, - resharing: bool, fee: Option, ) -> Result { - let req = DkgExecuteMsg::CommitDealingsChunk { chunk, resharing }; + let req = DkgExecuteMsg::CommitDealingsChunk { chunk }; self.execute_dkg_contract(fee, req, "dealing chunk commitment".to_string(), vec![]) .await From da70ae70a572e387ac1d85db64d2dd2cc065c2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 14:39:48 +0000 Subject: [PATCH 033/394] nym-api updates --- .../nyxd/contract_traits/dkg_query_client.rs | 19 ++++++++++ .../coconut-dkg/src/dealer.rs | 5 +++ .../coconut-dkg/src/msg.rs | 11 +++++- contracts/coconut-dkg/src/contract.rs | 9 +++++ contracts/coconut-dkg/src/dealers/queries.rs | 23 ++++++++++-- nym-api/src/coconut/client.rs | 20 ++++++----- nym-api/src/coconut/dkg/client.rs | 24 +++++++------ nym-api/src/coconut/dkg/dealing.rs | 35 +++++++++--------- nym-api/src/coconut/dkg/key_derivation.rs | 36 ++++++++++--------- nym-api/src/coconut/tests/mod.rs | 24 +++---------- nym-api/src/support/nyxd/mod.rs | 29 +++++++++------ 11 files changed, 149 insertions(+), 86 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index 978a585ce4..33ae58bc42 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -11,6 +11,7 @@ use cosmwasm_std::Addr; use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex}; use serde::Deserialize; +use nym_coconut_dkg_common::dealer::RegisteredDealerDetails; pub use nym_coconut_dkg_common::{ dealer::{DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse}, dealing::{ @@ -44,6 +45,18 @@ pub trait DkgQueryClient { self.query_dkg_contract(request).await } + async fn get_registered_dealer_details( + &self, + address: &AccountId, + epoch_id: Option, + ) -> Result { + let request = DkgQueryMsg::GetRegisteredDealer { + dealer_address: address.to_string(), + epoch_id, + }; + self.query_dkg_contract(request).await + } + async fn get_dealer_details( &self, address: &AccountId, @@ -235,6 +248,12 @@ mod tests { DkgQueryMsg::GetCurrentEpochThreshold {} => { client.get_current_epoch_threshold().ignore() } + DkgQueryMsg::GetRegisteredDealer { + dealer_address, + epoch_id, + } => client + .get_registered_dealer_details(&dealer_address.parse().unwrap(), epoch_id) + .ignore(), DkgQueryMsg::GetDealerDetails { dealer_address } => client .get_dealer_details(&dealer_address.parse().unwrap()) .ignore(), diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs index 3677d67dcd..2c0b1746eb 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/dealer.rs @@ -35,6 +35,11 @@ impl DealerType { } } +#[cw_serde] +pub struct RegisteredDealerDetails { + pub details: Option, +} + #[cw_serde] pub struct DealerDetailsResponse { pub details: Option, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index b048eb5f7d..02274926e9 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -11,7 +11,10 @@ use cosmwasm_schema::cw_serde; #[cfg(feature = "schema")] use crate::{ - dealer::{DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse}, + dealer::{ + DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse, + RegisteredDealerDetails, + }, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, DealingMetadataResponse, DealingStatusResponse, @@ -86,6 +89,12 @@ pub enum QueryMsg { #[cfg_attr(feature = "schema", returns(u64))] GetCurrentEpochThreshold {}, + #[cfg_attr(feature = "schema", returns(RegisteredDealerDetails))] + GetRegisteredDealer { + dealer_address: String, + epoch_id: Option, + }, + #[cfg_attr(feature = "schema", returns(DealerDetailsResponse))] GetDealerDetails { dealer_address: String }, diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index b8c5339ba8..01a3d38303 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -3,6 +3,7 @@ use crate::dealers::queries::{ query_current_dealers_paged, query_dealer_details, query_dealers_indices_paged, + query_registered_dealer_details, }; use crate::dealers::transactions::try_add_dealer; use crate::dealings::queries::{ @@ -130,6 +131,14 @@ pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { to_binary(&query_current_epoch_threshold(deps.storage)?)? } + QueryMsg::GetRegisteredDealer { + dealer_address, + epoch_id, + } => to_binary(&query_registered_dealer_details( + deps, + dealer_address, + epoch_id, + )?)?, QueryMsg::GetDealerDetails { dealer_address } => { to_binary(&query_dealer_details(deps, dealer_address)?)? } diff --git a/contracts/coconut-dkg/src/dealers/queries.rs b/contracts/coconut-dkg/src/dealers/queries.rs index 3bf0aa28f0..d88a739976 100644 --- a/contracts/coconut-dkg/src/dealers/queries.rs +++ b/contracts/coconut-dkg/src/dealers/queries.rs @@ -2,15 +2,34 @@ // SPDX-License-Identifier: Apache-2.0 use crate::dealers::storage::{ - self, get_dealer_details, get_dealer_index, DEALERS_INDICES, EPOCH_DEALERS_MAP, + self, get_dealer_details, get_dealer_index, get_registration_details, DEALERS_INDICES, + EPOCH_DEALERS_MAP, }; use crate::epoch_state::storage::CURRENT_EPOCH; use cosmwasm_std::{Deps, Order, StdResult}; use cw_storage_plus::Bound; use nym_coconut_dkg_common::dealer::{ DealerDetailsResponse, DealerType, PagedDealerIndexResponse, PagedDealerResponse, + RegisteredDealerDetails, }; -use nym_coconut_dkg_common::types::DealerDetails; +use nym_coconut_dkg_common::types::{DealerDetails, EpochId}; + +pub fn query_registered_dealer_details( + deps: Deps<'_>, + dealer_address: String, + epoch_id: Option, +) -> StdResult { + let addr = deps.api.addr_validate(&dealer_address)?; + + let epoch_id = match epoch_id { + Some(epoch_id) => epoch_id, + None => CURRENT_EPOCH.load(deps.storage)?.epoch_id, + }; + + Ok(RegisteredDealerDetails { + details: get_registration_details(deps.storage, &addr, epoch_id).ok(), + }) +} pub fn query_dealer_details( deps: Deps<'_>, diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index c4ef30ebef..414c89fcf1 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -5,13 +5,15 @@ use crate::coconut::error::Result; use cw3::{ProposalResponse, VoteResponse}; use cw4::MemberResponse; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; -use nym_coconut_dkg_common::dealer::{DealerDetails, DealerDetailsResponse}; +use nym_coconut_dkg_common::dealer::{ + DealerDetails, DealerDetailsResponse, RegisteredDealerDetails, +}; use nym_coconut_dkg_common::dealing::{ DealerDealingsStatusResponse, DealingChunkInfo, DealingMetadata, DealingStatusResponse, PartialContractDealing, }; use nym_coconut_dkg_common::types::{ - ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, InitialReplacementData, + ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, PartialContractDealingData, State, }; use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; @@ -47,10 +49,14 @@ pub trait Client { async fn get_current_epoch_threshold(&self) -> Result>; - async fn get_initial_dealers(&self) -> Result>; - async fn get_self_registered_dealer_details(&self) -> Result; + async fn get_registered_dealer_details( + &self, + epoch_id: EpochId, + dealer: String, + ) -> Result; + async fn get_dealer_dealings_status( &self, epoch_id: EpochId, @@ -111,11 +117,7 @@ pub trait Client { resharing: bool, ) -> Result; - async fn submit_dealing_chunk( - &self, - chunk: PartialContractDealing, - resharing: bool, - ) -> Result; + async fn submit_dealing_chunk(&self, chunk: PartialContractDealing) -> Result; async fn submit_verification_key_share( &self, diff --git a/nym-api/src/coconut/dkg/client.rs b/nym-api/src/coconut/dkg/client.rs index 9397d31a11..bad9ce6ea9 100644 --- a/nym-api/src/coconut/dkg/client.rs +++ b/nym-api/src/coconut/dkg/client.rs @@ -10,8 +10,8 @@ use nym_coconut_dkg_common::dealing::{ DealerDealingsStatusResponse, DealingChunkInfo, PartialContractDealing, }; use nym_coconut_dkg_common::types::{ - ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, InitialReplacementData, - NodeIndex, PartialContractDealingData, State as ContractState, + ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, NodeIndex, + PartialContractDealingData, State as ContractState, }; use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; use nym_contracts_common::IdentityKey; @@ -62,18 +62,23 @@ impl DkgClient { self.inner.get_current_epoch_threshold().await } - pub(crate) async fn get_initial_dealers( - &self, - ) -> Result, CoconutError> { - self.inner.get_initial_dealers().await - } - pub(crate) async fn get_self_registered_dealer_details( &self, ) -> Result { self.inner.get_self_registered_dealer_details().await } + pub(crate) async fn dealer_in_epoch( + &self, + epoch_id: EpochId, + dealer: String, + ) -> Result { + self.inner + .get_registered_dealer_details(epoch_id, dealer) + .await + .map(|d| d.details.is_some()) + } + pub(crate) async fn get_current_dealers(&self) -> Result, CoconutError> { self.inner.get_current_dealers().await } @@ -190,9 +195,8 @@ impl DkgClient { pub(crate) async fn submit_dealing_chunk( &self, chunk: PartialContractDealing, - resharing: bool, ) -> Result<(), CoconutError> { - self.inner.submit_dealing_chunk(chunk, resharing).await?; + self.inner.submit_dealing_chunk(chunk).await?; Ok(()) } diff --git a/nym-api/src/coconut/dkg/dealing.rs b/nym-api/src/coconut/dkg/dealing.rs index 77a6f3310e..0c5b8132a6 100644 --- a/nym-api/src/coconut/dkg/dealing.rs +++ b/nym-api/src/coconut/dkg/dealing.rs @@ -209,9 +209,7 @@ impl DkgController { .remove(chunk_index) .expect("chunking specification has changed mid-exchange!"); debug!("[dealing {dealing_index}]: resubmitting chunk index {chunk_index}"); - self.dkg_client - .submit_dealing_chunk(chunk, resharing) - .await?; + self.dkg_client.submit_dealing_chunk(chunk).await?; } } Ok(()) @@ -243,26 +241,28 @@ impl DkgController { let human_index = chunk_index + 1; debug!("[dealing {dealing_index}]: submitting chunk index {chunk_index} ({human_index}/{total_chunks})"); - self.dkg_client - .submit_dealing_chunk(chunk, resharing) - .await?; + self.dkg_client.submit_dealing_chunk(chunk).await?; } Ok(()) } /// Check whether this dealer can participate in the resharing - /// by looking into the contract and ensuring it's in the list of initial dealers for this epoch - async fn can_reshare(&self) -> Result { - let Some(initial_data) = self.dkg_client.get_initial_dealers().await? else { - return Ok(false); - }; + /// by looking into the contract and ensuring it's been a dealer in the previous epoch + async fn can_reshare(&self, epoch_id: EpochId) -> Result { + // SAFETY: + // it's impossible for the contract to trigger resharing for the 0th epoch + // otherwise some serious invariants have been broken + #[allow(clippy::expect_used)] + let previous_epoch_id = epoch_id + .checked_sub(1) + .expect("resharing epoch invariant has been broken"); let address = self.dkg_client.get_address().await; - Ok(initial_data - .initial_dealers - .iter() - .any(|d| d.as_str() == address.as_ref())) + Ok(self + .dkg_client + .dealer_in_epoch(previous_epoch_id, address.to_string()) + .await?) } /// Deal with the dealing generation case where the system requests resharing @@ -274,7 +274,7 @@ impl DkgController { old_keypair: KeyPairWithEpoch, ) -> Result<(), DealingGenerationError> { // make sure we're allowed to participate in resharing - if !self.can_reshare().await? { + if !self.can_reshare(epoch_id).await? { // we have to wait for other dealers to give us the dealings (hopefully) warn!("we we have an existing coconut keypair, but we're not allowed to participate in resharing"); return Ok(()); @@ -427,7 +427,7 @@ impl DkgController { // sure, the if statements could be collapsed, but i prefer to explicitly repeat the block for readability if resharing { debug!("resharing + no prior key -> nothing to do"); - if self.can_reshare().await? { + if self.can_reshare(epoch_id).await? { warn!("this dealer was expected to participate in resharing but it doesn't have any prior keys to use"); } } else { @@ -475,7 +475,6 @@ pub(crate) mod tests { }; use crate::coconut::tests::helpers::unchecked_decode_bte_key; use nym_coconut::{ttp_keygen, Parameters}; - use nym_coconut_dkg_common::types::InitialReplacementData; use nym_dkg::bte::PublicKeyWithProof; #[tokio::test] diff --git a/nym-api/src/coconut/dkg/key_derivation.rs b/nym-api/src/coconut/dkg/key_derivation.rs index 15f2a047d2..ca85716d13 100644 --- a/nym-api/src/coconut/dkg/key_derivation.rs +++ b/nym-api/src/coconut/dkg/key_derivation.rs @@ -186,7 +186,6 @@ impl DkgController { epoch_id: EpochId, dealer: &Addr, resharing: bool, - initial_dealers: &[Addr], ) -> Result>, DealerRejectionReason>, KeyDerivationError> { let dealing_statuses = self @@ -208,11 +207,25 @@ impl DkgController { )); } - // we might be in resharing mode and this dealer was not in "initial" set. - // in that case we don't expect any dealings - if resharing && !initial_dealers.contains(dealer) { - return Ok(Ok(HashMap::new())); + // if we're in the resharing mode and this dealer has not been a dealer in the previous epoch, + // we don't expect to have received anything from them + if resharing { + // SAFETY: + // it's impossible for the contract to trigger resharing for the 0th epoch + // otherwise some serious invariants have been broken + #[allow(clippy::expect_used)] + let previous_epoch_id = epoch_id + .checked_sub(1) + .expect("resharing epoch invariant has been broken"); + if !self + .dkg_client + .dealer_in_epoch(previous_epoch_id, dealer.to_string()) + .await? + { + return Ok(Ok(HashMap::new())); + } } + return Ok(Err(DealerRejectionReason::NoDealingsProvided)); } @@ -251,22 +264,13 @@ impl DkgController { let mut valid_dealings: BTreeMap<_, BTreeMap<_, _>> = BTreeMap::new(); // given at MOST we'll have like 50 entries here, iterating over entire vector for lookup is fine - let initial_dealers = self - .dkg_client - .get_initial_dealers() - .await? - .map(|i| i.initial_dealers) - .unwrap_or_default(); // for every valid dealer in this epoch, obtain its dealings for (dealer, dealer_index) in self.state.valid_epoch_receivers(epoch_id)? { // note: if we're in resharing mode, the contract itself will forbid submission of dealings from - // parties that were not "initial" dealers, so we don't have to worry about it + // parties that were dealers in the previous epoch, so we don't have to worry about it - let raw_dealings = match self - .get_raw_dealings(epoch_id, &dealer, resharing, &initial_dealers) - .await? - { + let raw_dealings = match self.get_raw_dealings(epoch_id, &dealer, resharing).await? { Ok(dealings) => dealings, Err(rejection) => { self.blacklist_dealer(epoch_id, dealer, rejection)?; diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index 5690c7c46e..eb055f3cfa 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -29,7 +29,7 @@ use nym_coconut_dkg_common::dealing::{ use nym_coconut_dkg_common::event_attributes::{DKG_PROPOSAL_ID, NODE_INDEX}; use nym_coconut_dkg_common::types::{ ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, EpochState, - InitialReplacementData, PartialContractDealingData, State as ContractState, + PartialContractDealingData, State as ContractState, }; use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; use nym_coconut_interface::VerificationKey; @@ -135,9 +135,9 @@ impl Dealing { pub(crate) struct FakeDkgContractState { pub(crate) address: AccountId, - pub(crate) dealers: HashMap, - pub(crate) past_dealers: HashMap, - pub(crate) initial_dealers: Option, + // pub(crate) dealers: HashMap, + // pub(crate) past_dealers: HashMap, + // pub(crate) initial_dealers: Option, // map of epoch id -> dealer -> dealings pub(crate) dealings: HashMap>>, @@ -651,16 +651,6 @@ impl super::client::Client for DummyClient { Ok(self.state.lock().unwrap().dkg_contract.threshold) } - async fn get_initial_dealers(&self) -> Result> { - Ok(self - .state - .lock() - .unwrap() - .dkg_contract - .initial_dealers - .clone()) - } - async fn get_self_registered_dealer_details(&self) -> Result { let address = self.validator_address.as_ref(); @@ -1081,11 +1071,7 @@ impl super::client::Client for DummyClient { }) } - async fn submit_dealing_chunk( - &self, - chunk: PartialContractDealing, - _resharing: bool, - ) -> Result { + async fn submit_dealing_chunk(&self, chunk: PartialContractDealing) -> Result { let mut guard = self.state.lock().unwrap(); let current_epoch = guard.dkg_contract.epoch.epoch_id; let current_height = guard.block_info.height; diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index d583669fe9..dcd60c1234 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -14,9 +14,7 @@ use nym_coconut_dkg_common::dealing::{ PartialContractDealing, }; use nym_coconut_dkg_common::msg::QueryMsg as DkgQueryMsg; -use nym_coconut_dkg_common::types::{ - ChunkIndex, DealingIndex, InitialReplacementData, PartialContractDealingData, State, -}; +use nym_coconut_dkg_common::types::{ChunkIndex, DealingIndex, PartialContractDealingData, State}; use nym_coconut_dkg_common::{ dealer::{DealerDetails, DealerDetailsResponse}, types::{EncodedBTEPublicKeyWithProof, Epoch, EpochId}, @@ -24,6 +22,7 @@ use nym_coconut_dkg_common::{ }; use nym_config::defaults::{ChainDetails, NymNetworkDetails}; +use nym_coconut_dkg_common::dealer::RegisteredDealerDetails; use nym_mixnet_contract_common::families::FamilyHead; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::reward_params::RewardingParams; @@ -412,12 +411,6 @@ impl crate::coconut::client::Client for Client { Ok(nyxd_query!(self, get_current_epoch_threshold().await?)) } - async fn get_initial_dealers( - &self, - ) -> crate::coconut::error::Result> { - Ok(nyxd_query!(self, get_initial_dealers().await?)) - } - async fn get_self_registered_dealer_details( &self, ) -> crate::coconut::error::Result { @@ -425,6 +418,21 @@ impl crate::coconut::client::Client for Client { Ok(nyxd_query!(self, get_dealer_details(self_address).await?)) } + async fn get_registered_dealer_details( + &self, + epoch_id: EpochId, + dealer: String, + ) -> crate::coconut::error::Result { + let dealer = dealer + .as_str() + .parse() + .map_err(|_| NyxdError::MalformedAccountAddress(dealer))?; + Ok(nyxd_query!( + self, + get_registered_dealer_details(&dealer, Some(epoch_id)).await? + )) + } + async fn get_dealer_dealings_status( &self, epoch_id: EpochId, @@ -547,11 +555,10 @@ impl crate::coconut::client::Client for Client { async fn submit_dealing_chunk( &self, chunk: PartialContractDealing, - resharing: bool, ) -> Result { Ok(nyxd_signing!( self, - submit_dealing_chunk(chunk, resharing, None).await? + submit_dealing_chunk(chunk, None).await? )) } From b960dc8aaf238dd5cd0ecc1f275852206074b40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 14:49:47 +0000 Subject: [PATCH 034/394] removed 'SurpassedThreshold' message --- .../contract_traits/dkg_signing_client.rs | 12 +-- .../coconut-dkg/src/msg.rs | 2 - .../coconut-dkg/schema/nym-coconut-dkg.json | 82 ++++++++++++++++--- contracts/coconut-dkg/schema/raw/execute.json | 13 --- contracts/coconut-dkg/schema/raw/query.json | 29 +++++++ .../response_to_get_registered_dealer.json | 40 +++++++++ contracts/coconut-dkg/src/contract.rs | 1 - 7 files changed, 140 insertions(+), 39 deletions(-) create mode 100644 contracts/coconut-dkg/schema/raw/response_to_get_registered_dealer.json diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index a1249070cc..e347c86b0f 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -39,13 +39,6 @@ pub trait DkgSigningClient { .await } - async fn surpass_threshold(&self, fee: Option) -> Result { - let req = DkgExecuteMsg::SurpassedThreshold {}; - - self.execute_dkg_contract(fee, req, "surpass DKG threshold".to_string(), vec![]) - .await - } - async fn register_dealer( &self, bte_key: EncodedBTEPublicKeyWithProof, @@ -191,8 +184,8 @@ mod tests { } => client .submit_dealing_metadata(dealing_index, chunks, resharing, None) .ignore(), - DkgExecuteMsg::CommitDealingsChunk { chunk, resharing } => { - client.submit_dealing_chunk(chunk, resharing, None).ignore() + DkgExecuteMsg::CommitDealingsChunk { chunk } => { + client.submit_dealing_chunk(chunk, None).ignore() } DkgExecuteMsg::CommitVerificationKeyShare { share, resharing } => client .submit_verification_key_share(share, resharing, None) @@ -200,7 +193,6 @@ mod tests { DkgExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => client .verify_verification_key_share(&owner.parse().unwrap(), resharing, None) .ignore(), - DkgExecuteMsg::SurpassedThreshold {} => client.surpass_threshold(None).ignore(), DkgExecuteMsg::AdvanceEpochState {} => client.advance_dkg_epoch_state(None).ignore(), }; } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 02274926e9..8874bce5cb 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -68,8 +68,6 @@ pub enum ExecuteMsg { resharing: bool, }, - SurpassedThreshold {}, - AdvanceEpochState {}, TriggerReset {}, diff --git a/contracts/coconut-dkg/schema/nym-coconut-dkg.json b/contracts/coconut-dkg/schema/nym-coconut-dkg.json index e6fca1f892..3f64c4f100 100644 --- a/contracts/coconut-dkg/schema/nym-coconut-dkg.json +++ b/contracts/coconut-dkg/schema/nym-coconut-dkg.json @@ -242,19 +242,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "surpassed_threshold" - ], - "properties": { - "surpassed_threshold": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ @@ -387,6 +374,35 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "get_registered_dealer" + ], + "properties": { + "get_registered_dealer": { + "type": "object", + "required": [ + "dealer_address" + ], + "properties": { + "dealer_address": { + "type": "string" + }, + "epoch_id": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "type": "object", "required": [ @@ -1594,6 +1610,46 @@ } } }, + "get_registered_dealer": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredDealerDetails", + "type": "object", + "properties": { + "details": { + "anyOf": [ + { + "$ref": "#/definitions/DealerRegistrationDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "DealerRegistrationDetails": { + "type": "object", + "required": [ + "announce_address", + "bte_public_key_with_proof", + "ed25519_identity" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "bte_public_key_with_proof": { + "type": "string" + }, + "ed25519_identity": { + "type": "string" + } + }, + "additionalProperties": false + } + } + }, "get_state": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "State", diff --git a/contracts/coconut-dkg/schema/raw/execute.json b/contracts/coconut-dkg/schema/raw/execute.json index b1395d8c2e..34547d0026 100644 --- a/contracts/coconut-dkg/schema/raw/execute.json +++ b/contracts/coconut-dkg/schema/raw/execute.json @@ -153,19 +153,6 @@ }, "additionalProperties": false }, - { - "type": "object", - "required": [ - "surpassed_threshold" - ], - "properties": { - "surpassed_threshold": { - "type": "object", - "additionalProperties": false - } - }, - "additionalProperties": false - }, { "type": "object", "required": [ diff --git a/contracts/coconut-dkg/schema/raw/query.json b/contracts/coconut-dkg/schema/raw/query.json index d55ad0769c..714003786d 100644 --- a/contracts/coconut-dkg/schema/raw/query.json +++ b/contracts/coconut-dkg/schema/raw/query.json @@ -41,6 +41,35 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "get_registered_dealer" + ], + "properties": { + "get_registered_dealer": { + "type": "object", + "required": [ + "dealer_address" + ], + "properties": { + "dealer_address": { + "type": "string" + }, + "epoch_id": { + "type": [ + "integer", + "null" + ], + "format": "uint64", + "minimum": 0.0 + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "type": "object", "required": [ diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_registered_dealer.json b/contracts/coconut-dkg/schema/raw/response_to_get_registered_dealer.json new file mode 100644 index 0000000000..8a70bb3ce4 --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_get_registered_dealer.json @@ -0,0 +1,40 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "RegisteredDealerDetails", + "type": "object", + "properties": { + "details": { + "anyOf": [ + { + "$ref": "#/definitions/DealerRegistrationDetails" + }, + { + "type": "null" + } + ] + } + }, + "additionalProperties": false, + "definitions": { + "DealerRegistrationDetails": { + "type": "object", + "required": [ + "announce_address", + "bte_public_key_with_proof", + "ed25519_identity" + ], + "properties": { + "announce_address": { + "type": "string" + }, + "bte_public_key_with_proof": { + "type": "string" + }, + "ed25519_identity": { + "type": "string" + } + }, + "additionalProperties": false + } + } +} diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index 01a3d38303..b1926206c6 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -116,7 +116,6 @@ pub fn execute( ExecuteMsg::VerifyVerificationKeyShare { owner, resharing } => { try_verify_verification_key_share(deps, info, owner, resharing) } - ExecuteMsg::SurpassedThreshold {} => todo!(), ExecuteMsg::AdvanceEpochState {} => try_advance_epoch_state(deps, env), ExecuteMsg::TriggerReset {} => try_trigger_reset(deps, env, info), ExecuteMsg::TriggerResharing {} => try_trigger_resharing(deps, env, info), From db826c4fb4713f8624abd33046c86861ea31a02a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 15:28:02 +0000 Subject: [PATCH 035/394] missing DkgExecuteMsg client impls --- .../nyxd/contract_traits/dkg_signing_client.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs index e347c86b0f..11c378420b 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_signing_client.rs @@ -122,6 +122,20 @@ pub trait DkgSigningClient { ) .await } + + async fn trigger_dkg_reset(&self, fee: Option) -> Result { + let req = DkgExecuteMsg::TriggerReset {}; + + self.execute_dkg_contract(fee, req, "trigger DKG reset".to_string(), vec![]) + .await + } + + async fn trigger_dkg_resharing(&self, fee: Option) -> Result { + let req = DkgExecuteMsg::TriggerResharing {}; + + self.execute_dkg_contract(fee, req, "trigger DKG resharing".to_string(), vec![]) + .await + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -194,6 +208,8 @@ mod tests { .verify_verification_key_share(&owner.parse().unwrap(), resharing, None) .ignore(), DkgExecuteMsg::AdvanceEpochState {} => client.advance_dkg_epoch_state(None).ignore(), + DkgExecuteMsg::TriggerReset {} => client.trigger_dkg_reset(None).ignore(), + DkgExecuteMsg::TriggerResharing {} => client.trigger_dkg_resharing(None).ignore(), }; } } From be3dd2c2509499afd75d552eb77386931032fc81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 17:30:54 +0000 Subject: [PATCH 036/394] setting threshold value upon entering dealing exchange --- common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs | 4 ++++ .../src/epoch_state/transactions/advance_epoch_state.rs | 9 +++++++++ 2 files changed, 13 insertions(+) diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index bd0f1d4e1a..a4d0afb077 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -270,4 +270,8 @@ impl EpochState { pub fn is_in_progress(&self) -> bool { matches!(self, EpochState::InProgress) } + + pub fn is_dealing_exchange(&self) -> bool { + matches!(self, EpochState::DealingExchange { .. }) + } } diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs index 715a6e5656..57681ed3cf 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -54,6 +54,15 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result Date: Thu, 15 Feb 2024 20:19:46 +0000 Subject: [PATCH 037/394] fixed nym-api tests --- nym-api/src/coconut/dkg/dealing.rs | 34 +- nym-api/src/coconut/tests/fixtures.rs | 45 +- nym-api/src/coconut/tests/mod.rs | 619 ++++++++++++++------------ 3 files changed, 389 insertions(+), 309 deletions(-) diff --git a/nym-api/src/coconut/dkg/dealing.rs b/nym-api/src/coconut/dkg/dealing.rs index 0c5b8132a6..6c4074af72 100644 --- a/nym-api/src/coconut/dkg/dealing.rs +++ b/nym-api/src/coconut/dkg/dealing.rs @@ -286,7 +286,7 @@ impl DkgController { // it could be outdated and we can't use it for resharing let previous = epoch_id.saturating_sub(1); if old_keypair.issued_for_epoch != previous { - warn!("our existing coconut keypair has been generated for an distant epoch ({} vs expected {previous} for resharing)", old_keypair.issued_for_epoch); + warn!("our existing coconut keypair has been generated for a distant epoch ({} vs expected {previous} for resharing)", old_keypair.issued_for_epoch); // don't participate in resharing return Ok(()); } @@ -475,6 +475,7 @@ pub(crate) mod tests { }; use crate::coconut::tests::helpers::unchecked_decode_bte_key; use nym_coconut::{ttp_keygen, Parameters}; + use nym_coconut_dkg_common::types::DealerRegistrationDetails; use nym_dkg::bte::PublicKeyWithProof; #[tokio::test] @@ -615,7 +616,7 @@ pub(crate) mod tests { let dealers = dealers_fixtures(&mut rng, 4); let self_dealer = dealers[0].clone(); - let epoch = 0; + let epoch = 1; let mut keys = ttp_keygen(&Parameters::new(4).unwrap(), 3, 4).unwrap(); let coconut_keypair = KeyPair::new(); @@ -672,29 +673,42 @@ pub(crate) mod tests { let dealers = dealers_fixtures(&mut rng, 4); let self_dealer = dealers[0].clone(); - let epoch = 0; + let epoch = 1; let mut keys = ttp_keygen(&Parameters::new(4).unwrap(), 3, 4).unwrap(); let coconut_keypair = KeyPair::new(); coconut_keypair - .set(KeyPairWithEpoch::new(keys.pop().unwrap(), epoch)) + .set(KeyPairWithEpoch::new(keys.pop().unwrap(), epoch - 1)) .await; - let initial_dealers = InitialReplacementData { - initial_dealers: vec![self_dealer.address.clone()], - initial_height: 100, - }; - let mut controller = TestingDkgControllerBuilder::default() .with_threshold(3) .with_dealers(dealers.clone()) .with_as_dealer(self_dealer.clone()) .with_keypair(coconut_keypair) .with_initial_epoch_id(epoch) - .with_initial_dealers(initial_dealers) .build() .await; + let chain = controller.chain_state.clone(); + + // TODO: put that functionality in the builder + chain + .lock() + .unwrap() + .dkg_contract + .dealers + .entry(epoch - 1) + .or_default() + .insert( + self_dealer.address.to_string(), + DealerRegistrationDetails { + bte_public_key_with_proof: self_dealer.bte_public_key_with_proof.clone(), + ed25519_identity: self_dealer.ed25519_identity.clone(), + announce_address: self_dealer.announce_address.clone(), + }, + ); + let key_size = controller.dkg_client.get_contract_state().await?.key_size; let res = controller.dealing_exchange(epoch, true).await; diff --git a/nym-api/src/coconut/tests/fixtures.rs b/nym-api/src/coconut/tests/fixtures.rs index b7da76d805..36e416df19 100644 --- a/nym-api/src/coconut/tests/fixtures.rs +++ b/nym-api/src/coconut/tests/fixtures.rs @@ -10,7 +10,8 @@ use crate::coconut::keys::KeyPair; use crate::coconut::tests::{DummyClient, SharedFakeChain}; use cosmwasm_std::Addr; use nym_coconut::VerificationKey; -use nym_coconut_dkg_common::types::{DealerDetails, EpochId, InitialReplacementData}; +use nym_coconut_dkg_common::dealer::DealerRegistrationDetails; +use nym_coconut_dkg_common::types::{DealerDetails, EpochId}; use nym_crypto::asymmetric::identity; use nym_dkg::bte::keys::KeyPair as DkgKeyPair; use nym_dkg::{NodeIndex, Threshold}; @@ -81,7 +82,6 @@ pub struct TestingDkgControllerBuilder { threshold: Option, self_dealer: Option, dealers: Vec, - initial_dealers: Option, } impl TestingDkgControllerBuilder { @@ -127,11 +127,6 @@ impl TestingDkgControllerBuilder { self } - pub fn with_initial_dealers(mut self, initial_dealers: InitialReplacementData) -> Self { - self.initial_dealers = Some(initial_dealers); - self - } - #[allow(dead_code)] pub fn with_address(mut self, address: impl Into) -> Self { let addr = address.into(); @@ -181,20 +176,34 @@ impl TestingDkgControllerBuilder { // insert initial data into the chain state { let mut state_guard = chain_state.lock().unwrap(); - if let Some(threshold) = self.threshold { - state_guard.dkg_contract.threshold = Some(threshold) - } - for dealer in self.dealers { - state_guard - .dkg_contract - .dealers - .insert(dealer.assigned_index, dealer); - } if let Some(epoch_id) = self.epoch_id { state_guard.dkg_contract.epoch.epoch_id = epoch_id; } - if let Some(initial_dealers) = self.initial_dealers { - state_guard.dkg_contract.initial_dealers = Some(initial_dealers) + if let Some(threshold) = self.threshold { + state_guard.dkg_contract.threshold = Some(threshold) + } + let epoch_id = state_guard.dkg_contract.epoch.epoch_id; + + for dealer in self.dealers { + let epoch_dealers = state_guard + .dkg_contract + .dealers + .entry(epoch_id) + .or_default(); + + epoch_dealers.insert( + dealer.address.to_string(), + DealerRegistrationDetails { + bte_public_key_with_proof: dealer.bte_public_key_with_proof, + ed25519_identity: dealer.ed25519_identity, + announce_address: dealer.announce_address, + }, + ); + + state_guard + .dkg_contract + .dealer_indices + .insert(dealer.address.to_string(), dealer.assigned_index); } } diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index eb055f3cfa..c28bb78398 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -21,15 +21,17 @@ use nym_coconut_bandwidth_contract_common::events::{ DEPOSIT_VALUE, }; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredentialResponse; -use nym_coconut_dkg_common::dealer::{DealerDetails, DealerDetailsResponse, DealerType}; +use nym_coconut_dkg_common::dealer::{ + DealerDetails, DealerDetailsResponse, DealerType, RegisteredDealerDetails, +}; use nym_coconut_dkg_common::dealing::{ DealerDealingsStatusResponse, DealingChunkInfo, DealingMetadata, DealingStatus, DealingStatusResponse, PartialContractDealing, }; use nym_coconut_dkg_common::event_attributes::{DKG_PROPOSAL_ID, NODE_INDEX}; use nym_coconut_dkg_common::types::{ - ChunkIndex, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, EpochId, EpochState, - PartialContractDealingData, State as ContractState, + ChunkIndex, DealerRegistrationDetails, DealingIndex, EncodedBTEPublicKeyWithProof, Epoch, + EpochId, EpochState, PartialContractDealingData, State as ContractState, }; use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; use nym_coconut_interface::VerificationKey; @@ -38,7 +40,6 @@ use nym_contracts_common::IdentityKey; use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_crypto::asymmetric::{encryption, identity}; use nym_dkg::{NodeIndex, Threshold}; -use nym_mixnet_contract_common::BlockHeight; use nym_validator_client::nym_api::routes::{ API_VERSION, BANDWIDTH, COCONUT_BLIND_SIGN, COCONUT_ROUTES, }; @@ -53,7 +54,6 @@ use rand_07::RngCore; use rocket::http::Status; use rocket::local::asynchronous::Client; use std::collections::{BTreeMap, HashMap}; -use std::mem; use std::ops::Deref; use std::str::FromStr; use std::sync::atomic::{AtomicU64, Ordering}; @@ -138,6 +138,10 @@ pub(crate) struct FakeDkgContractState { // pub(crate) dealers: HashMap, // pub(crate) past_dealers: HashMap, // pub(crate) initial_dealers: Option, + pub(crate) dealer_indices: HashMap, + + // map of epoch id -> dealer -> info + pub(crate) dealers: HashMap>, // map of epoch id -> dealer -> dealings pub(crate) dealings: HashMap>>, @@ -151,41 +155,84 @@ pub(crate) struct FakeDkgContractState { } impl FakeDkgContractState { - pub(crate) fn verified_dealers(&self) -> Vec { - let epoch_id = self.epoch.epoch_id; - let Some(shares) = self.verification_shares.get(&epoch_id) else { - return Vec::new(); - }; - - shares - .values() - .filter(|s| s.verified) - .map(|s| s.owner.clone()) - .collect() - } + // pub(crate) fn verified_dealers(&self) -> Vec { + // let epoch_id = self.epoch.epoch_id; + // let Some(shares) = self.verification_shares.get(&epoch_id) else { + // return Vec::new(); + // }; + // + // shares + // .values() + // .filter(|s| s.verified) + // .map(|s| s.owner.clone()) + // .collect() + // } fn reset_dkg_state(&mut self) { self.threshold = None; - let dealers = mem::take(&mut self.dealers); - for (index, details) in dealers { - self.past_dealers.insert(index, details); - } } - pub(crate) fn reset_epoch_in_reshare_mode(&mut self, block_height: BlockHeight) { - if let Some(initial_dealers) = self.initial_dealers.as_mut() { - initial_dealers.initial_height = block_height; - } else { - self.initial_dealers = Some(InitialReplacementData { - initial_dealers: self.verified_dealers(), - initial_height: block_height, - }) - } - + pub(crate) fn reset_epoch_in_reshare_mode(&mut self) { self.reset_dkg_state(); self.epoch.state = EpochState::PublicKeySubmission { resharing: true }; self.epoch.epoch_id += 1; } + + pub(crate) fn reset_dkg(&mut self) { + self.reset_dkg_state(); + self.epoch.state = EpochState::PublicKeySubmission { resharing: false }; + self.epoch.epoch_id += 1; + } + + pub(crate) fn get_registration_details( + &self, + addr: &str, + epoch_id: EpochId, + ) -> Option { + self.dealers.get(&epoch_id)?.get(addr).cloned() + } + + pub(crate) fn get_dealer_details( + &self, + addr: &str, + epoch_id: EpochId, + ) -> Option { + let registration_details = self.get_registration_details(addr, epoch_id)?; + let assigned_index = self.get_dealer_index(addr)?; + + Some(DealerDetails { + address: Addr::unchecked(addr), + bte_public_key_with_proof: registration_details.bte_public_key_with_proof, + ed25519_identity: registration_details.ed25519_identity, + announce_address: registration_details.announce_address, + assigned_index, + }) + } + + // implementation copied from our contract + pub(crate) fn query_dealer_details(&self, addr: &str) -> DealerDetailsResponse { + let current_epoch_id = self.epoch.epoch_id; + + // if the address has registration data for the current epoch, it means it's an active dealer + if let Some(dealer_details) = self.get_dealer_details(addr, current_epoch_id) { + let assigned_index = dealer_details.assigned_index; + return DealerDetailsResponse::new( + Some(dealer_details), + DealerType::Current { assigned_index }, + ); + } + + // and if has had an assigned index it must have been a dealer at some point in the past + if let Some(assigned_index) = self.get_dealer_index(addr) { + return DealerDetailsResponse::new(None, DealerType::Past { assigned_index }); + } + + DealerDetailsResponse::new(None, DealerType::Unknown) + } + + pub(crate) fn get_dealer_index(&self, addr: &str) -> Option { + self.dealer_indices.get(addr).copied() + } } #[derive(Debug)] @@ -274,8 +321,8 @@ impl Default for FakeChainState { dkg_contract: FakeDkgContractState { address: dkg_contract.as_ref().parse().unwrap(), + dealer_indices: Default::default(), dealers: HashMap::new(), - past_dealers: Default::default(), epoch: Epoch::default(), contract_state: ContractState { @@ -287,7 +334,6 @@ impl Default for FakeChainState { dealings: HashMap::new(), verification_shares: HashMap::new(), threshold: None, - initial_dealers: None, }, group_contract: FakeGroupContractState { address: group_contract, @@ -307,6 +353,18 @@ impl Default for FakeChainState { } impl FakeChainState { + pub(crate) fn get_or_assign_dealer(&mut self, addr: &str) -> NodeIndex { + if let Some(index) = self.dkg_contract.dealer_indices.get(addr) { + *index + } else { + let new = self._counters.next_node_index(); + self.dkg_contract + .dealer_indices + .insert(addr.to_string(), new); + new + } + } + pub(crate) fn total_group_weight(&self) -> u64 { self.group_contract.total_weight() } @@ -320,8 +378,12 @@ impl FakeChainState { } pub(crate) fn advance_epoch_in_reshare_mode(&mut self) { - self.dkg_contract - .reset_epoch_in_reshare_mode(self.block_info.height) + self.dkg_contract.reset_epoch_in_reshare_mode() + } + + #[allow(unused)] + pub(crate) fn advance_epoch_in_reset_mode(&mut self) { + self.dkg_contract.reset_dkg() } // TODO: make it return a result @@ -519,25 +581,25 @@ impl DummyClient { // // self // } - async fn get_dealer_by_address(&self, address: &str) -> Option { - let guard = self.state.lock().unwrap(); - for dealer in guard.dkg_contract.dealers.values() { - if dealer.address.as_str() == address { - return Some(dealer.clone()); - } - } - None - } - - async fn get_past_dealer_by_address(&self, address: &str) -> Option { - let guard = self.state.lock().unwrap(); - for dealer in guard.dkg_contract.past_dealers.values() { - if dealer.address.as_str() == address { - return Some(dealer.clone()); - } - } - None - } + // async fn get_dealer_by_address(&self, address: &str) -> Option { + // let guard = self.state.lock().unwrap(); + // for dealer in guard.dkg_contract.dealers.values() { + // if dealer.address.as_str() == address { + // return Some(dealer.clone()); + // } + // } + // None + // } + // + // async fn get_past_dealer_by_address(&self, address: &str) -> Option { + // let guard = self.state.lock().unwrap(); + // for dealer in guard.dkg_contract.past_dealers.values() { + // if dealer.address.as_str() == address { + // return Some(dealer.clone()); + // } + // } + // None + // } } #[async_trait] @@ -653,24 +715,74 @@ impl super::client::Client for DummyClient { async fn get_self_registered_dealer_details(&self) -> Result { let address = self.validator_address.as_ref(); + Ok(self + .state + .lock() + .unwrap() + .dkg_contract + .query_dealer_details(address)) + } - if let Some(details) = self.get_dealer_by_address(address).await { - return Ok(DealerDetailsResponse { - details: Some(details), - dealer_type: DealerType::Current, + async fn get_registered_dealer_details( + &self, + epoch_id: EpochId, + dealer: String, + ) -> Result { + let details = self + .state + .lock() + .unwrap() + .dkg_contract + .dealers + .get(&epoch_id) + .and_then(|dealers| dealers.get(&dealer)) + .cloned(); + Ok(RegisteredDealerDetails { details }) + } + + async fn get_dealer_dealings_status( + &self, + epoch_id: EpochId, + dealer: String, + ) -> Result { + let guard = self.state.lock().unwrap(); + let key_size = guard.dkg_contract.contract_state.key_size; + + let dealer_addr = Addr::unchecked(&dealer); + + let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { + return Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: dealer_addr, + all_dealings_fully_submitted: false, + dealing_submission_status: Default::default(), }); + }; + + let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { + return Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: dealer_addr, + all_dealings_fully_submitted: false, + dealing_submission_status: Default::default(), + }); + }; + + let mut dealing_submission_status: BTreeMap = BTreeMap::new(); + for dealing_index in 0..key_size { + let metadata = dealer_dealings + .get(&dealing_index) + .map(|d| d.metadata.clone()); + dealing_submission_status.insert(dealing_index, metadata.into()); } - if let Some(details) = self.get_past_dealer_by_address(address).await { - return Ok(DealerDetailsResponse { - details: Some(details), - dealer_type: DealerType::Past, - }); - } - - Ok(DealerDetailsResponse { - details: None, - dealer_type: DealerType::Unknown, + Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: Addr::unchecked(&dealer), + all_dealings_fully_submitted: dealing_submission_status + .values() + .all(|d| d.fully_submitted), + dealing_submission_status, }) } @@ -699,17 +811,75 @@ impl super::client::Client for DummyClient { } async fn get_current_dealers(&self) -> Result> { - Ok(self - .state - .lock() - .unwrap() - .dkg_contract - .dealers - .values() - .cloned() + let chain = self.state.lock().unwrap(); + let current_epoch_id = chain.dkg_contract.epoch.epoch_id; + + let Some(epoch_dealers) = chain.dkg_contract.dealers.get(¤t_epoch_id) else { + return Ok(Vec::new()); + }; + + Ok(epoch_dealers + .iter() + .map(|(address, details)| { + let assigned_index = chain.dkg_contract.get_dealer_index(address).unwrap(); + DealerDetails { + address: Addr::unchecked(address), + bte_public_key_with_proof: details.bte_public_key_with_proof.clone(), + ed25519_identity: details.ed25519_identity.clone(), + announce_address: details.announce_address.clone(), + assigned_index, + } + }) .collect()) } + async fn get_dealing_metadata( + &self, + epoch_id: EpochId, + dealer: String, + dealing_index: DealingIndex, + ) -> Result> { + let guard = self.state.lock().unwrap(); + + let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { + return Ok(None); + }; + + let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { + return Ok(None); + }; + + let Some(dealing) = dealer_dealings.get(&dealing_index) else { + return Ok(None); + }; + + Ok(Some(dealing.metadata.clone())) + } + + async fn get_dealing_chunk( + &self, + epoch_id: EpochId, + dealer: &str, + dealing_index: DealingIndex, + chunk_index: ChunkIndex, + ) -> Result> { + let guard = self.state.lock().unwrap(); + + let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { + return Ok(None); + }; + + let Some(dealer_dealings) = epoch_dealings.get(dealer) else { + return Ok(None); + }; + + let Some(dealing) = dealer_dealings.get(&dealing_index) else { + return Ok(None); + }; + + Ok(dealing.chunks.get(&chunk_index).cloned()) + } + async fn get_verification_key_share( &self, epoch_id: EpochId, @@ -733,7 +903,6 @@ impl super::client::Client for DummyClient { Some(epoch_shares) => Ok(epoch_shares.values().cloned().collect()), } } - async fn vote_proposal( &self, proposal_id: u64, @@ -819,43 +988,23 @@ impl super::client::Client for DummyClient { announce_address: String, _resharing: bool, ) -> Result { - let assigned_index = if let Some(already_registered) = self - .get_dealer_by_address(self.validator_address.as_ref()) - .await - { - // current dealer - already_registered.assigned_index - } else if let Some(registered_in_the_past) = self - .get_past_dealer_by_address(self.validator_address.as_ref()) - .await - { - // past dealer - let index = registered_in_the_past.assigned_index; - let mut guard = self.state.lock().unwrap(); - guard - .dkg_contract - .dealers - .insert(index, registered_in_the_past); - - index - } else { - // new dealer - let mut guard = self.state.lock().unwrap(); - let assigned_index = guard._counters.next_node_index(); - - guard.dkg_contract.dealers.insert( - assigned_index, - DealerDetails { - address: Addr::unchecked(self.validator_address.to_string()), - bte_public_key_with_proof, - ed25519_identity: identity_key, - announce_address, - assigned_index, - }, - ); - assigned_index - }; let mut guard = self.state.lock().unwrap(); + let assigned_index = guard.get_or_assign_dealer(self.validator_address.as_ref()); + let epoch = guard.dkg_contract.epoch.epoch_id; + + let dealer_details = DealerRegistrationDetails { + bte_public_key_with_proof, + ed25519_identity: identity_key, + announce_address, + }; + + let epoch_dealers = guard.dkg_contract.dealers.entry(epoch).or_default(); + if !epoch_dealers.contains_key(self.validator_address.as_ref()) { + epoch_dealers.insert(self.validator_address.to_string(), dealer_details); + } else { + unimplemented!("already registered") + } + let transaction_hash = guard._counters.next_tx_hash(); Ok(ExecuteResult { @@ -869,174 +1018,6 @@ impl super::client::Client for DummyClient { gas_info: Default::default(), }) } - async fn submit_verification_key_share( - &self, - share: VerificationKeyShare, - resharing: bool, - ) -> Result { - let address = self.validator_address.to_string(); - - let Some(dealer_details) = self.get_dealer_by_address(&address).await else { - // Just throw some error, not really the correct one - return Err(CoconutError::DepositEncrKeyNotFound); - }; - - let mut chain = self.state.lock().unwrap(); - let dkg_contract = chain.dkg_contract.address.clone(); - let epoch_id = chain.dkg_contract.epoch.epoch_id; - - chain - .dkg_contract - .verification_shares - .entry(epoch_id) - .or_default() - .insert( - self.validator_address.to_string(), - ContractVKShare { - share, - announce_address: dealer_details.announce_address.clone(), - node_index: dealer_details.assigned_index, - owner: Addr::unchecked(&address), - epoch_id, - verified: false, - }, - ); - - let proposal_id = chain._counters.next_proposal_id(); - let verify_vk_share_req = - nym_coconut_dkg_common::msg::ExecuteMsg::VerifyVerificationKeyShare { - owner: address, - resharing, - }; - let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute { - contract_addr: chain.dkg_contract.address.to_string(), - msg: to_binary(&verify_vk_share_req).unwrap(), - funds: vec![], - }); - let proposal = Proposal { - title: String::new(), - description: String::new(), - msgs: vec![verify_vk_share_msg], - status: cw3::Status::Open, - expires: cw_utils::Expiration::Never {}, - threshold: cw_utils::Threshold::AbsolutePercentage { - percentage: Decimal::from_ratio(2u32, 3u32), - }, - total_weight: chain.total_group_weight(), - votes: Votes::yes(0), - proposer: Addr::unchecked(dkg_contract.as_ref()), - deposit: None, - start_height: 0, - }; - chain - .multisig_contract - .proposals - .insert(proposal_id, proposal); - let transaction_hash = chain._counters.next_tx_hash(); - Ok(ExecuteResult { - logs: vec![Log { - msg_index: 0, - events: vec![cosmwasm_std::Event::new("wasm") - .add_attribute(DKG_PROPOSAL_ID, proposal_id.to_string())], - }], - data: Default::default(), - transaction_hash, - gas_info: Default::default(), - }) - } - - async fn get_dealer_dealings_status( - &self, - epoch_id: EpochId, - dealer: String, - ) -> Result { - let guard = self.state.lock().unwrap(); - let key_size = guard.dkg_contract.contract_state.key_size; - - let dealer_addr = Addr::unchecked(&dealer); - - let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { - return Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: dealer_addr, - all_dealings_fully_submitted: false, - dealing_submission_status: Default::default(), - }); - }; - - let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { - return Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: dealer_addr, - all_dealings_fully_submitted: false, - dealing_submission_status: Default::default(), - }); - }; - - let mut dealing_submission_status: BTreeMap = BTreeMap::new(); - for dealing_index in 0..key_size { - let metadata = dealer_dealings - .get(&dealing_index) - .map(|d| d.metadata.clone()); - dealing_submission_status.insert(dealing_index, metadata.into()); - } - - Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: Addr::unchecked(&dealer), - all_dealings_fully_submitted: dealing_submission_status - .values() - .all(|d| d.fully_submitted), - dealing_submission_status, - }) - } - - async fn get_dealing_metadata( - &self, - epoch_id: EpochId, - dealer: String, - dealing_index: DealingIndex, - ) -> Result> { - let guard = self.state.lock().unwrap(); - - let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { - return Ok(None); - }; - - let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { - return Ok(None); - }; - - let Some(dealing) = dealer_dealings.get(&dealing_index) else { - return Ok(None); - }; - - Ok(Some(dealing.metadata.clone())) - } - - async fn get_dealing_chunk( - &self, - epoch_id: EpochId, - dealer: &str, - dealing_index: DealingIndex, - chunk_index: ChunkIndex, - ) -> Result> { - let guard = self.state.lock().unwrap(); - - let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { - return Ok(None); - }; - - let Some(dealer_dealings) = epoch_dealings.get(dealer) else { - return Ok(None); - }; - - let Some(dealing) = dealer_dealings.get(&dealing_index) else { - return Ok(None); - }; - - Ok(dealing.chunks.get(&chunk_index).cloned()) - } async fn submit_dealing_metadata( &self, @@ -1104,6 +1085,82 @@ impl super::client::Client for DummyClient { gas_info: Default::default(), }) } + + async fn submit_verification_key_share( + &self, + share: VerificationKeyShare, + resharing: bool, + ) -> Result { + let mut chain = self.state.lock().unwrap(); + + let address = self.validator_address.to_string(); + let epoch_id = chain.dkg_contract.epoch.epoch_id; + let Some(dealer_details) = chain.dkg_contract.get_dealer_details(&address, epoch_id) else { + // Just throw some error, not really the correct one + return Err(CoconutError::DepositEncrKeyNotFound); + }; + + let dkg_contract = chain.dkg_contract.address.clone(); + + chain + .dkg_contract + .verification_shares + .entry(epoch_id) + .or_default() + .insert( + self.validator_address.to_string(), + ContractVKShare { + share, + announce_address: dealer_details.announce_address.clone(), + node_index: dealer_details.assigned_index, + owner: Addr::unchecked(&address), + epoch_id, + verified: false, + }, + ); + + let proposal_id = chain._counters.next_proposal_id(); + let verify_vk_share_req = + nym_coconut_dkg_common::msg::ExecuteMsg::VerifyVerificationKeyShare { + owner: address, + resharing, + }; + let verify_vk_share_msg = CosmosMsg::Wasm(WasmMsg::Execute { + contract_addr: chain.dkg_contract.address.to_string(), + msg: to_binary(&verify_vk_share_req).unwrap(), + funds: vec![], + }); + let proposal = Proposal { + title: String::new(), + description: String::new(), + msgs: vec![verify_vk_share_msg], + status: cw3::Status::Open, + expires: cw_utils::Expiration::Never {}, + threshold: cw_utils::Threshold::AbsolutePercentage { + percentage: Decimal::from_ratio(2u32, 3u32), + }, + total_weight: chain.total_group_weight(), + votes: Votes::yes(0), + proposer: Addr::unchecked(dkg_contract.as_ref()), + deposit: None, + start_height: 0, + }; + chain + .multisig_contract + .proposals + .insert(proposal_id, proposal); + let transaction_hash = chain._counters.next_tx_hash(); + Ok(ExecuteResult { + logs: vec![Log { + msg_index: 0, + events: vec![cosmwasm_std::Event::new("wasm") + .add_attribute(DKG_PROPOSAL_ID, proposal_id.to_string())], + }], + data: Default::default(), + transaction_hash, + gas_info: Default::default(), + }) + } } #[derive(Clone, Debug)] From 92bf31d9f4ca47527cb59f6a3057eb209e07c233 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 20:55:39 +0000 Subject: [PATCH 038/394] fixed dkg progress not being recorded --- contracts/coconut-dkg/src/dealings/transactions.rs | 11 +++++++++-- .../src/verification_key_shares/transactions.rs | 13 +++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index 467ee46eba..fbbc8880e8 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -137,7 +137,7 @@ pub fn try_commit_dealings_chunk( // note: checking permissions is implicit as if the metadata exists, // the sender must have been allowed to submit it - let epoch = CURRENT_EPOCH.load(deps.storage)?; + let mut epoch = CURRENT_EPOCH.load(deps.storage)?; // read meta let mut metadata = must_read_metadata( @@ -192,7 +192,14 @@ pub fn try_commit_dealings_chunk( // store the dealing StoredDealing::save(deps.storage, epoch.epoch_id, &info.sender, chunk); - + + // this is less than ideal since we have to iterate through all the chunks, but realistically, + // there won't be a lot of them + if metadata.is_complete() { + epoch.state_progress.submitted_dealings += 1; + CURRENT_EPOCH.save(deps.storage, &epoch)?; + } + Ok(Response::new()) } diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index 5c683a7690..f4760e9907 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -25,7 +25,8 @@ pub fn try_commit_verification_key_share( deps.storage, EpochState::VerificationKeySubmission { resharing }, )?; - let epoch_id = CURRENT_EPOCH.load(deps.storage)?.epoch_id; + let mut epoch = CURRENT_EPOCH.load(deps.storage)?; + let epoch_id = epoch.epoch_id; let details = get_dealer_details(deps.storage, &info.sender, epoch_id)?; if vk_shares() @@ -58,6 +59,9 @@ pub fn try_commit_verification_key_share( .plus_seconds(BLOCK_TIME_FOR_VERIFICATION_SECS), )?; + epoch.state_progress.submitted_key_shares += 1; + CURRENT_EPOCH.save(deps.storage, &epoch)?; + Ok(Response::new().add_message(msg)) } @@ -73,7 +77,9 @@ pub fn try_verify_verification_key_share( deps.storage, EpochState::VerificationKeyFinalization { resharing }, )?; - let epoch_id = CURRENT_EPOCH.load(deps.storage)?.epoch_id; + let mut epoch = CURRENT_EPOCH.load(deps.storage)?; + let epoch_id = epoch.epoch_id; + MULTISIG.assert_admin(deps.as_ref(), &info.sender)?; vk_shares().update(deps.storage, (&owner, epoch_id), |vk_share| { vk_share @@ -86,6 +92,9 @@ pub fn try_verify_verification_key_share( }) })?; + epoch.state_progress.verified_keys += 1; + CURRENT_EPOCH.save(deps.storage, &epoch)?; + Ok(Response::default()) } From c663ba08f2f2f47f7d33f0a04b3b5a543a25968c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 15 Feb 2024 21:01:46 +0000 Subject: [PATCH 039/394] fixed dkg incorrectly setting state deadlines --- .../coconut-dkg/src/types.rs | 49 ++++++++++++------- .../transactions/advance_epoch_state.rs | 3 +- 2 files changed, 31 insertions(+), 21 deletions(-) diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index a4d0afb077..0e527dee71 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -34,6 +34,26 @@ pub struct TimeConfiguration { pub in_progress_time_secs: u64, } +impl TimeConfiguration { + pub fn state_duration(&self, state: EpochState) -> Option { + match state { + EpochState::WaitingInitialisation => None, + EpochState::PublicKeySubmission { .. } => Some(self.public_key_submission_time_secs), + EpochState::DealingExchange { .. } => Some(self.dealing_exchange_time_secs), + EpochState::VerificationKeySubmission { .. } => { + Some(self.verification_key_submission_time_secs) + } + EpochState::VerificationKeyValidation { .. } => { + Some(self.verification_key_validation_time_secs) + } + EpochState::VerificationKeyFinalization { .. } => { + Some(self.verification_key_finalization_time_secs) + } + EpochState::InProgress => Some(self.in_progress_time_secs), + } + } +} + impl FromStr for TimeConfiguration { type Err = String; @@ -116,25 +136,8 @@ impl Epoch { time_configuration: TimeConfiguration, current_timestamp: Timestamp, ) -> Self { - let duration = match state { - EpochState::WaitingInitialisation => None, - EpochState::PublicKeySubmission { .. } => { - Some(time_configuration.public_key_submission_time_secs) - } - EpochState::DealingExchange { .. } => { - Some(time_configuration.dealing_exchange_time_secs) - } - EpochState::VerificationKeySubmission { .. } => { - Some(time_configuration.verification_key_submission_time_secs) - } - EpochState::VerificationKeyValidation { .. } => { - Some(time_configuration.verification_key_validation_time_secs) - } - EpochState::VerificationKeyFinalization { .. } => { - Some(time_configuration.verification_key_finalization_time_secs) - } - EpochState::InProgress => Some(time_configuration.in_progress_time_secs), - }; + let duration = time_configuration.state_duration(state); + Epoch { state, epoch_id, @@ -144,6 +147,14 @@ impl Epoch { } } + pub fn update(mut self, next_state: EpochState, current_timestamp: Timestamp) -> Self { + self.state = next_state; + let duration = self.time_configuration.state_duration(next_state); + self.deadline = duration.map(|d| current_timestamp.plus_seconds(d)); + + self + } + pub fn final_timestamp_secs(&self) -> Option { let mut finish = self.deadline?.seconds(); let time_configuration = self.time_configuration; diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs index 57681ed3cf..789eeff601 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -73,8 +73,7 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result Date: Fri, 16 Feb 2024 16:27:58 +0000 Subject: [PATCH 040/394] fixed existing dkg contract tests --- .../coconut-dkg/src/types.rs | 27 + contracts/coconut-dkg/Cargo.toml | 1 - contracts/coconut-dkg/src/dealers/queries.rs | 158 +++--- contracts/coconut-dkg/src/dealers/storage.rs | 6 +- .../coconut-dkg/src/dealers/transactions.rs | 80 +-- contracts/coconut-dkg/src/dealings/storage.rs | 3 +- .../coconut-dkg/src/dealings/transactions.rs | 126 +---- .../transactions/advance_epoch_state.rs | 482 ++++++++++++------ .../src/epoch_state/transactions/mod.rs | 356 +------------ .../coconut-dkg/src/epoch_state/utils.rs | 145 +++++- contracts/coconut-dkg/src/error.rs | 3 - .../coconut-dkg/src/support/tests/helpers.rs | 59 ++- .../verification_key_shares/transactions.rs | 23 +- 13 files changed, 684 insertions(+), 785 deletions(-) diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index 0e527dee71..7ff34d682e 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -104,15 +104,24 @@ pub struct State { #[cw_serde] #[derive(Copy, Default)] pub struct StateProgress { + /// Counts the number of dealers that have registered in this epoch. // ideally we want to have here all group members pub registered_dealers: u32, + /// Counts the number of resharing dealers that have registered in this epoch. + /// This field is only populated during a resharing exchange. + /// It is always <= registered_dealers. + pub registered_resharing_dealers: u32, + + /// Counts the number of fully received dealings (i.e. full chunks) from all the allowed dealers. // we expect registered_dealers * state.key_size number of dealings here (each dealer has to submit key_size number of dealings) pub submitted_dealings: u32, + /// Counts the number of submitted verification key shared from the dealers. // we expect registered_dealers number of keys here pub submitted_key_shares: u32, + /// Counts the number of verified key shares. // we expect submitted_key_shares number of verified keys here pub verified_keys: u32, } @@ -155,6 +164,24 @@ impl Epoch { self } + pub fn next_reset(self, current_timestamp: Timestamp) -> Self { + Epoch::new( + EpochState::PublicKeySubmission { resharing: false }, + self.epoch_id + 1, + self.time_configuration, + current_timestamp, + ) + } + + pub fn next_resharing(self, current_timestamp: Timestamp) -> Self { + Epoch::new( + EpochState::PublicKeySubmission { resharing: true }, + self.epoch_id + 1, + self.time_configuration, + current_timestamp, + ) + } + pub fn final_timestamp_secs(&self) -> Option { let mut finish = self.deadline?.seconds(); let time_configuration = self.time_configuration; diff --git a/contracts/coconut-dkg/Cargo.toml b/contracts/coconut-dkg/Cargo.toml index 13937bcb3a..7d81b122fe 100644 --- a/contracts/coconut-dkg/Cargo.toml +++ b/contracts/coconut-dkg/Cargo.toml @@ -30,7 +30,6 @@ thiserror = { workspace = true } cw-multi-test = { workspace = true } cw4-group = { path = "../multisig/cw4-group" } nym-group-contract-common = { path = "../../common/cosmwasm-smart-contracts/group-contract" } -rusty-fork = "0.3" [features] schema-gen = ["nym-coconut-dkg-common/schema", "cosmwasm-schema"] diff --git a/contracts/coconut-dkg/src/dealers/queries.rs b/contracts/coconut-dkg/src/dealers/queries.rs index d88a739976..9abf90c218 100644 --- a/contracts/coconut-dkg/src/dealers/queries.rs +++ b/contracts/coconut-dkg/src/dealers/queries.rs @@ -130,24 +130,22 @@ pub(crate) mod tests { use super::*; use crate::dealers::storage::{DEALERS_PAGE_DEFAULT_LIMIT, DEALERS_PAGE_MAX_LIMIT}; use crate::support::tests::fixtures::dealer_details_fixture; - use crate::support::tests::helpers::init_contract; + use crate::support::tests::helpers::{init_contract, insert_dealer}; use cosmwasm_std::DepsMut; - fn fill_dealers(deps: DepsMut<'_>, mapping: &IndexedDealersMap<'_>, size: usize) { - for n in 0..size { - let dealer_details = dealer_details_fixture(n as u64); - mapping - .save(deps.storage, &dealer_details.address, &dealer_details) - .unwrap(); + fn fill_dealers(mut deps: DepsMut<'_>, epoch_id: EpochId, size: usize) { + for assigned_index in 0..size { + let dealer_details = dealer_details_fixture(assigned_index as u64); + insert_dealer(deps.branch(), epoch_id, &dealer_details); } } - fn remove_dealers(deps: DepsMut<'_>, mapping: &IndexedDealersMap<'_>, size: usize) { - for n in 0..size { - let dealer_details = dealer_details_fixture(n as u64); - mapping - .remove(deps.storage, &dealer_details.address) - .unwrap(); + fn remove_dealers(deps: DepsMut<'_>, epoch_id: EpochId, size: usize) { + for assigned_index in 0..size { + let dealer_details = dealer_details_fixture(assigned_index as u64); + DEALERS_INDICES.remove(deps.storage, &dealer_details.address); + + EPOCH_DEALERS_MAP.remove(deps.storage, (epoch_id, &dealer_details.address)); } } @@ -155,10 +153,8 @@ pub(crate) mod tests { fn dealers_empty_on_init() { let deps = init_contract(); - for mapping in [storage::current_dealers(), storage::past_dealers()] { - let page1 = query_dealers(deps.as_ref(), None, None, &mapping).unwrap(); - assert_eq!(0, page1.dealers.len() as u32); - } + let page1 = query_current_dealers_paged(deps.as_ref(), None, None).unwrap(); + assert_eq!(0, page1.dealers.len() as u32); } #[test] @@ -166,30 +162,26 @@ pub(crate) mod tests { let mut deps = init_contract(); let limit = 2; - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 1000); + fill_dealers(deps.as_mut(), 0, 1000); - let page1 = query_dealers(deps.as_ref(), None, Option::from(limit), &mapping).unwrap(); - assert_eq!(limit, page1.dealers.len() as u32); + let page1 = query_current_dealers_paged(deps.as_ref(), None, Option::from(limit)).unwrap(); + assert_eq!(limit, page1.dealers.len() as u32); - remove_dealers(deps.as_mut(), &mapping, 1000); - } + remove_dealers(deps.as_mut(), 0, 1000); } #[test] fn dealers_paged_retrieval_has_default_limit() { let mut deps = init_contract(); - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 1000); + fill_dealers(deps.as_mut(), 0, 1000); - // query without explicitly setting a limit - let page1 = query_dealers(deps.as_ref(), None, None, &mapping).unwrap(); + // query without explicitly setting a limit + let page1 = query_current_dealers_paged(deps.as_ref(), None, None).unwrap(); - assert_eq!(DEALERS_PAGE_DEFAULT_LIMIT, page1.dealers.len() as u32); + assert_eq!(DEALERS_PAGE_DEFAULT_LIMIT, page1.dealers.len() as u32); - remove_dealers(deps.as_mut(), &mapping, 1000); - } + remove_dealers(deps.as_mut(), 0, 1000); } #[test] @@ -199,18 +191,16 @@ pub(crate) mod tests { // query with a crazily high limit in an attempt to use too many resources let crazy_limit = 1000 * DEALERS_PAGE_MAX_LIMIT; - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 1000); + fill_dealers(deps.as_mut(), 0, 1000); - let page1 = - query_dealers(deps.as_ref(), None, Option::from(crazy_limit), &mapping).unwrap(); + let page1 = + query_current_dealers_paged(deps.as_ref(), None, Option::from(crazy_limit)).unwrap(); - // we default to a decent sized upper bound instead - let expected_limit = DEALERS_PAGE_MAX_LIMIT; - assert_eq!(expected_limit, page1.dealers.len() as u32); + // we default to a decent sized upper bound instead + let expected_limit = DEALERS_PAGE_MAX_LIMIT; + assert_eq!(expected_limit, page1.dealers.len() as u32); - remove_dealers(deps.as_mut(), &mapping, 1000); - } + remove_dealers(deps.as_mut(), 0, 1000); } #[test] @@ -219,62 +209,52 @@ pub(crate) mod tests { let per_page = 2; - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 1); - let page1 = - query_dealers(deps.as_ref(), None, Option::from(per_page), &mapping).unwrap(); + fill_dealers(deps.as_mut(), 0, 1); + let page1 = + query_current_dealers_paged(deps.as_ref(), None, Option::from(per_page)).unwrap(); - // page should have 1 result on it - assert_eq!(1, page1.dealers.len()); - remove_dealers(deps.as_mut(), &mapping, 1); - } + // page should have 1 result on it + assert_eq!(1, page1.dealers.len()); + remove_dealers(deps.as_mut(), 0, 1); - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 2); - // page1 should have 2 results on it - let page1 = - query_dealers(deps.as_ref(), None, Option::from(per_page), &mapping).unwrap(); - assert_eq!(2, page1.dealers.len()); - remove_dealers(deps.as_mut(), &mapping, 2); - } + fill_dealers(deps.as_mut(), 0, 2); + // page1 should have 2 results on it + let page1 = + query_current_dealers_paged(deps.as_ref(), None, Option::from(per_page)).unwrap(); + assert_eq!(2, page1.dealers.len()); + remove_dealers(deps.as_mut(), 0, 2); - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 3); - // page1 still has 2 results - let page1 = - query_dealers(deps.as_ref(), None, Option::from(per_page), &mapping).unwrap(); - assert_eq!(2, page1.dealers.len()); + fill_dealers(deps.as_mut(), 0, 3); + // page1 still has 2 results + let page1 = + query_current_dealers_paged(deps.as_ref(), None, Option::from(per_page)).unwrap(); + assert_eq!(2, page1.dealers.len()); - // retrieving the next page should start after the last key on this page - let start_after = page1.start_next_after.unwrap(); - let page2 = query_dealers( - deps.as_ref(), - Option::from(start_after.to_string()), - Option::from(per_page), - &mapping, - ) - .unwrap(); + // retrieving the next page should start after the last key on this page + let start_after = page1.start_next_after.unwrap(); + let page2 = query_current_dealers_paged( + deps.as_ref(), + Option::from(start_after.to_string()), + Option::from(per_page), + ) + .unwrap(); - assert_eq!(1, page2.dealers.len()); - remove_dealers(deps.as_mut(), &mapping, 3); - } + assert_eq!(1, page2.dealers.len()); + remove_dealers(deps.as_mut(), 0, 3); - for mapping in [storage::current_dealers(), storage::past_dealers()] { - fill_dealers(deps.as_mut(), &mapping, 4); - let page1 = - query_dealers(deps.as_ref(), None, Option::from(per_page), &mapping).unwrap(); - let start_after = page1.start_next_after.unwrap(); - let page2 = query_dealers( - deps.as_ref(), - Option::from(start_after.to_string()), - Option::from(per_page), - &mapping, - ) - .unwrap(); + fill_dealers(deps.as_mut(), 0, 4); + let page1 = + query_current_dealers_paged(deps.as_ref(), None, Option::from(per_page)).unwrap(); + let start_after = page1.start_next_after.unwrap(); + let page2 = query_current_dealers_paged( + deps.as_ref(), + Option::from(start_after.to_string()), + Option::from(per_page), + ) + .unwrap(); - // now we have 2 pages, with 2 results on the second page - assert_eq!(2, page2.dealers.len()); - remove_dealers(deps.as_mut(), &mapping, 4); - } + // now we have 2 pages, with 2 results on the second page + assert_eq!(2, page2.dealers.len()); + remove_dealers(deps.as_mut(), 0, 4); } } diff --git a/contracts/coconut-dkg/src/dealers/storage.rs b/contracts/coconut-dkg/src/dealers/storage.rs index 979218b3ed..e713940175 100644 --- a/contracts/coconut-dkg/src/dealers/storage.rs +++ b/contracts/coconut-dkg/src/dealers/storage.rs @@ -52,12 +52,16 @@ pub(crate) fn ensure_dealer( dealer: Dealer, epoch_id: EpochId, ) -> Result<(), ContractError> { - if !EPOCH_DEALERS_MAP.has(storage, (epoch_id, dealer)) { + if !is_dealer(storage, dealer, epoch_id) { return Err(ContractError::NotADealer { epoch_id }); } Ok(()) } +pub(crate) fn is_dealer(storage: &dyn Storage, dealer: Dealer, epoch_id: EpochId) -> bool { + EPOCH_DEALERS_MAP.has(storage, (epoch_id, dealer)) +} + // note: `epoch_id` is provided purely for the error message. it has nothing to do with storage retrieval pub(crate) fn get_dealer_index( storage: &dyn Storage, diff --git a/contracts/coconut-dkg/src/dealers/transactions.rs b/contracts/coconut-dkg/src/dealers/transactions.rs index fe851df5b6..e534d072bc 100644 --- a/contracts/coconut-dkg/src/dealers/transactions.rs +++ b/contracts/coconut-dkg/src/dealers/transactions.rs @@ -1,7 +1,9 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::dealers::storage::{get_or_assign_index, save_dealer_details_if_not_a_dealer}; +use crate::dealers::storage::{ + get_or_assign_index, is_dealer, save_dealer_details_if_not_a_dealer, +}; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::utils::check_epoch_state; use crate::error::ContractError; @@ -53,10 +55,27 @@ pub fn try_add_dealer( dealer_details, )?; + // check if it's a resharing dealer + + let is_resharing_dealer = resharing + && is_dealer( + deps.storage, + &info.sender, + epoch + .epoch_id + .checked_sub(1) + .expect("epoch invariant broken: resharing during 0th epoch"), + ); + // increment the number of registered dealers CURRENT_EPOCH.update(deps.storage, |epoch| -> StdResult<_> { let mut updated_epoch = epoch; updated_epoch.state_progress.registered_dealers += 1; + + if is_resharing_dealer { + updated_epoch.state_progress.registered_resharing_dealers += 1; + } + Ok(updated_epoch) })?; @@ -66,63 +85,12 @@ pub fn try_add_dealer( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::dealers::storage::current_dealers; use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; - use crate::support::tests::fixtures::dealer_details_fixture; use crate::support::tests::helpers; - use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS, GROUP_MEMBERS}; + use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cw4::Member; - use nym_coconut_dkg_common::types::{InitialReplacementData, TimeConfiguration}; - use rusty_fork::rusty_fork_test; - - rusty_fork_test! { - #[test] - fn verification() { - let mut deps = helpers::init_contract(); - let new_dealer = Addr::unchecked("new_dealer"); - let details1 = dealer_details_fixture(1); - let details2 = dealer_details_fixture(2); - let details3 = dealer_details_fixture(3); - current_dealers() - .save(deps.as_mut().storage, &details1.address, &details1) - .unwrap(); - let err = verify_dealer(deps.as_mut(), &details1.address, false).unwrap_err(); - assert_eq!(err, ContractError::AlreadyADealer); - - INITIAL_REPLACEMENT_DATA - .save( - deps.as_mut().storage, - &InitialReplacementData { - initial_dealers: vec![details1.address, details2.address, details3.address], - initial_height: 1, - }, - ) - .unwrap(); - let err = verify_dealer(deps.as_mut(), &new_dealer, false).unwrap_err(); - assert_eq!(err, ContractError::Unauthorized); - - GROUP_MEMBERS.lock().unwrap().push(( - Member { - addr: new_dealer.to_string(), - weight: 10, - }, - 2, - )); - verify_dealer(deps.as_mut(), &new_dealer, false).unwrap(); - - let err = verify_dealer(deps.as_mut(), &new_dealer, true).unwrap_err(); - assert_eq!(err, ContractError::Unauthorized); - - INITIAL_REPLACEMENT_DATA - .update::<_, ContractError>(deps.as_mut().storage, |mut data| { - data.initial_height = 2; - Ok(data) - }) - .unwrap(); - verify_dealer(deps.as_mut(), &new_dealer, true).unwrap(); - } - } + use cosmwasm_std::Addr; + use nym_coconut_dkg_common::types::TimeConfiguration; #[test] fn invalid_state() { diff --git a/contracts/coconut-dkg/src/dealings/storage.rs b/contracts/coconut-dkg/src/dealings/storage.rs index bfa92722a4..6e2a4aaa90 100644 --- a/contracts/coconut-dkg/src/dealings/storage.rs +++ b/contracts/coconut-dkg/src/dealings/storage.rs @@ -179,7 +179,7 @@ impl StoredDealing { pub(crate) fn unchecked_all_entries( storage: &dyn Storage, ) -> Vec<( - (EpochId, Addr, (DealingIndex, ChunkIndex)), + (EpochId, cosmwasm_std::Addr, (DealingIndex, ChunkIndex)), PartialContractDealingData, )> { use cw_storage_plus::KeyDeserialize; @@ -209,6 +209,7 @@ impl StoredDealing { mod tests { use super::*; use crate::support::tests::helpers::init_contract; + use cosmwasm_std::Addr; use cw_storage_plus::Bound; use std::collections::HashMap; diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index fbbc8880e8..0780f1cfd1 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -192,14 +192,14 @@ pub fn try_commit_dealings_chunk( // store the dealing StoredDealing::save(deps.storage, epoch.epoch_id, &info.sender, chunk); - - // this is less than ideal since we have to iterate through all the chunks, but realistically, + + // this is less than ideal since we have to iterate through all the chunks, but realistically, // there won't be a lot of them if metadata.is_complete() { epoch.state_progress.submitted_dealings += 1; CURRENT_EPOCH.save(deps.storage, &epoch)?; } - + Ok(Response::new()) } @@ -208,17 +208,13 @@ pub(crate) mod tests { use super::*; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; - use crate::support::tests::fixtures::{ - dealer_details_fixture, dealing_metadata_fixture, partial_dealing_fixture, - }; + use crate::support::tests::fixtures::{dealing_metadata_fixture, partial_dealing_fixture}; use crate::support::tests::helpers; - use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS}; + use crate::support::tests::helpers::{add_current_dealer, re_register_dealer, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::Addr; use nym_coconut_dkg_common::dealer::DealerDetails; - use nym_coconut_dkg_common::types::{ - ContractSafeBytes, InitialReplacementData, TimeConfiguration, - }; + use nym_coconut_dkg_common::types::{ContractSafeBytes, TimeConfiguration}; #[test] fn invalid_commit_dealing_chunk() { @@ -228,41 +224,27 @@ pub(crate) mod tests { let owner = Addr::unchecked("owner1"); let info = mock_info(owner.as_str(), &[]); - let dealing = partial_dealing_fixture(); + let chunk = partial_dealing_fixture(); - let ret = try_commit_dealings_chunk( - deps.as_mut(), - env.clone(), - info.clone(), - dealing.clone(), - false, - ) - .unwrap_err(); + // no dealing metadata + let ret = + try_commit_dealings_chunk(deps.as_mut(), env.clone(), info.clone(), chunk.clone()) + .unwrap_err(); assert_eq!( ret, - ContractError::IncorrectEpochState { - current_state: EpochState::PublicKeySubmission { resharing: false }.to_string(), - expected_state: EpochState::DealingExchange { resharing: false }.to_string() + ContractError::UnavailableDealingMetadata { + epoch_id: 0, + dealer: info.sender.clone(), + dealing_index: chunk.dealing_index, } ); + // add dealing metadata env.block.time = env .block .time .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - add_fixture_dealer(deps.as_mut()); try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - - let ret = try_commit_dealings_chunk( - deps.as_mut(), - env.clone(), - info.clone(), - dealing.clone(), - false, - ) - .unwrap_err(); - assert_eq!(ret, ContractError::NotADealer); - let dealer_details = DealerDetails { address: owner.clone(), bte_public_key_with_proof: String::new(), @@ -270,60 +252,12 @@ pub(crate) mod tests { announce_address: String::new(), assigned_index: 1, }; - dealers_storage::current_dealers() - .save(deps.as_mut().storage, &owner, &dealer_details) - .unwrap(); + add_current_dealer(deps.as_mut(), &dealer_details); - // assume we're in resharing mode - CURRENT_EPOCH - .update::<_, ContractError>(deps.as_mut().storage, |mut epoch| { - epoch.state = EpochState::DealingExchange { resharing: true }; - Ok(epoch) - }) - .unwrap(); - INITIAL_REPLACEMENT_DATA - .save( - deps.as_mut().storage, - &InitialReplacementData { - initial_dealers: vec![], - initial_height: 1, - }, - ) - .unwrap(); - let ret = try_commit_dealings_chunk( - deps.as_mut(), - env.clone(), - info.clone(), - dealing.clone(), - true, - ) - .unwrap_err(); - assert_eq!(ret, ContractError::NotAnInitialDealer); - - INITIAL_REPLACEMENT_DATA - .update::<_, ContractError>(deps.as_mut().storage, |mut data| { - data.initial_dealers = vec![dealer_details_fixture(1).address]; - Ok(data) - }) - .unwrap(); - - // back to 'normal' mode - CURRENT_EPOCH - .update::<_, ContractError>(deps.as_mut().storage, |mut epoch| { - epoch.state = EpochState::DealingExchange { resharing: false }; - Ok(epoch) - }) - .unwrap(); - - // TODO: test case: no metadata - // - // - - // add dealing metadata try_submit_dealings_metadata( deps.as_mut(), info.clone(), - 0, + chunk.dealing_index, dealing_metadata_fixture(), false, ) @@ -339,7 +273,6 @@ pub(crate) mod tests { chunk_index: 42, data: ContractSafeBytes(vec![1, 2, 3]), }, - false, ) .unwrap_err(); assert_eq!( @@ -353,24 +286,14 @@ pub(crate) mod tests { ); // 'good' dealing - let ret = try_commit_dealings_chunk( - deps.as_mut(), - env.clone(), - info.clone(), - dealing.clone(), - false, - ); + let ret = + try_commit_dealings_chunk(deps.as_mut(), env.clone(), info.clone(), chunk.clone()); assert!(ret.is_ok()); // duplicate dealing - let ret = try_commit_dealings_chunk( - deps.as_mut(), - env.clone(), - info.clone(), - dealing.clone(), - false, - ) - .unwrap_err(); + let ret = + try_commit_dealings_chunk(deps.as_mut(), env.clone(), info.clone(), chunk.clone()) + .unwrap_err(); assert_eq!( ret, ContractError::DealingChunkAlreadyCommitted { @@ -389,6 +312,7 @@ pub(crate) mod tests { Ok(epoch) }) .unwrap(); + re_register_dealer(deps.as_mut(), &info.sender); try_submit_dealings_metadata( deps.as_mut(), @@ -399,7 +323,7 @@ pub(crate) mod tests { ) .unwrap(); - let ret = try_commit_dealings_chunk(deps.as_mut(), env, info, dealing.clone(), false); + let ret = try_commit_dealings_chunk(deps.as_mut(), env, info, chunk.clone()); assert!(ret.is_ok()); } } diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs index 789eeff601..396a7d1408 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/advance_epoch_state.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; +use crate::epoch_state::transactions::reset_dkg_state; use crate::epoch_state::utils::check_state_completion; use crate::error::ContractError; use cosmwasm_std::{Deps, DepsMut, Env, Response}; @@ -43,7 +44,7 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result next_state, None => { debug_assert!(current_epoch.state.is_in_progress()); @@ -64,16 +65,21 @@ pub fn try_advance_epoch_state(deps: DepsMut<'_>, env: Env) -> Result, env: Env) -> Result Epoch { + Epoch::new(state, 0, Default::default(), env.block.time) + } + + fn set_epoch(storage: &mut dyn Storage, epoch: Epoch) { + CURRENT_EPOCH.save(storage, &epoch).unwrap(); + } + + let mut deps = init_contract(); + let env = mock_env(); + + // it's never possible to short-circuit `WaitingInitialisation` + let epoch = epoch_in_state(EpochState::WaitingInitialisation, &env); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // neither PublicKeySubmission (in either resharing or non-resharing) + let epoch = epoch_in_state(EpochState::PublicKeySubmission { resharing: false }, &env); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let epoch = epoch_in_state(EpochState::PublicKeySubmission { resharing: true }, &env); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let key_size = STATE.load(&deps.storage).unwrap().key_size; + + THRESHOLD.save(deps.as_mut().storage, &3).unwrap(); + + // we can short-circuit `DealingExchange` if all dealers submitted their dealings + + // no dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }, &env); + epoch.state_progress.registered_dealers = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // some dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }, &env); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_dealings = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // all dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }, &env); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_dealings = key_size * 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state( + deps.as_ref().storage, + EpochState::VerificationKeySubmission { resharing: false }, + ) + .unwrap(); + + // no dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }, &env); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // some dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }, &env); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + epoch.state_progress.submitted_dealings = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // all dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }, &env); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + epoch.state_progress.submitted_dealings = key_size * 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state( + deps.as_ref().storage, + EpochState::VerificationKeySubmission { resharing: true }, + ) + .unwrap(); + + // we can short-circuit `VerificationKeySubmission` if all dealers submitted their verification keys + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: false }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: true }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: false }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: true }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: false }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state( + deps.as_ref().storage, + EpochState::VerificationKeyValidation { resharing: false }, + ) + .unwrap(); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeySubmission { resharing: true }, + &env, + ); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state( + deps.as_ref().storage, + EpochState::VerificationKeyValidation { resharing: true }, + ) + .unwrap(); + + // can't short-circuit `VerificationKeyValidation` => we rely on multisig votes here + let epoch = epoch_in_state( + EpochState::VerificationKeyValidation { resharing: false }, + &env, + ); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let epoch = epoch_in_state( + EpochState::VerificationKeyValidation { resharing: true }, + &env, + ); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + // we can short-circuit `VerificationKeyFinalization` if all submitted keys got verified + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: false }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: true }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: false }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: true }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 4; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: false }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state(deps.as_ref().storage, EpochState::InProgress).unwrap(); + + let mut epoch = epoch_in_state( + EpochState::VerificationKeyFinalization { resharing: true }, + &env, + ); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 5; + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_ok()); + check_epoch_state(deps.as_ref().storage, EpochState::InProgress).unwrap(); + + // it's never possible to short-circuit `InProgress` + let epoch = epoch_in_state(EpochState::InProgress, &env); + set_epoch(deps.as_mut().storage, epoch); + let res = try_advance_epoch_state(deps.as_mut(), env.clone()); + assert!(res.is_err()); + } + + #[test] + fn advance_state_with_deadline() { let mut deps = init_contract(); let mut env = mock_env(); - { - let mut group = GROUP_MEMBERS.lock().unwrap(); - - group.push(( - Member { - addr: "owner1".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner2".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner3".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner4".to_string(), - weight: 10, - }, - 1, - )); - } - // can't advance the state if dkg hasn't been initiated assert_eq!( try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap_err(), @@ -160,32 +381,15 @@ mod tests { ); env.block.time = env.block.time.plus_seconds(1); - try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); - // setup dealer details - let all_shares: [_; 4] = - std::array::from_fn(|i| vk_share_fixture(&format!("owner{}", i + 1), 0)); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), share) - .unwrap(); - } - let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); - for details in all_details.iter() { - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } + // add some dealers to prevent short-circuiting + CURRENT_EPOCH + .update(deps.as_mut().storage, |mut e| -> StdResult<_> { + e.state_progress.registered_dealers = 42; + Ok(e) + }) + .unwrap(); - assert!(INITIAL_REPLACEMENT_DATA - .may_load(&deps.storage) - .unwrap() - .is_none()); env.block.time = env .block .time @@ -266,6 +470,14 @@ mod tests { EarlyEpochStateAdvancement(3) ); + // add some key shares to prevent short-circuiting + CURRENT_EPOCH + .update(deps.as_mut().storage, |mut e| -> StdResult<_> { + e.state_progress.submitted_key_shares = 42; + Ok(e) + }) + .unwrap(); + env.block.time = env.block.time.plus_seconds(3); try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); @@ -273,6 +485,7 @@ mod tests { epoch.state, EpochState::VerificationKeyFinalization { resharing: false } ); + assert_eq!( epoch.deadline.unwrap(), env.block.time.plus_seconds( @@ -291,6 +504,14 @@ mod tests { EarlyEpochStateAdvancement(1) ); + // add some finalized keys to prevent reset + CURRENT_EPOCH + .update(deps.as_mut().storage, |mut e| -> StdResult<_> { + e.state_progress.verified_keys = 42; + Ok(e) + }) + .unwrap(); + env.block.time = env.block.time.plus_seconds(1); try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); @@ -322,103 +543,64 @@ mod tests { let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - let expected_epoch = Epoch::new( + let mut expected_epoch = Epoch::new( EpochState::InProgress, prev_epoch.epoch_id, prev_epoch.time_configuration, env.block.time, ); + expected_epoch.state_progress = curr_epoch.state_progress; assert_eq!(curr_epoch, expected_epoch); - // Group changed slightly, so re-run dkg in reshare mode - *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = ( - Member { - addr: "owner5".to_string(), - weight: 10, - }, - 1, - ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs); - let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); - let expected_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: true }, - prev_epoch.epoch_id + 1, - prev_epoch.time_configuration, + // advancing from key finalization without threshold keys verified results in reset + THRESHOLD.save(deps.as_mut().storage, &42).unwrap(); + let mut epoch = Epoch::new( + EpochState::VerificationKeyFinalization { resharing: true }, + 10, + TimeConfiguration::default(), env.block.time, ); - assert_eq!(curr_epoch, expected_epoch); - assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); - let replacement_data = INITIAL_REPLACEMENT_DATA.load(&deps.storage).unwrap(); - let expected_replacement_data = InitialReplacementData { - initial_dealers: all_details.iter().map(|d| d.address.clone()).collect(), - initial_height: 12345, - }; - assert_eq!(replacement_data, expected_replacement_data); - let all_details: [_; 4] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 2)); - for details in all_details.iter() { - past_dealers() - .remove(deps.as_mut().storage, &details.address) - .unwrap(); - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } - for times in [ - epoch.time_configuration.public_key_submission_time_secs, - epoch.time_configuration.dealing_exchange_time_secs, - epoch - .time_configuration - .verification_key_submission_time_secs, - epoch - .time_configuration - .verification_key_validation_time_secs, - epoch - .time_configuration - .verification_key_finalization_time_secs, - ] { - env.block.time = env.block.time.plus_seconds(times); - try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - } + // fewer than the threshold + epoch.state_progress.verified_keys = 41; + CURRENT_EPOCH.save(deps.as_mut().storage, &epoch).unwrap(); + env.block.time = env.block.time.plus_seconds(5000000); - let all_shares: [_; 4] = std::array::from_fn(|i| { - let mut share = vk_share_fixture(&format!("owner{}", i + 1), 1); - share.verified = i % 2 == 0; - share - }); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), share) - .unwrap(); - } - - // Group changed even more, surpassing threshold, so re-run dkg in reset mode - *GROUP_MEMBERS.lock().unwrap().last_mut().unwrap() = ( - Member { - addr: "owner6".to_string(), - weight: 10, - }, - 1, - ); - env.block.time = env - .block - .time - .plus_seconds(epoch.time_configuration.in_progress_time_secs); - let prev_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); let curr_epoch = CURRENT_EPOCH.load(deps.as_mut().storage).unwrap(); let expected_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: true }, - prev_epoch.epoch_id + 1, - prev_epoch.time_configuration, + EpochState::PublicKeySubmission { resharing: false }, + epoch.epoch_id + 1, + epoch.time_configuration, env.block.time, ); assert_eq!(curr_epoch, expected_epoch); assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); } + + #[test] + fn verify_threshold() { + let mut deps = init_contract(); + let mut env = mock_env(); + try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); + + assert!(THRESHOLD.may_load(deps.as_mut().storage).unwrap().is_none()); + + CURRENT_EPOCH + .update(deps.as_mut().storage, |mut e| -> StdResult<_> { + e.state_progress.registered_dealers = 100; + Ok(e) + }) + .unwrap(); + + env.block.time = env + .block + .time + .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); + try_advance_epoch_state(deps.as_mut(), env).unwrap(); + assert_eq!( + THRESHOLD.may_load(deps.as_mut().storage).unwrap().unwrap(), + 67 + ); + } } diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index 1a99b8a863..2409ae558c 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -56,12 +56,7 @@ pub(crate) fn try_trigger_reset( return Err(ContractError::CantReshareDuringExchange); } - let next_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: false }, - current_epoch.epoch_id + 1, - current_epoch.time_configuration, - env.block.time, - ); + let next_epoch = current_epoch.next_reset(env.block.time); CURRENT_EPOCH.save(deps.storage, &next_epoch)?; reset_dkg_state(deps.storage)?; @@ -83,12 +78,7 @@ pub(crate) fn try_trigger_resharing( return Err(ContractError::CantReshareDuringExchange); } - let next_epoch = Epoch::new( - EpochState::PublicKeySubmission { resharing: true }, - current_epoch.epoch_id + 1, - current_epoch.time_configuration, - env.block.time, - ); + let next_epoch = current_epoch.next_resharing(env.block.time); CURRENT_EPOCH.save(deps.storage, &next_epoch)?; reset_dkg_state(deps.storage)?; @@ -99,294 +89,10 @@ pub(crate) fn try_trigger_resharing( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::epoch_state::storage::INITIAL_REPLACEMENT_DATA; - use crate::epoch_state::transactions::advance_epoch_state::try_advance_epoch_state; - use crate::support::tests::fixtures::{dealer_details_fixture, vk_share_fixture}; - use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS, GROUP_MEMBERS}; - use crate::verification_key_shares::storage::vk_shares; + use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::Addr; - use cw4::Member; use cw_controllers::AdminError; - use nym_coconut_dkg_common::types::{ - DealerDetails, EpochState, InitialReplacementData, TimeConfiguration, - }; - use rusty_fork::rusty_fork_test; - - // Because of the global variable handling group, we need individual process for each test - - rusty_fork_test! { - // Using values from the DKG document - #[test] - fn threshold_surpassed() { - let mut deps = init_contract(); - let two_thirds = |n: u64| (2 * n + 3 - 1) / 3; - let three_fourths = |n: u64| (3 * n + 4 - 1) / 4; - let ninty_pc = |n: u64| (9 * n + 10 - 2) / 10; - let mut limits = [3, 4, 5, 5, 7, 11, 10, 14, 21, 18, 26, 41].iter(); - - for n in [10, 25, 50, 100] { - let dealers: Vec<_> = (0..n).map(dealer_details_fixture).collect(); - let shares: Vec<_> = (0..n) - .map(|idx| vk_share_fixture(&format!("owner{}", idx), 0)) - .collect(); - let initial_dealers = dealers.iter().map(|d| d.address.clone()).collect(); - let data = InitialReplacementData { - initial_dealers, - initial_height: 1, - }; - for share in shares { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), &share) - .unwrap(); - } - for f in [two_thirds, three_fourths, ninty_pc] { - let threshold = f(n); - THRESHOLD.save(deps.as_mut().storage, &threshold).unwrap(); - INITIAL_REPLACEMENT_DATA - .save(deps.as_mut().storage, &data) - .unwrap(); - - let limit = *limits.next().unwrap(); - { - let mut group_members = GROUP_MEMBERS.lock().unwrap(); - for dealer in dealers.iter() { - group_members.push(( - Member { - addr: dealer.address.to_string(), - weight: 10, - }, - 1, - )); - } - for _ in 1..limit { - group_members.pop(); - } - } - assert!(!replacement_threshold_surpassed(&deps.as_mut()).unwrap()); - GROUP_MEMBERS.lock().unwrap().pop(); - assert!(replacement_threshold_surpassed(&deps.as_mut()).unwrap()); - - *GROUP_MEMBERS.lock().unwrap() = vec![]; - } - } - } - - #[test] - fn dealers_and_members() { - let mut deps = init_contract(); - - assert!(dealers_eq_members(&deps.as_mut()).unwrap()); - - let share = vk_share_fixture("owner2", 0); - let different_share = vk_share_fixture("owner4", 0); - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), &share) - .unwrap(); - assert!(!dealers_eq_members(&deps.as_mut()).unwrap()); - - vk_shares() - .remove(deps.as_mut().storage, (&share.owner, 0)) - .unwrap(); - GROUP_MEMBERS.lock().unwrap().push(( - Member { - addr: "owner2".to_string(), - weight: 10, - }, - 1, - )); - assert!(!dealers_eq_members(&deps.as_mut()).unwrap()); - - vk_shares() - .save( - deps.as_mut().storage, - (&different_share.owner, 0), - &different_share, - ) - .unwrap(); - assert!(!dealers_eq_members(&deps.as_mut()).unwrap()); - - vk_shares() - .remove(deps.as_mut().storage, (&different_share.owner, 0)) - .unwrap(); - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), &share) - .unwrap(); - assert!(dealers_eq_members(&deps.as_mut()).unwrap()); - } - - #[test] - fn still_active() { - let mut deps = init_contract(); - { - let mut group = GROUP_MEMBERS.lock().unwrap(); - - group.push(( - Member { - addr: "owner1".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner2".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner3".to_string(), - weight: 10, - }, - 1, - )); - } - assert_eq!( - 0, - dealers_still_active( - &deps.as_ref(), - current_dealers() - .keys(&deps.storage, None, None, Order::Ascending) - .flatten() - ) - .unwrap() - ); - for i in 0..3_u64 { - let details = dealer_details_fixture(i + 1); - current_dealers() - .save(deps.as_mut().storage, &details.address, &details) - .unwrap(); - assert_eq!( - i as usize + 1, - dealers_still_active( - &deps.as_ref(), - current_dealers() - .keys(&deps.storage, None, None, Order::Ascending) - .flatten() - ) - .unwrap() - ); - } - } - - - - #[test] - fn surpass_threshold() { - let mut deps = init_contract(); - let mut env = mock_env(); - try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); - - let time_configuration = TimeConfiguration::default(); - { - let mut group = GROUP_MEMBERS.lock().unwrap(); - - group.push(( - Member { - addr: "owner1".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner2".to_string(), - weight: 10, - }, - 1, - )); - group.push(( - Member { - addr: "owner3".to_string(), - weight: 10, - }, - 1, - )); - } - - let ret = try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap_err(); - assert_eq!( - ret, - ContractError::IncorrectEpochState { - current_state: EpochState::PublicKeySubmission { resharing: false }.to_string(), - expected_state: EpochState::InProgress.to_string() - } - ); - - let all_shares: [_; 3] = - std::array::from_fn(|i| vk_share_fixture(&format!("owner{}", i + 1), 0)); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, 0), share) - .unwrap(); - } - let all_details: [_; 3] = std::array::from_fn(|i| dealer_details_fixture(i as u64 + 1)); - for details in all_details.iter() { - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } - let all_shares: [_; 3] = - std::array::from_fn(|i| vk_share_fixture(&format!("owner{}", i + 1), 0)); - for share in all_shares.iter() { - vk_shares() - .save(deps.as_mut().storage, (&share.owner, share.epoch_id), share) - .unwrap(); - } - - for times in [ - time_configuration.public_key_submission_time_secs, - time_configuration.dealing_exchange_time_secs, - time_configuration.verification_key_submission_time_secs, - time_configuration.verification_key_validation_time_secs, - time_configuration.verification_key_finalization_time_secs, - ] { - env.block.time = env.block.time.plus_seconds(times); - try_advance_epoch_state(deps.as_mut(), env.clone()).unwrap(); - } - let curr_epoch = CURRENT_EPOCH.load(&deps.storage).unwrap(); - assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); - - // epoch hasn't advanced as we are still in the threshold range - try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); - assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); - assert_eq!(CURRENT_EPOCH.load(&deps.storage).unwrap(), curr_epoch); - - *GROUP_MEMBERS.lock().unwrap().first_mut().unwrap() = ( - Member { - addr: "owner4".to_string(), - weight: 10, - }, - 1, - ); - // epoch hasn't advanced as we are still in the threshold range - try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); - assert_eq!(THRESHOLD.load(&deps.storage).unwrap(), 2); - assert_eq!(CURRENT_EPOCH.load(&deps.storage).unwrap(), curr_epoch); - - *GROUP_MEMBERS.lock().unwrap().last_mut().unwrap() = ( - Member { - addr: "owner5".to_string(), - weight: 10, - }, - 1, - ); - try_surpassed_threshold(deps.as_mut(), env.clone()).unwrap(); - assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); - let next_epoch = CURRENT_EPOCH.load(&deps.storage).unwrap(); - assert_eq!( - next_epoch, - Epoch::new( - EpochState::default(), - curr_epoch.epoch_id + 1, - curr_epoch.time_configuration, - env.block.time, - ) - ); - } - } + use nym_coconut_dkg_common::types::EpochState; #[test] fn initialising_dkg() { @@ -431,65 +137,11 @@ pub(crate) mod tests { #[test] fn reset_state() { let mut deps = init_contract(); - let all_details: [_; 100] = std::array::from_fn(|i| dealer_details_fixture(i as u64)); THRESHOLD.save(deps.as_mut().storage, &42).unwrap(); - for details in all_details.iter() { - current_dealers() - .save(deps.as_mut().storage, &details.address, details) - .unwrap(); - } reset_dkg_state(deps.as_mut().storage).unwrap(); assert!(THRESHOLD.may_load(&deps.storage).unwrap().is_none()); - for details in all_details { - assert!(current_dealers() - .may_load(deps.as_mut().storage, &details.address) - .unwrap() - .is_none()); - assert_eq!( - past_dealers() - .load(&deps.storage, &details.address) - .unwrap(), - details - ); - } - } - - #[test] - fn verify_threshold() { - let mut deps = init_contract(); - let mut env = mock_env(); - try_initiate_dkg(deps.as_mut(), env.clone(), mock_info(ADMIN_ADDRESS, &[])).unwrap(); - - assert!(THRESHOLD.may_load(deps.as_mut().storage).unwrap().is_none()); - - for i in 1..101 { - let address = Addr::unchecked(format!("dealer{}", i)); - current_dealers() - .save( - deps.as_mut().storage, - &address, - &DealerDetails { - address: address.clone(), - bte_public_key_with_proof: "bte_public_key_with_proof".to_string(), - ed25519_identity: "identity".to_string(), - announce_address: "127.0.0.1".to_string(), - assigned_index: i, - }, - ) - .unwrap(); - } - - env.block.time = env - .block - .time - .plus_seconds(TimeConfiguration::default().public_key_submission_time_secs); - try_advance_epoch_state(deps.as_mut(), env).unwrap(); - assert_eq!( - THRESHOLD.may_load(deps.as_mut().storage).unwrap().unwrap(), - 67 - ); } } diff --git a/contracts/coconut-dkg/src/epoch_state/utils.rs b/contracts/coconut-dkg/src/epoch_state/utils.rs index 3e712c431d..46fa44a885 100644 --- a/contracts/coconut-dkg/src/epoch_state/utils.rs +++ b/contracts/coconut-dkg/src/epoch_state/utils.rs @@ -20,9 +20,14 @@ pub(crate) fn check_state_completion( EpochState::PublicKeySubmission { .. } => Ok(false), // if every dealer has submitted all dealings, we're done - EpochState::DealingExchange { .. } => { - let expected_dealings = - contract_state.key_size * epoch.state_progress.registered_dealers; + EpochState::DealingExchange { resharing } => { + // during resharing, we only expect to receive dealings from resharing dealers + let expected_dealings = if !resharing { + contract_state.key_size * epoch.state_progress.registered_dealers + } else { + contract_state.key_size * epoch.state_progress.registered_resharing_dealers + }; + Ok(expected_dealings == epoch.state_progress.submitted_dealings) } @@ -63,8 +68,142 @@ pub(crate) mod test { use super::*; use crate::support::tests::helpers::init_contract; use cosmwasm_std::testing::mock_env; + use cosmwasm_std::Timestamp; use nym_coconut_dkg_common::types::{Epoch, TimeConfiguration}; + #[test] + fn checking_state_completion() { + fn epoch_in_state(state: EpochState) -> Epoch { + Epoch::new(state, 0, Default::default(), Timestamp::from_seconds(69)) + } + + let deps = init_contract(); + + // it's never possible to short-circuit `WaitingInitialisation` + let epoch = epoch_in_state(EpochState::WaitingInitialisation); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // neither PublicKeySubmission (in either resharing or non-resharing) + let epoch = epoch_in_state(EpochState::PublicKeySubmission { resharing: false }); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let epoch = epoch_in_state(EpochState::PublicKeySubmission { resharing: true }); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let key_size = STATE.load(&deps.storage).unwrap().key_size; + + // we can short-circuit `DealingExchange` if all dealers submitted their dealings + + // no dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }); + epoch.state_progress.registered_dealers = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // some dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_dealings = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // all dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: false }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_dealings = key_size * 5; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + // no dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // some dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + epoch.state_progress.submitted_dealings = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // all dealings + let mut epoch = epoch_in_state(EpochState::DealingExchange { resharing: true }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.registered_resharing_dealers = 4; + epoch.state_progress.submitted_dealings = key_size * 4; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + // we can short-circuit `VerificationKeySubmission` if all dealers submitted their verification keys + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: false }); + epoch.state_progress.registered_dealers = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: true }); + epoch.state_progress.registered_dealers = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: false }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 4; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: true }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 4; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: false }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 5; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeySubmission { resharing: true }); + epoch.state_progress.registered_dealers = 5; + epoch.state_progress.submitted_key_shares = 5; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + // can't short-circuit `VerificationKeyValidation` => we rely on multisig votes here + let epoch = epoch_in_state(EpochState::VerificationKeyValidation { resharing: false }); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let epoch = epoch_in_state(EpochState::VerificationKeyValidation { resharing: true }); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + // we can short-circuit `VerificationKeyFinalization` if all submitted keys got verified + let mut epoch = + epoch_in_state(EpochState::VerificationKeyFinalization { resharing: false }); + epoch.state_progress.submitted_key_shares = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeyFinalization { resharing: true }); + epoch.state_progress.submitted_key_shares = 5; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = + epoch_in_state(EpochState::VerificationKeyFinalization { resharing: false }); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 4; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeyFinalization { resharing: true }); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 4; + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = + epoch_in_state(EpochState::VerificationKeyFinalization { resharing: false }); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 5; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + let mut epoch = epoch_in_state(EpochState::VerificationKeyFinalization { resharing: true }); + epoch.state_progress.submitted_key_shares = 5; + epoch.state_progress.verified_keys = 5; + assert!(check_state_completion(&deps.storage, &epoch).unwrap()); + + // it's never possible to short-circuit `InProgress` + let epoch = epoch_in_state(EpochState::InProgress); + assert!(!check_state_completion(&deps.storage, &epoch).unwrap()); + } + #[test] pub fn check_state() { let mut deps = init_contract(); diff --git a/contracts/coconut-dkg/src/error.rs b/contracts/coconut-dkg/src/error.rs index f7952deedc..bde8738951 100644 --- a/contracts/coconut-dkg/src/error.rs +++ b/contracts/coconut-dkg/src/error.rs @@ -48,9 +48,6 @@ pub enum ContractError { #[error("This sender is not a dealer for epoch {epoch_id}")] NotADealer { epoch_id: EpochId }, - #[error("This sender is not a dealer for the current resharing epoch")] - NotAnInitialDealer, - #[error("Dealer {dealer} has already committed dealing chunk for epoch {epoch_id} with dealing index {dealing_index} and chunk index {chunk_index} at height {block_height}")] DealingChunkAlreadyCommitted { epoch_id: EpochId, diff --git a/contracts/coconut-dkg/src/support/tests/helpers.rs b/contracts/coconut-dkg/src/support/tests/helpers.rs index 5117c76841..ce0e370d55 100644 --- a/contracts/coconut-dkg/src/support/tests/helpers.rs +++ b/contracts/coconut-dkg/src/support/tests/helpers.rs @@ -2,16 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 use crate::contract::instantiate; -use crate::dealers::storage::current_dealers; +use crate::dealers::storage::{DEALERS_INDICES, EPOCH_DEALERS_MAP}; +use crate::epoch_state::storage::CURRENT_EPOCH; use cosmwasm_std::testing::{mock_dependencies, mock_env, mock_info, MockApi, MockQuerier}; use cosmwasm_std::{ from_binary, to_binary, Addr, ContractResult, DepsMut, Empty, MemoryStorage, OwnedDeps, QuerierResult, SystemResult, WasmQuery, }; use cw4::{Cw4QueryMsg, Member, MemberListResponse, MemberResponse}; +use nym_coconut_dkg_common::dealer::DealerRegistrationDetails; use nym_coconut_dkg_common::dealing::DEFAULT_DEALINGS; use nym_coconut_dkg_common::msg::InstantiateMsg; -use nym_coconut_dkg_common::types::DealerDetails; +use nym_coconut_dkg_common::types::{DealerDetails, EpochId}; use std::sync::Mutex; use super::fixtures::TEST_MIX_DENOM; @@ -23,21 +25,52 @@ pub const MULTISIG_CONTRACT: &str = "multisig contract address"; // wtf, why is this a thing? pub(crate) static GROUP_MEMBERS: Mutex> = Mutex::new(Vec::new()); -pub fn add_fixture_dealer(deps: DepsMut<'_>) { - let owner = Addr::unchecked("owner"); - current_dealers() +pub fn re_register_dealer(deps: DepsMut, dealer: &Addr) { + let epoch_id = CURRENT_EPOCH.load(deps.storage).unwrap().epoch_id; + let previous = epoch_id - 1; + let details = EPOCH_DEALERS_MAP + .load(deps.storage, (previous, dealer)) + .unwrap(); + EPOCH_DEALERS_MAP + .save(deps.storage, (epoch_id, dealer), &details) + .unwrap() +} + +pub fn add_current_dealer(deps: DepsMut<'_>, details: &DealerDetails) { + let epoch_id = CURRENT_EPOCH.load(deps.storage).unwrap().epoch_id; + insert_dealer(deps, epoch_id, details) +} + +pub fn insert_dealer(deps: DepsMut<'_>, epoch_id: EpochId, details: &DealerDetails) { + DEALERS_INDICES + .save(deps.storage, &details.address, &details.assigned_index) + .unwrap(); + + EPOCH_DEALERS_MAP .save( deps.storage, - &owner, - &DealerDetails { - address: owner.clone(), - bte_public_key_with_proof: String::new(), - ed25519_identity: String::new(), - announce_address: String::new(), - assigned_index: 100, + (epoch_id, &details.address), + &DealerRegistrationDetails { + bte_public_key_with_proof: details.bte_public_key_with_proof.clone(), + ed25519_identity: details.ed25519_identity.clone(), + announce_address: details.announce_address.clone(), }, ) - .unwrap(); + .unwrap() +} + +pub fn add_fixture_dealer(deps: DepsMut<'_>) { + let owner = Addr::unchecked("owner"); + add_current_dealer( + deps, + &DealerDetails { + address: owner.clone(), + bte_public_key_with_proof: String::new(), + ed25519_identity: String::new(), + announce_address: String::new(), + assigned_index: 100, + }, + ); } fn querier_handler(query: &WasmQuery) -> QuerierResult { diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index f4760e9907..9d65e11a89 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -103,7 +103,9 @@ mod tests { use super::*; use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; use crate::support::tests::helpers; - use crate::support::tests::helpers::{add_fixture_dealer, ADMIN_ADDRESS, MULTISIG_CONTRACT}; + use crate::support::tests::helpers::{ + add_current_dealer, add_fixture_dealer, ADMIN_ADDRESS, MULTISIG_CONTRACT, + }; use cosmwasm_std::testing::{mock_env, mock_info}; use cosmwasm_std::Addr; use cw_controllers::AdminError; @@ -139,9 +141,7 @@ mod tests { announce_address: announce_address.clone(), assigned_index: 1, }; - dealers_storage::current_dealers() - .save(deps.as_mut().storage, &dealer, &dealer_details) - .unwrap(); + add_current_dealer(deps.as_mut(), &dealer_details); try_commit_verification_key_share(deps.as_mut(), env, info.clone(), share.clone(), false) .unwrap(); @@ -203,7 +203,7 @@ mod tests { false, ) .unwrap_err(); - assert_eq!(ret, ContractError::NotADealer); + assert_eq!(ret, ContractError::NotADealer { epoch_id: 0 }); let dealer = Addr::unchecked("requester"); let dealer_details = DealerDetails { @@ -213,9 +213,7 @@ mod tests { announce_address: String::new(), assigned_index: 1, }; - dealers_storage::current_dealers() - .save(deps.as_mut().storage, &dealer, &dealer_details) - .unwrap(); + add_current_dealer(deps.as_mut(), &dealer_details); try_commit_verification_key_share( deps.as_mut(), @@ -325,13 +323,8 @@ mod tests { announce_address: String::new(), assigned_index: 1, }; - dealers_storage::current_dealers() - .save( - deps.as_mut().storage, - &Addr::unchecked(&owner), - &dealer_details, - ) - .unwrap(); + add_current_dealer(deps.as_mut(), &dealer_details); + try_commit_verification_key_share(deps.as_mut(), env.clone(), info, share, false).unwrap(); env.block.time = env From 9821dd994b693c6fd659e44235c938ddd708d358 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 16:38:03 +0000 Subject: [PATCH 041/394] updated schema --- contracts/Cargo.lock | 1 - contracts/coconut-dkg/schema/nym-coconut-dkg.json | 11 +++++++++++ .../raw/response_to_get_current_epoch_state.json | 11 +++++++++++ 3 files changed, 22 insertions(+), 1 deletion(-) diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index fdab88b8b7..2ee4e93b1b 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -1228,7 +1228,6 @@ dependencies = [ "cw4-group", "nym-coconut-dkg-common", "nym-group-contract-common", - "rusty-fork", "semver", "serde", "thiserror", diff --git a/contracts/coconut-dkg/schema/nym-coconut-dkg.json b/contracts/coconut-dkg/schema/nym-coconut-dkg.json index 3f64c4f100..7ac69ca8c5 100644 --- a/contracts/coconut-dkg/schema/nym-coconut-dkg.json +++ b/contracts/coconut-dkg/schema/nym-coconut-dkg.json @@ -989,27 +989,38 @@ "type": "object", "required": [ "registered_dealers", + "registered_resharing_dealers", "submitted_dealings", "submitted_key_shares", "verified_keys" ], "properties": { "registered_dealers": { + "description": "Counts the number of dealers that have registered in this epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "registered_resharing_dealers": { + "description": "Counts the number of resharing dealers that have registered in this epoch. This field is only populated during a resharing exchange. It is always <= registered_dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "submitted_dealings": { + "description": "Counts the number of fully received dealings (i.e. full chunks) from all the allowed dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "submitted_key_shares": { + "description": "Counts the number of submitted verification key shared from the dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "verified_keys": { + "description": "Counts the number of verified key shares.", "type": "integer", "format": "uint32", "minimum": 0.0 diff --git a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json index 251d4c7e01..7ef9d87477 100644 --- a/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json +++ b/contracts/coconut-dkg/schema/raw/response_to_get_current_epoch_state.json @@ -156,27 +156,38 @@ "type": "object", "required": [ "registered_dealers", + "registered_resharing_dealers", "submitted_dealings", "submitted_key_shares", "verified_keys" ], "properties": { "registered_dealers": { + "description": "Counts the number of dealers that have registered in this epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "registered_resharing_dealers": { + "description": "Counts the number of resharing dealers that have registered in this epoch. This field is only populated during a resharing exchange. It is always <= registered_dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "submitted_dealings": { + "description": "Counts the number of fully received dealings (i.e. full chunks) from all the allowed dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "submitted_key_shares": { + "description": "Counts the number of submitted verification key shared from the dealers.", "type": "integer", "format": "uint32", "minimum": 0.0 }, "verified_keys": { + "description": "Counts the number of verified key shares.", "type": "integer", "format": "uint32", "minimum": 0.0 From d4c98e3ff555bb3bbaba09fabac7fadc4a5544e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 16:47:01 +0000 Subject: [PATCH 042/394] clippy test --- contracts/coconut-test/src/helpers.rs | 4 +- .../coconut-test/src/reset_upon_threshold.rs | 65 ------------------- .../src/spend_credential_creates_proposal.rs | 2 +- contracts/coconut-test/src/test_wrapper.rs | 7 +- contracts/coconut-test/src/tests.rs | 1 - 5 files changed, 6 insertions(+), 73 deletions(-) delete mode 100644 contracts/coconut-test/src/reset_upon_threshold.rs diff --git a/contracts/coconut-test/src/helpers.rs b/contracts/coconut-test/src/helpers.rs index df67e9c311..229cd55128 100644 --- a/contracts/coconut-test/src/helpers.rs +++ b/contracts/coconut-test/src/helpers.rs @@ -1,10 +1,8 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use cosmwasm_std::{entry_point, Addr, Coin, DepsMut, Empty, Env, Response}; +use cosmwasm_std::{Addr, Coin, Empty}; use cw_multi_test::{App, AppBuilder, Contract, ContractWrapper}; -use nym_multisig_contract_common::error::ContractError; -use nym_multisig_contract_common::state::CONFIG; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; diff --git a/contracts/coconut-test/src/reset_upon_threshold.rs b/contracts/coconut-test/src/reset_upon_threshold.rs deleted file mode 100644 index a36597f666..0000000000 --- a/contracts/coconut-test/src/reset_upon_threshold.rs +++ /dev/null @@ -1,65 +0,0 @@ -// Copyright 2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use crate::test_wrapper::TestSetup; -use nym_coconut_dkg_common::types::EpochState; - -#[test] -fn removing_enough_members_causes_dkg_reset() { - let mut test = TestSetup::new(); - - let member1 = test.add_mock_group_member(None); - let member2 = test.add_mock_group_member(None); - let member3 = test.add_mock_group_member(None); - let member4 = test.add_mock_group_member(None); - let member5 = test.add_mock_group_member(None); - - test.begin_dkg(); - test.full_dummy_dkg( - vec![ - member1, - member2, - member3.clone(), - member4.clone(), - member5.clone(), - ], - false, - ); - - test.remove_group_member(&member3); - test.remove_group_member(&member4); - test.remove_group_member(&member5); - - test.skip_to_dkg_state_end(); - test.unchecked_advance_dkg_epoch(); - - let epoch = test.epoch(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); -} - -#[test] -fn adding_enough_members_causes_dkg_reset() { - let mut test = TestSetup::new(); - - let member1 = test.add_mock_group_member(None); - let member2 = test.add_mock_group_member(None); - - test.begin_dkg(); - test.full_dummy_dkg(vec![member1, member2], false); - - let _member3 = test.add_mock_group_member(None); - let _member4 = test.add_mock_group_member(None); - let _member5 = test.add_mock_group_member(None); - - test.skip_to_dkg_state_end(); - test.unchecked_advance_dkg_epoch(); - - let epoch = test.epoch(); - assert_eq!( - epoch.state, - EpochState::PublicKeySubmission { resharing: false } - ); -} diff --git a/contracts/coconut-test/src/spend_credential_creates_proposal.rs b/contracts/coconut-test/src/spend_credential_creates_proposal.rs index abcf761da5..05eb30ba9e 100644 --- a/contracts/coconut-test/src/spend_credential_creates_proposal.rs +++ b/contracts/coconut-test/src/spend_credential_creates_proposal.rs @@ -81,7 +81,7 @@ fn spend_credential_creates_proposal() { let msg = MigrateMsg { coconut_bandwidth_address: coconut_bandwidth_contract_addr.to_string(), - coconut_dkg_address: "".to_string(), + coconut_dkg_address: "dkg-address".to_string(), }; app.migrate_contract( Addr::unchecked(OWNER), diff --git a/contracts/coconut-test/src/test_wrapper.rs b/contracts/coconut-test/src/test_wrapper.rs index 975fdb531c..e9336ad19c 100644 --- a/contracts/coconut-test/src/test_wrapper.rs +++ b/contracts/coconut-test/src/test_wrapper.rs @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::helpers::{contract_bandwidth, contract_dkg, contract_group, contract_multisig}; -use cosmwasm_std::testing::mock_dependencies; -use cosmwasm_std::{coins, Addr, Api, CanonicalAddr}; +use cosmwasm_std::{coins, Addr}; use cw3::{Cw3Contract, ProposalListResponse, Status, Vote}; use cw4::{Cw4Contract, Member}; use cw_multi_test::{App, AppBuilder, Executor}; @@ -40,6 +39,7 @@ pub fn random_address(rng: &mut ChaCha20Rng) -> Addr { Addr::unchecked(bech32::encode(PREFIX, bytes)) } +#[allow(dead_code)] pub struct TestSetup { pub app: App, pub rng: ChaCha20Rng, @@ -51,6 +51,7 @@ pub struct TestSetup { pub bandwidth_contract: Addr, } +#[allow(dead_code)] impl TestSetup { pub fn new() -> Self { let mut rng = test_rng(); @@ -339,7 +340,7 @@ impl TestSetup { .execute_contract( member.clone(), self.dkg_contract.clone(), - &DkgExecuteMsg::CommitDealingsChunk { chunk, resharing }, + &DkgExecuteMsg::CommitDealingsChunk { chunk }, &[], ) .unwrap(); diff --git a/contracts/coconut-test/src/tests.rs b/contracts/coconut-test/src/tests.rs index 4c1310dbb8..04c6d327d2 100644 --- a/contracts/coconut-test/src/tests.rs +++ b/contracts/coconut-test/src/tests.rs @@ -3,7 +3,6 @@ mod deposit_and_release; mod helpers; -mod reset_upon_threshold; mod spend_credential_creates_proposal; mod submit_vk_creates_proposal; mod test_wrapper; From 627334cfe2e7fa45c41fce47e797458ba405cb5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:16:39 +0000 Subject: [PATCH 043/394] added dkg contract query to check if state can be advanced --- .../nyxd/contract_traits/dkg_query_client.rs | 8 ++++- .../coconut-dkg/src/msg.rs | 5 ++- .../coconut-dkg/src/types.rs | 16 ++++++++++ contracts/coconut-dkg/src/contract.rs | 7 +++-- .../coconut-dkg/src/epoch_state/queries.rs | 31 +++++++++++++++++-- 5 files changed, 61 insertions(+), 6 deletions(-) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index 33ae58bc42..dcf6590457 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -8,7 +8,7 @@ use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use cosmwasm_std::Addr; -use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex}; +use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex, StateAdvanceResponse}; use serde::Deserialize; use nym_coconut_dkg_common::dealer::RegisteredDealerDetails; @@ -40,6 +40,11 @@ pub trait DkgQueryClient { self.query_dkg_contract(request).await } + async fn can_advance_state(&self) -> Result { + let request = DkgQueryMsg::CanAdvanceState {}; + self.query_dkg_contract(request).await + } + async fn get_current_epoch_threshold(&self) -> Result, NyxdError> { let request = DkgQueryMsg::GetCurrentEpochThreshold {}; self.query_dkg_contract(request).await @@ -245,6 +250,7 @@ mod tests { match msg { DkgQueryMsg::GetState {} => client.get_state().ignore(), DkgQueryMsg::GetCurrentEpochState {} => client.get_current_epoch().ignore(), + DkgQueryMsg::CanAdvanceState {} => client.can_advance_state().ignore(), DkgQueryMsg::GetCurrentEpochThreshold {} => { client.get_current_epoch_threshold().ignore() } diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 8874bce5cb..4e2a155c3f 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -13,7 +13,7 @@ use cosmwasm_schema::cw_serde; use crate::{ dealer::{ DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse, - RegisteredDealerDetails, + RegisteredDealerDetails, StateAdvanceResponse, }, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, @@ -87,6 +87,9 @@ pub enum QueryMsg { #[cfg_attr(feature = "schema", returns(u64))] GetCurrentEpochThreshold {}, + #[cfg_attr(feature = "schema", returns(StateAdvanceResponse))] + CanAdvanceState {}, + #[cfg_attr(feature = "schema", returns(RegisteredDealerDetails))] GetRegisteredDealer { dealer_address: String, diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs index 7ff34d682e..43192e9622 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/types.rs @@ -21,6 +21,22 @@ pub type DealingIndex = u32; pub type ChunkIndex = u16; pub type PartialContractDealingData = ContractSafeBytes; +#[cw_serde] +#[derive(Copy, Default)] +pub struct StateAdvanceResponse { + pub current_state: EpochState, + pub progress: StateProgress, + pub deadline: Option, + pub reached_deadline: bool, + pub is_complete: bool, +} + +impl StateAdvanceResponse { + pub fn can_advance(&self) -> bool { + self.reached_deadline || self.is_complete + } +} + #[cw_serde] #[derive(Copy)] pub struct TimeConfiguration { diff --git a/contracts/coconut-dkg/src/contract.rs b/contracts/coconut-dkg/src/contract.rs index b1926206c6..2d1e25d5e9 100644 --- a/contracts/coconut-dkg/src/contract.rs +++ b/contracts/coconut-dkg/src/contract.rs @@ -11,7 +11,9 @@ use crate::dealings::queries::{ query_dealing_metadata, query_dealing_status, }; use crate::dealings::transactions::{try_commit_dealings_chunk, try_submit_dealings_metadata}; -use crate::epoch_state::queries::{query_current_epoch, query_current_epoch_threshold}; +use crate::epoch_state::queries::{ + query_can_advance_state, query_current_epoch, query_current_epoch_threshold, +}; use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{ try_advance_epoch_state, try_initiate_dkg, try_trigger_reset, try_trigger_resharing, @@ -123,10 +125,11 @@ pub fn execute( } #[entry_point] -pub fn query(deps: Deps<'_>, _env: Env, msg: QueryMsg) -> Result { +pub fn query(deps: Deps<'_>, env: Env, msg: QueryMsg) -> Result { let response = match msg { QueryMsg::GetState {} => to_binary(&query_state(deps.storage)?)?, QueryMsg::GetCurrentEpochState {} => to_binary(&query_current_epoch(deps.storage)?)?, + QueryMsg::CanAdvanceState {} => to_binary(&query_can_advance_state(deps.storage, env)?)?, QueryMsg::GetCurrentEpochThreshold {} => { to_binary(&query_current_epoch_threshold(deps.storage)?)? } diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 9a748385bb..76ea8ac9d7 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -2,9 +2,36 @@ // SPDX-License-Identifier: Apache-2.0 use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; +use crate::epoch_state::utils::check_state_completion; use crate::error::ContractError; -use cosmwasm_std::Storage; -use nym_coconut_dkg_common::types::Epoch; +use cosmwasm_std::{Env, StdResult, Storage}; +use nym_coconut_dkg_common::types::{Epoch, EpochState, StateAdvanceResponse}; + +pub(crate) fn query_can_advance_state( + storage: &dyn Storage, + env: Env, +) -> Result { + let epoch = CURRENT_EPOCH.load(storage)?; + + if epoch.state == EpochState::WaitingInitialisation { + return Ok(StateAdvanceResponse::default()); + } + + let is_complete = check_state_completion(storage, &epoch)?; + let reached_deadline = if let Some(finish_timestamp) = epoch.deadline { + finish_timestamp <= env.block.time + } else { + false + }; + + Ok(StateAdvanceResponse { + current_state: epoch.state, + progress: epoch.state_progress, + deadline: epoch.deadline, + reached_deadline, + is_complete, + }) +} pub(crate) fn query_current_epoch(storage: &dyn Storage) -> Result { CURRENT_EPOCH From 510ad11c98834c84b4ed3d33e8b3dd8e6e7b8cc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:33:07 +0000 Subject: [PATCH 044/394] nym-api using the new query --- nym-api/src/coconut/client.rs | 2 ++ nym-api/src/coconut/dkg/client.rs | 4 ++++ nym-api/src/coconut/dkg/controller/error.rs | 6 +++++ nym-api/src/coconut/dkg/controller/mod.rs | 25 ++++++++++++++------- nym-api/src/support/nyxd/mod.rs | 4 ++++ 5 files changed, 33 insertions(+), 8 deletions(-) diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index 414c89fcf1..f018c1f72d 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -100,6 +100,8 @@ pub trait Client { async fn execute_proposal(&self, proposal_id: u64) -> Result<()>; + async fn can_advance_epoch_state(&self) -> Result; + async fn advance_epoch_state(&self) -> Result<()>; async fn register_dealer( diff --git a/nym-api/src/coconut/dkg/client.rs b/nym-api/src/coconut/dkg/client.rs index bad9ce6ea9..f85902ba48 100644 --- a/nym-api/src/coconut/dkg/client.rs +++ b/nym-api/src/coconut/dkg/client.rs @@ -156,6 +156,10 @@ impl DkgClient { self.inner.advance_epoch_state().await } + pub(crate) async fn can_advance_epoch_state(&self) -> Result { + self.inner.can_advance_epoch_state().await + } + pub(crate) async fn register_dealer( &self, bte_key: EncodedBTEPublicKeyWithProof, diff --git a/nym-api/src/coconut/dkg/controller/error.rs b/nym-api/src/coconut/dkg/controller/error.rs index 2ac15d71f6..e634477db6 100644 --- a/nym-api/src/coconut/dkg/controller/error.rs +++ b/nym-api/src/coconut/dkg/controller/error.rs @@ -25,6 +25,12 @@ pub enum DkgError { source: CoconutError, }, + #[error("failed to query for the epoch state status: {source}")] + StateStatusQueryFailure { + #[source] + source: CoconutError, + }, + #[error("failed to query the CW4 group contract for the membership status: {source}")] GroupQueryFailure { #[source] diff --git a/nym-api/src/coconut/dkg/controller/mod.rs b/nym-api/src/coconut/dkg/controller/mod.rs index 8393b52770..4b35fb3fcf 100644 --- a/nym-api/src/coconut/dkg/controller/mod.rs +++ b/nym-api/src/coconut/dkg/controller/mod.rs @@ -17,7 +17,7 @@ use rand::{CryptoRng, Rng, RngCore}; use std::path::PathBuf; use std::time::Duration; use time::OffsetDateTime; -use tokio::time::interval; +use tokio::time::{interval, MissedTickBehavior}; mod error; pub(crate) mod keys; @@ -194,6 +194,14 @@ impl DkgController { Ok(()) } + async fn check_if_can_advance_epoch_state(&self) -> Result { + debug!("checking if we can advance the epoch state"); + self.dkg_client + .can_advance_epoch_state() + .await + .map_err(|source| DkgError::StateStatusQueryFailure { source }) + } + async fn try_advance_dkg_state(&mut self) -> Result<(), DkgError> { // We try advancing the epoch state, on a best-effort basis info!("DKG: Trying to advance the epoch"); @@ -234,13 +242,13 @@ impl DkgController { EpochState::InProgress => self.handle_in_progress(epoch.epoch_id).await?, }; - // add a bit of variance so that all apis wouldn't attempt to trigger it at the same time - let variance = self.rng.gen_range(0..=60); - if let Some(epoch_finish) = epoch.deadline { - let now = OffsetDateTime::now_utc(); - if now.unix_timestamp() > epoch_finish.seconds() as i64 + variance { - // TODO: make sure to not overload validator in case its running slow - // i.e. send it once at most every X seconds + if self.check_if_can_advance_epoch_state().await? { + // add a bit of variance so that all apis wouldn't attempt to trigger it at the same time + let variance = self.rng.gen_range(0..=60); + tokio::time::sleep(Duration::from_secs(variance)).await; + + // check if whether during our waiting somebody has already advanced the epoch + if self.check_if_can_advance_epoch_state().await? { self.try_advance_dkg_state().await? } } @@ -258,6 +266,7 @@ impl DkgController { pub(crate) async fn run(mut self, mut shutdown: TaskClient) { let mut interval = interval(self.polling_rate); + interval.set_missed_tick_behavior(MissedTickBehavior::Delay); // sometimes when the process is running behind, the ticker resolves multiple times in quick succession // so explicitly track those instances and make sure we don't overload the validator with contract calls diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index dcd60c1234..1ae492206e 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -522,6 +522,10 @@ impl crate::coconut::client::Client for Client { Ok(()) } + async fn can_advance_epoch_state(&self) -> crate::coconut::error::Result { + Ok(nyxd_query!(self, can_advance_state().await?.can_advance())) + } + async fn advance_epoch_state(&self) -> crate::coconut::error::Result<()> { nyxd_signing!(self, advance_dkg_epoch_state(None).await?); Ok(()) From 24a260fbc9bb4f2341b58bb24acf058793506cbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:36:23 +0000 Subject: [PATCH 045/394] missing trait implementation in test --- nym-api/src/coconut/tests/mod.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index c28bb78398..db20f4bc1b 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -903,6 +903,7 @@ impl super::client::Client for DummyClient { Some(epoch_shares) => Ok(epoch_shares.values().cloned().collect()), } } + async fn vote_proposal( &self, proposal_id: u64, @@ -954,7 +955,6 @@ impl super::client::Client for DummyClient { Ok(()) } - async fn execute_proposal(&self, proposal_id: u64) -> Result<()> { let mut chain = self.state.lock().unwrap(); let multisig_address: AccountId = chain.multisig_contract.address.as_str().parse().unwrap(); @@ -977,6 +977,17 @@ impl super::client::Client for DummyClient { Ok(()) } + async fn can_advance_epoch_state(&self) -> Result { + // TODO: incorporate the short-circuiting logic in here + let chain = self.state.lock().unwrap(); + let epoch = chain.dkg_contract.epoch; + Ok(if let Some(finish_timestamp) = epoch.deadline { + finish_timestamp <= chain.block_info.time + } else { + false + }) + } + async fn advance_epoch_state(&self) -> Result<()> { todo!() } From 8b0953624f7f6b2ffdf447df6bc6bd70f818edac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:39:22 +0000 Subject: [PATCH 046/394] being less aggressive in contract polling --- nym-api/src/coconut/dkg/controller/mod.rs | 5 +++++ nym-api/src/support/config/mod.rs | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/nym-api/src/coconut/dkg/controller/mod.rs b/nym-api/src/coconut/dkg/controller/mod.rs index 4b35fb3fcf..db9ce0a82c 100644 --- a/nym-api/src/coconut/dkg/controller/mod.rs +++ b/nym-api/src/coconut/dkg/controller/mod.rs @@ -191,6 +191,11 @@ impl DkgController { self.state.in_progress_state_mut(epoch_id).unwrap().entered = true; } + // so at this point we don't need to be polling the contract so often anymore, but we can't easily + // adjust the existing interval. + // however, what we can do is just wait here for a bit each iteration + tokio::time::sleep(Duration::from_secs(120)).await; + Ok(()) } diff --git a/nym-api/src/support/config/mod.rs b/nym-api/src/support/config/mod.rs index ca2eb1328c..c5191b7960 100644 --- a/nym-api/src/support/config/mod.rs +++ b/nym-api/src/support/config/mod.rs @@ -30,7 +30,7 @@ mod upgrade_helpers; pub const DEFAULT_LOCAL_VALIDATOR: &str = "http://localhost:26657"; -pub const DEFAULT_DKG_CONTRACT_POLLING_RATE: Duration = Duration::from_secs(10); +pub const DEFAULT_DKG_CONTRACT_POLLING_RATE: Duration = Duration::from_secs(30); const DEFAULT_GATEWAY_SENDING_RATE: usize = 200; const DEFAULT_MAX_CONCURRENT_GATEWAY_CLIENTS: usize = 50; From 6b6980c523e493a9b8e8e4b53bc80400aac9db7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 16 Feb 2024 17:41:46 +0000 Subject: [PATCH 047/394] missing schema --- .../coconut-dkg/src/msg.rs | 4 +- .../coconut-dkg/schema/nym-coconut-dkg.json | 222 ++++++++++++++++++ contracts/coconut-dkg/schema/raw/query.json | 13 + .../raw/response_to_can_advance_state.json | 209 +++++++++++++++++ .../coconut-dkg/src/epoch_state/queries.rs | 2 +- 5 files changed, 447 insertions(+), 3 deletions(-) create mode 100644 contracts/coconut-dkg/schema/raw/response_to_can_advance_state.json diff --git a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs index 4e2a155c3f..0b3da8a552 100644 --- a/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs +++ b/common/cosmwasm-smart-contracts/coconut-dkg/src/msg.rs @@ -13,13 +13,13 @@ use cosmwasm_schema::cw_serde; use crate::{ dealer::{ DealerDetailsResponse, PagedDealerIndexResponse, PagedDealerResponse, - RegisteredDealerDetails, StateAdvanceResponse, + RegisteredDealerDetails, }, dealing::{ DealerDealingsStatusResponse, DealingChunkResponse, DealingChunkStatusResponse, DealingMetadataResponse, DealingStatusResponse, }, - types::{Epoch, State}, + types::{Epoch, State, StateAdvanceResponse}, verification_key::{PagedVKSharesResponse, VkShareResponse}, }; #[cfg(feature = "schema")] diff --git a/contracts/coconut-dkg/schema/nym-coconut-dkg.json b/contracts/coconut-dkg/schema/nym-coconut-dkg.json index 7ac69ca8c5..43f3a69975 100644 --- a/contracts/coconut-dkg/schema/nym-coconut-dkg.json +++ b/contracts/coconut-dkg/schema/nym-coconut-dkg.json @@ -374,6 +374,19 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "can_advance_state" + ], + "properties": { + "can_advance_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "type": "object", "required": [ @@ -741,6 +754,215 @@ }, "sudo": null, "responses": { + "can_advance_state": { + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StateAdvanceResponse", + "type": "object", + "required": [ + "current_state", + "is_complete", + "progress", + "reached_deadline" + ], + "properties": { + "current_state": { + "$ref": "#/definitions/EpochState" + }, + "deadline": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "is_complete": { + "type": "boolean" + }, + "progress": { + "$ref": "#/definitions/StateProgress" + }, + "reached_deadline": { + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "EpochState": { + "oneOf": [ + { + "type": "string", + "enum": [ + "waiting_initialisation", + "in_progress" + ] + }, + { + "type": "object", + "required": [ + "public_key_submission" + ], + "properties": { + "public_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dealing_exchange" + ], + "properties": { + "dealing_exchange": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_submission" + ], + "properties": { + "verification_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_validation" + ], + "properties": { + "verification_key_validation": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_finalization" + ], + "properties": { + "verification_key_finalization": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "StateProgress": { + "type": "object", + "required": [ + "registered_dealers", + "registered_resharing_dealers", + "submitted_dealings", + "submitted_key_shares", + "verified_keys" + ], + "properties": { + "registered_dealers": { + "description": "Counts the number of dealers that have registered in this epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "registered_resharing_dealers": { + "description": "Counts the number of resharing dealers that have registered in this epoch. This field is only populated during a resharing exchange. It is always <= registered_dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_dealings": { + "description": "Counts the number of fully received dealings (i.e. full chunks) from all the allowed dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_key_shares": { + "description": "Counts the number of submitted verification key shared from the dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "verified_keys": { + "description": "Counts the number of verified key shares.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } + }, "get_c_w2_contract_version": { "$schema": "http://json-schema.org/draft-07/schema#", "title": "ContractVersion", diff --git a/contracts/coconut-dkg/schema/raw/query.json b/contracts/coconut-dkg/schema/raw/query.json index 714003786d..72e1e095cd 100644 --- a/contracts/coconut-dkg/schema/raw/query.json +++ b/contracts/coconut-dkg/schema/raw/query.json @@ -41,6 +41,19 @@ }, "additionalProperties": false }, + { + "type": "object", + "required": [ + "can_advance_state" + ], + "properties": { + "can_advance_state": { + "type": "object", + "additionalProperties": false + } + }, + "additionalProperties": false + }, { "type": "object", "required": [ diff --git a/contracts/coconut-dkg/schema/raw/response_to_can_advance_state.json b/contracts/coconut-dkg/schema/raw/response_to_can_advance_state.json new file mode 100644 index 0000000000..80f27e02ba --- /dev/null +++ b/contracts/coconut-dkg/schema/raw/response_to_can_advance_state.json @@ -0,0 +1,209 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "title": "StateAdvanceResponse", + "type": "object", + "required": [ + "current_state", + "is_complete", + "progress", + "reached_deadline" + ], + "properties": { + "current_state": { + "$ref": "#/definitions/EpochState" + }, + "deadline": { + "anyOf": [ + { + "$ref": "#/definitions/Timestamp" + }, + { + "type": "null" + } + ] + }, + "is_complete": { + "type": "boolean" + }, + "progress": { + "$ref": "#/definitions/StateProgress" + }, + "reached_deadline": { + "type": "boolean" + } + }, + "additionalProperties": false, + "definitions": { + "EpochState": { + "oneOf": [ + { + "type": "string", + "enum": [ + "waiting_initialisation", + "in_progress" + ] + }, + { + "type": "object", + "required": [ + "public_key_submission" + ], + "properties": { + "public_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "dealing_exchange" + ], + "properties": { + "dealing_exchange": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_submission" + ], + "properties": { + "verification_key_submission": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_validation" + ], + "properties": { + "verification_key_validation": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + }, + { + "type": "object", + "required": [ + "verification_key_finalization" + ], + "properties": { + "verification_key_finalization": { + "type": "object", + "required": [ + "resharing" + ], + "properties": { + "resharing": { + "type": "boolean" + } + }, + "additionalProperties": false + } + }, + "additionalProperties": false + } + ] + }, + "StateProgress": { + "type": "object", + "required": [ + "registered_dealers", + "registered_resharing_dealers", + "submitted_dealings", + "submitted_key_shares", + "verified_keys" + ], + "properties": { + "registered_dealers": { + "description": "Counts the number of dealers that have registered in this epoch.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "registered_resharing_dealers": { + "description": "Counts the number of resharing dealers that have registered in this epoch. This field is only populated during a resharing exchange. It is always <= registered_dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_dealings": { + "description": "Counts the number of fully received dealings (i.e. full chunks) from all the allowed dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "submitted_key_shares": { + "description": "Counts the number of submitted verification key shared from the dealers.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + }, + "verified_keys": { + "description": "Counts the number of verified key shares.", + "type": "integer", + "format": "uint32", + "minimum": 0.0 + } + }, + "additionalProperties": false + }, + "Timestamp": { + "description": "A point in time in nanosecond precision.\n\nThis type can represent times from 1970-01-01T00:00:00Z to 2554-07-21T23:34:33Z.\n\n## Examples\n\n``` # use cosmwasm_std::Timestamp; let ts = Timestamp::from_nanos(1_000_000_202); assert_eq!(ts.nanos(), 1_000_000_202); assert_eq!(ts.seconds(), 1); assert_eq!(ts.subsec_nanos(), 202);\n\nlet ts = ts.plus_seconds(2); assert_eq!(ts.nanos(), 3_000_000_202); assert_eq!(ts.seconds(), 3); assert_eq!(ts.subsec_nanos(), 202); ```", + "allOf": [ + { + "$ref": "#/definitions/Uint64" + } + ] + }, + "Uint64": { + "description": "A thin wrapper around u64 that is using strings for JSON encoding/decoding, such that the full u64 range can be used for clients that convert JSON numbers to floats, like JavaScript and jq.\n\n# Examples\n\nUse `from` to create instances of this and `u64` to get the value out:\n\n``` # use cosmwasm_std::Uint64; let a = Uint64::from(42u64); assert_eq!(a.u64(), 42);\n\nlet b = Uint64::from(70u32); assert_eq!(b.u64(), 70); ```", + "type": "string" + } + } +} diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 76ea8ac9d7..45eb3bcaf5 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -4,7 +4,7 @@ use crate::epoch_state::storage::{CURRENT_EPOCH, THRESHOLD}; use crate::epoch_state::utils::check_state_completion; use crate::error::ContractError; -use cosmwasm_std::{Env, StdResult, Storage}; +use cosmwasm_std::{Env, Storage}; use nym_coconut_dkg_common::types::{Epoch, EpochState, StateAdvanceResponse}; pub(crate) fn query_can_advance_state( From b764fcc756f874c4e2ed4c249f6eaca742b2e35a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 6 Feb 2024 17:34:34 +0000 Subject: [PATCH 048/394] revamped BandwidthVoucher to allow for different kinds of bandwidth credentials --- Cargo.lock | 2 + .../bandwidth-controller/src/acquire/mod.rs | 41 +- .../bandwidth-controller/src/acquire/state.rs | 15 +- common/bandwidth-controller/src/lib.rs | 57 +- common/bandwidth-controller/src/utils.rs | 41 ++ common/coconut-interface/src/lib.rs | 17 +- .../20240206120000_add_credential_types.sql | 5 + .../src/ephemeral_storage.rs | 8 +- common/credential-storage/src/models.rs | 21 +- .../src/persistent_storage.rs | 8 +- common/credential-storage/src/storage.rs | 9 +- .../credential-utils/src/recovery_storage.rs | 23 +- common/credential-utils/src/utils.rs | 41 +- common/credentials/Cargo.toml | 2 + common/credentials/src/coconut/bandwidth.rs | 428 -------------- .../src/coconut/bandwidth/freepass.rs | 77 +++ .../src/coconut/bandwidth/issuance.rs | 246 ++++++++ .../src/coconut/bandwidth/issued.rs | 140 +++++ .../credentials/src/coconut/bandwidth/mod.rs | 62 ++ .../src/coconut/bandwidth/voucher.rs | 541 ++++++++++++++++++ common/credentials/src/coconut/credential.rs | 10 + common/credentials/src/coconut/mod.rs | 3 +- common/credentials/src/coconut/utils.rs | 86 +-- common/network-defaults/src/lib.rs | 3 +- common/nymcoconut/src/impls/clone.rs | 4 +- common/nymcoconut/src/impls/serde.rs | 5 +- common/nymcoconut/src/lib.rs | 2 +- common/nymcoconut/src/scheme/verification.rs | 31 +- common/nymcoconut/src/tests/helpers.rs | 2 +- nym-api/src/coconut/api_routes/mod.rs | 6 +- nym-api/src/coconut/deposit.rs | 13 +- nym-api/src/coconut/state.rs | 14 +- nym-connect/desktop/Cargo.lock | 2 + .../rewarder/credential_issuance/monitor.rs | 13 +- sdk/rust/nym-sdk/src/bandwidth/client.rs | 4 +- 35 files changed, 1323 insertions(+), 659 deletions(-) create mode 100644 common/bandwidth-controller/src/utils.rs create mode 100644 common/credential-storage/migrations/20240206120000_add_credential_types.sql delete mode 100644 common/credentials/src/coconut/bandwidth.rs create mode 100644 common/credentials/src/coconut/bandwidth/freepass.rs create mode 100644 common/credentials/src/coconut/bandwidth/issuance.rs create mode 100644 common/credentials/src/coconut/bandwidth/issued.rs create mode 100644 common/credentials/src/coconut/bandwidth/mod.rs create mode 100644 common/credentials/src/coconut/bandwidth/voucher.rs create mode 100644 common/credentials/src/coconut/credential.rs diff --git a/Cargo.lock b/Cargo.lock index ac8415dbcf..7d92bcd044 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5383,7 +5383,9 @@ dependencies = [ "nym-crypto", "nym-validator-client", "rand 0.7.3", + "serde", "thiserror", + "time", "zeroize", ] diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 116634cf41..9bf1f371a3 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -4,10 +4,9 @@ use crate::error::BandwidthControllerError; use nym_coconut_interface::Base58; use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::{IssuanceBandwidthCredential, VOUCHER_INFO_TYPE}; use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_crypto::asymmetric::{encryption, identity}; -use nym_network_defaults::VOUCHER_INFO; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nyxd::contract_traits::CoconutBandwidthSigningClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; @@ -24,13 +23,11 @@ where let mut rng = OsRng; let signing_key = identity::PrivateKey::new(&mut rng); let encryption_key = encryption::PrivateKey::new(&mut rng); - let params = BandwidthVoucher::default_parameters(); - let voucher_value = amount.amount.to_string(); let tx_hash = client .deposit( - amount, - String::from(VOUCHER_INFO), + amount.clone(), + VOUCHER_INFO_TYPE.to_string(), signing_key.public_key().to_base58_string(), encryption_key.public_key().to_base58_string(), None, @@ -38,16 +35,10 @@ where .await? .transaction_hash; - let voucher = BandwidthVoucher::new( - ¶ms, - voucher_value, - VOUCHER_INFO.to_string(), - tx_hash, - signing_key, - encryption_key, - ); + let voucher = + IssuanceBandwidthCredential::new_voucher(amount, tx_hash, signing_key, encryption_key); - let state = State { voucher, params }; + let state = State { voucher }; Ok(state) } @@ -62,6 +53,9 @@ where St: Storage, ::StorageError: Send + Sync + 'static, { + // temporary + assert!(!state.voucher.typ().is_free_pass()); + let epoch_id = client.get_current_epoch().await?.epoch_id; let threshold = client .get_current_epoch_threshold() @@ -70,17 +64,16 @@ where let coconut_api_clients = all_coconut_api_clients(client, epoch_id).await?; - let signature = obtain_aggregate_signature( - &state.params, - &state.voucher, - &coconut_api_clients, - threshold, - ) - .await?; + let signature = + obtain_aggregate_signature(&state.voucher, &coconut_api_clients, threshold).await?; + + // we asserted the that the bandwidth credential we obtained is **NOT** the free pass + // so the first public attribute must be the value + let voucher_value = state.voucher.get_plain_public_attributes()[0].clone(); storage .insert_coconut_credential( - state.voucher.get_voucher_value(), - VOUCHER_INFO.to_string(), + voucher_value, + VOUCHER_INFO_TYPE.to_string(), state.voucher.get_private_attributes()[0].to_bs58(), state.voucher.get_private_attributes()[1].to_bs58(), signature.to_bs58(), diff --git a/common/bandwidth-controller/src/acquire/state.rs b/common/bandwidth-controller/src/acquire/state.rs index 7c6cc31c05..68945289b7 100644 --- a/common/bandwidth-controller/src/acquire/state.rs +++ b/common/bandwidth-controller/src/acquire/state.rs @@ -1,19 +1,14 @@ -// Copyright 2022-2023 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::Parameters; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; pub struct State { - pub voucher: BandwidthVoucher, - pub params: Parameters, + pub voucher: IssuanceBandwidthCredential, } impl State { - pub fn new(voucher: BandwidthVoucher) -> Self { - State { - voucher, - params: BandwidthVoucher::default_parameters(), - } + pub fn new(voucher: IssuanceBandwidthCredential) -> Self { + State { voucher } } } diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index b7d61e2935..f114dcab83 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; +use crate::utils::stored_credential_to_issued_bandwidth; use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; use nym_validator_client::coconut::all_coconut_api_clients; @@ -10,13 +11,12 @@ use std::str::FromStr; use zeroize::Zeroizing; use { nym_coconut_interface::Base58, - nym_credentials::coconut::{ - bandwidth::prepare_for_spending, utils::obtain_aggregate_verification_key, - }, + nym_credentials::coconut::utils::obtain_aggregate_verification_key, }; pub mod acquire; pub mod error; +mod utils; pub struct BandwidthController { storage: St, @@ -39,42 +39,37 @@ impl BandwidthController { C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, { - let bandwidth_credential = self + let retrieved_credential = self .storage - .get_next_coconut_credential() + .get_next_unspent_credential() .await .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))?; - let voucher_value = u64::from_str(&bandwidth_credential.voucher_value) - .map_err(|_| StorageError::InconsistentData)?; - let voucher_info = bandwidth_credential.voucher_info.clone(); - let serial_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( - bandwidth_credential.serial_number, - )?); - let binding_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( - bandwidth_credential.binding_number, - )?); - let signature = - nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?; - let epoch_id = u64::from_str(&bandwidth_credential.epoch_id) + + let epoch_id = u64::from_str(&retrieved_credential.epoch_id) .map_err(|_| StorageError::InconsistentData)?; + let issued_bandwidth = stored_credential_to_issued_bandwidth(retrieved_credential)?; + let coconut_api_clients = all_coconut_api_clients(&self.client, epoch_id).await?; - let verification_key = obtain_aggregate_verification_key(&coconut_api_clients).await?; - // the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff) - Ok(( - prepare_for_spending( - voucher_value, - voucher_info, - &serial_number, - &binding_number, - epoch_id, - &signature, - &verification_key, - )?, - bandwidth_credential.id, - )) + let spend_request = issued_bandwidth.prepare_for_spending(&verification_key)?; + + todo!() + + // // the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff) + // Ok(( + // prepare_for_spending( + // voucher_value, + // voucher_info, + // &serial_number, + // &binding_number, + // epoch_id, + // &signature, + // &verification_key, + // )?, + // bandwidth_credential.id, + // )) } pub async fn consume_credential(&self, id: i64) -> Result<(), BandwidthControllerError> diff --git a/common/bandwidth-controller/src/utils.rs b/common/bandwidth-controller/src/utils.rs new file mode 100644 index 0000000000..7f24f8e141 --- /dev/null +++ b/common/bandwidth-controller/src/utils.rs @@ -0,0 +1,41 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::error::BandwidthControllerError; +use nym_credential_storage::models::StoredIssuedCredential; +use nym_credentials::coconut::bandwidth::IssuedBandwidthCredential; +use nym_validator_client::nym_api::EpochId; + +pub fn stored_credential_to_issued_bandwidth( + cred: StoredIssuedCredential, +) -> Result { + /* + let bandwidth_credential = self + .storage + .get_next_coconut_credential() + .await + .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))?; + let voucher_value = u64::from_str(&bandwidth_credential.voucher_value) + .map_err(|_| StorageError::InconsistentData)?; + let voucher_info = bandwidth_credential.voucher_info.clone(); + let serial_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( + bandwidth_credential.serial_number, + )?); + let binding_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( + bandwidth_credential.binding_number, + )?); + let signature = + nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?; + let epoch_id = u64::from_str(&bandwidth_credential.epoch_id) + .map_err(|_| StorageError::InconsistentData)?; + + */ + todo!() +} + +pub fn issued_bandwidth_to_stored_credential( + issued: IssuedBandwidthCredential, + epoch_id: EpochId, +) -> StoredIssuedCredential { + todo!() +} diff --git a/common/coconut-interface/src/lib.rs b/common/coconut-interface/src/lib.rs index 30037e29e0..2a655a2980 100644 --- a/common/coconut-interface/src/lib.rs +++ b/common/coconut-interface/src/lib.rs @@ -1,12 +1,11 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -pub mod error; - +use error::CoconutInterfaceError; use getset::{CopyGetters, Getters}; use serde::{Deserialize, Serialize}; -use error::CoconutInterfaceError; +pub mod error; // We list these explicity instead of glob export due to shadowing warnings with the pub tests // module. @@ -14,7 +13,8 @@ pub use nym_coconut::{ aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, prepare_blind_sign, prove_bandwidth_credential, Attribute, Base58, BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute, - PublicAttribute, SecretKey, Signature, SignatureShare, Theta, VerificationKey, + PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, + VerifyCredentialRequest, }; #[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)] @@ -23,7 +23,7 @@ pub struct Credential { n_params: u32, #[getset(get = "pub")] - theta: Theta, + theta: VerifyCredentialRequest, voucher_value: u64, @@ -32,10 +32,11 @@ pub struct Credential { #[getset(get = "pub")] epoch_id: u64, } + impl Credential { pub fn new( n_params: u32, - theta: Theta, + theta: VerifyCredentialRequest, voucher_value: u64, voucher_info: String, epoch_id: u64, @@ -114,7 +115,7 @@ impl Credential { "To few bytes in credential", ))); } - let theta = Theta::from_bytes(&bytes[12..12 + theta_len as usize]) + let theta = VerifyCredentialRequest::from_bytes(&bytes[12..12 + theta_len as usize]) .map_err(|e| CoconutError::Deserialization(e.to_string()))?; eight_byte.copy_from_slice(&bytes[12 + theta_len as usize..20 + theta_len as usize]); let voucher_value = u64::from_be_bytes(eight_byte); diff --git a/common/credential-storage/migrations/20240206120000_add_credential_types.sql b/common/credential-storage/migrations/20240206120000_add_credential_types.sql new file mode 100644 index 0000000000..a72048344f --- /dev/null +++ b/common/credential-storage/migrations/20240206120000_add_credential_types.sql @@ -0,0 +1,5 @@ +/* + * Copyright 2024 - Nym Technologies SA + * SPDX-License-Identifier: Apache-2.0 + */ + diff --git a/common/credential-storage/src/ephemeral_storage.rs b/common/credential-storage/src/ephemeral_storage.rs index 577a2de8c5..9a4dd561ba 100644 --- a/common/credential-storage/src/ephemeral_storage.rs +++ b/common/credential-storage/src/ephemeral_storage.rs @@ -3,7 +3,7 @@ use crate::backends::memory::CoconutCredentialManager; use crate::error::StorageError; -use crate::models::CoconutCredential; +use crate::models::{CoconutCredential, StoredIssuedCredential}; use crate::storage::Storage; use async_trait::async_trait; @@ -60,6 +60,12 @@ impl Storage for EphemeralStorage { Ok(credential) } + async fn get_next_unspent_credential( + &self, + ) -> Result { + todo!() + } + async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { self.coconut_credential_manager .consume_coconut_credential(id) diff --git a/common/credential-storage/src/models.rs b/common/credential-storage/src/models.rs index 014054f3fa..7a1686b3d5 100644 --- a/common/credential-storage/src/models.rs +++ b/common/credential-storage/src/models.rs @@ -1,6 +1,8 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use sqlx::FromRow; + #[derive(Clone)] pub struct CoconutCredential { #[allow(dead_code)] @@ -13,3 +15,20 @@ pub struct CoconutCredential { pub epoch_id: String, pub consumed: bool, } + +#[derive(FromRow)] +pub struct StoredIssuedCredential { + #[allow(dead_code)] + pub id: i64, + + pub serial_number: String, + pub binding_number: String, + + pub signature: String, + + pub variant_type: String, + pub serialized_variant_data: String, + + pub epoch_id: String, + pub consumed: bool, +} diff --git a/common/credential-storage/src/persistent_storage.rs b/common/credential-storage/src/persistent_storage.rs index f214e40345..4fffc60777 100644 --- a/common/credential-storage/src/persistent_storage.rs +++ b/common/credential-storage/src/persistent_storage.rs @@ -5,7 +5,7 @@ use crate::backends::sqlite::CoconutCredentialManager; use crate::error::StorageError; use crate::storage::Storage; -use crate::models::CoconutCredential; +use crate::models::{CoconutCredential, StoredIssuedCredential}; use async_trait::async_trait; use log::{debug, error}; use sqlx::ConnectOptions; @@ -91,6 +91,12 @@ impl Storage for PersistentStorage { Ok(credential) } + async fn get_next_unspent_credential( + &self, + ) -> Result { + todo!() + } + async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { self.coconut_credential_manager .consume_coconut_credential(id) diff --git a/common/credential-storage/src/storage.rs b/common/credential-storage/src/storage.rs index e4fa9cbcba..af16a4a8de 100644 --- a/common/credential-storage/src/storage.rs +++ b/common/credential-storage/src/storage.rs @@ -1,7 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::models::CoconutCredential; +use crate::models::{CoconutCredential, StoredIssuedCredential}; use async_trait::async_trait; use std::error::Error; @@ -19,6 +19,7 @@ pub trait Storage: Send + Sync { /// * `binding_number`: Binding number of the credential. /// * `signature`: Coconut credential in the form of a signature. /// * `epoch_id`: The epoch when it was signed. + #[deprecated] async fn insert_coconut_credential( &self, voucher_value: String, @@ -30,8 +31,14 @@ pub trait Storage: Send + Sync { ) -> Result<(), Self::StorageError>; /// Tries to retrieve one of the stored, unused credentials. + #[deprecated] async fn get_next_coconut_credential(&self) -> Result; + /// Tries to retrieve one of the stored, unused credentials. + async fn get_next_unspent_credential( + &self, + ) -> Result; + /// Marks as consumed in the database the specified credential. /// /// # Arguments diff --git a/common/credential-utils/src/recovery_storage.rs b/common/credential-utils/src/recovery_storage.rs index 1793553c62..6dc6ec76bd 100644 --- a/common/credential-utils/src/recovery_storage.rs +++ b/common/credential-utils/src/recovery_storage.rs @@ -3,7 +3,7 @@ use crate::errors::Result; use log::error; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; use std::fs::{create_dir_all, read_dir, File}; use std::io::{Read, Write}; use std::path::PathBuf; @@ -18,7 +18,7 @@ impl RecoveryStorage { Ok(Self { recovery_dir }) } - pub fn unconsumed_vouchers(&self) -> Result> { + pub fn unconsumed_vouchers(&self) -> Result> { let entries = read_dir(&self.recovery_dir)?; let mut paths = vec![]; @@ -34,7 +34,7 @@ impl RecoveryStorage { if let Ok(mut file) = File::open(&path) { let mut buff = Vec::new(); if file.read_to_end(&mut buff).is_ok() { - match BandwidthVoucher::try_from_bytes(&buff) { + match IssuanceBandwidthCredential::try_from_bytes(&buff) { Ok(voucher) => vouchers.push(voucher), Err(err) => { error!("failed to parse the voucher at {}: {err}", path.display()) @@ -47,14 +47,15 @@ impl RecoveryStorage { Ok(vouchers) } - pub fn insert_voucher(&self, voucher: &BandwidthVoucher) -> Result { - let file_name = voucher.tx_hash().to_string(); - let file_path = self.recovery_dir.join(file_name); - let mut file = File::create(&file_path)?; - let buff = voucher.to_bytes(); - file.write_all(&buff)?; - - Ok(file_path) + pub fn insert_voucher(&self, voucher: &IssuanceBandwidthCredential) -> Result { + todo!() + // let file_name = voucher.tx_hash().to_string(); + // let file_path = self.recovery_dir.join(file_name); + // let mut file = File::create(&file_path)?; + // let buff = voucher.to_bytes(); + // file.write_all(&buff)?; + // + // Ok(file_path) } pub fn remove_voucher(&self, file_name: String) -> Result<()> { diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index e1e7c09850..7668b5f1b7 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -126,24 +126,25 @@ pub async fn recover_credentials( where C: DkgQueryClient + Send + Sync, { - let mut recovered_amount: u128 = 0; - for voucher in recovery_storage.unconsumed_vouchers()? { - let voucher_value = voucher.get_voucher_value(); - recovered_amount += voucher_value.parse::()?; - - let state = State::new(voucher); - let voucher = state.voucher.tx_hash(); - if let Err(e) = - nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await - { - error!("Could not recover deposit {voucher} due to {e}, try again later",) - } else { - info!("Converted deposit {voucher} to a credential, removing recovery data for it",); - if let Err(e) = recovery_storage.remove_voucher(voucher.to_string()) { - warn!("Could not remove recovery data: {e}"); - } - } - } - - Ok(recovered_amount) + todo!() + // let mut recovered_amount: u128 = 0; + // for voucher in recovery_storage.unconsumed_vouchers()? { + // let voucher_value = voucher.get_voucher_value(); + // recovered_amount += voucher_value.parse::()?; + // + // let state = State::new(voucher); + // let voucher = state.voucher.tx_hash(); + // if let Err(e) = + // nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await + // { + // error!("Could not recover deposit {voucher} due to {e}, try again later",) + // } else { + // info!("Converted deposit {voucher} to a credential, removing recovery data for it",); + // if let Err(e) = recovery_storage.remove_voucher(voucher.to_string()) { + // warn!("Could not remove recovery data: {e}"); + // } + // } + // } + // + // Ok(recovered_amount) } diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 8e96ce7b30..9c42f08418 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -11,6 +11,7 @@ bls12_381 = { workspace = true, default-features = false, features = ["pairings" cosmrs = { workspace = true } thiserror = { workspace = true } log = { workspace = true } +time = { workspace = true, features = ["serde"] } zeroize = { workspace = true } # I guess temporarily until we get serde support in coconut up and running @@ -18,6 +19,7 @@ nym-coconut-interface = { path = "../coconut-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } +serde = { version = "1.0.189", features = ["derive"] } [dev-dependencies] rand = "0.7.3" diff --git a/common/credentials/src/coconut/bandwidth.rs b/common/credentials/src/coconut/bandwidth.rs deleted file mode 100644 index 9646860a74..0000000000 --- a/common/credentials/src/coconut/bandwidth.rs +++ /dev/null @@ -1,428 +0,0 @@ -// Copyright 2021 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -// for time being assume the bandwidth credential consists of public identity of the requester -// and private (though known... just go along with it) infinite bandwidth value -// right now this has no double-spending protection, spender binding, etc -// it's the simplest possible case - -use cosmrs::tendermint::hash::Algorithm; -use cosmrs::tendermint::Hash; -use nym_coconut_interface::{ - hash_to_scalar, prepare_blind_sign, Attribute, BlindSignRequest, Credential, Parameters, - PrivateAttribute, PublicAttribute, Signature, VerificationKey, -}; -use nym_crypto::asymmetric::{encryption, identity}; -use zeroize::{Zeroize, ZeroizeOnDrop}; - -use super::utils::prepare_credential_for_spending; -use crate::error::Error; - -#[derive(Zeroize, ZeroizeOnDrop)] -pub struct BandwidthVoucher { - // private attributes - /// a random secret value generated by the client used for double-spending detection - serial_number: PrivateAttribute, - - /// a random secret value generated by the client used to bind multiple credentials together - binding_number: PrivateAttribute, - - // public atttributes: - /// the plain text value (e.g., bandwidth) encoded in this voucher - // TODO: in another PR change the value from `"1000"` to `"1000unym"` - voucher_value_plain: String, - - /// the plain text information - voucher_info_plain: String, - - /// the precomputed value (e.g., bandwidth) encoded in this voucher - _voucher_value_prehashed: PublicAttribute, - - /// the precomputed field with public information, e.g., type of voucher, interval etc. - _voucher_info_prehashed: PublicAttribute, - - /// the hash of the deposit transaction - #[zeroize(skip)] - tx_hash: Hash, - - /// base58 encoded private key ensuring the depositer requested these attributes - signing_key: identity::PrivateKey, - - /// base58 encoded private key ensuring only this client receives the signature share - unused_ed25519: encryption::PrivateKey, - - pedersen_commitments_openings: Vec, - - #[zeroize(skip)] - blind_sign_request: BlindSignRequest, -} - -impl BandwidthVoucher { - pub const PUBLIC_ATTRIBUTES: u32 = 2; - pub const PRIVATE_ATTRIBUTES: u32 = 2; - pub const ENCODED_ATTRIBUTES: u32 = 4; - - pub fn default_parameters() -> Parameters { - // safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero - Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap() - } - - pub fn new( - params: &Parameters, - voucher_value: String, - voucher_info: String, - tx_hash: Hash, - signing_key: identity::PrivateKey, - encryption_key: encryption::PrivateKey, - ) -> Self { - let serial_number = params.random_scalar(); - let binding_number = params.random_scalar(); - let voucher_value_plain = voucher_value.clone(); - let voucher_info_plain = voucher_info.clone(); - - let _voucher_value_prehashed = hash_to_scalar(voucher_value); - let _voucher_info_prehashed = hash_to_scalar(voucher_info); - - let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign( - params, - &[&serial_number, &binding_number], - &[&_voucher_value_prehashed, &_voucher_info_prehashed], - ) - .unwrap(); - BandwidthVoucher { - serial_number, - binding_number, - _voucher_value_prehashed, - voucher_value_plain, - _voucher_info_prehashed, - voucher_info_plain, - tx_hash, - signing_key, - unused_ed25519: encryption_key, - pedersen_commitments_openings, - blind_sign_request, - } - } - - pub fn to_bytes(&self) -> Vec { - let serial_number_b = self.serial_number.to_bytes(); - let binding_number_b = self.binding_number.to_bytes(); - let voucher_value_plain_b = self.voucher_value_plain.as_bytes(); - let voucher_info_plain_b = self.voucher_info_plain.as_bytes(); - let tx_hash_b = self.tx_hash.as_bytes(); - let signing_key_b = self.signing_key.to_bytes(); - let encryption_key_b = self.unused_ed25519.to_bytes(); - let blind_sign_request_b = self.blind_sign_request.to_bytes(); - - let mut ret = Vec::new(); - - ret.extend_from_slice(&serial_number_b); - ret.extend_from_slice(&binding_number_b); - ret.extend_from_slice(tx_hash_b); - ret.extend_from_slice(&signing_key_b); - ret.extend_from_slice(&encryption_key_b); - ret.extend_from_slice(&(voucher_value_plain_b.len() as u64).to_be_bytes()); - ret.extend_from_slice(&(voucher_info_plain_b.len() as u64).to_be_bytes()); - ret.extend_from_slice(&(blind_sign_request_b.len() as u64).to_be_bytes()); - ret.extend_from_slice(&(self.pedersen_commitments_openings.len() as u64).to_be_bytes()); - ret.extend_from_slice(voucher_value_plain_b); - ret.extend_from_slice(voucher_info_plain_b); - ret.extend_from_slice(&blind_sign_request_b); - for commitment in self.pedersen_commitments_openings.iter() { - ret.extend_from_slice(&commitment.to_bytes()); - } - - ret - } - - pub fn try_from_bytes(bytes: &[u8]) -> Result { - if bytes.len() < 32 * 5 + 4 * 8 { - return Err(Error::BandwidthVoucherDeserializationError(format!( - "Less then {} bytes needed", - 32 * 5 + 4 * 8 - ))); - } - let mut buff = [0u8; 32]; - let mut small_buff = [0u8; 8]; - let scalar_err = - || Error::BandwidthVoucherDeserializationError(String::from("Invalid Scalar")); - buff.copy_from_slice(&bytes[..32]); - let serial_number = Option::::from(PrivateAttribute::from_bytes(&buff)) - .ok_or_else(scalar_err)?; - buff.copy_from_slice(&bytes[32..2 * 32]); - let binding_number = Option::::from(PrivateAttribute::from_bytes(&buff)) - .ok_or_else(scalar_err)?; - buff.copy_from_slice(&bytes[2 * 32..3 * 32]); - let tx_hash = Hash::from_bytes(Algorithm::Sha256, &buff).map_err(|_| { - Error::BandwidthVoucherDeserializationError(String::from("Invalid transaction Hash")) - })?; - buff.copy_from_slice(&bytes[3 * 32..4 * 32]); - let signing_key = identity::PrivateKey::from_bytes(&buff).map_err(|_| { - Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) - })?; - buff.copy_from_slice(&bytes[4 * 32..5 * 32]); - let encryption_key = encryption::PrivateKey::from_bytes(&buff).map_err(|_| { - Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) - })?; - small_buff.copy_from_slice(&bytes[5 * 32..5 * 32 + 8]); - let voucher_value_plain_no = u64::from_be_bytes(small_buff) as usize; - small_buff.copy_from_slice(&bytes[5 * 32 + 8..5 * 32 + 2 * 8]); - let voucher_info_plain_no = u64::from_be_bytes(small_buff) as usize; - small_buff.copy_from_slice(&bytes[5 * 32 + 2 * 8..5 * 32 + 3 * 8]); - let blind_sign_request_no = u64::from_be_bytes(small_buff) as usize; - small_buff.copy_from_slice(&bytes[5 * 32 + 3 * 8..5 * 32 + 4 * 8]); - let pedersen_commitments_openings_no = u64::from_be_bytes(small_buff) as usize; - - let total_length = 32 * 5 - + 4 * 8 - + voucher_value_plain_no - + voucher_info_plain_no - + blind_sign_request_no - + pedersen_commitments_openings_no * 32; - if bytes.len() != total_length { - return Err(Error::BandwidthVoucherDeserializationError(format!( - "Expected {total_length} bytes", - ))); - } - - let utf_err = |_| { - Err(Error::BandwidthVoucherDeserializationError(String::from( - "Invalid UTF8 string", - ))) - }; - let mut var_length_pointer = 5 * 32 + 4 * 8; - let voucher_value_plain = String::from_utf8( - bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(), - ) - .or_else(utf_err)?; - let _voucher_value_prehashed = hash_to_scalar(&voucher_value_plain); - var_length_pointer += voucher_value_plain_no; - let voucher_info_plain = String::from_utf8( - bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(), - ) - .or_else(utf_err)?; - let _voucher_info_prehashed = hash_to_scalar(&voucher_info_plain); - var_length_pointer += voucher_info_plain_no; - let blind_sign_request = BlindSignRequest::from_bytes( - &bytes[var_length_pointer..var_length_pointer + blind_sign_request_no], - )?; - var_length_pointer += blind_sign_request_no; - - let mut pedersen_commitments_openings = Vec::new(); - for _ in 0..pedersen_commitments_openings_no { - buff.copy_from_slice(&bytes[var_length_pointer..var_length_pointer + 32]); - let commitment = - Option::::from(Attribute::from_bytes(&buff)).ok_or_else(scalar_err)?; - var_length_pointer += 32; - pedersen_commitments_openings.push(commitment); - } - - Ok(Self { - serial_number, - binding_number, - _voucher_value_prehashed, - voucher_value_plain, - _voucher_info_prehashed, - voucher_info_plain, - tx_hash, - signing_key, - unused_ed25519: encryption_key, - pedersen_commitments_openings, - blind_sign_request, - }) - } - - /// Check if the plain values correspond to the PublicAttributes - pub fn verify_against_plain(values: &[&PublicAttribute], plain_values: &[String]) -> bool { - values.len() == 2 - && plain_values.len() == 2 - && values[0] == &hash_to_scalar(&plain_values[0]) - && values[1] == &hash_to_scalar(&plain_values[1]) - } - - pub fn tx_hash(&self) -> Hash { - self.tx_hash - } - - pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> { - vec![ - &self._voucher_value_prehashed, - &self._voucher_info_prehashed, - ] - } - - pub fn identity_key(&self) -> &identity::PrivateKey { - &self.signing_key - } - - pub fn encryption_key(&self) -> &encryption::PrivateKey { - &self.unused_ed25519 - } - - pub fn pedersen_commitments_openings(&self) -> &Vec { - &self.pedersen_commitments_openings - } - - pub fn blind_sign_request(&self) -> &BlindSignRequest { - &self.blind_sign_request - } - - pub fn get_voucher_value(&self) -> String { - self.voucher_value_plain.clone() - } - - pub fn get_public_attributes_plain(&self) -> Vec { - vec![ - self.voucher_value_plain.clone(), - self.voucher_info_plain.clone(), - ] - } - - pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> { - vec![&self.serial_number, &self.binding_number] - } - - pub fn signable_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec { - let mut message = request.to_bytes(); - message.extend_from_slice(tx_hash.as_bytes()); - message - } - - pub fn sign(&self) -> identity::Signature { - let message = Self::signable_plaintext(&self.blind_sign_request, self.tx_hash); - self.signing_key.sign(message) - } -} - -pub fn prepare_for_spending( - voucher_value: u64, - voucher_info: String, - serial_number: &PrivateAttribute, - binding_number: &PrivateAttribute, - epoch_id: u64, - signature: &Signature, - verification_key: &VerificationKey, -) -> Result { - let params = Parameters::new(BandwidthVoucher::ENCODED_ATTRIBUTES)?; - - prepare_credential_for_spending( - ¶ms, - voucher_value, - voucher_info, - serial_number, - binding_number, - epoch_id, - signature, - verification_key, - ) -} - -#[cfg(test)] -mod test { - use super::*; - use cosmrs::tendermint::hash::Algorithm; - use nym_coconut_interface::Base58; - use rand::rngs::OsRng; - - fn voucher_fixture() -> BandwidthVoucher { - let params = Parameters::new(4).unwrap(); - let mut rng = OsRng; - BandwidthVoucher::new( - ¶ms, - "1234".to_string(), - "voucher info".to_string(), - Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), - identity::PrivateKey::from_base58_string( - identity::KeyPair::new(&mut rng) - .private_key() - .to_base58_string(), - ) - .unwrap(), - encryption::PrivateKey::from_bytes( - &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), - ) - .unwrap(), - ) - } - - #[test] - fn serde_voucher() { - let voucher = voucher_fixture(); - let bytes = voucher.to_bytes(); - let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap(); - assert_eq!(voucher.serial_number, deserialized_voucher.serial_number); - assert_eq!(voucher.binding_number, deserialized_voucher.binding_number); - assert_eq!( - voucher.voucher_value_plain, - deserialized_voucher.voucher_value_plain - ); - assert_eq!( - voucher.voucher_info_plain, - deserialized_voucher.voucher_info_plain - ); - assert_eq!( - voucher._voucher_value_prehashed, - deserialized_voucher._voucher_value_prehashed - ); - assert_eq!( - voucher._voucher_info_prehashed, - deserialized_voucher._voucher_info_prehashed - ); - assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash); - assert_eq!( - voucher.signing_key.to_string(), - deserialized_voucher.signing_key.to_string() - ); - assert_eq!( - voucher.unused_ed25519.to_string(), - deserialized_voucher.unused_ed25519.to_string() - ); - assert_eq!( - voucher.pedersen_commitments_openings, - deserialized_voucher.pedersen_commitments_openings - ); - assert_eq!( - voucher.blind_sign_request.to_bs58(), - deserialized_voucher.blind_sign_request.to_bs58() - ); - } - - #[test] - fn voucher_consistency() { - let voucher = voucher_fixture(); - assert!(!BandwidthVoucher::verify_against_plain( - &[], - &voucher.get_public_attributes_plain() - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[], - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[ - voucher.get_public_attributes_plain()[0].clone(), - String::new() - ] - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[ - String::new(), - voucher.get_public_attributes_plain()[1].clone() - ] - )); - assert!(!BandwidthVoucher::verify_against_plain( - &[voucher.get_public_attributes()[0], &Attribute::one()], - &voucher.get_public_attributes_plain() - )); - assert!(!BandwidthVoucher::verify_against_plain( - &[&Attribute::one(), voucher.get_public_attributes()[1]], - &voucher.get_public_attributes_plain() - )); - assert!(BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &voucher.get_public_attributes_plain() - )); - } -} diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs new file mode 100644 index 0000000000..d0e17ba55b --- /dev/null +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -0,0 +1,77 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use nym_coconut_interface::{hash_to_scalar, Attribute, PublicAttribute}; +use serde::{Deserialize, Serialize}; +use time::{Duration, OffsetDateTime, Time}; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +pub const MAX_FREE_PASS_VALIDITY: Duration = Duration::WEEK; // 1 week + +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +pub struct FreePassIssuedData { + /// the plain validity value of this credential expressed as unix timestamp + #[zeroize(skip)] + expiry_date: OffsetDateTime, +} + +impl<'a> From<&'a FreePassIssuanceData> for FreePassIssuedData { + fn from(value: &'a FreePassIssuanceData) -> Self { + FreePassIssuedData { + expiry_date: value.expiry_date, + } + } +} + +impl FreePassIssuedData { + pub fn expiry_date_plain(&self) -> String { + self.expiry_date.unix_timestamp().to_string() + } +} + +#[derive(Zeroize, ZeroizeOnDrop)] +pub struct FreePassIssuanceData { + /// the plain validity value of this credential expressed as unix timestamp + #[zeroize(skip)] + expiry_date: OffsetDateTime, + + // the expiry date, as unix timestamp, hashed into a scalar + expiry_date_prehashed: PublicAttribute, +} + +impl FreePassIssuanceData { + pub fn new(expiry_date: Option) -> Self { + // ideally we should have implemented a proper error handling here, sure. + // but given it's meant to only be used by nym, imo it's fine to just panic here in case of invalid arguments + let expiry_date = if let Some(provided) = expiry_date { + if provided - OffsetDateTime::now_utc() > MAX_FREE_PASS_VALIDITY { + panic!("the provided expiry date is bigger than the maximum value of {MAX_FREE_PASS_VALIDITY}"); + } + + provided + } else { + Self::default_expiry_date() + }; + + let expiry_date_prehashed = hash_to_scalar(expiry_date.unix_timestamp().to_string()); + + FreePassIssuanceData { + expiry_date, + expiry_date_prehashed, + } + } + + pub fn default_expiry_date() -> OffsetDateTime { + // set it to furthest midnight in the future such as it's no more than a week away, + // i.e. if it's currently for example 9:43 on 2nd March 2024, it will set it to 0:00 on 9th March 2024 + (OffsetDateTime::now_utc() + MAX_FREE_PASS_VALIDITY).replace_time(Time::MIDNIGHT) + } + + pub fn expiry_date_attribute(&self) -> &Attribute { + &self.expiry_date_prehashed + } + + pub fn expiry_date_plain(&self) -> String { + self.expiry_date.unix_timestamp().to_string() + } +} diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs new file mode 100644 index 0000000000..ba694d37f8 --- /dev/null +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -0,0 +1,246 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::coconut::bandwidth::freepass::FreePassIssuanceData; +use crate::coconut::bandwidth::issued::IssuedBandwidthCredential; +use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; +use crate::coconut::bandwidth::{ + bandwidth_voucher_params, CredentialSigningData, CredentialSpendingData, CredentialType, +}; +use crate::error::Error; +use nym_coconut_interface::{ + aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, prove_bandwidth_credential, + Attribute, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, + VerificationKey, +}; +use nym_crypto::asymmetric::{encryption, identity}; +use nym_validator_client::nyxd::{Coin, Hash}; +use time::OffsetDateTime; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Zeroize, ZeroizeOnDrop)] +pub enum BandwidthCredentialIssuanceDataVariant { + Voucher(BandwidthVoucherIssuanceData), + FreePass(FreePassIssuanceData), +} + +impl From for BandwidthCredentialIssuanceDataVariant { + fn from(value: FreePassIssuanceData) -> Self { + BandwidthCredentialIssuanceDataVariant::FreePass(value) + } +} + +impl From for BandwidthCredentialIssuanceDataVariant { + fn from(value: BandwidthVoucherIssuanceData) -> Self { + BandwidthCredentialIssuanceDataVariant::Voucher(value) + } +} + +impl BandwidthCredentialIssuanceDataVariant { + pub fn info(&self) -> CredentialType { + match self { + BandwidthCredentialIssuanceDataVariant::Voucher(..) => CredentialType::Voucher, + BandwidthCredentialIssuanceDataVariant::FreePass(..) => CredentialType::FreePass, + } + } + + // currently this works under the assumption of there being a single unique public attribute for given variant + pub fn public_value(&self) -> &Attribute { + match self { + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => voucher.value_attribute(), + BandwidthCredentialIssuanceDataVariant::FreePass(freepass) => { + freepass.expiry_date_attribute() + } + } + } + + // currently this works under the assumption of there being a single unique public attribute for given variant + pub fn public_value_plain(&self) -> String { + match self { + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => voucher.value_plain(), + BandwidthCredentialIssuanceDataVariant::FreePass(freepass) => { + freepass.expiry_date_plain() + } + } + } +} + +// all types of bandwidth credentials contain serial number and binding number +#[derive(Zeroize, ZeroizeOnDrop)] +pub struct IssuanceBandwidthCredential { + // private attributes + /// a random secret value generated by the client used for double-spending detection + serial_number: PrivateAttribute, + + /// a random secret value generated by the client used to bind multiple credentials together + binding_number: PrivateAttribute, + + /// data specific to given bandwidth credential, for example a value for bandwidth voucher and expiry date for the free pass + variant_data: BandwidthCredentialIssuanceDataVariant, + + /// type of the bandwdith credential hashed onto a scalar + type_prehashed: PublicAttribute, +} + +impl IssuanceBandwidthCredential { + pub const PUBLIC_ATTRIBUTES: u32 = 2; + pub const PRIVATE_ATTRIBUTES: u32 = 2; + pub const ENCODED_ATTRIBUTES: u32 = Self::PUBLIC_ATTRIBUTES + Self::PRIVATE_ATTRIBUTES; + + // just keep this value on hand for any possible future changes so that we could preserve backwards compatibility + pub const ENCODING_VERSION: u8 = 1; + + pub fn default_parameters() -> Parameters { + // safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero + Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap() + } + + pub fn new>(variant_data: B) -> Self { + let variant_data = variant_data.into(); + let type_prehashed = hash_to_scalar(variant_data.info().to_string()); + + let params = bandwidth_voucher_params(); + let serial_number = params.random_scalar(); + let binding_number = params.random_scalar(); + + IssuanceBandwidthCredential { + serial_number, + binding_number, + variant_data, + type_prehashed, + } + } + + pub fn new_voucher( + value: Coin, + deposit_tx_hash: Hash, + signing_key: identity::PrivateKey, + unused_ed25519: encryption::PrivateKey, + ) -> Self { + Self::new(BandwidthVoucherIssuanceData::new( + value, + deposit_tx_hash, + signing_key, + unused_ed25519, + )) + } + + pub fn new_freepass(expiry_date: Option) -> Self { + Self::new(FreePassIssuanceData::new(expiry_date)) + } + + pub fn typ(&self) -> CredentialType { + self.variant_data.info() + } + + pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> { + vec![&self.serial_number, &self.binding_number] + } + + pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> { + vec![self.variant_data.public_value(), &self.type_prehashed] + } + + pub fn get_plain_public_attributes(&self) -> Vec { + vec![ + self.variant_data.public_value_plain(), + self.typ().to_string(), + ] + } + + pub fn prepare_for_signing(&self) -> CredentialSigningData { + let params = bandwidth_voucher_params(); + + // safety: the creation of the request can only fail if one provided invalid parameters + // and we created then specific to this type of the credential so the unwrap is fine + let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign( + params, + &[&self.serial_number, &self.binding_number], + &self.get_public_attributes(), + ) + .unwrap(); + + CredentialSigningData { + pedersen_commitments_openings, + blind_sign_request, + public_attributes_plain: self.get_plain_public_attributes(), + } + } + + pub async fn obtain_partial_credential( + &self, + client: &nym_validator_client::client::NymApiClient, + validator_vk: &VerificationKey, + signing_data: impl Into>, + ) -> Result { + // if we provided signing data, do use them, otherwise generate fresh data + let signing_data = signing_data + .into() + .unwrap_or_else(|| self.prepare_for_signing()); + + let blinded_signature = match &self.variant_data { + BandwidthCredentialIssuanceDataVariant::FreePass(_freepass) => unimplemented!(), + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => { + // TODO: the request can be re-used between different apis + let request = voucher.create_blind_sign_request_body(&signing_data); + voucher.obtain_blinded_credential(client, &request).await? + } + }; + + let public_attributes = self.get_public_attributes(); + let private_attributes = self.get_private_attributes(); + + let params = bandwidth_voucher_params(); + let unblinded_signature = blinded_signature.unblind_and_verify( + params, + validator_vk, + &private_attributes, + &public_attributes, + &signing_data.blind_sign_request.get_commitment_hash(), + &signing_data.pedersen_commitments_openings, + )?; + + Ok(unblinded_signature) + } + + pub fn aggregate_signature_shares( + &self, + verification_key: &VerificationKey, + shares: &[SignatureShare], + ) -> Result { + let public_attributes = self.get_public_attributes(); + let private_attributes = self.get_private_attributes(); + + let params = bandwidth_voucher_params(); + + let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len()); + attributes.extend_from_slice(&private_attributes); + attributes.extend_from_slice(&public_attributes); + + aggregate_signature_shares(params, verification_key, &attributes, shares) + .map_err(Error::SignatureAggregationError) + } + + pub fn into_issued_credential( + self, + aggregate_signature: Signature, + ) -> IssuedBandwidthCredential { + IssuedBandwidthCredential::new( + self.serial_number, + self.binding_number, + aggregate_signature, + (&self.variant_data).into(), + self.type_prehashed, + ) + } + + // TODO: is that actually needed? + pub fn to_bytes(&self) -> Vec { + todo!() + } + + // TODO: is that actually needed? + pub fn try_from_bytes(bytes: &[u8]) -> Result { + todo!() + } +} diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs new file mode 100644 index 0000000000..2c541d2701 --- /dev/null +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -0,0 +1,140 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::coconut::bandwidth::freepass::FreePassIssuedData; +use crate::coconut::bandwidth::issuance::{ + BandwidthCredentialIssuanceDataVariant, IssuanceBandwidthCredential, +}; +use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuedData; +use crate::coconut::bandwidth::{bandwidth_voucher_params, CredentialSpendingData, CredentialType}; +use crate::error::Error; +use nym_coconut_interface::{ + prove_bandwidth_credential, Attribute, Parameters, PrivateAttribute, PublicAttribute, + Signature, VerificationKey, +}; +use serde::{Deserialize, Serialize}; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +pub enum BandwidthCredentialIssuedDataVariant { + Voucher(BandwidthVoucherIssuedData), + FreePass(FreePassIssuedData), +} + +impl<'a> From<&'a BandwidthCredentialIssuanceDataVariant> for BandwidthCredentialIssuedDataVariant { + fn from(value: &'a BandwidthCredentialIssuanceDataVariant) -> Self { + match value { + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => { + BandwidthCredentialIssuedDataVariant::Voucher(voucher.into()) + } + BandwidthCredentialIssuanceDataVariant::FreePass(freepass) => { + BandwidthCredentialIssuedDataVariant::FreePass(freepass.into()) + } + } + } +} + +impl From for BandwidthCredentialIssuedDataVariant { + fn from(value: FreePassIssuedData) -> Self { + BandwidthCredentialIssuedDataVariant::FreePass(value) + } +} + +impl From for BandwidthCredentialIssuedDataVariant { + fn from(value: BandwidthVoucherIssuedData) -> Self { + BandwidthCredentialIssuedDataVariant::Voucher(value) + } +} + +impl BandwidthCredentialIssuedDataVariant { + pub fn info(&self) -> CredentialType { + match self { + BandwidthCredentialIssuedDataVariant::Voucher(..) => CredentialType::Voucher, + BandwidthCredentialIssuedDataVariant::FreePass(..) => CredentialType::FreePass, + } + } + + // currently this works under the assumption of there being a single unique public attribute for given variant + pub fn public_value_plain(&self) -> String { + match self { + BandwidthCredentialIssuedDataVariant::Voucher(voucher) => voucher.value_plain(), + BandwidthCredentialIssuedDataVariant::FreePass(freepass) => { + freepass.expiry_date_plain() + } + } + } +} + +// the only important thing to zeroize here are the private attributes, the rest can be made fully public for what we're concerned +#[derive(Zeroize, ZeroizeOnDrop)] +pub struct IssuedBandwidthCredential { + // private attributes + /// a random secret value generated by the client used for double-spending detection + serial_number: PrivateAttribute, + + /// a random secret value generated by the client used to bind multiple credentials together + binding_number: PrivateAttribute, + + /// the underlying aggregated signature on the attributes + #[zeroize(skip)] + signature: Signature, + + /// data specific to given bandwidth credential, for example a value for bandwidth voucher and expiry date for the free pass + variant_data: BandwidthCredentialIssuedDataVariant, + + /// type of the bandwdith credential hashed onto a scalar + type_prehashed: PublicAttribute, +} + +impl IssuedBandwidthCredential { + pub fn new( + serial_number: PrivateAttribute, + binding_number: PrivateAttribute, + signature: Signature, + variant_data: BandwidthCredentialIssuedDataVariant, + type_prehashed: PublicAttribute, + ) -> Self { + IssuedBandwidthCredential { + serial_number, + binding_number, + signature, + variant_data, + type_prehashed, + } + } + + pub fn default_parameters() -> Parameters { + IssuanceBandwidthCredential::default_parameters() + } + + pub fn typ(&self) -> CredentialType { + self.variant_data.info() + } + + pub fn get_plain_public_attributes(&self) -> Vec { + vec![ + self.variant_data.public_value_plain(), + self.typ().to_string(), + ] + } + + pub fn prepare_for_spending( + &self, + verification_key: &VerificationKey, + ) -> Result { + let params = bandwidth_voucher_params(); + + let verify_credential_request = prove_bandwidth_credential( + params, + verification_key, + &self.signature, + &self.serial_number, + &self.binding_number, + )?; + + Ok(CredentialSpendingData { + verify_credential_request, + public_attributes_plain: self.get_plain_public_attributes(), + }) + } +} diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs new file mode 100644 index 0000000000..84101bc9cc --- /dev/null +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -0,0 +1,62 @@ +// Copyright 2021-2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use bls12_381::Scalar; +use nym_coconut_interface::{BlindSignRequest, Parameters, VerifyCredentialRequest}; +use std::fmt::{Display, Formatter}; +use std::sync::OnceLock; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +pub use issuance::IssuanceBandwidthCredential; +pub use issued::IssuedBandwidthCredential; + +pub mod freepass; +pub mod issuance; +pub mod issued; +pub mod voucher; + +pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; +pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; + +// works under the assumption of having 4 attributes in the underlying credential(s) +pub fn bandwidth_voucher_params() -> &'static Parameters { + static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); + BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters) +} + +#[derive(Zeroize, ZeroizeOnDrop, Clone, Debug)] +pub enum CredentialType { + Voucher, + FreePass, +} + +impl CredentialType { + pub fn is_free_pass(&self) -> bool { + matches!(self, CredentialType::FreePass) + } +} + +impl Display for CredentialType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CredentialType::Voucher => VOUCHER_INFO_TYPE.fmt(f), + CredentialType::FreePass => FREE_PASS_INFO_TYPE.fmt(f), + } + } +} + +#[derive(Debug, Clone)] +pub struct CredentialSigningData { + pub(crate) pedersen_commitments_openings: Vec, + + pub(crate) blind_sign_request: BlindSignRequest, + + pub(crate) public_attributes_plain: Vec, +} + +#[derive(Debug)] +pub struct CredentialSpendingData { + pub(crate) verify_credential_request: VerifyCredentialRequest, + + pub(crate) public_attributes_plain: Vec, +} diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs new file mode 100644 index 0000000000..cce7726b60 --- /dev/null +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -0,0 +1,541 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::coconut::bandwidth::CredentialSigningData; +use crate::error::Error; +use nym_api_requests::coconut::BlindSignRequestBody; +use nym_coconut_interface::{ + hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, PublicAttribute, +}; +use nym_crypto::asymmetric::{encryption, identity}; +use nym_validator_client::nyxd::{Coin, Hash}; +use serde::{Deserialize, Serialize}; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +pub struct BandwidthVoucherIssuedData { + /// the plain value (e.g., bandwidth) encoded in this voucher + // note: for legacy reasons we're only using the value of the coin and ignoring the denom + #[zeroize(skip)] + value: Coin, +} + +impl<'a> From<&'a BandwidthVoucherIssuanceData> for BandwidthVoucherIssuedData { + fn from(value: &'a BandwidthVoucherIssuanceData) -> Self { + BandwidthVoucherIssuedData { + value: value.value.clone(), + } + } +} + +impl BandwidthVoucherIssuedData { + pub fn value_plain(&self) -> String { + self.value.amount.to_string() + } +} + +#[derive(Zeroize, ZeroizeOnDrop)] +pub struct BandwidthVoucherIssuanceData { + /// the plain value (e.g., bandwidth) encoded in this voucher + // note: for legacy reasons we're only using the value of the coin and ignoring the denom + #[zeroize(skip)] + value: Coin, + + // note: as mentioned above, we're only hashing the value of the coin! + value_prehashed: PublicAttribute, + + /// the hash of the deposit transaction + #[zeroize(skip)] + deposit_tx_hash: Hash, + + /// base58 encoded private key ensuring the depositer requested these attributes + signing_key: identity::PrivateKey, + + /// base58 encoded private key ensuring only this client receives the signature share + unused_ed25519: encryption::PrivateKey, +} + +impl BandwidthVoucherIssuanceData { + pub fn new( + value: Coin, + deposit_tx_hash: Hash, + signing_key: identity::PrivateKey, + unused_ed25519: encryption::PrivateKey, + ) -> Self { + let value_prehashed = hash_to_scalar(value.amount.to_string()); + + BandwidthVoucherIssuanceData { + value, + value_prehashed, + deposit_tx_hash, + signing_key, + unused_ed25519, + } + } + + pub fn request_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec { + let mut message = request.to_bytes(); + message.extend_from_slice(tx_hash.as_bytes()); + message + } + + fn request_signature(&self, signing_request: &CredentialSigningData) -> identity::Signature { + let message = + Self::request_plaintext(&signing_request.blind_sign_request, self.deposit_tx_hash); + self.signing_key.sign(message) + } + + pub fn create_blind_sign_request_body( + &self, + signing_request: &CredentialSigningData, + ) -> BlindSignRequestBody { + let request_signature = self.request_signature(signing_request); + + BlindSignRequestBody::new( + signing_request.blind_sign_request.clone(), + self.deposit_tx_hash, + request_signature, + signing_request.public_attributes_plain.clone(), + ) + } + + pub async fn obtain_blinded_credential( + &self, + client: &nym_validator_client::client::NymApiClient, + request_body: &BlindSignRequestBody, + ) -> Result { + let server_response = client.blind_sign(request_body).await?; + Ok(server_response.blinded_signature) + } + + pub fn value_plain(&self) -> String { + self.value.amount.to_string() + } + + pub fn value_attribute(&self) -> &Attribute { + &self.value_prehashed + } + + pub fn tx_hash(&self) -> Hash { + self.deposit_tx_hash + } + + pub fn identity_key(&self) -> &identity::PrivateKey { + &self.signing_key + } + + pub fn encryption_key(&self) -> &encryption::PrivateKey { + &self.unused_ed25519 + } +} +// +// #[deprecated] +// #[derive(Zeroize, ZeroizeOnDrop)] +// pub struct BandwidthVoucher { +// // private attributes +// /// a random secret value generated by the client used for double-spending detection +// serial_number: PrivateAttribute, +// +// /// a random secret value generated by the client used to bind multiple credentials together +// binding_number: PrivateAttribute, +// +// // public atttributes: +// /// the plain text value (e.g., bandwidth) encoded in this voucher +// // TODO: in another PR change the value from `"1000"` to `"1000unym"` +// voucher_value_plain: String, +// +// /// the plain text information +// voucher_info_plain: String, +// +// /// the precomputed value (e.g., bandwidth) encoded in this voucher +// _voucher_value_prehashed: PublicAttribute, +// +// /// the precomputed field with public information, e.g., type of voucher, interval etc. +// _voucher_info_prehashed: PublicAttribute, +// +// /// the hash of the deposit transaction +// #[zeroize(skip)] +// tx_hash: Hash, +// +// /// base58 encoded private key ensuring the depositer requested these attributes +// signing_key: identity::PrivateKey, +// +// /// base58 encoded private key ensuring only this client receives the signature share +// unused_ed25519: encryption::PrivateKey, +// +// pedersen_commitments_openings: Vec, +// +// #[zeroize(skip)] +// blind_sign_request: BlindSignRequest, +// } +// +// impl BandwidthVoucher { +// pub const PUBLIC_ATTRIBUTES: u32 = 2; +// pub const PRIVATE_ATTRIBUTES: u32 = 2; +// pub const ENCODED_ATTRIBUTES: u32 = Self::PUBLIC_ATTRIBUTES + Self::PRIVATE_ATTRIBUTES; +// +// pub fn default_parameters() -> Parameters { +// // safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero +// Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap() +// } +// +// pub fn new( +// params: &Parameters, +// voucher_value: String, +// voucher_info: String, +// tx_hash: Hash, +// signing_key: identity::PrivateKey, +// encryption_key: encryption::PrivateKey, +// ) -> Self { +// let serial_number = params.random_scalar(); +// let binding_number = params.random_scalar(); +// let voucher_value_plain = voucher_value.clone(); +// let voucher_info_plain = voucher_info.clone(); +// +// let _voucher_value_prehashed = hash_to_scalar(voucher_value); +// let _voucher_info_prehashed = hash_to_scalar(voucher_info); +// +// let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign( +// params, +// &[&serial_number, &binding_number], +// &[&_voucher_value_prehashed, &_voucher_info_prehashed], +// ) +// .unwrap(); +// BandwidthVoucher { +// serial_number, +// binding_number, +// _voucher_value_prehashed, +// voucher_value_plain, +// _voucher_info_prehashed, +// voucher_info_plain, +// tx_hash, +// signing_key, +// unused_ed25519: encryption_key, +// pedersen_commitments_openings, +// blind_sign_request, +// } +// } +// +// pub fn to_bytes(&self) -> Vec { +// let serial_number_b = self.serial_number.to_bytes(); +// let binding_number_b = self.binding_number.to_bytes(); +// let voucher_value_plain_b = self.voucher_value_plain.as_bytes(); +// let voucher_info_plain_b = self.voucher_info_plain.as_bytes(); +// let tx_hash_b = self.tx_hash.as_bytes(); +// let signing_key_b = self.signing_key.to_bytes(); +// let encryption_key_b = self.unused_ed25519.to_bytes(); +// let blind_sign_request_b = self.blind_sign_request.to_bytes(); +// +// let mut ret = Vec::new(); +// +// ret.extend_from_slice(&serial_number_b); +// ret.extend_from_slice(&binding_number_b); +// ret.extend_from_slice(tx_hash_b); +// ret.extend_from_slice(&signing_key_b); +// ret.extend_from_slice(&encryption_key_b); +// ret.extend_from_slice(&(voucher_value_plain_b.len() as u64).to_be_bytes()); +// ret.extend_from_slice(&(voucher_info_plain_b.len() as u64).to_be_bytes()); +// ret.extend_from_slice(&(blind_sign_request_b.len() as u64).to_be_bytes()); +// ret.extend_from_slice(&(self.pedersen_commitments_openings.len() as u64).to_be_bytes()); +// ret.extend_from_slice(voucher_value_plain_b); +// ret.extend_from_slice(voucher_info_plain_b); +// ret.extend_from_slice(&blind_sign_request_b); +// for commitment in self.pedersen_commitments_openings.iter() { +// ret.extend_from_slice(&commitment.to_bytes()); +// } +// +// ret +// } +// +// pub fn try_from_bytes(bytes: &[u8]) -> Result { +// if bytes.len() < 32 * 5 + 4 * 8 { +// return Err(Error::BandwidthVoucherDeserializationError(format!( +// "Less then {} bytes needed", +// 32 * 5 + 4 * 8 +// ))); +// } +// let mut buff = [0u8; 32]; +// let mut small_buff = [0u8; 8]; +// let scalar_err = +// || Error::BandwidthVoucherDeserializationError(String::from("Invalid Scalar")); +// buff.copy_from_slice(&bytes[..32]); +// let serial_number = Option::::from(PrivateAttribute::from_bytes(&buff)) +// .ok_or_else(scalar_err)?; +// buff.copy_from_slice(&bytes[32..2 * 32]); +// let binding_number = Option::::from(PrivateAttribute::from_bytes(&buff)) +// .ok_or_else(scalar_err)?; +// buff.copy_from_slice(&bytes[2 * 32..3 * 32]); +// let tx_hash = Hash::from_bytes(Algorithm::Sha256, &buff).map_err(|_| { +// Error::BandwidthVoucherDeserializationError(String::from("Invalid transaction Hash")) +// })?; +// buff.copy_from_slice(&bytes[3 * 32..4 * 32]); +// let signing_key = identity::PrivateKey::from_bytes(&buff).map_err(|_| { +// Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) +// })?; +// buff.copy_from_slice(&bytes[4 * 32..5 * 32]); +// let encryption_key = encryption::PrivateKey::from_bytes(&buff).map_err(|_| { +// Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) +// })?; +// small_buff.copy_from_slice(&bytes[5 * 32..5 * 32 + 8]); +// let voucher_value_plain_no = u64::from_be_bytes(small_buff) as usize; +// small_buff.copy_from_slice(&bytes[5 * 32 + 8..5 * 32 + 2 * 8]); +// let voucher_info_plain_no = u64::from_be_bytes(small_buff) as usize; +// small_buff.copy_from_slice(&bytes[5 * 32 + 2 * 8..5 * 32 + 3 * 8]); +// let blind_sign_request_no = u64::from_be_bytes(small_buff) as usize; +// small_buff.copy_from_slice(&bytes[5 * 32 + 3 * 8..5 * 32 + 4 * 8]); +// let pedersen_commitments_openings_no = u64::from_be_bytes(small_buff) as usize; +// +// let total_length = 32 * 5 +// + 4 * 8 +// + voucher_value_plain_no +// + voucher_info_plain_no +// + blind_sign_request_no +// + pedersen_commitments_openings_no * 32; +// if bytes.len() != total_length { +// return Err(Error::BandwidthVoucherDeserializationError(format!( +// "Expected {total_length} bytes", +// ))); +// } +// +// let utf_err = |_| { +// Err(Error::BandwidthVoucherDeserializationError(String::from( +// "Invalid UTF8 string", +// ))) +// }; +// let mut var_length_pointer = 5 * 32 + 4 * 8; +// let voucher_value_plain = String::from_utf8( +// bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(), +// ) +// .or_else(utf_err)?; +// let _voucher_value_prehashed = hash_to_scalar(&voucher_value_plain); +// var_length_pointer += voucher_value_plain_no; +// let voucher_info_plain = String::from_utf8( +// bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(), +// ) +// .or_else(utf_err)?; +// let _voucher_info_prehashed = hash_to_scalar(&voucher_info_plain); +// var_length_pointer += voucher_info_plain_no; +// let blind_sign_request = BlindSignRequest::from_bytes( +// &bytes[var_length_pointer..var_length_pointer + blind_sign_request_no], +// )?; +// var_length_pointer += blind_sign_request_no; +// +// let mut pedersen_commitments_openings = Vec::new(); +// for _ in 0..pedersen_commitments_openings_no { +// buff.copy_from_slice(&bytes[var_length_pointer..var_length_pointer + 32]); +// let commitment = +// Option::::from(Attribute::from_bytes(&buff)).ok_or_else(scalar_err)?; +// var_length_pointer += 32; +// pedersen_commitments_openings.push(commitment); +// } +// +// Ok(Self { +// serial_number, +// binding_number, +// _voucher_value_prehashed, +// voucher_value_plain, +// _voucher_info_prehashed, +// voucher_info_plain, +// tx_hash, +// signing_key, +// unused_ed25519: encryption_key, +// pedersen_commitments_openings, +// blind_sign_request, +// }) +// } +// +// /// Check if the plain values correspond to the PublicAttributes +// pub fn verify_against_plain(values: &[&PublicAttribute], plain_values: &[String]) -> bool { +// values.len() == 2 +// && plain_values.len() == 2 +// && values[0] == &hash_to_scalar(&plain_values[0]) +// && values[1] == &hash_to_scalar(&plain_values[1]) +// } +// +// pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> { +// vec![ +// &self._voucher_value_prehashed, +// &self._voucher_info_prehashed, +// ] +// } +// +// pub fn tx_hash(&self) -> Hash { +// self.tx_hash +// } +// +// pub fn identity_key(&self) -> &identity::PrivateKey { +// &self.signing_key +// } +// +// pub fn encryption_key(&self) -> &encryption::PrivateKey { +// &self.unused_ed25519 +// } +// +// pub fn pedersen_commitments_openings(&self) -> &Vec { +// &self.pedersen_commitments_openings +// } +// +// pub fn blind_sign_request(&self) -> &BlindSignRequest { +// &self.blind_sign_request +// } +// +// pub fn get_voucher_value(&self) -> String { +// self.voucher_value_plain.clone() +// } +// +// pub fn get_public_attributes_plain(&self) -> Vec { +// vec![ +// self.voucher_value_plain.clone(), +// self.voucher_info_plain.clone(), +// ] +// } +// +// pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> { +// vec![&self.serial_number, &self.binding_number] +// } +// +// pub fn signable_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec { +// let mut message = request.to_bytes(); +// message.extend_from_slice(tx_hash.as_bytes()); +// message +// } +// +// pub fn sign(&self) -> identity::Signature { +// let message = Self::signable_plaintext(&self.blind_sign_request, self.tx_hash); +// self.signing_key.sign(message) +// } +// } + +// pub fn prepare_for_spending( +// voucher_value: u64, +// voucher_info: String, +// serial_number: &PrivateAttribute, +// binding_number: &PrivateAttribute, +// epoch_id: u64, +// signature: &Signature, +// verification_key: &VerificationKey, +// ) -> Result { +// todo!() +// // let params = Parameters::new(BandwidthVoucher::ENCODED_ATTRIBUTES)?; +// // +// // prepare_credential_for_spending( +// // ¶ms, +// // voucher_value, +// // voucher_info, +// // serial_number, +// // binding_number, +// // epoch_id, +// // signature, +// // verification_key, +// // ) +// } + +#[cfg(test)] +mod test { + use super::*; + use cosmrs::tendermint::hash::Algorithm; + use nym_coconut_interface::Base58; + use rand::rngs::OsRng; + + fn voucher_fixture() -> BandwidthVoucher { + let params = Parameters::new(4).unwrap(); + let mut rng = OsRng; + BandwidthVoucher::new( + ¶ms, + "1234".to_string(), + "voucher info".to_string(), + Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), + identity::PrivateKey::from_base58_string( + identity::KeyPair::new(&mut rng) + .private_key() + .to_base58_string(), + ) + .unwrap(), + encryption::PrivateKey::from_bytes( + &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), + ) + .unwrap(), + ) + } + + #[test] + fn serde_voucher() { + let voucher = voucher_fixture(); + let bytes = voucher.to_bytes(); + let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap(); + assert_eq!(voucher.serial_number, deserialized_voucher.serial_number); + assert_eq!(voucher.binding_number, deserialized_voucher.binding_number); + assert_eq!( + voucher.voucher_value_plain, + deserialized_voucher.voucher_value_plain + ); + assert_eq!( + voucher.voucher_info_plain, + deserialized_voucher.voucher_info_plain + ); + assert_eq!( + voucher._voucher_value_prehashed, + deserialized_voucher._voucher_value_prehashed + ); + assert_eq!( + voucher._voucher_info_prehashed, + deserialized_voucher._voucher_info_prehashed + ); + assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash); + assert_eq!( + voucher.signing_key.to_string(), + deserialized_voucher.signing_key.to_string() + ); + assert_eq!( + voucher.unused_ed25519.to_string(), + deserialized_voucher.unused_ed25519.to_string() + ); + assert_eq!( + voucher.pedersen_commitments_openings, + deserialized_voucher.pedersen_commitments_openings + ); + assert_eq!( + voucher.blind_sign_request.to_bs58(), + deserialized_voucher.blind_sign_request.to_bs58() + ); + } + + #[test] + fn voucher_consistency() { + let voucher = voucher_fixture(); + assert!(!BandwidthVoucher::verify_against_plain( + &[], + &voucher.get_public_attributes_plain() + )); + assert!(!BandwidthVoucher::verify_against_plain( + &voucher.get_public_attributes(), + &[], + )); + assert!(!BandwidthVoucher::verify_against_plain( + &voucher.get_public_attributes(), + &[ + voucher.get_public_attributes_plain()[0].clone(), + String::new() + ] + )); + assert!(!BandwidthVoucher::verify_against_plain( + &voucher.get_public_attributes(), + &[ + String::new(), + voucher.get_public_attributes_plain()[1].clone() + ] + )); + assert!(!BandwidthVoucher::verify_against_plain( + &[voucher.get_public_attributes()[0], &Attribute::one()], + &voucher.get_public_attributes_plain() + )); + assert!(!BandwidthVoucher::verify_against_plain( + &[&Attribute::one(), voucher.get_public_attributes()[1]], + &voucher.get_public_attributes_plain() + )); + assert!(BandwidthVoucher::verify_against_plain( + &voucher.get_public_attributes(), + &voucher.get_public_attributes_plain() + )); + } +} diff --git a/common/credentials/src/coconut/credential.rs b/common/credentials/src/coconut/credential.rs new file mode 100644 index 0000000000..6863200e17 --- /dev/null +++ b/common/credentials/src/coconut/credential.rs @@ -0,0 +1,10 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +pub trait NymCredential { + fn prove_credential(&self); + + // pub attr + // hashed + // private +} diff --git a/common/credentials/src/coconut/mod.rs b/common/credentials/src/coconut/mod.rs index bf480ad58a..c02b932712 100644 --- a/common/credentials/src/coconut/mod.rs +++ b/common/credentials/src/coconut/mod.rs @@ -1,5 +1,6 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 pub mod bandwidth; +pub mod credential; pub mod utils; diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index 367f62e2c3..b1247881ff 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -1,13 +1,12 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::coconut::bandwidth::BandwidthVoucher; +use crate::coconut::bandwidth::IssuanceBandwidthCredential; use crate::error::Error; use log::{debug, warn}; -use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut_interface::{ - aggregate_signature_shares, aggregate_verification_keys, prove_bandwidth_credential, Attribute, - Credential, Parameters, Signature, SignatureShare, VerificationKey, + aggregate_verification_keys, prove_bandwidth_credential, Attribute, Credential, Parameters, + Signature, SignatureShare, VerificationKey, }; use nym_validator_client::client::CoconutApiClient; @@ -30,44 +29,8 @@ pub async fn obtain_aggregate_verification_key( Ok(aggregate_verification_keys(&shares, Some(&indices))?) } -async fn obtain_partial_credential( - params: &Parameters, - voucher: &BandwidthVoucher, - client: &nym_validator_client::client::NymApiClient, - validator_vk: &VerificationKey, -) -> Result { - let public_attributes_plain = voucher.get_public_attributes_plain(); - let blind_sign_request = voucher.blind_sign_request(); - let request_signature = voucher.sign(); - - let blind_sign_request_body = BlindSignRequestBody::new( - blind_sign_request.clone(), - voucher.tx_hash(), - request_signature, - public_attributes_plain, - ); - let response = client.blind_sign(&blind_sign_request_body).await?; - - let blinded_signature = response.blinded_signature; - - let public_attributes = voucher.get_public_attributes(); - let private_attributes = voucher.get_private_attributes(); - - let unblinded_signature = blinded_signature.unblind_and_verify( - params, - validator_vk, - &private_attributes, - &public_attributes, - &blind_sign_request.get_commitment_hash(), - voucher.pedersen_commitments_openings(), - )?; - - Ok(unblinded_signature) -} - pub async fn obtain_aggregate_signature( - params: &Parameters, - voucher: &BandwidthVoucher, + voucher: &IssuanceBandwidthCredential, coconut_api_clients: &[CoconutApiClient], threshold: u64, ) -> Result { @@ -75,16 +38,9 @@ pub async fn obtain_aggregate_signature( return Err(Error::NoValidatorsAvailable); } let mut shares = Vec::with_capacity(coconut_api_clients.len()); - let validators_partial_vks: Vec<_> = coconut_api_clients - .iter() - .map(|api_client| api_client.verification_key.clone()) - .collect(); - let indices: Vec<_> = coconut_api_clients - .iter() - .map(|api_client| api_client.node_id) - .collect(); - let verification_key = - aggregate_verification_keys(&validators_partial_vks, Some(indices.as_ref()))?; + let verification_key = obtain_aggregate_verification_key(coconut_api_clients).await?; + + let request = voucher.prepare_for_signing(); for coconut_api_client in coconut_api_clients.iter() { debug!( @@ -92,13 +48,13 @@ pub async fn obtain_aggregate_signature( coconut_api_client.api_client.api_url() ); - match obtain_partial_credential( - params, - voucher, - &coconut_api_client.api_client, - &coconut_api_client.verification_key, - ) - .await + match voucher + .obtain_partial_credential( + &coconut_api_client.api_client, + &coconut_api_client.verification_key, + Some(request.clone()), + ) + .await { Ok(signature) => { let share = SignatureShare::new(signature, coconut_api_client.node_id); @@ -116,15 +72,7 @@ pub async fn obtain_aggregate_signature( return Err(Error::NotEnoughShares); } - let public_attributes = voucher.get_public_attributes(); - let private_attributes = voucher.get_private_attributes(); - - let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len()); - attributes.extend_from_slice(&private_attributes); - attributes.extend_from_slice(&public_attributes); - - aggregate_signature_shares(params, &verification_key, &attributes, &shares) - .map_err(Error::SignatureAggregationError) + voucher.aggregate_signature_shares(&verification_key, &shares) } // TODO: better type flow @@ -148,7 +96,7 @@ pub fn prepare_credential_for_spending( )?; Ok(Credential::new( - BandwidthVoucher::ENCODED_ATTRIBUTES, + IssuanceBandwidthCredential::ENCODED_ATTRIBUTES, theta, voucher_value, voucher_info, diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index ea265e83d3..4404b0e51f 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -466,10 +466,9 @@ pub const UTOKENS_TO_BURN: u64 = TOKENS_TO_BURN * 1000000; /// Default bandwidth (in bytes) that we try to buy pub const BANDWIDTH_VALUE: u64 = UTOKENS_TO_BURN * BYTES_PER_UTOKEN; +#[deprecated] pub const VOUCHER_INFO: &str = "BandwidthVoucher"; -pub const ETH_MIN_BLOCK_DEPTH: usize = 7; - /// Defaults Cosmos Hub/ATOM path pub const COSMOS_DERIVATION_PATH: &str = "m/44'/118'/0'/0/0"; // as set by validators in their configs diff --git a/common/nymcoconut/src/impls/clone.rs b/common/nymcoconut/src/impls/clone.rs index fdcee5c0de..88ee6664c0 100644 --- a/common/nymcoconut/src/impls/clone.rs +++ b/common/nymcoconut/src/impls/clone.rs @@ -1,4 +1,4 @@ -use crate::{BlindSignRequest, BlindedSignature, Bytable, Theta}; +use crate::{BlindSignRequest, BlindedSignature, Bytable, VerifyCredentialRequest}; macro_rules! impl_clone { ($struct:ident) => { @@ -12,4 +12,4 @@ macro_rules! impl_clone { impl_clone!(BlindSignRequest); impl_clone!(BlindedSignature); -impl_clone!(Theta); +impl_clone!(VerifyCredentialRequest); diff --git a/common/nymcoconut/src/impls/serde.rs b/common/nymcoconut/src/impls/serde.rs index 91dbf41f46..7d1e020cb1 100644 --- a/common/nymcoconut/src/impls/serde.rs +++ b/common/nymcoconut/src/impls/serde.rs @@ -1,7 +1,8 @@ use crate::elgamal::PrivateKey; use crate::scheme::SecretKey; use crate::{ - Base58, BlindSignRequest, BlindedSignature, PublicKey, Signature, Theta, VerificationKey, + Base58, BlindSignRequest, BlindedSignature, PublicKey, Signature, VerificationKey, + VerifyCredentialRequest, }; use serde::de::Unexpected; use serde::{de::Error, de::Visitor, Deserialize, Deserializer, Serialize, Serializer}; @@ -53,4 +54,4 @@ impl_serde!(PrivateKey, V4); impl_serde!(BlindSignRequest, V5); impl_serde!(BlindedSignature, V6); impl_serde!(Signature, V7); -impl_serde!(Theta, V8); +impl_serde!(VerifyCredentialRequest, V8); diff --git a/common/nymcoconut/src/lib.rs b/common/nymcoconut/src/lib.rs index 7f1631f801..ed258cd557 100644 --- a/common/nymcoconut/src/lib.rs +++ b/common/nymcoconut/src/lib.rs @@ -23,7 +23,7 @@ pub use scheme::setup::Parameters; pub use scheme::verification::check_vk_pairing; pub use scheme::verification::prove_bandwidth_credential; pub use scheme::verification::verify_credential; -pub use scheme::verification::Theta; +pub use scheme::verification::VerifyCredentialRequest; pub use scheme::BlindedSignature; pub use scheme::Signature; pub use scheme::SignatureShare; diff --git a/common/nymcoconut/src/scheme/verification.rs b/common/nymcoconut/src/scheme/verification.rs index 1373c30bc7..cbf36fde2f 100644 --- a/common/nymcoconut/src/scheme/verification.rs +++ b/common/nymcoconut/src/scheme/verification.rs @@ -21,7 +21,7 @@ use crate::Attribute; // TODO NAMING: this whole thing // Theta #[derive(Debug, PartialEq, Eq)] -pub struct Theta { +pub struct VerifyCredentialRequest { // blinded_message (kappa) pub blinded_message: G2Projective, // blinded serial number (zeta) @@ -32,10 +32,10 @@ pub struct Theta { pub pi_v: ProofKappaZeta, } -impl TryFrom<&[u8]> for Theta { +impl TryFrom<&[u8]> for VerifyCredentialRequest { type Error = CoconutError; - fn try_from(bytes: &[u8]) -> Result { + fn try_from(bytes: &[u8]) -> Result { if bytes.len() < 288 { return Err( CoconutError::Deserialization( @@ -66,7 +66,7 @@ impl TryFrom<&[u8]> for Theta { let pi_v = ProofKappaZeta::from_bytes(&bytes[288..])?; - Ok(Theta { + Ok(VerifyCredentialRequest { blinded_message, blinded_serial_number, credential, @@ -75,7 +75,7 @@ impl TryFrom<&[u8]> for Theta { } } -impl Theta { +impl VerifyCredentialRequest { fn verify_proof(&self, params: &Parameters, verification_key: &VerificationKey) -> bool { self.pi_v.verify( params, @@ -107,8 +107,8 @@ impl Theta { bytes } - pub fn from_bytes(bytes: &[u8]) -> Result { - Theta::try_from(bytes) + pub fn from_bytes(bytes: &[u8]) -> Result { + VerifyCredentialRequest::try_from(bytes) } pub fn blinded_serial_number_bs58(&self) -> String { @@ -119,17 +119,17 @@ impl Theta { } } -impl Bytable for Theta { +impl Bytable for VerifyCredentialRequest { fn to_byte_vec(&self) -> Vec { self.to_bytes() } fn try_from_byte_slice(slice: &[u8]) -> Result { - Theta::try_from(slice) + VerifyCredentialRequest::try_from(slice) } } -impl Base58 for Theta {} +impl Base58 for VerifyCredentialRequest {} pub fn compute_kappa( params: &Parameters, @@ -156,7 +156,7 @@ pub fn prove_bandwidth_credential( signature: &Signature, serial_number: &Attribute, binding_number: &Attribute, -) -> Result { +) -> Result { if verification_key.beta_g2.len() < 2 { return Err( CoconutError::Verification( @@ -196,7 +196,7 @@ pub fn prove_bandwidth_credential( &blinded_serial_number, ); - Ok(Theta { + Ok(VerifyCredentialRequest { blinded_message, blinded_serial_number, credential: signature_prime, @@ -256,7 +256,7 @@ pub fn check_vk_pairing( pub fn verify_credential( params: &Parameters, verification_key: &VerificationKey, - theta: &Theta, + theta: &VerifyCredentialRequest, public_attributes: &[&Attribute], ) -> bool { if public_attributes.len() + theta.pi_v.private_attributes_len() @@ -358,6 +358,9 @@ mod tests { .unwrap(); let bytes = theta.to_bytes(); - assert_eq!(Theta::try_from(bytes.as_slice()).unwrap(), theta); + assert_eq!( + VerifyCredentialRequest::try_from(bytes.as_slice()).unwrap(), + theta + ); } } diff --git a/common/nymcoconut/src/tests/helpers.rs b/common/nymcoconut/src/tests/helpers.rs index e0f58ba33b..9b3b16d44c 100644 --- a/common/nymcoconut/src/tests/helpers.rs +++ b/common/nymcoconut/src/tests/helpers.rs @@ -12,7 +12,7 @@ pub fn theta_from_keys_and_attributes( coconut_keypairs: &Vec, indices: &[scheme::SignerIndex], public_attributes: &[&PublicAttribute], -) -> Result { +) -> Result { let serial_number = params.random_scalar(); let binding_number = params.random_scalar(); let private_attributes = vec![&serial_number, &binding_number]; diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 12fa660f51..c8a739319d 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2023 - Nym Technologies SA +// Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only use crate::coconut::api_routes::helpers::build_credentials_response; @@ -17,7 +17,7 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{ funds_from_cosmos_msgs, SpendCredentialStatus, }; use nym_coconut_dkg_common::types::EpochId; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; use nym_validator_client::nyxd::Coin; use rocket::serde::json::Json; use rocket::State as RocketState; @@ -36,7 +36,7 @@ pub async fn post_blind_sign( // early check: does the request have the expected number of public attributes? debug!("performing basic request validation"); if blind_sign_request_body.public_attributes_plain.len() - != BandwidthVoucher::PUBLIC_ATTRIBUTES as usize + != IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize { return Err(CoconutError::InconsistentPublicAttributes); } diff --git a/nym-api/src/coconut/deposit.rs b/nym-api/src/coconut/deposit.rs index 22f59fc969..ab1c345991 100644 --- a/nym-api/src/coconut/deposit.rs +++ b/nym-api/src/coconut/deposit.rs @@ -7,13 +7,16 @@ use nym_coconut_bandwidth_contract_common::events::{ COSMWASM_DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_ENCRYPTION_KEY, DEPOSIT_IDENTITY_KEY, DEPOSIT_INFO, DEPOSIT_VALUE, }; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; +use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::helpers::find_tx_attribute; use nym_validator_client::nyxd::TxResponse; pub async fn validate_deposit_tx(request: &BlindSignRequestBody, tx: TxResponse) -> Result<()> { - if request.public_attributes_plain.len() != BandwidthVoucher::PUBLIC_ATTRIBUTES as usize { + if request.public_attributes_plain.len() + != IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize + { return Err(CoconutError::InconsistentPublicAttributes); } @@ -58,8 +61,10 @@ pub async fn validate_deposit_tx(request: &BlindSignRequestBody, tx: TxResponse) // verify signature let x25519 = identity::PublicKey::from_base58_string(x25519_raw)?; - let plaintext = - BandwidthVoucher::signable_plaintext(&request.inner_sign_request, request.tx_hash); + let plaintext = BandwidthVoucherIssuanceData::request_plaintext( + &request.inner_sign_request, + request.tx_hash, + ); x25519.verify(plaintext, &request.signature)?; Ok(()) diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index de38ca614f..72fad9b27d 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -10,23 +10,13 @@ use crate::coconut::storage::CoconutStorageExt; use crate::support::storage::NymApiStorage; use nym_api_requests::coconut::helpers::issued_credential_plaintext; use nym_api_requests::coconut::BlindSignRequestBody; -use nym_coconut::Parameters; use nym_coconut_dkg_common::types::EpochId; use nym_coconut_interface::{BlindedSignature, VerificationKey}; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::{Hash, TxResponse}; -use std::sync::{Arc, OnceLock}; +use std::sync::Arc; -// keep it as a global static due to relatively high cost of computing the curve points; -// plus we expect all clients to use the same set of parameters -// -// future note: once we allow for credentials with variable number of attributes, just create Parameters(max_allowed_attributes) -// and take as many hs elements as required (since they will match for all variants) -pub(crate) fn bandwidth_voucher_params() -> &'static Parameters { - static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); - BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(BandwidthVoucher::default_parameters) -} +pub use nym_credentials::coconut::bandwidth::bandwidth_voucher_params; pub struct State { pub(crate) client: Arc, diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index c284610844..9083541347 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3937,7 +3937,9 @@ dependencies = [ "nym-coconut-interface", "nym-crypto", "nym-validator-client", + "serde", "thiserror", + "time", "zeroize", ] diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index 96bdef6aae..251489b3b5 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -1,4 +1,4 @@ -// Copyright 2023 - Nym Technologies SA +// Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::config; @@ -11,25 +11,18 @@ use crate::rewarder::nyxd_client::NyxdClient; use bip39::rand::prelude::SliceRandom; use bip39::rand::thread_rng; use nym_coconut::{ - hash_to_scalar, verify_partial_blind_signature, Base58, G1Projective, Parameters, - VerificationKey, + hash_to_scalar, verify_partial_blind_signature, Base58, G1Projective, VerificationKey, }; use nym_coconut_dkg_common::types::EpochId; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::bandwidth_voucher_params; use nym_task::TaskClient; use nym_validator_client::nym_api::{IssuedCredential, IssuedCredentialBody, NymApiClientExt}; use nym_validator_client::nyxd::Hash; use std::cmp::max; use std::collections::HashMap; -use std::sync::OnceLock; use tokio::time::interval; use tracing::{debug, error, info, instrument, trace, warn}; -pub(crate) fn bandwidth_voucher_params() -> &'static Parameters { - static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); - BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(BandwidthVoucher::default_parameters) -} - pub struct CredentialIssuanceMonitor { nyxd_client: NyxdClient, monitoring_results: MonitoringResults, diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 7171282a71..2733279e58 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -4,7 +4,7 @@ use crate::error::{Error, Result}; use nym_bandwidth_controller::acquire::state::State; use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; use nym_network_defaults::NymNetworkDetails; use nym_validator_client::nyxd::Coin; use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; @@ -68,7 +68,7 @@ where /// In case of an error in the mid of the acquire process, this function should be used for /// later retries to recover the bandwidth credential, either immediately or after some time. pub async fn recover(&self, voucher_blob: &VoucherBlob) -> Result<()> { - let voucher = BandwidthVoucher::try_from_bytes(voucher_blob) + let voucher = IssuanceBandwidthCredential::try_from_bytes(voucher_blob) .map_err(|_| Error::InvalidVoucherBlob)?; let state = State::new(voucher); nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) From 36242fa2571ead3c09ceed3dcfa9701049e88ada Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 6 Feb 2024 17:58:21 +0000 Subject: [PATCH 049/394] serde for 'IssuanceBandwidthCredential' --- .../src/coconut/bandwidth/freepass.rs | 4 +- .../src/coconut/bandwidth/issuance.rs | 9 +++- .../src/coconut/bandwidth/voucher.rs | 4 +- common/credentials/src/coconut/utils.rs | 45 ++++++++----------- 4 files changed, 32 insertions(+), 30 deletions(-) diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index d0e17ba55b..5783a8c25d 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -1,6 +1,7 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::coconut::utils::scalar_serde_helper; use nym_coconut_interface::{hash_to_scalar, Attribute, PublicAttribute}; use serde::{Deserialize, Serialize}; use time::{Duration, OffsetDateTime, Time}; @@ -29,13 +30,14 @@ impl FreePassIssuedData { } } -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct FreePassIssuanceData { /// the plain validity value of this credential expressed as unix timestamp #[zeroize(skip)] expiry_date: OffsetDateTime, // the expiry date, as unix timestamp, hashed into a scalar + #[serde(with = "scalar_serde_helper")] expiry_date_prehashed: PublicAttribute, } diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index ba694d37f8..36d540c493 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -7,6 +7,7 @@ use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; use crate::coconut::bandwidth::{ bandwidth_voucher_params, CredentialSigningData, CredentialSpendingData, CredentialType, }; +use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use nym_coconut_interface::{ aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, prove_bandwidth_credential, @@ -15,10 +16,11 @@ use nym_coconut_interface::{ }; use nym_crypto::asymmetric::{encryption, identity}; use nym_validator_client::nyxd::{Coin, Hash}; +use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use zeroize::{Zeroize, ZeroizeOnDrop}; -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub enum BandwidthCredentialIssuanceDataVariant { Voucher(BandwidthVoucherIssuanceData), FreePass(FreePassIssuanceData), @@ -66,19 +68,22 @@ impl BandwidthCredentialIssuanceDataVariant { } // all types of bandwidth credentials contain serial number and binding number -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct IssuanceBandwidthCredential { // private attributes /// a random secret value generated by the client used for double-spending detection + #[serde(with = "scalar_serde_helper")] serial_number: PrivateAttribute, /// a random secret value generated by the client used to bind multiple credentials together + #[serde(with = "scalar_serde_helper")] binding_number: PrivateAttribute, /// data specific to given bandwidth credential, for example a value for bandwidth voucher and expiry date for the free pass variant_data: BandwidthCredentialIssuanceDataVariant, /// type of the bandwdith credential hashed onto a scalar + #[serde(with = "scalar_serde_helper")] type_prehashed: PublicAttribute, } diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index cce7726b60..06f88d2414 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::coconut::bandwidth::CredentialSigningData; +use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut_interface::{ @@ -34,7 +35,7 @@ impl BandwidthVoucherIssuedData { } } -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct BandwidthVoucherIssuanceData { /// the plain value (e.g., bandwidth) encoded in this voucher // note: for legacy reasons we're only using the value of the coin and ignoring the denom @@ -42,6 +43,7 @@ pub struct BandwidthVoucherIssuanceData { value: Coin, // note: as mentioned above, we're only hashing the value of the coin! + #[serde(with = "scalar_serde_helper")] value_prehashed: PublicAttribute, /// the hash of the deposit transaction diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index b1247881ff..2a59d0fc2d 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -75,31 +75,24 @@ pub async fn obtain_aggregate_signature( voucher.aggregate_signature_shares(&verification_key, &shares) } -// TODO: better type flow -#[allow(clippy::too_many_arguments)] -pub fn prepare_credential_for_spending( - params: &Parameters, - voucher_value: u64, - voucher_info: String, - serial_number: &Attribute, - binding_number: &Attribute, - epoch_id: u64, - signature: &Signature, - verification_key: &VerificationKey, -) -> Result { - let theta = prove_bandwidth_credential( - params, - verification_key, - signature, - serial_number, - binding_number, - )?; +pub(crate) mod scalar_serde_helper { + use bls12_381::Scalar; + use serde::{Deserialize, Deserializer, Serialize, Serializer}; + use zeroize::Zeroizing; - Ok(Credential::new( - IssuanceBandwidthCredential::ENCODED_ATTRIBUTES, - theta, - voucher_value, - voucher_info, - epoch_id, - )) + pub fn serialize(scalar: &Scalar, serializer: S) -> Result { + scalar.to_bytes().serialize(serializer) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result { + let b = <[u8; 32]>::deserialize(deserializer)?; + + // make sure the bytes get zeroed + let bytes = Zeroizing::new(b); + + let maybe_scalar: Option = Scalar::from_bytes(&bytes).into(); + maybe_scalar.ok_or(serde::de::Error::custom( + "did not construct a valid bls12-381 scalar out of the provided bytes", + )) + } } From 7a7fbce8ea98a2c7943cd068543afe3b7ca95e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 6 Feb 2024 18:10:25 +0000 Subject: [PATCH 050/394] using bincode serialization --- .../credential-utils/src/recovery_storage.rs | 2 +- common/credentials/Cargo.toml | 1 + .../src/coconut/bandwidth/issuance.rs | 22 +++++++++---------- .../src/coconut/bandwidth/issued.rs | 4 ++-- common/credentials/src/coconut/utils.rs | 10 +++++++-- common/credentials/src/error.rs | 3 +++ sdk/rust/nym-sdk/src/bandwidth/client.rs | 4 ++-- 7 files changed, 28 insertions(+), 18 deletions(-) diff --git a/common/credential-utils/src/recovery_storage.rs b/common/credential-utils/src/recovery_storage.rs index 6dc6ec76bd..3c9b8c17af 100644 --- a/common/credential-utils/src/recovery_storage.rs +++ b/common/credential-utils/src/recovery_storage.rs @@ -34,7 +34,7 @@ impl RecoveryStorage { if let Ok(mut file) = File::open(&path) { let mut buff = Vec::new(); if file.read_to_end(&mut buff).is_ok() { - match IssuanceBandwidthCredential::try_from_bytes(&buff) { + match IssuanceBandwidthCredential::try_from_recovered_bytes(&buff) { Ok(voucher) => vouchers.push(voucher), Err(err) => { error!("failed to parse the voucher at {}: {err}", path.display()) diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 9c42f08418..f08a3a5cd5 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] bls12_381 = { workspace = true, default-features = false, features = ["pairings", "alloc", "experimental"] } +bincode = "1.3.3" cosmrs = { workspace = true } thiserror = { workspace = true } log = { workspace = true } diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 36d540c493..e889fcef22 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -4,15 +4,12 @@ use crate::coconut::bandwidth::freepass::FreePassIssuanceData; use crate::coconut::bandwidth::issued::IssuedBandwidthCredential; use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; -use crate::coconut::bandwidth::{ - bandwidth_voucher_params, CredentialSigningData, CredentialSpendingData, CredentialType, -}; -use crate::coconut::utils::scalar_serde_helper; +use crate::coconut::bandwidth::{bandwidth_voucher_params, CredentialSigningData, CredentialType}; +use crate::coconut::utils::{make_bincode_serializer, scalar_serde_helper}; use crate::error::Error; use nym_coconut_interface::{ - aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, prove_bandwidth_credential, - Attribute, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, - VerificationKey, + aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, + PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, }; use nym_crypto::asymmetric::{encryption, identity}; use nym_validator_client::nyxd::{Coin, Hash}; @@ -240,12 +237,15 @@ impl IssuanceBandwidthCredential { } // TODO: is that actually needed? - pub fn to_bytes(&self) -> Vec { - todo!() + pub fn to_recovery_bytes(&self) -> Vec { + use bincode::Options; + // safety: our data format is stable and thus the serialization should not fail + make_bincode_serializer().serialize(self).unwrap() } // TODO: is that actually needed? - pub fn try_from_bytes(bytes: &[u8]) -> Result { - todo!() + pub fn try_from_recovered_bytes(bytes: &[u8]) -> Result { + use bincode::Options; + Ok(make_bincode_serializer().deserialize(bytes)?) } } diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 2c541d2701..e12cacb6c4 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -9,8 +9,8 @@ use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuedData; use crate::coconut::bandwidth::{bandwidth_voucher_params, CredentialSpendingData, CredentialType}; use crate::error::Error; use nym_coconut_interface::{ - prove_bandwidth_credential, Attribute, Parameters, PrivateAttribute, PublicAttribute, - Signature, VerificationKey, + prove_bandwidth_credential, Parameters, PrivateAttribute, PublicAttribute, Signature, + VerificationKey, }; use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index 2a59d0fc2d..08379c9017 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -5,8 +5,7 @@ use crate::coconut::bandwidth::IssuanceBandwidthCredential; use crate::error::Error; use log::{debug, warn}; use nym_coconut_interface::{ - aggregate_verification_keys, prove_bandwidth_credential, Attribute, Credential, Parameters, - Signature, SignatureShare, VerificationKey, + aggregate_verification_keys, Signature, SignatureShare, VerificationKey, }; use nym_validator_client::client::CoconutApiClient; @@ -96,3 +95,10 @@ pub(crate) mod scalar_serde_helper { )) } } + +pub(crate) fn make_bincode_serializer() -> impl bincode::Options { + use bincode::Options; + bincode::DefaultOptions::new() + .with_big_endian() + .with_varint_encoding() +} diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index 4c10971e3d..c89667aad6 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -12,6 +12,9 @@ pub enum Error { #[error("IO error")] IOError(#[from] std::io::Error), + #[error("failed to (de)serialize credential structure: {0}")] + SerializationFailure(#[from] bincode::Error), + #[error("The detailed description is yet to be determined")] BandwidthCredentialError, diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index 2733279e58..c5756e0cdc 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -61,14 +61,14 @@ where .await .map_err(|reason| Error::UnconvertedDeposit { reason, - voucher_blob: state.voucher.to_bytes(), + voucher_blob: state.voucher.to_recovery_bytes(), }) } /// In case of an error in the mid of the acquire process, this function should be used for /// later retries to recover the bandwidth credential, either immediately or after some time. pub async fn recover(&self, voucher_blob: &VoucherBlob) -> Result<()> { - let voucher = IssuanceBandwidthCredential::try_from_bytes(voucher_blob) + let voucher = IssuanceBandwidthCredential::try_from_recovered_bytes(voucher_blob) .map_err(|_| Error::InvalidVoucherBlob)?; let state = State::new(voucher); nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) From 6f3dd9f778c89f6961e79e6689ee8277367cf427 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 7 Feb 2024 11:32:26 +0000 Subject: [PATCH 051/394] wip --- Cargo.lock | 4 +- common/bandwidth-controller/Cargo.toml | 1 + common/bandwidth-controller/src/lib.rs | 71 ++++++++++----- common/client-libs/gateway-client/Cargo.toml | 2 +- .../client-libs/gateway-client/src/client.rs | 18 ++-- common/coconut-interface/src/lib.rs | 8 +- common/credential-storage/src/models.rs | 5 +- .../src/coconut/bandwidth/issuance.rs | 29 ++++--- .../src/coconut/bandwidth/issued.rs | 8 +- .../credentials/src/coconut/bandwidth/mod.rs | 39 ++++++++- common/credentials/src/coconut/utils.rs | 7 -- common/credentials/src/lib.rs | 4 + gateway/gateway-requests/src/lib.rs | 1 + gateway/gateway-requests/src/models.rs | 30 +++++++ gateway/gateway-requests/src/types.rs | 87 +++++++++---------- nym-api/src/coconut/dkg/key_derivation.rs | 6 +- nym-api/src/coconut/dkg/key_validation.rs | 4 +- nym-api/src/coconut/helpers.rs | 4 +- nym-api/src/coconut/keys/persistence.rs | 4 +- nym-api/src/coconut/state.rs | 2 +- nym-connect/desktop/Cargo.lock | 4 +- .../rewarder/credential_issuance/monitor.rs | 4 +- 22 files changed, 217 insertions(+), 125 deletions(-) create mode 100644 gateway/gateway-requests/src/models.rs diff --git a/Cargo.lock b/Cargo.lock index 7d92bcd044..468a7c6790 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5015,6 +5015,7 @@ name = "nym-bandwidth-controller" version = "0.1.0" dependencies = [ "bip39", + "log", "nym-coconut-interface", "nym-credential-storage", "nym-credentials", @@ -5375,6 +5376,7 @@ dependencies = [ name = "nym-credentials" version = "0.1.0" dependencies = [ + "bincode", "bls12_381", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", @@ -5561,8 +5563,8 @@ dependencies = [ "gloo-utils", "log", "nym-bandwidth-controller", - "nym-coconut-interface", "nym-credential-storage", + "nym-credentials", "nym-crypto", "nym-gateway-requests", "nym-network-defaults", diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 75050e6e75..116f8d20c4 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] bip39 = { workspace = true } +log = { workspace = true } rand = "0.7.3" thiserror = { workspace = true } url = { workspace = true } diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index f114dcab83..d6f5dfb731 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -3,16 +3,16 @@ use crate::error::BandwidthControllerError; use crate::utils::stored_credential_to_issued_bandwidth; +use log::{error, warn}; +use nym_coconut_interface::VerificationKey; use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::CredentialSpendingData; +use nym_credentials::coconut::utils::obtain_aggregate_verification_key; use nym_validator_client::coconut::all_coconut_api_clients; +use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use std::str::FromStr; -use zeroize::Zeroizing; -use { - nym_coconut_interface::Base58, - nym_credentials::coconut::utils::obtain_aggregate_verification_key, -}; pub mod acquire; pub mod error; @@ -23,6 +23,18 @@ pub struct BandwidthController { client: C, } +pub struct PreparedCredential { + /// The cryptographic material required for spending the underlying credential. + pub data: CredentialSpendingData, + + /// The (DKG) epoch id under which the credential has been issued so that the verifier + /// could use correct verification key for validation. + pub epoch_id: EpochId, + + /// The database id of the stored credential. + pub credential_id: i64, +} + impl BandwidthController { pub fn new(storage: St, client: C) -> Self { BandwidthController { storage, client } @@ -32,9 +44,21 @@ impl BandwidthController { &self.storage } + async fn get_aggregate_verification_key( + &self, + epoch_id: EpochId, + ) -> Result + where + C: DkgQueryClient + Sync + Send, + ::StorageError: Send + Sync + 'static, + { + let coconut_api_clients = all_coconut_api_clients(&self.client, epoch_id).await?; + Ok(obtain_aggregate_verification_key(&coconut_api_clients).await?) + } + pub async fn prepare_coconut_credential( &self, - ) -> Result<(nym_coconut_interface::Credential, i64), BandwidthControllerError> + ) -> Result where C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, @@ -47,29 +71,28 @@ impl BandwidthController { let epoch_id = u64::from_str(&retrieved_credential.epoch_id) .map_err(|_| StorageError::InconsistentData)?; + let credential_id = retrieved_credential.id; let issued_bandwidth = stored_credential_to_issued_bandwidth(retrieved_credential)?; - let coconut_api_clients = all_coconut_api_clients(&self.client, epoch_id).await?; - let verification_key = obtain_aggregate_verification_key(&coconut_api_clients).await?; + let verification_key = match self.get_aggregate_verification_key(epoch_id).await { + Ok(key) => key, + Err(err) => { + warn!("failed to obtain master verification key: {err}. Putting the credential back into the database"); + + // TODO: ERROR RECOVERY: + error!("unimplemented: putting the credential back into the database"); + return Err(err); + } + }; let spend_request = issued_bandwidth.prepare_for_spending(&verification_key)?; - todo!() - - // // the below would only be executed once we know where we want to spend it (i.e. which gateway and stuff) - // Ok(( - // prepare_for_spending( - // voucher_value, - // voucher_info, - // &serial_number, - // &binding_number, - // epoch_id, - // &signature, - // &verification_key, - // )?, - // bandwidth_credential.id, - // )) + Ok(PreparedCredential { + data: spend_request, + epoch_id, + credential_id, + }) } pub async fn consume_credential(&self, id: i64) -> Result<(), BandwidthControllerError> @@ -88,7 +111,7 @@ impl BandwidthController { impl Clone for BandwidthController where C: Clone, - St: Storage + Clone, + St: Clone, { fn clone(&self) -> Self { BandwidthController { diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 67297687e4..44b9a58e82 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -19,7 +19,7 @@ tokio = { version = "1.24.1", features = ["macros"] } # internal nym-bandwidth-controller = { path = "../../bandwidth-controller" } -nym-coconut-interface = { path = "../../coconut-interface" } +nym-credentials = { path = "../../credentials" } nym-credential-storage = { path = "../../credential-storage" } nym-crypto = { path = "../../crypto" } nym-gateway-requests = { path = "../../../gateway/gateway-requests" } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index f65e61c29f..08d25beed7 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -1,4 +1,4 @@ -// Copyright 2021-2023 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::error::GatewayClientError; @@ -12,9 +12,9 @@ use crate::{cleanup_socket_message, try_decrypt_binary_message}; use futures::{SinkExt, StreamExt}; use log::*; use nym_bandwidth_controller::BandwidthController; -use nym_coconut_interface::Credential; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; +use nym_credentials::CredentialSpendingData; use nym_crypto::asymmetric::identity; use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressBytes; use nym_gateway_requests::iv::IV; @@ -23,6 +23,7 @@ use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; +use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use rand::rngs::OsRng; use std::convert::TryFrom; @@ -515,13 +516,15 @@ impl GatewayClient { async fn claim_coconut_bandwidth( &mut self, - credential: Credential, + credential: CredentialSpendingData, + epoch_id: EpochId, ) -> Result<(), GatewayClientError> { let mut rng = OsRng; let iv = IV::new_random(&mut rng); let msg = ClientControlRequest::new_enc_coconut_bandwidth_credential( - &credential, + credential, + epoch_id, self.shared_key.as_ref().unwrap(), iv, ) @@ -567,18 +570,19 @@ impl GatewayClient { return self.try_claim_testnet_bandwidth().await; } - let (credential, credential_id) = self + let prepared_credential = self .bandwidth_controller .as_ref() .unwrap() .prepare_coconut_credential() .await?; - self.claim_coconut_bandwidth(credential).await?; + self.claim_coconut_bandwidth(prepared_credential.data, prepared_credential.epoch_id) + .await?; self.bandwidth_controller .as_ref() .unwrap() - .consume_credential(credential_id) + .consume_credential(prepared_credential.credential_id) .await?; Ok(()) diff --git a/common/coconut-interface/src/lib.rs b/common/coconut-interface/src/lib.rs index 2a655a2980..4ac0706463 100644 --- a/common/coconut-interface/src/lib.rs +++ b/common/coconut-interface/src/lib.rs @@ -11,12 +11,14 @@ pub mod error; // module. pub use nym_coconut::{ aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, - prepare_blind_sign, prove_bandwidth_credential, Attribute, Base58, BlindSignRequest, - BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute, - PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, + prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, + BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, + PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, VerifyCredentialRequest, }; +// TODO: maybe just remove this sucker? +#[deprecated] #[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)] pub struct Credential { #[getset(get = "pub")] diff --git a/common/credential-storage/src/models.rs b/common/credential-storage/src/models.rs index 7a1686b3d5..47372dd2b6 100644 --- a/common/credential-storage/src/models.rs +++ b/common/credential-storage/src/models.rs @@ -1,8 +1,6 @@ // Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use sqlx::FromRow; - #[derive(Clone)] pub struct CoconutCredential { #[allow(dead_code)] @@ -16,9 +14,8 @@ pub struct CoconutCredential { pub consumed: bool, } -#[derive(FromRow)] +#[cfg_attr(not(target_arch = "wasm32"), derive(sqlx::FromRow))] pub struct StoredIssuedCredential { - #[allow(dead_code)] pub id: i64, pub serial_number: String, diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index e889fcef22..736555bfdc 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -4,8 +4,10 @@ use crate::coconut::bandwidth::freepass::FreePassIssuanceData; use crate::coconut::bandwidth::issued::IssuedBandwidthCredential; use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; -use crate::coconut::bandwidth::{bandwidth_voucher_params, CredentialSigningData, CredentialType}; -use crate::coconut::utils::{make_bincode_serializer, scalar_serde_helper}; +use crate::coconut::bandwidth::{ + bandwidth_credential_params, CredentialSigningData, CredentialType, +}; +use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use nym_coconut_interface::{ aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, @@ -89,9 +91,6 @@ impl IssuanceBandwidthCredential { pub const PRIVATE_ATTRIBUTES: u32 = 2; pub const ENCODED_ATTRIBUTES: u32 = Self::PUBLIC_ATTRIBUTES + Self::PRIVATE_ATTRIBUTES; - // just keep this value on hand for any possible future changes so that we could preserve backwards compatibility - pub const ENCODING_VERSION: u8 = 1; - pub fn default_parameters() -> Parameters { // safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap() @@ -101,7 +100,7 @@ impl IssuanceBandwidthCredential { let variant_data = variant_data.into(); let type_prehashed = hash_to_scalar(variant_data.info().to_string()); - let params = bandwidth_voucher_params(); + let params = bandwidth_credential_params(); let serial_number = params.random_scalar(); let binding_number = params.random_scalar(); @@ -151,7 +150,7 @@ impl IssuanceBandwidthCredential { } pub fn prepare_for_signing(&self) -> CredentialSigningData { - let params = bandwidth_voucher_params(); + let params = bandwidth_credential_params(); // safety: the creation of the request can only fail if one provided invalid parameters // and we created then specific to this type of the credential so the unwrap is fine @@ -166,6 +165,7 @@ impl IssuanceBandwidthCredential { pedersen_commitments_openings, blind_sign_request, public_attributes_plain: self.get_plain_public_attributes(), + typ: self.typ(), } } @@ -192,7 +192,7 @@ impl IssuanceBandwidthCredential { let public_attributes = self.get_public_attributes(); let private_attributes = self.get_private_attributes(); - let params = bandwidth_voucher_params(); + let params = bandwidth_credential_params(); let unblinded_signature = blinded_signature.unblind_and_verify( params, validator_vk, @@ -213,7 +213,7 @@ impl IssuanceBandwidthCredential { let public_attributes = self.get_public_attributes(); let private_attributes = self.get_private_attributes(); - let params = bandwidth_voucher_params(); + let params = bandwidth_credential_params(); let mut attributes = Vec::with_capacity(private_attributes.len() + public_attributes.len()); attributes.extend_from_slice(&private_attributes); @@ -240,12 +240,19 @@ impl IssuanceBandwidthCredential { pub fn to_recovery_bytes(&self) -> Vec { use bincode::Options; // safety: our data format is stable and thus the serialization should not fail - make_bincode_serializer().serialize(self).unwrap() + make_recovery_bincode_serializer().serialize(self).unwrap() } // TODO: is that actually needed? pub fn try_from_recovered_bytes(bytes: &[u8]) -> Result { use bincode::Options; - Ok(make_bincode_serializer().deserialize(bytes)?) + Ok(make_recovery_bincode_serializer().deserialize(bytes)?) } } + +fn make_recovery_bincode_serializer() -> impl bincode::Options { + use bincode::Options; + bincode::DefaultOptions::new() + .with_big_endian() + .with_varint_encoding() +} diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index e12cacb6c4..d3e8807f05 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -6,7 +6,9 @@ use crate::coconut::bandwidth::issuance::{ BandwidthCredentialIssuanceDataVariant, IssuanceBandwidthCredential, }; use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuedData; -use crate::coconut::bandwidth::{bandwidth_voucher_params, CredentialSpendingData, CredentialType}; +use crate::coconut::bandwidth::{ + bandwidth_credential_params, CredentialSpendingData, CredentialType, +}; use crate::error::Error; use nym_coconut_interface::{ prove_bandwidth_credential, Parameters, PrivateAttribute, PublicAttribute, Signature, @@ -122,7 +124,7 @@ impl IssuedBandwidthCredential { &self, verification_key: &VerificationKey, ) -> Result { - let params = bandwidth_voucher_params(); + let params = bandwidth_credential_params(); let verify_credential_request = prove_bandwidth_credential( params, @@ -133,8 +135,10 @@ impl IssuedBandwidthCredential { )?; Ok(CredentialSpendingData { + embedded_private_attributes: IssuanceBandwidthCredential::PRIVATE_ATTRIBUTES as usize, verify_credential_request, public_attributes_plain: self.get_plain_public_attributes(), + typ: self.typ(), }) } } diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 84101bc9cc..8e5a7d5631 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -2,7 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use bls12_381::Scalar; -use nym_coconut_interface::{BlindSignRequest, Parameters, VerifyCredentialRequest}; +use nym_coconut_interface::{ + hash_to_scalar, BlindSignRequest, Parameters, VerificationKey, VerifyCredentialRequest, +}; +use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::sync::OnceLock; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -19,12 +22,12 @@ pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; // works under the assumption of having 4 attributes in the underlying credential(s) -pub fn bandwidth_voucher_params() -> &'static Parameters { +pub fn bandwidth_credential_params() -> &'static Parameters { static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters) } -#[derive(Zeroize, ZeroizeOnDrop, Clone, Debug)] +#[derive(Zeroize, ZeroizeOnDrop, Clone, Debug, Serialize, Deserialize)] pub enum CredentialType { Voucher, FreePass, @@ -52,11 +55,39 @@ pub struct CredentialSigningData { pub(crate) blind_sign_request: BlindSignRequest, pub(crate) public_attributes_plain: Vec, + + pub(crate) typ: CredentialType, } -#[derive(Debug)] +#[derive(Debug, Serialize, Deserialize)] pub struct CredentialSpendingData { + pub(crate) embedded_private_attributes: usize, + pub(crate) verify_credential_request: VerifyCredentialRequest, pub(crate) public_attributes_plain: Vec, + + pub(crate) typ: CredentialType, +} + +impl CredentialSpendingData { + pub fn verify(&self, verification_key: &VerificationKey) -> bool { + let params = bandwidth_credential_params(); + + let hashed_public_attributes = self + .public_attributes_plain + .iter() + .map(hash_to_scalar) + .collect::>(); + + // get references to the attributes + let public_attributes = hashed_public_attributes.iter().collect::>(); + + nym_coconut_interface::verify_credential( + params, + verification_key, + &self.verify_credential_request, + &public_attributes, + ) + } } diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index 08379c9017..a2014d8c1a 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -95,10 +95,3 @@ pub(crate) mod scalar_serde_helper { )) } } - -pub(crate) fn make_bincode_serializer() -> impl bincode::Options { - use bincode::Options; - bincode::DefaultOptions::new() - .with_big_endian() - .with_varint_encoding() -} diff --git a/common/credentials/src/lib.rs b/common/credentials/src/lib.rs index 4f923ae059..caa16ee410 100644 --- a/common/credentials/src/lib.rs +++ b/common/credentials/src/lib.rs @@ -4,4 +4,8 @@ pub mod coconut; pub mod error; +pub use coconut::bandwidth::{ + CredentialSigningData, CredentialSpendingData, IssuanceBandwidthCredential, + IssuedBandwidthCredential, +}; pub use coconut::utils::{obtain_aggregate_signature, obtain_aggregate_verification_key}; diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index a2404d6c4b..9bc55978d9 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -9,6 +9,7 @@ pub use types::*; pub mod authentication; pub mod iv; +mod models; pub mod registration; pub mod types; diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs new file mode 100644 index 0000000000..1f155e7711 --- /dev/null +++ b/gateway/gateway-requests/src/models.rs @@ -0,0 +1,30 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::GatewayRequestsError; +use nym_credentials::coconut::bandwidth::CredentialSpendingData; +use serde::{Deserialize, Serialize}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct CredentialSpendingWithEpoch { + /// The cryptographic material required for spending the underlying credential. + pub data: CredentialSpendingData, + + /// The (DKG) epoch id under which the credential has been issued so that the verifier + /// could use correct verification key for validation. + pub epoch_id: u64, +} + +impl CredentialSpendingWithEpoch { + pub fn new(data: CredentialSpendingData, epoch_id: u64) -> Self { + CredentialSpendingWithEpoch { data, epoch_id } + } + + pub fn to_bytes(&self) -> Vec { + todo!() + } + + pub fn try_from_bytes(raw: &[u8]) -> Result { + todo!() + } +} diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 3683144980..0c5542464e 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -3,10 +3,11 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; +use crate::models::CredentialSpendingWithEpoch; use crate::registration::handshake::SharedKeys; use crate::{GatewayMacSize, PROTOCOL_VERSION}; use log::error; -use nym_coconut_interface::Credential; +use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_crypto::generic_array::typenum::Unsigned; use nym_crypto::hmac::recompute_keyed_hmac_and_verify_tag; use nym_crypto::symmetric::stream_cipher; @@ -16,10 +17,8 @@ use nym_sphinx::params::packet_sizes::PacketSize; use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorithm}; use nym_sphinx::DestinationAddressBytes; use serde::{Deserialize, Serialize}; -use std::{ - convert::{TryFrom, TryInto}, - fmt::{self, Error, Formatter}, -}; +use std::convert::{TryFrom, TryInto}; +use thiserror::Error; use tungstenite::protocol::Message; #[derive(Serialize, Deserialize, Debug)] @@ -66,53 +65,43 @@ impl TryInto for RegistrationHandshake { } } -#[derive(Debug)] +#[derive(Debug, Error)] pub enum GatewayRequestsError { + #[error("the request is too short")] TooShortRequest, + + #[error("provided MAC is invalid")] InvalidMac, - IncorrectlyEncodedAddress, + + #[error("address field was incorrectly encoded: {source}")] + IncorrectlyEncodedAddress { + #[from] + source: NymNodeRoutingAddressError, + }, + + #[error("received request had invalid size. (actual: {0}, but expected one of: {} (ACK), {} (REGULAR), {}, {}, {} (EXTENDED))", + PacketSize::AckPacket.size(), + PacketSize::RegularPacket.size(), + PacketSize::ExtendedPacket8.size(), + PacketSize::ExtendedPacket16.size(), + PacketSize::ExtendedPacket32.size()) + ] RequestOfInvalidSize(usize), + + #[error("received sphinx packet was malformed")] MalformedSphinxPacket, + + #[error("the received encrypted data was malformed")] MalformedEncryption, + + #[error("provided packet mode is invalid")] InvalidPacketMode, - InvalidMixPacket(MixPacketFormattingError), -} -impl fmt::Display for GatewayRequestsError { - fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> { - use GatewayRequestsError::*; - match self { - TooShortRequest => write!(f, "the request is too short"), - InvalidMac => write!(f, "provided MAC is invalid"), - IncorrectlyEncodedAddress => write!(f, "address field was incorrectly encoded"), - RequestOfInvalidSize(actual) => - write!( - f, - "received request had invalid size. (actual: {}, but expected one of: {} (ACK), {} (REGULAR), {}, {}, {} (EXTENDED))", - actual, PacketSize::AckPacket.size(), PacketSize::RegularPacket.size(), - PacketSize::ExtendedPacket8.size(), PacketSize::ExtendedPacket16.size(), - PacketSize::ExtendedPacket32.size() - ), - MalformedSphinxPacket => write!(f, "received sphinx packet was malformed"), - MalformedEncryption => write!(f, "the received encrypted data was malformed"), - InvalidPacketMode => write!(f, "provided packet mode is invalid"), - InvalidMixPacket(err) => write!(f, "provided mix packet was malformed - {err}") - } - } -} - -impl std::error::Error for GatewayRequestsError {} - -impl From for GatewayRequestsError { - fn from(_: NymNodeRoutingAddressError) -> Self { - GatewayRequestsError::IncorrectlyEncodedAddress - } -} - -impl From for GatewayRequestsError { - fn from(err: MixPacketFormattingError) -> Self { - GatewayRequestsError::InvalidMixPacket(err) - } + #[error("provided mix packet was malformed: {source}")] + InvalidMixPacket { + #[from] + source: MixPacketFormattingError, + }, } #[derive(Serialize, Deserialize, Debug)] @@ -155,11 +144,13 @@ impl ClientControlRequest { } pub fn new_enc_coconut_bandwidth_credential( - credential: &Credential, + credential: CredentialSpendingData, + epoch_id: u64, shared_key: &SharedKeys, iv: IV, ) -> Self { - let serialized_credential = credential.as_bytes(); + let cred = CredentialSpendingWithEpoch::new(credential, epoch_id); + let serialized_credential = cred.to_bytes(); let enc_credential = shared_key.encrypt_and_tag(&serialized_credential, Some(iv.inner())); ClientControlRequest::BandwidthCredential { @@ -172,9 +163,9 @@ impl ClientControlRequest { enc_credential: Vec, shared_key: &SharedKeys, iv: IV, - ) -> Result { + ) -> Result { let credential_bytes = shared_key.decrypt_tagged(&enc_credential, Some(iv.inner()))?; - Credential::from_bytes(&credential_bytes) + CredentialSpendingWithEpoch::try_from_bytes(&credential_bytes) .map_err(|_| GatewayRequestsError::MalformedEncryption) } } diff --git a/nym-api/src/coconut/dkg/key_derivation.rs b/nym-api/src/coconut/dkg/key_derivation.rs index ca85716d13..db86ec39a5 100644 --- a/nym-api/src/coconut/dkg/key_derivation.rs +++ b/nym-api/src/coconut/dkg/key_derivation.rs @@ -7,7 +7,7 @@ use crate::coconut::dkg::controller::DkgController; use crate::coconut::dkg::state::key_derivation::{DealerRejectionReason, DerivationFailure}; use crate::coconut::error::CoconutError; use crate::coconut::keys::KeyPairWithEpoch; -use crate::coconut::state::bandwidth_voucher_params; +use crate::coconut::state::bandwidth_credential_params; use cosmwasm_std::Addr; use log::debug; use nym_coconut::{check_vk_pairing, Base58, SecretKey, VerificationKey}; @@ -425,7 +425,7 @@ impl DkgController { // we know we had a non-empty map of dealings and thus, at the very least, we must have derived a single secret // (i.e. the x-element) let sk = SecretKey::create_from_raw(derived_x.unwrap(), derived_secrets); - let derived_vk = sk.verification_key(bandwidth_voucher_params()); + let derived_vk = sk.verification_key(bandwidth_credential_params()); // make the key we derived out of the decrypted shares matches the partial key // (cryptographically there shouldn't be any reason for the mismatch, @@ -436,7 +436,7 @@ impl DkgController { .derived_partials_for(receiver_index) .ok_or(KeyDerivationError::NoSelfPartialKey { receiver_index })?; - if !check_vk_pairing(bandwidth_voucher_params(), &derived_partial, &derived_vk) { + if !check_vk_pairing(bandwidth_credential_params(), &derived_partial, &derived_vk) { // can't do anything, we got all dealings, we derived all keys, but somehow they don't match error!("our derived key does not match the expected partials!"); return Ok(Err(DerivationFailure::MismatchedPartialKey)); diff --git a/nym-api/src/coconut/dkg/key_validation.rs b/nym-api/src/coconut/dkg/key_validation.rs index a957db8f23..68068d30b6 100644 --- a/nym-api/src/coconut/dkg/key_validation.rs +++ b/nym-api/src/coconut/dkg/key_validation.rs @@ -3,7 +3,7 @@ use crate::coconut::dkg::controller::DkgController; use crate::coconut::error::CoconutError; -use crate::coconut::state::bandwidth_voucher_params; +use crate::coconut::state::bandwidth_credential_params; use cosmwasm_std::Addr; use cw3::Vote; use nym_coconut::{check_vk_pairing, Base58, VerificationKey}; @@ -119,7 +119,7 @@ impl DkgController { }); }; - if !check_vk_pairing(bandwidth_voucher_params(), &self_derived, &recovered_key) { + if !check_vk_pairing(bandwidth_credential_params(), &self_derived, &recovered_key) { return reject(ShareRejectionReason::InconsistentKeys { epoch_id, owner, diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index 150ace1864..e5778674e6 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::coconut::error::CoconutError; -use crate::coconut::state::bandwidth_voucher_params; +use crate::coconut::state::bandwidth_credential_params; use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut::{BlindedSignature, SecretKey}; use nym_validator_client::nyxd::error::NyxdError::AbciError; @@ -29,7 +29,7 @@ pub(crate) fn blind_sign( let attributes_ref = public_attributes.iter().collect::>(); Ok(nym_coconut_interface::blind_sign( - bandwidth_voucher_params(), + bandwidth_credential_params(), signing_key, &request.inner_sign_request, &attributes_ref, diff --git a/nym-api/src/coconut/keys/persistence.rs b/nym-api/src/coconut/keys/persistence.rs index b3c9c330ce..4a67876036 100644 --- a/nym-api/src/coconut/keys/persistence.rs +++ b/nym-api/src/coconut/keys/persistence.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::coconut::keys::KeyPairWithEpoch; -use crate::coconut::state::bandwidth_voucher_params; +use crate::coconut::state::bandwidth_credential_params; use nym_coconut::{CoconutError, KeyPair, SecretKey}; use nym_coconut_dkg_common::types::EpochId; use nym_pemstore::traits::PemStorableKey; @@ -33,7 +33,7 @@ impl PemStorableKey for KeyPairWithEpoch { ]); let sk = SecretKey::from_bytes(&bytes[mem::size_of::()..])?; - let vk = sk.verification_key(bandwidth_voucher_params()); + let vk = sk.verification_key(bandwidth_credential_params()); Ok(KeyPairWithEpoch { keys: KeyPair::from_keys(sk, vk), diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index 72fad9b27d..6bf4159c2e 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -16,7 +16,7 @@ use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::{Hash, TxResponse}; use std::sync::Arc; -pub use nym_credentials::coconut::bandwidth::bandwidth_voucher_params; +pub use nym_credentials::coconut::bandwidth::bandwidth_credential_params; pub struct State { pub(crate) client: Arc, diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 9083541347..a745917381 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3708,6 +3708,7 @@ name = "nym-bandwidth-controller" version = "0.1.0" dependencies = [ "bip39", + "log", "nym-coconut-interface", "nym-credential-storage", "nym-credentials", @@ -3930,6 +3931,7 @@ dependencies = [ name = "nym-credentials" version = "0.1.0" dependencies = [ + "bincode", "bls12_381", "cosmrs", "log", @@ -4040,8 +4042,8 @@ dependencies = [ "gloo-utils", "log", "nym-bandwidth-controller", - "nym-coconut-interface", "nym-credential-storage", + "nym-credentials", "nym-crypto", "nym-gateway-requests", "nym-network-defaults", diff --git a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs index 251489b3b5..6a02ca52a5 100644 --- a/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs +++ b/nym-validator-rewarder/src/rewarder/credential_issuance/monitor.rs @@ -14,7 +14,7 @@ use nym_coconut::{ hash_to_scalar, verify_partial_blind_signature, Base58, G1Projective, VerificationKey, }; use nym_coconut_dkg_common::types::EpochId; -use nym_credentials::coconut::bandwidth::bandwidth_voucher_params; +use nym_credentials::coconut::bandwidth::bandwidth_credential_params; use nym_task::TaskClient; use nym_validator_client::nym_api::{IssuedCredential, IssuedCredentialBody, NymApiClientExt}; use nym_validator_client::nyxd::Hash; @@ -154,7 +154,7 @@ impl CredentialIssuanceMonitor { // actually do verify the credential now if !verify_partial_blind_signature( - bandwidth_voucher_params(), + bandwidth_credential_params(), &public_attribute_commitments, &attributes_refs, &credential.blinded_partial_credential, From 9a0cbf507299362c3e610f0ad9ffb3a413e4313b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 7 Feb 2024 16:06:13 +0000 Subject: [PATCH 052/394] wip in removing the Credential type for more strongly typed alternative --- common/bandwidth-controller/src/lib.rs | 2 +- .../client-libs/gateway-client/src/client.rs | 2 +- common/coconut-interface/Cargo.toml | 2 +- common/credential-utils/Cargo.toml | 1 + common/credentials/Cargo.toml | 4 +- .../credentials/src/coconut/bandwidth/mod.rs | 39 ++++++++--- common/credentials/src/coconut/credential.rs | 6 +- gateway/gateway-requests/src/lib.rs | 2 +- gateway/gateway-requests/src/models.rs | 18 +++++ gateway/src/node/client_handling/bandwidth.rs | 38 +++++++++- gateway/src/node/client_handling/mod.rs | 6 +- .../connection_handler/authenticated.rs | 69 ++++++++++++------- .../websocket/connection_handler/coconut.rs | 36 ++++++---- nym-api/nym-api-requests/Cargo.toml | 2 + .../nym-api-requests/src/coconut/models.rs | 27 +++++--- nym-connect/desktop/Cargo.lock | 1 + nym-wallet/Cargo.lock | 1 + 17 files changed, 186 insertions(+), 70 deletions(-) diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index d6f5dfb731..6d78bd7401 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -56,7 +56,7 @@ impl BandwidthController { Ok(obtain_aggregate_verification_key(&coconut_api_clients).await?) } - pub async fn prepare_coconut_credential( + pub async fn prepare_bandwidth_credential( &self, ) -> Result where diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 08d25beed7..b1ebb23fa4 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -574,7 +574,7 @@ impl GatewayClient { .bandwidth_controller .as_ref() .unwrap() - .prepare_coconut_credential() + .prepare_bandwidth_credential() .await?; self.claim_coconut_bandwidth(prepared_credential.data, prepared_credential.epoch_id) diff --git a/common/coconut-interface/Cargo.toml b/common/coconut-interface/Cargo.toml index dc81f4847f..a85115d95f 100644 --- a/common/coconut-interface/Cargo.toml +++ b/common/coconut-interface/Cargo.toml @@ -11,4 +11,4 @@ getset = "0.1.1" serde = { workspace = true, features = ["derive"] } thiserror = { workspace = true } -nym-coconut = {path = "../nymcoconut" } +nym-coconut = { path = "../nymcoconut" } diff --git a/common/credential-utils/Cargo.toml b/common/credential-utils/Cargo.toml index 1b5ebfd5bd..232c9cdb1f 100644 --- a/common/credential-utils/Cargo.toml +++ b/common/credential-utils/Cargo.toml @@ -12,6 +12,7 @@ thiserror = { workspace = true } tokio = { workspace = true } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } +nym-coconut = { path = "../nymcoconut" } nym-credentials = { path = "../../common/credentials" } nym-credential-storage = { path = "../../common/credential-storage" } nym-validator-client = { path = "../../common/client-libs/validator-client" } diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index f08a3a5cd5..55894c3754 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -17,10 +17,10 @@ zeroize = { workspace = true } # I guess temporarily until we get serde support in coconut up and running nym-coconut-interface = { path = "../coconut-interface" } -nym-crypto = { path = "../crypto", features = ["rand", "asymmetric"] } +nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "serde"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } -serde = { version = "1.0.189", features = ["derive"] } +serde = { workspace = true, features = ["derive"] } [dev-dependencies] rand = "0.7.3" diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 8e5a7d5631..8fe23a444b 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -27,7 +27,7 @@ pub fn bandwidth_credential_params() -> &'static Parameters { BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters) } -#[derive(Zeroize, ZeroizeOnDrop, Clone, Debug, Serialize, Deserialize)] +#[derive(Zeroize, Copy, Clone, Debug, Serialize, Deserialize)] pub enum CredentialType { Voucher, FreePass, @@ -37,6 +37,10 @@ impl CredentialType { pub fn is_free_pass(&self) -> bool { matches!(self, CredentialType::FreePass) } + + pub fn is_voucher(&self) -> bool { + matches!(self, CredentialType::Voucher) + } } impl Display for CredentialType { @@ -50,24 +54,24 @@ impl Display for CredentialType { #[derive(Debug, Clone)] pub struct CredentialSigningData { - pub(crate) pedersen_commitments_openings: Vec, + pub pedersen_commitments_openings: Vec, - pub(crate) blind_sign_request: BlindSignRequest, + pub blind_sign_request: BlindSignRequest, - pub(crate) public_attributes_plain: Vec, + pub public_attributes_plain: Vec, - pub(crate) typ: CredentialType, + pub typ: CredentialType, } #[derive(Debug, Serialize, Deserialize)] pub struct CredentialSpendingData { - pub(crate) embedded_private_attributes: usize, + pub embedded_private_attributes: usize, - pub(crate) verify_credential_request: VerifyCredentialRequest, + pub verify_credential_request: VerifyCredentialRequest, - pub(crate) public_attributes_plain: Vec, + pub public_attributes_plain: Vec, - pub(crate) typ: CredentialType, + pub typ: CredentialType, } impl CredentialSpendingData { @@ -90,4 +94,21 @@ impl CredentialSpendingData { &public_attributes, ) } + + pub fn validate_type_attribute(&self) -> bool { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + let Some(type_plain) = self.public_attributes_plain.get(1) else { + return false; + }; + + match self.typ { + CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE, + CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE, + } + } + + pub fn get_bandwidth_attribute(&self) -> Option<&String> { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + self.public_attributes_plain.first() + } } diff --git a/common/credentials/src/coconut/credential.rs b/common/credentials/src/coconut/credential.rs index 6863200e17..446682a398 100644 --- a/common/credentials/src/coconut/credential.rs +++ b/common/credentials/src/coconut/credential.rs @@ -2,9 +2,5 @@ // SPDX-License-Identifier: Apache-2.0 pub trait NymCredential { - fn prove_credential(&self); - - // pub attr - // hashed - // private + fn prove_credential(&self) -> Result<(), ()>; } diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index 9bc55978d9..9bb25dc45c 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -9,7 +9,7 @@ pub use types::*; pub mod authentication; pub mod iv; -mod models; +pub mod models; pub mod registration; pub mod types; diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 1f155e7711..43881d3ceb 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::GatewayRequestsError; +use nym_coconut_interface::CoconutError; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use serde::{Deserialize, Serialize}; @@ -20,6 +21,23 @@ impl CredentialSpendingWithEpoch { CredentialSpendingWithEpoch { data, epoch_id } } + pub fn matches_blinded_serial_number( + &self, + blinded_serial_number_bs58: &str, + ) -> Result { + self.data + .verify_credential_request + .has_blinded_serial_number(blinded_serial_number_bs58) + } + + pub fn unchecked_voucher_value(&self) -> u64 { + self.data + .get_bandwidth_attribute() + .expect("failed to extract bandwidth attribute") + .parse() + .expect("failed to parse voucher value") + } + pub fn to_bytes(&self) -> Vec { todo!() } diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index e1b4d831e0..d5ea02b2d2 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -1,13 +1,49 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use log::error; use nym_coconut_interface::Credential; +use nym_credentials::coconut::bandwidth::CredentialType; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum BandwidthError {} pub struct Bandwidth { value: u64, } impl Bandwidth { + pub const fn new(value: u64) -> Bandwidth { + Bandwidth { value } + } + + pub fn try_from_raw_value(value: &String, typ: CredentialType) -> Result { + // let bandwidth_value = match credential.data.typ { + // CredentialType::Voucher => { + // todo!() + // } + // CredentialType::FreePass => { + // error!("unimplemented handling of free pass credential"); + // return Err(()); + // } + // }; + + /* + if bandwidth_value > i64::MAX as u64 { + // note that this would have represented more than 1 exabyte, + // which is like 125,000 worth of hard drives so I don't think we have + // to worry about it for now... + warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now"); + return Err(RequestHandlingError::UnsupportedBandwidthValue( + bandwidth_value, + )); + } + */ + + todo!() + } + pub fn value(&self) -> u64 { self.value } diff --git a/gateway/src/node/client_handling/mod.rs b/gateway/src/node/client_handling/mod.rs index ff4691e256..ae26cc558d 100644 --- a/gateway/src/node/client_handling/mod.rs +++ b/gateway/src/node/client_handling/mod.rs @@ -1,9 +1,11 @@ -// Copyright 2020 - Nym Technologies SA +// Copyright 2020-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use crate::node::client_handling::bandwidth::Bandwidth; + pub(crate) mod active_clients; mod bandwidth; pub(crate) mod embedded_network_requester; pub(crate) mod websocket; -pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: i64 = 64 * 1024 * 1024 * 1024; // 64GB +pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = Bandwidth::new(64 * 1024 * 1024 * 1024); // 64GB diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index b97bae206f..548037e9d3 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -19,8 +19,11 @@ use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; +use nym_coconut_interface::CoconutError; +use nym_credentials::coconut::bandwidth::CredentialType; use std::{convert::TryFrom, process, time::Duration}; +use crate::node::client_handling::bandwidth::BandwidthError; use crate::node::{ client_handling::{ bandwidth::Bandwidth, @@ -76,11 +79,20 @@ pub(crate) enum RequestHandlingError { #[error("Coconut interface error - {0}")] CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), + #[error("coconut failure: {0}")] + CoconutError(#[from] CoconutError), + #[error("coconut api query failure: {0}")] CoconutApiError(#[from] CoconutApiError), #[error("Credential error - {0}")] CredentialError(#[from] nym_credentials::error::Error), + + #[error("failed to recover bandwidth value: {0}")] + BandwidthRecoveryFailure(#[from] BandwidthError), + + #[error("free pass credentials haven't been implemented yet")] + UnimplementedFreePass, } impl RequestHandlingError { @@ -177,10 +189,10 @@ where /// # Arguments /// /// * `amount`: amount to increase the available bandwidth by. - async fn increase_bandwidth(&self, amount: i64) -> Result<(), RequestHandlingError> { + async fn increase_bandwidth(&self, bandwidth: Bandwidth) -> Result<(), RequestHandlingError> { self.inner .storage - .increase_bandwidth(self.client.address, amount) + .increase_bandwidth(self.client.address, bandwidth.value() as i64) .await?; Ok(()) } @@ -232,40 +244,45 @@ where let aggregated_verification_key = self .inner .coconut_verifier - .verification_key(*credential.epoch_id()) + .verification_key(credential.epoch_id) .await?; - if !credential.verify(&aggregated_verification_key) { + if !credential.data.validate_type_attribute() { + unimplemented!() + } + + let Some(bandwidth_attribute) = credential.data.get_bandwidth_attribute() else { + unimplemented!() + }; + + let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; + + if !credential.data.verify(&aggregated_verification_key) { return Err(RequestHandlingError::InvalidBandwidthCredential( String::from("credential failed to verify on gateway"), )); } - let api_clients = self - .inner - .coconut_verifier - .api_clients(*credential.epoch_id()) - .await?; + match credential.data.typ { + CredentialType::Voucher => { + let api_clients = self + .inner + .coconut_verifier + .api_clients(credential.epoch_id) + .await?; - self.inner - .coconut_verifier - .release_funds(&api_clients, &credential) - .await?; - - let bandwidth = Bandwidth::from(credential); - let bandwidth_value = bandwidth.value(); - - if bandwidth_value > i64::MAX as u64 { - // note that this would have represented more than 1 exabyte, - // which is like 125,000 worth of hard drives so I don't think we have - // to worry about it for now... - warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now"); - return Err(RequestHandlingError::UnsupportedBandwidthValue( - bandwidth_value, - )); + self.inner + .coconut_verifier + .release_bandwidth_voucher_funds(&api_clients, credential) + .await?; + } + CredentialType::FreePass => { + error!("unimplemented handling of free pass credential"); + return Err(RequestHandlingError::UnimplementedFreePass); + } } - self.increase_bandwidth(bandwidth_value as i64).await?; + self.increase_bandwidth(bandwidth).await?; let available_total = self.get_available_bandwidth().await?; Ok(ServerResponse::Bandwidth { available_total }) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index 89711d31e7..e62d6afa5a 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -4,6 +4,7 @@ use super::authenticated::RequestHandlingError; use log::*; use nym_coconut_interface::{Credential, VerificationKey}; +use nym_gateway_requests::models::CredentialSpendingWithEpoch; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::{MultisigQueryClient, NymContractsProvider}; @@ -176,21 +177,31 @@ impl CoconutVerifier { Ok(all_coconut_api_clients(self.nyxd_client.read().await.deref(), epoch_id).await?) } - pub async fn release_funds( + pub async fn release_bandwidth_voucher_funds( &self, api_clients: &[CoconutApiClient], - credential: &Credential, + credential: CredentialSpendingWithEpoch, ) -> Result<(), RequestHandlingError> { + if !credential.data.typ.is_voucher() { + unimplemented!() + } + + // safety: the voucher funds are released after the credential has already been verified locally + // and the underlying bandwidth value has been extracted, so the below MUST succeed + let voucher_amount = credential.unchecked_voucher_value() as u128; + + let blinded_serial_number = credential + .data + .verify_credential_request + .blinded_serial_number_bs58(); + let res = self .nyxd_client .write() .await .spend_credential( - Coin::new( - credential.voucher_value().into(), - self.mix_denom_base.clone(), - ), - credential.blinded_serial_number(), + Coin::new(voucher_amount, &self.mix_denom_base), + blinded_serial_number, self.address.to_string(), None, ) @@ -211,27 +222,28 @@ impl CoconutVerifier { .await .query_proposal(proposal_id) .await?; - if !credential.has_blinded_serial_number(&proposal.description)? { + if !credential.matches_blinded_serial_number(&proposal.description)? { return Err(RequestHandlingError::ProposalIdError { reason: String::from("proposal has different serial number"), }); } let req = nym_api_requests::coconut::VerifyCredentialBody::new( - credential.clone(), + credential, proposal_id, self.address.clone(), ); for client in api_clients { let ret = client.api_client.verify_bandwidth_credential(&req).await; + let client_url = client.api_client.nym_api.current_url(); match ret { Ok(res) => { if !res.verification_result { - debug!("Validator {} didn't accept the credential. It will probably vote No on the spending proposal", client.api_client.nym_api.current_url()); + warn!("Validator at {client_url} didn't accept the credential. It will probably vote No on the spending proposal"); } } - Err(e) => { - warn!("Validator {} could not be reached. There might be a problem with the coconut endpoint - {:?}", client.api_client.nym_api.current_url(), e); + Err(err) => { + warn!("Validator at {client_url} could not be reached. There might be a problem with the coconut endpoint: {err}"); } } } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index 1befc394cf..aaf7309fcf 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -16,7 +16,9 @@ serde = { workspace = true, features = ["derive"] } ts-rs = { workspace = true, optional = true } tendermint = { workspace = true } +nym-coconut = { path = "../../common/nymcoconut" } nym-coconut-interface = { path = "../../common/coconut-interface" } +#nym-credentials = { path = "../../common/credentials" } nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]} nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" } diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index aa6e82ef00..15efe1a9f6 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -1,11 +1,11 @@ -// Copyright 2023 - Nym Technologies SA +// Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::coconut::helpers::issued_credential_plaintext; use cosmrs::AccountId; -use nym_coconut_interface::{ - error::CoconutInterfaceError, hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, - Bytable, Credential, VerificationKey, +use nym_coconut::{ + hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, Bytable, CoconutError, + Signature, VerificationKey, }; use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; @@ -14,21 +14,30 @@ use tendermint::hash::Hash; #[derive(Serialize, Deserialize)] pub struct VerifyCredentialBody { - pub credential: Credential, + /// The cryptographic material required for spending the underlying credential. + pub credential_data: (), + /// The (DKG) epoch id under which the credential has been issued so that the verifier + /// could use correct verification key for validation. + pub epoch_id: u64, + + /// Multisig proposal for releasing funds for the provided bandwidth credential pub proposal_id: u64, + /// Cosmos address of the spender of the credential pub gateway_cosmos_addr: AccountId, } impl VerifyCredentialBody { pub fn new( - credential: Credential, + credential_data: (), + epoch_id: u64, proposal_id: u64, gateway_cosmos_addr: AccountId, ) -> VerifyCredentialBody { VerifyCredentialBody { - credential, + credential_data, + epoch_id, proposal_id, gateway_cosmos_addr, } @@ -115,7 +124,7 @@ impl BlindedSignatureResponse { bs58::encode(&self.to_bytes()).into_string() } - pub fn from_base58_string>(val: I) -> Result { + pub fn from_base58_string>(val: I) -> Result { let bytes = bs58::decode(val).into_vec()?; Self::from_bytes(&bytes) } @@ -124,7 +133,7 @@ impl BlindedSignatureResponse { self.blinded_signature.to_byte_vec() } - pub fn from_bytes(bytes: &[u8]) -> Result { + pub fn from_bytes(bytes: &[u8]) -> Result { Ok(BlindedSignatureResponse { blinded_signature: BlindedSignature::from_bytes(bytes)?, }) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index a745917381..555390c706 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3694,6 +3694,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "getset", + "nym-coconut", "nym-coconut-interface", "nym-crypto", "nym-mixnet-contract-common", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index a197456fb9..b5dfb64b97 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3098,6 +3098,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", + "nym-coconut", "nym-coconut-interface", "nym-crypto", "nym-mixnet-contract-common", From 675cf3d7daa7fbf966974803ae78a293d1abca00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 7 Feb 2024 17:01:30 +0000 Subject: [PATCH 053/394] removed usage of coconut-interface crate --- Cargo.lock | 38 ++-- Cargo.toml | 2 +- clients/native/Cargo.toml | 1 - clients/socks5/Cargo.toml | 1 - common/bandwidth-controller/Cargo.toml | 3 +- .../bandwidth-controller/src/acquire/mod.rs | 8 +- common/bandwidth-controller/src/error.rs | 2 +- common/bandwidth-controller/src/lib.rs | 2 +- .../client-libs/validator-client/Cargo.toml | 2 +- .../validator-client/src/coconut/mod.rs | 2 +- .../validator-client/src/nyxd/error.rs | 3 - common/coconut-interface/Cargo.toml | 14 -- common/coconut-interface/src/error.rs | 17 -- common/coconut-interface/src/lib.rs | 199 ------------------ common/credentials-interface/Cargo.toml | 17 ++ common/credentials-interface/src/lib.rs | 109 ++++++++++ common/credentials/Cargo.toml | 2 +- .../src/coconut/bandwidth/freepass.rs | 2 +- .../src/coconut/bandwidth/issuance.rs | 2 +- .../src/coconut/bandwidth/issued.rs | 2 +- .../credentials/src/coconut/bandwidth/mod.rs | 99 +-------- .../src/coconut/bandwidth/voucher.rs | 2 +- common/credentials/src/coconut/credential.rs | 6 - common/credentials/src/coconut/mod.rs | 1 - common/credentials/src/coconut/utils.rs | 2 +- common/credentials/src/error.rs | 2 +- common/types/Cargo.toml | 1 - gateway/Cargo.toml | 2 +- gateway/gateway-requests/Cargo.toml | 2 +- gateway/gateway-requests/src/models.rs | 2 +- gateway/src/node/client_handling/bandwidth.rs | 19 +- .../connection_handler/authenticated.rs | 48 ++--- .../websocket/connection_handler/coconut.rs | 5 +- nym-api/Cargo.toml | 1 - nym-api/nym-api-requests/Cargo.toml | 4 +- .../nym-api-requests/src/coconut/helpers.rs | 2 +- .../nym-api-requests/src/coconut/models.rs | 10 +- nym-api/src/coconut/api_routes/mod.rs | 35 +-- nym-api/src/coconut/comm.rs | 2 +- nym-api/src/coconut/dkg/key_derivation.rs | 2 +- nym-api/src/coconut/error.rs | 3 - nym-api/src/coconut/helpers.rs | 2 +- nym-api/src/coconut/keys/mod.rs | 4 +- nym-api/src/coconut/state.rs | 2 +- nym-connect/desktop/Cargo.lock | 32 ++- nym-wallet/Cargo.lock | 27 +-- nym-wallet/src-tauri/Cargo.toml | 1 - 47 files changed, 260 insertions(+), 486 deletions(-) delete mode 100644 common/coconut-interface/Cargo.toml delete mode 100644 common/coconut-interface/src/error.rs delete mode 100644 common/coconut-interface/src/lib.rs create mode 100644 common/credentials-interface/Cargo.toml create mode 100644 common/credentials-interface/src/lib.rs delete mode 100644 common/credentials/src/coconut/credential.rs diff --git a/Cargo.lock b/Cargo.lock index 468a7c6790..eb1d3f96cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4945,7 +4945,6 @@ dependencies = [ "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-credential-storage", @@ -5000,7 +4999,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -5016,9 +5015,10 @@ version = "0.1.0" dependencies = [ "bip39", "log", - "nym-coconut-interface", + "nym-coconut", "nym-credential-storage", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -5156,7 +5156,6 @@ dependencies = [ "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5309,17 +5308,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -5364,6 +5352,7 @@ dependencies = [ "log", "nym-bandwidth-controller", "nym-client-core", + "nym-coconut", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5381,7 +5370,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", "nym-api-requests", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-validator-client", "rand 0.7.3", @@ -5391,6 +5380,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -5518,9 +5516,9 @@ dependencies = [ "log", "nym-api-requests", "nym-bin-common", - "nym-coconut-interface", "nym-config", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-gateway-requests", "nym-ip-packet-router", @@ -5594,8 +5592,8 @@ dependencies = [ "futures", "generic-array 0.14.7", "log", - "nym-coconut-interface", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -6138,7 +6136,6 @@ dependencies = [ "log", "nym-bin-common", "nym-client-core", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -6484,7 +6481,6 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", - "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -6526,9 +6522,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", diff --git a/Cargo.toml b/Cargo.toml index 305be5b37b..c92723a54c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,7 +27,6 @@ members = [ "common/client-libs/gateway-client", "common/client-libs/mixnet-client", "common/client-libs/validator-client", - "common/coconut-interface", "common/commands", "common/config", "common/cosmwasm-smart-contracts/coconut-bandwidth-contract", @@ -43,6 +42,7 @@ members = [ "common/credential-storage", "common/credentials", "common/credential-utils", + "common/credentials-interface", "common/crypto", "common/dkg", "common/execute", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 0c5d4b5fd1..076b7128c8 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -38,7 +38,6 @@ tokio-tungstenite = { workspace = true } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-config = { path = "../../common/config" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credentials = { path = "../../common/credentials" } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 72a94c4c2d..89edffb4fc 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -23,7 +23,6 @@ url = { workspace = true } # internal nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-config = { path = "../../common/config" } nym-credentials = { path = "../../common/credentials" } nym-crypto = { path = "../../common/crypto" } diff --git a/common/bandwidth-controller/Cargo.toml b/common/bandwidth-controller/Cargo.toml index 116f8d20c4..284ccbfc77 100644 --- a/common/bandwidth-controller/Cargo.toml +++ b/common/bandwidth-controller/Cargo.toml @@ -14,9 +14,10 @@ thiserror = { workspace = true } url = { workspace = true } zeroize = { workspace = true } -nym-coconut-interface = { path = "../coconut-interface" } +nym-coconut = { path = "../nymcoconut" } nym-credential-storage = { path = "../credential-storage" } nym-credentials = { path = "../credentials" } +nym-credentials-interface = { path = "../credentials-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "symmetric", "aes", "hashing"] } nym-network-defaults = { path = "../network-defaults" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 9bf1f371a3..5b842fc775 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use nym_coconut_interface::Base58; +use nym_coconut::Base58; use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::{IssuanceBandwidthCredential, VOUCHER_INFO_TYPE}; +use nym_credentials::coconut::bandwidth::{CredentialType, IssuanceBandwidthCredential}; use nym_credentials::coconut::utils::obtain_aggregate_signature; use nym_crypto::asymmetric::{encryption, identity}; use nym_validator_client::coconut::all_coconut_api_clients; @@ -27,7 +27,7 @@ where let tx_hash = client .deposit( amount.clone(), - VOUCHER_INFO_TYPE.to_string(), + CredentialType::Voucher.to_string(), signing_key.public_key().to_base58_string(), encryption_key.public_key().to_base58_string(), None, @@ -73,7 +73,7 @@ where storage .insert_coconut_credential( voucher_value, - VOUCHER_INFO_TYPE.to_string(), + CredentialType::Voucher.to_string(), state.voucher.get_private_attributes()[0].to_bs58(), state.voucher.get_private_attributes()[1].to_bs58(), signature.to_bs58(), diff --git a/common/bandwidth-controller/src/error.rs b/common/bandwidth-controller/src/error.rs index 5f464c82e5..7b4e787cb5 100644 --- a/common/bandwidth-controller/src/error.rs +++ b/common/bandwidth-controller/src/error.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::CoconutError; +use nym_coconut::CoconutError; use nym_credential_storage::error::StorageError; use nym_credentials::error::Error as CredentialsError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 6d78bd7401..2902d93451 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -4,11 +4,11 @@ use crate::error::BandwidthControllerError; use crate::utils::stored_credential_to_issued_bandwidth; use log::{error, warn}; -use nym_coconut_interface::VerificationKey; use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; +use nym_credentials_interface::VerificationKey; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 5325428da2..3a0b2340d9 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -32,7 +32,7 @@ url = { workspace = true, features = ["serde"] } tokio = { workspace = true, features = ["sync", "time"] } futures = { workspace = true } -nym-coconut-interface = { path = "../../coconut-interface" } +nym-coconut = { path = "../../nymcoconut" } nym-network-defaults = { path = "../../network-defaults" } nym-api-requests = { path = "../../../nym-api/nym-api-requests" } diff --git a/common/client-libs/validator-client/src/coconut/mod.rs b/common/client-libs/validator-client/src/coconut/mod.rs index 97ac95cad7..66f5d0e05a 100644 --- a/common/client-libs/validator-client/src/coconut/mod.rs +++ b/common/client-libs/validator-client/src/coconut/mod.rs @@ -4,9 +4,9 @@ use crate::nyxd::contract_traits::{DkgQueryClient, PagedDkgQueryClient}; use crate::nyxd::error::NyxdError; use crate::NymApiClient; +use nym_coconut::{Base58, CoconutError, VerificationKey}; use nym_coconut_dkg_common::types::{EpochId, NodeIndex}; use nym_coconut_dkg_common::verification_key::ContractVKShare; -use nym_coconut_interface::{Base58, CoconutError, VerificationKey}; use thiserror::Error; use url::Url; diff --git a/common/client-libs/validator-client/src/nyxd/error.rs b/common/client-libs/validator-client/src/nyxd/error.rs index e247dff6a1..905d484b72 100644 --- a/common/client-libs/validator-client/src/nyxd/error.rs +++ b/common/client-libs/validator-client/src/nyxd/error.rs @@ -140,9 +140,6 @@ pub enum NyxdError { #[error("Cosmwasm std error: {0}")] CosmwasmStdError(#[from] cosmwasm_std::StdError), - #[error("Coconut interface error: {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("Account had an unexpected bech32 prefix. Expected: {expected}, got: {got}")] UnexpectedBech32Prefix { got: String, expected: String }, } diff --git a/common/coconut-interface/Cargo.toml b/common/coconut-interface/Cargo.toml deleted file mode 100644 index a85115d95f..0000000000 --- a/common/coconut-interface/Cargo.toml +++ /dev/null @@ -1,14 +0,0 @@ -[package] -name = "nym-coconut-interface" -version = "0.1.0" -edition = "2021" -description = "Crutch library until there is proper SerDe support for coconut structs" -license.workspace = true - -[dependencies] -bs58 = "0.4.0" -getset = "0.1.1" -serde = { workspace = true, features = ["derive"] } -thiserror = { workspace = true } - -nym-coconut = { path = "../nymcoconut" } diff --git a/common/coconut-interface/src/error.rs b/common/coconut-interface/src/error.rs deleted file mode 100644 index e096ee34f8..0000000000 --- a/common/coconut-interface/src/error.rs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2021 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use nym_coconut::CoconutError; -use thiserror::Error; - -#[derive(Debug, Error)] -pub enum CoconutInterfaceError { - #[error("not enough bytes: {0} received, minimum {1} required")] - InvalidByteLength(usize, usize), - - #[error("Could not decode base 58 string - {0}")] - MalformedString(#[from] bs58::decode::Error), - - #[error("Coconut error - {0}")] - CoconutError(#[from] CoconutError), -} diff --git a/common/coconut-interface/src/lib.rs b/common/coconut-interface/src/lib.rs deleted file mode 100644 index 4ac0706463..0000000000 --- a/common/coconut-interface/src/lib.rs +++ /dev/null @@ -1,199 +0,0 @@ -// Copyright 2021-2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -use error::CoconutInterfaceError; -use getset::{CopyGetters, Getters}; -use serde::{Deserialize, Serialize}; - -pub mod error; - -// We list these explicity instead of glob export due to shadowing warnings with the pub tests -// module. -pub use nym_coconut::{ - aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, - prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, - BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, - PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, - VerifyCredentialRequest, -}; - -// TODO: maybe just remove this sucker? -#[deprecated] -#[derive(Debug, Serialize, Deserialize, Getters, CopyGetters, Clone, PartialEq, Eq)] -pub struct Credential { - #[getset(get = "pub")] - n_params: u32, - - #[getset(get = "pub")] - theta: VerifyCredentialRequest, - - voucher_value: u64, - - voucher_info: String, - - #[getset(get = "pub")] - epoch_id: u64, -} - -impl Credential { - pub fn new( - n_params: u32, - theta: VerifyCredentialRequest, - voucher_value: u64, - voucher_info: String, - epoch_id: u64, - ) -> Credential { - Credential { - n_params, - theta, - voucher_value, - voucher_info, - epoch_id, - } - } - - pub fn blinded_serial_number(&self) -> String { - self.theta.blinded_serial_number_bs58() - } - - pub fn has_blinded_serial_number( - &self, - blinded_serial_number_bs58: &str, - ) -> Result { - Ok(self - .theta - .has_blinded_serial_number(blinded_serial_number_bs58)?) - } - - pub fn voucher_value(&self) -> u64 { - self.voucher_value - } - - pub fn verify(&self, verification_key: &VerificationKey) -> bool { - let params = Parameters::new(self.n_params).unwrap(); - - let hashed_value = hash_to_scalar(self.voucher_value.to_string()); - let hashed_info = hash_to_scalar(&self.voucher_info); - let public_attributes = &[&hashed_value, &hashed_info]; - - nym_coconut::verify_credential(¶ms, verification_key, &self.theta, public_attributes) - } - - pub fn as_bytes(&self) -> Vec { - let n_params_bytes = self.n_params.to_be_bytes(); - let theta_bytes = self.theta.to_bytes(); - let theta_bytes_len = theta_bytes.len(); - let voucher_value_bytes = self.voucher_value.to_be_bytes(); - let epoch_id_bytes = self.epoch_id.to_be_bytes(); - let voucher_info_bytes = self.voucher_info.as_bytes(); - let voucher_info_len = voucher_info_bytes.len(); - - let mut bytes = Vec::with_capacity(28 + theta_bytes_len + voucher_info_len); - bytes.extend_from_slice(&n_params_bytes); - bytes.extend_from_slice(&(theta_bytes_len as u64).to_be_bytes()); - bytes.extend_from_slice(&theta_bytes); - bytes.extend_from_slice(&voucher_value_bytes); - bytes.extend_from_slice(&epoch_id_bytes); - bytes.extend_from_slice(voucher_info_bytes); - - bytes - } - - pub fn from_bytes(bytes: &[u8]) -> Result { - if bytes.len() < 28 { - return Err(CoconutError::Deserialization(String::from( - "To few bytes in credential", - ))); - } - let mut four_byte = [0u8; 4]; - let mut eight_byte = [0u8; 8]; - - four_byte.copy_from_slice(&bytes[..4]); - let n_params = u32::from_be_bytes(four_byte); - eight_byte.copy_from_slice(&bytes[4..12]); - let theta_len = u64::from_be_bytes(eight_byte); - if bytes.len() < 28 + theta_len as usize { - return Err(CoconutError::Deserialization(String::from( - "To few bytes in credential", - ))); - } - let theta = VerifyCredentialRequest::from_bytes(&bytes[12..12 + theta_len as usize]) - .map_err(|e| CoconutError::Deserialization(e.to_string()))?; - eight_byte.copy_from_slice(&bytes[12 + theta_len as usize..20 + theta_len as usize]); - let voucher_value = u64::from_be_bytes(eight_byte); - eight_byte.copy_from_slice(&bytes[20 + theta_len as usize..28 + theta_len as usize]); - let epoch_id = u64::from_be_bytes(eight_byte); - let voucher_info = String::from_utf8(bytes[28 + theta_len as usize..].to_vec()) - .map_err(|e| CoconutError::Deserialization(e.to_string()))?; - - Ok(Credential { - n_params, - theta, - voucher_value, - voucher_info, - epoch_id, - }) - } -} - -impl Bytable for Credential { - fn to_byte_vec(&self) -> Vec { - self.as_bytes() - } - - fn try_from_byte_slice(slice: &[u8]) -> Result { - Credential::from_bytes(slice) - } -} - -impl Base58 for Credential {} - -#[cfg(test)] -mod tests { - use nym_coconut::{prove_bandwidth_credential, Signature}; - - use super::*; - - #[test] - fn serde_coconut_credential() { - let voucher_value = 1000000u64; - let voucher_info = String::from("BandwidthVoucher"); - let serial_number = - Attribute::try_from_bs58("7Rp3imcuNX3w9se9wm5th8gSvc2czsnMrGsdt5HsrycA").unwrap(); - let binding_number = - Attribute::try_from_bs58("Auf8yVEgyEAWNHaXUZmimS4n9g5YiYnNYqp6F9BtBe9E").unwrap(); - let signature = Signature::try_from_bs58( - "ta3pM9ffj5T6YGbwjSBp2W118rcwyP9PXStc\ - 7ssb91g5GQYMQHhuTNajbdZcjxUFBFL5rhED8EHpRzE8r432ss3qbPBfpNev4CdkfMkQ3wepyM7hy7q1W6Rn9WmFoZL\ - ZR9j", - ) - .unwrap(); - let params = Parameters::new(4).unwrap(); - let verification_key = VerificationKey::try_from_bs58("8CFtVVXdwLy4WHMQPE4\ - woe89q3DRHoNxBSchftrEjSBPWA4r4xZv4Y9qSvS5x5bMmFtp7BX6ikECAnuXr5EjXWSsgjirZJmpS5XDUynVfht1cD\ - FWGDvy2XFrRCuoCMotNXi3PoF6wYqdTR9Rqcfoj3i2H5Nid422WBaLtVoC9QNobvpvaqq6vX5PbsSyPayvU8HCXFxM6\ - JjScYpbRTxQtdwefWLrk3LmXyJQBWi7c2VAhSxu9msp7VTBycqdwQNgxHETStZuwXsozxaGQ2KssVUCaaoYPR4g2RqK\ - UAvtWwA7pMiAQNcbkXcbsjCgVjWaCpMWC37XA31cLcFf3zbjHD9e5tXjAcqa4M89fbFhuvvSXxowSAZ5NoWrN32kd5d\ - wxJm1JW3Tt2h6yDDBe84oMy71462dZn7N78DVk2mFNGwBCibrZWA7oUzRBMfYxiQrksoFcou7QfLLd58zoNYmPQPt84\ - 1VpQopEBfdQ7Nf9zoXxBt3zMy7g5NsFGvzh7KTbDUyeeXrdkKJPQBs6dqaizr9sS8CPPmR4uk96vDTRh8CJ5FbSsmb8\ - nP71dRvvwRZJHGzwYirMo6SXS3ZYxFuiA3mkxYuqDHCwkTWDuRCcAaztrDYRZg7VCMo4Q446AaEso5eqpeWpHZQt53E\ - ZRpqmNYKASGwMhTeEHPSLgSmtoAAUcaRWpGRzYfd6kzEma8tdGLwyP4rLXgvSvtDLP37dU7YgF3LEXbGAz57U9ATy46\ - 6sroLpHPdaCWB8RF11wvB6Tu196JnJd2KyQBP1iUWP3rtZs3GhAF1QVcxquh8BqDZzAcpQ6wCS1P9c5GxKgww77FVF5\ - Kp83XtoxSrw3GaYVyKTGxNh3vcKPR31txCjTxPaN2fg7TaPLhoQJX4YaAroFSXqrqbbRsisuHhhCeUP2YwDjHedes9y") - .unwrap(); - let theta = prove_bandwidth_credential( - ¶ms, - &verification_key, - &signature, - &serial_number, - &binding_number, - ) - .unwrap(); - let credential = Credential::new(4, theta, voucher_value, voucher_info, 42); - - let serialized_credential = credential.as_bytes(); - let deserialized_credential = Credential::from_bytes(&serialized_credential).unwrap(); - - assert_eq!(credential, deserialized_credential); - } -} diff --git a/common/credentials-interface/Cargo.toml b/common/credentials-interface/Cargo.toml new file mode 100644 index 0000000000..789552ebff --- /dev/null +++ b/common/credentials-interface/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "nym-credentials-interface" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bls12_381 = { workspace = true, default-features = false } +serde = { workspace = true, features = ["derive"] } + +nym-coconut = { path = "../nymcoconut" } diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs new file mode 100644 index 0000000000..f962bf8c9e --- /dev/null +++ b/common/credentials-interface/src/lib.rs @@ -0,0 +1,109 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use bls12_381::Scalar; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; + +pub use nym_coconut::{ + aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, + prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, + BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, + PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, + VerifyCredentialRequest, +}; + +pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; +pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; + +// pub trait NymCredential { +// fn prove_credential(&self) -> Result<(), ()>; +// } + +#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +pub enum CredentialType { + Voucher, + FreePass, +} + +impl CredentialType { + pub fn validate(&self, type_plain: &str) -> bool { + match self { + CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE, + CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE, + } + } + + pub fn is_free_pass(&self) -> bool { + matches!(self, CredentialType::FreePass) + } + + pub fn is_voucher(&self) -> bool { + matches!(self, CredentialType::Voucher) + } +} + +impl Display for CredentialType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + CredentialType::Voucher => VOUCHER_INFO_TYPE.fmt(f), + CredentialType::FreePass => FREE_PASS_INFO_TYPE.fmt(f), + } + } +} + +#[derive(Debug, Clone)] +pub struct CredentialSigningData { + pub pedersen_commitments_openings: Vec, + + pub blind_sign_request: BlindSignRequest, + + pub public_attributes_plain: Vec, + + pub typ: CredentialType, +} + +#[derive(Debug, Serialize, Deserialize)] +pub struct CredentialSpendingData { + pub embedded_private_attributes: usize, + + pub verify_credential_request: VerifyCredentialRequest, + + pub public_attributes_plain: Vec, + + pub typ: CredentialType, +} + +impl CredentialSpendingData { + pub fn verify(&self, params: &Parameters, verification_key: &VerificationKey) -> bool { + let hashed_public_attributes = self + .public_attributes_plain + .iter() + .map(hash_to_scalar) + .collect::>(); + + // get references to the attributes + let public_attributes = hashed_public_attributes.iter().collect::>(); + + verify_credential( + params, + verification_key, + &self.verify_credential_request, + &public_attributes, + ) + } + + pub fn validate_type_attribute(&self) -> bool { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + let Some(type_plain) = self.public_attributes_plain.get(1) else { + return false; + }; + + self.typ.validate(type_plain) + } + + pub fn get_bandwidth_attribute(&self) -> Option<&String> { + // the first attribute is variant specific bandwidth encoding, the second one should be the type + self.public_attributes_plain.first() + } +} diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index 55894c3754..bc096fa5a9 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -16,7 +16,7 @@ time = { workspace = true, features = ["serde"] } zeroize = { workspace = true } # I guess temporarily until we get serde support in coconut up and running -nym-coconut-interface = { path = "../coconut-interface" } +nym-credentials-interface = { path = "../credentials-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "serde"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 5783a8c25d..67fab7197b 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::coconut::utils::scalar_serde_helper; -use nym_coconut_interface::{hash_to_scalar, Attribute, PublicAttribute}; +use nym_credentials_interface::{hash_to_scalar, Attribute, PublicAttribute}; use serde::{Deserialize, Serialize}; use time::{Duration, OffsetDateTime, Time}; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 736555bfdc..7078d358d5 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -9,7 +9,7 @@ use crate::coconut::bandwidth::{ }; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; -use nym_coconut_interface::{ +use nym_credentials_interface::{ aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, }; diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index d3e8807f05..8a66e36365 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -10,7 +10,7 @@ use crate::coconut::bandwidth::{ bandwidth_credential_params, CredentialSpendingData, CredentialType, }; use crate::error::Error; -use nym_coconut_interface::{ +use nym_credentials_interface::{ prove_bandwidth_credential, Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey, }; diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 8fe23a444b..195db20598 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -1,114 +1,21 @@ // Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use bls12_381::Scalar; -use nym_coconut_interface::{ - hash_to_scalar, BlindSignRequest, Parameters, VerificationKey, VerifyCredentialRequest, -}; -use serde::{Deserialize, Serialize}; -use std::fmt::{Display, Formatter}; use std::sync::OnceLock; -use zeroize::{Zeroize, ZeroizeOnDrop}; pub use issuance::IssuanceBandwidthCredential; pub use issued::IssuedBandwidthCredential; +pub use nym_credentials_interface::{ + CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, +}; pub mod freepass; pub mod issuance; pub mod issued; pub mod voucher; -pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; -pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; - // works under the assumption of having 4 attributes in the underlying credential(s) pub fn bandwidth_credential_params() -> &'static Parameters { static BANDWIDTH_CREDENTIAL_PARAMS: OnceLock = OnceLock::new(); BANDWIDTH_CREDENTIAL_PARAMS.get_or_init(IssuanceBandwidthCredential::default_parameters) } - -#[derive(Zeroize, Copy, Clone, Debug, Serialize, Deserialize)] -pub enum CredentialType { - Voucher, - FreePass, -} - -impl CredentialType { - pub fn is_free_pass(&self) -> bool { - matches!(self, CredentialType::FreePass) - } - - pub fn is_voucher(&self) -> bool { - matches!(self, CredentialType::Voucher) - } -} - -impl Display for CredentialType { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - CredentialType::Voucher => VOUCHER_INFO_TYPE.fmt(f), - CredentialType::FreePass => FREE_PASS_INFO_TYPE.fmt(f), - } - } -} - -#[derive(Debug, Clone)] -pub struct CredentialSigningData { - pub pedersen_commitments_openings: Vec, - - pub blind_sign_request: BlindSignRequest, - - pub public_attributes_plain: Vec, - - pub typ: CredentialType, -} - -#[derive(Debug, Serialize, Deserialize)] -pub struct CredentialSpendingData { - pub embedded_private_attributes: usize, - - pub verify_credential_request: VerifyCredentialRequest, - - pub public_attributes_plain: Vec, - - pub typ: CredentialType, -} - -impl CredentialSpendingData { - pub fn verify(&self, verification_key: &VerificationKey) -> bool { - let params = bandwidth_credential_params(); - - let hashed_public_attributes = self - .public_attributes_plain - .iter() - .map(hash_to_scalar) - .collect::>(); - - // get references to the attributes - let public_attributes = hashed_public_attributes.iter().collect::>(); - - nym_coconut_interface::verify_credential( - params, - verification_key, - &self.verify_credential_request, - &public_attributes, - ) - } - - pub fn validate_type_attribute(&self) -> bool { - // the first attribute is variant specific bandwidth encoding, the second one should be the type - let Some(type_plain) = self.public_attributes_plain.get(1) else { - return false; - }; - - match self.typ { - CredentialType::Voucher => type_plain == VOUCHER_INFO_TYPE, - CredentialType::FreePass => type_plain == FREE_PASS_INFO_TYPE, - } - } - - pub fn get_bandwidth_attribute(&self) -> Option<&String> { - // the first attribute is variant specific bandwidth encoding, the second one should be the type - self.public_attributes_plain.first() - } -} diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index 06f88d2414..6bf4e55dcb 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -5,7 +5,7 @@ use crate::coconut::bandwidth::CredentialSigningData; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use nym_api_requests::coconut::BlindSignRequestBody; -use nym_coconut_interface::{ +use nym_credentials_interface::{ hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, PublicAttribute, }; use nym_crypto::asymmetric::{encryption, identity}; diff --git a/common/credentials/src/coconut/credential.rs b/common/credentials/src/coconut/credential.rs deleted file mode 100644 index 446682a398..0000000000 --- a/common/credentials/src/coconut/credential.rs +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2024 - Nym Technologies SA -// SPDX-License-Identifier: Apache-2.0 - -pub trait NymCredential { - fn prove_credential(&self) -> Result<(), ()>; -} diff --git a/common/credentials/src/coconut/mod.rs b/common/credentials/src/coconut/mod.rs index c02b932712..16d9819ab4 100644 --- a/common/credentials/src/coconut/mod.rs +++ b/common/credentials/src/coconut/mod.rs @@ -2,5 +2,4 @@ // SPDX-License-Identifier: Apache-2.0 pub mod bandwidth; -pub mod credential; pub mod utils; diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index a2014d8c1a..cf0025826c 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -4,7 +4,7 @@ use crate::coconut::bandwidth::IssuanceBandwidthCredential; use crate::error::Error; use log::{debug, warn}; -use nym_coconut_interface::{ +use nym_credentials_interface::{ aggregate_verification_keys, Signature, SignatureShare, VerificationKey, }; use nym_validator_client::client::CoconutApiClient; diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index c89667aad6..76c4aa068c 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::CoconutError; +use nym_credentials_interface::CoconutError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_validator_client::ValidatorClientError; diff --git a/common/types/Cargo.toml b/common/types/Cargo.toml index d08e435486..8b5f0c3340 100644 --- a/common/types/Cargo.toml +++ b/common/types/Cargo.toml @@ -31,7 +31,6 @@ nym-validator-client = { path = "../../common/client-libs/validator-client" } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } [dev-dependencies] diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index a845ba908b..ff1fb32888 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -62,9 +62,9 @@ nym-node = { path = "../nym-node" } nym-api-requests = { path = "../nym-api/nym-api-requests" } nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } -nym-coconut-interface = { path = "../common/coconut-interface" } nym-config = { path = "../common/config" } nym-credentials = { path = "../common/credentials" } +nym-credentials-interface = { path = "../common/credentials-interface" } nym-crypto = { path = "../common/crypto" } nym-gateway-requests = { path = "gateway-requests" } nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index 7916fa3038..d63170628e 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -25,8 +25,8 @@ nym-crypto = { path = "../../common/crypto" } nym-pemstore = { path = "../../common/pemstore" } nym-sphinx = { path = "../../common/nymsphinx" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-credentials = { path = "../../common/credentials" } +nym-credentials-interface = { path = "../../common/credentials-interface" } [dependencies.tungstenite] workspace = true diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 43881d3ceb..4e1df1d61e 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::GatewayRequestsError; -use nym_coconut_interface::CoconutError; use nym_credentials::coconut::bandwidth::CredentialSpendingData; +use nym_credentials_interface::CoconutError; use serde::{Deserialize, Serialize}; #[derive(Debug, Serialize, Deserialize)] diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index d5ea02b2d2..76406360f6 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use log::error; -use nym_coconut_interface::Credential; use nym_credentials::coconut::bandwidth::CredentialType; use thiserror::Error; @@ -49,12 +48,12 @@ impl Bandwidth { } } -impl From for Bandwidth { - fn from(credential: Credential) -> Self { - let token_value = credential.voucher_value(); - let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN; - Bandwidth { - value: bandwidth_bytes, - } - } -} +// impl From for Bandwidth { +// fn from(credential: Credential) -> Self { +// let token_value = credential.voucher_value(); +// let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN; +// Bandwidth { +// value: bandwidth_bytes, +// } +// } +// } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 548037e9d3..d5a662c2ed 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -1,28 +1,6 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use futures::{ - future::{FusedFuture, OptionFuture}, - FutureExt, StreamExt, -}; -use log::*; -use nym_gateway_requests::{ - iv::{IVConversionError, IV}, - types::{BinaryRequest, ServerResponse}, - ClientControlRequest, GatewayRequestsError, -}; -use nym_sphinx::forwarding::packet::MixPacket; -use nym_task::TaskClient; -use nym_validator_client::coconut::CoconutApiError; -use rand::{CryptoRng, Rng}; -use thiserror::Error; -use tokio::io::{AsyncRead, AsyncWrite}; -use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; - -use nym_coconut_interface::CoconutError; -use nym_credentials::coconut::bandwidth::CredentialType; -use std::{convert::TryFrom, process, time::Duration}; - use crate::node::client_handling::bandwidth::BandwidthError; use crate::node::{ client_handling::{ @@ -37,6 +15,26 @@ use crate::node::{ }, storage::{error::StorageError, Storage}, }; +use futures::{ + future::{FusedFuture, OptionFuture}, + FutureExt, StreamExt, +}; +use log::*; +use nym_credentials::coconut::bandwidth::{bandwidth_credential_params, CredentialType}; +use nym_credentials_interface::CoconutError; +use nym_gateway_requests::{ + iv::{IVConversionError, IV}, + types::{BinaryRequest, ServerResponse}, + ClientControlRequest, GatewayRequestsError, +}; +use nym_sphinx::forwarding::packet::MixPacket; +use nym_task::TaskClient; +use nym_validator_client::coconut::CoconutApiError; +use rand::{CryptoRng, Rng}; +use std::{convert::TryFrom, process, time::Duration}; +use thiserror::Error; +use tokio::io::{AsyncRead, AsyncWrite}; +use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; #[derive(Debug, Error)] pub(crate) enum RequestHandlingError { @@ -76,9 +74,6 @@ pub(crate) enum RequestHandlingError { #[error("There was a problem with the proposal id: {reason}")] ProposalIdError { reason: String }, - #[error("Coconut interface error - {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("coconut failure: {0}")] CoconutError(#[from] CoconutError), @@ -257,7 +252,8 @@ where let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; - if !credential.data.verify(&aggregated_verification_key) { + let params = bandwidth_credential_params(); + if !credential.data.verify(params, &aggregated_verification_key) { return Err(RequestHandlingError::InvalidBandwidthCredential( String::from("credential failed to verify on gateway"), )); diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index e62d6afa5a..7515157b55 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -3,7 +3,7 @@ use super::authenticated::RequestHandlingError; use log::*; -use nym_coconut_interface::{Credential, VerificationKey}; +use nym_credentials_interface::VerificationKey; use nym_gateway_requests::models::CredentialSpendingWithEpoch; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; @@ -229,7 +229,8 @@ impl CoconutVerifier { } let req = nym_api_requests::coconut::VerifyCredentialBody::new( - credential, + credential.data, + credential.epoch_id, proposal_id, self.address.clone(), ); diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 579a98d991..db80920086 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -78,7 +78,6 @@ zeroize = { workspace = true } nym-bandwidth-controller = { path = "../common/bandwidth-controller" } nym-coconut-bandwidth-contract-common = { path = "../common/cosmwasm-smart-contracts/coconut-bandwidth-contract" } nym-coconut-dkg-common = { path = "../common/cosmwasm-smart-contracts/coconut-dkg" } -nym-coconut-interface = { path = "../common/coconut-interface" } #nym-ephemera-common = { path = "../common/cosmwasm-smart-contracts/ephemera" } nym-config = { path = "../common/config" } cosmwasm-std = { workspace = true } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index aaf7309fcf..1baf4d17dd 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -16,9 +16,7 @@ serde = { workspace = true, features = ["derive"] } ts-rs = { workspace = true, optional = true } tendermint = { workspace = true } -nym-coconut = { path = "../../common/nymcoconut" } -nym-coconut-interface = { path = "../../common/coconut-interface" } -#nym-credentials = { path = "../../common/credentials" } +nym-credentials-interface = { path = "../../common/credentials-interface" } nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]} nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" } diff --git a/nym-api/nym-api-requests/src/coconut/helpers.rs b/nym-api/nym-api-requests/src/coconut/helpers.rs index 58aec3eca0..73d1a7f42f 100644 --- a/nym-api/nym-api-requests/src/coconut/helpers.rs +++ b/nym-api/nym-api-requests/src/coconut/helpers.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use nym_coconut_interface::BlindedSignature; +use nym_credentials_interface::BlindedSignature; use tendermint::hash::Hash; // recomputes plaintext on the credential nym-api has used for signing diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 15efe1a9f6..ce58d8a05e 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -3,9 +3,9 @@ use crate::coconut::helpers::issued_credential_plaintext; use cosmrs::AccountId; -use nym_coconut::{ +use nym_credentials_interface::{ hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, Bytable, CoconutError, - Signature, VerificationKey, + CredentialSpendingData, Signature, VerificationKey, }; use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; @@ -15,7 +15,7 @@ use tendermint::hash::Hash; #[derive(Serialize, Deserialize)] pub struct VerifyCredentialBody { /// The cryptographic material required for spending the underlying credential. - pub credential_data: (), + pub credential_data: CredentialSpendingData, /// The (DKG) epoch id under which the credential has been issued so that the verifier /// could use correct verification key for validation. @@ -30,7 +30,7 @@ pub struct VerifyCredentialBody { impl VerifyCredentialBody { pub fn new( - credential_data: (), + credential_data: CredentialSpendingData, epoch_id: u64, proposal_id: u64, gateway_cosmos_addr: AccountId, @@ -100,7 +100,7 @@ impl BlindSignRequestBody { } pub fn encode_commitments(&self) -> Vec { - use nym_coconut_interface::Base58; + use nym_credentials_interface::Base58; self.inner_sign_request .get_private_attributes_pedersen_commitments() diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index c8a739319d..8a276d5e2d 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -17,7 +17,9 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{ funds_from_cosmos_msgs, SpendCredentialStatus, }; use nym_coconut_dkg_common::types::EpochId; -use nym_credentials::coconut::bandwidth::IssuanceBandwidthCredential; +use nym_credentials::coconut::bandwidth::{ + bandwidth_credential_params, IssuanceBandwidthCredential, +}; use nym_validator_client::nyxd::Coin; use rocket::serde::json::Json; use rocket::State as RocketState; @@ -93,15 +95,22 @@ pub async fn verify_bandwidth_credential( state: &RocketState, ) -> Result> { let proposal_id = verify_credential_body.proposal_id; - let proposal = state.client.get_proposal(proposal_id).await?; + let epoch_id = verify_credential_body.epoch_id; + let credential_data = &verify_credential_body.credential_data; + let theta = &credential_data.verify_credential_request; + + let voucher_value: u64 = if credential_data.typ.is_voucher() { + todo!() + } else { + todo!("return error here") + }; // TODO: introduce a check to make sure we haven't already voted for this proposal to prevent DDOS + let proposal = state.client.get_proposal(proposal_id).await?; + // Proposal description is the blinded serial number - if !verify_credential_body - .credential - .has_blinded_serial_number(&proposal.description)? - { + if !theta.has_blinded_serial_number(&proposal.description)? { return Err(CoconutError::IncorrectProposal { reason: String::from("incorrect blinded serial number in description"), }); @@ -113,7 +122,7 @@ pub async fn verify_bandwidth_credential( // Credential has not been spent before, and is on its way of being spent let credential_status = state .client - .get_spent_credential(verify_credential_body.credential.blinded_serial_number()) + .get_spent_credential(theta.blinded_serial_number_bs58()) .await? .spend_credential .ok_or(CoconutError::InvalidCredentialStatus { @@ -125,16 +134,12 @@ pub async fn verify_bandwidth_credential( status: format!("{:?}", credential_status), }); } - let verification_key = state - .verification_key(*verify_credential_body.credential.epoch_id()) - .await?; - let mut vote_yes = verify_credential_body.credential.verify(&verification_key); + let verification_key = state.verification_key(epoch_id).await?; + let params = bandwidth_credential_params(); + let mut vote_yes = credential_data.verify(params, &verification_key); vote_yes &= Coin::from(proposed_release_funds) - == Coin::new( - verify_credential_body.credential.voucher_value() as u128, - state.mix_denom.clone(), - ); + == Coin::new(voucher_value as u128, state.mix_denom.clone()); // Vote yes or no on the proposal based on the verification result let ret = state diff --git a/nym-api/src/coconut/comm.rs b/nym-api/src/coconut/comm.rs index 0cb84fc894..2019d99650 100644 --- a/nym-api/src/coconut/comm.rs +++ b/nym-api/src/coconut/comm.rs @@ -4,8 +4,8 @@ use crate::coconut::error::Result; use crate::nyxd; use crate::support::nyxd::ClientInner; +use nym_coconut::VerificationKey; use nym_coconut_dkg_common::types::{Epoch, EpochId}; -use nym_coconut_interface::VerificationKey; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; diff --git a/nym-api/src/coconut/dkg/key_derivation.rs b/nym-api/src/coconut/dkg/key_derivation.rs index db86ec39a5..eb6c5b7214 100644 --- a/nym-api/src/coconut/dkg/key_derivation.rs +++ b/nym-api/src/coconut/dkg/key_derivation.rs @@ -10,10 +10,10 @@ use crate::coconut::keys::KeyPairWithEpoch; use crate::coconut::state::bandwidth_credential_params; use cosmwasm_std::Addr; use log::debug; +use nym_coconut::KeyPair as CoconutKeyPair; use nym_coconut::{check_vk_pairing, Base58, SecretKey, VerificationKey}; use nym_coconut_dkg_common::event_attributes::DKG_PROPOSAL_ID; use nym_coconut_dkg_common::types::{DealingIndex, EpochId, NodeIndex}; -use nym_coconut_interface::KeyPair as CoconutKeyPair; use nym_dkg::{ bte::{self, decrypt_share}, combine_shares, try_recover_verification_keys, Dealing, diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 423574db8d..4f464ef175 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -87,9 +87,6 @@ pub enum CoconutError { #[error("public attributes in request differ from the ones in deposit: Expected {0}, got {1}")] DifferentPublicAttributes(String, String), - #[error("error in coconut interface: {0}")] - CoconutInterfaceError(#[from] nym_coconut_interface::error::CoconutInterfaceError), - #[error("storage error: {0}")] StorageError(#[from] NymApiStorageError), diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index e5778674e6..ee55f9ff1d 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -28,7 +28,7 @@ pub(crate) fn blind_sign( let public_attributes = request.public_attributes_hashed(); let attributes_ref = public_attributes.iter().collect::>(); - Ok(nym_coconut_interface::blind_sign( + Ok(nym_coconut::blind_sign( bandwidth_credential_params(), signing_key, &request.inner_sign_request, diff --git a/nym-api/src/coconut/keys/mod.rs b/nym-api/src/coconut/keys/mod.rs index 117c512b9e..7c719c7a53 100644 --- a/nym-api/src/coconut/keys/mod.rs +++ b/nym-api/src/coconut/keys/mod.rs @@ -18,12 +18,12 @@ pub struct KeyPair { #[derive(Debug)] pub struct KeyPairWithEpoch { - pub(crate) keys: nym_coconut_interface::KeyPair, + pub(crate) keys: nym_coconut::KeyPair, pub(crate) issued_for_epoch: EpochId, } impl KeyPairWithEpoch { - pub(crate) fn new(keys: nym_coconut_interface::KeyPair, issued_for_epoch: EpochId) -> Self { + pub(crate) fn new(keys: nym_coconut::KeyPair, issued_for_epoch: EpochId) -> Self { KeyPairWithEpoch { keys, issued_for_epoch, diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index 6bf4159c2e..d92a5d6f81 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -10,8 +10,8 @@ use crate::coconut::storage::CoconutStorageExt; use crate::support::storage::NymApiStorage; use nym_api_requests::coconut::helpers::issued_credential_plaintext; use nym_api_requests::coconut::BlindSignRequestBody; +use nym_coconut::{BlindedSignature, VerificationKey}; use nym_coconut_dkg_common::types::EpochId; -use nym_coconut_interface::{BlindedSignature, VerificationKey}; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::{Hash, TxResponse}; use std::sync::Arc; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 555390c706..2cfd6ab068 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3694,8 +3694,7 @@ dependencies = [ "cosmrs", "cosmwasm-std", "getset", - "nym-coconut", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -3710,9 +3709,10 @@ version = "0.1.0" dependencies = [ "bip39", "log", - "nym-coconut-interface", + "nym-coconut", "nym-credential-storage", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -3830,17 +3830,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -3937,7 +3926,7 @@ dependencies = [ "cosmrs", "log", "nym-api-requests", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-validator-client", "serde", @@ -3946,6 +3935,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -4074,8 +4072,8 @@ dependencies = [ "futures", "generic-array 0.14.7", "log", - "nym-coconut-interface", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -4505,9 +4503,9 @@ dependencies = [ "itertools", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index b5dfb64b97..8c3109210f 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3098,8 +3098,7 @@ dependencies = [ "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "getset", - "nym-coconut", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -3167,17 +3166,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -3203,6 +3191,15 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", +] + [[package]] name = "nym-crypto" version = "0.4.0" @@ -3401,7 +3398,6 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", - "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -3442,9 +3438,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", @@ -3546,7 +3542,6 @@ dependencies = [ "itertools 0.10.5", "k256 0.13.1", "log", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-crypto", diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 854aa1d57f..a9b72b234e 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -57,7 +57,6 @@ nym-contracts-common = { path = "../../common/cosmwasm-smart-contracts/contracts nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-vesting-contract-common = { path = "../../common/cosmwasm-smart-contracts/vesting-contract" } nym-config = { path = "../../common/config" } -nym-coconut-interface = { path = "../../common/coconut-interface" } nym-types = { path = "../../common/types" } nym-wallet-types = { path = "../nym-wallet-types" } nym-store-cipher = { path = "../../common/store-cipher", features = ["json"] } From 0ee727bac1fe48e5208f95acd75f2ad61835aedf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 7 Feb 2024 17:21:29 +0000 Subject: [PATCH 054/394] gateway handling of both credential types --- common/network-defaults/src/lib.rs | 3 + gateway/Cargo.toml | 1 + gateway/src/node/client_handling/bandwidth.rs | 91 +++++++++++++------ .../connection_handler/authenticated.rs | 11 +-- 4 files changed, 69 insertions(+), 37 deletions(-) diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 4404b0e51f..1891cd3cc3 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -457,6 +457,9 @@ pub const ETH_ERC20_APPROVE_FUNCTION_NAME: &str = "approve"; /// How much bandwidth (in bytes) one token can buy pub const BYTES_PER_UTOKEN: u64 = 1024; +/// How much bandwidth (in bytes) one freepass provides +pub const BYTES_PER_FREEPASS: u64 = 1024 * 1024 * 1024; // 1GB + /// Threshold for claiming more bandwidth: 1 MB pub const REMAINING_BANDWIDTH_THRESHOLD: i64 = 1024 * 1024; /// How many ERC20 tokens should be burned to buy bandwidth diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index ff1fb32888..51f0307f76 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -55,6 +55,7 @@ tokio-stream = { version = "0.1.11", features = ["fs"] } tokio-tungstenite = { version = "0.20.1" } tokio-util = { workspace = true, features = ["codec"] } url = { workspace = true, features = ["serde"] } +time = { workspace = true } zeroize = { workspace = true } # internal diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index 76406360f6..ae8469c504 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -1,12 +1,40 @@ // Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use log::error; +use log::{error, warn}; use nym_credentials::coconut::bandwidth::CredentialType; +use std::num::ParseIntError; use thiserror::Error; +use time::error::ComponentRange; +use time::OffsetDateTime; #[derive(Debug, Error)] -pub enum BandwidthError {} +pub enum BandwidthError { + #[error("Provided bandwidth credential asks for more bandwidth than it is supported to add at once (credential value: {0}, supported: {}). Try to split it before attempting again", i64::MAX)] + UnsupportedBandwidthValue(u64), + + #[error("the provided free pass has already expired (expiry was on {expiry_date})")] + ExpiredFreePass { expiry_date: OffsetDateTime }, + + #[error("failed to pass the bandwidth voucher value: {source}")] + VoucherValueParsingFailure { + #[source] + source: ParseIntError, + }, + + #[error("failed to pass the free pass expiry date: {source}")] + ExpiryDateParsingFailure { + #[source] + source: ParseIntError, + }, + + #[error("failed to parse expiry timestamp into proper datetime: {source}")] + InvalidExpiryDate { + unix_timestamp: i64, + #[source] + source: ComponentRange, + }, +} pub struct Bandwidth { value: u64, @@ -18,42 +46,47 @@ impl Bandwidth { } pub fn try_from_raw_value(value: &String, typ: CredentialType) -> Result { - // let bandwidth_value = match credential.data.typ { - // CredentialType::Voucher => { - // todo!() - // } - // CredentialType::FreePass => { - // error!("unimplemented handling of free pass credential"); - // return Err(()); - // } - // }; + let bandwidth_value = + match typ { + CredentialType::Voucher => { + let token_value: u64 = value + .parse() + .map_err(|source| BandwidthError::VoucherValueParsingFailure { source })?; + token_value * nym_network_defaults::BYTES_PER_UTOKEN + } + CredentialType::FreePass => { + let expiry_timestamp: i64 = value + .parse() + .map_err(|source| BandwidthError::ExpiryDateParsingFailure { source })?; - /* - if bandwidth_value > i64::MAX as u64 { + let expiry_date = OffsetDateTime::from_unix_timestamp(expiry_timestamp) + .map_err(|source| BandwidthError::InvalidExpiryDate { + unix_timestamp: expiry_timestamp, + source, + })?; + let now = OffsetDateTime::now_utc(); + + if expiry_date < now { + return Err(BandwidthError::ExpiredFreePass { expiry_date }); + } + nym_network_defaults::BYTES_PER_FREEPASS + } + }; + + if bandwidth_value > i64::MAX as u64 { // note that this would have represented more than 1 exabyte, - // which is like 125,000 worth of hard drives so I don't think we have + // which is like 125,000 worth of hard drives, so I don't think we have // to worry about it for now... warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now"); - return Err(RequestHandlingError::UnsupportedBandwidthValue( - bandwidth_value, - )); + return Err(BandwidthError::UnsupportedBandwidthValue(bandwidth_value)); } - */ - todo!() + Ok(Bandwidth { + value: bandwidth_value, + }) } pub fn value(&self) -> u64 { self.value } } - -// impl From for Bandwidth { -// fn from(credential: Credential) -> Self { -// let token_value = credential.voucher_value(); -// let bandwidth_bytes = token_value * nym_network_defaults::BYTES_PER_UTOKEN; -// Bandwidth { -// value: bandwidth_bytes, -// } -// } -// } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index d5a662c2ed..3c3ff21fa4 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -53,9 +53,6 @@ pub(crate) enum RequestHandlingError { #[error("The received request is not valid in the current context")] IllegalRequest, - #[error("Provided bandwidth credential asks for more bandwidth than it is supported to add at once (credential value: {0}, supported: {}). Try to split it before attempting again", i64::MAX)] - UnsupportedBandwidthValue(u64), - #[error("Provided bandwidth credential did not verify correctly on {0}")] InvalidBandwidthCredential(String), @@ -85,9 +82,6 @@ pub(crate) enum RequestHandlingError { #[error("failed to recover bandwidth value: {0}")] BandwidthRecoveryFailure(#[from] BandwidthError), - - #[error("free pass credentials haven't been implemented yet")] - UnimplementedFreePass, } impl RequestHandlingError { @@ -250,6 +244,7 @@ where unimplemented!() }; + // this will extract token amounts out of bandwidth vouchers and validate expiry of free passes let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; let params = bandwidth_credential_params(); @@ -273,8 +268,8 @@ where .await?; } CredentialType::FreePass => { - error!("unimplemented handling of free pass credential"); - return Err(RequestHandlingError::UnimplementedFreePass); + // no need to do anything special here, we already extracted the bandwidth amount and checked expiry + info!("received a free pass credential"); } } From 16c942d72ef110546efdd0db97a9292bd9a70edd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Wed, 7 Feb 2024 17:31:30 +0000 Subject: [PATCH 055/394] removed nym-api placeholders --- nym-api/nym-api-requests/src/coconut/models.rs | 2 +- nym-api/src/coconut/api_routes/mod.rs | 10 ++++++++-- nym-api/src/coconut/error.rs | 16 ++++++++++++++++ 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index ce58d8a05e..c4de811281 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -5,7 +5,7 @@ use crate::coconut::helpers::issued_credential_plaintext; use cosmrs::AccountId; use nym_credentials_interface::{ hash_to_scalar, Attribute, BlindSignRequest, BlindedSignature, Bytable, CoconutError, - CredentialSpendingData, Signature, VerificationKey, + CredentialSpendingData, VerificationKey, }; use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 8a276d5e2d..b2b2dfc4bc 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -100,9 +100,15 @@ pub async fn verify_bandwidth_credential( let theta = &credential_data.verify_credential_request; let voucher_value: u64 = if credential_data.typ.is_voucher() { - todo!() + credential_data + .get_bandwidth_attribute() + .ok_or(CoconutError::MissingBandwidthValue)? + .parse() + .map_err(|source| CoconutError::VoucherValueParsingFailure { source })? } else { - todo!("return error here") + return Err(CoconutError::NotABandwidthVoucher { + typ: credential_data.typ, + }); }; // TODO: introduce a check to make sure we haven't already voted for this proposal to prevent DDOS diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 4f464ef175..ec43b0d65d 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -3,6 +3,7 @@ use crate::node_status_api::models::NymApiStorageError; use nym_coconut_dkg_common::types::{ChunkIndex, DealingIndex, EpochId}; +use nym_credentials::coconut::bandwidth::CredentialType; use nym_crypto::asymmetric::{ encryption::KeyRecoveryError, identity::{Ed25519RecoveryError, SignatureError}, @@ -14,6 +15,7 @@ use rocket::http::{ContentType, Status}; use rocket::response::Responder; use rocket::{response, Request, Response}; use std::io::Cursor; +use std::num::ParseIntError; use thiserror::Error; pub type Result = std::result::Result; @@ -23,6 +25,20 @@ pub enum CoconutError { #[error(transparent)] IOError(#[from] std::io::Error), + #[error("the received bandwidth voucher did not contain deposit value")] + MissingBandwidthValue, + + #[error( + "the received bandwidth credential is not a bandwidth voucher. the encoded type is: {typ}" + )] + NotABandwidthVoucher { typ: CredentialType }, + + #[error("failed to parse the bandwidth voucher value: {source}")] + VoucherValueParsingFailure { + #[source] + source: ParseIntError, + }, + #[error("coconut api query failure: {0}")] CoconutApiError(#[from] CoconutApiError), From ddf2770c8ec450078d454447152caf8f3be36552 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 8 Feb 2024 10:11:05 +0000 Subject: [PATCH 056/394] reintroduced recovery of vouchers --- .../credential-utils/src/recovery_storage.rs | 29 +++++++---- common/credential-utils/src/utils.rs | 51 +++++++++++-------- .../src/coconut/bandwidth/issuance.rs | 15 ++++++ common/nymcoconut/src/scheme/setup.rs | 6 +-- gateway/src/node/client_handling/bandwidth.rs | 4 +- 5 files changed, 69 insertions(+), 36 deletions(-) diff --git a/common/credential-utils/src/recovery_storage.rs b/common/credential-utils/src/recovery_storage.rs index 3c9b8c17af..f003b562cd 100644 --- a/common/credential-utils/src/recovery_storage.rs +++ b/common/credential-utils/src/recovery_storage.rs @@ -8,6 +8,8 @@ use std::fs::{create_dir_all, read_dir, File}; use std::io::{Read, Write}; use std::path::PathBuf; +pub const DUMPED_VOUCHER_EXTENSION: &str = "credentialrecovery"; + pub struct RecoveryStorage { recovery_dir: PathBuf, } @@ -24,8 +26,10 @@ impl RecoveryStorage { let mut paths = vec![]; for entry in entries.flatten() { let path = entry.path(); - if path.is_file() { - paths.push(path) + if let Some(extension) = path.extension() { + if extension == DUMPED_VOUCHER_EXTENSION { + paths.push(path) + } } } @@ -47,15 +51,20 @@ impl RecoveryStorage { Ok(vouchers) } + pub fn voucher_filename(voucher: &IssuanceBandwidthCredential) -> String { + let prefix = voucher.typ().to_string(); + let suffix = voucher.blinded_g1_serial_number_bs58(); + format!("{prefix}-{suffix}.{DUMPED_VOUCHER_EXTENSION}") + } + pub fn insert_voucher(&self, voucher: &IssuanceBandwidthCredential) -> Result { - todo!() - // let file_name = voucher.tx_hash().to_string(); - // let file_path = self.recovery_dir.join(file_name); - // let mut file = File::create(&file_path)?; - // let buff = voucher.to_bytes(); - // file.write_all(&buff)?; - // - // Ok(file_path) + let file_name = Self::voucher_filename(voucher); + let file_path = self.recovery_dir.join(file_name); + let mut file = File::create(&file_path)?; + let buff = voucher.to_recovery_bytes(); + file.write_all(&buff)?; + + Ok(file_path) } pub fn remove_voucher(&self, file_name: String) -> Result<()> { diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index 7668b5f1b7..8e773a3225 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -5,6 +5,7 @@ use nym_bandwidth_controller::acquire::state::State; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::DEFAULT_DATA_DIR; use nym_credential_storage::persistent_storage::PersistentStorage; +use nym_credentials::coconut::bandwidth::CredentialType; use nym_validator_client::nyxd::contract_traits::{ dkg_query_client::EpochState, CoconutBandwidthSigningClient, DkgQueryClient, }; @@ -126,25 +127,33 @@ pub async fn recover_credentials( where C: DkgQueryClient + Send + Sync, { - todo!() - // let mut recovered_amount: u128 = 0; - // for voucher in recovery_storage.unconsumed_vouchers()? { - // let voucher_value = voucher.get_voucher_value(); - // recovered_amount += voucher_value.parse::()?; - // - // let state = State::new(voucher); - // let voucher = state.voucher.tx_hash(); - // if let Err(e) = - // nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await - // { - // error!("Could not recover deposit {voucher} due to {e}, try again later",) - // } else { - // info!("Converted deposit {voucher} to a credential, removing recovery data for it",); - // if let Err(e) = recovery_storage.remove_voucher(voucher.to_string()) { - // warn!("Could not remove recovery data: {e}"); - // } - // } - // } - // - // Ok(recovered_amount) + let mut recovered_amount: u128 = 0; + for voucher in recovery_storage.unconsumed_vouchers()? { + let voucher_value = match voucher.typ() { + CredentialType::Voucher => voucher.get_bandwidth_attribute(), + CredentialType::FreePass => { + error!("unimplemented recovery of free pass credentials"); + continue; + } + }; + recovered_amount += voucher_value.parse::()?; + + let voucher_name = RecoveryStorage::voucher_filename(&voucher); + let state = State::new(voucher); + + if let Err(e) = + nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await + { + error!("Could not recover deposit {voucher_name} due to {e}, try again later",) + } else { + info!( + "Converted deposit {voucher_name} to a credential, removing recovery data for it", + ); + if let Err(err) = recovery_storage.remove_voucher(voucher_name) { + warn!("Could not remove recovery data: {err}"); + } + } + } + + Ok(recovered_amount) } diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 7078d358d5..3ef9352782 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -9,6 +9,7 @@ use crate::coconut::bandwidth::{ }; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; +use bls12_381::G1Projective; use nym_credentials_interface::{ aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, @@ -126,6 +127,16 @@ impl IssuanceBandwidthCredential { )) } + pub fn blind_serial_number_in_g1subgroup(&self) -> G1Projective { + bandwidth_credential_params().gen1() * self.serial_number + } + + pub fn blinded_g1_serial_number_bs58(&self) -> String { + use nym_credentials_interface::Base58; + + self.blind_serial_number_in_g1subgroup().to_bs58() + } + pub fn new_freepass(expiry_date: Option) -> Self { Self::new(FreePassIssuanceData::new(expiry_date)) } @@ -149,6 +160,10 @@ impl IssuanceBandwidthCredential { ] } + pub fn get_bandwidth_attribute(&self) -> String { + self.variant_data.public_value_plain() + } + pub fn prepare_for_signing(&self) -> CredentialSigningData { let params = bandwidth_credential_params(); diff --git a/common/nymcoconut/src/scheme/setup.rs b/common/nymcoconut/src/scheme/setup.rs index 926d8f5ed0..63add88404 100644 --- a/common/nymcoconut/src/scheme/setup.rs +++ b/common/nymcoconut/src/scheme/setup.rs @@ -44,11 +44,11 @@ impl Parameters { }) } - pub(crate) fn gen1(&self) -> &G1Affine { + pub fn gen1(&self) -> &G1Affine { &self.g1 } - pub(crate) fn gen2(&self) -> &G2Affine { + pub fn gen2(&self) -> &G2Affine { &self.g2 } @@ -56,7 +56,7 @@ impl Parameters { &self._g2_prepared_miller } - pub(crate) fn gen_hs(&self) -> &[G1Affine] { + pub fn gen_hs(&self) -> &[G1Affine] { &self.hs } diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index ae8469c504..ce1caed6a7 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -16,13 +16,13 @@ pub enum BandwidthError { #[error("the provided free pass has already expired (expiry was on {expiry_date})")] ExpiredFreePass { expiry_date: OffsetDateTime }, - #[error("failed to pass the bandwidth voucher value: {source}")] + #[error("failed to parse the bandwidth voucher value: {source}")] VoucherValueParsingFailure { #[source] source: ParseIntError, }, - #[error("failed to pass the free pass expiry date: {source}")] + #[error("failed to parse the free pass expiry date: {source}")] ExpiryDateParsingFailure { #[source] source: ParseIntError, From f687ebb0f5505ade07cdc6193968d3fa54cd86e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 8 Feb 2024 15:01:58 +0000 Subject: [PATCH 057/394] persisting the issued credentials --- Cargo.lock | 2 + .../bandwidth-controller/src/acquire/mod.rs | 31 +++++---- common/bandwidth-controller/src/lib.rs | 7 +- common/bandwidth-controller/src/utils.rs | 2 +- common/credential-storage/Cargo.toml | 4 +- .../20240206120000_add_credential_types.sql | 12 ++++ .../credential-storage/src/backends/memory.rs | 65 ++++++++++--------- .../credential-storage/src/backends/sqlite.rs | 50 +++++--------- .../src/ephemeral_storage.rs | 42 +++++------- common/credential-storage/src/models.rs | 47 ++++++++------ .../src/persistent_storage.rs | 37 ++++------- common/credential-storage/src/storage.rs | 26 +------- common/credential-utils/src/utils.rs | 5 +- common/credentials/Cargo.toml | 2 +- .../src/coconut/bandwidth/freepass.rs | 2 +- .../src/coconut/bandwidth/issuance.rs | 8 +++ .../src/coconut/bandwidth/issued.rs | 48 ++++++++++++-- nym-connect/desktop/Cargo.lock | 1 + sdk/rust/nym-sdk/src/bandwidth/client.rs | 10 ++- sdk/rust/nym-sdk/src/mixnet.rs | 4 +- 20 files changed, 210 insertions(+), 195 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eb1d3f96cc..6a90787a0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5343,6 +5343,7 @@ dependencies = [ "sqlx", "thiserror", "tokio", + "zeroize", ] [[package]] @@ -5543,6 +5544,7 @@ dependencies = [ "sqlx", "subtle-encoding", "thiserror", + "time", "tokio", "tokio-stream", "tokio-tungstenite", diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index 5b842fc775..b61bfc2ad4 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use nym_coconut::Base58; +use nym_credential_storage::models::StorableIssuedCredential; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::{CredentialType, IssuanceBandwidthCredential}; use nym_credentials::coconut::utils::obtain_aggregate_signature; @@ -13,6 +13,7 @@ use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use nym_validator_client::nyxd::Coin; use rand::rngs::OsRng; use state::State; +use zeroize::Zeroizing; pub mod state; @@ -43,7 +44,7 @@ where Ok(state) } -pub async fn get_credential( +pub async fn get_bandwidth_voucher( state: &State, client: &C, storage: &St, @@ -54,7 +55,7 @@ where ::StorageError: Send + Sync + 'static, { // temporary - assert!(!state.voucher.typ().is_free_pass()); + assert!(state.voucher.typ().is_voucher()); let epoch_id = client.get_current_epoch().await?.epoch_id; let threshold = client @@ -66,19 +67,21 @@ where let signature = obtain_aggregate_signature(&state.voucher, &coconut_api_clients, threshold).await?; + let issued = state.voucher.to_issued_credential(signature); + + // make sure the data gets zeroized after persisting it + let credential_data = Zeroizing::new(issued.pack_v1()); + let storable = StorableIssuedCredential { + serialization_revision: issued.current_serialization_revision(), + credential_data: credential_data.as_ref(), + credential_type: issued.typ().to_string(), + epoch_id: epoch_id + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; - // we asserted the that the bandwidth credential we obtained is **NOT** the free pass - // so the first public attribute must be the value - let voucher_value = state.voucher.get_plain_public_attributes()[0].clone(); storage - .insert_coconut_credential( - voucher_value, - CredentialType::Voucher.to_string(), - state.voucher.get_private_attributes()[0].to_bs58(), - state.voucher.get_private_attributes()[1].to_bs58(), - signature.to_bs58(), - epoch_id.to_string(), - ) + .insert_issued_credential(storable) .await .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err))) } diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 2902d93451..3fa91802ee 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -1,10 +1,9 @@ -// Copyright 2021-2023 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; use crate::utils::stored_credential_to_issued_bandwidth; use log::{error, warn}; -use nym_credential_storage::error::StorageError; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; @@ -12,7 +11,6 @@ use nym_credentials_interface::VerificationKey; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; -use std::str::FromStr; pub mod acquire; pub mod error; @@ -69,8 +67,7 @@ impl BandwidthController { .await .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))?; - let epoch_id = u64::from_str(&retrieved_credential.epoch_id) - .map_err(|_| StorageError::InconsistentData)?; + let epoch_id = retrieved_credential.epoch_id as EpochId; let credential_id = retrieved_credential.id; let issued_bandwidth = stored_credential_to_issued_bandwidth(retrieved_credential)?; diff --git a/common/bandwidth-controller/src/utils.rs b/common/bandwidth-controller/src/utils.rs index 7f24f8e141..690466daa5 100644 --- a/common/bandwidth-controller/src/utils.rs +++ b/common/bandwidth-controller/src/utils.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use nym_credential_storage::models::StoredIssuedCredential; +use nym_credential_storage::models::{StorableIssuedCredential, StoredIssuedCredential}; use nym_credentials::coconut::bandwidth::IssuedBandwidthCredential; use nym_validator_client::nym_api::EpochId; diff --git a/common/credential-storage/Cargo.toml b/common/credential-storage/Cargo.toml index 9beb030e22..d478759ee7 100644 --- a/common/credential-storage/Cargo.toml +++ b/common/credential-storage/Cargo.toml @@ -11,7 +11,9 @@ async-trait = { workspace = true } log = { workspace = true } thiserror = { workspace = true } -tokio = { version = "1.24.1", features = ["sync"]} +tokio = { workspace = true, features = ["sync"]} +zeroize = { workspace = true, features = ["zeroize_derive"] } + [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] workspace = true diff --git a/common/credential-storage/migrations/20240206120000_add_credential_types.sql b/common/credential-storage/migrations/20240206120000_add_credential_types.sql index a72048344f..a75acca881 100644 --- a/common/credential-storage/migrations/20240206120000_add_credential_types.sql +++ b/common/credential-storage/migrations/20240206120000_add_credential_types.sql @@ -3,3 +3,15 @@ * SPDX-License-Identifier: Apache-2.0 */ +DROP TABLE coconut_credentials; +CREATE TABLE coconut_credentials +( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + +-- introduce a way for us to introduce breaking changes in serialization + serialization_revision INTEGER NOT NULL, + credential_type TEXT NOT NULL, + credential_data BLOB NOT NULL, + epoch_id TEXT NOT NULL, + consumed BOOLEAN NOT NULL +); \ No newline at end of file diff --git a/common/credential-storage/src/backends/memory.rs b/common/credential-storage/src/backends/memory.rs index 2dbdff0925..80538337c8 100644 --- a/common/credential-storage/src/backends/memory.rs +++ b/common/credential-storage/src/backends/memory.rs @@ -1,59 +1,60 @@ -// Copyright 2023 - Nym Technologies SA +// Copyright 2023-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::models::CoconutCredential; +use crate::models::StoredIssuedCredential; use std::sync::Arc; use tokio::sync::RwLock; #[derive(Clone)] pub struct CoconutCredentialManager { - inner: Arc>>, + inner: Arc>, +} + +#[derive(Default)] +struct CoconutCredentialManagerInner { + data: Vec, + _next_id: i64, +} + +impl CoconutCredentialManagerInner { + fn next_id(&mut self) -> i64 { + let next = self._next_id; + self._next_id += 1; + next + } } impl CoconutCredentialManager { /// Creates new empty instance of the `CoconutCredentialManager`. pub fn new() -> Self { CoconutCredentialManager { - inner: Arc::new(RwLock::new(Vec::new())), + inner: Default::default(), } } - /// Inserts provided signature into the database. - /// - /// # Arguments - /// - /// * `voucher_value`: Plaintext bandwidth value of the credential. - /// * `voucher_info`: Plaintext information of the credential. - /// * `serial_number`: Base58 representation of the serial number attribute. - /// * `binding_number`: Base58 representation of the binding number attribute. - /// * `signature`: Coconut credential in the form of a signature. - pub async fn insert_coconut_credential( + pub async fn insert_issued_credential( &self, - voucher_value: String, - voucher_info: String, - serial_number: String, - binding_number: String, - signature: String, - epoch_id: String, + credential_type: String, + serialization_revision: u8, + credential_data: &[u8], + epoch_id: u32, ) { - let mut creds = self.inner.write().await; - let id = creds.len() as i64; - creds.push(CoconutCredential { + let mut inner = self.inner.write().await; + let id = inner.next_id(); + inner.data.push(StoredIssuedCredential { id, - voucher_value, - voucher_info, - serial_number, - binding_number, - signature, + serialization_revision, + credential_data: credential_data.to_vec(), + credential_type, epoch_id, consumed: false, - }); + }) } /// Tries to retrieve one of the stored, unused credentials. - pub async fn get_next_coconut_credential(&self) -> Option { + pub async fn get_next_unspent_credential(&self) -> Option { let creds = self.inner.read().await; - creds.iter().find(|c| !c.consumed).cloned() + creds.data.iter().find(|c| !c.consumed).cloned() } /// Consumes in the database the specified credential. @@ -63,7 +64,7 @@ impl CoconutCredentialManager { /// * `id`: Database id. pub async fn consume_coconut_credential(&self, id: i64) { let mut creds = self.inner.write().await; - if let Some(cred) = creds.get_mut(id as usize) { + if let Some(cred) = creds.data.get_mut(id as usize) { cred.consumed = true; } } diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs index f64ef811b0..d007c03c16 100644 --- a/common/credential-storage/src/backends/sqlite.rs +++ b/common/credential-storage/src/backends/sqlite.rs @@ -1,7 +1,7 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::models::CoconutCredential; +use crate::models::StoredIssuedCredential; #[derive(Clone)] pub struct CoconutCredentialManager { @@ -18,43 +18,29 @@ impl CoconutCredentialManager { CoconutCredentialManager { connection_pool } } - /// Inserts provided signature into the database. - /// - /// # Arguments - /// - /// * `voucher_value`: Plaintext bandwidth value of the credential. - /// * `voucher_info`: Plaintext information of the credential. - /// * `serial_number`: Base58 representation of the serial number attribute. - /// * `binding_number`: Base58 representation of the binding number attribute. - /// * `signature`: Coconut credential in the form of a signature. - pub async fn insert_coconut_credential( + pub async fn insert_issued_credential( &self, - voucher_value: String, - voucher_info: String, - serial_number: String, - binding_number: String, - signature: String, - epoch_id: String, + credential_type: String, + serialization_revision: u8, + credential_data: &[u8], + epoch_id: u32, ) -> Result<(), sqlx::Error> { sqlx::query!( - "INSERT INTO coconut_credentials(voucher_value, voucher_info, serial_number, binding_number, signature, epoch_id, consumed) VALUES (?, ?, ?, ?, ?, ?, ?)", - voucher_value, voucher_info, serial_number, binding_number, signature, epoch_id, false - ) - .execute(&self.connection_pool) - .await?; + r#" + INSERT INTO coconut_credentials(serialization_revision, credential_type, credential_data, epoch_id, consumed) + VALUES (?, ?, ?, ?, false) + "#, + serialization_revision, credential_type, credential_data, epoch_id + ).execute(&self.connection_pool).await?; Ok(()) } - /// Tries to retrieve one of the stored, unused credentials. - pub async fn get_next_coconut_credential( + pub async fn get_next_unspent_credential( &self, - ) -> Result, sqlx::Error> { - sqlx::query_as!( - CoconutCredential, - "SELECT * FROM coconut_credentials WHERE NOT consumed" - ) - .fetch_optional(&self.connection_pool) - .await + ) -> Result, sqlx::Error> { + sqlx::query_as("SELECT * FROM coconut_credentials WHERE NOT consumed LIMIT 1") + .fetch_optional(&self.connection_pool) + .await } /// Consumes in the database the specified credential. diff --git a/common/credential-storage/src/ephemeral_storage.rs b/common/credential-storage/src/ephemeral_storage.rs index 9a4dd561ba..aa6756ac78 100644 --- a/common/credential-storage/src/ephemeral_storage.rs +++ b/common/credential-storage/src/ephemeral_storage.rs @@ -3,7 +3,7 @@ use crate::backends::memory::CoconutCredentialManager; use crate::error::StorageError; -use crate::models::{CoconutCredential, StoredIssuedCredential}; +use crate::models::{StorableIssuedCredential, StoredIssuedCredential}; use crate::storage::Storage; use async_trait::async_trait; @@ -27,43 +27,31 @@ impl Default for EphemeralStorage { impl Storage for EphemeralStorage { type StorageError = StorageError; - async fn insert_coconut_credential( + async fn insert_issued_credential<'a>( &self, - voucher_value: String, - voucher_info: String, - serial_number: String, - binding_number: String, - signature: String, - epoch_id: String, + bandwidth_credential: StorableIssuedCredential<'a>, ) -> Result<(), StorageError> { self.coconut_credential_manager - .insert_coconut_credential( - voucher_value, - voucher_info, - serial_number, - binding_number, - signature, - epoch_id, + .insert_issued_credential( + bandwidth_credential.credential_type, + bandwidth_credential.serialization_revision, + bandwidth_credential.credential_data, + bandwidth_credential.epoch_id, ) .await; - Ok(()) } - async fn get_next_coconut_credential(&self) -> Result { - let credential = self - .coconut_credential_manager - .get_next_coconut_credential() - .await - .ok_or(StorageError::NoCredential)?; - - Ok(credential) - } - async fn get_next_unspent_credential( &self, ) -> Result { - todo!() + let credential = self + .coconut_credential_manager + .get_next_unspent_credential() + .await + .ok_or(StorageError::NoCredential)?; + + Ok(credential) } async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { diff --git a/common/credential-storage/src/models.rs b/common/credential-storage/src/models.rs index 47372dd2b6..2695a190ad 100644 --- a/common/credential-storage/src/models.rs +++ b/common/credential-storage/src/models.rs @@ -1,31 +1,38 @@ // Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -#[derive(Clone)] -pub struct CoconutCredential { - #[allow(dead_code)] - pub id: i64, - pub voucher_value: String, - pub voucher_info: String, - pub serial_number: String, - pub binding_number: String, - pub signature: String, - pub epoch_id: String, - pub consumed: bool, -} +use zeroize::{Zeroize, ZeroizeOnDrop}; + +// #[derive(Clone)] +// pub struct CoconutCredential { +// #[allow(dead_code)] +// pub id: i64, +// pub voucher_value: String, +// pub voucher_info: String, +// pub serial_number: String, +// pub binding_number: String, +// pub signature: String, +// pub epoch_id: String, +// pub consumed: bool, +// } #[cfg_attr(not(target_arch = "wasm32"), derive(sqlx::FromRow))] +#[derive(Zeroize, ZeroizeOnDrop, Clone)] pub struct StoredIssuedCredential { pub id: i64, - pub serial_number: String, - pub binding_number: String, + pub serialization_revision: u8, + pub credential_data: Vec, + pub credential_type: String, - pub signature: String, - - pub variant_type: String, - pub serialized_variant_data: String, - - pub epoch_id: String, + pub epoch_id: u32, pub consumed: bool, } + +pub struct StorableIssuedCredential<'a> { + pub serialization_revision: u8, + pub credential_data: &'a [u8], + pub credential_type: String, + + pub epoch_id: u32, +} diff --git a/common/credential-storage/src/persistent_storage.rs b/common/credential-storage/src/persistent_storage.rs index 4fffc60777..b6772fdf56 100644 --- a/common/credential-storage/src/persistent_storage.rs +++ b/common/credential-storage/src/persistent_storage.rs @@ -5,7 +5,7 @@ use crate::backends::sqlite::CoconutCredentialManager; use crate::error::StorageError; use crate::storage::Storage; -use crate::models::{CoconutCredential, StoredIssuedCredential}; +use crate::models::{StorableIssuedCredential, StoredIssuedCredential}; use async_trait::async_trait; use log::{debug, error}; use sqlx::ConnectOptions; @@ -58,45 +58,34 @@ impl PersistentStorage { impl Storage for PersistentStorage { type StorageError = StorageError; - async fn insert_coconut_credential( + async fn insert_issued_credential<'a>( &self, - voucher_value: String, - voucher_info: String, - serial_number: String, - binding_number: String, - signature: String, - epoch_id: String, - ) -> Result<(), StorageError> { + bandwidth_credential: StorableIssuedCredential<'a>, + ) -> Result<(), Self::StorageError> { self.coconut_credential_manager - .insert_coconut_credential( - voucher_value, - voucher_info, - serial_number, - binding_number, - signature, - epoch_id, + .insert_issued_credential( + bandwidth_credential.credential_type, + bandwidth_credential.serialization_revision, + bandwidth_credential.credential_data, + bandwidth_credential.epoch_id, ) .await?; Ok(()) } - async fn get_next_coconut_credential(&self) -> Result { + async fn get_next_unspent_credential( + &self, + ) -> Result { let credential = self .coconut_credential_manager - .get_next_coconut_credential() + .get_next_unspent_credential() .await? .ok_or(StorageError::NoCredential)?; Ok(credential) } - async fn get_next_unspent_credential( - &self, - ) -> Result { - todo!() - } - async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { self.coconut_credential_manager .consume_coconut_credential(id) diff --git a/common/credential-storage/src/storage.rs b/common/credential-storage/src/storage.rs index af16a4a8de..64fe0d6e82 100644 --- a/common/credential-storage/src/storage.rs +++ b/common/credential-storage/src/storage.rs @@ -1,7 +1,7 @@ // Copyright 2022 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use crate::models::{CoconutCredential, StoredIssuedCredential}; +use crate::models::{StorableIssuedCredential, StoredIssuedCredential}; use async_trait::async_trait; use std::error::Error; @@ -9,31 +9,11 @@ use std::error::Error; pub trait Storage: Send + Sync { type StorageError: Error; - /// Inserts provided signature into the database. - /// - /// # Arguments - /// - /// * `voucher_value`: How much bandwidth is in the credential. - /// * `voucher_info`: What type of credential it is. - /// * `serial_number`: Serial number of the credential. - /// * `binding_number`: Binding number of the credential. - /// * `signature`: Coconut credential in the form of a signature. - /// * `epoch_id`: The epoch when it was signed. - #[deprecated] - async fn insert_coconut_credential( + async fn insert_issued_credential<'a>( &self, - voucher_value: String, - voucher_info: String, - serial_number: String, - binding_number: String, - signature: String, - epoch_id: String, + bandwidth_credential: StorableIssuedCredential<'a>, ) -> Result<(), Self::StorageError>; - /// Tries to retrieve one of the stored, unused credentials. - #[deprecated] - async fn get_next_coconut_credential(&self) -> Result; - /// Tries to retrieve one of the stored, unused credentials. async fn get_next_unspent_credential( &self, diff --git a/common/credential-utils/src/utils.rs b/common/credential-utils/src/utils.rs index 8e773a3225..2b2aaba9f7 100644 --- a/common/credential-utils/src/utils.rs +++ b/common/credential-utils/src/utils.rs @@ -44,7 +44,7 @@ where let state = nym_bandwidth_controller::acquire::deposit(client, amount.clone()).await?; - if nym_bandwidth_controller::acquire::get_credential(&state, client, persistent_storage) + if nym_bandwidth_controller::acquire::get_bandwidth_voucher(&state, client, persistent_storage) .await .is_err() { @@ -142,7 +142,8 @@ where let state = State::new(voucher); if let Err(e) = - nym_bandwidth_controller::acquire::get_credential(&state, client, shared_storage).await + nym_bandwidth_controller::acquire::get_bandwidth_voucher(&state, client, shared_storage) + .await { error!("Could not recover deposit {voucher_name} due to {e}, try again later",) } else { diff --git a/common/credentials/Cargo.toml b/common/credentials/Cargo.toml index bc096fa5a9..053e0f80fc 100644 --- a/common/credentials/Cargo.toml +++ b/common/credentials/Cargo.toml @@ -13,6 +13,7 @@ cosmrs = { workspace = true } thiserror = { workspace = true } log = { workspace = true } time = { workspace = true, features = ["serde"] } +serde = { workspace = true, features = ["derive"] } zeroize = { workspace = true } # I guess temporarily until we get serde support in coconut up and running @@ -20,7 +21,6 @@ nym-credentials-interface = { path = "../credentials-interface" } nym-crypto = { path = "../crypto", features = ["rand", "asymmetric", "serde"] } nym-api-requests = { path = "../../nym-api/nym-api-requests" } nym-validator-client = { path = "../client-libs/validator-client", default-features = false } -serde = { workspace = true, features = ["derive"] } [dev-dependencies] rand = "0.7.3" diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 67fab7197b..0a1707ba3b 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -30,7 +30,7 @@ impl FreePassIssuedData { } } -#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +#[derive(Zeroize, Serialize, Deserialize)] pub struct FreePassIssuanceData { /// the plain validity value of this credential expressed as unix timestamp #[zeroize(skip)] diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 3ef9352782..02eb1a3c6c 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -238,9 +238,17 @@ impl IssuanceBandwidthCredential { .map_err(Error::SignatureAggregationError) } + // also drops self after the conversion pub fn into_issued_credential( self, aggregate_signature: Signature, + ) -> IssuedBandwidthCredential { + self.to_issued_credential(aggregate_signature) + } + + pub fn to_issued_credential( + &self, + aggregate_signature: Signature, ) -> IssuedBandwidthCredential { IssuedBandwidthCredential::new( self.serial_number, diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 8a66e36365..62d5a4ecc7 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -1,23 +1,25 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use crate::coconut::bandwidth::bandwidth_credential_params; use crate::coconut::bandwidth::freepass::FreePassIssuedData; use crate::coconut::bandwidth::issuance::{ BandwidthCredentialIssuanceDataVariant, IssuanceBandwidthCredential, }; use crate::coconut::bandwidth::voucher::BandwidthVoucherIssuedData; -use crate::coconut::bandwidth::{ - bandwidth_credential_params, CredentialSpendingData, CredentialType, -}; +use crate::coconut::bandwidth::{CredentialSpendingData, CredentialType}; +use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; +use nym_credentials_interface::prove_bandwidth_credential; use nym_credentials_interface::{ - prove_bandwidth_credential, Parameters, PrivateAttribute, PublicAttribute, Signature, - VerificationKey, + Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey, }; use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; -#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +pub const CURRENT_SERIALIZATION_REVISION: u8 = 1; + +#[derive(Zeroize, Serialize, Deserialize)] pub enum BandwidthCredentialIssuedDataVariant { Voucher(BandwidthVoucherIssuedData), FreePass(FreePassIssuedData), @@ -68,13 +70,15 @@ impl BandwidthCredentialIssuedDataVariant { } // the only important thing to zeroize here are the private attributes, the rest can be made fully public for what we're concerned -#[derive(Zeroize, ZeroizeOnDrop)] +#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct IssuedBandwidthCredential { // private attributes /// a random secret value generated by the client used for double-spending detection + #[serde(with = "scalar_serde_helper")] serial_number: PrivateAttribute, /// a random secret value generated by the client used to bind multiple credentials together + #[serde(with = "scalar_serde_helper")] binding_number: PrivateAttribute, /// the underlying aggregated signature on the attributes @@ -85,6 +89,7 @@ pub struct IssuedBandwidthCredential { variant_data: BandwidthCredentialIssuedDataVariant, /// type of the bandwdith credential hashed onto a scalar + #[serde(with = "scalar_serde_helper")] type_prehashed: PublicAttribute, } @@ -105,6 +110,28 @@ impl IssuedBandwidthCredential { } } + pub fn current_serialization_revision(&self) -> u8 { + CURRENT_SERIALIZATION_REVISION + } + + /// Pack (serialize) this credential data into a stream of bytes using v1 serializer. + pub fn pack_v1(&self) -> Vec { + use bincode::Options; + // safety: our data format is stable and thus the serialization should not fail + make_storable_bincode_serializer().serialize(self).unwrap() + } + + /// Unpack (deserialize) the credential data from the given bytes using v1 serializer. + pub fn unpack_v1(bytes: &[u8]) -> Result { + use bincode::Options; + Ok(make_storable_bincode_serializer().deserialize(bytes)?) + } + + pub fn randomise_signature(&mut self) { + let signature_prime = self.signature.randomise(bandwidth_credential_params()); + self.signature = signature_prime.0 + } + pub fn default_parameters() -> Parameters { IssuanceBandwidthCredential::default_parameters() } @@ -142,3 +169,10 @@ impl IssuedBandwidthCredential { }) } } + +fn make_storable_bincode_serializer() -> impl bincode::Options { + use bincode::Options; + bincode::DefaultOptions::new() + .with_big_endian() + .with_varint_encoding() +} diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 2cfd6ab068..ca362dc721 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3915,6 +3915,7 @@ dependencies = [ "sqlx", "thiserror", "tokio", + "zeroize", ] [[package]] diff --git a/sdk/rust/nym-sdk/src/bandwidth/client.rs b/sdk/rust/nym-sdk/src/bandwidth/client.rs index c5756e0cdc..5051e5a1d4 100644 --- a/sdk/rust/nym-sdk/src/bandwidth/client.rs +++ b/sdk/rust/nym-sdk/src/bandwidth/client.rs @@ -57,7 +57,7 @@ where pub async fn acquire(&self, amount: u128) -> Result<()> { let amount = Coin::new(amount, &self.network_details.chain_details.mix_denom.base); let state = nym_bandwidth_controller::acquire::deposit(&self.client, amount).await?; - nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) + nym_bandwidth_controller::acquire::get_bandwidth_voucher(&state, &self.client, self.storage) .await .map_err(|reason| Error::UnconvertedDeposit { reason, @@ -71,8 +71,12 @@ where let voucher = IssuanceBandwidthCredential::try_from_recovered_bytes(voucher_blob) .map_err(|_| Error::InvalidVoucherBlob)?; let state = State::new(voucher); - nym_bandwidth_controller::acquire::get_credential(&state, &self.client, self.storage) - .await?; + nym_bandwidth_controller::acquire::get_bandwidth_voucher( + &state, + &self.client, + self.storage, + ) + .await?; Ok(()) } diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index 9dc4dd9681..b54ef462ee 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -59,8 +59,8 @@ pub use nym_client_core::{ config::{GatewayEndpointConfig, GroupBy}, }; pub use nym_credential_storage::{ - ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage, models::CoconutCredential, - storage::Storage as CredentialStorage, + ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage, + models::StoredIssuedCredential, storage::Storage as CredentialStorage, }; pub use nym_network_defaults::NymNetworkDetails; pub use nym_socks5_client_core::config::Socks5; From ad9aee0ec0e33e843ba4bb12f9c6f0448e051069 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 8 Feb 2024 16:10:10 +0000 Subject: [PATCH 058/394] missing serialization --- Cargo.lock | 1 + common/bandwidth-controller/src/error.rs | 3 + common/bandwidth-controller/src/utils.rs | 41 ++--- common/credentials-interface/Cargo.toml | 1 + common/credentials-interface/src/lib.rs | 26 ++- .../src/coconut/bandwidth/issuance.rs | 8 +- common/nymcoconut/src/lib.rs | 1 + common/nymcoconut/src/scheme/keygen.rs | 1 - gateway/gateway-requests/Cargo.toml | 1 + gateway/gateway-requests/src/lib.rs | 5 +- gateway/gateway-requests/src/models.rs | 153 +++++++++++++++++- gateway/gateway-requests/src/types.rs | 16 +- nym-connect/desktop/Cargo.lock | 1 + nym-wallet/Cargo.lock | 1 + 14 files changed, 215 insertions(+), 44 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6a90787a0f..a91515295e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5388,6 +5388,7 @@ dependencies = [ "bls12_381", "nym-coconut", "serde", + "thiserror", ] [[package]] diff --git a/common/bandwidth-controller/src/error.rs b/common/bandwidth-controller/src/error.rs index 7b4e787cb5..4adda09b0f 100644 --- a/common/bandwidth-controller/src/error.rs +++ b/common/bandwidth-controller/src/error.rs @@ -45,4 +45,7 @@ pub enum BandwidthControllerError { #[error("Threshold not set yet")] NoThreshold, + + #[error("can't handle recovering storage with revision {stored}. {expected} was expected")] + UnsupportedCredentialStorageRevision { stored: u8, expected: u8 }, } diff --git a/common/bandwidth-controller/src/utils.rs b/common/bandwidth-controller/src/utils.rs index 690466daa5..89891dba48 100644 --- a/common/bandwidth-controller/src/utils.rs +++ b/common/bandwidth-controller/src/utils.rs @@ -2,40 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::BandwidthControllerError; -use nym_credential_storage::models::{StorableIssuedCredential, StoredIssuedCredential}; +use nym_credential_storage::models::StoredIssuedCredential; +use nym_credentials::coconut::bandwidth::issued::CURRENT_SERIALIZATION_REVISION; use nym_credentials::coconut::bandwidth::IssuedBandwidthCredential; -use nym_validator_client::nym_api::EpochId; pub fn stored_credential_to_issued_bandwidth( cred: StoredIssuedCredential, ) -> Result { - /* - let bandwidth_credential = self - .storage - .get_next_coconut_credential() - .await - .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))?; - let voucher_value = u64::from_str(&bandwidth_credential.voucher_value) - .map_err(|_| StorageError::InconsistentData)?; - let voucher_info = bandwidth_credential.voucher_info.clone(); - let serial_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( - bandwidth_credential.serial_number, - )?); - let binding_number = Zeroizing::new(nym_coconut_interface::Attribute::try_from_bs58( - bandwidth_credential.binding_number, - )?); - let signature = - nym_coconut_interface::Signature::try_from_bs58(bandwidth_credential.signature)?; - let epoch_id = u64::from_str(&bandwidth_credential.epoch_id) - .map_err(|_| StorageError::InconsistentData)?; + if cred.serialization_revision != CURRENT_SERIALIZATION_REVISION { + return Err( + BandwidthControllerError::UnsupportedCredentialStorageRevision { + stored: cred.serialization_revision, + expected: CURRENT_SERIALIZATION_REVISION, + }, + ); + } - */ - todo!() -} - -pub fn issued_bandwidth_to_stored_credential( - issued: IssuedBandwidthCredential, - epoch_id: EpochId, -) -> StoredIssuedCredential { - todo!() + Ok(IssuedBandwidthCredential::unpack_v1(&cred.credential_data)?) } diff --git a/common/credentials-interface/Cargo.toml b/common/credentials-interface/Cargo.toml index 789552ebff..5393ea37fd 100644 --- a/common/credentials-interface/Cargo.toml +++ b/common/credentials-interface/Cargo.toml @@ -13,5 +13,6 @@ license.workspace = true [dependencies] bls12_381 = { workspace = true, default-features = false } serde = { workspace = true, features = ["derive"] } +thiserror = { workspace = true } nym-coconut = { path = "../nymcoconut" } diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index f962bf8c9e..36af1ef380 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -4,9 +4,11 @@ use bls12_381::Scalar; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; +use std::str::FromStr; +use thiserror::Error; pub use nym_coconut::{ - aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, + aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, keygen, prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, @@ -20,12 +22,30 @@ pub const FREE_PASS_INFO_TYPE: &str = "FreeBandwidthPass"; // fn prove_credential(&self) -> Result<(), ()>; // } -#[derive(Copy, Clone, Debug, Serialize, Deserialize)] +#[derive(Debug, Error)] +#[error("{0} is not a valid credential type")] +pub struct UnknownCredentialType(String); + +#[derive(Copy, Clone, Debug, Serialize, Deserialize, PartialEq, Eq, Hash)] pub enum CredentialType { Voucher, FreePass, } +impl FromStr for CredentialType { + type Err = UnknownCredentialType; + + fn from_str(s: &str) -> Result { + if s == VOUCHER_INFO_TYPE { + Ok(CredentialType::Voucher) + } else if s == FREE_PASS_INFO_TYPE { + Ok(CredentialType::FreePass) + } else { + Err(UnknownCredentialType(s.to_string())) + } + } +} + impl CredentialType { pub fn validate(&self, type_plain: &str) -> bool { match self { @@ -63,7 +83,7 @@ pub struct CredentialSigningData { pub typ: CredentialType, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct CredentialSpendingData { pub embedded_private_attributes: usize, diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 02eb1a3c6c..1bba208cc5 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -127,6 +127,10 @@ impl IssuanceBandwidthCredential { )) } + pub fn new_freepass(expiry_date: Option) -> Self { + Self::new(FreePassIssuanceData::new(expiry_date)) + } + pub fn blind_serial_number_in_g1subgroup(&self) -> G1Projective { bandwidth_credential_params().gen1() * self.serial_number } @@ -137,10 +141,6 @@ impl IssuanceBandwidthCredential { self.blind_serial_number_in_g1subgroup().to_bs58() } - pub fn new_freepass(expiry_date: Option) -> Self { - Self::new(FreePassIssuanceData::new(expiry_date)) - } - pub fn typ(&self) -> CredentialType { self.variant_data.info() } diff --git a/common/nymcoconut/src/lib.rs b/common/nymcoconut/src/lib.rs index ed258cd557..4ac8245c37 100644 --- a/common/nymcoconut/src/lib.rs +++ b/common/nymcoconut/src/lib.rs @@ -14,6 +14,7 @@ pub use scheme::issuance::blind_sign; pub use scheme::issuance::prepare_blind_sign; pub use scheme::issuance::verify_partial_blind_signature; pub use scheme::issuance::BlindSignRequest; +pub use scheme::keygen::keygen; pub use scheme::keygen::ttp_keygen; pub use scheme::keygen::KeyPair; pub use scheme::keygen::SecretKey; diff --git a/common/nymcoconut/src/scheme/keygen.rs b/common/nymcoconut/src/scheme/keygen.rs index 966ebb141c..50d735ef92 100644 --- a/common/nymcoconut/src/scheme/keygen.rs +++ b/common/nymcoconut/src/scheme/keygen.rs @@ -565,7 +565,6 @@ impl TryFrom<&[u8]> for KeyPair { /// Generate a single Coconut keypair ((x, y0, y1...), (g2^x, g2^y0, ...)). /// It is not suitable for threshold credentials as all subsequent calls to `keygen` generate keys /// that are independent of each other. -#[cfg(test)] pub fn keygen(params: &Parameters) -> KeyPair { let attributes = params.gen_hs().len(); diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index d63170628e..e771a71de1 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -32,3 +32,4 @@ nym-credentials-interface = { path = "../../common/credentials-interface" } workspace = true default-features = false + diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index 9bb25dc45c..e27d272f23 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -15,7 +15,10 @@ pub mod types; /// Defines the current version of the communication protocol between gateway and clients. /// It has to be incremented for any breaking change. -pub const PROTOCOL_VERSION: u8 = 1; +// history: +// 1 - initial release +// 2 - changes to client credentials structure +pub const PROTOCOL_VERSION: u8 = 2; pub type GatewayMac = HmacOutput; diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 4e1df1d61e..6e06aabc7e 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -3,10 +3,10 @@ use crate::GatewayRequestsError; use nym_credentials::coconut::bandwidth::CredentialSpendingData; -use nym_credentials_interface::CoconutError; +use nym_credentials_interface::{CoconutError, VerifyCredentialRequest}; use serde::{Deserialize, Serialize}; -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct CredentialSpendingWithEpoch { /// The cryptographic material required for spending the underlying credential. pub data: CredentialSpendingData, @@ -16,6 +16,23 @@ pub struct CredentialSpendingWithEpoch { pub epoch_id: u64, } +// just a helper macro for checking required length and advancing the buffer +macro_rules! ensure_len_and_advance { + ($b:expr, $n:expr) => {{ + if $b.len() < $n { + return Err(GatewayRequestsError::CredentialDeserializationFailureEOF); + } + // create binding to the desired range + let bytes = &$b[..$n]; + + // update the initial binding + + $b = &$b[$n..]; + + bytes + }}; +} + impl CredentialSpendingWithEpoch { pub fn new(data: CredentialSpendingData, epoch_id: u64) -> Self { CredentialSpendingWithEpoch { data, epoch_id } @@ -39,10 +56,138 @@ impl CredentialSpendingWithEpoch { } pub fn to_bytes(&self) -> Vec { - todo!() + // simple length prefixed serialization + // TODO: change it to a standard format instead + let mut bytes = Vec::new(); + + let embedded_private = (self.data.embedded_private_attributes as u32).to_be_bytes(); + let theta = self.data.verify_credential_request.to_bytes(); + let theta_len = (theta.len() as u32).to_be_bytes(); + + let public = (self.data.public_attributes_plain.len() as u32).to_be_bytes(); + let typ = self.data.typ.to_string(); + let typ_bytes = typ.as_bytes(); + let typ_len = (typ_bytes.len() as u32).to_be_bytes(); + + bytes.extend_from_slice(&embedded_private); + bytes.extend_from_slice(&theta_len); + bytes.extend_from_slice(&theta); + bytes.extend_from_slice(&public); + + for pub_element in &self.data.public_attributes_plain { + let bytes_el = pub_element.as_bytes(); + let len = (bytes_el.len() as u32).to_be_bytes(); + + bytes.extend_from_slice(&len); + bytes.extend_from_slice(bytes_el); + } + + bytes.extend_from_slice(&typ_len); + bytes.extend_from_slice(typ_bytes); + bytes.extend_from_slice(&self.epoch_id.to_be_bytes()); + + bytes } pub fn try_from_bytes(raw: &[u8]) -> Result { - todo!() + // initial binding + let mut b = raw; + let embedded_private_bytes = ensure_len_and_advance!(b, 4); + let embedded_private_attributes = + u32::from_be_bytes(embedded_private_bytes.try_into().unwrap()) as usize; + + let theta_len_bytes = ensure_len_and_advance!(b, 4); + let theta_len = u32::from_be_bytes(theta_len_bytes.try_into().unwrap()) as usize; + + let theta_bytes = ensure_len_and_advance!(b, theta_len); + let theta = VerifyCredentialRequest::from_bytes(theta_bytes) + .map_err(GatewayRequestsError::CredentialDeserializationFailureMalformedTheta)?; + + let public_bytes = ensure_len_and_advance!(b, 4); + let public = u32::from_be_bytes(public_bytes.try_into().unwrap()) as usize; + + let mut public_attributes_plain = Vec::with_capacity(public); + for _ in 0..public { + let element_len_bytes = ensure_len_and_advance!(b, 4); + let element_len = u32::from_be_bytes(element_len_bytes.try_into().unwrap()) as usize; + + let element_bytes = ensure_len_and_advance!(b, element_len); + let element = String::from_utf8(element_bytes.to_vec())?; + public_attributes_plain.push(element); + } + + let typ_len_bytes = ensure_len_and_advance!(b, 4); + let typ_len = u32::from_be_bytes(typ_len_bytes.try_into().unwrap()) as usize; + + let typ_bytes = ensure_len_and_advance!(b, typ_len); + let raw_typ = String::from_utf8(typ_bytes.to_vec())?; + let typ = raw_typ.parse()?; + + // tell the linter to chill out in for this last iteration + #[allow(unused_assignments)] + let epoch_id_bytes = ensure_len_and_advance!(b, 8); + let epoch_id = u64::from_be_bytes(epoch_id_bytes.try_into().unwrap()); + + Ok(CredentialSpendingWithEpoch { + data: CredentialSpendingData { + embedded_private_attributes, + verify_credential_request: theta, + public_attributes_plain, + typ, + }, + epoch_id, + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use nym_credentials::coconut::bandwidth::bandwidth_credential_params; + use nym_credentials::IssuanceBandwidthCredential; + use nym_credentials_interface::{blind_sign, hash_to_scalar}; + + #[test] + fn credential_roundtrip() { + // make valid request + let params = bandwidth_credential_params(); + let keypair = nym_credentials_interface::keygen(params); + + let issuance = IssuanceBandwidthCredential::new_freepass(None); + let sig_req = issuance.prepare_for_signing(); + let pub_attrs_hashed = sig_req + .public_attributes_plain + .iter() + .map(hash_to_scalar) + .collect::>(); + let pub_attrs = pub_attrs_hashed.iter().collect::>(); + let blind_sig = blind_sign( + params, + keypair.secret_key(), + &sig_req.blind_sign_request, + &pub_attrs, + ) + .unwrap(); + let sig = blind_sig + .unblind( + keypair.verification_key(), + &sig_req.pedersen_commitments_openings, + ) + .unwrap(); + + let issued = issuance.into_issued_credential(sig); + let spending = issued + .prepare_for_spending(keypair.verification_key()) + .unwrap(); + + let with_epoch = CredentialSpendingWithEpoch { + data: spending, + epoch_id: 42, + }; + + let bytes = with_epoch.to_bytes(); + let recovered = CredentialSpendingWithEpoch::try_from_bytes(&bytes).unwrap(); + + assert_eq!(with_epoch, recovered); } } diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 0c5542464e..67ccb148f7 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -1,4 +1,4 @@ -// Copyright 2020 - Nym Technologies SA +// Copyright 2020-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 use crate::authentication::encrypted_address::EncryptedAddressBytes; @@ -8,6 +8,7 @@ use crate::registration::handshake::SharedKeys; use crate::{GatewayMacSize, PROTOCOL_VERSION}; use log::error; use nym_credentials::coconut::bandwidth::CredentialSpendingData; +use nym_credentials_interface::{CoconutError, UnknownCredentialType}; use nym_crypto::generic_array::typenum::Unsigned; use nym_crypto::hmac::recompute_keyed_hmac_and_verify_tag; use nym_crypto::symmetric::stream_cipher; @@ -18,6 +19,7 @@ use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorit use nym_sphinx::DestinationAddressBytes; use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; +use std::string::FromUtf8Error; use thiserror::Error; use tungstenite::protocol::Message; @@ -102,6 +104,18 @@ pub enum GatewayRequestsError { #[from] source: MixPacketFormattingError, }, + + #[error("failed to deserialize provided credential: EOF")] + CredentialDeserializationFailureEOF, + + #[error("failed to deserialize provided credential: malformed string: {0}")] + CredentialDeserializationFailureMalformedString(#[from] FromUtf8Error), + + #[error("failed to deserialize provided credential: {0}")] + CredentialDeserializationFailureUnknownType(#[from] UnknownCredentialType), + + #[error("failed to deserialize provided credential: malformed verify request: {0}")] + CredentialDeserializationFailureMalformedTheta(CoconutError), } #[derive(Serialize, Deserialize, Debug)] diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index ca362dc721..6480b0a255 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3943,6 +3943,7 @@ dependencies = [ "bls12_381", "nym-coconut", "serde", + "thiserror", ] [[package]] diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 8c3109210f..e9cdff7476 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -3198,6 +3198,7 @@ dependencies = [ "bls12_381", "nym-coconut", "serde", + "thiserror", ] [[package]] From 9a3bd7a2a964706b5be7a3ff43a3eaf39e3b9909 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Thu, 8 Feb 2024 17:14:21 +0000 Subject: [PATCH 059/394] clippy and fixing tests --- common/credentials-interface/src/lib.rs | 2 +- .../src/coconut/bandwidth/issuance.rs | 14 +- .../src/coconut/bandwidth/voucher.rs | 414 +----------------- common/network-defaults/src/lib.rs | 3 - gateway/src/node/client_handling/bandwidth.rs | 2 +- nym-api/src/coconut/deposit.rs | 13 +- .../src/coconut/tests/issued_credentials.rs | 47 +- nym-api/src/coconut/tests/mod.rs | 261 ++++++----- 8 files changed, 190 insertions(+), 566 deletions(-) diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index 36af1ef380..f2be1ef70f 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -83,7 +83,7 @@ pub struct CredentialSigningData { pub typ: CredentialType, } -#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] +#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)] pub struct CredentialSpendingData { pub embedded_private_attributes: usize, diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 1bba208cc5..bf166313a6 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -65,6 +65,13 @@ impl BandwidthCredentialIssuanceDataVariant { } } } + + pub fn voucher_data(&self) -> Option<&BandwidthVoucherIssuanceData> { + match self { + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => Some(voucher), + _ => None, + } + } } // all types of bandwidth credentials contain serial number and binding number @@ -114,7 +121,7 @@ impl IssuanceBandwidthCredential { } pub fn new_voucher( - value: Coin, + value: impl Into, deposit_tx_hash: Hash, signing_key: identity::PrivateKey, unused_ed25519: encryption::PrivateKey, @@ -135,6 +142,7 @@ impl IssuanceBandwidthCredential { bandwidth_credential_params().gen1() * self.serial_number } + // NOT TO BE CONFUSED WITH BLINDED SERIAL NUMBER IN CREDENTIAL ITSELF pub fn blinded_g1_serial_number_bs58(&self) -> String { use nym_credentials_interface::Base58; @@ -160,6 +168,10 @@ impl IssuanceBandwidthCredential { ] } + pub fn get_variant_data(&self) -> &BandwidthCredentialIssuanceDataVariant { + &self.variant_data + } + pub fn get_bandwidth_attribute(&self) -> String { self.variant_data.public_value_plain() } diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index 6bf4e55dcb..06866d9606 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -59,11 +59,12 @@ pub struct BandwidthVoucherIssuanceData { impl BandwidthVoucherIssuanceData { pub fn new( - value: Coin, + value: impl Into, deposit_tx_hash: Hash, signing_key: identity::PrivateKey, unused_ed25519: encryption::PrivateKey, ) -> Self { + let value = value.into(); let value_prehashed = hash_to_scalar(value.amount.to_string()); BandwidthVoucherIssuanceData { @@ -130,414 +131,3 @@ impl BandwidthVoucherIssuanceData { &self.unused_ed25519 } } -// -// #[deprecated] -// #[derive(Zeroize, ZeroizeOnDrop)] -// pub struct BandwidthVoucher { -// // private attributes -// /// a random secret value generated by the client used for double-spending detection -// serial_number: PrivateAttribute, -// -// /// a random secret value generated by the client used to bind multiple credentials together -// binding_number: PrivateAttribute, -// -// // public atttributes: -// /// the plain text value (e.g., bandwidth) encoded in this voucher -// // TODO: in another PR change the value from `"1000"` to `"1000unym"` -// voucher_value_plain: String, -// -// /// the plain text information -// voucher_info_plain: String, -// -// /// the precomputed value (e.g., bandwidth) encoded in this voucher -// _voucher_value_prehashed: PublicAttribute, -// -// /// the precomputed field with public information, e.g., type of voucher, interval etc. -// _voucher_info_prehashed: PublicAttribute, -// -// /// the hash of the deposit transaction -// #[zeroize(skip)] -// tx_hash: Hash, -// -// /// base58 encoded private key ensuring the depositer requested these attributes -// signing_key: identity::PrivateKey, -// -// /// base58 encoded private key ensuring only this client receives the signature share -// unused_ed25519: encryption::PrivateKey, -// -// pedersen_commitments_openings: Vec, -// -// #[zeroize(skip)] -// blind_sign_request: BlindSignRequest, -// } -// -// impl BandwidthVoucher { -// pub const PUBLIC_ATTRIBUTES: u32 = 2; -// pub const PRIVATE_ATTRIBUTES: u32 = 2; -// pub const ENCODED_ATTRIBUTES: u32 = Self::PUBLIC_ATTRIBUTES + Self::PRIVATE_ATTRIBUTES; -// -// pub fn default_parameters() -> Parameters { -// // safety: the unwrap is fine here as Self::ENCODED_ATTRIBUTES is non-zero -// Parameters::new(Self::ENCODED_ATTRIBUTES).unwrap() -// } -// -// pub fn new( -// params: &Parameters, -// voucher_value: String, -// voucher_info: String, -// tx_hash: Hash, -// signing_key: identity::PrivateKey, -// encryption_key: encryption::PrivateKey, -// ) -> Self { -// let serial_number = params.random_scalar(); -// let binding_number = params.random_scalar(); -// let voucher_value_plain = voucher_value.clone(); -// let voucher_info_plain = voucher_info.clone(); -// -// let _voucher_value_prehashed = hash_to_scalar(voucher_value); -// let _voucher_info_prehashed = hash_to_scalar(voucher_info); -// -// let (pedersen_commitments_openings, blind_sign_request) = prepare_blind_sign( -// params, -// &[&serial_number, &binding_number], -// &[&_voucher_value_prehashed, &_voucher_info_prehashed], -// ) -// .unwrap(); -// BandwidthVoucher { -// serial_number, -// binding_number, -// _voucher_value_prehashed, -// voucher_value_plain, -// _voucher_info_prehashed, -// voucher_info_plain, -// tx_hash, -// signing_key, -// unused_ed25519: encryption_key, -// pedersen_commitments_openings, -// blind_sign_request, -// } -// } -// -// pub fn to_bytes(&self) -> Vec { -// let serial_number_b = self.serial_number.to_bytes(); -// let binding_number_b = self.binding_number.to_bytes(); -// let voucher_value_plain_b = self.voucher_value_plain.as_bytes(); -// let voucher_info_plain_b = self.voucher_info_plain.as_bytes(); -// let tx_hash_b = self.tx_hash.as_bytes(); -// let signing_key_b = self.signing_key.to_bytes(); -// let encryption_key_b = self.unused_ed25519.to_bytes(); -// let blind_sign_request_b = self.blind_sign_request.to_bytes(); -// -// let mut ret = Vec::new(); -// -// ret.extend_from_slice(&serial_number_b); -// ret.extend_from_slice(&binding_number_b); -// ret.extend_from_slice(tx_hash_b); -// ret.extend_from_slice(&signing_key_b); -// ret.extend_from_slice(&encryption_key_b); -// ret.extend_from_slice(&(voucher_value_plain_b.len() as u64).to_be_bytes()); -// ret.extend_from_slice(&(voucher_info_plain_b.len() as u64).to_be_bytes()); -// ret.extend_from_slice(&(blind_sign_request_b.len() as u64).to_be_bytes()); -// ret.extend_from_slice(&(self.pedersen_commitments_openings.len() as u64).to_be_bytes()); -// ret.extend_from_slice(voucher_value_plain_b); -// ret.extend_from_slice(voucher_info_plain_b); -// ret.extend_from_slice(&blind_sign_request_b); -// for commitment in self.pedersen_commitments_openings.iter() { -// ret.extend_from_slice(&commitment.to_bytes()); -// } -// -// ret -// } -// -// pub fn try_from_bytes(bytes: &[u8]) -> Result { -// if bytes.len() < 32 * 5 + 4 * 8 { -// return Err(Error::BandwidthVoucherDeserializationError(format!( -// "Less then {} bytes needed", -// 32 * 5 + 4 * 8 -// ))); -// } -// let mut buff = [0u8; 32]; -// let mut small_buff = [0u8; 8]; -// let scalar_err = -// || Error::BandwidthVoucherDeserializationError(String::from("Invalid Scalar")); -// buff.copy_from_slice(&bytes[..32]); -// let serial_number = Option::::from(PrivateAttribute::from_bytes(&buff)) -// .ok_or_else(scalar_err)?; -// buff.copy_from_slice(&bytes[32..2 * 32]); -// let binding_number = Option::::from(PrivateAttribute::from_bytes(&buff)) -// .ok_or_else(scalar_err)?; -// buff.copy_from_slice(&bytes[2 * 32..3 * 32]); -// let tx_hash = Hash::from_bytes(Algorithm::Sha256, &buff).map_err(|_| { -// Error::BandwidthVoucherDeserializationError(String::from("Invalid transaction Hash")) -// })?; -// buff.copy_from_slice(&bytes[3 * 32..4 * 32]); -// let signing_key = identity::PrivateKey::from_bytes(&buff).map_err(|_| { -// Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) -// })?; -// buff.copy_from_slice(&bytes[4 * 32..5 * 32]); -// let encryption_key = encryption::PrivateKey::from_bytes(&buff).map_err(|_| { -// Error::BandwidthVoucherDeserializationError(String::from("Invalid key")) -// })?; -// small_buff.copy_from_slice(&bytes[5 * 32..5 * 32 + 8]); -// let voucher_value_plain_no = u64::from_be_bytes(small_buff) as usize; -// small_buff.copy_from_slice(&bytes[5 * 32 + 8..5 * 32 + 2 * 8]); -// let voucher_info_plain_no = u64::from_be_bytes(small_buff) as usize; -// small_buff.copy_from_slice(&bytes[5 * 32 + 2 * 8..5 * 32 + 3 * 8]); -// let blind_sign_request_no = u64::from_be_bytes(small_buff) as usize; -// small_buff.copy_from_slice(&bytes[5 * 32 + 3 * 8..5 * 32 + 4 * 8]); -// let pedersen_commitments_openings_no = u64::from_be_bytes(small_buff) as usize; -// -// let total_length = 32 * 5 -// + 4 * 8 -// + voucher_value_plain_no -// + voucher_info_plain_no -// + blind_sign_request_no -// + pedersen_commitments_openings_no * 32; -// if bytes.len() != total_length { -// return Err(Error::BandwidthVoucherDeserializationError(format!( -// "Expected {total_length} bytes", -// ))); -// } -// -// let utf_err = |_| { -// Err(Error::BandwidthVoucherDeserializationError(String::from( -// "Invalid UTF8 string", -// ))) -// }; -// let mut var_length_pointer = 5 * 32 + 4 * 8; -// let voucher_value_plain = String::from_utf8( -// bytes[var_length_pointer..var_length_pointer + voucher_value_plain_no].to_vec(), -// ) -// .or_else(utf_err)?; -// let _voucher_value_prehashed = hash_to_scalar(&voucher_value_plain); -// var_length_pointer += voucher_value_plain_no; -// let voucher_info_plain = String::from_utf8( -// bytes[var_length_pointer..var_length_pointer + voucher_info_plain_no].to_vec(), -// ) -// .or_else(utf_err)?; -// let _voucher_info_prehashed = hash_to_scalar(&voucher_info_plain); -// var_length_pointer += voucher_info_plain_no; -// let blind_sign_request = BlindSignRequest::from_bytes( -// &bytes[var_length_pointer..var_length_pointer + blind_sign_request_no], -// )?; -// var_length_pointer += blind_sign_request_no; -// -// let mut pedersen_commitments_openings = Vec::new(); -// for _ in 0..pedersen_commitments_openings_no { -// buff.copy_from_slice(&bytes[var_length_pointer..var_length_pointer + 32]); -// let commitment = -// Option::::from(Attribute::from_bytes(&buff)).ok_or_else(scalar_err)?; -// var_length_pointer += 32; -// pedersen_commitments_openings.push(commitment); -// } -// -// Ok(Self { -// serial_number, -// binding_number, -// _voucher_value_prehashed, -// voucher_value_plain, -// _voucher_info_prehashed, -// voucher_info_plain, -// tx_hash, -// signing_key, -// unused_ed25519: encryption_key, -// pedersen_commitments_openings, -// blind_sign_request, -// }) -// } -// -// /// Check if the plain values correspond to the PublicAttributes -// pub fn verify_against_plain(values: &[&PublicAttribute], plain_values: &[String]) -> bool { -// values.len() == 2 -// && plain_values.len() == 2 -// && values[0] == &hash_to_scalar(&plain_values[0]) -// && values[1] == &hash_to_scalar(&plain_values[1]) -// } -// -// pub fn get_public_attributes(&self) -> Vec<&PublicAttribute> { -// vec![ -// &self._voucher_value_prehashed, -// &self._voucher_info_prehashed, -// ] -// } -// -// pub fn tx_hash(&self) -> Hash { -// self.tx_hash -// } -// -// pub fn identity_key(&self) -> &identity::PrivateKey { -// &self.signing_key -// } -// -// pub fn encryption_key(&self) -> &encryption::PrivateKey { -// &self.unused_ed25519 -// } -// -// pub fn pedersen_commitments_openings(&self) -> &Vec { -// &self.pedersen_commitments_openings -// } -// -// pub fn blind_sign_request(&self) -> &BlindSignRequest { -// &self.blind_sign_request -// } -// -// pub fn get_voucher_value(&self) -> String { -// self.voucher_value_plain.clone() -// } -// -// pub fn get_public_attributes_plain(&self) -> Vec { -// vec![ -// self.voucher_value_plain.clone(), -// self.voucher_info_plain.clone(), -// ] -// } -// -// pub fn get_private_attributes(&self) -> Vec<&PrivateAttribute> { -// vec![&self.serial_number, &self.binding_number] -// } -// -// pub fn signable_plaintext(request: &BlindSignRequest, tx_hash: Hash) -> Vec { -// let mut message = request.to_bytes(); -// message.extend_from_slice(tx_hash.as_bytes()); -// message -// } -// -// pub fn sign(&self) -> identity::Signature { -// let message = Self::signable_plaintext(&self.blind_sign_request, self.tx_hash); -// self.signing_key.sign(message) -// } -// } - -// pub fn prepare_for_spending( -// voucher_value: u64, -// voucher_info: String, -// serial_number: &PrivateAttribute, -// binding_number: &PrivateAttribute, -// epoch_id: u64, -// signature: &Signature, -// verification_key: &VerificationKey, -// ) -> Result { -// todo!() -// // let params = Parameters::new(BandwidthVoucher::ENCODED_ATTRIBUTES)?; -// // -// // prepare_credential_for_spending( -// // ¶ms, -// // voucher_value, -// // voucher_info, -// // serial_number, -// // binding_number, -// // epoch_id, -// // signature, -// // verification_key, -// // ) -// } - -#[cfg(test)] -mod test { - use super::*; - use cosmrs::tendermint::hash::Algorithm; - use nym_coconut_interface::Base58; - use rand::rngs::OsRng; - - fn voucher_fixture() -> BandwidthVoucher { - let params = Parameters::new(4).unwrap(); - let mut rng = OsRng; - BandwidthVoucher::new( - ¶ms, - "1234".to_string(), - "voucher info".to_string(), - Hash::from_bytes(Algorithm::Sha256, &[0; 32]).unwrap(), - identity::PrivateKey::from_base58_string( - identity::KeyPair::new(&mut rng) - .private_key() - .to_base58_string(), - ) - .unwrap(), - encryption::PrivateKey::from_bytes( - &encryption::KeyPair::new(&mut rng).private_key().to_bytes(), - ) - .unwrap(), - ) - } - - #[test] - fn serde_voucher() { - let voucher = voucher_fixture(); - let bytes = voucher.to_bytes(); - let deserialized_voucher = BandwidthVoucher::try_from_bytes(&bytes).unwrap(); - assert_eq!(voucher.serial_number, deserialized_voucher.serial_number); - assert_eq!(voucher.binding_number, deserialized_voucher.binding_number); - assert_eq!( - voucher.voucher_value_plain, - deserialized_voucher.voucher_value_plain - ); - assert_eq!( - voucher.voucher_info_plain, - deserialized_voucher.voucher_info_plain - ); - assert_eq!( - voucher._voucher_value_prehashed, - deserialized_voucher._voucher_value_prehashed - ); - assert_eq!( - voucher._voucher_info_prehashed, - deserialized_voucher._voucher_info_prehashed - ); - assert_eq!(voucher.tx_hash, deserialized_voucher.tx_hash); - assert_eq!( - voucher.signing_key.to_string(), - deserialized_voucher.signing_key.to_string() - ); - assert_eq!( - voucher.unused_ed25519.to_string(), - deserialized_voucher.unused_ed25519.to_string() - ); - assert_eq!( - voucher.pedersen_commitments_openings, - deserialized_voucher.pedersen_commitments_openings - ); - assert_eq!( - voucher.blind_sign_request.to_bs58(), - deserialized_voucher.blind_sign_request.to_bs58() - ); - } - - #[test] - fn voucher_consistency() { - let voucher = voucher_fixture(); - assert!(!BandwidthVoucher::verify_against_plain( - &[], - &voucher.get_public_attributes_plain() - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[], - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[ - voucher.get_public_attributes_plain()[0].clone(), - String::new() - ] - )); - assert!(!BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &[ - String::new(), - voucher.get_public_attributes_plain()[1].clone() - ] - )); - assert!(!BandwidthVoucher::verify_against_plain( - &[voucher.get_public_attributes()[0], &Attribute::one()], - &voucher.get_public_attributes_plain() - )); - assert!(!BandwidthVoucher::verify_against_plain( - &[&Attribute::one(), voucher.get_public_attributes()[1]], - &voucher.get_public_attributes_plain() - )); - assert!(BandwidthVoucher::verify_against_plain( - &voucher.get_public_attributes(), - &voucher.get_public_attributes_plain() - )); - } -} diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 1891cd3cc3..ffd5ff6384 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -469,9 +469,6 @@ pub const UTOKENS_TO_BURN: u64 = TOKENS_TO_BURN * 1000000; /// Default bandwidth (in bytes) that we try to buy pub const BANDWIDTH_VALUE: u64 = UTOKENS_TO_BURN * BYTES_PER_UTOKEN; -#[deprecated] -pub const VOUCHER_INFO: &str = "BandwidthVoucher"; - /// Defaults Cosmos Hub/ATOM path pub const COSMOS_DERIVATION_PATH: &str = "m/44'/118'/0'/0/0"; // as set by validators in their configs diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index ce1caed6a7..47c6447a7a 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -45,7 +45,7 @@ impl Bandwidth { Bandwidth { value } } - pub fn try_from_raw_value(value: &String, typ: CredentialType) -> Result { + pub fn try_from_raw_value(value: &str, typ: CredentialType) -> Result { let bandwidth_value = match typ { CredentialType::Voucher => { diff --git a/nym-api/src/coconut/deposit.rs b/nym-api/src/coconut/deposit.rs index ab1c345991..8448342c08 100644 --- a/nym-api/src/coconut/deposit.rs +++ b/nym-api/src/coconut/deposit.rs @@ -73,17 +73,20 @@ pub async fn validate_deposit_tx(request: &BlindSignRequestBody, tx: TxResponse) #[cfg(test)] mod test { use super::*; - use crate::coconut::tests::{tx_entry_fixture, voucher_request_fixture}; + use crate::coconut::tests::{tx_entry_fixture, voucher_fixture}; use cosmwasm_std::coin; use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut::BlindSignRequest; use nym_coconut_bandwidth_contract_common::events::DEPOSITED_FUNDS_EVENT_TYPE; - use nym_config::defaults::VOUCHER_INFO; + use nym_credentials::coconut::bandwidth::CredentialType; use nym_validator_client::nyxd::{Event, EventAttribute}; #[tokio::test] async fn validate_deposit_tx_test() { - let (voucher, correct_request) = voucher_request_fixture(coin(1234, "unym"), None); + let voucher = voucher_fixture(coin(1234, "unym"), None); + let signing_data = voucher.prepare_for_signing(); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let correct_request = voucher_data.create_blind_sign_request_body(&signing_data); let mut tx_entry = tx_entry_fixture(correct_request.tx_hash); let good_deposit_attribute = EventAttribute { @@ -171,7 +174,7 @@ mod test { err.to_string(), CoconutError::InconsistentDepositInfo { on_chain: "bandwidth deposit info".to_string(), - request: VOUCHER_INFO.to_string(), + request: CredentialType::Voucher.to_string(), } .to_string(), ); @@ -312,7 +315,7 @@ mod test { .parse() .unwrap(), "3vUCc6MCN5AC2LNgDYjRB1QeErZSN1S8f6K14JHjpUcKWXbjGYFExA8DbwQQBki9gyUqrpBF94Drttb4eMcGQXkp".parse().unwrap(), - voucher.get_public_attributes_plain(), + voucher.get_plain_public_attributes(), ); tx_entry.tx_result.events.get_mut(0).unwrap().attributes = vec![ good_deposit_attribute.clone(), diff --git a/nym-api/src/coconut/tests/issued_credentials.rs b/nym-api/src/coconut/tests/issued_credentials.rs index d753476235..ef64c38da8 100644 --- a/nym-api/src/coconut/tests/issued_credentials.rs +++ b/nym-api/src/coconut/tests/issued_credentials.rs @@ -1,13 +1,12 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::coconut::tests::{voucher_request_fixture, TestFixture}; +use crate::coconut::tests::{voucher_fixture, TestFixture}; use cosmwasm_std::coin; use nym_api_requests::coconut::models::{ EpochCredentialsResponse, IssuedCredentialResponse, IssuedCredentialsResponse, Pagination, }; use nym_api_requests::coconut::CredentialsRequestBody; -use nym_coconut::Base58; use nym_validator_client::nym_api::routes::{API_VERSION, BANDWIDTH, COCONUT_ROUTES}; use rocket::http::Status; use std::collections::BTreeMap; @@ -102,12 +101,20 @@ async fn issued_credential() { let hash1 = "6B27412050B823E58BB38447D7870BBC8CBE3C51C905BEA89D459ACCDA80A00E".to_string(); let hash2 = "9F4DF28B36189B4410BC23D97FD757FC74B919122E80534CC2CA6F3D646F6518".to_string(); - let (voucher1, req1) = voucher_request_fixture(coin(1234, "unym"), Some(hash1.clone())); - let (voucher2, req2) = voucher_request_fixture(coin(1234, "unym"), Some(hash2.clone())); + let voucher1 = voucher_fixture(coin(1234, "unym"), Some(hash1.clone())); + let voucher2 = voucher_fixture(coin(1234, "unym"), Some(hash2.clone())); + + let signing_data1 = voucher1.prepare_for_signing(); + let voucher_data1 = voucher1.get_variant_data().voucher_data().unwrap(); + let request1 = voucher_data1.create_blind_sign_request_body(&signing_data1); + + let signing_data2 = voucher2.prepare_for_signing(); + let voucher_data2 = voucher2.get_variant_data().voucher_data().unwrap(); + let request2 = voucher_data2.create_blind_sign_request_body(&signing_data2); let test_fixture = TestFixture::new().await; - test_fixture.add_deposit_tx(&voucher1); - test_fixture.add_deposit_tx(&voucher2); + test_fixture.add_deposit_tx(voucher_data1); + test_fixture.add_deposit_tx(voucher_data2); // random credential that was never issued let response = test_fixture.rocket.get(route(42)).dispatch().await; @@ -116,10 +123,10 @@ async fn issued_credential() { serde_json::from_str(&response.into_string().await.unwrap()).unwrap(); assert!(parsed_response.credential.is_none()); - let cred1 = test_fixture.issue_credential(req1).await; + let cred1 = test_fixture.issue_credential(request1.clone()).await; test_fixture.set_epoch(3); - let cred2 = test_fixture.issue_credential(req2).await; + let cred2 = test_fixture.issue_credential(request2.clone()).await; let response = test_fixture.rocket.get(route(1)).dispatch().await; assert_eq!(response.status(), Status::Ok); @@ -136,49 +143,37 @@ async fn issued_credential() { // TODO: currently we have no signature checks assert_eq!(1, issued1.credential.id); assert_eq!(1, issued1.credential.epoch_id); - assert_eq!(voucher1.tx_hash(), issued1.credential.tx_hash); + assert_eq!(voucher_data1.tx_hash(), issued1.credential.tx_hash); assert_eq!( cred1.to_bytes(), issued1.credential.blinded_partial_credential.to_bytes() ); - let cms: Vec<_> = voucher1 - .blind_sign_request() - .get_private_attributes_pedersen_commitments() - .iter() - .map(|c| c.to_bs58()) - .collect(); assert_eq!( - cms, + request1.encode_commitments(), issued1 .credential .bs58_encoded_private_attributes_commitments ); assert_eq!( - voucher1.get_public_attributes_plain(), + voucher1.get_plain_public_attributes(), issued1.credential.public_attributes ); assert_eq!(2, issued2.credential.id); assert_eq!(3, issued2.credential.epoch_id); - assert_eq!(voucher2.tx_hash(), issued2.credential.tx_hash); + assert_eq!(voucher_data2.tx_hash(), issued2.credential.tx_hash); assert_eq!( cred2.to_bytes(), issued2.credential.blinded_partial_credential.to_bytes() ); - let cms: Vec<_> = voucher2 - .blind_sign_request() - .get_private_attributes_pedersen_commitments() - .iter() - .map(|c| c.to_bs58()) - .collect(); assert_eq!( - cms, + request2.encode_commitments(), issued2 .credential .bs58_encoded_private_attributes_commitments ); assert_eq!( - voucher2.get_public_attributes_plain(), + voucher2.get_plain_public_attributes(), issued2.credential.public_attributes ); } diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index db20f4bc1b..726c42dbd2 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -15,7 +15,7 @@ use cw3::{Proposal, ProposalResponse, Vote, VoteInfo, VoteResponse, Votes}; use cw4::{Cw4Contract, MemberResponse}; use nym_api_requests::coconut::models::{IssuedCredentialBody, IssuedCredentialResponse}; use nym_api_requests::coconut::{BlindSignRequestBody, BlindedSignatureResponse}; -use nym_coconut::{BlindedSignature, Parameters}; +use nym_coconut::{BlindedSignature, Parameters, VerificationKey}; use nym_coconut_bandwidth_contract_common::events::{ DEPOSITED_FUNDS_EVENT_TYPE, DEPOSIT_ENCRYPTION_KEY, DEPOSIT_IDENTITY_KEY, DEPOSIT_INFO, DEPOSIT_VALUE, @@ -34,10 +34,10 @@ use nym_coconut_dkg_common::types::{ EpochId, EpochState, PartialContractDealingData, State as ContractState, }; use nym_coconut_dkg_common::verification_key::{ContractVKShare, VerificationKeyShare}; -use nym_coconut_interface::VerificationKey; -use nym_config::defaults::VOUCHER_INFO; use nym_contracts_common::IdentityKey; -use nym_credentials::coconut::bandwidth::BandwidthVoucher; +use nym_credentials::coconut::bandwidth::voucher::BandwidthVoucherIssuanceData; +use nym_credentials::coconut::bandwidth::CredentialType; +use nym_credentials::IssuanceBandwidthCredential; use nym_crypto::asymmetric::{encryption, identity}; use nym_dkg::{NodeIndex, Threshold}; use nym_validator_client::nym_api::routes::{ @@ -1225,9 +1225,9 @@ pub fn tx_entry_fixture(hash: Hash) -> TxResponse { } } -pub fn deposit_tx_fixture(voucher: &BandwidthVoucher) -> TxResponse { +pub fn deposit_tx_fixture(voucher_data: &BandwidthVoucherIssuanceData) -> TxResponse { TxResponse { - hash: voucher.tx_hash(), + hash: voucher_data.tx_hash(), height: Default::default(), index: 0, tx_result: ExecTxResult { @@ -1242,22 +1242,25 @@ pub fn deposit_tx_fixture(voucher: &BandwidthVoucher) -> TxResponse { attributes: vec![ EventAttribute { key: DEPOSIT_VALUE.to_string(), - value: voucher.get_voucher_value(), + value: voucher_data.value_plain(), index: false, }, EventAttribute { key: DEPOSIT_INFO.to_string(), - value: VOUCHER_INFO.to_string(), + value: CredentialType::Voucher.to_string(), index: false, }, EventAttribute { key: DEPOSIT_IDENTITY_KEY.to_string(), - value: voucher.identity_key().public_key().to_base58_string(), + value: voucher_data.identity_key().public_key().to_base58_string(), index: false, }, EventAttribute { key: DEPOSIT_ENCRYPTION_KEY.parse().unwrap(), - value: voucher.encryption_key().public_key().to_base58_string(), + value: voucher_data + .encryption_key() + .public_key() + .to_base58_string(), index: false, }, ], @@ -1285,11 +1288,10 @@ pub fn blinded_signature_fixture() -> BlindedSignature { BlindedSignature::from_bytes(&dummy_bytes).unwrap() } -pub fn voucher_request_fixture>( +pub fn voucher_fixture>( amount: C, tx_hash: Option, -) -> (BandwidthVoucher, BlindSignRequestBody) { - let params = Parameters::new(4).unwrap(); +) -> IssuanceBandwidthCredential { let mut rng = OsRng; let tx_hash = if let Some(provided) = &tx_hash { provided.parse().unwrap() @@ -1304,23 +1306,7 @@ pub fn voucher_request_fixture>( let enc_priv = encryption::PrivateKey::from_bytes(&encryption_keypair.private_key().to_bytes()).unwrap(); - let voucher = BandwidthVoucher::new( - ¶ms, - amount.into().amount.to_string(), - VOUCHER_INFO.to_string(), - tx_hash, - id_priv, - enc_priv, - ); - - let request = BlindSignRequestBody::new( - voucher.blind_sign_request().clone(), - tx_hash, - voucher.sign(), - voucher.get_public_attributes_plain(), - ); - - (voucher, request) + IssuanceBandwidthCredential::new_voucher(amount.into(), tx_hash, id_priv, enc_priv) } fn dummy_signature() -> identity::Signature { @@ -1398,9 +1384,10 @@ impl TestFixture { self.chain_state.lock().unwrap().txs.insert(hash, tx); } - fn add_deposit_tx(&self, voucher: &BandwidthVoucher) { + fn add_deposit_tx(&self, voucher: &BandwidthVoucherIssuanceData) { let mut guard = self.chain_state.lock().unwrap(); let fixture = deposit_tx_fixture(voucher); + guard.txs.insert(voucher.tx_hash(), fixture); } @@ -1410,9 +1397,13 @@ impl TestFixture { rng.fill_bytes(&mut tx_hash); let tx_hash = Hash::from_bytes(Algorithm::Sha256, &tx_hash).unwrap(); - let (voucher, req) = voucher_request_fixture(coin(1234, "unym"), Some(tx_hash.to_string())); - self.add_deposit_tx(&voucher); + let voucher = voucher_fixture(coin(1234, "unym"), Some(tx_hash.to_string())); + let signing_data = voucher.prepare_for_signing(); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let req = voucher_data.create_blind_sign_request_body(&signing_data); + + self.add_deposit_tx(voucher_data); self.issue_credential(req).await; } @@ -1456,15 +1447,18 @@ mod credential_tests { use super::*; use crate::coconut::tests::helpers::init_chain; use nym_api_requests::coconut::{VerifyCredentialBody, VerifyCredentialResponse}; - use nym_coconut::tests::helpers::theta_from_keys_and_attributes; - use nym_coconut::{hash_to_scalar, ttp_keygen}; + use nym_coconut::{blind_sign, hash_to_scalar, ttp_keygen}; use nym_coconut_bandwidth_contract_common::spend_credential::SpendCredential; - use nym_coconut_interface::Credential; + use nym_credentials::coconut::bandwidth::bandwidth_credential_params; use nym_validator_client::nym_api::routes::COCONUT_VERIFY_BANDWIDTH_CREDENTIAL; #[tokio::test] async fn already_issued() { - let (_, request_body) = voucher_request_fixture(coin(1234, TEST_COIN_DENOM), None); + let voucher = voucher_fixture(coin(1234, TEST_COIN_DENOM), None); + let signing_data = voucher.prepare_for_signing(); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let request_body = voucher_data.create_blind_sign_request_body(&signing_data); + let tx_hash = request_body.tx_hash; let tx_entry = tx_entry_fixture(tx_hash); @@ -1547,7 +1541,11 @@ mod credential_tests { .unwrap(); assert!(state.already_issued(tx_hash).await.unwrap().is_none()); - let (_, request_body) = voucher_request_fixture(coin(1234, TEST_COIN_DENOM), None); + let voucher = voucher_fixture(coin(1234, TEST_COIN_DENOM), None); + let signing_data = voucher.prepare_for_signing(); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let request_body = voucher_data.create_blind_sign_request_body(&signing_data); + let commitments = request_body.encode_commitments(); let public = request_body.public_attributes_plain.clone(); let sig = blinded_signature_fixture(); @@ -1637,10 +1635,8 @@ mod credential_tests { let identity_keypair = identity::KeyPair::new(&mut rng); let encryption_keypair = encryption::KeyPair::new(&mut rng); - let voucher = BandwidthVoucher::new( - ¶ms, - "1234".to_string(), - VOUCHER_INFO.to_string(), + let voucher = IssuanceBandwidthCredential::new_voucher( + coin(1234, "unym"), tx_hash, identity::PrivateKey::from_base58_string( identity_keypair.private_key().to_base58_string(), @@ -1658,7 +1654,9 @@ mod credential_tests { let chain = init_chain(); - let tx_entry = deposit_tx_fixture(&voucher); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let tx_entry = deposit_tx_fixture(voucher_data); + chain.lock().unwrap().txs.insert(tx_hash, tx_entry.clone()); let nyxd_client = DummyClient::new( @@ -1688,14 +1686,9 @@ mod credential_tests { .await .expect("valid rocket instance"); - let request_signature = voucher.sign(); - - let request_body = BlindSignRequestBody::new( - voucher.blind_sign_request().clone(), - tx_hash, - request_signature, - voucher.get_public_attributes_plain(), - ); + let signing_data = voucher.prepare_for_signing(); + let voucher_data = voucher.get_variant_data().voucher_data().unwrap(); + let request_body = voucher_data.create_blind_sign_request_body(&signing_data); let response = client .post(format!( @@ -1727,24 +1720,39 @@ mod credential_tests { let nyxd_client = DummyClient::new(validator_address.clone(), chain.clone()); let db_dir = tempdir().unwrap(); - let params = Parameters::new(4).unwrap(); - let mut key_pairs = ttp_keygen(¶ms, 1, 1).unwrap(); - let voucher_value = 1234u64; - let voucher_info = "voucher info"; - let public_attributes = [ - hash_to_scalar(voucher_value.to_string()), - hash_to_scalar(voucher_info), - ]; - let public_attributes_ref = vec![&public_attributes[0], &public_attributes[1]]; - let indices: Vec = key_pairs + + // generate all the credential requests + let params = bandwidth_credential_params(); + let key_pair = nym_coconut::keygen(params); + + let voucher_amount = coin(1234, "unym"); + let issuance = voucher_fixture(coin(1234, "unym"), None); + let sig_req = issuance.prepare_for_signing(); + let pub_attrs_hashed = sig_req + .public_attributes_plain .iter() - .enumerate() - .map(|(idx, _)| (idx + 1) as u64) - .collect(); - let theta = - theta_from_keys_and_attributes(¶ms, &key_pairs, &indices, &public_attributes_ref) - .unwrap(); - let key_pair = key_pairs.remove(0); + .map(hash_to_scalar) + .collect::>(); + let pub_attrs = pub_attrs_hashed.iter().collect::>(); + let blind_sig = blind_sign( + params, + key_pair.secret_key(), + &sig_req.blind_sign_request, + &pub_attrs, + ) + .unwrap(); + let sig = blind_sig + .unblind( + key_pair.verification_key(), + &sig_req.pedersen_commitments_openings, + ) + .unwrap(); + + let issued = issuance.into_issued_credential(sig); + let spending = issued + .prepare_for_spending(key_pair.verification_key()) + .unwrap(); + let storage1 = NymApiStorage::init(db_dir.path().join("storage.db")) .await .unwrap(); @@ -1773,13 +1781,16 @@ mod credential_tests { .await .expect("valid rocket instance"); - let credential = - Credential::new(4, theta.clone(), voucher_value, voucher_info.to_string(), 0); + let epoch_id = 69; let proposal_id = 42; // The address is not used, so we can use a duplicate let gateway_cosmos_addr = validator_address.clone(); - let req = - VerifyCredentialBody::new(credential.clone(), proposal_id, gateway_cosmos_addr.clone()); + let req = VerifyCredentialBody::new( + spending.clone(), + epoch_id, + proposal_id, + gateway_cosmos_addr.clone(), + ); // Test endpoint with not proposal for the proposal id let response = client @@ -1841,7 +1852,9 @@ mod credential_tests { ); // Test the endpoint with no msg in the proposal action - proposal.description = credential.blinded_serial_number(); + proposal.description = spending + .verify_credential_request + .blinded_serial_number_bs58(); chain .lock() .unwrap() @@ -1866,9 +1879,9 @@ mod credential_tests { ); // Test the endpoint without any credential recorded in the Coconut Bandwidth Contract - let funds = Coin::new(voucher_value as u128, TEST_COIN_DENOM); + let funds = voucher_amount.clone(); let msg = nym_coconut_bandwidth_contract_common::msg::ExecuteMsg::ReleaseFunds { - funds: funds.clone().into(), + funds: funds.clone(), }; let cosmos_msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: String::new(), @@ -1905,7 +1918,9 @@ mod credential_tests { .bandwidth_contract .spent_credentials .insert( - credential.blinded_serial_number(), + spending + .verify_credential_request + .blinded_serial_number_bs58(), SpendCredentialResponse::new(None), ); @@ -1928,8 +1943,10 @@ mod credential_tests { // Test the endpoint with a credential that doesn't verify correctly let mut spent_credential = SpendCredential::new( - funds.clone().into(), - credential.blinded_serial_number(), + funds.clone(), + spending + .verify_credential_request + .blinded_serial_number_bs58(), Addr::unchecked("unimportant"), ); chain @@ -1938,47 +1955,55 @@ mod credential_tests { .bandwidth_contract .spent_credentials .insert( - credential.blinded_serial_number(), + spending + .verify_credential_request + .blinded_serial_number_bs58(), SpendCredentialResponse::new(Some(spent_credential.clone())), ); - let bad_credential = Credential::new( - 4, - theta.clone(), - voucher_value, - String::from("bad voucher info"), - 0, - ); - let bad_req = - VerifyCredentialBody::new(bad_credential, proposal_id, gateway_cosmos_addr.clone()); - let response = client - .post(format!( - "/{}/{}/{}/{}", - API_VERSION, COCONUT_ROUTES, BANDWIDTH, COCONUT_VERIFY_BANDWIDTH_CREDENTIAL - )) - .json(&bad_req) - .dispatch() - .await; - assert_eq!(response.status(), Status::Ok); - let verify_credential_response = serde_json::from_str::( - &response.into_string().await.unwrap(), - ) - .unwrap(); - assert!(!verify_credential_response.verification_result); - assert_eq!( - cw3::Status::Rejected, - chain - .lock() - .unwrap() - .multisig_contract - .proposals - .get(&proposal_id) - .unwrap() - .status - ); + + // TODO: somehow restore that test + // let bad_credential = Credential::new( + // 4, + // theta.clone(), + // voucher_value, + // String::from("bad voucher info"), + // 0, + // ); + // let bad_req = VerifyCredentialBody::new( + // bad_credential, + // epoch_id, + // proposal_id, + // gateway_cosmos_addr.clone(), + // ); + // let response = client + // .post(format!( + // "/{}/{}/{}/{}", + // API_VERSION, COCONUT_ROUTES, BANDWIDTH, COCONUT_VERIFY_BANDWIDTH_CREDENTIAL + // )) + // .json(&bad_req) + // .dispatch() + // .await; + // assert_eq!(response.status(), Status::Ok); + // let verify_credential_response = serde_json::from_str::( + // &response.into_string().await.unwrap(), + // ) + // .unwrap(); + // assert!(!verify_credential_response.verification_result); + // assert_eq!( + // cw3::Status::Rejected, + // chain + // .lock() + // .unwrap() + // .multisig_contract + // .proposals + // .get(&proposal_id) + // .unwrap() + // .status + // ); // Test the endpoint with a proposal that has a different value for the funds to be released // then what's in the credential - let funds = Coin::new((voucher_value + 10) as u128, TEST_COIN_DENOM); + let funds = Coin::new(voucher_amount.amount.u128() + 10, TEST_COIN_DENOM); let msg = nym_coconut_bandwidth_contract_common::msg::ExecuteMsg::ReleaseFunds { funds: funds.clone().into(), }; @@ -2022,9 +2047,9 @@ mod credential_tests { ); // Test the endpoint with every dependency met - let funds = Coin::new(voucher_value as u128, TEST_COIN_DENOM); + let funds = voucher_amount; let msg = nym_coconut_bandwidth_contract_common::msg::ExecuteMsg::ReleaseFunds { - funds: funds.clone().into(), + funds: funds.clone(), }; let cosmos_msg = CosmosMsg::Wasm(WasmMsg::Execute { contract_addr: String::new(), @@ -2073,7 +2098,9 @@ mod credential_tests { .bandwidth_contract .spent_credentials .insert( - credential.blinded_serial_number(), + spending + .verify_credential_request + .blinded_serial_number_bs58(), SpendCredentialResponse::new(Some(spent_credential)), ); let response = client From 2638952f5a08245f8a8ce803d3cef5d859ec2de4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 09:59:54 +0000 Subject: [PATCH 060/394] reintroduced handling of old v1 credentials --- .../client-libs/gateway-client/src/client.rs | 6 +- gateway/gateway-requests/src/models.rs | 155 +++++++++++++++++- gateway/gateway-requests/src/types.rs | 39 ++++- .../connection_handler/authenticated.rs | 73 ++++++--- .../websocket/connection_handler/fresh.rs | 4 +- 5 files changed, 247 insertions(+), 30 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index b1ebb23fa4..e0cb06215e 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -384,7 +384,7 @@ impl GatewayClient { // note: in +1.2.0 we will have to return a hard error here Ok(()) } - Some(v) if v != PROTOCOL_VERSION => { + Some(v) if v > PROTOCOL_VERSION => { let err = GatewayClientError::IncompatibleProtocol { gateway: Some(v), current: PROTOCOL_VERSION, @@ -394,7 +394,7 @@ impl GatewayClient { } Some(_) => { - info!("the gateway is using exactly the same protocol version as we are. We're good to continue!"); + info!("the gateway is using exactly the same (or older) protocol version as we are. We're good to continue!"); Ok(()) } } @@ -522,7 +522,7 @@ impl GatewayClient { let mut rng = OsRng; let iv = IV::new_random(&mut rng); - let msg = ClientControlRequest::new_enc_coconut_bandwidth_credential( + let msg = ClientControlRequest::new_enc_coconut_bandwidth_credential_v2( credential, epoch_id, self.shared_key.as_ref().unwrap(), diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 6e06aabc7e..0bef6c4084 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -6,6 +6,106 @@ use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials_interface::{CoconutError, VerifyCredentialRequest}; use serde::{Deserialize, Serialize}; +// reimplements old coconut-interface::Credential for backwards compatibility sake +// (so that 'new' gateways could still understand those requests) +#[derive(Debug, PartialEq, Eq)] +pub struct OldV1Credential { + pub n_params: u32, + + pub theta: VerifyCredentialRequest, + + pub voucher_value: u64, + + pub voucher_info: String, + + pub epoch_id: u64, +} + +// attempt to convert the old request type into the new variant +impl TryFrom for CredentialSpendingWithEpoch { + type Error = GatewayRequestsError; + + fn try_from(value: OldV1Credential) -> Result { + if value.n_params <= 2 { + return Err(GatewayRequestsError::InvalidNumberOfEmbededParameters( + value.n_params, + )); + } + let embedded_private_attributes = value.n_params as usize - 2; + let typ = value.voucher_info.parse()?; + let public_attributes_plain = vec![value.voucher_value.to_string(), value.voucher_info]; + + Ok(CredentialSpendingWithEpoch { + data: CredentialSpendingData { + embedded_private_attributes, + verify_credential_request: value.theta, + public_attributes_plain, + typ, + }, + epoch_id: value.epoch_id, + }) + } +} + +impl OldV1Credential { + #[cfg(test)] + pub fn as_bytes(&self) -> Vec { + let n_params_bytes = self.n_params.to_be_bytes(); + let theta_bytes = self.theta.to_bytes(); + let theta_bytes_len = theta_bytes.len(); + let voucher_value_bytes = self.voucher_value.to_be_bytes(); + let epoch_id_bytes = self.epoch_id.to_be_bytes(); + let voucher_info_bytes = self.voucher_info.as_bytes(); + let voucher_info_len = voucher_info_bytes.len(); + + let mut bytes = Vec::with_capacity(28 + theta_bytes_len + voucher_info_len); + bytes.extend_from_slice(&n_params_bytes); + bytes.extend_from_slice(&(theta_bytes_len as u64).to_be_bytes()); + bytes.extend_from_slice(&theta_bytes); + bytes.extend_from_slice(&voucher_value_bytes); + bytes.extend_from_slice(&epoch_id_bytes); + bytes.extend_from_slice(voucher_info_bytes); + + bytes + } + + pub fn from_bytes(bytes: &[u8]) -> Result { + if bytes.len() < 28 { + return Err(CoconutError::Deserialization(String::from( + "To few bytes in credential", + ))); + } + let mut four_byte = [0u8; 4]; + let mut eight_byte = [0u8; 8]; + + four_byte.copy_from_slice(&bytes[..4]); + let n_params = u32::from_be_bytes(four_byte); + eight_byte.copy_from_slice(&bytes[4..12]); + let theta_len = u64::from_be_bytes(eight_byte); + if bytes.len() < 28 + theta_len as usize { + return Err(CoconutError::Deserialization(String::from( + "To few bytes in credential", + ))); + } + let theta = VerifyCredentialRequest::from_bytes(&bytes[12..12 + theta_len as usize]) + .map_err(|e| CoconutError::Deserialization(e.to_string()))?; + eight_byte.copy_from_slice(&bytes[12 + theta_len as usize..20 + theta_len as usize]); + let voucher_value = u64::from_be_bytes(eight_byte); + eight_byte.copy_from_slice(&bytes[20 + theta_len as usize..28 + theta_len as usize]); + let epoch_id = u64::from_be_bytes(eight_byte); + let voucher_info = String::from_utf8(bytes[28 + theta_len as usize..].to_vec()) + .map_err(|e| CoconutError::Deserialization(e.to_string()))?; + + Ok(OldV1Credential { + n_params, + theta, + voucher_value, + voucher_info, + epoch_id, + }) + } +} + #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] pub struct CredentialSpendingWithEpoch { /// The cryptographic material required for spending the underlying credential. @@ -145,7 +245,60 @@ mod tests { use super::*; use nym_credentials::coconut::bandwidth::bandwidth_credential_params; use nym_credentials::IssuanceBandwidthCredential; - use nym_credentials_interface::{blind_sign, hash_to_scalar}; + use nym_credentials_interface::{ + blind_sign, hash_to_scalar, prove_bandwidth_credential, Attribute, Base58, Parameters, + Signature, VerificationKey, + }; + + #[test] + fn old_v1_coconut_credential_roundtrip() { + let voucher_value = 1000000u64; + let voucher_info = String::from("BandwidthVoucher"); + let serial_number = + Attribute::try_from_bs58("7Rp3imcuNX3w9se9wm5th8gSvc2czsnMrGsdt5HsrycA").unwrap(); + let binding_number = + Attribute::try_from_bs58("Auf8yVEgyEAWNHaXUZmimS4n9g5YiYnNYqp6F9BtBe9E").unwrap(); + let signature = Signature::try_from_bs58( + "ta3pM9ffj5T6YGbwjSBp2W118rcwyP9PXStc\ + 7ssb91g5GQYMQHhuTNajbdZcjxUFBFL5rhED8EHpRzE8r432ss3qbPBfpNev4CdkfMkQ3wepyM7hy7q1W6Rn9WmFoZL\ + ZR9j", + ) + .unwrap(); + let params = Parameters::new(4).unwrap(); + let verification_key = VerificationKey::try_from_bs58("8CFtVVXdwLy4WHMQPE4\ + woe89q3DRHoNxBSchftrEjSBPWA4r4xZv4Y9qSvS5x5bMmFtp7BX6ikECAnuXr5EjXWSsgjirZJmpS5XDUynVfht1cD\ + FWGDvy2XFrRCuoCMotNXi3PoF6wYqdTR9Rqcfoj3i2H5Nid422WBaLtVoC9QNobvpvaqq6vX5PbsSyPayvU8HCXFxM6\ + JjScYpbRTxQtdwefWLrk3LmXyJQBWi7c2VAhSxu9msp7VTBycqdwQNgxHETStZuwXsozxaGQ2KssVUCaaoYPR4g2RqK\ + UAvtWwA7pMiAQNcbkXcbsjCgVjWaCpMWC37XA31cLcFf3zbjHD9e5tXjAcqa4M89fbFhuvvSXxowSAZ5NoWrN32kd5d\ + wxJm1JW3Tt2h6yDDBe84oMy71462dZn7N78DVk2mFNGwBCibrZWA7oUzRBMfYxiQrksoFcou7QfLLd58zoNYmPQPt84\ + 1VpQopEBfdQ7Nf9zoXxBt3zMy7g5NsFGvzh7KTbDUyeeXrdkKJPQBs6dqaizr9sS8CPPmR4uk96vDTRh8CJ5FbSsmb8\ + nP71dRvvwRZJHGzwYirMo6SXS3ZYxFuiA3mkxYuqDHCwkTWDuRCcAaztrDYRZg7VCMo4Q446AaEso5eqpeWpHZQt53E\ + ZRpqmNYKASGwMhTeEHPSLgSmtoAAUcaRWpGRzYfd6kzEma8tdGLwyP4rLXgvSvtDLP37dU7YgF3LEXbGAz57U9ATy46\ + 6sroLpHPdaCWB8RF11wvB6Tu196JnJd2KyQBP1iUWP3rtZs3GhAF1QVcxquh8BqDZzAcpQ6wCS1P9c5GxKgww77FVF5\ + Kp83XtoxSrw3GaYVyKTGxNh3vcKPR31txCjTxPaN2fg7TaPLhoQJX4YaAroFSXqrqbbRsisuHhhCeUP2YwDjHedes9y") + .unwrap(); + let theta = prove_bandwidth_credential( + ¶ms, + &verification_key, + &signature, + &serial_number, + &binding_number, + ) + .unwrap(); + + let credential = OldV1Credential { + n_params: 4, + theta, + voucher_value, + voucher_info, + epoch_id: 42, + }; + + let serialized_credential = credential.as_bytes(); + let deserialized_credential = OldV1Credential::from_bytes(&serialized_credential).unwrap(); + + assert_eq!(credential, deserialized_credential); + } #[test] fn credential_roundtrip() { diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 67ccb148f7..e7e402c37c 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -3,7 +3,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; -use crate::models::CredentialSpendingWithEpoch; +use crate::models::{CredentialSpendingWithEpoch, OldV1Credential}; use crate::registration::handshake::SharedKeys; use crate::{GatewayMacSize, PROTOCOL_VERSION}; use log::error; @@ -116,6 +116,9 @@ pub enum GatewayRequestsError { #[error("failed to deserialize provided credential: malformed verify request: {0}")] CredentialDeserializationFailureMalformedTheta(CoconutError), + + #[error("the provided [v1] credential has invalid number of parameters - {0}")] + InvalidNumberOfEmbededParameters(u32), } #[derive(Serialize, Deserialize, Debug)] @@ -140,6 +143,10 @@ pub enum ClientControlRequest { enc_credential: Vec, iv: Vec, }, + BandwidthCredentialV2 { + enc_credential: Vec, + iv: Vec, + }, ClaimFreeTestnetBandwidth, } @@ -157,7 +164,31 @@ impl ClientControlRequest { } } - pub fn new_enc_coconut_bandwidth_credential( + pub fn new_enc_coconut_bandwidth_credential_v1( + credential: &OldV1Credential, + shared_key: &SharedKeys, + iv: IV, + ) -> Self { + let serialized_credential = credential.as_bytes(); + let enc_credential = shared_key.encrypt_and_tag(&serialized_credential, Some(iv.inner())); + + ClientControlRequest::BandwidthCredential { + enc_credential, + iv: iv.to_bytes(), + } + } + + pub fn try_from_enc_coconut_bandwidth_credential_v1( + enc_credential: Vec, + shared_key: &SharedKeys, + iv: IV, + ) -> Result { + let credential_bytes = shared_key.decrypt_tagged(&enc_credential, Some(iv.inner()))?; + OldV1Credential::from_bytes(&credential_bytes) + .map_err(|_| GatewayRequestsError::MalformedEncryption) + } + + pub fn new_enc_coconut_bandwidth_credential_v2( credential: CredentialSpendingData, epoch_id: u64, shared_key: &SharedKeys, @@ -167,13 +198,13 @@ impl ClientControlRequest { let serialized_credential = cred.to_bytes(); let enc_credential = shared_key.encrypt_and_tag(&serialized_credential, Some(iv.inner())); - ClientControlRequest::BandwidthCredential { + ClientControlRequest::BandwidthCredentialV2 { enc_credential, iv: iv.to_bytes(), } } - pub fn try_from_enc_coconut_bandwidth_credential( + pub fn try_from_enc_coconut_bandwidth_credential_v2( enc_credential: Vec, shared_key: &SharedKeys, iv: IV, diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 3c3ff21fa4..0f4bd0d7d6 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -22,6 +22,7 @@ use futures::{ use log::*; use nym_credentials::coconut::bandwidth::{bandwidth_credential_params, CredentialType}; use nym_credentials_interface::CoconutError; +use nym_gateway_requests::models::CredentialSpendingWithEpoch; use nym_gateway_requests::{ iv::{IVConversionError, IV}, types::{BinaryRequest, ServerResponse}, @@ -82,6 +83,12 @@ pub(crate) enum RequestHandlingError { #[error("failed to recover bandwidth value: {0}")] BandwidthRecoveryFailure(#[from] BandwidthError), + + #[error("the provided credential did not contain a valid type attribute")] + InvalidTypeAttribute, + + #[error("the provided credential did not have a bandwidth attribute")] + MissingBandwidthAttribute, } impl RequestHandlingError { @@ -211,25 +218,10 @@ where } } - /// Tries to handle the received bandwidth request by checking correctness of the received data - /// and if successful, increases client's bandwidth by an appropriate amount. - /// - /// # Arguments - /// - /// * `enc_credential`: raw encrypted bandwidth credential to verify. - /// * `iv`: fresh iv used for the credential. - async fn handle_bandwidth( + async fn handle_bandwidth_request( &mut self, - enc_credential: Vec, - iv: Vec, + credential: CredentialSpendingWithEpoch, ) -> Result { - let iv = IV::try_from_bytes(&iv)?; - let credential = ClientControlRequest::try_from_enc_coconut_bandwidth_credential( - enc_credential, - &self.client.shared_keys, - iv, - )?; - let aggregated_verification_key = self .inner .coconut_verifier @@ -237,11 +229,11 @@ where .await?; if !credential.data.validate_type_attribute() { - unimplemented!() + return Err(RequestHandlingError::InvalidTypeAttribute); } let Some(bandwidth_attribute) = credential.data.get_bandwidth_attribute() else { - unimplemented!() + return Err(RequestHandlingError::MissingBandwidthAttribute); }; // this will extract token amounts out of bandwidth vouchers and validate expiry of free passes @@ -279,6 +271,43 @@ where Ok(ServerResponse::Bandwidth { available_total }) } + async fn handle_bandwidth_v1( + &mut self, + enc_credential: Vec, + iv: Vec, + ) -> Result { + let iv = IV::try_from_bytes(&iv)?; + let credential = ClientControlRequest::try_from_enc_coconut_bandwidth_credential_v1( + enc_credential, + &self.client.shared_keys, + iv, + )?; + + self.handle_bandwidth_request(credential.try_into()?).await + } + + /// Tries to handle the received bandwidth request by checking correctness of the received data + /// and if successful, increases client's bandwidth by an appropriate amount. + /// + /// # Arguments + /// + /// * `enc_credential`: raw encrypted bandwidth credential to verify. + /// * `iv`: fresh iv used for the credential. + async fn handle_bandwidth_v2( + &mut self, + enc_credential: Vec, + iv: Vec, + ) -> Result { + let iv = IV::try_from_bytes(&iv)?; + let credential = ClientControlRequest::try_from_enc_coconut_bandwidth_credential_v2( + enc_credential, + &self.client.shared_keys, + iv, + )?; + + self.handle_bandwidth_request(credential).await + } + async fn handle_claim_testnet_bandwidth( &mut self, ) -> Result { @@ -357,7 +386,11 @@ where Err(e) => RequestHandlingError::InvalidTextRequest(e).into_error_message(), Ok(request) => match request { ClientControlRequest::BandwidthCredential { enc_credential, iv } => self - .handle_bandwidth(enc_credential, iv) + .handle_bandwidth_v1(enc_credential, iv) + .await + .into_ws_message(), + ClientControlRequest::BandwidthCredentialV2 { enc_credential, iv } => self + .handle_bandwidth_v2(enc_credential, iv) .await .into_ws_message(), ClientControlRequest::ClaimFreeTestnetBandwidth => self diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 2d08c85709..ee1395e8a8 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -366,7 +366,7 @@ where // note: in +1.2.0 we will have to return a hard error here Ok(()) } - Some(v) if v != PROTOCOL_VERSION => { + Some(v) if v > PROTOCOL_VERSION => { let err = InitialAuthenticationError::IncompatibleProtocol { client: Some(v), current: PROTOCOL_VERSION, @@ -376,7 +376,7 @@ where } Some(_) => { - info!("the client is using exactly the same protocol version as we are. We're good to continue!"); + info!("the client is using exactly the same (or older) protocol version as we are. We're good to continue!"); Ok(()) } } From 78e1d84905fce2dd9eac16fc4055890fa945c0fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 10:14:34 +0000 Subject: [PATCH 061/394] restored OldV1Credential::as_bytes to be available to non-test code --- gateway/gateway-requests/src/models.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 0bef6c4084..c16bf023cf 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -48,7 +48,6 @@ impl TryFrom for CredentialSpendingWithEpoch { } impl OldV1Credential { - #[cfg(test)] pub fn as_bytes(&self) -> Vec { let n_params_bytes = self.n_params.to_be_bytes(); let theta_bytes = self.theta.to_bytes(); From b02bbdef19ac974a9e330a619433e7eca02df2a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 13:57:35 +0000 Subject: [PATCH 062/394] fixed SQL type for epoch_id --- .../migrations/20240206120000_add_credential_types.sql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/credential-storage/migrations/20240206120000_add_credential_types.sql b/common/credential-storage/migrations/20240206120000_add_credential_types.sql index a75acca881..696d6d46a4 100644 --- a/common/credential-storage/migrations/20240206120000_add_credential_types.sql +++ b/common/credential-storage/migrations/20240206120000_add_credential_types.sql @@ -12,6 +12,6 @@ CREATE TABLE coconut_credentials serialization_revision INTEGER NOT NULL, credential_type TEXT NOT NULL, credential_data BLOB NOT NULL, - epoch_id TEXT NOT NULL, + epoch_id INTEGER NOT NULL, consumed BOOLEAN NOT NULL ); \ No newline at end of file From 00f1ce98bade2a243c7d0f1b2931c5d59d9c01c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 14:17:20 +0000 Subject: [PATCH 063/394] gateway downgrading advertised protocol for incompatible clients --- .../client-libs/gateway-client/src/client.rs | 14 +++- gateway/gateway-requests/src/lib.rs | 3 +- gateway/gateway-requests/src/types.rs | 6 +- .../websocket/connection_handler/fresh.rs | 65 +++++++++++-------- 4 files changed, 54 insertions(+), 34 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index e0cb06215e..b84e761952 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -19,7 +19,7 @@ use nym_crypto::asymmetric::identity; use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressBytes; use nym_gateway_requests::iv::IV; use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys}; -use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, PROTOCOL_VERSION}; +use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION}; use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; @@ -80,6 +80,9 @@ pub struct GatewayClient { /// Delay between each subsequent reconnection attempt. reconnection_backoff: Duration, + // currently unused (but populated) + negotiated_protocol: Option, + /// Listen to shutdown messages. shutdown: TaskClient, } @@ -109,6 +112,7 @@ impl GatewayClient { should_reconnect_on_failure: true, reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS, reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF, + negotiated_protocol: None, shutdown, } } @@ -384,10 +388,10 @@ impl GatewayClient { // note: in +1.2.0 we will have to return a hard error here Ok(()) } - Some(v) if v > PROTOCOL_VERSION => { + Some(v) if v > CURRENT_PROTOCOL_VERSION => { let err = GatewayClientError::IncompatibleProtocol { gateway: Some(v), - current: PROTOCOL_VERSION, + current: CURRENT_PROTOCOL_VERSION, }; error!("{err}"); Err(err) @@ -440,6 +444,10 @@ impl GatewayClient { if self.authenticated { self.shared_key = Some(Arc::new(shared_key)); } + + // populate the negotiated protocol for future uses + self.negotiated_protocol = gateway_protocol; + Ok(()) } diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index e27d272f23..e9aae85d7f 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -18,7 +18,8 @@ pub mod types; // history: // 1 - initial release // 2 - changes to client credentials structure -pub const PROTOCOL_VERSION: u8 = 2; +pub const INITIAL_PROTOCOL_VERSION: u8 = 1; +pub const CURRENT_PROTOCOL_VERSION: u8 = 2; pub type GatewayMac = HmacOutput; diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index e7e402c37c..0165a40c6d 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -5,7 +5,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; use crate::models::{CredentialSpendingWithEpoch, OldV1Credential}; use crate::registration::handshake::SharedKeys; -use crate::{GatewayMacSize, PROTOCOL_VERSION}; +use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION}; use log::error; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials_interface::{CoconutError, UnknownCredentialType}; @@ -39,7 +39,7 @@ pub enum RegistrationHandshake { impl RegistrationHandshake { pub fn new_payload(data: Vec) -> Self { RegistrationHandshake::HandshakePayload { - protocol_version: Some(PROTOCOL_VERSION), + protocol_version: Some(CURRENT_PROTOCOL_VERSION), data, } } @@ -157,7 +157,7 @@ impl ClientControlRequest { iv: IV, ) -> Self { ClientControlRequest::Authenticate { - protocol_version: Some(PROTOCOL_VERSION), + protocol_version: Some(CURRENT_PROTOCOL_VERSION), address: address.as_base58_string(), enc_address: enc_address.to_base58_string(), iv: iv.to_base58_string(), diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index ee1395e8a8..8f9dafe112 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -15,7 +15,7 @@ use nym_gateway_requests::{ iv::{IVConversionError, IV}, registration::handshake::{error::HandshakeError, gateway_handshake, SharedKeys}, types::{ClientControlRequest, ServerResponse}, - BinaryResponse, PROTOCOL_VERSION, + BinaryResponse, CURRENT_PROTOCOL_VERSION, INITIAL_PROTOCOL_VERSION, }; use nym_mixnet_client::forwarder::MixForwardingSender; use nym_sphinx::DestinationAddressBytes; @@ -95,6 +95,9 @@ pub(crate) struct FreshHandler { pub(crate) socket_connection: SocketStream, pub(crate) storage: St, pub(crate) coconut_verifier: Arc, + + // currently unused (but populated) + pub(crate) negotiated_protocol: Option, } impl FreshHandler @@ -126,6 +129,7 @@ where local_identity, storage, coconut_verifier, + negotiated_protocol: None, } } @@ -310,7 +314,7 @@ where /// Checks whether the stored shared keys match the received data, i.e. whether the upon decryption /// the provided encrypted address matches the expected unencrypted address. /// - /// Returns the the retrieved shared keys if the check was successful. + /// Returns the retrieved shared keys if the check was successful. /// /// # Arguments /// @@ -355,30 +359,33 @@ where } } - fn check_client_protocol( + fn negotiate_client_protocol( &self, client_protocol: Option, - ) -> Result<(), InitialAuthenticationError> { - // right now there are no failure cases here, but this might change in the future - match client_protocol { - None => { - warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); - // note: in +1.2.0 we will have to return a hard error here - Ok(()) - } - Some(v) if v > PROTOCOL_VERSION => { - let err = InitialAuthenticationError::IncompatibleProtocol { - client: Some(v), - current: PROTOCOL_VERSION, - }; - error!("{err}"); - Err(err) - } + ) -> Result { + let Some(client_protocol_version) = client_protocol else { + warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); + // note: in +1.2.0 we will have to return a hard error here + Ok(INITIAL_PROTOCOL_VERSION) + }; - Some(_) => { - info!("the client is using exactly the same (or older) protocol version as we are. We're good to continue!"); - Ok(()) - } + // a v2 gateway will understand v1 requests, but v1 client will not understand v2 responses + if client_protocol_version == 1 { + return Ok(1); + } + + // we can't handle clients with higher protocol than ours + // (perhaps we could try to negotiate downgrade on our end? sounds like a nice future improvement) + if client_protocol_version <= CURRENT_PROTOCOL_VERSION { + info!("the client is using exactly the same (or older) protocol version as we are. We're good to continue!"); + Ok(CURRENT_PROTOCOL_VERSION) + } else { + let err = InitialAuthenticationError::IncompatibleProtocol { + client: client_protocol, + current: CURRENT_PROTOCOL_VERSION, + }; + error!("{err}"); + Err(err) } } @@ -490,7 +497,9 @@ where where S: AsyncRead + AsyncWrite + Unpin, { - self.check_client_protocol(client_protocol_version)?; + let negotiated_protocol = self.negotiate_client_protocol(client_protocol_version)?; + // populate the negotiated protocol for future uses + self.negotiated_protocol = Some(negotiated_protocol); let address = DestinationAddressBytes::try_from_base58_string(address) .map_err(|err| InitialAuthenticationError::MalformedClientAddress(err.to_string()))?; @@ -519,7 +528,7 @@ where Ok(InitialAuthResult::new( client_details, ServerResponse::Authenticate { - protocol_version: Some(PROTOCOL_VERSION), + protocol_version: Some(negotiated_protocol), status, bandwidth_remaining, }, @@ -580,7 +589,9 @@ where where S: AsyncRead + AsyncWrite + Unpin + Send, { - self.check_client_protocol(client_protocol_version)?; + let negotiated_protocol = self.negotiate_client_protocol(client_protocol_version)?; + // populate the negotiated protocol for future uses + self.negotiated_protocol = Some(negotiated_protocol); let remote_identity = Self::extract_remote_identity_from_register_init(&init_data)?; let remote_address = remote_identity.derive_destination_address(); @@ -597,7 +608,7 @@ where Ok(InitialAuthResult::new( Some(client_details), ServerResponse::Register { - protocol_version: Some(PROTOCOL_VERSION), + protocol_version: Some(negotiated_protocol), status, }, )) From ffe55ba072db65c8c50a0296da31c6a1cdc4326f Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 9 Feb 2024 15:32:35 +0100 Subject: [PATCH 064/394] running cargo fmt --- common/client-libs/gateway-client/src/client.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index b84e761952..a27ec472ba 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -19,7 +19,9 @@ use nym_crypto::asymmetric::identity; use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressBytes; use nym_gateway_requests::iv::IV; use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys}; -use nym_gateway_requests::{BinaryRequest, ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION}; +use nym_gateway_requests::{ + BinaryRequest, ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION, +}; use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; @@ -447,7 +449,7 @@ impl GatewayClient { // populate the negotiated protocol for future uses self.negotiated_protocol = gateway_protocol; - + Ok(()) } From 400d71bf07ed9403b9cf2ea0747ece86f42486a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 14:57:49 +0000 Subject: [PATCH 065/394] ibid --- common/client-libs/gateway-client/src/client.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index a27ec472ba..87e9fa758a 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -831,6 +831,7 @@ impl GatewayClient { should_reconnect_on_failure: false, reconnection_attempts: DEFAULT_RECONNECTION_ATTEMPTS, reconnection_backoff: DEFAULT_RECONNECTION_BACKOFF, + negotiated_protocol: None, shutdown, } } @@ -862,6 +863,7 @@ impl GatewayClient { should_reconnect_on_failure: self.should_reconnect_on_failure, reconnection_attempts: self.reconnection_attempts, reconnection_backoff: self.reconnection_backoff, + negotiated_protocol: self.negotiated_protocol, shutdown, } } From 691884e20a6d894e8515838be07a13e3d4178aad Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 9 Feb 2024 16:32:53 +0100 Subject: [PATCH 066/394] add return statement --- .../node/client_handling/websocket/connection_handler/fresh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 8f9dafe112..c37b0acaae 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -366,7 +366,7 @@ where let Some(client_protocol_version) = client_protocol else { warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); // note: in +1.2.0 we will have to return a hard error here - Ok(INITIAL_PROTOCOL_VERSION) + return Ok(INITIAL_PROTOCOL_VERSION) }; // a v2 gateway will understand v1 requests, but v1 client will not understand v2 responses From 6e7bac1e7e27d9287f9b08ccfd5c07437e69564b Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Fri, 9 Feb 2024 16:41:01 +0100 Subject: [PATCH 067/394] cargo fmt --- .../node/client_handling/websocket/connection_handler/fresh.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index c37b0acaae..a2e9e98e7d 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -366,7 +366,7 @@ where let Some(client_protocol_version) = client_protocol else { warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); // note: in +1.2.0 we will have to return a hard error here - return Ok(INITIAL_PROTOCOL_VERSION) + return Ok(INITIAL_PROTOCOL_VERSION); }; // a v2 gateway will understand v1 requests, but v1 client will not understand v2 responses From 740cc72ec89068faa485f1ce42a3ff07fde8cc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 13:54:13 +0000 Subject: [PATCH 068/394] request type for obtaining free pass --- .../validator-client/src/nym_api/routes.rs | 1 + nym-api/nym-api-requests/Cargo.toml | 5 ++++- nym-api/nym-api-requests/src/coconut/models.rs | 14 ++++++++++++++ nym-api/src/coconut/api_routes/mod.rs | 5 +++++ nym-connect/desktop/Cargo.lock | 14 ++++++++++++++ nym-wallet/Cargo.lock | 14 ++++++++++++++ 6 files changed, 52 insertions(+), 1 deletion(-) diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index d670033049..bb3125f001 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -15,6 +15,7 @@ pub const REWARDED: &str = "rewarded"; pub const COCONUT_ROUTES: &str = "coconut"; pub const BANDWIDTH: &str = "bandwidth"; +pub const COCONUT_FREE_PASS: &str = "free-pass"; pub const COCONUT_BLIND_SIGN: &str = "blind-sign"; pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential"; pub const COCONUT_EPOCH_CREDENTIALS: &str = "epoch-credentials"; diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index 1baf4d17dd..d76ce70675 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -16,10 +16,13 @@ serde = { workspace = true, features = ["derive"] } ts-rs = { workspace = true, optional = true } tendermint = { workspace = true } +# for serde on secp256k1 signatures +ecdsa = { version = "0.16", features = ["serde"] } + nym-credentials-interface = { path = "../../common/credentials-interface" } nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]} -nym-mixnet-contract-common = { path= "../../common/cosmwasm-smart-contracts/mixnet-contract" } +nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-node-requests = { path = "../../nym-node/nym-node-requests", default-features = false } [features] diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index c4de811281..4092f8fbee 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -140,6 +140,20 @@ impl BlindedSignatureResponse { } } +#[derive(Serialize, Deserialize)] +pub struct FreePassRequest { + // secp256k1 key associated with the admin account + pub cosmos_pubkey: cosmrs::crypto::PublicKey, + + pub inner_sign_request: BlindSignRequest, + + /// Signature on the inner sign request + /// to prove the possession of the cosmos key/address + pub signature: cosmrs::crypto::secp256k1::Signature, + + pub public_attributes_plain: Vec, +} + #[derive(Serialize, Deserialize)] pub struct VerificationKeyResponse { pub key: VerificationKey, diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index b2b2dfc4bc..8d0a6a2caf 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -26,6 +26,11 @@ use rocket::State as RocketState; mod helpers; +pub async fn post_free_pass(state: &RocketState) { + // attach secp256k1 pubkey; derive address; check contract admin verify signature + todo!() +} + #[post("/blind-sign", data = "")] // Until we have serialization and deserialization traits we'll be using a crutch pub async fn post_blind_sign( diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 6480b0a255..3c146f252d 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -1729,6 +1729,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.5", "rfc6979 0.4.0", + "serdect", "signature 2.1.0", "spki 0.7.2", ] @@ -1837,6 +1838,7 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -3693,6 +3695,7 @@ dependencies = [ "bs58 0.4.0", "cosmrs", "cosmwasm-std", + "ecdsa 0.16.8", "getset", "nym-credentials-interface", "nym-crypto", @@ -5824,6 +5827,7 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -6149,6 +6153,16 @@ dependencies = [ "syn 2.0.28", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "serialize-to-javascript" version = "0.1.1" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index e9cdff7476..885674bddb 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -1480,6 +1480,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.5", "rfc6979 0.4.0", + "serdect", "signature 2.1.0", "spki 0.7.2", ] @@ -1588,6 +1589,7 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -3097,6 +3099,7 @@ dependencies = [ "bs58 0.4.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", + "ecdsa 0.16.8", "getset", "nym-credentials-interface", "nym-crypto", @@ -4690,6 +4693,7 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -4878,6 +4882,16 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "serialize-to-javascript" version = "0.1.1" From c9ff5503118dcfb223410fd3893af8a9e553c918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 16:54:07 +0000 Subject: [PATCH 069/394] nym-api logic for issuing free passes (minus storage impl) --- nym-api/Cargo.toml | 1 + .../20240209120000_free_pass_nonces.sql | 10 ++ .../nym-api-requests/src/coconut/models.rs | 27 ++++- nym-api/src/coconut/api_routes/mod.rs | 103 +++++++++++++++++- nym-api/src/coconut/client.rs | 2 + nym-api/src/coconut/error.rs | 25 +++++ nym-api/src/coconut/helpers.rs | 37 ++++++- nym-api/src/coconut/mod.rs | 1 + nym-api/src/coconut/state.rs | 11 +- nym-api/src/coconut/storage/mod.rs | 12 ++ nym-api/src/coconut/tests/mod.rs | 57 ++++++++++ nym-api/src/support/nyxd/mod.rs | 14 +++ 12 files changed, 286 insertions(+), 14 deletions(-) create mode 100644 nym-api/migrations/20240209120000_free_pass_nonces.sql diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index db80920086..536f7915a8 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -26,6 +26,7 @@ dirs = "4.0" futures = { workspace = true } itertools = "0.12.0" humantime-serde = "1.0" +k256 = { version = "*", features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies lazy_static = "1.4.0" log = { workspace = true } pin-project = "1.0" diff --git a/nym-api/migrations/20240209120000_free_pass_nonces.sql b/nym-api/migrations/20240209120000_free_pass_nonces.sql new file mode 100644 index 0000000000..da6fd73d37 --- /dev/null +++ b/nym-api/migrations/20240209120000_free_pass_nonces.sql @@ -0,0 +1,10 @@ +/* + * Copyright 2024 - Nym Technologies SA + * SPDX-License-Identifier: Apache-2.0 + */ + +CREATE TABLE ISSUED_FREEPASS +( + id INTEGER PRIMARY KEY CHECK (id = 0), + current_nonce INTEGER NOT NULL +); \ No newline at end of file diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 4092f8fbee..295a8b2720 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -140,20 +140,41 @@ impl BlindedSignatureResponse { } } -#[derive(Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct FreePassRequest { // secp256k1 key associated with the admin account pub cosmos_pubkey: cosmrs::crypto::PublicKey, pub inner_sign_request: BlindSignRequest, - /// Signature on the inner sign request + // we need to include a nonce here to prevent replay attacks + // (and not making the nym-api store the serial numbers of all issued credential) + pub used_nonce: u64, + + /// Signature on the nonce /// to prove the possession of the cosmos key/address - pub signature: cosmrs::crypto::secp256k1::Signature, + pub nonce_signature: cosmrs::crypto::secp256k1::Signature, pub public_attributes_plain: Vec, } +impl FreePassRequest { + pub fn tendermint_pubkey(&self) -> tendermint::PublicKey { + self.cosmos_pubkey.into() + } + + pub fn nonce_plaintext(&self) -> [u8; 8] { + self.used_nonce.to_be_bytes() + } + + pub fn public_attributes_hashed(&self) -> Vec { + self.public_attributes_plain + .iter() + .map(hash_to_scalar) + .collect() + } +} + #[derive(Serialize, Deserialize)] pub struct VerificationKeyResponse { pub key: VerificationKey, diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 8d0a6a2caf..76a53c0d8e 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -6,8 +6,9 @@ use crate::coconut::error::{CoconutError, Result}; use crate::coconut::helpers::{accepted_vote_err, blind_sign}; use crate::coconut::state::State; use crate::coconut::storage::CoconutStorageExt; +use k256::ecdsa::signature::Verifier; use nym_api_requests::coconut::models::{ - CredentialsRequestBody, EpochCredentialsResponse, IssuedCredentialResponse, + CredentialsRequestBody, EpochCredentialsResponse, FreePassRequest, IssuedCredentialResponse, IssuedCredentialsResponse, }; use nym_api_requests::coconut::{ @@ -23,12 +24,93 @@ use nym_credentials::coconut::bandwidth::{ use nym_validator_client::nyxd::Coin; use rocket::serde::json::Json; use rocket::State as RocketState; +use std::ops::Deref; mod helpers; -pub async fn post_free_pass(state: &RocketState) { - // attach secp256k1 pubkey; derive address; check contract admin verify signature - todo!() +#[post("/free-pass", data = "")] +pub async fn post_free_pass( + freepass_request_body: Json, + state: &RocketState, +) -> Result> { + debug!("Received free pass sign request"); + trace!("body: {:?}", freepass_request_body); + + // grab the admin of the bandwidth contract + let Some(authorised_admin) = state.get_bandwidth_contract_admin().await? else { + error!("our bandwidth contract does not have an admin set! We won't be able to migrate the contract! We should redeploy it ASAP"); + return Err(CoconutError::MissingBandwidthContractAdmin); + }; + + // derive the address out of the provided pubkey + let requester = match freepass_request_body + .cosmos_pubkey + .account_id(authorised_admin.prefix()) + { + Ok(address) => address, + Err(err) => { + return Err(CoconutError::AdminAccountDerivationFailure { + formatted_source: err.to_string(), + }) + } + }; + debug!("derived the following address out of the provided public key: {requester}. Going to check it against the authorised admin ({authorised_admin})"); + + if &requester != authorised_admin { + return Err(CoconutError::UnauthorisedFreePassAccount { + requester, + authorised_admin: authorised_admin.clone(), + }); + } + + let current_nonce = state.storage.get_current_freepass_nonce().await?; + debug!("the current expected nonce is {current_nonce}"); + + if current_nonce != freepass_request_body.used_nonce { + return Err(CoconutError::InvalidNonce { + current: current_nonce, + received: freepass_request_body.used_nonce, + }); + } + + // check if we have the signing key available + debug!("checking if we actually have coconut keys derived..."); + let maybe_keypair_guard = state.coconut_keypair.get().await; + let Some(keypair_guard) = maybe_keypair_guard.as_ref() else { + return Err(CoconutError::KeyPairNotDerivedYet); + }; + let Some(signing_key) = keypair_guard.as_ref() else { + return Err(CoconutError::KeyPairNotDerivedYet); + }; + + let tm_pubkey = freepass_request_body.tendermint_pubkey(); + + // currently accounts (excluding validators) don't use ed25519 and are secp256k1-based + let Some(secp256k1_pubkey) = tm_pubkey.secp256k1() else { + return Err(CoconutError::UnsupportedNonSecp256k1Key); + }; + + // make sure the signature actually verifies + secp256k1_pubkey + .verify( + &freepass_request_body.nonce_plaintext(), + &freepass_request_body.nonce_signature, + ) + .map_err(|_| CoconutError::FreePassSignatureVerificationFailure)?; + + // produce the partial signature + debug!("producing the partial credential"); + let blinded_signature = + blind_sign(freepass_request_body.deref(), signing_key.keys.secret_key())?; + + // update the nonce in storage (and also check if a parallel request hasn't updated it; if so we return an error. no race conditions allowed) + state + .storage + .update_and_validate_freepass_nonce(current_nonce + 1) + .await?; + + // finally return the credential to the client + Ok(Json(BlindedSignatureResponse { blinded_signature })) } #[post("/blind-sign", data = "")] @@ -82,7 +164,10 @@ pub async fn post_blind_sign( // produce the partial signature debug!("producing the partial credential"); - let blinded_signature = blind_sign(&blind_sign_request_body, signing_key.keys.secret_key())?; + let blinded_signature = blind_sign( + blind_sign_request_body.deref(), + signing_key.keys.secret_key(), + )?; // store the information locally debug!("storing the issued credential in the database"); @@ -223,3 +308,11 @@ pub async fn issued_credentials( build_credentials_response(credentials).map(Json) } + +#[cfg(test)] +mod tests { + use super::*; + + #[tokio::test] + async fn foo() {} +} diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index f018c1f72d..bf0b7ac60a 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -27,6 +27,8 @@ pub trait Client { async fn address(&self) -> AccountId; async fn dkg_contract_address(&self) -> Result; + + async fn bandwidth_contract_admin(&self) -> Result>; async fn get_tx(&self, tx_hash: Hash) -> Result; diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index ec43b0d65d..9efa07b2b7 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -11,6 +11,7 @@ use nym_crypto::asymmetric::{ use nym_dkg::error::DkgError; use nym_validator_client::coconut::CoconutApiError; use nym_validator_client::nyxd::error::{NyxdError, TendermintError}; +use nym_validator_client::nyxd::AccountId; use rocket::http::{ContentType, Status}; use rocket::response::Responder; use rocket::{response, Request, Response}; @@ -25,6 +26,30 @@ pub enum CoconutError { #[error(transparent)] IOError(#[from] std::io::Error), + #[error("the address of the bandwidth contract hasn't been set")] + MissingBandwidthContractAddress, + + #[error("the current bandwidth contract does not have any admin address set")] + MissingBandwidthContractAdmin, + + #[error("failed to derive the admin account from the provided public key: {formatted_source}")] + AdminAccountDerivationFailure { formatted_source: String }, + + #[error("the requester of the free pass ({requester}) is not authorised. the only allowed account is {authorised_admin}.")] + UnauthorisedFreePassAccount { + requester: AccountId, + authorised_admin: AccountId, + }, + + #[error("failed to verify signature on the provided free pass request")] + FreePassSignatureVerificationFailure, + + #[error("the provided signing nonce is invalid. the current value is: {current}. got {received} instead")] + InvalidNonce { current: u64, received: u64 }, + + #[error("only secp256k1 keys are supported for free pass issuance")] + UnsupportedNonSecp256k1Key, + #[error("the received bandwidth voucher did not contain deposit value")] MissingBandwidthValue, diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index ee55f9ff1d..15b9a15477 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -3,8 +3,9 @@ use crate::coconut::error::CoconutError; use crate::coconut::state::bandwidth_credential_params; +use nym_api_requests::coconut::models::FreePassRequest; use nym_api_requests::coconut::BlindSignRequestBody; -use nym_coconut::{BlindedSignature, SecretKey}; +use nym_coconut::{Attribute, BlindSignRequest, BlindedSignature, SecretKey}; use nym_validator_client::nyxd::error::NyxdError::AbciError; // If the result is already established, the vote might be redundant and @@ -21,17 +22,43 @@ pub(crate) fn accepted_vote_err(ret: Result<(), CoconutError>) -> Result<(), Coc Ok(()) } -pub(crate) fn blind_sign( - request: &BlindSignRequestBody, +pub(crate) trait CredentialRequest { + fn blind_sign_request(&self) -> &BlindSignRequest; + + fn public_attributes(&self) -> Vec; +} + +impl CredentialRequest for BlindSignRequestBody { + fn blind_sign_request(&self) -> &BlindSignRequest { + &self.inner_sign_request + } + + fn public_attributes(&self) -> Vec { + self.public_attributes_hashed() + } +} + +impl CredentialRequest for FreePassRequest { + fn blind_sign_request(&self) -> &BlindSignRequest { + &self.inner_sign_request + } + + fn public_attributes(&self) -> Vec { + self.public_attributes_hashed() + } +} + +pub(crate) fn blind_sign( + request: &C, signing_key: &SecretKey, ) -> Result { - let public_attributes = request.public_attributes_hashed(); + let public_attributes = request.public_attributes(); let attributes_ref = public_attributes.iter().collect::>(); Ok(nym_coconut::blind_sign( bandwidth_credential_params(), signing_key, - &request.inner_sign_request, + &request.blind_sign_request(), &attributes_ref, )?) } diff --git a/nym-api/src/coconut/mod.rs b/nym-api/src/coconut/mod.rs index 2e1af74968..82ca3c59b2 100644 --- a/nym-api/src/coconut/mod.rs +++ b/nym-api/src/coconut/mod.rs @@ -52,6 +52,7 @@ where // this format! is so ugly... format!("/{NYM_API_VERSION}/{COCONUT_ROUTES}/{BANDWIDTH}"), routes![ + api_routes::post_free_pass, api_routes::post_blind_sign, api_routes::verify_bandwidth_credential, api_routes::epoch_credentials, diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index d92a5d6f81..c85c77575a 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -13,13 +13,15 @@ use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut::{BlindedSignature, VerificationKey}; use nym_coconut_dkg_common::types::EpochId; use nym_crypto::asymmetric::identity; -use nym_validator_client::nyxd::{Hash, TxResponse}; +use nym_validator_client::nyxd::{AccountId, Hash, TxResponse}; use std::sync::Arc; +use tokio::sync::OnceCell; pub use nym_credentials::coconut::bandwidth::bandwidth_credential_params; pub struct State { pub(crate) client: Arc, + pub(crate) bandwidth_contract_admin: OnceCell>, pub(crate) mix_denom: String, pub(crate) coconut_keypair: KeyPair, pub(crate) identity_keypair: identity::KeyPair, @@ -45,6 +47,7 @@ impl State { Self { client, + bandwidth_contract_admin: OnceCell::new(), mix_denom, coconut_keypair: key_pair, identity_keypair, @@ -67,6 +70,12 @@ impl State { self.client.get_tx(tx_hash).await } + pub async fn get_bandwidth_contract_admin(&self) -> Result<&Option> { + self.bandwidth_contract_admin + .get_or_try_init(|| async { self.client.bandwidth_contract_admin().await }) + .await + } + pub async fn validate_request( &self, request: &BlindSignRequestBody, diff --git a/nym-api/src/coconut/storage/mod.rs b/nym-api/src/coconut/storage/mod.rs index 5633ba468d..ad7a98ff05 100644 --- a/nym-api/src/coconut/storage/mod.rs +++ b/nym-api/src/coconut/storage/mod.rs @@ -63,6 +63,10 @@ pub trait CoconutStorageExt { &self, pagination: Pagination, ) -> Result, NymApiStorageError>; + + async fn get_current_freepass_nonce(&self) -> Result; + + async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError>; } #[async_trait] @@ -163,4 +167,12 @@ impl CoconutStorageExt for NymApiStorage { .get_issued_credentials_paged(start_after, limit) .await?) } + + async fn get_current_freepass_nonce(&self) -> Result { + todo!() + } + + async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError> { + todo!() + } } diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index 726c42dbd2..fe0ad3b165 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -275,6 +275,7 @@ impl FakeMultisigContractState { #[derive(Debug)] pub(crate) struct FakeBandwidthContractState { pub(crate) address: Addr, + pub(crate) admin: Option, pub(crate) spent_credentials: HashMap, } @@ -313,6 +314,11 @@ impl Default for FakeChainState { let bandwidth_contract = Addr::unchecked("n16a32stm6kknhq5cc8rx77elr66pygf2hfszw7wvpq746x3uffylqkjar4l"); + let bandwidth_contract_admin = + "n1ahg0erc2fs6xx3j5m8sfx3ryuzdjh6kf6qm9plsf865fltekyrfsesac6a" + .parse() + .unwrap(); + FakeChainState { _counters: Default::default(), @@ -346,6 +352,7 @@ impl Default for FakeChainState { }, bandwidth_contract: FakeBandwidthContractState { address: bandwidth_contract, + admin: Some(bandwidth_contract_admin), spent_credentials: Default::default(), }, } @@ -612,6 +619,10 @@ impl super::client::Client for DummyClient { Ok(self.state.lock().unwrap().dkg_contract.address.clone()) } + async fn bandwidth_contract_admin(&self) -> Result> { + Ok(self.state.lock().unwrap().bandwidth_contract.admin.clone()) + } + async fn get_tx(&self, tx_hash: Hash) -> Result { Ok(self .state @@ -786,6 +797,52 @@ impl super::client::Client for DummyClient { }) } + async fn get_dealer_dealings_status( + &self, + epoch_id: EpochId, + dealer: String, + ) -> Result { + let guard = self.state.lock().unwrap(); + let key_size = guard.dkg_contract.contract_state.key_size; + + let dealer_addr = Addr::unchecked(&dealer); + + let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { + return Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: dealer_addr, + all_dealings_fully_submitted: false, + dealing_submission_status: Default::default(), + }); + }; + + let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { + return Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: dealer_addr, + all_dealings_fully_submitted: false, + dealing_submission_status: Default::default(), + }); + }; + + let mut dealing_submission_status: BTreeMap = BTreeMap::new(); + for dealing_index in 0..key_size { + let metadata = dealer_dealings + .get(&dealing_index) + .map(|d| d.metadata.clone()); + dealing_submission_status.insert(dealing_index, metadata.into()); + } + + Ok(DealerDealingsStatusResponse { + epoch_id, + dealer: Addr::unchecked(&dealer), + all_dealings_fully_submitted: dealing_submission_status + .values() + .all(|d| d.fully_submitted), + dealing_submission_status, + }) + } + async fn get_dealing_status( &self, epoch_id: EpochId, diff --git a/nym-api/src/support/nyxd/mod.rs b/nym-api/src/support/nyxd/mod.rs index 1ae492206e..79fb39b663 100644 --- a/nym-api/src/support/nyxd/mod.rs +++ b/nym-api/src/support/nyxd/mod.rs @@ -355,6 +355,20 @@ impl crate::coconut::client::Client for Client { ) } + async fn bandwidth_contract_admin(&self) -> crate::coconut::error::Result> { + let guard = self.inner.read().await; + + let bandwidth_contract = query_guard!( + guard, + coconut_bandwidth_contract_address() + .ok_or(CoconutError::MissingBandwidthContractAddress) + )?; + + let contract = query_guard!(guard, get_contract(bandwidth_contract)).await?; + + Ok(contract.contract_info.admin) + } + async fn get_tx(&self, tx_hash: Hash) -> crate::coconut::error::Result { nyxd_query!(self, get_tx(tx_hash).await).map_err(|source| { CoconutError::TxRetrievalFailure { From f61b898c4f0b625f480ef8204f4269d794c2f005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 17:23:58 +0000 Subject: [PATCH 070/394] storage implementation --- .../20240209120000_free_pass_nonces.sql | 6 +- .../nym-api-requests/src/coconut/models.rs | 4 +- nym-api/src/coconut/error.rs | 2 +- nym-api/src/coconut/storage/manager.rs | 57 +++++++++++++++++++ nym-api/src/coconut/storage/mod.rs | 8 +-- 5 files changed, 68 insertions(+), 9 deletions(-) diff --git a/nym-api/migrations/20240209120000_free_pass_nonces.sql b/nym-api/migrations/20240209120000_free_pass_nonces.sql index da6fd73d37..441910036b 100644 --- a/nym-api/migrations/20240209120000_free_pass_nonces.sql +++ b/nym-api/migrations/20240209120000_free_pass_nonces.sql @@ -3,8 +3,10 @@ * SPDX-License-Identifier: Apache-2.0 */ -CREATE TABLE ISSUED_FREEPASS +CREATE TABLE issued_freepass ( id INTEGER PRIMARY KEY CHECK (id = 0), current_nonce INTEGER NOT NULL -); \ No newline at end of file +); + +INSERT INTO issued_freepass(id, current_nonce) VALUES (0,0); \ No newline at end of file diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 295a8b2720..0a3c3c0138 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -149,7 +149,7 @@ pub struct FreePassRequest { // we need to include a nonce here to prevent replay attacks // (and not making the nym-api store the serial numbers of all issued credential) - pub used_nonce: u64, + pub used_nonce: u32, /// Signature on the nonce /// to prove the possession of the cosmos key/address @@ -163,7 +163,7 @@ impl FreePassRequest { self.cosmos_pubkey.into() } - pub fn nonce_plaintext(&self) -> [u8; 8] { + pub fn nonce_plaintext(&self) -> [u8; 4] { self.used_nonce.to_be_bytes() } diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 9efa07b2b7..969b7dfeb2 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -45,7 +45,7 @@ pub enum CoconutError { FreePassSignatureVerificationFailure, #[error("the provided signing nonce is invalid. the current value is: {current}. got {received} instead")] - InvalidNonce { current: u64, received: u64 }, + InvalidNonce { current: u32, received: u32 }, #[error("only secp256k1 keys are supported for free pass issuance")] UnsupportedNonSecp256k1Key, diff --git a/nym-api/src/coconut/storage/manager.rs b/nym-api/src/coconut/storage/manager.rs index e40b2a4a96..17816bebd8 100644 --- a/nym-api/src/coconut/storage/manager.rs +++ b/nym-api/src/coconut/storage/manager.rs @@ -4,6 +4,7 @@ use crate::coconut::storage::models::{EpochCredentials, IssuedCredential}; use crate::support::storage::manager::StorageManager; use nym_coconut_dkg_common::types::EpochId; +use thiserror::Error; #[async_trait] pub trait CoconutStorageManagerExt { @@ -120,6 +121,17 @@ pub trait CoconutStorageManagerExt { start_after: i64, limit: u32, ) -> Result, sqlx::Error>; + + /// Attempts to retrieve the current value of the freepass nonce. + async fn get_current_freepass_nonce(&self) -> Result; + + /// Attempt to update the currently stored nonce to the provided value whilst ensuring + /// it's strictly equal the current value plus 1 + /// + /// # Arguments + /// + /// * `new`: the new value of the free pass nonce + async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error>; } #[async_trait] @@ -378,4 +390,49 @@ impl CoconutStorageManagerExt for StorageManager { .fetch_all(&self.connection_pool) .await } + + /// Attempts to retrieve the current value of the freepass nonce. + async fn get_current_freepass_nonce(&self) -> Result { + sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass") + .fetch_one(&self.connection_pool) + .await + .map(|row| row.current_nonce) + } + + /// Attempt to update the currently stored nonce to the provided value whilst ensuring + /// it's strictly equal the current value plus 1 + /// + /// # Arguments + /// + /// * `new`: the new value of the free pass nonce + async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error> { + let mut tx = self.connection_pool.begin().await?; + + let currently_stored = + sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass") + .fetch_one(&mut tx) + .await? + .current_nonce; + + if currently_stored + 1 != new { + // this is not the best error but I really don't want to be creating a new enum + return Err(sqlx::Error::Decode(Box::new(UnexpectedNonce { + current: currently_stored, + got: new, + }))); + } + + sqlx::query!("UPDATE issued_freepass SET current_nonce = ?", new) + .execute(&mut tx) + .await?; + + tx.commit().await + } +} + +#[derive(Debug, Error)] +#[error("tried to store an invalid nonce. the received value is {got} while current is {current}. expected {current} + 1")] +pub struct UnexpectedNonce { + current: u32, + got: u32, } diff --git a/nym-api/src/coconut/storage/mod.rs b/nym-api/src/coconut/storage/mod.rs index ad7a98ff05..89156ee7da 100644 --- a/nym-api/src/coconut/storage/mod.rs +++ b/nym-api/src/coconut/storage/mod.rs @@ -64,9 +64,9 @@ pub trait CoconutStorageExt { pagination: Pagination, ) -> Result, NymApiStorageError>; - async fn get_current_freepass_nonce(&self) -> Result; + async fn get_current_freepass_nonce(&self) -> Result; - async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError>; + async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError>; } #[async_trait] @@ -168,11 +168,11 @@ impl CoconutStorageExt for NymApiStorage { .await?) } - async fn get_current_freepass_nonce(&self) -> Result { + async fn get_current_freepass_nonce(&self) -> Result { todo!() } - async fn update_and_validate_freepass_nonce(&self, new: u64) -> Result<(), NymApiStorageError> { + async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError> { todo!() } } From 96f3192694ecf40cb0d57def6bb6ad26022591d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 9 Feb 2024 17:35:07 +0000 Subject: [PATCH 071/394] validating request attributes --- .../credentials/src/coconut/bandwidth/mod.rs | 2 +- nym-api/src/coconut/api_routes/mod.rs | 44 ++++++++++++++++++- nym-api/src/coconut/error.rs | 31 ++++++++++++- nym-api/src/coconut/storage/mod.rs | 4 +- 4 files changed, 76 insertions(+), 5 deletions(-) diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 195db20598..8a0e8f4136 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -6,7 +6,7 @@ use std::sync::OnceLock; pub use issuance::IssuanceBandwidthCredential; pub use issued::IssuedBandwidthCredential; pub use nym_credentials_interface::{ - CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, + CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, UnknownCredentialType }; pub mod freepass; diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 76a53c0d8e..45fef58525 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -18,16 +18,56 @@ use nym_coconut_bandwidth_contract_common::spend_credential::{ funds_from_cosmos_msgs, SpendCredentialStatus, }; use nym_coconut_dkg_common::types::EpochId; +use nym_credentials::coconut::bandwidth::freepass::MAX_FREE_PASS_VALIDITY; use nym_credentials::coconut::bandwidth::{ - bandwidth_credential_params, IssuanceBandwidthCredential, + bandwidth_credential_params, CredentialType, IssuanceBandwidthCredential, }; use nym_validator_client::nyxd::Coin; use rocket::serde::json::Json; use rocket::State as RocketState; use std::ops::Deref; +use time::OffsetDateTime; mod helpers; +fn validate_freepass_public_attributes(res: &FreePassRequest) -> Result<()> { + let public_attributes = &res.public_attributes_plain; + + if public_attributes.len() != IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize { + return Err(CoconutError::InvalidFreePassAttributes { + got: public_attributes.len(), + expected: IssuanceBandwidthCredential::PUBLIC_ATTRIBUTES as usize, + }); + } + + // SAFETY: we just ensured correct number of attributes + let expiry_raw = public_attributes.first().unwrap(); + let type_raw = public_attributes.get(1).unwrap(); + + let parsed_type = type_raw.parse::()?; + if parsed_type != CredentialType::FreePass { + return Err(CoconutError::InvalidFreePassTypeAttribute { got: parsed_type }); + } + + let expiry_timestamp: i64 = expiry_raw + .parse() + .map_err(|source| CoconutError::ExpiryDateParsingFailure { source })?; + + let expiry_date = OffsetDateTime::from_unix_timestamp(expiry_timestamp).map_err(|source| { + CoconutError::InvalidExpiryDate { + unix_timestamp: expiry_timestamp, + source, + } + })?; + let now = OffsetDateTime::now_utc(); + + if expiry_date > now + MAX_FREE_PASS_VALIDITY { + return Err(CoconutError::TooLongFreePass { expiry_date }); + } + + Ok(()) +} + #[post("/free-pass", data = "")] pub async fn post_free_pass( freepass_request_body: Json, @@ -36,6 +76,8 @@ pub async fn post_free_pass( debug!("Received free pass sign request"); trace!("body: {:?}", freepass_request_body); + validate_freepass_public_attributes(&freepass_request_body)?; + // grab the admin of the bandwidth contract let Some(authorised_admin) = state.get_bandwidth_contract_admin().await? else { error!("our bandwidth contract does not have an admin set! We won't be able to migrate the contract! We should redeploy it ASAP"); diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 969b7dfeb2..d5f6ac81d6 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -3,7 +3,7 @@ use crate::node_status_api::models::NymApiStorageError; use nym_coconut_dkg_common::types::{ChunkIndex, DealingIndex, EpochId}; -use nym_credentials::coconut::bandwidth::CredentialType; +use nym_credentials::coconut::bandwidth::{CredentialType, UnknownCredentialType}; use nym_crypto::asymmetric::{ encryption::KeyRecoveryError, identity::{Ed25519RecoveryError, SignatureError}, @@ -18,6 +18,8 @@ use rocket::{response, Request, Response}; use std::io::Cursor; use std::num::ParseIntError; use thiserror::Error; +use time::error::ComponentRange; +use time::OffsetDateTime; pub type Result = std::result::Result; @@ -50,6 +52,33 @@ pub enum CoconutError { #[error("only secp256k1 keys are supported for free pass issuance")] UnsupportedNonSecp256k1Key, + #[error("received credential request for an unknown type: {0}")] + UnknownCredentialType(#[from] UnknownCredentialType), + + #[error("the provided free pass request had an unexpected number of public attributes. got {got} but expected {expected}")] + InvalidFreePassAttributes { got: usize, expected: usize }, + + #[error("the provided free pass request had an invalid type attribute (got: '{got}')")] + InvalidFreePassTypeAttribute { got: CredentialType }, + + #[error("failed to parse the free pass expiry date: {source}")] + ExpiryDateParsingFailure { + #[source] + source: ParseIntError, + }, + + #[error("failed to parse expiry timestamp into proper datetime: {source}")] + InvalidExpiryDate { + unix_timestamp: i64, + #[source] + source: ComponentRange, + }, + + #[error( + "the provided free pass request has too long expiry (expiry is set to on {expiry_date})" + )] + TooLongFreePass { expiry_date: OffsetDateTime }, + #[error("the received bandwidth voucher did not contain deposit value")] MissingBandwidthValue, diff --git a/nym-api/src/coconut/storage/mod.rs b/nym-api/src/coconut/storage/mod.rs index 89156ee7da..f77703cea8 100644 --- a/nym-api/src/coconut/storage/mod.rs +++ b/nym-api/src/coconut/storage/mod.rs @@ -169,10 +169,10 @@ impl CoconutStorageExt for NymApiStorage { } async fn get_current_freepass_nonce(&self) -> Result { - todo!() + Ok(self.manager.get_current_freepass_nonce().await?) } async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError> { - todo!() + Ok(self.manager.update_and_validate_freepass_nonce(new).await?) } } From 3fa74c90ff3ee518cab794a7a0797d05735aa955 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 10:01:50 +0000 Subject: [PATCH 072/394] cargo fmt --- common/credentials/src/coconut/bandwidth/mod.rs | 3 ++- nym-api/src/coconut/client.rs | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/common/credentials/src/coconut/bandwidth/mod.rs b/common/credentials/src/coconut/bandwidth/mod.rs index 8a0e8f4136..de49c9d4b4 100644 --- a/common/credentials/src/coconut/bandwidth/mod.rs +++ b/common/credentials/src/coconut/bandwidth/mod.rs @@ -6,7 +6,8 @@ use std::sync::OnceLock; pub use issuance::IssuanceBandwidthCredential; pub use issued::IssuedBandwidthCredential; pub use nym_credentials_interface::{ - CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, UnknownCredentialType + CredentialSigningData, CredentialSpendingData, CredentialType, Parameters, + UnknownCredentialType, }; pub mod freepass; diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index bf0b7ac60a..45ebe7758e 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -27,7 +27,7 @@ pub trait Client { async fn address(&self) -> AccountId; async fn dkg_contract_address(&self) -> Result; - + async fn bandwidth_contract_admin(&self) -> Result>; async fn get_tx(&self, tx_hash: Hash) -> Result; From c2517ac63bef0730d2333fffb75a9e5fd2645f0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 17:29:44 +0000 Subject: [PATCH 073/394] clippy --- nym-api/src/coconut/api_routes/mod.rs | 8 -------- nym-api/src/coconut/helpers.rs | 2 +- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 45fef58525..4a5bfe8f2a 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -350,11 +350,3 @@ pub async fn issued_credentials( build_credentials_response(credentials).map(Json) } - -#[cfg(test)] -mod tests { - use super::*; - - #[tokio::test] - async fn foo() {} -} diff --git a/nym-api/src/coconut/helpers.rs b/nym-api/src/coconut/helpers.rs index 15b9a15477..699c9b8823 100644 --- a/nym-api/src/coconut/helpers.rs +++ b/nym-api/src/coconut/helpers.rs @@ -58,7 +58,7 @@ pub(crate) fn blind_sign( Ok(nym_coconut::blind_sign( bandwidth_credential_params(), signing_key, - &request.blind_sign_request(), + request.blind_sign_request(), &attributes_ref, )?) } From 3f0194a9aa6697ae52a0de99238c64928fbe8d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 16:26:19 +0000 Subject: [PATCH 074/394] nym-cli commands for issuing free passes --- Cargo.lock | 4 + .../bandwidth-controller/src/acquire/mod.rs | 2 +- common/bandwidth-controller/src/lib.rs | 2 +- .../validator-client/src/client.rs | 15 +- .../validator-client/src/nym_api/mod.rs | 32 +++ .../validator-client/src/nym_api/routes.rs | 1 + .../validator-client/src/nyxd/mod.rs | 4 + common/commands/Cargo.toml | 4 + .../commands/src/coconut/generate_freepass.rs | 188 ++++++++++++++++++ common/commands/src/coconut/mod.rs | 2 + .../src/coconut/bandwidth/freepass.rs | 57 +++++- .../src/coconut/bandwidth/issuance.rs | 77 +++++-- .../src/coconut/bandwidth/issued.rs | 6 + common/credentials/src/coconut/utils.rs | 6 +- common/credentials/src/error.rs | 9 + common/nymcoconut/src/scheme/mod.rs | 9 + gateway/gateway-requests/src/models.rs | 2 +- .../websocket/connection_handler/coconut.rs | 4 +- nym-api/nym-api-requests/src/coconut/mod.rs | 2 +- .../nym-api-requests/src/coconut/models.rs | 21 ++ nym-api/src/coconut/api_routes/mod.rs | 16 +- nym-api/src/coconut/comm.rs | 2 +- nym-api/src/coconut/mod.rs | 1 + tools/nym-cli/src/coconut/mod.rs | 7 + 24 files changed, 439 insertions(+), 34 deletions(-) create mode 100644 common/commands/src/coconut/generate_freepass.rs diff --git a/Cargo.lock b/Cargo.lock index a91515295e..5c93874c55 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5107,6 +5107,7 @@ dependencies = [ "cosmwasm-std", "csv", "cw-utils", + "futures", "handlebars", "humantime-serde", "inquire", @@ -5122,6 +5123,7 @@ dependencies = [ "nym-credential-storage", "nym-credential-utils", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-multisig-contract-common", @@ -5139,8 +5141,10 @@ dependencies = [ "tap", "thiserror", "time", + "tokio", "toml 0.5.11", "url", + "zeroize", ] [[package]] diff --git a/common/bandwidth-controller/src/acquire/mod.rs b/common/bandwidth-controller/src/acquire/mod.rs index b61bfc2ad4..4f2431b45b 100644 --- a/common/bandwidth-controller/src/acquire/mod.rs +++ b/common/bandwidth-controller/src/acquire/mod.rs @@ -67,7 +67,7 @@ where let signature = obtain_aggregate_signature(&state.voucher, &coconut_api_clients, threshold).await?; - let issued = state.voucher.to_issued_credential(signature); + let issued = state.voucher.to_issued_credential(signature, epoch_id); // make sure the data gets zeroized after persisting it let credential_data = Zeroizing::new(issued.pack_v1()); diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 3fa91802ee..fbfcf41865 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -51,7 +51,7 @@ impl BandwidthController { ::StorageError: Send + Sync + 'static, { let coconut_api_clients = all_coconut_api_clients(&self.client, epoch_id).await?; - Ok(obtain_aggregate_verification_key(&coconut_api_clients).await?) + Ok(obtain_aggregate_verification_key(&coconut_api_clients)?) } pub async fn prepare_bandwidth_credential( diff --git a/common/client-libs/validator-client/src/client.rs b/common/client-libs/validator-client/src/client.rs index f28e45bd37..968a9ddbd3 100644 --- a/common/client-libs/validator-client/src/client.rs +++ b/common/client-libs/validator-client/src/client.rs @@ -8,8 +8,10 @@ use crate::{ nym_api, DirectSigningReqwestRpcValidatorClient, QueryReqwestRpcValidatorClient, ReqwestRpcClient, ValidatorClientError, }; +use nym_api_requests::coconut::models::FreePassNonceResponse; use nym_api_requests::coconut::{ - BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, + BlindSignRequestBody, BlindedSignatureResponse, FreePassRequest, VerifyCredentialBody, + VerifyCredentialResponse, }; use nym_api_requests::models::{DescribedGateway, MixNodeBondAnnotated}; use nym_api_requests::models::{ @@ -348,4 +350,15 @@ impl NymApiClient { .verify_bandwidth_credential(request_body) .await?) } + + pub async fn free_pass_nonce(&self) -> Result { + Ok(self.nym_api.free_pass_nonce().await?) + } + + pub async fn issue_free_pass_credential( + &self, + request: &FreePassRequest, + ) -> Result { + Ok(self.nym_api.free_pass(request).await?) + } } diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index ced2e4caff..a2ad37e5d8 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -32,6 +32,8 @@ pub mod error; pub mod routes; pub use http_api_client::Client; +use nym_api_requests::coconut::models::FreePassNonceResponse; +use nym_api_requests::coconut::FreePassRequest; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -373,6 +375,36 @@ pub trait NymApiClientExt: ApiClient { .await } + async fn free_pass_nonce(&self) -> Result { + self.get_json( + &[ + routes::API_VERSION, + routes::COCONUT_ROUTES, + routes::BANDWIDTH, + routes::COCONUT_FREE_PASS_NONCE, + ], + NO_PARAMS, + ) + .await + } + + async fn free_pass( + &self, + request: &FreePassRequest, + ) -> Result { + self.post_json( + &[ + routes::API_VERSION, + routes::COCONUT_ROUTES, + routes::BANDWIDTH, + routes::COCONUT_FREE_PASS_NONCE, + ], + NO_PARAMS, + request, + ) + .await + } + async fn blind_sign( &self, request_body: &BlindSignRequestBody, diff --git a/common/client-libs/validator-client/src/nym_api/routes.rs b/common/client-libs/validator-client/src/nym_api/routes.rs index bb3125f001..212ae0a8c0 100644 --- a/common/client-libs/validator-client/src/nym_api/routes.rs +++ b/common/client-libs/validator-client/src/nym_api/routes.rs @@ -16,6 +16,7 @@ pub const COCONUT_ROUTES: &str = "coconut"; pub const BANDWIDTH: &str = "bandwidth"; pub const COCONUT_FREE_PASS: &str = "free-pass"; +pub const COCONUT_FREE_PASS_NONCE: &str = "free-pass-nonce"; pub const COCONUT_BLIND_SIGN: &str = "blind-sign"; pub const COCONUT_VERIFY_BANDWIDTH_CREDENTIAL: &str = "verify-bandwidth-credential"; pub const COCONUT_EPOCH_CREDENTIALS: &str = "epoch-credentials"; diff --git a/common/client-libs/validator-client/src/nyxd/mod.rs b/common/client-libs/validator-client/src/nyxd/mod.rs index 2757f66967..416bf7bb2f 100644 --- a/common/client-libs/validator-client/src/nyxd/mod.rs +++ b/common/client-libs/validator-client/src/nyxd/mod.rs @@ -358,6 +358,10 @@ where S: OfflineSigner + Send + Sync, NyxdError: From<::Error>, { + pub fn signing_account(&self) -> Result { + Ok(self.find_account(&self.address())?) + } + pub fn address(&self) -> AccountId { match self.client.signer_addresses() { Ok(addresses) => addresses[0].clone(), diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index a8e665acb4..3a552ecc77 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -15,6 +15,7 @@ cfg-if = "1.0.0" clap = { workspace = true, features = ["derive"] } csv = "1.3.0" cw-utils = { workspace = true } +futures = { workspace = true } handlebars = "3.0.1" humantime-serde = "1.0" inquire = "0.6.2" @@ -25,9 +26,11 @@ serde = { version = "1.0", features = ["derive"] } serde_json = { workspace = true } thiserror = { workspace = true } time = { workspace = true, features = ["parsing", "formatting"] } +tokio = { workspace = true, features = ["sync"]} toml = "0.5.6" url = { workspace = true } tap = "1" +zeroize = { workspace = true } cosmrs = { workspace = true } cosmwasm-std = { workspace = true } @@ -49,6 +52,7 @@ nym-sphinx = { path = "../../common/nymsphinx" } nym-client-core = { path = "../../common/client-core" } nym-config = { path = "../../common/config" } nym-credentials = { path = "../../common/credentials" } +nym-credentials-interface = { path = "../../common/credentials-interface" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credential-utils = { path = "../../common/credential-utils" } diff --git a/common/commands/src/coconut/generate_freepass.rs b/common/commands/src/coconut/generate_freepass.rs new file mode 100644 index 0000000000..7bcd42e858 --- /dev/null +++ b/common/commands/src/coconut/generate_freepass.rs @@ -0,0 +1,188 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::SigningClient; +use anyhow::{anyhow, bail}; +use clap::ArgGroup; +use clap::Parser; +use futures::StreamExt; +use log::{error, info}; +use nym_coconut_dkg_common::types::EpochId; +use nym_credential_utils::utils::block_until_coconut_is_available; +use nym_credentials::coconut::bandwidth::freepass::MAX_FREE_PASS_VALIDITY; +use nym_credentials::{ + obtain_aggregate_verification_key, IssuanceBandwidthCredential, IssuedBandwidthCredential, +}; +use nym_credentials_interface::VerificationKey; +use nym_validator_client::coconut::all_coconut_api_clients; +use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, NymContractsProvider}; +use nym_validator_client::nyxd::CosmWasmClient; +use nym_validator_client::signing::AccountData; +use nym_validator_client::CoconutApiClient; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +use std::sync::Arc; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +fn parse_rfc3339_expiration_date(raw: &str) -> Result { + OffsetDateTime::parse(raw, &Rfc3339) +} + +#[derive(Debug, Parser)] +#[clap(group(ArgGroup::new("expiration").required(true)))] +pub struct Args { + /// Specifies the expiration date of the free pass(es) + /// Requires + #[clap(long, group = "expiration", value_parser = parse_rfc3339_expiration_date)] + pub(crate) expiration_date: Option, + + #[clap(long, group = "expiration")] + pub(crate) expiration_timestamp: Option, + + /// The number of free passes to issue + #[clap(long, default_value = "1")] + pub(crate) amount: u64, + + /// Path to the output directory for generated free passes. + #[clap(long)] + pub(crate) output_dir: PathBuf, +} + +async fn get_freepass( + api_clients: Vec, + aggregate_vk: &VerificationKey, + threshold: u64, + epoch_id: EpochId, + signing_account: &AccountData, + expiration_date: OffsetDateTime, +) -> anyhow::Result { + let issuance_pass = IssuanceBandwidthCredential::new_freepass(Some(expiration_date)); + let signing_data = issuance_pass.prepare_for_signing(); + + let credential_shares = Arc::new(tokio::sync::Mutex::new(Vec::new())); + + futures::stream::iter(api_clients) + .for_each_concurrent(None, |client| async { + // move the client into the block + let client = client; + let api_url = client.api_client.api_url(); + + info!("contacting {api_url} for blinded free pass"); + + match issuance_pass + .obtain_partial_freepass_credential( + &client.api_client, + &signing_account, + &client.verification_key, + signing_data.clone(), + ) + .await + { + Ok(partial_credential) => { + credential_shares + .lock() + .await + .push((partial_credential, client.node_id).into()); + } + Err(err) => { + error!("failed to obtain partial free pass from {api_url}: {err}") + } + } + }) + .await; + + // SAFETY: the futures have completed, so we MUST have the only arc reference + #[allow(clippy::unwrap_used)] + let credential_shares = Arc::into_inner(credential_shares).unwrap().into_inner(); + + if credential_shares.len() < threshold as usize { + bail!("we managed to obtain only {} partial credentials while the minimum threshold is {threshold}", credential_shares.len()); + } + + let signature = issuance_pass.aggregate_signature_shares(aggregate_vk, &credential_shares)?; + Ok(issuance_pass.into_issued_credential(signature, epoch_id)) +} + +pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { + let address = client.address(); + + if !args.output_dir.is_dir() { + bail!("the provided output directory is not a directory!"); + } + + if args.output_dir.read_dir()?.next().is_some() { + bail!("the provided output directory is not empty!"); + } + + let Some(bandwidth_contract) = client.coconut_bandwidth_contract_address() else { + bail!("the bandwidth contract address is not set") + }; + + let Some(bandwidth_admin) = client + .get_contract(bandwidth_contract) + .await + .map(|c| c.contract_info.admin)? + else { + bail!("the bandwidth contract doesn't have any admin set") + }; + + // sanity checks since nym-apis will reject invalid requests anyway + if address != bandwidth_admin { + bail!("the provided mnemonic does not correspond to the current admin of the bandwidth contract") + } + + let expiration_date = match args.expiration_date { + Some(date) => date, + // SAFETY: one of those arguments must have been set + None => OffsetDateTime::from_unix_timestamp(args.expiration_timestamp.unwrap())?, + }; + + let now = OffsetDateTime::now_utc(); + + if expiration_date > now + MAX_FREE_PASS_VALIDITY { + bail!("the provided free pass request has too long expiry (expiry is set to on {expiration_date})") + } + + // issuance start + block_until_coconut_is_available(&client).await?; + + let signing_account = client.signing_account()?; + + let epoch_id = client.get_current_epoch().await?.epoch_id; + let threshold = client + .get_current_epoch_threshold() + .await? + .ok_or(anyhow!("no threshold available"))?; + let api_clients = all_coconut_api_clients(&client, epoch_id).await?; + + if api_clients.len() < threshold as usize { + bail!( + "we have only {} api clients available while the minimum threshold is {threshold}", + api_clients.len() + ) + } + let aggregate_vk = obtain_aggregate_verification_key(&api_clients)?; + + for i in 0..args.amount { + let human_index = i + 1; + info!("trying to obtain free pass {human_index}/{}", args.amount); + let free_pass = get_freepass( + api_clients.clone(), + &aggregate_vk, + threshold, + epoch_id, + &signing_account, + expiration_date, + ) + .await?; + let credential_data = Zeroizing::new(free_pass.pack_v1()); + let output = args.output_dir.join(format!("freepass_{i}.nym")); + info!("saving the freepass to '{}'", output.display()); + File::create(output)?.write_all(&credential_data)?; + } + + Ok(()) +} diff --git a/common/commands/src/coconut/mod.rs b/common/commands/src/coconut/mod.rs index 531a316125..c6499deed4 100644 --- a/common/commands/src/coconut/mod.rs +++ b/common/commands/src/coconut/mod.rs @@ -3,6 +3,7 @@ use clap::{Args, Subcommand}; +pub mod generate_freepass; pub mod issue_credentials; pub mod recover_credentials; @@ -15,6 +16,7 @@ pub struct Coconut { #[derive(Debug, Subcommand)] pub enum CoconutCommands { + GenerateFreepass(generate_freepass::Args), IssueCredentials(issue_credentials::Args), RecoverCredentials(recover_credentials::Args), } diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 0a1707ba3b..ed2b57000c 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -2,7 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use crate::coconut::utils::scalar_serde_helper; -use nym_credentials_interface::{hash_to_scalar, Attribute, PublicAttribute}; +use crate::error::Error; +use nym_api_requests::coconut::FreePassRequest; +use nym_credentials_interface::{ + hash_to_scalar, Attribute, BlindedSignature, CredentialSigningData, PublicAttribute, +}; +use nym_validator_client::signing::AccountData; use serde::{Deserialize, Serialize}; use time::{Duration, OffsetDateTime, Time}; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -76,4 +81,54 @@ impl FreePassIssuanceData { pub fn expiry_date_plain(&self) -> String { self.expiry_date.unix_timestamp().to_string() } + + pub async fn obtain_free_pass_nonce( + &self, + client: &nym_validator_client::client::NymApiClient, + ) -> Result { + let server_response = client.free_pass_nonce().await?; + Ok(server_response.current_nonce) + } + + pub fn create_free_pass_request( + &self, + signing_request: &CredentialSigningData, + account_data: &AccountData, + issuer_nonce: u32, + ) -> Result { + let plaintext = issuer_nonce.to_be_bytes(); + let nonce_signature = account_data + .private_key() + .sign(&plaintext) + .map_err(|_| Error::Secp256k1SignFailure)?; + + Ok(FreePassRequest { + cosmos_pubkey: account_data.public_key(), + inner_sign_request: signing_request.blind_sign_request.clone(), + used_nonce: issuer_nonce, + nonce_signature, + public_attributes_plain: signing_request.public_attributes_plain.clone(), + }) + } + + pub async fn obtain_blinded_credential( + &self, + client: &nym_validator_client::client::NymApiClient, + request: &FreePassRequest, + ) -> Result { + let server_response = client.issue_free_pass_credential(request).await?; + Ok(server_response.blinded_signature) + } + + pub async fn request_blinded_credential( + &self, + signing_request: &CredentialSigningData, + account_data: &AccountData, + client: &nym_validator_client::client::NymApiClient, + ) -> Result { + let signing_nonce = self.obtain_free_pass_nonce(client).await?; + let request = + self.create_free_pass_request(signing_request, account_data, signing_nonce)?; + self.obtain_blinded_credential(client, &request).await + } } diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index bf166313a6..5441a899fc 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -11,11 +11,13 @@ use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; use bls12_381::G1Projective; use nym_credentials_interface::{ - aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, Parameters, - PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, + aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, BlindedSignature, + Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, }; use nym_crypto::asymmetric::{encryption, identity}; +use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::{Coin, Hash}; +use nym_validator_client::signing::AccountData; use serde::{Deserialize, Serialize}; use time::OffsetDateTime; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -196,26 +198,12 @@ impl IssuanceBandwidthCredential { } } - pub async fn obtain_partial_credential( + pub fn unblind_signature( &self, - client: &nym_validator_client::client::NymApiClient, validator_vk: &VerificationKey, - signing_data: impl Into>, + signing_data: &CredentialSigningData, + blinded_signature: BlindedSignature, ) -> Result { - // if we provided signing data, do use them, otherwise generate fresh data - let signing_data = signing_data - .into() - .unwrap_or_else(|| self.prepare_for_signing()); - - let blinded_signature = match &self.variant_data { - BandwidthCredentialIssuanceDataVariant::FreePass(_freepass) => unimplemented!(), - BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => { - // TODO: the request can be re-used between different apis - let request = voucher.create_blind_sign_request_body(&signing_data); - voucher.obtain_blinded_credential(client, &request).await? - } - }; - let public_attributes = self.get_public_attributes(); let private_attributes = self.get_private_attributes(); @@ -232,6 +220,52 @@ impl IssuanceBandwidthCredential { Ok(unblinded_signature) } + pub async fn obtain_partial_freepass_credential( + &self, + client: &nym_validator_client::client::NymApiClient, + account_data: &AccountData, + validator_vk: &VerificationKey, + signing_data: impl Into>, + ) -> Result { + // if we provided signing data, do use them, otherwise generate fresh data + let signing_data = signing_data + .into() + .unwrap_or_else(|| self.prepare_for_signing()); + + let blinded_signature = match &self.variant_data { + BandwidthCredentialIssuanceDataVariant::FreePass(freepass) => { + freepass + .request_blinded_credential(&signing_data, account_data, client) + .await? + } + _ => return Err(Error::NotAFreePass), + }; + self.unblind_signature(validator_vk, &signing_data, blinded_signature) + } + + // ideally this would have been generic over credential type, but we really don't need secp256k1 keys for bandwidth vouchers + pub async fn obtain_partial_bandwidth_voucher_credential( + &self, + client: &nym_validator_client::client::NymApiClient, + validator_vk: &VerificationKey, + signing_data: impl Into>, + ) -> Result { + // if we provided signing data, do use them, otherwise generate fresh data + let signing_data = signing_data + .into() + .unwrap_or_else(|| self.prepare_for_signing()); + + let blinded_signature = match &self.variant_data { + BandwidthCredentialIssuanceDataVariant::Voucher(voucher) => { + // TODO: the request can be re-used between different apis + let request = voucher.create_blind_sign_request_body(&signing_data); + voucher.obtain_blinded_credential(client, &request).await? + } + _ => return Err(Error::NotABandwdithVoucher), + }; + self.unblind_signature(validator_vk, &signing_data, blinded_signature) + } + pub fn aggregate_signature_shares( &self, verification_key: &VerificationKey, @@ -254,13 +288,15 @@ impl IssuanceBandwidthCredential { pub fn into_issued_credential( self, aggregate_signature: Signature, + epoch_id: EpochId, ) -> IssuedBandwidthCredential { - self.to_issued_credential(aggregate_signature) + self.to_issued_credential(aggregate_signature, epoch_id) } pub fn to_issued_credential( &self, aggregate_signature: Signature, + epoch_id: EpochId, ) -> IssuedBandwidthCredential { IssuedBandwidthCredential::new( self.serial_number, @@ -268,6 +304,7 @@ impl IssuanceBandwidthCredential { aggregate_signature, (&self.variant_data).into(), self.type_prehashed, + epoch_id, ) } diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 62d5a4ecc7..753f5434d2 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -16,6 +16,7 @@ use nym_credentials_interface::{ }; use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; +use nym_validator_client::nym_api::EpochId; pub const CURRENT_SERIALIZATION_REVISION: u8 = 1; @@ -91,6 +92,9 @@ pub struct IssuedBandwidthCredential { /// type of the bandwdith credential hashed onto a scalar #[serde(with = "scalar_serde_helper")] type_prehashed: PublicAttribute, + + /// Specifies the (DKG) epoch id when this credential has been issued + epoch_id: EpochId } impl IssuedBandwidthCredential { @@ -100,6 +104,7 @@ impl IssuedBandwidthCredential { signature: Signature, variant_data: BandwidthCredentialIssuedDataVariant, type_prehashed: PublicAttribute, + epoch_id: EpochId ) -> Self { IssuedBandwidthCredential { serial_number, @@ -107,6 +112,7 @@ impl IssuedBandwidthCredential { signature, variant_data, type_prehashed, + epoch_id, } } diff --git a/common/credentials/src/coconut/utils.rs b/common/credentials/src/coconut/utils.rs index cf0025826c..3192804530 100644 --- a/common/credentials/src/coconut/utils.rs +++ b/common/credentials/src/coconut/utils.rs @@ -9,7 +9,7 @@ use nym_credentials_interface::{ }; use nym_validator_client::client::CoconutApiClient; -pub async fn obtain_aggregate_verification_key( +pub fn obtain_aggregate_verification_key( api_clients: &[CoconutApiClient], ) -> Result { if api_clients.is_empty() { @@ -37,7 +37,7 @@ pub async fn obtain_aggregate_signature( return Err(Error::NoValidatorsAvailable); } let mut shares = Vec::with_capacity(coconut_api_clients.len()); - let verification_key = obtain_aggregate_verification_key(coconut_api_clients).await?; + let verification_key = obtain_aggregate_verification_key(coconut_api_clients)?; let request = voucher.prepare_for_signing(); @@ -48,7 +48,7 @@ pub async fn obtain_aggregate_signature( ); match voucher - .obtain_partial_credential( + .obtain_partial_bandwidth_voucher_credential( &coconut_api_client.api_client, &coconut_api_client.verification_key, Some(request.clone()), diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index 76c4aa068c..620196b627 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -44,4 +44,13 @@ pub enum Error { #[error("Could not deserialize bandwidth voucher - {0}")] BandwidthVoucherDeserializationError(String), + + #[error("the provided issuance data wasn't prepared for a bandwidth voucher")] + NotABandwdithVoucher, + + #[error("the provided issuance data wasn't prepared for a free pass")] + NotAFreePass, + + #[error("failed to create a secp256k1 signature")] + Secp256k1SignFailure } diff --git a/common/nymcoconut/src/scheme/mod.rs b/common/nymcoconut/src/scheme/mod.rs index 68dd0d2b9a..58c1ca0f5e 100644 --- a/common/nymcoconut/src/scheme/mod.rs +++ b/common/nymcoconut/src/scheme/mod.rs @@ -248,6 +248,15 @@ pub struct SignatureShare { index: SignerIndex, } +impl From<(Signature, SignerIndex)> for SignatureShare { + fn from(value: (Signature, SignerIndex)) -> Self { + SignatureShare { + signature: value.0, + index: value.1, + } + } +} + impl SignatureShare { pub fn new(signature: Signature, index: SignerIndex) -> Self { SignatureShare { signature, index } diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index c16bf023cf..93407363bd 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -327,7 +327,7 @@ mod tests { ) .unwrap(); - let issued = issuance.into_issued_credential(sig); + let issued = issuance.into_issued_credential(sig, 42); let spending = issued .prepare_for_spending(keypair.verification_key()) .unwrap(); diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index 7515157b55..db4ec9ee6c 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -89,7 +89,7 @@ impl CoconutVerifier { }); } let aggregated_verification_key = - nym_credentials::obtain_aggregate_verification_key(&epoch_api_clients).await?; + nym_credentials::obtain_aggregate_verification_key(&epoch_api_clients)?; api_clients.insert(current_epoch.epoch_id, epoch_api_clients); master_keys.insert(current_epoch.epoch_id, aggregated_verification_key); @@ -155,7 +155,7 @@ impl CoconutVerifier { let api_clients = self.api_clients(epoch_id).await?; let aggregated_verification_key = - nym_credentials::obtain_aggregate_verification_key(&api_clients).await?; + nym_credentials::obtain_aggregate_verification_key(&api_clients)?; let mut guard = self.master_keys.write().await; guard.insert(epoch_id, aggregated_verification_key); diff --git a/nym-api/nym-api-requests/src/coconut/mod.rs b/nym-api/nym-api-requests/src/coconut/mod.rs index fb5740928c..1971f0b8f8 100644 --- a/nym-api/nym-api-requests/src/coconut/mod.rs +++ b/nym-api/nym-api-requests/src/coconut/mod.rs @@ -5,6 +5,6 @@ pub mod helpers; pub mod models; pub use models::{ - BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, + BlindSignRequestBody, BlindedSignatureResponse, CredentialsRequestBody, FreePassRequest, VerificationKeyResponse, VerifyCredentialBody, VerifyCredentialResponse, }; diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index 0a3c3c0138..aae0bc9ea0 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -110,6 +110,11 @@ impl BlindSignRequestBody { } } +#[derive(Debug, Serialize, Deserialize)] +pub struct FreePassNonceResponse { + pub current_nonce: u32, +} + #[derive(Debug, Serialize, Deserialize)] pub struct BlindedSignatureResponse { pub blinded_signature: BlindedSignature, @@ -159,6 +164,22 @@ pub struct FreePassRequest { } impl FreePassRequest { + pub fn new( + cosmos_pubkey: cosmrs::crypto::PublicKey, + inner_sign_request: BlindSignRequest, + used_nonce: u32, + nonce_signature: cosmrs::crypto::secp256k1::Signature, + public_attributes_plain: Vec, + ) -> Self { + FreePassRequest { + cosmos_pubkey, + inner_sign_request, + used_nonce, + nonce_signature, + public_attributes_plain, + } + } + pub fn tendermint_pubkey(&self) -> tendermint::PublicKey { self.cosmos_pubkey.into() } diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 4a5bfe8f2a..df8300746e 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -8,8 +8,8 @@ use crate::coconut::state::State; use crate::coconut::storage::CoconutStorageExt; use k256::ecdsa::signature::Verifier; use nym_api_requests::coconut::models::{ - CredentialsRequestBody, EpochCredentialsResponse, FreePassRequest, IssuedCredentialResponse, - IssuedCredentialsResponse, + CredentialsRequestBody, EpochCredentialsResponse, FreePassNonceResponse, FreePassRequest, + IssuedCredentialResponse, IssuedCredentialsResponse, }; use nym_api_requests::coconut::{ BlindSignRequestBody, BlindedSignatureResponse, VerifyCredentialBody, VerifyCredentialResponse, @@ -68,6 +68,18 @@ fn validate_freepass_public_attributes(res: &FreePassRequest) -> Result<()> { Ok(()) } +#[get("/free-pass-nonce")] +pub async fn get_current_free_pass_nonce( + state: &RocketState, +) -> Result> { + debug!("Received free pass nonce request"); + + let current_nonce = state.storage.get_current_freepass_nonce().await?; + debug!("the current expected nonce is {current_nonce}"); + + Ok(Json(FreePassNonceResponse { current_nonce })) +} + #[post("/free-pass", data = "")] pub async fn post_free_pass( freepass_request_body: Json, diff --git a/nym-api/src/coconut/comm.rs b/nym-api/src/coconut/comm.rs index 2019d99650..48e7823fce 100644 --- a/nym-api/src/coconut/comm.rs +++ b/nym-api/src/coconut/comm.rs @@ -110,7 +110,7 @@ impl APICommunicationChannel for QueryCommunicationChannel { ClientInner::Signing(client) => all_coconut_api_clients(client, epoch_id).await?, }; - let vk = obtain_aggregate_verification_key(&coconut_api_clients).await?; + let vk = obtain_aggregate_verification_key(&coconut_api_clients)?; guard.insert(epoch_id, vk.clone()); diff --git a/nym-api/src/coconut/mod.rs b/nym-api/src/coconut/mod.rs index 82ca3c59b2..5047982304 100644 --- a/nym-api/src/coconut/mod.rs +++ b/nym-api/src/coconut/mod.rs @@ -52,6 +52,7 @@ where // this format! is so ugly... format!("/{NYM_API_VERSION}/{COCONUT_ROUTES}/{BANDWIDTH}"), routes![ + api_routes::get_current_free_pass_nonce, api_routes::post_free_pass, api_routes::post_blind_sign, api_routes::verify_bandwidth_credential, diff --git a/tools/nym-cli/src/coconut/mod.rs b/tools/nym-cli/src/coconut/mod.rs index ea4fd45381..4df05bb5fd 100644 --- a/tools/nym-cli/src/coconut/mod.rs +++ b/tools/nym-cli/src/coconut/mod.rs @@ -7,6 +7,13 @@ pub(crate) async fn execute( network_details: &NymNetworkDetails, ) -> anyhow::Result<()> { match coconut.command { + nym_cli_commands::coconut::CoconutCommands::GenerateFreepass(args) => { + nym_cli_commands::coconut::generate_freepass::execute( + args, + create_signing_client(global_args, network_details)?, + ) + .await? + } nym_cli_commands::coconut::CoconutCommands::IssueCredentials(args) => { nym_cli_commands::coconut::issue_credentials::execute( args, From edbcade5f5c23ccd61f35c73d53aa3275ec31bea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 16:39:03 +0000 Subject: [PATCH 075/394] clippy --- common/commands/src/coconut/generate_freepass.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/commands/src/coconut/generate_freepass.rs b/common/commands/src/coconut/generate_freepass.rs index 7bcd42e858..98325ea710 100644 --- a/common/commands/src/coconut/generate_freepass.rs +++ b/common/commands/src/coconut/generate_freepass.rs @@ -75,7 +75,7 @@ async fn get_freepass( match issuance_pass .obtain_partial_freepass_credential( &client.api_client, - &signing_account, + signing_account, &client.verification_key, signing_data.clone(), ) From fa93c4598fb142da58af7a4ac415610cd434f070 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 16:56:55 +0000 Subject: [PATCH 076/394] removing redundant epoch_id field --- .../client-libs/gateway-client/src/client.rs | 5 +-- common/credentials-interface/src/lib.rs | 3 ++ .../src/coconut/bandwidth/issued.rs | 9 +++--- gateway/gateway-requests/src/models.rs | 31 +++++++------------ gateway/gateway-requests/src/types.rs | 9 +++--- .../connection_handler/authenticated.rs | 8 ++--- .../websocket/connection_handler/coconut.rs | 5 ++- .../nym-api-requests/src/coconut/models.rs | 7 ----- nym-api/src/coconut/api_routes/mod.rs | 2 +- 9 files changed, 32 insertions(+), 47 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 87e9fa758a..2a9750e7a1 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -25,7 +25,6 @@ use nym_gateway_requests::{ use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; -use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use rand::rngs::OsRng; use std::convert::TryFrom; @@ -527,14 +526,12 @@ impl GatewayClient { async fn claim_coconut_bandwidth( &mut self, credential: CredentialSpendingData, - epoch_id: EpochId, ) -> Result<(), GatewayClientError> { let mut rng = OsRng; let iv = IV::new_random(&mut rng); let msg = ClientControlRequest::new_enc_coconut_bandwidth_credential_v2( credential, - epoch_id, self.shared_key.as_ref().unwrap(), iv, ) @@ -587,7 +584,7 @@ impl GatewayClient { .prepare_bandwidth_credential() .await?; - self.claim_coconut_bandwidth(prepared_credential.data, prepared_credential.epoch_id) + self.claim_coconut_bandwidth(prepared_credential.data) .await?; self.bandwidth_controller .as_ref() diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index f2be1ef70f..7acc98499c 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -92,6 +92,9 @@ pub struct CredentialSpendingData { pub public_attributes_plain: Vec, pub typ: CredentialType, + + /// The (DKG) epoch id under which the credential has been issued so that the verifier could use correct verification key for validation. + pub epoch_id: u64, } impl CredentialSpendingData { diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 753f5434d2..8354408533 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -14,9 +14,9 @@ use nym_credentials_interface::prove_bandwidth_credential; use nym_credentials_interface::{ Parameters, PrivateAttribute, PublicAttribute, Signature, VerificationKey, }; +use nym_validator_client::nym_api::EpochId; use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; -use nym_validator_client::nym_api::EpochId; pub const CURRENT_SERIALIZATION_REVISION: u8 = 1; @@ -92,9 +92,9 @@ pub struct IssuedBandwidthCredential { /// type of the bandwdith credential hashed onto a scalar #[serde(with = "scalar_serde_helper")] type_prehashed: PublicAttribute, - + /// Specifies the (DKG) epoch id when this credential has been issued - epoch_id: EpochId + epoch_id: EpochId, } impl IssuedBandwidthCredential { @@ -104,7 +104,7 @@ impl IssuedBandwidthCredential { signature: Signature, variant_data: BandwidthCredentialIssuedDataVariant, type_prehashed: PublicAttribute, - epoch_id: EpochId + epoch_id: EpochId, ) -> Self { IssuedBandwidthCredential { serial_number, @@ -172,6 +172,7 @@ impl IssuedBandwidthCredential { verify_credential_request, public_attributes_plain: self.get_plain_public_attributes(), typ: self.typ(), + epoch_id: self.epoch_id, }) } } diff --git a/gateway/gateway-requests/src/models.rs b/gateway/gateway-requests/src/models.rs index 93407363bd..a250612508 100644 --- a/gateway/gateway-requests/src/models.rs +++ b/gateway/gateway-requests/src/models.rs @@ -22,7 +22,7 @@ pub struct OldV1Credential { } // attempt to convert the old request type into the new variant -impl TryFrom for CredentialSpendingWithEpoch { +impl TryFrom for CredentialSpendingRequest { type Error = GatewayRequestsError; fn try_from(value: OldV1Credential) -> Result { @@ -35,14 +35,14 @@ impl TryFrom for CredentialSpendingWithEpoch { let typ = value.voucher_info.parse()?; let public_attributes_plain = vec![value.voucher_value.to_string(), value.voucher_info]; - Ok(CredentialSpendingWithEpoch { + Ok(CredentialSpendingRequest { data: CredentialSpendingData { embedded_private_attributes, verify_credential_request: value.theta, public_attributes_plain, typ, + epoch_id: value.epoch_id, }, - epoch_id: value.epoch_id, }) } } @@ -106,13 +106,9 @@ impl OldV1Credential { } #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)] -pub struct CredentialSpendingWithEpoch { +pub struct CredentialSpendingRequest { /// The cryptographic material required for spending the underlying credential. pub data: CredentialSpendingData, - - /// The (DKG) epoch id under which the credential has been issued so that the verifier - /// could use correct verification key for validation. - pub epoch_id: u64, } // just a helper macro for checking required length and advancing the buffer @@ -132,9 +128,9 @@ macro_rules! ensure_len_and_advance { }}; } -impl CredentialSpendingWithEpoch { - pub fn new(data: CredentialSpendingData, epoch_id: u64) -> Self { - CredentialSpendingWithEpoch { data, epoch_id } +impl CredentialSpendingRequest { + pub fn new(data: CredentialSpendingData) -> Self { + CredentialSpendingRequest { data } } pub fn matches_blinded_serial_number( @@ -183,7 +179,7 @@ impl CredentialSpendingWithEpoch { bytes.extend_from_slice(&typ_len); bytes.extend_from_slice(typ_bytes); - bytes.extend_from_slice(&self.epoch_id.to_be_bytes()); + bytes.extend_from_slice(&self.data.epoch_id.to_be_bytes()); bytes } @@ -227,14 +223,14 @@ impl CredentialSpendingWithEpoch { let epoch_id_bytes = ensure_len_and_advance!(b, 8); let epoch_id = u64::from_be_bytes(epoch_id_bytes.try_into().unwrap()); - Ok(CredentialSpendingWithEpoch { + Ok(CredentialSpendingRequest { data: CredentialSpendingData { embedded_private_attributes, verify_credential_request: theta, public_attributes_plain, typ, + epoch_id, }, - epoch_id, }) } } @@ -332,13 +328,10 @@ mod tests { .prepare_for_spending(keypair.verification_key()) .unwrap(); - let with_epoch = CredentialSpendingWithEpoch { - data: spending, - epoch_id: 42, - }; + let with_epoch = CredentialSpendingRequest { data: spending }; let bytes = with_epoch.to_bytes(); - let recovered = CredentialSpendingWithEpoch::try_from_bytes(&bytes).unwrap(); + let recovered = CredentialSpendingRequest::try_from_bytes(&bytes).unwrap(); assert_eq!(with_epoch, recovered); } diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 0165a40c6d..cc85d408c6 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -3,7 +3,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; -use crate::models::{CredentialSpendingWithEpoch, OldV1Credential}; +use crate::models::{CredentialSpendingRequest, OldV1Credential}; use crate::registration::handshake::SharedKeys; use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION}; use log::error; @@ -190,11 +190,10 @@ impl ClientControlRequest { pub fn new_enc_coconut_bandwidth_credential_v2( credential: CredentialSpendingData, - epoch_id: u64, shared_key: &SharedKeys, iv: IV, ) -> Self { - let cred = CredentialSpendingWithEpoch::new(credential, epoch_id); + let cred = CredentialSpendingRequest::new(credential); let serialized_credential = cred.to_bytes(); let enc_credential = shared_key.encrypt_and_tag(&serialized_credential, Some(iv.inner())); @@ -208,9 +207,9 @@ impl ClientControlRequest { enc_credential: Vec, shared_key: &SharedKeys, iv: IV, - ) -> Result { + ) -> Result { let credential_bytes = shared_key.decrypt_tagged(&enc_credential, Some(iv.inner()))?; - CredentialSpendingWithEpoch::try_from_bytes(&credential_bytes) + CredentialSpendingRequest::try_from_bytes(&credential_bytes) .map_err(|_| GatewayRequestsError::MalformedEncryption) } } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 0f4bd0d7d6..de56f78413 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -22,7 +22,7 @@ use futures::{ use log::*; use nym_credentials::coconut::bandwidth::{bandwidth_credential_params, CredentialType}; use nym_credentials_interface::CoconutError; -use nym_gateway_requests::models::CredentialSpendingWithEpoch; +use nym_gateway_requests::models::CredentialSpendingRequest; use nym_gateway_requests::{ iv::{IVConversionError, IV}, types::{BinaryRequest, ServerResponse}, @@ -220,12 +220,12 @@ where async fn handle_bandwidth_request( &mut self, - credential: CredentialSpendingWithEpoch, + credential: CredentialSpendingRequest, ) -> Result { let aggregated_verification_key = self .inner .coconut_verifier - .verification_key(credential.epoch_id) + .verification_key(credential.data.epoch_id) .await?; if !credential.data.validate_type_attribute() { @@ -251,7 +251,7 @@ where let api_clients = self .inner .coconut_verifier - .api_clients(credential.epoch_id) + .api_clients(credential.data.epoch_id) .await?; self.inner diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index db4ec9ee6c..d013f8fda7 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -4,7 +4,7 @@ use super::authenticated::RequestHandlingError; use log::*; use nym_credentials_interface::VerificationKey; -use nym_gateway_requests::models::CredentialSpendingWithEpoch; +use nym_gateway_requests::models::CredentialSpendingRequest; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; use nym_validator_client::nyxd::contract_traits::{MultisigQueryClient, NymContractsProvider}; @@ -180,7 +180,7 @@ impl CoconutVerifier { pub async fn release_bandwidth_voucher_funds( &self, api_clients: &[CoconutApiClient], - credential: CredentialSpendingWithEpoch, + credential: CredentialSpendingRequest, ) -> Result<(), RequestHandlingError> { if !credential.data.typ.is_voucher() { unimplemented!() @@ -230,7 +230,6 @@ impl CoconutVerifier { let req = nym_api_requests::coconut::VerifyCredentialBody::new( credential.data, - credential.epoch_id, proposal_id, self.address.clone(), ); diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index aae0bc9ea0..aaa980cc5a 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -17,10 +17,6 @@ pub struct VerifyCredentialBody { /// The cryptographic material required for spending the underlying credential. pub credential_data: CredentialSpendingData, - /// The (DKG) epoch id under which the credential has been issued so that the verifier - /// could use correct verification key for validation. - pub epoch_id: u64, - /// Multisig proposal for releasing funds for the provided bandwidth credential pub proposal_id: u64, @@ -31,13 +27,11 @@ pub struct VerifyCredentialBody { impl VerifyCredentialBody { pub fn new( credential_data: CredentialSpendingData, - epoch_id: u64, proposal_id: u64, gateway_cosmos_addr: AccountId, ) -> VerifyCredentialBody { VerifyCredentialBody { credential_data, - epoch_id, proposal_id, gateway_cosmos_addr, } @@ -68,7 +62,6 @@ pub struct BlindSignRequestBody { /// Signature on the inner sign request and the tx hash pub signature: identity::Signature, - // public_attributes: Vec, pub public_attributes_plain: Vec, } diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index df8300746e..013f600897 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -239,8 +239,8 @@ pub async fn verify_bandwidth_credential( state: &RocketState, ) -> Result> { let proposal_id = verify_credential_body.proposal_id; - let epoch_id = verify_credential_body.epoch_id; let credential_data = &verify_credential_body.credential_data; + let epoch_id = credential_data.epoch_id; let theta = &credential_data.verify_credential_request; let voucher_value: u64 = if credential_data.typ.is_voucher() { From 5a4dfafe9fe57092a06879dcaa8c4c5110042838 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 12 Feb 2024 17:00:11 +0000 Subject: [PATCH 077/394] cargo fmt --- common/credentials/src/error.rs | 4 ++-- nym-api/src/coconut/tests/mod.rs | 14 +++++--------- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index 620196b627..96d8bf4202 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -50,7 +50,7 @@ pub enum Error { #[error("the provided issuance data wasn't prepared for a free pass")] NotAFreePass, - + #[error("failed to create a secp256k1 signature")] - Secp256k1SignFailure + Secp256k1SignFailure, } diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index fe0ad3b165..9912916a0d 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -1781,6 +1781,7 @@ mod credential_tests { // generate all the credential requests let params = bandwidth_credential_params(); let key_pair = nym_coconut::keygen(params); + let epoch = 1; let voucher_amount = coin(1234, "unym"); let issuance = voucher_fixture(coin(1234, "unym"), None); @@ -1805,7 +1806,7 @@ mod credential_tests { ) .unwrap(); - let issued = issuance.into_issued_credential(sig); + let issued = issuance.into_issued_credential(sig, epoch); let spending = issued .prepare_for_spending(key_pair.verification_key()) .unwrap(); @@ -1818,7 +1819,7 @@ mod credential_tests { staged_key_pair .set(KeyPairWithEpoch { keys: key_pair, - issued_for_epoch: 1, + issued_for_epoch: epoch, }) .await; staged_key_pair.validate(); @@ -1838,16 +1839,11 @@ mod credential_tests { .await .expect("valid rocket instance"); - let epoch_id = 69; let proposal_id = 42; // The address is not used, so we can use a duplicate let gateway_cosmos_addr = validator_address.clone(); - let req = VerifyCredentialBody::new( - spending.clone(), - epoch_id, - proposal_id, - gateway_cosmos_addr.clone(), - ); + let req = + VerifyCredentialBody::new(spending.clone(), proposal_id, gateway_cosmos_addr.clone()); // Test endpoint with not proposal for the proposal id let response = client From 92d9cb7dab484c37cc302c89c41311ed9d68c8b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Fri, 26 Jan 2024 15:13:25 +0000 Subject: [PATCH 078/394] added database code for the serial number storage --- .../credential-utils/src/recovery_storage.rs | 2 +- common/credentials-interface/src/lib.rs | 6 +- .../src/coconut/bandwidth/issuance.rs | 15 ++--- common/nymcoconut/src/lib.rs | 1 + common/nymcoconut/src/scheme/double_use.rs | 49 +++++++++++--- common/nymcoconut/src/scheme/verification.rs | 41 +++++------- .../20240126120000_store_serial_numbers.sql | 11 +++ gateway/src/node/storage/bandwidth.rs | 52 +++++++++++++- gateway/src/node/storage/mod.rs | 67 +++++++++++++++++++ gateway/src/node/storage/models.rs | 14 +++- 10 files changed, 209 insertions(+), 49 deletions(-) create mode 100644 gateway/migrations/20240126120000_store_serial_numbers.sql diff --git a/common/credential-utils/src/recovery_storage.rs b/common/credential-utils/src/recovery_storage.rs index f003b562cd..0344a3ad86 100644 --- a/common/credential-utils/src/recovery_storage.rs +++ b/common/credential-utils/src/recovery_storage.rs @@ -53,7 +53,7 @@ impl RecoveryStorage { pub fn voucher_filename(voucher: &IssuanceBandwidthCredential) -> String { let prefix = voucher.typ().to_string(); - let suffix = voucher.blinded_g1_serial_number_bs58(); + let suffix = voucher.blinded_serial_number_bs58(); format!("{prefix}-{suffix}.{DUMPED_VOUCHER_EXTENSION}") } diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index 7acc98499c..ed3a2ca03c 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -10,9 +10,9 @@ use thiserror::Error; pub use nym_coconut::{ aggregate_signature_shares, aggregate_verification_keys, blind_sign, hash_to_scalar, keygen, prepare_blind_sign, prove_bandwidth_credential, verify_credential, Attribute, Base58, - BlindSignRequest, BlindedSignature, Bytable, CoconutError, KeyPair, Parameters, - PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, VerificationKey, - VerifyCredentialRequest, + BlindSignRequest, BlindedSerialNumber, BlindedSignature, Bytable, CoconutError, KeyPair, + Parameters, PrivateAttribute, PublicAttribute, SecretKey, Signature, SignatureShare, + VerificationKey, VerifyCredentialRequest, }; pub const VOUCHER_INFO_TYPE: &str = "BandwidthVoucher"; diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index 5441a899fc..bc56bda0fd 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -9,10 +9,10 @@ use crate::coconut::bandwidth::{ }; use crate::coconut::utils::scalar_serde_helper; use crate::error::Error; -use bls12_381::G1Projective; use nym_credentials_interface::{ - aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, BlindedSignature, - Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, VerificationKey, + aggregate_signature_shares, hash_to_scalar, prepare_blind_sign, Attribute, BlindedSerialNumber, + BlindedSignature, Parameters, PrivateAttribute, PublicAttribute, Signature, SignatureShare, + VerificationKey, }; use nym_crypto::asymmetric::{encryption, identity}; use nym_validator_client::nym_api::EpochId; @@ -140,15 +140,14 @@ impl IssuanceBandwidthCredential { Self::new(FreePassIssuanceData::new(expiry_date)) } - pub fn blind_serial_number_in_g1subgroup(&self) -> G1Projective { - bandwidth_credential_params().gen1() * self.serial_number + pub fn blind_serial_number(&self) -> BlindedSerialNumber { + (bandwidth_credential_params().gen2() * self.serial_number).into() } - // NOT TO BE CONFUSED WITH BLINDED SERIAL NUMBER IN CREDENTIAL ITSELF - pub fn blinded_g1_serial_number_bs58(&self) -> String { + pub fn blinded_serial_number_bs58(&self) -> String { use nym_credentials_interface::Base58; - self.blind_serial_number_in_g1subgroup().to_bs58() + self.blind_serial_number().to_bs58() } pub fn typ(&self) -> CredentialType { diff --git a/common/nymcoconut/src/lib.rs b/common/nymcoconut/src/lib.rs index 4ac8245c37..e2a3138b3a 100644 --- a/common/nymcoconut/src/lib.rs +++ b/common/nymcoconut/src/lib.rs @@ -24,6 +24,7 @@ pub use scheme::setup::Parameters; pub use scheme::verification::check_vk_pairing; pub use scheme::verification::prove_bandwidth_credential; pub use scheme::verification::verify_credential; +pub use scheme::verification::BlindedSerialNumber; pub use scheme::verification::VerifyCredentialRequest; pub use scheme::BlindedSignature; pub use scheme::Signature; diff --git a/common/nymcoconut/src/scheme/double_use.rs b/common/nymcoconut/src/scheme/double_use.rs index ce3cf58d67..c8f89820b4 100644 --- a/common/nymcoconut/src/scheme/double_use.rs +++ b/common/nymcoconut/src/scheme/double_use.rs @@ -1,17 +1,46 @@ -// Copyright 2022 - Nym Technologies SA +// Copyright 2022-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use bls12_381::G2Projective; -use group::Curve; -use std::convert::TryFrom; -use std::convert::TryInto; - use crate::error::{CoconutError, Result}; use crate::traits::{Base58, Bytable}; use crate::utils::try_deserialize_g2_projective; +use bls12_381::{G2Affine, G2Projective}; +use group::Curve; +use std::convert::TryFrom; +use std::convert::TryInto; +use std::fmt::{Debug, Formatter}; +use std::ops::Deref; -pub struct BlindedSerialNumber { - pub(crate) inner: G2Projective, +#[derive(PartialEq, Eq, Clone, Copy)] +pub struct BlindedSerialNumber(G2Projective); + +// use custom Debug implementation to show base58 encoding (rather than raw curve elements) +impl Debug for BlindedSerialNumber { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + f.debug_tuple("BlindedSerialNumber") + .field(&self.to_bs58()) + .finish() + } +} + +impl From for BlindedSerialNumber { + fn from(value: G2Projective) -> Self { + BlindedSerialNumber(value) + } +} + +impl From for BlindedSerialNumber { + fn from(value: G2Affine) -> Self { + BlindedSerialNumber(value.into()) + } +} + +impl Deref for BlindedSerialNumber { + type Target = G2Projective; + + fn deref(&self) -> &Self::Target { + &self.0 + } } impl TryFrom<&[u8]> for BlindedSerialNumber { @@ -34,13 +63,13 @@ impl TryFrom<&[u8]> for BlindedSerialNumber { ), )?; - Ok(BlindedSerialNumber { inner }) + Ok(BlindedSerialNumber(inner)) } } impl Bytable for BlindedSerialNumber { fn to_byte_vec(&self) -> Vec { - self.inner.to_affine().to_compressed().to_vec() + self.0.to_affine().to_compressed().to_vec() } fn try_from_byte_slice(slice: &[u8]) -> Result { diff --git a/common/nymcoconut/src/scheme/verification.rs b/common/nymcoconut/src/scheme/verification.rs index cbf36fde2f..e9957a7c73 100644 --- a/common/nymcoconut/src/scheme/verification.rs +++ b/common/nymcoconut/src/scheme/verification.rs @@ -1,22 +1,21 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 -use core::ops::Neg; -use std::convert::TryFrom; -use std::convert::TryInto; - -use bls12_381::{multi_miller_loop, G1Affine, G2Prepared, G2Projective, Scalar}; -use group::{Curve, Group}; - use crate::error::{CoconutError, Result}; use crate::proofs::ProofKappaZeta; -use crate::scheme::double_use::BlindedSerialNumber; use crate::scheme::setup::Parameters; use crate::scheme::Signature; use crate::scheme::VerificationKey; use crate::traits::{Base58, Bytable}; use crate::utils::try_deserialize_g2_projective; use crate::Attribute; +use bls12_381::{multi_miller_loop, G1Affine, G2Prepared, G2Projective, Scalar}; +use core::ops::Neg; +use group::{Curve, Group}; +use std::convert::TryFrom; +use std::convert::TryInto; + +pub use crate::scheme::double_use::BlindedSerialNumber; // TODO NAMING: this whole thing // Theta @@ -25,7 +24,7 @@ pub struct VerifyCredentialRequest { // blinded_message (kappa) pub blinded_message: G2Projective, // blinded serial number (zeta) - pub blinded_serial_number: G2Projective, + pub blinded_serial_number: BlindedSerialNumber, // sigma pub credential: Signature, // pi_v @@ -53,15 +52,10 @@ impl TryFrom<&[u8]> for VerifyCredentialRequest { ), )?; - // safety: we just checked for the length so the unwraps are fine - #[allow(clippy::unwrap_used)] - let blinded_serial_number_bytes = bytes[96..192].try_into().unwrap(); - let blinded_serial_number = try_deserialize_g2_projective( - &blinded_serial_number_bytes, - CoconutError::Deserialization( - "failed to deserialize the blinded serial number (zeta)".to_string(), - ), - )?; + let blinded_serial_number_bytes = &bytes[96..192]; + let blinded_serial_number = + BlindedSerialNumber::try_from_byte_slice(blinded_serial_number_bytes)?; + let credential = Signature::try_from(&bytes[192..288])?; let pi_v = ProofKappaZeta::from_bytes(&bytes[288..])?; @@ -87,7 +81,7 @@ impl VerifyCredentialRequest { pub fn has_blinded_serial_number(&self, blinded_serial_number_bs58: &str) -> Result { let blinded_serial_number = BlindedSerialNumber::try_from_bs58(blinded_serial_number_bs58)?; - let ret = self.blinded_serial_number.eq(&blinded_serial_number.inner); + let ret = self.blinded_serial_number.eq(&blinded_serial_number); Ok(ret) } @@ -112,10 +106,7 @@ impl VerifyCredentialRequest { } pub fn blinded_serial_number_bs58(&self) -> String { - let blinded_serial_nuumber = BlindedSerialNumber { - inner: self.blinded_serial_number, - }; - blinded_serial_nuumber.to_bs58() + self.blinded_serial_number.to_bs58() } } @@ -198,7 +189,7 @@ pub fn prove_bandwidth_credential( Ok(VerifyCredentialRequest { blinded_message, - blinded_serial_number, + blinded_serial_number: blinded_serial_number.into(), credential: signature_prime, pi_v, }) diff --git a/gateway/migrations/20240126120000_store_serial_numbers.sql b/gateway/migrations/20240126120000_store_serial_numbers.sql new file mode 100644 index 0000000000..b7e1384dad --- /dev/null +++ b/gateway/migrations/20240126120000_store_serial_numbers.sql @@ -0,0 +1,11 @@ +/* + * Copyright 2024 - Nym Technologies SA + * SPDX-License-Identifier: Apache-2.0 + */ + +CREATE TABLE spent_credential +( + blinded_serial_number_bs58 TEXT NOT NULL PRIMARY KEY UNIQUE, + was_freepass BOOLEAN NOT NULL, + client_address_bs58 TEXT NOT NULL REFERENCES shared_keys (client_address_bs58) +); \ No newline at end of file diff --git a/gateway/src/node/storage/bandwidth.rs b/gateway/src/node/storage/bandwidth.rs index 536f9b69f0..3eb4dab057 100644 --- a/gateway/src/node/storage/bandwidth.rs +++ b/gateway/src/node/storage/bandwidth.rs @@ -1,7 +1,7 @@ // Copyright 2021 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use crate::node::storage::models::PersistedBandwidth; +use crate::node::storage::models::{PersistedBandwidth, SpentCredential}; #[derive(Clone)] pub(crate) struct BandwidthManager { @@ -103,4 +103,54 @@ impl BandwidthManager { .await?; Ok(()) } + + /// Mark received credential as spent and insert it into the storage. + /// + /// # Arguments + /// + /// * `blinded_serial_number_bs58`: the unique blinded serial number embedded in the credential + /// * `was_freepass`: indicates whether the spent credential was a freepass + /// * `client_address_bs58`: address of the client that spent the credential + pub(crate) async fn insert_spent_credential( + &self, + blinded_serial_number_bs58: &str, + was_freepass: bool, + client_address_bs58: &str, + ) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + INSERT INTO spent_credential + (blinded_serial_number_bs58, was_freepass, client_address_bs58) + VALUES (?, ?, ?) + "#, + blinded_serial_number_bs58, + was_freepass, + client_address_bs58 + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + /// Retrieve the spent credential with the provided blinded serial number from the storage. + /// + /// # Arguments + /// + /// * `blinded_serial_number_bs58`: the unique blinded serial number embedded in the credential + pub(crate) async fn retrieve_spent_credential( + &self, + blinded_serial_number_bs58: &str, + ) -> Result, sqlx::Error> { + sqlx::query_as!( + SpentCredential, + r#" + SELECT * FROM spent_credential + WHERE blinded_serial_number_bs58 = ? + LIMIT 1 + "#, + blinded_serial_number_bs58, + ) + .fetch_optional(&self.connection_pool) + .await + } } diff --git a/gateway/src/node/storage/mod.rs b/gateway/src/node/storage/mod.rs index 77f87437ea..bc6bbb76f9 100644 --- a/gateway/src/node/storage/mod.rs +++ b/gateway/src/node/storage/mod.rs @@ -8,6 +8,7 @@ use crate::node::storage::models::{PersistedSharedKeys, StoredMessage}; use crate::node::storage::shared_keys::SharedKeysManager; use async_trait::async_trait; use log::{debug, error}; +use nym_credentials_interface::{Base58, BlindedSerialNumber}; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::DestinationAddressBytes; use sqlx::ConnectOptions; @@ -134,6 +135,29 @@ pub(crate) trait Storage: Send + Sync { client_address: DestinationAddressBytes, amount: i64, ) -> Result<(), StorageError>; + + /// Mark received credential as spent and insert it into the storage. + /// + /// # Arguments + /// + /// * `blinded_serial_number`: the unique blinded serial number embedded in the credential + /// * `client_address`: address of the client that spent the credential + async fn insert_spent_credential( + &self, + blinded_serial_number: BlindedSerialNumber, + was_freepass: bool, + client_address: DestinationAddressBytes, + ) -> Result<(), StorageError>; + + /// Check if the credential with the provided blinded serial number if already present in the storage. + /// + /// # Arguments + /// + /// * `blinded_serial_number`: the unique blinded serial number embedded in the credential + async fn contains_credential( + &self, + blinded_serial_number: &BlindedSerialNumber, + ) -> Result; } // note that clone here is fine as upon cloning the same underlying pool will be used @@ -304,6 +328,34 @@ impl Storage for PersistentStorage { .await?; Ok(()) } + + async fn insert_spent_credential( + &self, + blinded_serial_number: BlindedSerialNumber, + was_freepass: bool, + client_address: DestinationAddressBytes, + ) -> Result<(), StorageError> { + self.bandwidth_manager + .insert_spent_credential( + &blinded_serial_number.to_bs58(), + was_freepass, + &client_address.as_base58_string(), + ) + .await?; + Ok(()) + } + + async fn contains_credential( + &self, + blinded_serial_number: &BlindedSerialNumber, + ) -> Result { + let cred = self + .bandwidth_manager + .retrieve_spent_credential(&blinded_serial_number.to_bs58()) + .await?; + + Ok(cred.is_some()) + } } /// In-memory implementation of `Storage`. The intention is primarily in testing environments. @@ -393,4 +445,19 @@ impl Storage for InMemStorage { ) -> Result<(), StorageError> { todo!() } + + async fn insert_spent_credential( + &self, + blinded_serial_number: BlindedSerialNumber, + client_address: DestinationAddressBytes, + ) -> Result<(), StorageError> { + todo!() + } + + async fn contains_credential( + &self, + blinded_serial_number: &BlindedSerialNumber, + ) -> Result { + todo!() + } } diff --git a/gateway/src/node/storage/models.rs b/gateway/src/node/storage/models.rs index c98fb4c26b..2bef3b7265 100644 --- a/gateway/src/node/storage/models.rs +++ b/gateway/src/node/storage/models.rs @@ -1,6 +1,8 @@ -// Copyright 2021 - Nym Technologies SA +// Copyright 2021-2024 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only +use sqlx::FromRow; + pub(crate) struct PersistedSharedKeys { pub(crate) client_address_bs58: String, pub(crate) derived_aes128_ctr_blake3_hmac_keys_bs58: String, @@ -18,3 +20,13 @@ pub(crate) struct PersistedBandwidth { pub(crate) client_address_bs58: String, pub(crate) available: i64, } + +#[derive(Debug, Clone, FromRow)] +pub(crate) struct SpentCredential { + #[allow(dead_code)] + pub(crate) blinded_serial_number_bs58: String, + #[allow(dead_code)] + pub(crate) was_freepass: bool, + #[allow(dead_code)] + pub(crate) client_address_bs58: String, +} From dd97eb13a81920f10f45a61c20439c03c00eaf1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 09:53:13 +0000 Subject: [PATCH 079/394] locally marking credentials as spent --- common/credentials-interface/src/lib.rs | 4 +++ common/nymcoconut/src/scheme/verification.rs | 4 +++ .../connection_handler/authenticated.rs | 35 +++++++++++++++++-- 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/common/credentials-interface/src/lib.rs b/common/credentials-interface/src/lib.rs index ed3a2ca03c..277dcbe5a5 100644 --- a/common/credentials-interface/src/lib.rs +++ b/common/credentials-interface/src/lib.rs @@ -129,4 +129,8 @@ impl CredentialSpendingData { // the first attribute is variant specific bandwidth encoding, the second one should be the type self.public_attributes_plain.first() } + + pub fn blinded_serial_number(&self) -> BlindedSerialNumber { + self.verify_credential_request.blinded_serial_number() + } } diff --git a/common/nymcoconut/src/scheme/verification.rs b/common/nymcoconut/src/scheme/verification.rs index e9957a7c73..652a02a04e 100644 --- a/common/nymcoconut/src/scheme/verification.rs +++ b/common/nymcoconut/src/scheme/verification.rs @@ -105,6 +105,10 @@ impl VerifyCredentialRequest { VerifyCredentialRequest::try_from(bytes) } + pub fn blinded_serial_number(&self) -> BlindedSerialNumber { + self.blinded_serial_number + } + pub fn blinded_serial_number_bs58(&self) -> String { self.blinded_serial_number.to_bs58() } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index de56f78413..1c22df93b7 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -57,6 +57,9 @@ pub(crate) enum RequestHandlingError { #[error("Provided bandwidth credential did not verify correctly on {0}")] InvalidBandwidthCredential(String), + #[error("the provided bandwidth credential has already been spent before at this gateway")] + BandwidthCredentialAlreadySpent, + #[error("This gateway is only accepting coconut credentials for bandwidth")] OnlyCoconutCredentials, @@ -222,6 +225,17 @@ where &mut self, credential: CredentialSpendingRequest, ) -> Result { + // check if the credential hasn't been spent before + let serial_number = credential.data.blinded_serial_number(); + let already_spent = self + .inner + .storage + .contains_credential(&serial_number) + .await?; + if already_spent { + return Err(RequestHandlingError::BandwidthCredentialAlreadySpent); + } + let aggregated_verification_key = self .inner .coconut_verifier @@ -239,6 +253,7 @@ where // this will extract token amounts out of bandwidth vouchers and validate expiry of free passes let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; + // locally verify the credential let params = bandwidth_credential_params(); if !credential.data.verify(params, &aggregated_verification_key) { return Err(RequestHandlingError::InvalidBandwidthCredential( @@ -246,7 +261,7 @@ where )); } - match credential.data.typ { + let was_freepass = match credential.data.typ { CredentialType::Voucher => { let api_clients = self .inner @@ -258,12 +273,28 @@ where .coconut_verifier .release_bandwidth_voucher_funds(&api_clients, credential) .await?; + false } CredentialType::FreePass => { // no need to do anything special here, we already extracted the bandwidth amount and checked expiry info!("received a free pass credential"); + + true } - } + }; + + // technically this is not atomic, i.e. checking for the spending and then marking as spent, + // but because we have the `UNIQUE` constraint on the database table + // if somebody attempts to spend the same credential in another, parallel request, + // one of them will fail + // + // mark the credential as spent + // TODO: technically this should be done under a storage transaction so that if we experience any + // failures later on, it'd get reverted + self.inner + .storage + .insert_spent_credential(serial_number, was_freepass, self.client.address) + .await?; self.increase_bandwidth(bandwidth).await?; let available_total = self.get_available_bandwidth().await?; From f348e6972aa9273b1d1c44d0b0a4d36a69facd4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 13 Feb 2024 10:35:24 +0000 Subject: [PATCH 080/394] clippy --- gateway/src/node/storage/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gateway/src/node/storage/mod.rs b/gateway/src/node/storage/mod.rs index bc6bbb76f9..5349686a86 100644 --- a/gateway/src/node/storage/mod.rs +++ b/gateway/src/node/storage/mod.rs @@ -448,15 +448,16 @@ impl Storage for InMemStorage { async fn insert_spent_credential( &self, - blinded_serial_number: BlindedSerialNumber, - client_address: DestinationAddressBytes, + _blinded_serial_number: BlindedSerialNumber, + _was_freepass: bool, + _client_address: DestinationAddressBytes, ) -> Result<(), StorageError> { todo!() } async fn contains_credential( &self, - blinded_serial_number: &BlindedSerialNumber, + _blinded_serial_number: &BlindedSerialNumber, ) -> Result { todo!() } From 688ac2efb5c06eb918af1b7b9606139e8c90affd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 10:12:40 +0000 Subject: [PATCH 081/394] added nym-cli command for importing credentials --- .../commands/src/coconut/generate_freepass.rs | 4 +- .../commands/src/coconut/import_credential.rs | 106 ++++++++++++++++++ common/commands/src/coconut/mod.rs | 2 + .../src/coconut/bandwidth/freepass.rs | 4 + .../src/coconut/bandwidth/issued.rs | 8 ++ .../src/coconut/bandwidth/voucher.rs | 4 + 6 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 common/commands/src/coconut/import_credential.rs diff --git a/common/commands/src/coconut/generate_freepass.rs b/common/commands/src/coconut/generate_freepass.rs index 98325ea710..b10dd2bbc4 100644 --- a/common/commands/src/coconut/generate_freepass.rs +++ b/common/commands/src/coconut/generate_freepass.rs @@ -35,10 +35,12 @@ fn parse_rfc3339_expiration_date(raw: &str) -> Result, + /// The expiration of the free pass(es) expresses as unix timestamp. + /// Can't be set to more than a week into the future. #[clap(long, group = "expiration")] pub(crate) expiration_timestamp: Option, diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs new file mode 100644 index 0000000000..3d90e02c42 --- /dev/null +++ b/common/commands/src/coconut/import_credential.rs @@ -0,0 +1,106 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::utils::CommonConfigsWrapper; +use anyhow::bail; +use clap::ArgGroup; +use clap::Parser; +use log::{error, info}; +use nym_credential_storage::initialise_persistent_storage; +use nym_credential_storage::models::StorableIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; +use nym_credentials::IssuedBandwidthCredential; +use std::fs; +use std::path::PathBuf; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { + bs58::decode(raw).into_vec() +} + +#[derive(Debug, Parser)] +#[clap(group(ArgGroup::new("cred_data").required(true)))] +pub struct Args { + /// Config file of the client that is supposed to use the credential. + #[clap(long)] + pub(crate) client_config: PathBuf, + + /// Explicitly provide the encoded credential data (as base58) + #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] + pub(crate) credential_data: Option>, + + /// Specifies the path to file containing binary credential data + #[clap(long, group = "cred_data")] + pub(crate) credential_path: Option, + + // currently hidden as there exists only a single serialization standard + #[clap(long, hide = true, default_value_t = 1)] + pub(crate) version: u8, +} + +pub async fn execute(args: Args) -> anyhow::Result<()> { + let loaded = CommonConfigsWrapper::try_load(args.client_config)?; + + if let Ok(id) = loaded.try_get_id() { + println!("loaded config file for client '{id}'"); + } + + let Ok(credentials_store) = loaded.try_get_credentials_store() else { + bail!("the loaded config does not have a credentials store information") + }; + + println!( + "using credentials store at '{}'", + credentials_store.display() + ); + + let raw_credential = match args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + fs::read(args.credential_path.unwrap())? + } + }; + let raw_credential = Zeroizing::new(raw_credential); + + // we're unpacking the data in order to make sure it's valid + // and to extract relevant metadata for storage purposes + let credential = match args.version { + 1 => Zeroizing::new(IssuedBandwidthCredential::unpack_v1(&raw_credential)?), + other => panic!("unknown credential serialization version {other}"), + }; + let persistent_storage = initialise_persistent_storage(credentials_store).await; + + info!("importing {}", credential.typ()); + match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { + info!("with value of {}", voucher_info.value()) + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + info!("with expiry at {}", freepass_info.expiry_date()); + if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + error!("the free pass has already expired!"); + + // technically we can, but the gateway will just reject it so what's the point + bail!("can't import an expired free pass") + } + } + } + + let storable = StorableIssuedCredential { + serialization_revision: args.version, + credential_data: &raw_credential, + credential_type: credential.typ().to_string(), + epoch_id: credential + .epoch_id() + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; + + persistent_storage + .insert_issued_credential(storable) + .await?; + Ok(()) +} diff --git a/common/commands/src/coconut/mod.rs b/common/commands/src/coconut/mod.rs index c6499deed4..700c7d521f 100644 --- a/common/commands/src/coconut/mod.rs +++ b/common/commands/src/coconut/mod.rs @@ -4,6 +4,7 @@ use clap::{Args, Subcommand}; pub mod generate_freepass; +pub mod import_credential; pub mod issue_credentials; pub mod recover_credentials; @@ -19,4 +20,5 @@ pub enum CoconutCommands { GenerateFreepass(generate_freepass::Args), IssueCredentials(issue_credentials::Args), RecoverCredentials(recover_credentials::Args), + ImportCredential(import_credential::Args), } diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index ed2b57000c..1321e59f1d 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -30,6 +30,10 @@ impl<'a> From<&'a FreePassIssuanceData> for FreePassIssuedData { } impl FreePassIssuedData { + pub fn expiry_date(&self) -> OffsetDateTime { + self.expiry_date + } + pub fn expiry_date_plain(&self) -> String { self.expiry_date.unix_timestamp().to_string() } diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 8354408533..b9d3ee02b3 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -116,6 +116,14 @@ impl IssuedBandwidthCredential { } } + pub fn epoch_id(&self) -> EpochId { + self.epoch_id + } + + pub fn variant_data(&self) -> &BandwidthCredentialIssuedDataVariant { + &self.variant_data + } + pub fn current_serialization_revision(&self) -> u8 { CURRENT_SERIALIZATION_REVISION } diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index 06866d9606..f61f5c3544 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -30,6 +30,10 @@ impl<'a> From<&'a BandwidthVoucherIssuanceData> for BandwidthVoucherIssuedData { } impl BandwidthVoucherIssuedData { + pub fn value(&self) -> &Coin { + &self.value + } + pub fn value_plain(&self) -> String { self.value.amount.to_string() } From 7bbac26676d486bd34f5fdac638db5875d380a95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 10:26:10 +0000 Subject: [PATCH 082/394] replaced usage of lazy_static to oncelock for build information --- clients/native/Cargo.toml | 1 - clients/native/src/commands/mod.rs | 11 ++++------- clients/socks5/Cargo.toml | 1 - clients/socks5/src/commands/mod.rs | 10 +++------- explorer-api/Cargo.toml | 1 - explorer-api/src/commands/mod.rs | 10 +++------- gateway/Cargo.toml | 1 - gateway/src/main.rs | 10 +++------- mixnode/Cargo.toml | 1 - mixnode/src/main.rs | 10 +++------- nym-api/Cargo.toml | 1 - sdk/lib/socks5-listener/Cargo.toml | 1 - sdk/lib/socks5-listener/src/lib.rs | 1 - service-providers/ip-packet-router/Cargo.toml | 1 - service-providers/ip-packet-router/src/cli/mod.rs | 9 +++------ service-providers/network-requester/Cargo.toml | 1 - service-providers/network-requester/src/cli/mod.rs | 9 +++------ 17 files changed, 22 insertions(+), 57 deletions(-) diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 076b7128c8..59e8d212c0 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -23,7 +23,6 @@ url = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } dirs = "4.0" -lazy_static = "1.4.0" log = { workspace = true } # self explanatory pretty_env_logger = "0.4" # for formatting log messages rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 3ebe929b16..c49b197f62 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -8,7 +8,6 @@ use crate::client::config::{BaseClientConfig, Config}; use crate::error::ClientError; use clap::CommandFactory; use clap::{Parser, Subcommand}; -use lazy_static::lazy_static; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; @@ -21,18 +20,16 @@ use nym_client_core::error::ClientCoreError; use nym_config::OptionalSet; use std::error::Error; use std::net::IpAddr; +use std::sync::OnceLock; pub(crate) mod build_info; +pub(crate) mod import_credential; pub(crate) mod init; pub(crate) mod run; -lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 89edffb4fc..00a1932209 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -9,7 +9,6 @@ license.workspace = true [dependencies] clap = { workspace = true, features = ["cargo", "derive"] } -lazy_static = "1.4.0" log = { workspace = true } pretty_env_logger = "0.4" serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 7bd5205791..3b2ebd25fa 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -9,7 +9,6 @@ use crate::config::{BaseClientConfig, Config, SocksClientPaths}; use crate::error::Socks5ClientError; use clap::CommandFactory; use clap::{Parser, Subcommand}; -use lazy_static::lazy_static; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; @@ -24,18 +23,15 @@ use nym_config::OptionalSet; use nym_sphinx::params::{PacketSize, PacketType}; use std::error::Error; use std::net::IpAddr; +use std::sync::OnceLock; pub(crate) mod build_info; pub mod init; pub(crate) mod run; -lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index f4d132d92a..eaf3876402 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -13,7 +13,6 @@ dotenvy = { workspace = true } humantime-serde = "1.0" isocountry = "0.3.2" itertools = "0.10.3" -lazy_static = "1.4.0" log = { workspace = true } maxminddb = "0.23.0" okapi = { version = "0.7.0", features = ["impl_json_schema"] } diff --git a/explorer-api/src/commands/mod.rs b/explorer-api/src/commands/mod.rs index 1e19d2efce..0c0855d065 100644 --- a/explorer-api/src/commands/mod.rs +++ b/explorer-api/src/commands/mod.rs @@ -2,16 +2,12 @@ // SPDX-License-Identifier: Apache-2.0 use clap::Parser; -use lazy_static::lazy_static; use nym_bin_common::bin_info; +use std::sync::OnceLock; -lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 51f0307f76..ac7aefb4a4 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -29,7 +29,6 @@ dotenvy = { workspace = true } futures = { workspace = true } humantime-serde = "1.0.1" ipnetwork = "0.16" -lazy_static = "1.4.0" log = { workspace = true } once_cell = "1.7.2" pretty_env_logger = "0.4" diff --git a/gateway/src/main.rs b/gateway/src/main.rs index 0ec4b7865a..f88398e0b9 100644 --- a/gateway/src/main.rs +++ b/gateway/src/main.rs @@ -6,13 +6,13 @@ use clap::{crate_name, crate_version, Parser}; use colored::Colorize; -use lazy_static::lazy_static; use log::error; use nym_bin_common::bin_info; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; use nym_bin_common::output_format::OutputFormat; use nym_network_defaults::setup_env; use std::error::Error; +use std::sync::OnceLock; mod commands; mod config; @@ -21,13 +21,9 @@ mod http; mod node; pub(crate) mod support; -lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 9ad7c5081f..a15308cb4a 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -26,7 +26,6 @@ cupid = "0.6.1" dirs = "4.0" futures = { workspace = true } humantime-serde = "1.0" -lazy_static = "1.4.0" log = { workspace = true } rand = "0.7.3" serde = { workspace = true, features = ["derive"] } diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index d6383477cc..a7b1592776 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -3,9 +3,9 @@ use ::nym_config::defaults::setup_env; use clap::{crate_name, crate_version, Parser}; -use lazy_static::lazy_static; use log::info; use nym_bin_common::bin_info; +use std::sync::OnceLock; #[allow(unused_imports)] use nym_bin_common::logging::{maybe_print_banner, setup_logging}; @@ -21,13 +21,9 @@ mod config; pub(crate) mod error; mod node; -lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 536f7915a8..5a5f31d778 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -27,7 +27,6 @@ futures = { workspace = true } itertools = "0.12.0" humantime-serde = "1.0" k256 = { version = "*", features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies -lazy_static = "1.4.0" log = { workspace = true } pin-project = "1.0" rand = "0.8.5" diff --git a/sdk/lib/socks5-listener/Cargo.toml b/sdk/lib/socks5-listener/Cargo.toml index 425154a5cb..129afb5e87 100644 --- a/sdk/lib/socks5-listener/Cargo.toml +++ b/sdk/lib/socks5-listener/Cargo.toml @@ -16,7 +16,6 @@ crate-type = ["cdylib", "staticlib", "rlib"] [dependencies] anyhow = { workspace = true } futures = { workspace = true } -lazy_static = "1.4.0" nym-bin-common = { path = "../../../common/bin-common"} nym-client-core = { path = "../../../common/client-core", default-features = false } nym-config-common = { path = "../../../common/config", package = "nym-config" } diff --git a/sdk/lib/socks5-listener/src/lib.rs b/sdk/lib/socks5-listener/src/lib.rs index 0c9e2f7771..352638f84d 100644 --- a/sdk/lib/socks5-listener/src/lib.rs +++ b/sdk/lib/socks5-listener/src/lib.rs @@ -5,7 +5,6 @@ use crate::config::{config_filepath_from_root, Config}; use crate::persistence::MobileClientStorage; use ::safer_ffi::prelude::*; use anyhow::{anyhow, Result}; -use lazy_static::lazy_static; use log::{debug, info, warn}; use nym_bin_common::logging::setup_logging; use nym_client_core::init::helpers::current_gateways; diff --git a/service-providers/ip-packet-router/Cargo.toml b/service-providers/ip-packet-router/Cargo.toml index 39f3e33e48..ce6674550d 100644 --- a/service-providers/ip-packet-router/Cargo.toml +++ b/service-providers/ip-packet-router/Cargo.toml @@ -15,7 +15,6 @@ bytes = "1.5.0" clap.workspace = true etherparse = "0.13.0" futures = { workspace = true } -lazy_static.workspace = true log = { workspace = true } nym-bin-common = { path = "../../common/bin-common" } nym-client-core = { path = "../../common/client-core" } diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index d17391eaed..eda51a5554 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -8,6 +8,7 @@ use nym_client_core::client::base_client::storage::gateway_details::{ use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; +use std::sync::OnceLock; use crate::config::{BaseClientConfig, Config}; use crate::error::IpPacketRouterError; @@ -17,13 +18,9 @@ mod init; mod run; mod sign; -lazy_static::lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 7a2805cd17..323a11c286 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -24,7 +24,6 @@ dirs = "4.0" futures = { workspace = true } humantime-serde = "1.1.1" ipnetwork = "0.20.0" -lazy_static = { workspace = true } log = { workspace = true } pretty_env_logger = "0.4.0" publicsuffix = "2.2.3" diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 2dba60cb16..874f191134 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -20,19 +20,16 @@ use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; use nym_config::OptionalSet; +use std::sync::OnceLock; mod build_info; mod init; mod run; mod sign; -lazy_static::lazy_static! { - pub static ref PRETTY_BUILD_INFORMATION: String = bin_info!().pretty_print(); -} - -// Helper for passing LONG_VERSION to clap fn pretty_build_info_static() -> &'static str { - &PRETTY_BUILD_INFORMATION + static PRETTY_BUILD_INFORMATION: OnceLock = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) } #[derive(Parser)] From e7d0c1812ae6c2ddd4260597a117eef2e36952d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 10:50:08 +0000 Subject: [PATCH 083/394] added import commands for client binaries --- Cargo.toml | 1 + clients/native/Cargo.toml | 4 +- .../native/src/commands/import_credential.rs | 102 ++++++++++++++++++ clients/native/src/commands/mod.rs | 4 + clients/native/src/error.rs | 22 +++- clients/socks5/Cargo.toml | 4 +- .../socks5/src/commands/import_credential.rs | 102 ++++++++++++++++++ clients/socks5/src/commands/mod.rs | 5 + clients/socks5/src/error.rs | 22 +++- common/commands/Cargo.toml | 2 +- .../contracts-common/Cargo.toml | 2 +- common/crypto/Cargo.toml | 2 +- common/dkg/Cargo.toml | 2 +- common/nymcoconut/Cargo.toml | 2 +- common/nymsphinx/anonymous-replies/Cargo.toml | 2 +- common/topology/Cargo.toml | 2 +- contracts/Cargo.lock | 53 +++++---- contracts/Cargo.toml | 2 + contracts/mixnet/Cargo.toml | 4 +- contracts/name-service/Cargo.toml | 2 +- .../service-provider-directory/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- gateway/gateway-requests/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-api/nym-api-requests/Cargo.toml | 2 +- nym-connect/desktop/Cargo.lock | 17 +-- nym-wallet/Cargo.lock | 11 +- service-providers/ip-packet-router/Cargo.toml | 2 +- .../network-requester/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- tools/nym-cli/src/coconut/mod.rs | 3 + 32 files changed, 332 insertions(+), 58 deletions(-) create mode 100644 clients/native/src/commands/import_credential.rs create mode 100644 clients/socks5/src/commands/import_credential.rs diff --git a/Cargo.toml b/Cargo.toml index c92723a54c..6e78dea995 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -143,6 +143,7 @@ anyhow = "1.0.71" async-trait = "0.1.68" axum = "0.6.20" base64 = "0.21.4" +bs58 = "0.5.0" bip39 = { version = "2.0.0", features = ["zeroize"] } clap = "4.4.7" cfg-if = "1.0.0" diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 59e8d212c0..465ba5ea1d 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -21,17 +21,19 @@ futures = { workspace = true } # bunch of futures stuff, however, now that I thi # and the single instance of abortable we have should really be refactored anyway url = { workspace = true } +bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } dirs = "4.0" log = { workspace = true } # self explanatory -pretty_env_logger = "0.4" # for formatting log messages rand = { version = "0.7.3", features = ["wasm-bindgen"] } # rng-related traits + some rng implementation to use serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization serde_json = { workspace = true } thiserror = { workspace = true } tap = "1.0.1" +time = { workspace = true } tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } # async runtime tokio-tungstenite = { workspace = true } +zeroize = { workspace = true } ## internal nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs new file mode 100644 index 0000000000..9d156d32ff --- /dev/null +++ b/clients/native/src/commands/import_credential.rs @@ -0,0 +1,102 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::try_load_current_config; +use crate::error::ClientError; +use clap::ArgGroup; +use log::{error, info}; +use nym_credential_storage::models::StorableIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; +use nym_credentials::IssuedBandwidthCredential; +use std::fs; +use std::path::PathBuf; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { + bs58::decode(raw).into_vec() +} + +#[derive(clap::Args)] +#[clap(group(ArgGroup::new("cred_data").required(true)))] +pub(crate) struct Args { + /// Id of client that is going to import the credential + #[clap(long)] + pub id: String, + + /// Explicitly provide the encoded credential data (as base58) + #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] + pub(crate) credential_data: Option>, + + /// Specifies the path to file containing binary credential data + #[clap(long, group = "cred_data")] + pub(crate) credential_path: Option, + + // currently hidden as there exists only a single serialization standard + #[clap(long, hide = true, default_value_t = 1)] + pub(crate) version: u8, +} + +pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { + let config = try_load_current_config(&args.id)?; + + let credentials_store = nym_credential_storage::initialise_persistent_storage( + &config.storage_paths.common_paths.credentials_database, + ) + .await; + + let raw_credential = match args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + fs::read(args.credential_path.unwrap())? + } + }; + let raw_credential = Zeroizing::new(raw_credential); + + // we're unpacking the data in order to make sure it's valid + // and to extract relevant metadata for storage purposes + let credential = match args.version { + 1 => Zeroizing::new( + IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { + ClientError::CredentialDeserializationFailure { + storage_revision: 1, + source, + } + })?, + ), + other => panic!("unknown credential serialization version {other}"), + }; + + info!("importing {}", credential.typ()); + match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { + info!("with value of {}", voucher_info.value()) + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + info!("with expiry at {}", freepass_info.expiry_date()); + if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + error!("the free pass has already expired!"); + + // technically we can import it, but the gateway will just reject it so what's the point + return Err(ClientError::ExpiredCredentialImport { + expiration: freepass_info.expiry_date(), + }); + } + } + } + + let storable = StorableIssuedCredential { + serialization_revision: args.version, + credential_data: &raw_credential, + credential_type: credential.typ().to_string(), + epoch_id: credential + .epoch_id() + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; + + credentials_store.insert_issued_credential(storable).await?; + Ok(()) +} diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index c49b197f62..ff1b8087fd 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -55,6 +55,9 @@ pub(crate) enum Commands { /// Run the Nym client with provided configuration client optionally overriding set parameters Run(run::Run), + /// Import a pre-generated credential + ImportCredential(import_credential::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -83,6 +86,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, + Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 59d022999a..8a21803736 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -1,11 +1,13 @@ use nym_client_core::error::ClientCoreError; +use nym_credential_storage::error::StorageError; +use time::OffsetDateTime; #[derive(thiserror::Error, Debug)] pub enum ClientError { #[error("I/O error: {0}")] IoError(#[from] std::io::Error), - #[error("client-core error: {0}")] + #[error(transparent)] ClientCoreError(#[from] ClientCoreError), #[error("Failed to load config for: {0}")] @@ -20,4 +22,22 @@ pub enum ClientError { #[error("Attempted to start the client in invalid socket mode")] InvalidSocketMode, + + #[error("failed to store credential: {source}")] + CredentialStorageFailure { + #[from] + source: StorageError, + }, + + #[error( + "failed to deserialize provided credential using revision {storage_revision}: {source}" + )] + CredentialDeserializationFailure { + storage_revision: u8, + #[source] + source: nym_credentials::error::Error, + }, + + #[error("attempted to import an expired credential (it expired on {expiration})")] + ExpiredCredentialImport { expiration: OffsetDateTime }, } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 00a1932209..565b6c1c72 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -8,16 +8,18 @@ rust-version = "1.56" license.workspace = true [dependencies] +bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } log = { workspace = true } -pretty_env_logger = "0.4" serde = { workspace = true, features = ["derive"] } # for config serialization/deserialization serde_json = { workspace = true } tap = "1.0.1" thiserror = { workspace = true } tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } rand = "0.7.3" +time = { workspace = true } url = { workspace = true } +zeroize = { workspace = true } # internal nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs new file mode 100644 index 0000000000..b4c050b815 --- /dev/null +++ b/clients/socks5/src/commands/import_credential.rs @@ -0,0 +1,102 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::try_load_current_config; +use crate::error::Socks5ClientError; +use clap::ArgGroup; +use log::{error, info}; +use nym_credential_storage::models::StorableIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; +use nym_credentials::IssuedBandwidthCredential; +use std::fs; +use std::path::PathBuf; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { + bs58::decode(raw).into_vec() +} + +#[derive(clap::Args)] +#[clap(group(ArgGroup::new("cred_data").required(true)))] +pub(crate) struct Args { + /// Id of client that is going to import the credential + #[clap(long)] + pub id: String, + + /// Explicitly provide the encoded credential data (as base58) + #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] + pub(crate) credential_data: Option>, + + /// Specifies the path to file containing binary credential data + #[clap(long, group = "cred_data")] + pub(crate) credential_path: Option, + + // currently hidden as there exists only a single serialization standard + #[clap(long, hide = true, default_value_t = 1)] + pub(crate) version: u8, +} + +pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { + let config = try_load_current_config(&args.id)?; + + let credentials_store = nym_credential_storage::initialise_persistent_storage( + &config.storage_paths.common_paths.credentials_database, + ) + .await; + + let raw_credential = match args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + fs::read(args.credential_path.unwrap())? + } + }; + let raw_credential = Zeroizing::new(raw_credential); + + // we're unpacking the data in order to make sure it's valid + // and to extract relevant metadata for storage purposes + let credential = match args.version { + 1 => Zeroizing::new( + IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { + Socks5ClientError::CredentialDeserializationFailure { + storage_revision: 1, + source, + } + })?, + ), + other => panic!("unknown credential serialization version {other}"), + }; + + info!("importing {}", credential.typ()); + match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { + info!("with value of {}", voucher_info.value()) + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + info!("with expiry at {}", freepass_info.expiry_date()); + if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + error!("the free pass has already expired!"); + + // technically we can import it, but the gateway will just reject it so what's the point + return Err(Socks5ClientError::ExpiredCredentialImport { + expiration: freepass_info.expiry_date(), + }); + } + } + } + + let storable = StorableIssuedCredential { + serialization_revision: args.version, + credential_data: &raw_credential, + credential_type: credential.typ().to_string(), + epoch_id: credential + .epoch_id() + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; + + credentials_store.insert_issued_credential(storable).await?; + Ok(()) +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 3b2ebd25fa..da3166fd7e 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -26,6 +26,7 @@ use std::net::IpAddr; use std::sync::OnceLock; pub(crate) mod build_info; +mod import_credential; pub mod init; pub(crate) mod run; @@ -57,6 +58,9 @@ pub(crate) enum Commands { /// Run the Nym client with provided configuration client optionally overriding set parameters Run(run::Run), + /// Import a pre-generated credential + ImportCredential(import_credential::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -88,6 +92,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, + Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index 0005cadf8d..bed06bd385 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -1,4 +1,6 @@ use nym_client_core::error::ClientCoreError; +use nym_credential_storage::error::StorageError; +use time::OffsetDateTime; #[derive(thiserror::Error, Debug)] pub enum Socks5ClientError { @@ -18,6 +20,24 @@ pub enum Socks5ClientError { #[error("Fail to bind address")] FailToBindAddress, - #[error("client-core error: {0}")] + #[error(transparent)] ClientCoreError(#[from] ClientCoreError), + + #[error("failed to store credential: {source}")] + CredentialStorageFailure { + #[from] + source: StorageError, + }, + + #[error( + "failed to deserialize provided credential using revision {storage_revision}: {source}" + )] + CredentialDeserializationFailure { + storage_revision: u8, + #[source] + source: nym_credentials::error::Error, + }, + + #[error("attempted to import an expired credential (it expired on {expiration})")] + ExpiredCredentialImport { expiration: OffsetDateTime }, } diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 3a552ecc77..b2ef8bc3ea 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true anyhow = { workspace = true } base64 = "0.13.0" bip39 = { workspace = true } -bs58 = "0.4" +bs58 = { workspace = true } comfy-table = "6.0.0" cfg-if = "1.0.0" clap = { workspace = true, features = ["derive"] } diff --git a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml index fc55402be0..db46d56ce7 100644 --- a/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml +++ b/common/cosmwasm-smart-contracts/contracts-common/Cargo.toml @@ -8,7 +8,7 @@ license = { workspace = true } repository = { workspace = true } [dependencies] -bs58 = "0.4.0" +bs58 = { workspace = true } cosmwasm-std = { workspace = true } cosmwasm-schema = { workspace = true } schemars = "0.8" diff --git a/common/crypto/Cargo.toml b/common/crypto/Cargo.toml index 481ecbf1f7..061dea6183 100644 --- a/common/crypto/Cargo.toml +++ b/common/crypto/Cargo.toml @@ -9,7 +9,7 @@ repository = { workspace = true } [dependencies] aes = { version = "0.8.1", optional = true } -bs58 = "0.4.0" +bs58 = { workspace = true } blake3 = { version = "1.3.1", features = ["traits-preview"], optional = true } ctr = { version = "0.9.1", optional = true } digest = { version = "0.10.3", optional = true } diff --git a/common/dkg/Cargo.toml b/common/dkg/Cargo.toml index 03b0d35c9f..a2d101a231 100644 --- a/common/dkg/Cargo.toml +++ b/common/dkg/Cargo.toml @@ -14,7 +14,7 @@ bitvec = "1.0.0" # as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm bls12_381 = { workspace = true, default-features = false, features = ["alloc", "pairings", "experimental", "zeroize"] } nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common", optional = true } -bs58 = "0.4" +bs58 = { workspace = true } lazy_static = "1.4.0" diff --git a/common/nymcoconut/Cargo.toml b/common/nymcoconut/Cargo.toml index 9984550071..428bc9da2b 100644 --- a/common/nymcoconut/Cargo.toml +++ b/common/nymcoconut/Cargo.toml @@ -15,7 +15,7 @@ rand = "0.8" thiserror = { workspace = true } serde = { workspace = true } serde_derive = "1.0" -bs58 = "0.4.0" +bs58 = { workspace = true } sha2 = "0.9" zeroize = { workspace = true, optional = true } diff --git a/common/nymsphinx/anonymous-replies/Cargo.toml b/common/nymsphinx/anonymous-replies/Cargo.toml index 58c7c44890..9c057f31f5 100644 --- a/common/nymsphinx/anonymous-replies/Cargo.toml +++ b/common/nymsphinx/anonymous-replies/Cargo.toml @@ -9,7 +9,7 @@ repository = { workspace = true } [dependencies] rand = { version = "0.7.3", features = ["wasm-bindgen"] } -bs58 = "0.4" +bs58 = { workspace = true } serde = { workspace = true } thiserror = { workspace = true } diff --git a/common/topology/Cargo.toml b/common/topology/Cargo.toml index 3d43cfe229..f8ec395887 100644 --- a/common/topology/Cargo.toml +++ b/common/topology/Cargo.toml @@ -12,7 +12,7 @@ documentation = { workspace = true } # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bs58 = "0.4" +bs58 = { workspace = true } log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } thiserror = { workspace = true } diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 2ee4e93b1b..f7c83faa24 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -116,6 +116,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "tinyvec", +] + [[package]] name = "bumpalo" version = "3.12.1" @@ -822,7 +831,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.49", ] [[package]] @@ -1250,7 +1259,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58", + "bs58 0.5.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -1262,7 +1271,7 @@ dependencies = [ name = "nym-crypto" version = "0.4.0" dependencies = [ - "bs58", + "bs58 0.5.0", "ed25519-dalek", "nym-pemstore", "nym-sphinx-types", @@ -1318,7 +1327,7 @@ dependencies = [ name = "nym-mixnet-contract" version = "1.5.1" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-derive", "cosmwasm-schema", "cosmwasm-std", @@ -1341,7 +1350,7 @@ dependencies = [ name = "nym-mixnet-contract-common" version = "0.6.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-schema", "cosmwasm-std", "cw2", @@ -1376,7 +1385,7 @@ name = "nym-name-service" version = "0.1.0" dependencies = [ "anyhow", - "bs58", + "bs58 0.4.0", "cosmwasm-schema", "cosmwasm-std", "cw-controllers", @@ -1423,7 +1432,7 @@ name = "nym-service-provider-directory" version = "0.1.0" dependencies = [ "anyhow", - "bs58", + "bs58 0.4.0", "cosmwasm-schema", "cosmwasm-std", "cw-controllers", @@ -1610,9 +1619,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.63" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b368fba921b0dce7e60f5e04ec15e565b3303972b42bcfde1d0713b881959eb" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -1648,9 +1657,9 @@ checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" [[package]] name = "quote" -version = "1.0.30" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5907a1b7c277254a8b15170f6e7c97cfa60ee7872a3217663bb81151e48184bb" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -1890,9 +1899,9 @@ checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" [[package]] name = "serde" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" dependencies = [ "serde_derive", ] @@ -1908,13 +1917,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.196" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.49", ] [[package]] @@ -1947,7 +1956,7 @@ checksum = "bcec881020c684085e55a25f7fd888954d56609ef363479dc5a1305eb0d40cab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.49", ] [[package]] @@ -2002,7 +2011,7 @@ dependencies = [ "aes", "arrayref", "blake2", - "bs58", + "bs58 0.4.0", "byteorder", "chacha", "curve25519-dalek", @@ -2061,9 +2070,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.32" +version = "2.0.49" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2" +checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496" dependencies = [ "proc-macro2", "quote", @@ -2100,7 +2109,7 @@ checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.49", ] [[package]] @@ -2449,5 +2458,5 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.32", + "syn 2.0.49", ] diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 83f0a46531..74e6e4bb07 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -34,6 +34,7 @@ incremental = false overflow-checks = true [workspace.dependencies] +bs58 = "0.4.0" cosmwasm-crypto = "=1.3.0" cosmwasm-derive = "=1.3.0" cosmwasm-schema = "=1.3.0" @@ -49,5 +50,6 @@ cw3-fixed-multisig = "=1.1.0" cw4 = "=1.1.0" cw20 = "=1.1.0" semver = "1.0.21" +serde = "1.0.196" thiserror = "1.0.48" diff --git a/contracts/mixnet/Cargo.toml b/contracts/mixnet/Cargo.toml index c365dda0c6..9f2ba07124 100644 --- a/contracts/mixnet/Cargo.toml +++ b/contracts/mixnet/Cargo.toml @@ -37,8 +37,8 @@ cosmwasm-derive = { workspace = true } cw2 = { workspace = true } cw-storage-plus = { workspace = true } -bs58 = "0.4.0" -serde = { version = "1.0.103", default-features = false, features = ["derive"] } +bs58 = { workspace = true } +serde = { workspace = true, default-features = false, features = ["derive"] } thiserror = { workspace = true } time = { version = "0.3", features = ["macros"] } semver = { workspace = true, default-features = false } diff --git a/contracts/name-service/Cargo.toml b/contracts/name-service/Cargo.toml index 13cbb7a6c0..c1bf210637 100644 --- a/contracts/name-service/Cargo.toml +++ b/contracts/name-service/Cargo.toml @@ -11,7 +11,7 @@ required-features = ["schema-gen"] crate-type = ["cdylib", "rlib"] [dependencies] -bs58 = "0.4.0" +bs58 = { workspace = true } cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cw-controllers = { workspace = true } diff --git a/contracts/service-provider-directory/Cargo.toml b/contracts/service-provider-directory/Cargo.toml index 4acd39aa09..e4a75c50f0 100644 --- a/contracts/service-provider-directory/Cargo.toml +++ b/contracts/service-provider-directory/Cargo.toml @@ -11,7 +11,7 @@ required-features = ["schema-gen"] crate-type = ["cdylib", "rlib"] [dependencies] -bs58 = "0.4.0" +bs58 = { workspace = true } cosmwasm-schema = { workspace = true, optional = true } cosmwasm-std = { workspace = true } cw-controllers = { workspace = true } diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index ac7aefb4a4..028658525d 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -20,7 +20,7 @@ anyhow = { workspace = true } async-trait = { workspace = true } atty = "0.2" bip39 = { workspace = true } -bs58 = "0.4.0" +bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } colored = "2.0" dashmap = { workspace = true } diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index e771a71de1..2ca9a3b440 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -11,7 +11,7 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bs58 = "0.4.0" +bs58 = { workspace = true } futures = { workspace = true } generic-array = { workspace = true, features = ["serde"] } log = { workspace = true } diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index a15308cb4a..489b998e2c 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -19,7 +19,7 @@ rust-version = "1.58.1" [dependencies] axum = { workspace = true } anyhow = { workspace = true } -bs58 = "0.4.0" +bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } colored = "2.0" cupid = "0.6.1" diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 5a5f31d778..0bb2b2c263 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -17,7 +17,7 @@ rust-version = "1.56" [dependencies] async-trait = { workspace = true } -bs58 = { version = "0.4.0" } +bs58 = { workspace = true } bip39 = { workspace = true } cfg-if = "1.0" clap = { workspace = true, features = ["cargo", "derive"] } diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index d76ce70675..456c319224 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bs58 = "0.4.0" +bs58 = { workspace = true } cosmrs = { workspace = true } cosmwasm-std = { workspace = true } getset = "0.1.1" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 3c146f252d..f8ee12014b 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -612,6 +612,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ "sha2 0.10.8", + "tinyvec", ] [[package]] @@ -3692,7 +3693,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmrs", "cosmwasm-std", "ecdsa 0.16.8", @@ -3796,7 +3797,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "digest 0.9.0", "ff 0.13.0", "getrandom 0.2.10", @@ -3901,7 +3902,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -3955,7 +3956,7 @@ version = "0.4.0" dependencies = [ "aes 0.8.3", "blake3", - "bs58 0.4.0", + "bs58 0.5.0", "cipher 0.4.4", "ctr 0.9.2", "digest 0.10.7", @@ -3980,7 +3981,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "ff 0.13.0", "group 0.13.0", "lazy_static", @@ -4073,7 +4074,7 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "futures", "generic-array 0.14.7", "log", @@ -4358,7 +4359,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -4468,7 +4469,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58 0.4.0", + "bs58 0.5.0", "log", "nym-api-requests", "nym-bin-common", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 885674bddb..ff36739bb2 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -452,6 +452,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ "sha2 0.10.8", + "tinyvec", ] [[package]] @@ -3096,7 +3097,7 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", "ecdsa 0.16.8", @@ -3132,7 +3133,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "digest 0.9.0", "ff 0.13.0", "getrandom 0.2.10", @@ -3186,7 +3187,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -3208,7 +3209,7 @@ dependencies = [ name = "nym-crypto" version = "0.4.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "ed25519-dalek", "nym-pemstore", "nym-sphinx-types", @@ -3227,7 +3228,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "ff 0.13.0", "group 0.13.0", "lazy_static", diff --git a/service-providers/ip-packet-router/Cargo.toml b/service-providers/ip-packet-router/Cargo.toml index ce6674550d..e700505a96 100644 --- a/service-providers/ip-packet-router/Cargo.toml +++ b/service-providers/ip-packet-router/Cargo.toml @@ -10,7 +10,7 @@ license.workspace = true [dependencies] bincode = "1.3.3" -bs58 = "0.4.0" +bs58 = { workspace = true } bytes = "1.5.0" clap.workspace = true etherparse = "0.13.0" diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 323a11c286..b2486db390 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -18,7 +18,7 @@ path = "src/lib.rs" [dependencies] addr = "0.15.6" async-trait = { workspace = true } -bs58 = "0.4.0" +bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"]} dirs = "4.0" futures = { workspace = true } diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index 29a6f85e2f..194466b2f6 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -7,7 +7,7 @@ license.workspace = true [dependencies] base64 = "0.13.0" -bs58 = "0.4" +bs58 = { workspace = true } clap = { workspace = true, features = ["derive"] } clap_complete = "4.0" clap_complete_fig = "4.0" diff --git a/tools/nym-cli/src/coconut/mod.rs b/tools/nym-cli/src/coconut/mod.rs index 4df05bb5fd..2939175aed 100644 --- a/tools/nym-cli/src/coconut/mod.rs +++ b/tools/nym-cli/src/coconut/mod.rs @@ -28,6 +28,9 @@ pub(crate) async fn execute( ) .await? } + nym_cli_commands::coconut::CoconutCommands::ImportCredential(args) => { + nym_cli_commands::coconut::import_credential::execute(args).await? + } } Ok(()) } From dcd6dcc6e3c72d1dcba2e7348075a6af82732fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 11:10:51 +0000 Subject: [PATCH 084/394] restored accidentally removed lazy static in socks5 lib --- sdk/lib/socks5-listener/Cargo.toml | 1 + sdk/lib/socks5-listener/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/sdk/lib/socks5-listener/Cargo.toml b/sdk/lib/socks5-listener/Cargo.toml index 129afb5e87..425154a5cb 100644 --- a/sdk/lib/socks5-listener/Cargo.toml +++ b/sdk/lib/socks5-listener/Cargo.toml @@ -16,6 +16,7 @@ crate-type = ["cdylib", "staticlib", "rlib"] [dependencies] anyhow = { workspace = true } futures = { workspace = true } +lazy_static = "1.4.0" nym-bin-common = { path = "../../../common/bin-common"} nym-client-core = { path = "../../../common/client-core", default-features = false } nym-config-common = { path = "../../../common/config", package = "nym-config" } diff --git a/sdk/lib/socks5-listener/src/lib.rs b/sdk/lib/socks5-listener/src/lib.rs index 352638f84d..0c9e2f7771 100644 --- a/sdk/lib/socks5-listener/src/lib.rs +++ b/sdk/lib/socks5-listener/src/lib.rs @@ -5,6 +5,7 @@ use crate::config::{config_filepath_from_root, Config}; use crate::persistence::MobileClientStorage; use ::safer_ffi::prelude::*; use anyhow::{anyhow, Result}; +use lazy_static::lazy_static; use log::{debug, info, warn}; use nym_bin_common::logging::setup_logging; use nym_client_core::init::helpers::current_gateways; From 387d07fb9350548454573d293f745eff2292569d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 11:34:51 +0000 Subject: [PATCH 085/394] additional logs --- common/client-libs/gateway-client/src/client.rs | 2 ++ .../node/client_handling/websocket/connection_handler/fresh.rs | 1 + 2 files changed, 3 insertions(+) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 2a9750e7a1..d5c5ec6d42 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -382,6 +382,8 @@ impl GatewayClient { &self, gateway_protocol: Option, ) -> Result<(), GatewayClientError> { + debug!("gateway protocol: {gateway_protocol:?}, ours: {INITIAL_PROTOCOL_VERSION}"); + // right now there are no failure cases here, but this might change in the future match gateway_protocol { None => { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index a2e9e98e7d..930080b19e 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -363,6 +363,7 @@ where &self, client_protocol: Option, ) -> Result { + debug!("client protocol: {client_protocol:?}, ours: {INITIAL_PROTOCOL_VERSION}"); let Some(client_protocol_version) = client_protocol else { warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); // note: in +1.2.0 we will have to return a hard error here From 5cf53b70020c1c0ebfb6ff2690d28637de3653be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 12:11:50 +0000 Subject: [PATCH 086/394] fixed logging --- Cargo.lock | 62 +++++++++++-------- .../client-libs/gateway-client/src/client.rs | 2 +- contracts/Cargo.lock | 2 +- .../websocket/connection_handler/fresh.rs | 2 +- 4 files changed, 40 insertions(+), 28 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5c93874c55..55105ed993 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -825,6 +825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ "sha2 0.10.8", + "tinyvec", ] [[package]] @@ -2318,6 +2319,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.6", "rfc6979 0.4.0", + "serdect", "signature 2.1.0", "spki 0.7.2", ] @@ -2428,6 +2430,7 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -2517,7 +2520,6 @@ dependencies = [ "humantime-serde", "isocountry", "itertools 0.10.5", - "lazy_static", "log", "maxminddb", "nym-bin-common", @@ -4923,7 +4925,7 @@ dependencies = [ "anyhow", "async-trait", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "console-subscriber", @@ -4937,7 +4939,7 @@ dependencies = [ "getset", "humantime-serde", "itertools 0.12.0", - "lazy_static", + "k256", "log", "nym-api-requests", "nym-bandwidth-controller", @@ -4995,9 +4997,10 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", + "ecdsa 0.16.8", "getset", "nym-credentials-interface", "nym-crypto", @@ -5074,7 +5077,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "clap_complete", "clap_complete_fig", @@ -5099,7 +5102,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "comfy-table", @@ -5151,10 +5154,10 @@ dependencies = [ name = "nym-client" version = "1.1.32" dependencies = [ + "bs58 0.5.0", "clap 4.4.7", "dirs 4.0.0", "futures", - "lazy_static", "log", "nym-bandwidth-controller", "nym-bin-common", @@ -5171,15 +5174,16 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", + "time", "tokio", "tokio-tungstenite", "url", + "zeroize", ] [[package]] @@ -5270,7 +5274,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "criterion", "digest 0.9.0", "doc-comment", @@ -5329,7 +5333,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -5401,7 +5405,7 @@ version = "0.4.0" dependencies = [ "aes 0.8.3", "blake3", - "bs58 0.4.0", + "bs58 0.5.0", "cipher 0.4.4", "ctr 0.9.2", "digest 0.10.7", @@ -5427,7 +5431,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "criterion", "ff 0.13.0", "group 0.13.0", @@ -5507,7 +5511,7 @@ dependencies = [ "async-trait", "atty", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "colored", "dashmap", @@ -5518,7 +5522,6 @@ dependencies = [ "humantime-serde", "hyper", "ipnetwork 0.16.0", - "lazy_static", "log", "nym-api-requests", "nym-bin-common", @@ -5595,7 +5598,7 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "futures", "generic-array 0.14.7", "log", @@ -5652,12 +5655,11 @@ name = "nym-ip-packet-router" version = "0.1.0" dependencies = [ "bincode", - "bs58 0.4.0", + "bs58 0.5.0", "bytes", "clap 4.4.7", "etherparse", "futures", - "lazy_static", "log", "nym-bin-common", "nym-client-core", @@ -5726,7 +5728,7 @@ version = "1.1.34" dependencies = [ "anyhow", "axum", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "colored", @@ -5735,7 +5737,6 @@ dependencies = [ "dirs 4.0.0", "futures", "humantime-serde", - "lazy_static", "log", "nym-bin-common", "nym-config", @@ -5848,13 +5849,12 @@ dependencies = [ "anyhow", "async-file-watcher", "async-trait", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "dirs 4.0.0", "futures", "humantime-serde", "ipnetwork 0.20.0", - "lazy_static", "log", "nym-bin-common", "nym-client-core", @@ -6138,8 +6138,8 @@ dependencies = [ name = "nym-socks5-client" version = "1.1.32" dependencies = [ + "bs58 0.5.0", "clap 4.4.7", - "lazy_static", "log", "nym-bin-common", "nym-client-core", @@ -6154,14 +6154,15 @@ dependencies = [ "nym-socks5-client-core", "nym-sphinx", "nym-topology", - "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", + "time", "tokio", "url", + "zeroize", ] [[package]] @@ -6305,7 +6306,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -6445,7 +6446,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58 0.4.0", + "bs58 0.5.0", "log", "nym-api-requests", "nym-bin-common", @@ -8582,6 +8583,7 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -8814,6 +8816,16 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index d5c5ec6d42..a6f0600d82 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -382,7 +382,7 @@ impl GatewayClient { &self, gateway_protocol: Option, ) -> Result<(), GatewayClientError> { - debug!("gateway protocol: {gateway_protocol:?}, ours: {INITIAL_PROTOCOL_VERSION}"); + debug!("gateway protocol: {gateway_protocol:?}, ours: {CURRENT_PROTOCOL_VERSION}"); // right now there are no failure cases here, but this might change in the future match gateway_protocol { diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index f7c83faa24..1b7383f41f 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -187,7 +187,7 @@ dependencies = [ name = "coconut-test" version = "0.1.0" dependencies = [ - "bs58", + "bs58 0.4.0", "cosmwasm-std", "cosmwasm-storage", "cw-controllers", diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 930080b19e..46dc7f5f80 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -363,7 +363,7 @@ where &self, client_protocol: Option, ) -> Result { - debug!("client protocol: {client_protocol:?}, ours: {INITIAL_PROTOCOL_VERSION}"); + debug!("client protocol: {client_protocol:?}, ours: {CURRENT_PROTOCOL_VERSION}"); let Some(client_protocol_version) = client_protocol else { warn!("the client we're connected to has not specified its protocol version. It's probably running version < 1.1.X, but that's still fine for now. It will become a hard error in 1.2.0"); // note: in +1.2.0 we will have to return a hard error here From ff01fc79e3cda41a4c72416e478816710ee8f6ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 12:19:54 +0000 Subject: [PATCH 087/394] removed duplicate code --- nym-api/src/coconut/tests/mod.rs | 46 -------------------------------- 1 file changed, 46 deletions(-) diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index 9912916a0d..0cdb60a1b5 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -797,52 +797,6 @@ impl super::client::Client for DummyClient { }) } - async fn get_dealer_dealings_status( - &self, - epoch_id: EpochId, - dealer: String, - ) -> Result { - let guard = self.state.lock().unwrap(); - let key_size = guard.dkg_contract.contract_state.key_size; - - let dealer_addr = Addr::unchecked(&dealer); - - let Some(epoch_dealings) = guard.dkg_contract.dealings.get(&epoch_id) else { - return Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: dealer_addr, - all_dealings_fully_submitted: false, - dealing_submission_status: Default::default(), - }); - }; - - let Some(dealer_dealings) = epoch_dealings.get(&dealer) else { - return Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: dealer_addr, - all_dealings_fully_submitted: false, - dealing_submission_status: Default::default(), - }); - }; - - let mut dealing_submission_status: BTreeMap = BTreeMap::new(); - for dealing_index in 0..key_size { - let metadata = dealer_dealings - .get(&dealing_index) - .map(|d| d.metadata.clone()); - dealing_submission_status.insert(dealing_index, metadata.into()); - } - - Ok(DealerDealingsStatusResponse { - epoch_id, - dealer: Addr::unchecked(&dealer), - all_dealings_fully_submitted: dealing_submission_status - .values() - .all(|d| d.fully_submitted), - dealing_submission_status, - }) - } - async fn get_dealing_status( &self, epoch_id: EpochId, From 88a49dfc7e8d9d1167269ebcb4f1c62c616ba968 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 15:26:51 +0000 Subject: [PATCH 088/394] making sure the retrieved credentials haven't expired --- common/bandwidth-controller/src/error.rs | 3 + common/bandwidth-controller/src/lib.rs | 87 ++++++++++++++----- .../20240206120000_add_credential_types.sql | 3 +- .../credential-storage/src/backends/memory.rs | 19 +++- .../credential-storage/src/backends/sqlite.rs | 27 ++++-- .../src/ephemeral_storage.rs | 15 ++-- common/credential-storage/src/models.rs | 1 + .../src/persistent_storage.rs | 15 ++-- common/credential-storage/src/storage.rs | 12 ++- .../src/coconut/bandwidth/freepass.rs | 4 + 10 files changed, 144 insertions(+), 42 deletions(-) diff --git a/common/bandwidth-controller/src/error.rs b/common/bandwidth-controller/src/error.rs index 4adda09b0f..44832aaab4 100644 --- a/common/bandwidth-controller/src/error.rs +++ b/common/bandwidth-controller/src/error.rs @@ -21,6 +21,9 @@ pub enum BandwidthControllerError { #[error("There was a credential storage error - {0}")] CredentialStorageError(Box), + #[error("the credential storage does not contain any usable credentials")] + NoCredentialsAvailable, + // this should really be fully incorporated into the above, but messing with coconut is the last thing I want to do now #[error(transparent)] StorageError(#[from] StorageError), diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index fbfcf41865..31d499dac9 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -3,10 +3,12 @@ use crate::error::BandwidthControllerError; use crate::utils::stored_credential_to_issued_bandwidth; -use log::{error, warn}; +use log::{debug, error, warn}; use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials::coconut::utils::obtain_aggregate_verification_key; +use nym_credentials::IssuedBandwidthCredential; use nym_credentials_interface::VerificationKey; use nym_validator_client::coconut::all_coconut_api_clients; use nym_validator_client::nym_api::EpochId; @@ -33,11 +35,67 @@ pub struct PreparedCredential { pub credential_id: i64, } +pub struct RetrievedCredential { + pub credential: IssuedBandwidthCredential, + pub credential_id: i64, +} + impl BandwidthController { pub fn new(storage: St, client: C) -> Self { BandwidthController { storage, client } } + /// Tries to retrieve one of the stored, unused credentials that hasn't yet expired. + /// It marks any retrieved intermediate credentials as expired. + pub async fn get_next_usable_credential( + &self, + ) -> Result + where + ::StorageError: Send + Sync + 'static, + { + loop { + let Some(maybe_next) = self + .storage + .get_next_unspent_credential() + .await + .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))? + else { + return Err(BandwidthControllerError::NoCredentialsAvailable); + }; + let id = maybe_next.id; + + // try to deserialize it + let valid_credential = match stored_credential_to_issued_bandwidth(maybe_next) { + // check if it has already expired + Ok(credential) => match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(_) => { + debug!("credential {id} is a bandwidth voucher"); + credential + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + debug!("credential {id} is a free pass"); + if freepass_info.expired() { + warn!("the free pass (id: {id}) has already expired! The expiration was set to {}", freepass_info.expiry_date()); + self.storage.mark_expired(id).await.map_err(|err| { + BandwidthControllerError::CredentialStorageError(Box::new(err)) + })?; + continue; + } + credential + } + }, + Err(err) => { + error!("failed to deserialize credential with id {id}: {err}. it may need to be manually removed from the storage"); + return Err(err); + } + }; + return Ok(RetrievedCredential { + credential: valid_credential, + credential_id: id, + }); + } + } + pub fn storage(&self) -> &St { &self.storage } @@ -61,29 +119,16 @@ impl BandwidthController { C: DkgQueryClient + Sync + Send, ::StorageError: Send + Sync + 'static, { - let retrieved_credential = self - .storage - .get_next_unspent_credential() - .await - .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))?; + let retrieved_credential = self.get_next_usable_credential().await?; - let epoch_id = retrieved_credential.epoch_id as EpochId; - let credential_id = retrieved_credential.id; + let epoch_id = retrieved_credential.credential.epoch_id(); + let credential_id = retrieved_credential.credential_id; - let issued_bandwidth = stored_credential_to_issued_bandwidth(retrieved_credential)?; + let verification_key = self.get_aggregate_verification_key(epoch_id).await?; - let verification_key = match self.get_aggregate_verification_key(epoch_id).await { - Ok(key) => key, - Err(err) => { - warn!("failed to obtain master verification key: {err}. Putting the credential back into the database"); - - // TODO: ERROR RECOVERY: - error!("unimplemented: putting the credential back into the database"); - return Err(err); - } - }; - - let spend_request = issued_bandwidth.prepare_for_spending(&verification_key)?; + let spend_request = retrieved_credential + .credential + .prepare_for_spending(&verification_key)?; Ok(PreparedCredential { data: spend_request, diff --git a/common/credential-storage/migrations/20240206120000_add_credential_types.sql b/common/credential-storage/migrations/20240206120000_add_credential_types.sql index 696d6d46a4..dfa7eda2ef 100644 --- a/common/credential-storage/migrations/20240206120000_add_credential_types.sql +++ b/common/credential-storage/migrations/20240206120000_add_credential_types.sql @@ -13,5 +13,6 @@ CREATE TABLE coconut_credentials credential_type TEXT NOT NULL, credential_data BLOB NOT NULL, epoch_id INTEGER NOT NULL, - consumed BOOLEAN NOT NULL + consumed BOOLEAN NOT NULL, + expired BOOLEAN NOT NULL ); \ No newline at end of file diff --git a/common/credential-storage/src/backends/memory.rs b/common/credential-storage/src/backends/memory.rs index 80538337c8..ddf5b7017e 100644 --- a/common/credential-storage/src/backends/memory.rs +++ b/common/credential-storage/src/backends/memory.rs @@ -48,13 +48,18 @@ impl CoconutCredentialManager { credential_type, epoch_id, consumed: false, + expired: false, }) } /// Tries to retrieve one of the stored, unused credentials. pub async fn get_next_unspent_credential(&self) -> Option { let creds = self.inner.read().await; - creds.data.iter().find(|c| !c.consumed).cloned() + creds + .data + .iter() + .find(|c| !c.consumed && !c.expired) + .cloned() } /// Consumes in the database the specified credential. @@ -68,4 +73,16 @@ impl CoconutCredentialManager { cred.consumed = true; } } + + /// Marks the specified credential as expired + /// + /// # Arguments + /// + /// * `id`: Id of the credential to mark as expired. + pub async fn mark_expired(&self, id: i64) { + let mut creds = self.inner.write().await; + if let Some(cred) = creds.data.get_mut(id as usize) { + cred.expired = true; + } + } } diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs index d007c03c16..50465f434d 100644 --- a/common/credential-storage/src/backends/sqlite.rs +++ b/common/credential-storage/src/backends/sqlite.rs @@ -27,8 +27,8 @@ impl CoconutCredentialManager { ) -> Result<(), sqlx::Error> { sqlx::query!( r#" - INSERT INTO coconut_credentials(serialization_revision, credential_type, credential_data, epoch_id, consumed) - VALUES (?, ?, ?, ?, false) + INSERT INTO coconut_credentials(serialization_revision, credential_type, credential_data, epoch_id, consumed, expired) + VALUES (?, ?, ?, ?, false, false) "#, serialization_revision, credential_type, credential_data, epoch_id ).execute(&self.connection_pool).await?; @@ -38,9 +38,11 @@ impl CoconutCredentialManager { pub async fn get_next_unspent_credential( &self, ) -> Result, sqlx::Error> { - sqlx::query_as("SELECT * FROM coconut_credentials WHERE NOT consumed LIMIT 1") - .fetch_optional(&self.connection_pool) - .await + sqlx::query_as( + "SELECT * FROM coconut_credentials WHERE NOT consumed AND NOT expired LIMIT 1", + ) + .fetch_optional(&self.connection_pool) + .await } /// Consumes in the database the specified credential. @@ -57,4 +59,19 @@ impl CoconutCredentialManager { .await?; Ok(()) } + + /// Marks the specified credential as expired + /// + /// # Arguments + /// + /// * `id`: Id of the credential to mark as expired. + pub async fn mark_expired(&self, id: i64) -> Result<(), sqlx::Error> { + sqlx::query!( + "UPDATE coconut_credentials SET expired = TRUE WHERE id = ?", + id + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } } diff --git a/common/credential-storage/src/ephemeral_storage.rs b/common/credential-storage/src/ephemeral_storage.rs index aa6756ac78..5b1b5b23e9 100644 --- a/common/credential-storage/src/ephemeral_storage.rs +++ b/common/credential-storage/src/ephemeral_storage.rs @@ -44,14 +44,11 @@ impl Storage for EphemeralStorage { async fn get_next_unspent_credential( &self, - ) -> Result { - let credential = self + ) -> Result, Self::StorageError> { + Ok(self .coconut_credential_manager .get_next_unspent_credential() - .await - .ok_or(StorageError::NoCredential)?; - - Ok(credential) + .await) } async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { @@ -61,4 +58,10 @@ impl Storage for EphemeralStorage { Ok(()) } + + async fn mark_expired(&self, id: i64) -> Result<(), Self::StorageError> { + self.coconut_credential_manager.mark_expired(id).await; + + Ok(()) + } } diff --git a/common/credential-storage/src/models.rs b/common/credential-storage/src/models.rs index 2695a190ad..5af5a3c089 100644 --- a/common/credential-storage/src/models.rs +++ b/common/credential-storage/src/models.rs @@ -27,6 +27,7 @@ pub struct StoredIssuedCredential { pub epoch_id: u32, pub consumed: bool, + pub expired: bool, } pub struct StorableIssuedCredential<'a> { diff --git a/common/credential-storage/src/persistent_storage.rs b/common/credential-storage/src/persistent_storage.rs index b6772fdf56..8d0961c38d 100644 --- a/common/credential-storage/src/persistent_storage.rs +++ b/common/credential-storage/src/persistent_storage.rs @@ -76,14 +76,11 @@ impl Storage for PersistentStorage { async fn get_next_unspent_credential( &self, - ) -> Result { - let credential = self + ) -> Result, Self::StorageError> { + Ok(self .coconut_credential_manager .get_next_unspent_credential() - .await? - .ok_or(StorageError::NoCredential)?; - - Ok(credential) + .await?) } async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { @@ -93,4 +90,10 @@ impl Storage for PersistentStorage { Ok(()) } + + async fn mark_expired(&self, id: i64) -> Result<(), Self::StorageError> { + self.coconut_credential_manager.mark_expired(id).await?; + + Ok(()) + } } diff --git a/common/credential-storage/src/storage.rs b/common/credential-storage/src/storage.rs index 64fe0d6e82..8f8cb7798e 100644 --- a/common/credential-storage/src/storage.rs +++ b/common/credential-storage/src/storage.rs @@ -14,10 +14,11 @@ pub trait Storage: Send + Sync { bandwidth_credential: StorableIssuedCredential<'a>, ) -> Result<(), Self::StorageError>; - /// Tries to retrieve one of the stored, unused credentials. + /// Tries to retrieve one of the stored, unused credentials, + /// that is also not marked as expired async fn get_next_unspent_credential( &self, - ) -> Result; + ) -> Result, Self::StorageError>; /// Marks as consumed in the database the specified credential. /// @@ -25,4 +26,11 @@ pub trait Storage: Send + Sync { /// /// * `id`: Id of the credential to be consumed. async fn consume_coconut_credential(&self, id: i64) -> Result<(), Self::StorageError>; + + /// Marks the specified credential as expired + /// + /// # Arguments + /// + /// * `id`: Id of the credential to mark as expired. + async fn mark_expired(&self, id: i64) -> Result<(), Self::StorageError>; } diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 1321e59f1d..b90c8b2dee 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -30,6 +30,10 @@ impl<'a> From<&'a FreePassIssuanceData> for FreePassIssuedData { } impl FreePassIssuedData { + pub fn expired(&self) -> bool { + self.expiry_date <= OffsetDateTime::now_utc() + } + pub fn expiry_date(&self) -> OffsetDateTime { self.expiry_date } From d3e30e98f934a50e946926fb2dc5181309d687ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 16:01:29 +0000 Subject: [PATCH 089/394] preventing spending credentials with outdated gateways --- common/client-libs/gateway-client/src/client.rs | 16 +++++++++++++++- common/client-libs/gateway-client/src/error.rs | 3 +++ gateway/gateway-requests/src/lib.rs | 4 +++- 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index a6f0600d82..461e5ae4d0 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -20,7 +20,8 @@ use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressByt use nym_gateway_requests::iv::IV; use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys}; use nym_gateway_requests::{ - BinaryRequest, ClientControlRequest, ServerResponse, CURRENT_PROTOCOL_VERSION, + BinaryRequest, ClientControlRequest, ServerResponse, CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION, + CURRENT_PROTOCOL_VERSION, }; use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; use nym_sphinx::forwarding::packet::MixPacket; @@ -493,6 +494,7 @@ impl GatewayClient { self.check_gateway_protocol(protocol_version)?; self.authenticated = status; self.bandwidth_remaining = bandwidth_remaining; + self.negotiated_protocol = protocol_version; Ok(()) } ServerResponse::Error { message } => Err(GatewayClientError::GatewayError(message)), @@ -579,6 +581,18 @@ impl GatewayClient { return self.try_claim_testnet_bandwidth().await; } + let Some(gateway_protocol) = self.negotiated_protocol else { + return Err(GatewayClientError::OutdatedGatewayCredentialVersion { + negotiated_protocol: None, + }); + }; + + if gateway_protocol < CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION { + return Err(GatewayClientError::OutdatedGatewayCredentialVersion { + negotiated_protocol: Some(gateway_protocol), + }); + } + let prepared_credential = self .bandwidth_controller .as_ref() diff --git a/common/client-libs/gateway-client/src/error.rs b/common/client-libs/gateway-client/src/error.rs index 081ea3f999..4bcaf4cfd1 100644 --- a/common/client-libs/gateway-client/src/error.rs +++ b/common/client-libs/gateway-client/src/error.rs @@ -47,6 +47,9 @@ pub enum GatewayClientError { #[error("Credential could not be serialized")] SerializeCredential, + #[error("can not spend bandwidth credential with the gateway as it's using outdated protocol (version: {negotiated_protocol:?})")] + OutdatedGatewayCredentialVersion { negotiated_protocol: Option }, + #[error("Client is not authenticated")] NotAuthenticated, diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index e9aae85d7f..45bc486322 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -13,13 +13,15 @@ pub mod models; pub mod registration; pub mod types; +pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION; + /// Defines the current version of the communication protocol between gateway and clients. /// It has to be incremented for any breaking change. // history: // 1 - initial release // 2 - changes to client credentials structure pub const INITIAL_PROTOCOL_VERSION: u8 = 1; -pub const CURRENT_PROTOCOL_VERSION: u8 = 2; +pub const CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION: u8 = 2; pub type GatewayMac = HmacOutput; From d62a41b9c1475fdda7246cb1896d564624042b4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 17:09:16 +0000 Subject: [PATCH 090/394] fixed client route used for free pass --- common/client-libs/validator-client/src/nym_api/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index a2ad37e5d8..5cf79d462e 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -397,7 +397,7 @@ pub trait NymApiClientExt: ApiClient { routes::API_VERSION, routes::COCONUT_ROUTES, routes::BANDWIDTH, - routes::COCONUT_FREE_PASS_NONCE, + routes::COCONUT_FREE_PASS, ], NO_PARAMS, request, From 1a8814ccdce5a9eb9fb3f56325ac194b73ec61b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 17:45:39 +0000 Subject: [PATCH 091/394] changed nonces to be random bytes to prevent replay attacks --- .../src/coconut/bandwidth/freepass.rs | 7 ++- .../20240209120000_free_pass_count.sql | 13 +++++ .../20240209120000_free_pass_nonces.sql | 12 ----- .../nym-api-requests/src/coconut/models.rs | 10 ++-- nym-api/src/coconut/api_routes/mod.rs | 31 +++++++----- nym-api/src/coconut/error.rs | 7 ++- nym-api/src/coconut/state.rs | 9 +++- nym-api/src/coconut/storage/manager.rs | 50 ++----------------- nym-api/src/coconut/storage/mod.rs | 12 ++--- 9 files changed, 58 insertions(+), 93 deletions(-) create mode 100644 nym-api/migrations/20240209120000_free_pass_count.sql delete mode 100644 nym-api/migrations/20240209120000_free_pass_nonces.sql diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index b90c8b2dee..5bb971c2cf 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -93,7 +93,7 @@ impl FreePassIssuanceData { pub async fn obtain_free_pass_nonce( &self, client: &nym_validator_client::client::NymApiClient, - ) -> Result { + ) -> Result<[u8; 16], Error> { let server_response = client.free_pass_nonce().await?; Ok(server_response.current_nonce) } @@ -102,12 +102,11 @@ impl FreePassIssuanceData { &self, signing_request: &CredentialSigningData, account_data: &AccountData, - issuer_nonce: u32, + issuer_nonce: [u8; 16], ) -> Result { - let plaintext = issuer_nonce.to_be_bytes(); let nonce_signature = account_data .private_key() - .sign(&plaintext) + .sign(&issuer_nonce) .map_err(|_| Error::Secp256k1SignFailure)?; Ok(FreePassRequest { diff --git a/nym-api/migrations/20240209120000_free_pass_count.sql b/nym-api/migrations/20240209120000_free_pass_count.sql new file mode 100644 index 0000000000..f468e925cb --- /dev/null +++ b/nym-api/migrations/20240209120000_free_pass_count.sql @@ -0,0 +1,13 @@ +/* + * Copyright 2024 - Nym Technologies SA + * SPDX-License-Identifier: Apache-2.0 + */ + +CREATE TABLE issued_freepass +( + id INTEGER PRIMARY KEY CHECK (id = 0), + issued INTEGER NOT NULL +); + +INSERT INTO issued_freepass(id, issued) +VALUES (0, 0); \ No newline at end of file diff --git a/nym-api/migrations/20240209120000_free_pass_nonces.sql b/nym-api/migrations/20240209120000_free_pass_nonces.sql deleted file mode 100644 index 441910036b..0000000000 --- a/nym-api/migrations/20240209120000_free_pass_nonces.sql +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright 2024 - Nym Technologies SA - * SPDX-License-Identifier: Apache-2.0 - */ - -CREATE TABLE issued_freepass -( - id INTEGER PRIMARY KEY CHECK (id = 0), - current_nonce INTEGER NOT NULL -); - -INSERT INTO issued_freepass(id, current_nonce) VALUES (0,0); \ No newline at end of file diff --git a/nym-api/nym-api-requests/src/coconut/models.rs b/nym-api/nym-api-requests/src/coconut/models.rs index aaa980cc5a..50df750a82 100644 --- a/nym-api/nym-api-requests/src/coconut/models.rs +++ b/nym-api/nym-api-requests/src/coconut/models.rs @@ -105,7 +105,7 @@ impl BlindSignRequestBody { #[derive(Debug, Serialize, Deserialize)] pub struct FreePassNonceResponse { - pub current_nonce: u32, + pub current_nonce: [u8; 16], } #[derive(Debug, Serialize, Deserialize)] @@ -147,7 +147,7 @@ pub struct FreePassRequest { // we need to include a nonce here to prevent replay attacks // (and not making the nym-api store the serial numbers of all issued credential) - pub used_nonce: u32, + pub used_nonce: [u8; 16], /// Signature on the nonce /// to prove the possession of the cosmos key/address @@ -160,7 +160,7 @@ impl FreePassRequest { pub fn new( cosmos_pubkey: cosmrs::crypto::PublicKey, inner_sign_request: BlindSignRequest, - used_nonce: u32, + used_nonce: [u8; 16], nonce_signature: cosmrs::crypto::secp256k1::Signature, public_attributes_plain: Vec, ) -> Self { @@ -177,10 +177,6 @@ impl FreePassRequest { self.cosmos_pubkey.into() } - pub fn nonce_plaintext(&self) -> [u8; 4] { - self.used_nonce.to_be_bytes() - } - pub fn public_attributes_hashed(&self) -> Vec { self.public_attributes_plain .iter() diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 013f600897..9b38eaf135 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -23,6 +23,8 @@ use nym_credentials::coconut::bandwidth::{ bandwidth_credential_params, CredentialType, IssuanceBandwidthCredential, }; use nym_validator_client::nyxd::Coin; +use rand::rngs::OsRng; +use rand::RngCore; use rocket::serde::json::Json; use rocket::State as RocketState; use std::ops::Deref; @@ -74,10 +76,12 @@ pub async fn get_current_free_pass_nonce( ) -> Result> { debug!("Received free pass nonce request"); - let current_nonce = state.storage.get_current_freepass_nonce().await?; - debug!("the current expected nonce is {current_nonce}"); + let current_nonce = state.freepass_nonce.read().await; + debug!("the current expected nonce is {current_nonce:?}"); - Ok(Json(FreePassNonceResponse { current_nonce })) + Ok(Json(FreePassNonceResponse { + current_nonce: *current_nonce, + })) } #[post("/free-pass", data = "")] @@ -117,12 +121,13 @@ pub async fn post_free_pass( }); } - let current_nonce = state.storage.get_current_freepass_nonce().await?; - debug!("the current expected nonce is {current_nonce}"); + // get the write lock on the nonce to block other requests (since we don't need concurrency and nym is the only one getting them) + let mut current_nonce = state.freepass_nonce.write().await; + debug!("the current expected nonce is {current_nonce:?}"); - if current_nonce != freepass_request_body.used_nonce { + if *current_nonce != freepass_request_body.used_nonce { return Err(CoconutError::InvalidNonce { - current: current_nonce, + current: *current_nonce, received: freepass_request_body.used_nonce, }); } @@ -147,7 +152,7 @@ pub async fn post_free_pass( // make sure the signature actually verifies secp256k1_pubkey .verify( - &freepass_request_body.nonce_plaintext(), + &freepass_request_body.used_nonce, &freepass_request_body.nonce_signature, ) .map_err(|_| CoconutError::FreePassSignatureVerificationFailure)?; @@ -157,11 +162,11 @@ pub async fn post_free_pass( let blinded_signature = blind_sign(freepass_request_body.deref(), signing_key.keys.secret_key())?; - // update the nonce in storage (and also check if a parallel request hasn't updated it; if so we return an error. no race conditions allowed) - state - .storage - .update_and_validate_freepass_nonce(current_nonce + 1) - .await?; + // update the number of issued free passes + state.storage.increment_issued_freepasses().await?; + + // update the nonce + OsRng.fill_bytes(current_nonce.as_mut_slice()); // finally return the credential to the client Ok(Json(BlindedSignatureResponse { blinded_signature })) diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index d5f6ac81d6..593e78a016 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -46,8 +46,11 @@ pub enum CoconutError { #[error("failed to verify signature on the provided free pass request")] FreePassSignatureVerificationFailure, - #[error("the provided signing nonce is invalid. the current value is: {current}. got {received} instead")] - InvalidNonce { current: u32, received: u32 }, + #[error("the provided signing nonce is invalid. the current value is: {current:?}. got {received:?} instead")] + InvalidNonce { + current: [u8; 16], + received: [u8; 16], + }, #[error("only secp256k1 keys are supported for free pass issuance")] UnsupportedNonSecp256k1Key, diff --git a/nym-api/src/coconut/state.rs b/nym-api/src/coconut/state.rs index c85c77575a..3e04110888 100644 --- a/nym-api/src/coconut/state.rs +++ b/nym-api/src/coconut/state.rs @@ -14,8 +14,10 @@ use nym_coconut::{BlindedSignature, VerificationKey}; use nym_coconut_dkg_common::types::EpochId; use nym_crypto::asymmetric::identity; use nym_validator_client::nyxd::{AccountId, Hash, TxResponse}; +use rand::rngs::OsRng; +use rand::RngCore; use std::sync::Arc; -use tokio::sync::OnceCell; +use tokio::sync::{OnceCell, RwLock}; pub use nym_credentials::coconut::bandwidth::bandwidth_credential_params; @@ -27,6 +29,7 @@ pub struct State { pub(crate) identity_keypair: identity::KeyPair, pub(crate) comm_channel: Arc, pub(crate) storage: NymApiStorage, + pub(crate) freepass_nonce: Arc>, } impl State { @@ -45,6 +48,9 @@ impl State { let client = Arc::new(client); let comm_channel = Arc::new(comm_channel); + let mut nonce = [0u8; 16]; + OsRng.fill_bytes(&mut nonce); + Self { client, bandwidth_contract_admin: OnceCell::new(), @@ -53,6 +59,7 @@ impl State { identity_keypair, comm_channel, storage, + freepass_nonce: Arc::new(RwLock::new(nonce)), } } diff --git a/nym-api/src/coconut/storage/manager.rs b/nym-api/src/coconut/storage/manager.rs index 17816bebd8..313a2db047 100644 --- a/nym-api/src/coconut/storage/manager.rs +++ b/nym-api/src/coconut/storage/manager.rs @@ -122,16 +122,7 @@ pub trait CoconutStorageManagerExt { limit: u32, ) -> Result, sqlx::Error>; - /// Attempts to retrieve the current value of the freepass nonce. - async fn get_current_freepass_nonce(&self) -> Result; - - /// Attempt to update the currently stored nonce to the provided value whilst ensuring - /// it's strictly equal the current value plus 1 - /// - /// # Arguments - /// - /// * `new`: the new value of the free pass nonce - async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error>; + async fn increment_issued_freepasses(&self) -> Result<(), sqlx::Error>; } #[async_trait] @@ -391,42 +382,11 @@ impl CoconutStorageManagerExt for StorageManager { .await } - /// Attempts to retrieve the current value of the freepass nonce. - async fn get_current_freepass_nonce(&self) -> Result { - sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass") - .fetch_one(&self.connection_pool) - .await - .map(|row| row.current_nonce) - } - - /// Attempt to update the currently stored nonce to the provided value whilst ensuring - /// it's strictly equal the current value plus 1 - /// - /// # Arguments - /// - /// * `new`: the new value of the free pass nonce - async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), sqlx::Error> { - let mut tx = self.connection_pool.begin().await?; - - let currently_stored = - sqlx::query!("SELECT current_nonce as 'current_nonce: u32' FROM issued_freepass") - .fetch_one(&mut tx) - .await? - .current_nonce; - - if currently_stored + 1 != new { - // this is not the best error but I really don't want to be creating a new enum - return Err(sqlx::Error::Decode(Box::new(UnexpectedNonce { - current: currently_stored, - got: new, - }))); - } - - sqlx::query!("UPDATE issued_freepass SET current_nonce = ?", new) - .execute(&mut tx) + async fn increment_issued_freepasses(&self) -> Result<(), sqlx::Error> { + sqlx::query!("UPDATE issued_freepass SET issued = issued + 1",) + .execute(&self.connection_pool) .await?; - - tx.commit().await + Ok(()) } } diff --git a/nym-api/src/coconut/storage/mod.rs b/nym-api/src/coconut/storage/mod.rs index f77703cea8..45cecf1f23 100644 --- a/nym-api/src/coconut/storage/mod.rs +++ b/nym-api/src/coconut/storage/mod.rs @@ -64,9 +64,7 @@ pub trait CoconutStorageExt { pagination: Pagination, ) -> Result, NymApiStorageError>; - async fn get_current_freepass_nonce(&self) -> Result; - - async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError>; + async fn increment_issued_freepasses(&self) -> Result<(), NymApiStorageError>; } #[async_trait] @@ -168,11 +166,7 @@ impl CoconutStorageExt for NymApiStorage { .await?) } - async fn get_current_freepass_nonce(&self) -> Result { - Ok(self.manager.get_current_freepass_nonce().await?) - } - - async fn update_and_validate_freepass_nonce(&self, new: u32) -> Result<(), NymApiStorageError> { - Ok(self.manager.update_and_validate_freepass_nonce(new).await?) + async fn increment_issued_freepasses(&self) -> Result<(), NymApiStorageError> { + Ok(self.manager.increment_issued_freepasses().await?) } } From 04373589b1c887374cdf1ec0457fd2e5ec165a64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 17:51:19 +0000 Subject: [PATCH 092/394] added import-credential command to network requester --- Cargo.lock | 3 + .../network-requester/Cargo.toml | 4 + .../src/cli/import_credential.rs | 102 ++++++++++++++++++ .../network-requester/src/cli/mod.rs | 5 + .../network-requester/src/error.rs | 20 ++++ 5 files changed, 134 insertions(+) create mode 100644 service-providers/network-requester/src/cli/import_credential.rs diff --git a/Cargo.lock b/Cargo.lock index 55105ed993..6f88f34cb4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5861,6 +5861,7 @@ dependencies = [ "nym-client-websocket-requests", "nym-config", "nym-credential-storage", + "nym-credentials", "nym-crypto", "nym-exit-policy", "nym-network-defaults", @@ -5884,9 +5885,11 @@ dependencies = [ "tap", "tempfile", "thiserror", + "time", "tokio", "tokio-tungstenite", "url", + "zeroize", ] [[package]] diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index b2486db390..c0f75f1670 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -38,6 +38,8 @@ thiserror = { workspace = true } tokio = { workspace = true, features = [ "net", "rt-multi-thread", "macros" ] } tokio-tungstenite = { workspace = true } url = { workspace = true } +time = "0.3.30" +zeroize = "1.6.0" # internal async-file-watcher = { path = "../../common/async-file-watcher" } @@ -45,6 +47,7 @@ nym-bin-common = { path = "../../common/bin-common", features = ["output_format" nym-client-core = { path = "../../common/client-core", features = ["cli"] } nym-client-websocket-requests = { path = "../../clients/native/websocket-requests" } nym-config = { path = "../../common/config" } +nym-credentials = { path = "../../common/credentials" } nym-credential-storage = { path = "../../common/credential-storage" } nym-crypto = { path = "../../common/crypto" } nym-network-defaults = { path = "../../common/network-defaults" } @@ -59,6 +62,7 @@ nym-task = { path = "../../common/task" } nym-types = { path = "../../common/types" } nym-exit-policy = { path = "../../common/exit-policy", features = ["client"] } + [dev-dependencies] tempfile = "3.5.0" anyhow = { workspace = true } diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs new file mode 100644 index 0000000000..5f5c599c3c --- /dev/null +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -0,0 +1,102 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::try_load_current_config; +use crate::error::NetworkRequesterError; +use clap::ArgGroup; +use log::{error, info}; +use nym_credential_storage::models::StorableIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; +use nym_credentials::IssuedBandwidthCredential; +use std::fs; +use std::path::PathBuf; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { + bs58::decode(raw).into_vec() +} + +#[derive(clap::Args)] +#[clap(group(ArgGroup::new("cred_data").required(true)))] +pub(crate) struct Args { + /// Id of client that is going to import the credential + #[clap(long)] + pub id: String, + + /// Explicitly provide the encoded credential data (as base58) + #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] + pub(crate) credential_data: Option>, + + /// Specifies the path to file containing binary credential data + #[clap(long, group = "cred_data")] + pub(crate) credential_path: Option, + + // currently hidden as there exists only a single serialization standard + #[clap(long, hide = true, default_value_t = 1)] + pub(crate) version: u8, +} + +pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { + let config = try_load_current_config(&args.id)?; + + let credentials_store = nym_credential_storage::initialise_persistent_storage( + &config.storage_paths.common_paths.credentials_database, + ) + .await; + + let raw_credential = match args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + fs::read(args.credential_path.unwrap())? + } + }; + let raw_credential = Zeroizing::new(raw_credential); + + // we're unpacking the data in order to make sure it's valid + // and to extract relevant metadata for storage purposes + let credential = match args.version { + 1 => Zeroizing::new( + IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { + NetworkRequesterError::CredentialDeserializationFailure { + storage_revision: 1, + source, + } + })?, + ), + other => panic!("unknown credential serialization version {other}"), + }; + + info!("importing {}", credential.typ()); + match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { + info!("with value of {}", voucher_info.value()) + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + info!("with expiry at {}", freepass_info.expiry_date()); + if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + error!("the free pass has already expired!"); + + // technically we can import it, but the gateway will just reject it so what's the point + return Err(NetworkRequesterError::ExpiredCredentialImport { + expiration: freepass_info.expiry_date(), + }); + } + } + } + + let storable = StorableIssuedCredential { + serialization_revision: args.version, + credential_data: &raw_credential, + credential_type: credential.typ().to_string(), + epoch_id: credential + .epoch_id() + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; + + credentials_store.insert_issued_credential(storable).await?; + Ok(()) +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 874f191134..cd5e84071e 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -23,6 +23,7 @@ use nym_config::OptionalSet; use std::sync::OnceLock; mod build_info; +mod import_credential; mod init; mod run; mod sign; @@ -60,6 +61,9 @@ pub(crate) enum Commands { /// Sign to prove ownership of this network requester Sign(sign::Sign), + /// Import a pre-generated credential + ImportCredential(import_credential::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -154,6 +158,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(&m).await?, Commands::Sign(m) => sign::execute(&m).await?, + Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index 47d7b12bbc..ce14ed7cf9 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -2,9 +2,11 @@ // SPDX-License-Identifier: GPL-3.0-only pub use nym_client_core::error::ClientCoreError; +use nym_credential_storage::error::StorageError; use nym_exit_policy::policy::PolicyError; use nym_socks5_requests::{RemoteAddress, Socks5RequestError}; use std::net::SocketAddr; +use time::OffsetDateTime; #[derive(thiserror::Error, Debug)] pub enum NetworkRequesterError { @@ -67,4 +69,22 @@ pub enum NetworkRequesterError { #[error("can't setup an exit policy without any upstream urls")] NoUpstreamExitPolicy, + + #[error("failed to store credential: {source}")] + CredentialStorageFailure { + #[from] + source: StorageError, + }, + + #[error( + "failed to deserialize provided credential using revision {storage_revision}: {source}" + )] + CredentialDeserializationFailure { + storage_revision: u8, + #[source] + source: nym_credentials::error::Error, + }, + + #[error("attempted to import an expired credential (it expired on {expiration})")] + ExpiredCredentialImport { expiration: OffsetDateTime }, } From 3ec2ea904f9b040c24420e1a3e2fd66d19074465 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 17:55:36 +0000 Subject: [PATCH 093/394] fixed local expiration check --- clients/native/src/commands/import_credential.rs | 2 +- clients/socks5/src/commands/import_credential.rs | 2 +- common/commands/src/coconut/import_credential.rs | 2 +- .../network-requester/src/cli/import_credential.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 9d156d32ff..11916ced72 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -76,7 +76,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { } BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + if freepass_info.expired() { error!("the free pass has already expired!"); // technically we can import it, but the gateway will just reject it so what's the point diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index b4c050b815..a4306c1a09 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -76,7 +76,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { } BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + if freepass_info.expired() { error!("the free pass has already expired!"); // technically we can import it, but the gateway will just reject it so what's the point diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs index 3d90e02c42..6d5612ac53 100644 --- a/common/commands/src/coconut/import_credential.rs +++ b/common/commands/src/coconut/import_credential.rs @@ -80,7 +80,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> { } BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + if freepass_info.expired() { error!("the free pass has already expired!"); // technically we can, but the gateway will just reject it so what's the point diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index 5f5c599c3c..a2d71d3c92 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -76,7 +76,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { } BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expiry_date() > OffsetDateTime::now_utc() { + if freepass_info.expired() { error!("the free pass has already expired!"); // technically we can import it, but the gateway will just reject it so what's the point From f96f74f2f118c902930ccdb6f854acb9d4cc8d41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Mon, 19 Feb 2024 18:27:16 +0000 Subject: [PATCH 094/394] removed unused imports --- clients/native/src/commands/import_credential.rs | 1 - clients/socks5/src/commands/import_credential.rs | 1 - common/commands/src/coconut/import_credential.rs | 1 - service-providers/network-requester/src/cli/import_credential.rs | 1 - 4 files changed, 4 deletions(-) diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 11916ced72..de211aef01 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -11,7 +11,6 @@ use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVa use nym_credentials::IssuedBandwidthCredential; use std::fs; use std::path::PathBuf; -use time::OffsetDateTime; use zeroize::Zeroizing; fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index a4306c1a09..2ce3457015 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -11,7 +11,6 @@ use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVa use nym_credentials::IssuedBandwidthCredential; use std::fs; use std::path::PathBuf; -use time::OffsetDateTime; use zeroize::Zeroizing; fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs index 6d5612ac53..337bf9125b 100644 --- a/common/commands/src/coconut/import_credential.rs +++ b/common/commands/src/coconut/import_credential.rs @@ -13,7 +13,6 @@ use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVa use nym_credentials::IssuedBandwidthCredential; use std::fs; use std::path::PathBuf; -use time::OffsetDateTime; use zeroize::Zeroizing; fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index a2d71d3c92..6d0b8fffb1 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -11,7 +11,6 @@ use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVa use nym_credentials::IssuedBandwidthCredential; use std::fs; use std::path::PathBuf; -use time::OffsetDateTime; use zeroize::Zeroizing; fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result> { From cae97663c14b64873ec449ca98717aba650e84ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 20 Feb 2024 11:03:44 +0000 Subject: [PATCH 095/394] additional gateway logs --- .../src/coconut/bandwidth/freepass.rs | 2 +- .../src/coconut/bandwidth/issued.rs | 2 +- .../src/coconut/bandwidth/voucher.rs | 2 +- gateway/src/node/client_handling/bandwidth.rs | 1 + .../connection_handler/authenticated.rs | 34 +++++++++++++++++-- .../websocket/connection_handler/coconut.rs | 12 +++++++ 6 files changed, 48 insertions(+), 5 deletions(-) diff --git a/common/credentials/src/coconut/bandwidth/freepass.rs b/common/credentials/src/coconut/bandwidth/freepass.rs index 5bb971c2cf..57893b259d 100644 --- a/common/credentials/src/coconut/bandwidth/freepass.rs +++ b/common/credentials/src/coconut/bandwidth/freepass.rs @@ -14,7 +14,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub const MAX_FREE_PASS_VALIDITY: Duration = Duration::WEEK; // 1 week -#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +#[derive(Debug, Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct FreePassIssuedData { /// the plain validity value of this credential expressed as unix timestamp #[zeroize(skip)] diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index b9d3ee02b3..486fd7c7ee 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -20,7 +20,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub const CURRENT_SERIALIZATION_REVISION: u8 = 1; -#[derive(Zeroize, Serialize, Deserialize)] +#[derive(Debug, Zeroize, Serialize, Deserialize)] pub enum BandwidthCredentialIssuedDataVariant { Voucher(BandwidthVoucherIssuedData), FreePass(FreePassIssuedData), diff --git a/common/credentials/src/coconut/bandwidth/voucher.rs b/common/credentials/src/coconut/bandwidth/voucher.rs index f61f5c3544..acce944fae 100644 --- a/common/credentials/src/coconut/bandwidth/voucher.rs +++ b/common/credentials/src/coconut/bandwidth/voucher.rs @@ -13,7 +13,7 @@ use nym_validator_client::nyxd::{Coin, Hash}; use serde::{Deserialize, Serialize}; use zeroize::{Zeroize, ZeroizeOnDrop}; -#[derive(Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +#[derive(Debug, Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] pub struct BandwidthVoucherIssuedData { /// the plain value (e.g., bandwidth) encoded in this voucher // note: for legacy reasons we're only using the value of the coin and ignoring the denom diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index 47c6447a7a..10d1f50b3c 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -36,6 +36,7 @@ pub enum BandwidthError { }, } +#[derive(Debug, Copy, Clone)] pub struct Bandwidth { value: u64, } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 1c22df93b7..6c9456224b 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -21,7 +21,7 @@ use futures::{ }; use log::*; use nym_credentials::coconut::bandwidth::{bandwidth_credential_params, CredentialType}; -use nym_credentials_interface::CoconutError; +use nym_credentials_interface::{Base58, CoconutError}; use nym_gateway_requests::models::CredentialSpendingRequest; use nym_gateway_requests::{ iv::{IVConversionError, IV}, @@ -227,15 +227,23 @@ where ) -> Result { // check if the credential hasn't been spent before let serial_number = credential.data.blinded_serial_number(); + trace!("processing credential {}", serial_number.to_bs58()); + let already_spent = self .inner .storage .contains_credential(&serial_number) .await?; if already_spent { + trace!("the credential has already been spent before"); return Err(RequestHandlingError::BandwidthCredentialAlreadySpent); } + trace!( + "attempting to obtain aggregate verification key for epoch {}", + credential.data.epoch_id + ); + let aggregated_verification_key = self .inner .coconut_verifier @@ -243,26 +251,32 @@ where .await?; if !credential.data.validate_type_attribute() { + trace!("mismatch in the type attribute"); return Err(RequestHandlingError::InvalidTypeAttribute); } let Some(bandwidth_attribute) = credential.data.get_bandwidth_attribute() else { + trace!("missing bandwidth attribute"); return Err(RequestHandlingError::MissingBandwidthAttribute); }; // this will extract token amounts out of bandwidth vouchers and validate expiry of free passes let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; + trace!("embedded bandwidth: {bandwidth:?}"); + // locally verify the credential let params = bandwidth_credential_params(); if !credential.data.verify(params, &aggregated_verification_key) { + trace!("the credential did not verify correctly"); return Err(RequestHandlingError::InvalidBandwidthCredential( - String::from("credential failed to verify on gateway"), + String::from("local credential verification has failed"), )); } let was_freepass = match credential.data.typ { CredentialType::Voucher => { + trace!("the credential is a bandwidth voucher. attempting to release the funds"); let api_clients = self .inner .coconut_verifier @@ -291,11 +305,13 @@ where // mark the credential as spent // TODO: technically this should be done under a storage transaction so that if we experience any // failures later on, it'd get reverted + trace!("storing serial number information"); self.inner .storage .insert_spent_credential(serial_number, was_freepass, self.client.address) .await?; + trace!("increasing client bandwidth"); self.increase_bandwidth(bandwidth).await?; let available_total = self.get_available_bandwidth().await?; @@ -307,6 +323,8 @@ where enc_credential: Vec, iv: Vec, ) -> Result { + debug!("handling v1 bandwidth request"); + let iv = IV::try_from_bytes(&iv)?; let credential = ClientControlRequest::try_from_enc_coconut_bandwidth_credential_v1( enc_credential, @@ -329,6 +347,8 @@ where enc_credential: Vec, iv: Vec, ) -> Result { + debug!("handling v2 bandwidth request"); + let iv = IV::try_from_bytes(&iv)?; let credential = ClientControlRequest::try_from_enc_coconut_bandwidth_credential_v2( enc_credential, @@ -342,6 +362,8 @@ where async fn handle_claim_testnet_bandwidth( &mut self, ) -> Result { + debug!("handling testnet bandwidth request"); + if self.inner.only_coconut_credentials { return Err(RequestHandlingError::OnlyCoconutCredentials); } @@ -389,6 +411,7 @@ where /// /// * `bin_msg`: raw message to handle. async fn handle_binary(&self, bin_msg: Vec) -> Message { + trace!("binary request"); // this function decrypts the request and checks the MAC match BinaryRequest::try_from_encrypted_tagged_bytes(bin_msg, &self.client.shared_keys) { Err(e) => { @@ -413,6 +436,7 @@ where /// /// * `raw_request`: raw message to handle. async fn handle_text(&mut self, raw_request: String) -> Message { + trace!("text request"); match ClientControlRequest::try_from(raw_request) { Err(e) => RequestHandlingError::InvalidTextRequest(e).into_error_message(), Ok(request) => match request { @@ -465,6 +489,12 @@ where /// /// * `raw_request`: raw received websocket message. async fn handle_request(&mut self, raw_request: Message) -> Option { + // TODO: this should be added via tracing + debug!( + "handling request from {}", + self.client.address.as_base58_string() + ); + // apparently tungstenite auto-handles ping/pong/close messages so for now let's ignore // them and let's test that claim. If that's not the case, just copy code from // desktop nym-client websocket as I've manually handled everything there diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index d013f8fda7..d075e01bb8 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -112,10 +112,15 @@ impl CoconutVerifier { // the key was already in the map if let Ok(mapped) = RwLockReadGuard::try_map(guard, |clients| clients.get(&epoch_id)) { + trace!("we already had cached api clients for epoch {epoch_id}"); return Ok(mapped); } let api_clients = self.query_api_clients(epoch_id).await?; + trace!( + "obtained {} api clients for epoch {epoch_id} from the contract", + api_clients.len() + ); // EDGE CASE: // if this epoch is from the past, we can't query for its threshold @@ -131,6 +136,7 @@ impl CoconutVerifier { let mut guard = self.api_clients.write().await; guard.insert(epoch_id, api_clients); let guard = guard.downgrade(); + trace!("stored api clients for epoch {epoch_id}"); // SAFETY: // we just inserted the entry into the map while NEVER dropping the lock (only downgraded it) @@ -149,10 +155,15 @@ impl CoconutVerifier { // the key was already in the map if let Ok(mapped) = RwLockReadGuard::try_map(guard, |keys| keys.get(&epoch_id)) { + trace!("we already had cached verification key for epoch {epoch_id}"); return Ok(mapped); } let api_clients = self.api_clients(epoch_id).await?; + trace!( + "attempting to obtain verification key from {} api clients", + api_clients.len() + ); let aggregated_verification_key = nym_credentials::obtain_aggregate_verification_key(&api_clients)?; @@ -160,6 +171,7 @@ impl CoconutVerifier { let mut guard = self.master_keys.write().await; guard.insert(epoch_id, aggregated_verification_key); let guard = guard.downgrade(); + trace!("stored aggregated verification key for epoch {epoch_id}"); // SAFETY: // we just inserted the entry into the map while NEVER dropping the lock (only downgraded it) From 1d481db1792b27ba66be1102e681149a1df2cd1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= Date: Tue, 20 Feb 2024 11:07:04 +0000 Subject: [PATCH 096/394] additional log for dkg address --- .../src/nyxd/contract_traits/dkg_query_client.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs index dcf6590457..c85f85c399 100644 --- a/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/contract_traits/dkg_query_client.rs @@ -8,6 +8,7 @@ use crate::nyxd::CosmWasmClient; use async_trait::async_trait; use cosmrs::AccountId; use cosmwasm_std::Addr; +use log::trace; use nym_coconut_dkg_common::types::{ChunkIndex, NodeIndex, StateAdvanceResponse}; use serde::Deserialize; @@ -230,6 +231,7 @@ where let dkg_contract_address = &self .dkg_contract_address() .ok_or_else(|| NyxdError::unavailable_contract_address("dkg contract"))?; + trace!("using the following dkg contract: {dkg_contract_address}"); self.query_contract_smart(dkg_contract_address, &query) .await } From 73632a0ae7889c45d80977cb33aef034f3c8b0a9 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Tue, 20 Feb 2024 12:08:36 +0000 Subject: [PATCH 097/394] [DOC]: Update nym-vpn commands (#4386) * update nym-vpn commands * update testing flow * bumped up scripts and version url to 0.0.4 * correct cli script version -> 0.0.2 * update extract commands * update extract commands * update gui and cli auto scripts * correct curl url * minor fixes to formatting * add final bash script for desktop * syntax change * commenting mac manual steps * comment off mac manual steps from summary * Update SUMMARY.md * Update troubleshooting.md --------- Co-authored-by: mfahampshire --- documentation/dev-portal/book.toml | 2 +- documentation/dev-portal/src/SUMMARY.md | 1 - .../dev-portal/src/nymvpn/cli-linux.md | 17 ++++-- .../dev-portal/src/nymvpn/cli-mac.md | 20 ++++--- documentation/dev-portal/src/nymvpn/cli.md | 9 ++-- .../dev-portal/src/nymvpn/gui-linux.md | 54 ++++++++++++++++--- .../dev-portal/src/nymvpn/gui-mac.md | 18 ++++--- documentation/dev-portal/src/nymvpn/gui.md | 18 ++++--- .../dev-portal/src/nymvpn/testing.md | 17 +++--- .../dev-portal/src/nymvpn/troubleshooting.md | 22 ++++++-- 10 files changed, 125 insertions(+), 53 deletions(-) diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 6c944bd37d..3b6b9f077d 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -31,7 +31,7 @@ assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install` minimum_rust_version = "1.66" wallet_release_version = "1.2.8" # nym-vpn related variables -nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.3" +nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.4" nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" [preprocessor.last-changed] diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index 3a14919b99..e98304dea0 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -21,7 +21,6 @@ - [NymVPN alpha](nymvpn/intro.md) - [GUI](nymvpn/gui.md) - [Linux](nymvpn/gui-linux.md) - - [MacOS](nymvpn/gui-mac.md) - [CLI](nymvpn/cli.md) - [Linux](nymvpn/cli-linux.md) - [MacOS](nymvpn/cli-mac.md) diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index 614522950f..eb08043535 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -14,11 +14,17 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes echo "" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_0.1.0_ubuntu-22.04_amd64.zip" | shasum -a 256 -c +# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_0.1.0_ubuntu-22.04_amd64.zip" | shasum -a 256 -c ``` -3. Extract files with `unzip` command or manually as you are used to -4. Make executable by running: +1. Extract files: ```sh +tar -xvf +# for example +# tar -xvf nym-vpn-cli_0.0.2_ubuntu-22.04_x86_64.tar.gz +``` +2. Make executable by running: +```sh +# possibly you may have to cd into a sub-directory chmod u+x ./nym-vpn-cli ``` 5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: @@ -54,7 +60,7 @@ sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit ./nym-vpn-cli --help ``` ~~~admonish example collapsible=true title="Console output" -``` +```sh Usage: nym-vpn-cli [OPTIONS] Options: @@ -88,11 +94,12 @@ Options: Enable two-hop mixnet traffic. This means that traffic jumps directly from entry gateway to exit gateway --enable-poisson-rate Enable Poisson process rate limiting of outbound traffic + --disable-background-cover-traffic + Disable constant rate background loop cover traffic -h, --help Print help -V, --version Print version - ``` ~~~ diff --git a/documentation/dev-portal/src/nymvpn/cli-mac.md b/documentation/dev-portal/src/nymvpn/cli-mac.md index 470941070a..a4093168db 100644 --- a/documentation/dev-portal/src/nymvpn/cli-mac.md +++ b/documentation/dev-portal/src/nymvpn/cli-mac.md @@ -14,14 +14,20 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes echo "" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_0.1.0_macos_x86_64.zip" | shasum -a 256 -c +# echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_0.1.0_macos_x86_64.zip" | shasum -a 256 -c ``` -5. Extract files with `unzip` command or manually as you are used to -6. Make executable by running: +3. Extract files: ```sh +tar -xvf +# for example +# tar -xvf nym-vpn-cli_0.0.2_macos_aarch64.tar.gz +``` +4. Make executable by running: +```sh +# possibly you may have to cd into a sub-directory chmod u+x ./nym-vpn-cli ``` -7. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: +5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: ```sh curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o sandbox.env ``` @@ -32,7 +38,6 @@ curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary. - 1. Go to [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha) to get the entire command with all the needed arguments' values and your wireguard private key for testing purposes 2. Run it as root with `sudo` - the command will look like this with specified arguments: ```sh @@ -55,7 +60,7 @@ sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit ./nym-vpn-cli --help ``` ~~~admonish example collapsible=true title="Console output" -``` +```sh Usage: nym-vpn-cli [OPTIONS] Options: @@ -89,11 +94,12 @@ Options: Enable two-hop mixnet traffic. This means that traffic jumps directly from entry gateway to exit gateway --enable-poisson-rate Enable Poisson process rate limiting of outbound traffic + --disable-background-cover-traffic + Disable constant rate background loop cover traffic -h, --help Print help -V, --version Print version - ``` ~~~ diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index e2d96b6a5d..ea0a7f0e9a 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -12,11 +12,11 @@ Follow the simple [automated script](#automated-script-for-cli-installation) bel ## Automated Script for CLI Installation -We wrote a [script](https://gist.github.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: +We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8fb31) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: 1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/2a8b703655549f2e515ef1960b5f6dc54adc02fa/execute-nym-vpn-cli-binary.sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/0cbcdd18f7ee94f559692b936061248ebbbf2773/execute-nym-vpn-cli-binary.sh ``` 2. Make the script executable @@ -24,9 +24,9 @@ curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tomm chmod u+x execute-nym-vpn-cli-binary.sh ``` -3. Start the script as root, turn off any VPN and run +3. Start the script, turn off any VPN and run ```sh -sudo ./execute-nym-vpn-cli-binary.sh +sudo -E ./execute-nym-vpn-cli-binary.sh ``` 4. Follow the prompts in the program @@ -43,4 +43,3 @@ sudo ./execute-nym-vpn-cli-binary.sh To run `nym-vpn-cli` again, reconnect your wifi, move to the directory of your CLI binary `cd ~/nym-vpn-cli-dir` and follow the guide for [Linux](cli-linux.md#run-nymvpn) or [MacOS](cli-mac.md#run-nymvpn). If you find it too difficult, just run this script again - like in step \#3 above. In case of errors check out the [troubleshooting](troubleshooting.md) section. - diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 4e79e90ebb..01c2b0438d 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -1,4 +1,4 @@ -# NymVPN alpha GUI: Guide for GNU/Linux +# NymVPN alpha - Desktop: Guide for GNU/Linux
@@ -18,9 +18,52 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes echo "" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -echo "a5f91f20d587975e30b6a75d3a9e195234cf1269eac278139a5b9c39b039e807 nym-vpn-desktop_0.0.3_ubuntu-22.04_x86_64.zip" | shasum -a 256 -c +# echo "a5f91f20d587975e30b6a75d3a9e195234cf1269eac278139a5b9c39b039e807 nym-vpn-desktop_0.0.3_ubuntu-22.04_x86_64.zip" | shasum -a 256 -c ``` -3. Extract files with `unzip` command or manually as you are used to +3. Extract files: +```sh +tar -xvf +# for example +# tar -xvf nym-vpn-desktop_0.0.4_ubuntu-22.04_x86_64.tar.gz +``` +2. Make executable by running: +```sh +# possibly you may have to cd into a sub-directory +chmod u+x +``` +5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: +```sh +curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env +``` + +## Run NymVPN + +**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. + +Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary. + +1. Go to [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha) to get the entire command with all the needed arguments' values and your wireguard private key for testing purposes +2. Run it as root with `sudo` - the command will look like this with specified arguments: +```sh +sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit-router-address --enable-wireguard --private-key --wg-ip +``` +3. To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) and pick one +4. See all possibilities in [command explanation](#cli-commands-and-options) section below + +In case of errors, see [troubleshooting section](troubleshooting.md). + +### CLI Commands and Options + +The basic syntax of `nym-vpn-cli` is: +```sh +sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit-router-address --enable-wireguard --private-key --wg-ip +``` +* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) +* To see all possibilities run with `--help` flag: +```sh +./nym-vpn-cli --help +``` + 4. If you prefer to run `.AppImage` make executable by running: ```sh chmod u+x ./appimage/nym-vpn_0.0.2_amd64.AppImage @@ -49,9 +92,6 @@ curl -o $HOME/.config/nym-vpn/sandbox.env -L https://raw.githubusercontent.com/n ```toml # change to your username env_config_file = "/home//.config/nym-vpn/sandbox.env" -entry_node_location = "DE" # two letters country code -# You can choose different entry by entering one of the following two letter country codes: -# DE, UK, FR, IE ``` ## Run NymVPN @@ -64,7 +104,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn_0.0.2_amd64.AppImage +sudo -E ./nym-vpn_0.033_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index f60b2af416..ba74a23f41 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -1,4 +1,4 @@ -# NymVPN alpha GUI: Guide for Mac OS +# NymVPN alpha - Desktop: Guide for Mac OS ```admonish info NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. @@ -20,9 +20,14 @@ mkdir -p "$HOME/nym-vpn-latest" echo "" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c +# echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c +``` +4. Extract files: +```sh +tar -xvf +# for example +# tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz ``` -4. Extract files with `unzip` command or manually as you are used to 5. Move to the application directory and make executable ```sh cd "macos/nym-vpn.app/Contents/MacOS" @@ -39,9 +44,6 @@ mv nym-vpn "$HOME/nym-vpn-latest" 7. Create the configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` ```toml env_config_file = ".env" -entry_node_location = "DE" # two letters country code -# You can choose different entry by entering one of the following two letter country codes: -# DE, UK, FR, IE ``` 8. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` ```sh @@ -51,9 +53,9 @@ curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" **For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. -Open terminal in your `~/nym-vpn-latest` directory and run: +Run: ```sh -sudo ./nym-vpn +sudo -E $HOME/nym-vpn-latest/nym-vpn ``` In case of errors check out the [troubleshooting](troubleshooting.html#installing-gui-on-macos-not-working) section. diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index 1b0ccc2bb8..2f06b22dd9 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -1,4 +1,4 @@ -# NymVPN Application (GUI) +# NymVPN - Desktop (GUI) ```admonish info Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future. @@ -6,9 +6,11 @@ Our alpha testing round is done with participants at live workshop events. This **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` -This is the alpha version of NymVPN application - the GUI. A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users. +This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users. -Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md). +Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md). + +Visit NymVPN alpha latest [release page]({{nym_vpn_latest_binary_url}}) to check sha sums or download the binaries directly. ## Automated Script for GUI Installation @@ -16,7 +18,7 @@ We wrote a [script](https://gist.github.com/serinko/e0a9f7ff3d79e974ec6f6783caa1 1. Open a terminal window in a directory where you want the script and NymVPN binary be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/064c0d42af6a187b4f62998a0c2e6a84c319eeef/nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/227c8c348a1e58f68cb500e4504b22412177c680/nym-vpn-desktop-install-run.sh ``` 2. Make the script executable @@ -24,7 +26,7 @@ curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/ser chmod u+x nym-vpn-desktop-install-run.sh ``` -3. Start the script as root, turn off any VPN and run +3. Start the script, turn off any VPN and run ```sh sudo -E ./nym-vpn-desktop-install-run.sh ``` @@ -34,10 +36,10 @@ sudo -E ./nym-vpn-desktop-install-run.sh To start the application again, reconnect your wifi and run ```sh # Linux -sudo -E ~/nym-vpn-latest/nym-vpn_0.0.3_amd64.AppImage +sudo -E ~/nym-vpn-latest/nym-vpn_0.0.4_amd64.AppImage # MacOS -sudo $nym_vpn_dir/nym-vpn +sudo -E $HOME/nym-vpn-latest/nym-vpn ``` -In case of errors check out the [troubleshooting](troubleshooting.md#installing-gui-on-macos-not-working) section. +In case of errors check out the [troubleshooting](troubleshooting.md#running-gui-failed-due-to-toml-parse-error) section. diff --git a/documentation/dev-portal/src/nymvpn/testing.md b/documentation/dev-portal/src/nymvpn/testing.md index a2e87ea623..f5e6558bf4 100644 --- a/documentation/dev-portal/src/nymvpn/testing.md +++ b/documentation/dev-portal/src/nymvpn/testing.md @@ -14,14 +14,17 @@ One of the main aims of NymVPN alpha release is testing; your results will help > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary ([download here]({{nym_vpn_latest_binary_url}})) and [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) to that directory -2. Copy the [block below](#testssh) and save it as `tests.sh` to the same folder -3. Open terminal in the same directory -4. Turn off any existing VPN's (including the NymVPN instances), reconnect your wifi and make the script executable by running +1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary ([download here]({{nym_vpn_latest_binary_url}})) +2. Copy or download [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) testnet config file to the same directory +```sh +curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env +``` +3. Copy the [block below](#testssh) and save it as `tests.sh` to the same folder +4. Open terminal in the same directory and make the script executable ```sh chmod u+x ./tests.sh ``` -5. Run the `tests.sh` script: +5. Turn off any existing VPN's (including NymVPN instances), reconnect your wifi and run the `tests.sh` script ```sh sudo ./tests.sh ```` @@ -46,8 +49,8 @@ nym-vpn-tests ├── timeout └── two_hop_perf_test_results.log ``` -10. When the tests are finished, remove the `nym-vpn-cli` binary from the folder and compress the entire folder as `nym-vpn-tests.zip` -11. Upload this compressed file to the [form]({{nym_vpn_form_url}}) upload field when prompted +10. When the tests are finished, remove the `nym-vpn-cli` binary from the folder and compress the entire folder as `nym-vpn-tests.zip` (both of these can be done in your graphical environment) +11. Upload this compressed file to the [form]({{nym_vpn_form_url}}) drop field when prompted #### tests.sh diff --git a/documentation/dev-portal/src/nymvpn/troubleshooting.md b/documentation/dev-portal/src/nymvpn/troubleshooting.md index 3b3fa49a55..32f9139516 100644 --- a/documentation/dev-portal/src/nymvpn/troubleshooting.md +++ b/documentation/dev-portal/src/nymvpn/troubleshooting.md @@ -2,13 +2,27 @@ Below are listed some points which may need to be addressed when testing NymVPN alpha. If you crashed into any errors which are not listed, please contact us at the testing workshop or in the NymVPN [Matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat). -#### Problems with the newest version `nym-vpn-alpha-0.0.X demo` +#### Running GUI failed due to `TOML parse error` -Try the previous version which was tested multiple times by downloading the client from the [release page](https://github.com/nymtech/nym/releases). Then follow all the setup steps the name of your downloaded binary. +If you see this error when running NymVPN alpha desktop, it's because the older versions needed entry location in `config.toml` configuration file. From `v0.0.3` the entry location is selected directly by the user in the application. This error is due to an old `app-data.toml` config in your computer. -#### Installing GUI on MacOS not working +```sh +2024-02-15T14:25:02.745331Z ERROR read: nym_vpn_desktop::fs::storage: TOML parse error at line 5, column 1 + | +5 | [entry_node_location] + | ^^^^^^^^^^^^^^^^^^^^^ +wanted exactly 1 element, more than 1 element + self=AppStorage { data: AppData { monitoring: None, autoconnect: None, killswitch: None, entry_location_selector: None, ui_theme: None, ui_root_font_size: None, vpn_mode: None, entry_node_location: None, exit_node_location: None }, dir_path: "/home/companero/.local/share/nym-vpn", filename: "app-data.toml", full_path: "/home/companero/.local/share/nym-vpn/app-data.toml" } +Error: TOML parse error at line 5, column 1 + | +5 | [entry_node_location] + | ^^^^^^^^^^^^^^^^^^^^^ +wanted exactly 1 element, more than 1 element +``` -In case there was a problem running the script, try the [manual setup](gui-mac.md) for MacOS. +Simply delete this file `app-data.toml` from the path listed in the error message. In the example above it would be `/home/companero/.local/share/nym-vpn/app-data.toml`. + +The application will create a new one on startup. #### Thread `main` panicked From 7483d107019da0582579f1ad904f3eed3411d112 Mon Sep 17 00:00:00 2001 From: Lawrence Stalder Date: Tue, 20 Feb 2024 16:02:53 +0100 Subject: [PATCH 098/394] fix: localnet script fix typo to attach tmux session --- scripts/localnet_start.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/localnet_start.sh b/scripts/localnet_start.sh index 9b2d93475e..1a821c31e1 100755 --- a/scripts/localnet_start.sh +++ b/scripts/localnet_start.sh @@ -73,4 +73,4 @@ tmux send-keys -t localnet:1 "time curl -x socks5h://127.0.0.1:1080 https://test tmux select-layout -t localnet:0 tiled tmux select-layout -t localnet:1 tiled -tmux attach -tlocalnet +tmux attach -t localnet From d92a8ea02806591edce2ff346f2a2409d22eb427 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Tue, 20 Feb 2024 16:25:58 +0100 Subject: [PATCH 099/394] temporarily remove the debian builder from gh action - it's not needed but in the future we may want to reactivate it, currently commenting it out --- .github/workflows/ci-build-upload-binaries.yml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/ci-build-upload-binaries.yml b/.github/workflows/ci-build-upload-binaries.yml index afaae3536e..eb4a271afd 100644 --- a/.github/workflows/ci-build-upload-binaries.yml +++ b/.github/workflows/ci-build-upload-binaries.yml @@ -79,15 +79,15 @@ jobs: command: build args: --workspace --release ${{ env.CARGO_FEATURES }} - - name: Install cargo-deb - uses: actions-rs/cargo@v1 - with: - command: install - args: cargo-deb + # - name: Install cargo-deb + # uses: actions-rs/cargo@v1 + # with: + # command: install + # args: cargo-deb - - name: Build deb packages - shell: bash - run: make deb + # - name: Build deb packages + # shell: bash + # run: make deb # If this was a manual workflow_dispatch, publish binaries. @@ -124,7 +124,7 @@ jobs: cp target/release/nym-network-statistics $OUTPUT_DIR cp target/release/nym-cli $OUTPUT_DIR cp target/release/explorer-api $OUTPUT_DIR - cp target/debian/*.deb $OUTPUT_DIR + # cp target/debian/*.deb $OUTPUT_DIR - name: Deploy branch to CI www # if: github.event_name == 'schedule' || github.event_name == 'pull_request' From 3c2d47ad18d2eca10623ac4b388b2a2ccc9e4055 Mon Sep 17 00:00:00 2001 From: benedettadavico Date: Tue, 20 Feb 2024 18:34:23 +0100 Subject: [PATCH 100/394] update cargo.lock --- Cargo.lock | 1261 ++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 1124 insertions(+), 137 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6f88f34cb4..70ea613374 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,185 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" +[[package]] +name = "actix-codec" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" +dependencies = [ + "bitflags 1.3.2", + "bytes", + "futures-core", + "futures-sink", + "memchr", + "pin-project-lite 0.2.13", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "actix-http" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" +dependencies = [ + "actix-codec", + "actix-rt", + "actix-service", + "actix-utils", + "ahash 0.8.3", + "base64 0.21.4", + "bitflags 2.4.1", + "brotli", + "bytes", + "bytestring", + "derive_more", + "encoding_rs", + "flate2", + "futures-core", + "h2", + "http", + "httparse", + "httpdate", + "itoa", + "language-tags", + "local-channel", + "mime", + "percent-encoding", + "pin-project-lite 0.2.13", + "rand 0.8.5", + "sha1", + "smallvec", + "tokio", + "tokio-util", + "tracing", + "zstd", +] + +[[package]] +name = "actix-macros" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" +dependencies = [ + "quote", + "syn 2.0.38", +] + +[[package]] +name = "actix-router" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" +dependencies = [ + "bytestring", + "http", + "regex", + "serde", + "tracing", +] + +[[package]] +name = "actix-rt" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" +dependencies = [ + "futures-core", + "tokio", +] + +[[package]] +name = "actix-server" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" +dependencies = [ + "actix-rt", + "actix-service", + "actix-utils", + "futures-core", + "futures-util", + "mio", + "socket2 0.5.4", + "tokio", + "tracing", +] + +[[package]] +name = "actix-service" +version = "2.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" +dependencies = [ + "futures-core", + "paste", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "actix-utils" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" +dependencies = [ + "local-waker", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "actix-web" +version = "4.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" +dependencies = [ + "actix-codec", + "actix-http", + "actix-macros", + "actix-router", + "actix-rt", + "actix-server", + "actix-service", + "actix-utils", + "actix-web-codegen", + "ahash 0.8.3", + "bytes", + "bytestring", + "cfg-if", + "cookie 0.16.2", + "derive_more", + "encoding_rs", + "futures-core", + "futures-util", + "itoa", + "language-tags", + "log", + "mime", + "once_cell", + "pin-project-lite 0.2.13", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "smallvec", + "socket2 0.5.4", + "time", + "url", +] + +[[package]] +name = "actix-web-codegen" +version = "4.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" +dependencies = [ + "actix-router", + "proc-macro2", + "quote", + "syn 2.0.38", +] + [[package]] name = "addr" version = "0.15.6" @@ -163,6 +342,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", + "getrandom 0.2.10", "once_cell", "version_check", ] @@ -176,6 +356,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + [[package]] name = "allocator-api2" version = "0.2.16" @@ -274,6 +469,9 @@ name = "anyhow" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +dependencies = [ + "backtrace", +] [[package]] name = "arc-swap" @@ -293,6 +491,12 @@ dependencies = [ "password-hash", ] +[[package]] +name = "array-bytes" +version = "6.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" + [[package]] name = "arrayref" version = "0.3.7" @@ -378,6 +582,12 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" +[[package]] +name = "assert_matches" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" + [[package]] name = "async-channel" version = "1.9.0" @@ -812,6 +1022,27 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +[[package]] +name = "brotli" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + [[package]] name = "bs58" version = "0.4.0" @@ -825,7 +1056,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ "sha2 0.10.8", - "tinyvec", ] [[package]] @@ -871,6 +1101,15 @@ dependencies = [ "serde", ] +[[package]] +name = "bytestring" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" +dependencies = [ + "bytes", +] + [[package]] name = "cast" version = "0.3.0" @@ -889,6 +1128,7 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ + "jobserver", "libc", ] @@ -1182,6 +1422,20 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "config" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" +dependencies = [ + "async-trait", + "lazy_static", + "nom", + "pathdiff", + "serde", + "toml 0.5.11", +] + [[package]] name = "console-api" version = "0.5.0" @@ -1266,6 +1520,23 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" +[[package]] +name = "convert_case" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" + +[[package]] +name = "cookie" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "cookie" version = "0.18.0" @@ -1600,6 +1871,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "crunchy" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" + [[package]] name = "crypto-bigint" version = "0.4.9" @@ -1767,6 +2044,7 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", + "digest 0.10.7", "fiat-crypto", "platforms", "rustc_version 0.4.0", @@ -2158,6 +2436,19 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "derive_more" +version = "0.99.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" +dependencies = [ + "convert_case", + "proc-macro2", + "quote", + "rustc_version 0.4.0", + "syn 1.0.109", +] + [[package]] name = "devise" version = "0.4.1" @@ -2319,7 +2610,6 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.6", "rfc6979 0.4.0", - "serdect", "signature 2.1.0", "spki 0.7.2", ] @@ -2372,6 +2662,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ed25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" +dependencies = [ + "curve25519-dalek 4.1.1", + "ed25519 2.2.3", + "rand_core 0.6.4", + "serde", + "sha2 0.10.8", + "zeroize", +] + [[package]] name = "ed25519-zebra" version = "3.1.0" @@ -2430,7 +2734,6 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", - "serdect", "subtle 2.4.1", "zeroize", ] @@ -2479,6 +2782,55 @@ dependencies = [ "regex", ] +[[package]] +name = "ephemera" +version = "0.1.0" +dependencies = [ + "actix-web", + "anyhow", + "array-bytes", + "assert_matches", + "async-trait", + "asynchronous-codec", + "blake2 0.10.6", + "bs58 0.4.0", + "bytes", + "cfg-if", + "chrono", + "clap 4.4.7", + "config", + "digest 0.10.7", + "dirs 5.0.1", + "enum-as-inner", + "futures", + "futures-util", + "lazy_static", + "libp2p 0.51.3", + "libp2p-identity", + "log", + "lru 0.10.1", + "nym-config", + "nym-ephemera-common", + "nym-task", + "pretty_env_logger", + "rand 0.8.5", + "refinery", + "reqwest", + "rusqlite", + "serde", + "serde_derive", + "serde_json", + "thiserror", + "tokio", + "tokio-tungstenite", + "tokio-util", + "toml 0.7.8", + "unsigned-varint", + "utoipa", + "utoipa-swagger-ui", + "uuid 1.5.0", +] + [[package]] name = "equivalent" version = "1.0.1" @@ -2512,7 +2864,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "explorer-api" -version = "1.1.32" +version = "1.1.33" dependencies = [ "chrono", "clap 4.4.7", @@ -2520,6 +2872,7 @@ dependencies = [ "humantime-serde", "isocountry", "itertools 0.10.5", + "lazy_static", "log", "maxminddb", "nym-bin-common", @@ -2600,6 +2953,18 @@ dependencies = [ "once_cell", ] +[[package]] +name = "fallible-iterator" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + [[package]] name = "fastrand" version = "1.9.0" @@ -3116,6 +3481,15 @@ dependencies = [ "serde_json", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.6", +] + [[package]] name = "hashbrown" version = "0.12.3" @@ -3144,6 +3518,15 @@ dependencies = [ "allocator-api2", ] +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + [[package]] name = "hashlink" version = "0.8.4" @@ -3409,7 +3792,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.10", + "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", ] @@ -3827,6 +4210,15 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + [[package]] name = "js-sys" version = "0.3.64" @@ -3876,6 +4268,12 @@ dependencies = [ "libc", ] +[[package]] +name = "language-tags" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" + [[package]] name = "lazy_static" version = "1.4.0" @@ -3952,25 +4350,80 @@ dependencies = [ "futures-timer", "getrandom 0.2.10", "instant", - "libp2p-core", - "libp2p-dns", - "libp2p-gossipsub", + "libp2p-core 0.39.0", + "libp2p-dns 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-gossipsub 0.44.0", "libp2p-identify", - "libp2p-mdns", - "libp2p-metrics", + "libp2p-mdns 0.43.0", + "libp2p-metrics 0.12.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", "libp2p-mplex", - "libp2p-noise", + "libp2p-noise 0.42.0", "libp2p-ping", - "libp2p-quic", - "libp2p-swarm", - "libp2p-tcp", - "libp2p-webrtc", + "libp2p-quic 0.7.0-alpha.2", + "libp2p-swarm 0.42.0", + "libp2p-tcp 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-webrtc 0.4.0-alpha.2", "libp2p-websocket", - "libp2p-yamux", - "multiaddr", + "libp2p-yamux 0.43.0", + "multiaddr 0.17.0", "pin-project", ] +[[package]] +name = "libp2p" +version = "0.51.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "getrandom 0.2.10", + "instant", + "libp2p-allow-block-list", + "libp2p-connection-limits", + "libp2p-core 0.39.2", + "libp2p-dns 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-gossipsub 0.44.4", + "libp2p-identity", + "libp2p-kad", + "libp2p-mdns 0.43.1", + "libp2p-metrics 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-noise 0.42.2", + "libp2p-quic 0.7.0-alpha.3", + "libp2p-request-response", + "libp2p-swarm 0.42.2", + "libp2p-tcp 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", + "libp2p-webrtc 0.4.0-alpha.4", + "libp2p-yamux 0.43.1", + "multiaddr 0.17.1", + "pin-project", +] + +[[package]] +name = "libp2p-allow-block-list" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" +dependencies = [ + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", + "void", +] + +[[package]] +name = "libp2p-connection-limits" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" +dependencies = [ + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", + "void", +] + [[package]] name = "libp2p-core" version = "0.39.0" @@ -3978,23 +4431,23 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "asn1_der", "bs58 0.4.0", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "either", "fnv", "futures", "futures-timer", "instant", "log", - "multiaddr", + "multiaddr 0.17.0", "multihash", - "multistream-select", + "multistream-select 0.12.1 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", "once_cell", "parking_lot 0.12.1", "pin-project", "prost 0.11.9", "prost-build", "rand 0.8.5", - "rw-stream-sink", + "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", "sec1 0.3.0", "sha2 0.10.8", "smallvec", @@ -4004,13 +4457,56 @@ dependencies = [ "zeroize", ] +[[package]] +name = "libp2p-core" +version = "0.39.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c1df63c0b582aa434fb09b2d86897fa2b419ffeccf934b36f87fcedc8e835c2" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-identity", + "log", + "multiaddr 0.17.1", + "multihash", + "multistream-select 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", + "once_cell", + "parking_lot 0.12.1", + "pin-project", + "quick-protobuf", + "rand 0.8.5", + "rw-stream-sink 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde", + "smallvec", + "thiserror", + "unsigned-varint", + "void", +] + +[[package]] +name = "libp2p-dns" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" +dependencies = [ + "futures", + "libp2p-core 0.39.2", + "log", + "parking_lot 0.12.1", + "smallvec", + "trust-dns-resolver", +] + [[package]] name = "libp2p-dns" version = "0.39.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.39.0", "log", "parking_lot 0.12.1", "smallvec", @@ -4030,8 +4526,8 @@ dependencies = [ "futures", "hex_fmt", "instant", - "libp2p-core", - "libp2p-swarm", + "libp2p-core 0.39.0", + "libp2p-swarm 0.42.0", "log", "prometheus-client", "prost 0.11.9", @@ -4046,6 +4542,39 @@ dependencies = [ "wasm-timer", ] +[[package]] +name = "libp2p-gossipsub" +version = "0.44.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" +dependencies = [ + "asynchronous-codec", + "base64 0.21.4", + "byteorder", + "bytes", + "either", + "fnv", + "futures", + "hex_fmt", + "instant", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", + "log", + "prometheus-client", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "regex", + "serde", + "sha2 0.10.8", + "smallvec", + "thiserror", + "unsigned-varint", + "void", + "wasm-timer", +] + [[package]] name = "libp2p-identify" version = "0.42.0" @@ -4055,10 +4584,10 @@ dependencies = [ "either", "futures", "futures-timer", - "libp2p-core", - "libp2p-swarm", + "libp2p-core 0.39.0", + "libp2p-swarm 0.42.0", "log", - "lru", + "lru 0.9.0", "prost 0.11.9", "prost-build", "prost-codec", @@ -4067,6 +4596,54 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-identity" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" +dependencies = [ + "bs58 0.4.0", + "ed25519-dalek 2.0.0", + "log", + "multiaddr 0.17.1", + "multihash", + "quick-protobuf", + "rand 0.8.5", + "serde", + "sha2 0.10.8", + "thiserror", + "zeroize", +] + +[[package]] +name = "libp2p-kad" +version = "0.43.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" +dependencies = [ + "arrayvec", + "asynchronous-codec", + "bytes", + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", + "log", + "quick-protobuf", + "rand 0.8.5", + "serde", + "sha2 0.10.8", + "smallvec", + "thiserror", + "uint", + "unsigned-varint", + "void", +] + [[package]] name = "libp2p-mdns" version = "0.43.0" @@ -4075,8 +4652,29 @@ dependencies = [ "data-encoding", "futures", "if-watch", - "libp2p-core", - "libp2p-swarm", + "libp2p-core 0.39.0", + "libp2p-swarm 0.42.0", + "log", + "rand 0.8.5", + "smallvec", + "socket2 0.4.9", + "tokio", + "trust-dns-proto", + "void", +] + +[[package]] +name = "libp2p-mdns" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19983e1f949f979a928f2c603de1cf180cc0dc23e4ac93a62651ccb18341460b" +dependencies = [ + "data-encoding", + "futures", + "if-watch", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", "log", "rand 0.8.5", "smallvec", @@ -4086,16 +4684,29 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-metrics" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" +dependencies = [ + "libp2p-core 0.39.2", + "libp2p-gossipsub 0.44.4", + "libp2p-kad", + "libp2p-swarm 0.42.2", + "prometheus-client", +] + [[package]] name = "libp2p-metrics" version = "0.12.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ - "libp2p-core", - "libp2p-gossipsub", + "libp2p-core 0.39.0", + "libp2p-gossipsub 0.44.0", "libp2p-identify", "libp2p-ping", - "libp2p-swarm", + "libp2p-swarm 0.42.0", "prometheus-client", ] @@ -4107,7 +4718,7 @@ dependencies = [ "asynchronous-codec", "bytes", "futures", - "libp2p-core", + "libp2p-core 0.39.0", "log", "nohash-hasher", "parking_lot 0.12.1", @@ -4124,7 +4735,7 @@ dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "libp2p-core", + "libp2p-core 0.39.0", "log", "once_cell", "prost 0.11.9", @@ -4138,6 +4749,29 @@ dependencies = [ "zeroize", ] +[[package]] +name = "libp2p-noise" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" +dependencies = [ + "bytes", + "curve25519-dalek 3.2.0", + "futures", + "libp2p-core 0.39.2", + "libp2p-identity", + "log", + "once_cell", + "quick-protobuf", + "rand 0.8.5", + "sha2 0.10.8", + "snow", + "static_assertions", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + [[package]] name = "libp2p-ping" version = "0.42.0" @@ -4147,8 +4781,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", - "libp2p-swarm", + "libp2p-core 0.39.0", + "libp2p-swarm 0.42.0", "log", "rand 0.8.5", "void", @@ -4163,8 +4797,8 @@ dependencies = [ "futures", "futures-timer", "if-watch", - "libp2p-core", - "libp2p-tls", + "libp2p-core 0.39.0", + "libp2p-tls 0.1.0-alpha.2", "log", "parking_lot 0.12.1", "quinn-proto", @@ -4174,6 +4808,44 @@ dependencies = [ "tokio", ] +[[package]] +name = "libp2p-quic" +version = "0.7.0-alpha.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6b26abd81cd2398382a1edfe739b539775be8a90fa6914f39b2ab49571ec735" +dependencies = [ + "bytes", + "futures", + "futures-timer", + "if-watch", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-tls 0.1.0", + "log", + "parking_lot 0.12.1", + "quinn-proto", + "rand 0.8.5", + "rustls 0.20.9", + "thiserror", + "tokio", +] + +[[package]] +name = "libp2p-request-response" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffdb374267d42dc5ed5bc53f6e601d4a64ac5964779c6e40bb9e4f14c1e30d5" +dependencies = [ + "async-trait", + "futures", + "instant", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm 0.42.2", + "rand 0.8.5", + "smallvec", +] + [[package]] name = "libp2p-swarm" version = "0.42.0" @@ -4184,8 +4856,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core", - "libp2p-swarm-derive", + "libp2p-core 0.39.0", + "libp2p-swarm-derive 0.32.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", "log", "rand 0.8.5", "smallvec", @@ -4193,6 +4865,38 @@ dependencies = [ "void", ] +[[package]] +name = "libp2p-swarm" +version = "0.42.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "903b3d592d7694e56204d211f29d31bc004be99386644ba8731fc3e3ef27b296" +dependencies = [ + "either", + "fnv", + "futures", + "futures-timer", + "instant", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-swarm-derive 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", + "log", + "rand 0.8.5", + "smallvec", + "tokio", + "void", +] + +[[package]] +name = "libp2p-swarm-derive" +version = "0.32.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" +dependencies = [ + "heck 0.4.1", + "quote", + "syn 1.0.109", +] + [[package]] name = "libp2p-swarm-derive" version = "0.32.0" @@ -4203,6 +4907,22 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "libp2p-tcp" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d33698596d7722d85d3ab0c86c2c322254fce1241e91208e3679b4eb3026cf" +dependencies = [ + "futures", + "futures-timer", + "if-watch", + "libc", + "libp2p-core 0.39.2", + "log", + "socket2 0.4.9", + "tokio", +] + [[package]] name = "libp2p-tcp" version = "0.39.0" @@ -4212,7 +4932,7 @@ dependencies = [ "futures-timer", "if-watch", "libc", - "libp2p-core", + "libp2p-core 0.39.0", "log", "socket2 0.4.9", "tokio", @@ -4225,7 +4945,26 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "futures", "futures-rustls", - "libp2p-core", + "libp2p-core 0.39.0", + "rcgen 0.10.0", + "ring 0.16.20", + "rustls 0.20.9", + "thiserror", + "webpki 0.22.4", + "x509-parser 0.14.0", + "yasna", +] + +[[package]] +name = "libp2p-tls" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" +dependencies = [ + "futures", + "futures-rustls", + "libp2p-core 0.39.2", + "libp2p-identity", "rcgen 0.10.0", "ring 0.16.20", "rustls 0.20.9", @@ -4247,8 +4986,8 @@ dependencies = [ "futures-timer", "hex", "if-watch", - "libp2p-core", - "libp2p-noise", + "libp2p-core 0.39.0", + "libp2p-noise 0.42.0", "log", "multihash", "prost 0.11.9", @@ -4265,6 +5004,37 @@ dependencies = [ "webrtc", ] +[[package]] +name = "libp2p-webrtc" +version = "0.4.0-alpha.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" +dependencies = [ + "async-trait", + "asynchronous-codec", + "bytes", + "futures", + "futures-timer", + "hex", + "if-watch", + "libp2p-core 0.39.2", + "libp2p-identity", + "libp2p-noise 0.42.2", + "log", + "multihash", + "quick-protobuf", + "quick-protobuf-codec", + "rand 0.8.5", + "rcgen 0.9.3", + "serde", + "stun", + "thiserror", + "tinytemplate", + "tokio", + "tokio-util", + "webrtc", +] + [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -4273,11 +5043,11 @@ dependencies = [ "either", "futures", "futures-rustls", - "libp2p-core", + "libp2p-core 0.39.0", "log", "parking_lot 0.12.1", "quicksink", - "rw-stream-sink", + "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", "soketto", "url", "webpki-roots 0.22.6", @@ -4289,7 +5059,20 @@ version = "0.43.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core", + "libp2p-core 0.39.0", + "log", + "thiserror", + "yamux", +] + +[[package]] +name = "libp2p-yamux" +version = "0.43.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" +dependencies = [ + "futures", + "libp2p-core 0.39.2", "log", "thiserror", "yamux", @@ -4348,6 +5131,23 @@ dependencies = [ "keystream", ] +[[package]] +name = "local-channel" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" +dependencies = [ + "futures-core", + "futures-sink", + "local-waker", +] + +[[package]] +name = "local-waker" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" + [[package]] name = "lock_api" version = "0.4.11" @@ -4388,6 +5188,15 @@ dependencies = [ "hashbrown 0.13.2", ] +[[package]] +name = "lru" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" +dependencies = [ + "hashbrown 0.13.2", +] + [[package]] name = "lru-cache" version = "0.1.2" @@ -4591,6 +5400,25 @@ dependencies = [ "url", ] +[[package]] +name = "multiaddr" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" +dependencies = [ + "arrayref", + "byteorder", + "data-encoding", + "log", + "multibase", + "multihash", + "percent-encoding", + "serde", + "static_assertions", + "unsigned-varint", + "url", +] + [[package]] name = "multibase" version = "0.9.1" @@ -4611,6 +5439,8 @@ dependencies = [ "core2", "digest 0.10.7", "multihash-derive", + "serde", + "serde-big-array", "sha2 0.10.8", "unsigned-varint", ] @@ -4635,6 +5465,20 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" +[[package]] +name = "multistream-select" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" +dependencies = [ + "bytes", + "futures", + "log", + "pin-project", + "smallvec", + "unsigned-varint", +] + [[package]] name = "multistream-select" version = "0.12.1" @@ -4920,13 +5764,16 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.34" +version = "1.1.35" dependencies = [ + "actix-web", "anyhow", + "array-bytes", "async-trait", "bip39", - "bs58 0.5.0", + "bs58 0.4.0", "cfg-if", + "chrono", "clap 4.4.7", "console-subscriber", "cosmwasm-std", @@ -4935,11 +5782,13 @@ dependencies = [ "cw3", "cw4", "dirs 4.0.0", + "ephemera", "futures", + "futures-util", "getset", "humantime-serde", "itertools 0.12.0", - "k256", + "lazy_static", "log", "nym-api-requests", "nym-bandwidth-controller", @@ -4947,12 +5796,14 @@ dependencies = [ "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", + "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-credential-storage", "nym-credentials", "nym-crypto", "nym-dkg", + "nym-ephemera-common", "nym-gateway-client", "nym-inclusion-probability", "nym-mixnet-contract-common", @@ -4979,6 +5830,7 @@ dependencies = [ "rocket_okapi", "schemars", "serde", + "serde_derive", "serde_json", "sha2 0.9.9", "sqlx", @@ -4990,6 +5842,7 @@ dependencies = [ "tokio-stream", "ts-rs", "url", + "uuid 1.5.0", "zeroize", ] @@ -4997,12 +5850,11 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.4.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", - "ecdsa 0.16.8", "getset", - "nym-credentials-interface", + "nym-coconut-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -5017,11 +5869,9 @@ name = "nym-bandwidth-controller" version = "0.1.0" dependencies = [ "bip39", - "log", - "nym-coconut", + "nym-coconut-interface", "nym-credential-storage", "nym-credentials", - "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -5072,12 +5922,12 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.33" +version = "1.1.34" dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.5.0", + "bs58 0.4.0", "clap 4.4.7", "clap_complete", "clap_complete_fig", @@ -5102,7 +5952,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.5.0", + "bs58 0.4.0", "cfg-if", "clap 4.4.7", "comfy-table", @@ -5110,7 +5960,6 @@ dependencies = [ "cosmwasm-std", "csv", "cw-utils", - "futures", "handlebars", "humantime-serde", "inquire", @@ -5126,7 +5975,6 @@ dependencies = [ "nym-credential-storage", "nym-credential-utils", "nym-credentials", - "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-multisig-contract-common", @@ -5144,25 +5992,24 @@ dependencies = [ "tap", "thiserror", "time", - "tokio", "toml 0.5.11", "url", - "zeroize", ] [[package]] name = "nym-client" -version = "1.1.32" +version = "1.1.33" dependencies = [ - "bs58 0.5.0", "clap 4.4.7", "dirs 4.0.0", "futures", + "lazy_static", "log", "nym-bandwidth-controller", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", + "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5174,16 +6021,15 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", + "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", - "time", "tokio", "tokio-tungstenite", "url", - "zeroize", ] [[package]] @@ -5274,7 +6120,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58 0.5.0", + "bs58 0.4.0", "criterion", "digest 0.9.0", "doc-comment", @@ -5316,6 +6162,17 @@ dependencies = [ "nym-multisig-contract-common", ] +[[package]] +name = "nym-coconut-interface" +version = "0.1.0" +dependencies = [ + "bs58 0.4.0", + "getset", + "nym-coconut", + "serde", + "thiserror", +] + [[package]] name = "nym-config" version = "0.1.0" @@ -5333,7 +6190,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.4.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -5351,7 +6208,6 @@ dependencies = [ "sqlx", "thiserror", "tokio", - "zeroize", ] [[package]] @@ -5361,7 +6217,6 @@ dependencies = [ "log", "nym-bandwidth-controller", "nym-client-core", - "nym-coconut", "nym-config", "nym-credential-storage", "nym-credentials", @@ -5374,42 +6229,29 @@ dependencies = [ name = "nym-credentials" version = "0.1.0" dependencies = [ - "bincode", "bls12_381", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", "nym-api-requests", - "nym-credentials-interface", + "nym-coconut-interface", "nym-crypto", "nym-validator-client", "rand 0.7.3", - "serde", "thiserror", - "time", "zeroize", ] -[[package]] -name = "nym-credentials-interface" -version = "0.1.0" -dependencies = [ - "bls12_381", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-crypto" version = "0.4.0" dependencies = [ "aes 0.8.3", "blake3", - "bs58 0.5.0", + "bs58 0.4.0", "cipher 0.4.4", "ctr 0.9.2", "digest 0.10.7", - "ed25519-dalek", + "ed25519-dalek 1.0.1", "generic-array 0.14.7", "hkdf 0.12.3", "hmac 0.12.1", @@ -5431,7 +6273,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58 0.5.0", + "bs58 0.4.0", "criterion", "ff 0.13.0", "group 0.13.0", @@ -5505,13 +6347,13 @@ dependencies = [ [[package]] name = "nym-gateway" -version = "1.1.32" +version = "1.1.33" dependencies = [ "anyhow", "async-trait", "atty", "bip39", - "bs58 0.5.0", + "bs58 0.4.0", "clap 4.4.7", "colored", "dashmap", @@ -5522,12 +6364,13 @@ dependencies = [ "humantime-serde", "hyper", "ipnetwork 0.16.0", + "lazy_static", "log", "nym-api-requests", "nym-bin-common", + "nym-coconut-interface", "nym-config", "nym-credentials", - "nym-credentials-interface", "nym-crypto", "nym-gateway-requests", "nym-ip-packet-router", @@ -5552,7 +6395,6 @@ dependencies = [ "sqlx", "subtle-encoding", "thiserror", - "time", "tokio", "tokio-stream", "tokio-tungstenite", @@ -5571,8 +6413,8 @@ dependencies = [ "gloo-utils", "log", "nym-bandwidth-controller", + "nym-coconut-interface", "nym-credential-storage", - "nym-credentials", "nym-crypto", "nym-gateway-requests", "nym-network-defaults", @@ -5598,12 +6440,12 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.4.0", "futures", "generic-array 0.14.7", "log", + "nym-coconut-interface", "nym-credentials", - "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -5655,11 +6497,12 @@ name = "nym-ip-packet-router" version = "0.1.0" dependencies = [ "bincode", - "bs58 0.5.0", + "bs58 0.4.0", "bytes", "clap 4.4.7", "etherparse", "futures", + "lazy_static", "log", "nym-bin-common", "nym-client-core", @@ -5724,11 +6567,11 @@ dependencies = [ [[package]] name = "nym-mixnode" -version = "1.1.34" +version = "1.1.35" dependencies = [ "anyhow", "axum", - "bs58 0.5.0", + "bs58 0.4.0", "cfg-if", "clap 4.4.7", "colored", @@ -5737,6 +6580,7 @@ dependencies = [ "dirs 4.0.0", "futures", "humantime-serde", + "lazy_static", "log", "nym-bin-common", "nym-config", @@ -5843,25 +6687,25 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.32" +version = "1.1.33" dependencies = [ "addr", "anyhow", "async-file-watcher", "async-trait", - "bs58 0.5.0", + "bs58 0.4.0", "clap 4.4.7", "dirs 4.0.0", "futures", "humantime-serde", "ipnetwork 0.20.0", + "lazy_static", "log", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", "nym-config", "nym-credential-storage", - "nym-credentials", "nym-crypto", "nym-exit-policy", "nym-network-defaults", @@ -5885,16 +6729,14 @@ dependencies = [ "tap", "tempfile", "thiserror", - "time", "tokio", "tokio-tungstenite", "url", - "zeroize", ] [[package]] name = "nym-network-statistics" -version = "1.1.32" +version = "1.1.33" dependencies = [ "dirs 4.0.0", "log", @@ -6075,7 +6917,7 @@ dependencies = [ "hex", "http", "httpcodec", - "libp2p", + "libp2p 0.51.0", "log", "nym-bandwidth-controller", "nym-bin-common", @@ -6139,13 +6981,14 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.32" +version = "1.1.33" dependencies = [ - "bs58 0.5.0", "clap 4.4.7", + "lazy_static", "log", "nym-bin-common", "nym-client-core", + "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -6157,15 +7000,14 @@ dependencies = [ "nym-socks5-client-core", "nym-sphinx", "nym-topology", + "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", - "time", "tokio", "url", - "zeroize", ] [[package]] @@ -6309,7 +7151,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.4.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -6449,7 +7291,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58 0.5.0", + "bs58 0.4.0", "log", "nym-api-requests", "nym-bin-common", @@ -6492,6 +7334,7 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", + "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -6533,9 +7376,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", - "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", + "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", @@ -6705,7 +7548,6 @@ dependencies = [ "tendermint", "tendermint-rpc", "thiserror", - "time", "tokio", "tokio-stream", "tokio-util", @@ -7013,6 +7855,12 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" +[[package]] +name = "pathdiff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" + [[package]] name = "pbkdf2" version = "0.12.2" @@ -7569,6 +8417,28 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" +[[package]] +name = "quick-protobuf" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" +dependencies = [ + "byteorder", +] + +[[package]] +name = "quick-protobuf-codec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1693116345026436eb2f10b677806169c1a1260c1c60eaaffe3fb5a29ae23d8b" +dependencies = [ + "asynchronous-codec", + "bytes", + "quick-protobuf", + "thiserror", + "unsigned-varint", +] + [[package]] name = "quicksink" version = "0.1.2" @@ -7930,6 +8800,50 @@ dependencies = [ "syn 2.0.38", ] +[[package]] +name = "refinery" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "529664dbccc0a296947615c997a857912d72d1c44be1fafb7bae54ecfa7a8c24" +dependencies = [ + "refinery-core", + "refinery-macros", +] + +[[package]] +name = "refinery-core" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e895cb870cf06e92318cbbeb701f274d022d5ca87a16fa8244e291cd035ef954" +dependencies = [ + "async-trait", + "cfg-if", + "lazy_static", + "log", + "regex", + "rusqlite", + "serde", + "siphasher", + "thiserror", + "time", + "toml 0.7.8", + "url", + "walkdir", +] + +[[package]] +name = "refinery-macros" +version = "0.8.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "123e8b80f8010c3ae38330c81e76938fc7adf6cdbfbaad20295bb8c22718b4f1" +dependencies = [ + "proc-macro2", + "quote", + "refinery-core", + "regex", + "syn 2.0.38", +] + [[package]] name = "regex" version = "1.10.2" @@ -7997,7 +8911,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.10", + "rustls 0.21.7", "rustls-native-certs", "rustls-pemfile", "serde", @@ -8165,7 +9079,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e" dependencies = [ - "cookie", + "cookie 0.18.0", "either", "futures", "http", @@ -8254,6 +9168,21 @@ dependencies = [ "webrtc-util", ] +[[package]] +name = "rusqlite" +version = "0.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" +dependencies = [ + "bitflags 1.3.2", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink 0.7.0", + "libsqlite3-sys", + "memchr", + "smallvec", +] + [[package]] name = "rust-embed" version = "6.8.1" @@ -8382,12 +9311,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" dependencies = [ "log", - "ring 0.17.4", + "ring 0.16.20", "rustls-webpki", "sct 0.7.0", ] @@ -8415,12 +9344,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.101.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" dependencies = [ - "ring 0.17.4", - "untrusted 0.9.0", + "ring 0.16.20", + "untrusted 0.7.1", ] [[package]] @@ -8429,6 +9358,17 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" +[[package]] +name = "rw-stream-sink" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" +dependencies = [ + "futures", + "pin-project", + "static_assertions", +] + [[package]] name = "rw-stream-sink" version = "0.3.0" @@ -8586,7 +9526,6 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", - "serdect", "subtle 2.4.1", "zeroize", ] @@ -8662,6 +9601,15 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "serde-big-array" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" +dependencies = [ + "serde", +] + [[package]] name = "serde-json-wasm" version = "0.5.0" @@ -8819,16 +9767,6 @@ dependencies = [ "unsafe-libyaml", ] -[[package]] -name = "serdect" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" -dependencies = [ - "base16ct 0.2.0", - "serde", -] - [[package]] name = "sha-1" version = "0.9.8" @@ -8951,6 +9889,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "siphasher" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe" + [[package]] name = "slab" version = "0.4.9" @@ -9155,7 +10099,7 @@ dependencies = [ "futures-executor", "futures-intrusive", "futures-util", - "hashlink", + "hashlink 0.8.4", "hex", "indexmap 1.9.3", "itoa", @@ -9763,7 +10707,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.7", "tokio", ] @@ -9824,7 +10768,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.10", + "rustls 0.21.7", "tokio", "tungstenite", ] @@ -10256,7 +11200,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.10", + "rustls 0.21.7", "sha1", "thiserror", "url", @@ -10303,6 +11247,18 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "uncased" version = "0.9.9" @@ -10501,6 +11457,7 @@ version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653" dependencies = [ + "actix-web", "axum", "mime_guess", "regex", @@ -10524,6 +11481,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "getrandom 0.2.10", + "serde", "wasm-bindgen", ] @@ -11446,3 +12404,32 @@ dependencies = [ "crossbeam-utils", "flate2", ] + +[[package]] +name = "zstd" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" +dependencies = [ + "zstd-safe", +] + +[[package]] +name = "zstd-safe" +version = "6.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" +dependencies = [ + "libc", + "zstd-sys", +] + +[[package]] +name = "zstd-sys" +version = "2.0.9+zstd.1.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" +dependencies = [ + "cc", + "pkg-config", +] From d8f73ef97ae921852b474fc4d44197ff22eab8ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= Date: Tue, 20 Feb 2024 19:02:06 +0100 Subject: [PATCH 101/394] Update Cargo.lock --- Cargo.lock | 1243 ++++++---------------------------------------------- 1 file changed, 128 insertions(+), 1115 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 70ea613374..7dcb192b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,185 +8,6 @@ version = "0.11.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fe438c63458706e03479442743baae6c88256498e6431708f6dfc520a26515d3" -[[package]] -name = "actix-codec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "617a8268e3537fe1d8c9ead925fca49ef6400927ee7bc26750e90ecee14ce4b8" -dependencies = [ - "bitflags 1.3.2", - "bytes", - "futures-core", - "futures-sink", - "memchr", - "pin-project-lite 0.2.13", - "tokio", - "tokio-util", - "tracing", -] - -[[package]] -name = "actix-http" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a92ef85799cba03f76e4f7c10f533e66d87c9a7e7055f3391f09000ad8351bc9" -dependencies = [ - "actix-codec", - "actix-rt", - "actix-service", - "actix-utils", - "ahash 0.8.3", - "base64 0.21.4", - "bitflags 2.4.1", - "brotli", - "bytes", - "bytestring", - "derive_more", - "encoding_rs", - "flate2", - "futures-core", - "h2", - "http", - "httparse", - "httpdate", - "itoa", - "language-tags", - "local-channel", - "mime", - "percent-encoding", - "pin-project-lite 0.2.13", - "rand 0.8.5", - "sha1", - "smallvec", - "tokio", - "tokio-util", - "tracing", - "zstd", -] - -[[package]] -name = "actix-macros" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb" -dependencies = [ - "quote", - "syn 2.0.38", -] - -[[package]] -name = "actix-router" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d66ff4d247d2b160861fa2866457e85706833527840e4133f8f49aa423a38799" -dependencies = [ - "bytestring", - "http", - "regex", - "serde", - "tracing", -] - -[[package]] -name = "actix-rt" -version = "2.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28f32d40287d3f402ae0028a9d54bef51af15c8769492826a69d28f81893151d" -dependencies = [ - "futures-core", - "tokio", -] - -[[package]] -name = "actix-server" -version = "2.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb13e7eef0423ea6eab0e59f6c72e7cb46d33691ad56a726b3cd07ddec2c2d4" -dependencies = [ - "actix-rt", - "actix-service", - "actix-utils", - "futures-core", - "futures-util", - "mio", - "socket2 0.5.4", - "tokio", - "tracing", -] - -[[package]] -name = "actix-service" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b894941f818cfdc7ccc4b9e60fa7e53b5042a2e8567270f9147d5591893373a" -dependencies = [ - "futures-core", - "paste", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "actix-utils" -version = "3.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88a1dcdff1466e3c2488e1cb5c36a71822750ad43839937f85d2f4d9f8b705d8" -dependencies = [ - "local-waker", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "actix-web" -version = "4.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e4a5b5e29603ca8c94a77c65cf874718ceb60292c5a5c3e5f4ace041af462b9" -dependencies = [ - "actix-codec", - "actix-http", - "actix-macros", - "actix-router", - "actix-rt", - "actix-server", - "actix-service", - "actix-utils", - "actix-web-codegen", - "ahash 0.8.3", - "bytes", - "bytestring", - "cfg-if", - "cookie 0.16.2", - "derive_more", - "encoding_rs", - "futures-core", - "futures-util", - "itoa", - "language-tags", - "log", - "mime", - "once_cell", - "pin-project-lite 0.2.13", - "regex", - "serde", - "serde_json", - "serde_urlencoded", - "smallvec", - "socket2 0.5.4", - "time", - "url", -] - -[[package]] -name = "actix-web-codegen" -version = "4.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5" -dependencies = [ - "actix-router", - "proc-macro2", - "quote", - "syn 2.0.38", -] - [[package]] name = "addr" version = "0.15.6" @@ -342,7 +163,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" dependencies = [ "cfg-if", - "getrandom 0.2.10", "once_cell", "version_check", ] @@ -356,21 +176,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "alloc-no-stdlib" -version = "2.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" - -[[package]] -name = "alloc-stdlib" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" -dependencies = [ - "alloc-no-stdlib", -] - [[package]] name = "allocator-api2" version = "0.2.16" @@ -469,9 +274,6 @@ name = "anyhow" version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" -dependencies = [ - "backtrace", -] [[package]] name = "arc-swap" @@ -491,12 +293,6 @@ dependencies = [ "password-hash", ] -[[package]] -name = "array-bytes" -version = "6.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b1c5a481ec30a5abd8dfbd94ab5cf1bb4e9a66be7f1b3b322f2f1170c200fd" - [[package]] name = "arrayref" version = "0.3.7" @@ -582,12 +378,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "155a5a185e42c6b77ac7b88a15143d930a9e9727a5b7b77eed417404ab15c247" -[[package]] -name = "assert_matches" -version = "1.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b34d609dfbaf33d6889b2b7106d3ca345eacad44200913df5ba02bfd31d2ba9" - [[package]] name = "async-channel" version = "1.9.0" @@ -1022,27 +812,6 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" -[[package]] -name = "brotli" -version = "3.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "516074a47ef4bce09577a3b379392300159ce5b1ba2e501ff1c819950066100f" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", - "brotli-decompressor", -] - -[[package]] -name = "brotli-decompressor" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da74e2b81409b1b743f8f0c62cc6254afefb8b8e50bbfe3735550f7aeefa3448" -dependencies = [ - "alloc-no-stdlib", - "alloc-stdlib", -] - [[package]] name = "bs58" version = "0.4.0" @@ -1056,6 +825,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" dependencies = [ "sha2 0.10.8", + "tinyvec", ] [[package]] @@ -1101,15 +871,6 @@ dependencies = [ "serde", ] -[[package]] -name = "bytestring" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "238e4886760d98c4f899360c834fa93e62cf7f721ac3c2da375cbdf4b8679aae" -dependencies = [ - "bytes", -] - [[package]] name = "cast" version = "0.3.0" @@ -1128,7 +889,6 @@ version = "1.0.83" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" dependencies = [ - "jobserver", "libc", ] @@ -1422,20 +1182,6 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "config" -version = "0.13.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7" -dependencies = [ - "async-trait", - "lazy_static", - "nom", - "pathdiff", - "serde", - "toml 0.5.11", -] - [[package]] name = "console-api" version = "0.5.0" @@ -1520,23 +1266,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" -[[package]] -name = "convert_case" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e" - -[[package]] -name = "cookie" -version = "0.16.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e859cd57d0710d9e06c381b550c06e76992472a8c6d527aecd2fc673dcc231fb" -dependencies = [ - "percent-encoding", - "time", - "version_check", -] - [[package]] name = "cookie" version = "0.18.0" @@ -1871,12 +1600,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "crunchy" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7" - [[package]] name = "crypto-bigint" version = "0.4.9" @@ -2044,7 +1767,6 @@ dependencies = [ "cfg-if", "cpufeatures", "curve25519-dalek-derive", - "digest 0.10.7", "fiat-crypto", "platforms", "rustc_version 0.4.0", @@ -2436,19 +2158,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "derive_more" -version = "0.99.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321" -dependencies = [ - "convert_case", - "proc-macro2", - "quote", - "rustc_version 0.4.0", - "syn 1.0.109", -] - [[package]] name = "devise" version = "0.4.1" @@ -2610,6 +2319,7 @@ dependencies = [ "digest 0.10.7", "elliptic-curve 0.13.6", "rfc6979 0.4.0", + "serdect", "signature 2.1.0", "spki 0.7.2", ] @@ -2662,20 +2372,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ed25519-dalek" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980" -dependencies = [ - "curve25519-dalek 4.1.1", - "ed25519 2.2.3", - "rand_core 0.6.4", - "serde", - "sha2 0.10.8", - "zeroize", -] - [[package]] name = "ed25519-zebra" version = "3.1.0" @@ -2734,6 +2430,7 @@ dependencies = [ "pkcs8 0.10.2", "rand_core 0.6.4", "sec1 0.7.3", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -2782,55 +2479,6 @@ dependencies = [ "regex", ] -[[package]] -name = "ephemera" -version = "0.1.0" -dependencies = [ - "actix-web", - "anyhow", - "array-bytes", - "assert_matches", - "async-trait", - "asynchronous-codec", - "blake2 0.10.6", - "bs58 0.4.0", - "bytes", - "cfg-if", - "chrono", - "clap 4.4.7", - "config", - "digest 0.10.7", - "dirs 5.0.1", - "enum-as-inner", - "futures", - "futures-util", - "lazy_static", - "libp2p 0.51.3", - "libp2p-identity", - "log", - "lru 0.10.1", - "nym-config", - "nym-ephemera-common", - "nym-task", - "pretty_env_logger", - "rand 0.8.5", - "refinery", - "reqwest", - "rusqlite", - "serde", - "serde_derive", - "serde_json", - "thiserror", - "tokio", - "tokio-tungstenite", - "tokio-util", - "toml 0.7.8", - "unsigned-varint", - "utoipa", - "utoipa-swagger-ui", - "uuid 1.5.0", -] - [[package]] name = "equivalent" version = "1.0.1" @@ -2872,7 +2520,6 @@ dependencies = [ "humantime-serde", "isocountry", "itertools 0.10.5", - "lazy_static", "log", "maxminddb", "nym-bin-common", @@ -2953,18 +2600,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "fallible-iterator" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4443176a9f2c162692bd3d352d745ef9413eec5782a80d8fd6f8a1ac692a07f7" - -[[package]] -name = "fallible-streaming-iterator" -version = "0.1.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" - [[package]] name = "fastrand" version = "1.9.0" @@ -3481,15 +3116,6 @@ dependencies = [ "serde_json", ] -[[package]] -name = "hashbrown" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" -dependencies = [ - "ahash 0.7.6", -] - [[package]] name = "hashbrown" version = "0.12.3" @@ -3518,15 +3144,6 @@ dependencies = [ "allocator-api2", ] -[[package]] -name = "hashlink" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" -dependencies = [ - "hashbrown 0.11.2", -] - [[package]] name = "hashlink" version = "0.8.4" @@ -3792,7 +3409,7 @@ dependencies = [ "futures-util", "http", "hyper", - "rustls 0.21.7", + "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", ] @@ -4210,15 +3827,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" -[[package]] -name = "jobserver" -version = "0.1.27" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" -dependencies = [ - "libc", -] - [[package]] name = "js-sys" version = "0.3.64" @@ -4268,12 +3876,6 @@ dependencies = [ "libc", ] -[[package]] -name = "language-tags" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4345964bb142484797b161f473a503a434de77149dd8c7427788c6e13379388" - [[package]] name = "lazy_static" version = "1.4.0" @@ -4350,80 +3952,25 @@ dependencies = [ "futures-timer", "getrandom 0.2.10", "instant", - "libp2p-core 0.39.0", - "libp2p-dns 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-gossipsub 0.44.0", + "libp2p-core", + "libp2p-dns", + "libp2p-gossipsub", "libp2p-identify", - "libp2p-mdns 0.43.0", - "libp2p-metrics 0.12.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-mdns", + "libp2p-metrics", "libp2p-mplex", - "libp2p-noise 0.42.0", + "libp2p-noise", "libp2p-ping", - "libp2p-quic 0.7.0-alpha.2", - "libp2p-swarm 0.42.0", - "libp2p-tcp 0.39.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", - "libp2p-webrtc 0.4.0-alpha.2", + "libp2p-quic", + "libp2p-swarm", + "libp2p-tcp", + "libp2p-webrtc", "libp2p-websocket", - "libp2p-yamux 0.43.0", - "multiaddr 0.17.0", + "libp2p-yamux", + "multiaddr", "pin-project", ] -[[package]] -name = "libp2p" -version = "0.51.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f210d259724eae82005b5c48078619b7745edb7b76de370b03f8ba59ea103097" -dependencies = [ - "bytes", - "futures", - "futures-timer", - "getrandom 0.2.10", - "instant", - "libp2p-allow-block-list", - "libp2p-connection-limits", - "libp2p-core 0.39.2", - "libp2p-dns 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-gossipsub 0.44.4", - "libp2p-identity", - "libp2p-kad", - "libp2p-mdns 0.43.1", - "libp2p-metrics 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-noise 0.42.2", - "libp2p-quic 0.7.0-alpha.3", - "libp2p-request-response", - "libp2p-swarm 0.42.2", - "libp2p-tcp 0.39.0 (registry+https://github.com/rust-lang/crates.io-index)", - "libp2p-webrtc 0.4.0-alpha.4", - "libp2p-yamux 0.43.1", - "multiaddr 0.17.1", - "pin-project", -] - -[[package]] -name = "libp2p-allow-block-list" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "510daa05efbc25184458db837f6f9a5143888f1caa742426d92e1833ddd38a50" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "void", -] - -[[package]] -name = "libp2p-connection-limits" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4caa33f1d26ed664c4fe2cca81a08c8e07d4c1c04f2f4ac7655c2dd85467fda0" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "void", -] - [[package]] name = "libp2p-core" version = "0.39.0" @@ -4431,23 +3978,23 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "asn1_der", "bs58 0.4.0", - "ed25519-dalek 1.0.1", + "ed25519-dalek", "either", "fnv", "futures", "futures-timer", "instant", "log", - "multiaddr 0.17.0", + "multiaddr", "multihash", - "multistream-select 0.12.1 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "multistream-select", "once_cell", "parking_lot 0.12.1", "pin-project", "prost 0.11.9", "prost-build", "rand 0.8.5", - "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "rw-stream-sink", "sec1 0.3.0", "sha2 0.10.8", "smallvec", @@ -4457,56 +4004,13 @@ dependencies = [ "zeroize", ] -[[package]] -name = "libp2p-core" -version = "0.39.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c1df63c0b582aa434fb09b2d86897fa2b419ffeccf934b36f87fcedc8e835c2" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-identity", - "log", - "multiaddr 0.17.1", - "multihash", - "multistream-select 0.12.1 (registry+https://github.com/rust-lang/crates.io-index)", - "once_cell", - "parking_lot 0.12.1", - "pin-project", - "quick-protobuf", - "rand 0.8.5", - "rw-stream-sink 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "serde", - "smallvec", - "thiserror", - "unsigned-varint", - "void", -] - -[[package]] -name = "libp2p-dns" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146ff7034daae62077c415c2376b8057368042df6ab95f5432ad5e88568b1554" -dependencies = [ - "futures", - "libp2p-core 0.39.2", - "log", - "parking_lot 0.12.1", - "smallvec", - "trust-dns-resolver", -] - [[package]] name = "libp2p-dns" version = "0.39.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "parking_lot 0.12.1", "smallvec", @@ -4526,8 +4030,8 @@ dependencies = [ "futures", "hex_fmt", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "prometheus-client", "prost 0.11.9", @@ -4542,39 +4046,6 @@ dependencies = [ "wasm-timer", ] -[[package]] -name = "libp2p-gossipsub" -version = "0.44.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70b34b6da8165c0bde35c82db8efda39b824776537e73973549e76cadb3a77c5" -dependencies = [ - "asynchronous-codec", - "base64 0.21.4", - "byteorder", - "bytes", - "either", - "fnv", - "futures", - "hex_fmt", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "prometheus-client", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "regex", - "serde", - "sha2 0.10.8", - "smallvec", - "thiserror", - "unsigned-varint", - "void", - "wasm-timer", -] - [[package]] name = "libp2p-identify" version = "0.42.0" @@ -4584,10 +4055,10 @@ dependencies = [ "either", "futures", "futures-timer", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", - "lru 0.9.0", + "lru", "prost 0.11.9", "prost-build", "prost-codec", @@ -4596,54 +4067,6 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-identity" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "276bb57e7af15d8f100d3c11cbdd32c6752b7eef4ba7a18ecf464972c07abcce" -dependencies = [ - "bs58 0.4.0", - "ed25519-dalek 2.0.0", - "log", - "multiaddr 0.17.1", - "multihash", - "quick-protobuf", - "rand 0.8.5", - "serde", - "sha2 0.10.8", - "thiserror", - "zeroize", -] - -[[package]] -name = "libp2p-kad" -version = "0.43.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39d5ef876a2b2323d63c258e63c2f8e36f205fe5a11f0b3095d59635650790ff" -dependencies = [ - "arrayvec", - "asynchronous-codec", - "bytes", - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "quick-protobuf", - "rand 0.8.5", - "serde", - "sha2 0.10.8", - "smallvec", - "thiserror", - "uint", - "unsigned-varint", - "void", -] - [[package]] name = "libp2p-mdns" version = "0.43.0" @@ -4652,8 +4075,8 @@ dependencies = [ "data-encoding", "futures", "if-watch", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "rand 0.8.5", "smallvec", @@ -4663,50 +4086,16 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-mdns" -version = "0.43.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19983e1f949f979a928f2c603de1cf180cc0dc23e4ac93a62651ccb18341460b" -dependencies = [ - "data-encoding", - "futures", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "log", - "rand 0.8.5", - "smallvec", - "socket2 0.4.9", - "tokio", - "trust-dns-proto", - "void", -] - -[[package]] -name = "libp2p-metrics" -version = "0.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a42ec91e227d7d0dafa4ce88b333cdf5f277253873ab087555c92798db2ddd46" -dependencies = [ - "libp2p-core 0.39.2", - "libp2p-gossipsub 0.44.4", - "libp2p-kad", - "libp2p-swarm 0.42.2", - "prometheus-client", -] - [[package]] name = "libp2p-metrics" version = "0.12.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ - "libp2p-core 0.39.0", - "libp2p-gossipsub 0.44.0", + "libp2p-core", + "libp2p-gossipsub", "libp2p-identify", "libp2p-ping", - "libp2p-swarm 0.42.0", + "libp2p-swarm", "prometheus-client", ] @@ -4718,7 +4107,7 @@ dependencies = [ "asynchronous-codec", "bytes", "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "nohash-hasher", "parking_lot 0.12.1", @@ -4735,7 +4124,7 @@ dependencies = [ "bytes", "curve25519-dalek 3.2.0", "futures", - "libp2p-core 0.39.0", + "libp2p-core", "log", "once_cell", "prost 0.11.9", @@ -4749,29 +4138,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "libp2p-noise" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c3673da89d29936bc6435bafc638e2f184180d554ce844db65915113f86ec5e" -dependencies = [ - "bytes", - "curve25519-dalek 3.2.0", - "futures", - "libp2p-core 0.39.2", - "libp2p-identity", - "log", - "once_cell", - "quick-protobuf", - "rand 0.8.5", - "sha2 0.10.8", - "snow", - "static_assertions", - "thiserror", - "x25519-dalek 1.1.1", - "zeroize", -] - [[package]] name = "libp2p-ping" version = "0.42.0" @@ -4781,8 +4147,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm 0.42.0", + "libp2p-core", + "libp2p-swarm", "log", "rand 0.8.5", "void", @@ -4797,8 +4163,8 @@ dependencies = [ "futures", "futures-timer", "if-watch", - "libp2p-core 0.39.0", - "libp2p-tls 0.1.0-alpha.2", + "libp2p-core", + "libp2p-tls", "log", "parking_lot 0.12.1", "quinn-proto", @@ -4808,44 +4174,6 @@ dependencies = [ "tokio", ] -[[package]] -name = "libp2p-quic" -version = "0.7.0-alpha.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6b26abd81cd2398382a1edfe739b539775be8a90fa6914f39b2ab49571ec735" -dependencies = [ - "bytes", - "futures", - "futures-timer", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-tls 0.1.0", - "log", - "parking_lot 0.12.1", - "quinn-proto", - "rand 0.8.5", - "rustls 0.20.9", - "thiserror", - "tokio", -] - -[[package]] -name = "libp2p-request-response" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ffdb374267d42dc5ed5bc53f6e601d4a64ac5964779c6e40bb9e4f14c1e30d5" -dependencies = [ - "async-trait", - "futures", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm 0.42.2", - "rand 0.8.5", - "smallvec", -] - [[package]] name = "libp2p-swarm" version = "0.42.0" @@ -4856,8 +4184,8 @@ dependencies = [ "futures", "futures-timer", "instant", - "libp2p-core 0.39.0", - "libp2p-swarm-derive 0.32.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "libp2p-core", + "libp2p-swarm-derive", "log", "rand 0.8.5", "smallvec", @@ -4865,38 +4193,6 @@ dependencies = [ "void", ] -[[package]] -name = "libp2p-swarm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "903b3d592d7694e56204d211f29d31bc004be99386644ba8731fc3e3ef27b296" -dependencies = [ - "either", - "fnv", - "futures", - "futures-timer", - "instant", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-swarm-derive 0.32.0 (registry+https://github.com/rust-lang/crates.io-index)", - "log", - "rand 0.8.5", - "smallvec", - "tokio", - "void", -] - -[[package]] -name = "libp2p-swarm-derive" -version = "0.32.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fba456131824ab6acd4c7bf61e9c0f0a3014b5fc9868ccb8e10d344594cdc4f" -dependencies = [ - "heck 0.4.1", - "quote", - "syn 1.0.109", -] - [[package]] name = "libp2p-swarm-derive" version = "0.32.0" @@ -4907,22 +4203,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "libp2p-tcp" -version = "0.39.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33d33698596d7722d85d3ab0c86c2c322254fce1241e91208e3679b4eb3026cf" -dependencies = [ - "futures", - "futures-timer", - "if-watch", - "libc", - "libp2p-core 0.39.2", - "log", - "socket2 0.4.9", - "tokio", -] - [[package]] name = "libp2p-tcp" version = "0.39.0" @@ -4932,7 +4212,7 @@ dependencies = [ "futures-timer", "if-watch", "libc", - "libp2p-core 0.39.0", + "libp2p-core", "log", "socket2 0.4.9", "tokio", @@ -4945,26 +4225,7 @@ source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c dependencies = [ "futures", "futures-rustls", - "libp2p-core 0.39.0", - "rcgen 0.10.0", - "ring 0.16.20", - "rustls 0.20.9", - "thiserror", - "webpki 0.22.4", - "x509-parser 0.14.0", - "yasna", -] - -[[package]] -name = "libp2p-tls" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff08d13d0dc66e5e9ba6279c1de417b84fa0d0adc3b03e5732928c180ec02781" -dependencies = [ - "futures", - "futures-rustls", - "libp2p-core 0.39.2", - "libp2p-identity", + "libp2p-core", "rcgen 0.10.0", "ring 0.16.20", "rustls 0.20.9", @@ -4986,8 +4247,8 @@ dependencies = [ "futures-timer", "hex", "if-watch", - "libp2p-core 0.39.0", - "libp2p-noise 0.42.0", + "libp2p-core", + "libp2p-noise", "log", "multihash", "prost 0.11.9", @@ -5004,37 +4265,6 @@ dependencies = [ "webrtc", ] -[[package]] -name = "libp2p-webrtc" -version = "0.4.0-alpha.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dba48592edbc2f60b4bc7c10d65445b0c3964c07df26fdf493b6880d33be36f8" -dependencies = [ - "async-trait", - "asynchronous-codec", - "bytes", - "futures", - "futures-timer", - "hex", - "if-watch", - "libp2p-core 0.39.2", - "libp2p-identity", - "libp2p-noise 0.42.2", - "log", - "multihash", - "quick-protobuf", - "quick-protobuf-codec", - "rand 0.8.5", - "rcgen 0.9.3", - "serde", - "stun", - "thiserror", - "tinytemplate", - "tokio", - "tokio-util", - "webrtc", -] - [[package]] name = "libp2p-websocket" version = "0.41.0" @@ -5043,11 +4273,11 @@ dependencies = [ "either", "futures", "futures-rustls", - "libp2p-core 0.39.0", + "libp2p-core", "log", "parking_lot 0.12.1", "quicksink", - "rw-stream-sink 0.3.0 (git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6)", + "rw-stream-sink", "soketto", "url", "webpki-roots 0.22.6", @@ -5059,20 +4289,7 @@ version = "0.43.0" source = "git+https://github.com/ChainSafe/rust-libp2p.git?rev=e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6#e3440d25681df380c9f0f8cfdcfd5ecc0a4f2fb6" dependencies = [ "futures", - "libp2p-core 0.39.0", - "log", - "thiserror", - "yamux", -] - -[[package]] -name = "libp2p-yamux" -version = "0.43.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4dcd21d950662700a385d4c6d68e2f5f54d778e97068cdd718522222ef513bda" -dependencies = [ - "futures", - "libp2p-core 0.39.2", + "libp2p-core", "log", "thiserror", "yamux", @@ -5131,23 +4348,6 @@ dependencies = [ "keystream", ] -[[package]] -name = "local-channel" -version = "0.1.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0a493488de5f18c8ffcba89eebb8532ffc562dc400490eb65b84893fae0b178" -dependencies = [ - "futures-core", - "futures-sink", - "local-waker", -] - -[[package]] -name = "local-waker" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e34f76eb3611940e0e7d53a9aaa4e6a3151f69541a282fd0dad5571420c53ff1" - [[package]] name = "lock_api" version = "0.4.11" @@ -5188,15 +4388,6 @@ dependencies = [ "hashbrown 0.13.2", ] -[[package]] -name = "lru" -version = "0.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "718e8fae447df0c7e1ba7f5189829e63fd536945c8988d61444c19039f16b670" -dependencies = [ - "hashbrown 0.13.2", -] - [[package]] name = "lru-cache" version = "0.1.2" @@ -5400,25 +4591,6 @@ dependencies = [ "url", ] -[[package]] -name = "multiaddr" -version = "0.17.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b36f567c7099511fa8612bbbb52dda2419ce0bdbacf31714e3a5ffdb766d3bd" -dependencies = [ - "arrayref", - "byteorder", - "data-encoding", - "log", - "multibase", - "multihash", - "percent-encoding", - "serde", - "static_assertions", - "unsigned-varint", - "url", -] - [[package]] name = "multibase" version = "0.9.1" @@ -5439,8 +4611,6 @@ dependencies = [ "core2", "digest 0.10.7", "multihash-derive", - "serde", - "serde-big-array", "sha2 0.10.8", "unsigned-varint", ] @@ -5465,20 +4635,6 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e5ce46fe64a9d73be07dcbe690a38ce1b293be448fd8ce1e6c1b8062c9f72c6a" -[[package]] -name = "multistream-select" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8552ab875c1313b97b8d20cb857b9fd63e2d1d6a0a1b53ce9821e575405f27a" -dependencies = [ - "bytes", - "futures", - "log", - "pin-project", - "smallvec", - "unsigned-varint", -] - [[package]] name = "multistream-select" version = "0.12.1" @@ -5766,14 +4922,11 @@ dependencies = [ name = "nym-api" version = "1.1.35" dependencies = [ - "actix-web", "anyhow", - "array-bytes", "async-trait", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", - "chrono", "clap 4.4.7", "console-subscriber", "cosmwasm-std", @@ -5782,13 +4935,11 @@ dependencies = [ "cw3", "cw4", "dirs 4.0.0", - "ephemera", "futures", - "futures-util", "getset", "humantime-serde", "itertools 0.12.0", - "lazy_static", + "k256", "log", "nym-api-requests", "nym-bandwidth-controller", @@ -5796,14 +4947,12 @@ dependencies = [ "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-credential-storage", "nym-credentials", "nym-crypto", "nym-dkg", - "nym-ephemera-common", "nym-gateway-client", "nym-inclusion-probability", "nym-mixnet-contract-common", @@ -5830,7 +4979,6 @@ dependencies = [ "rocket_okapi", "schemars", "serde", - "serde_derive", "serde_json", "sha2 0.9.9", "sqlx", @@ -5842,7 +4990,6 @@ dependencies = [ "tokio-stream", "ts-rs", "url", - "uuid 1.5.0", "zeroize", ] @@ -5850,11 +4997,12 @@ dependencies = [ name = "nym-api-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", + "ecdsa 0.16.8", "getset", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-node-requests", @@ -5869,9 +5017,11 @@ name = "nym-bandwidth-controller" version = "0.1.0" dependencies = [ "bip39", - "nym-coconut-interface", + "log", + "nym-coconut", "nym-credential-storage", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-network-defaults", "nym-validator-client", @@ -5927,7 +5077,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "clap_complete", "clap_complete_fig", @@ -5952,7 +5102,7 @@ dependencies = [ "anyhow", "base64 0.13.1", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "comfy-table", @@ -5960,6 +5110,7 @@ dependencies = [ "cosmwasm-std", "csv", "cw-utils", + "futures", "handlebars", "humantime-serde", "inquire", @@ -5975,6 +5126,7 @@ dependencies = [ "nym-credential-storage", "nym-credential-utils", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-mixnet-contract-common", "nym-multisig-contract-common", @@ -5992,24 +5144,25 @@ dependencies = [ "tap", "thiserror", "time", + "tokio", "toml 0.5.11", "url", + "zeroize", ] [[package]] name = "nym-client" version = "1.1.33" dependencies = [ + "bs58 0.5.0", "clap 4.4.7", "dirs 4.0.0", "futures", - "lazy_static", "log", "nym-bandwidth-controller", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -6021,15 +5174,16 @@ dependencies = [ "nym-task", "nym-topology", "nym-validator-client", - "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", + "time", "tokio", "tokio-tungstenite", "url", + "zeroize", ] [[package]] @@ -6120,7 +5274,7 @@ name = "nym-coconut" version = "0.5.0" dependencies = [ "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "criterion", "digest 0.9.0", "doc-comment", @@ -6162,17 +5316,6 @@ dependencies = [ "nym-multisig-contract-common", ] -[[package]] -name = "nym-coconut-interface" -version = "0.1.0" -dependencies = [ - "bs58 0.4.0", - "getset", - "nym-coconut", - "serde", - "thiserror", -] - [[package]] name = "nym-config" version = "0.1.0" @@ -6190,7 +5333,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -6208,6 +5351,7 @@ dependencies = [ "sqlx", "thiserror", "tokio", + "zeroize", ] [[package]] @@ -6217,6 +5361,7 @@ dependencies = [ "log", "nym-bandwidth-controller", "nym-client-core", + "nym-coconut", "nym-config", "nym-credential-storage", "nym-credentials", @@ -6229,29 +5374,42 @@ dependencies = [ name = "nym-credentials" version = "0.1.0" dependencies = [ + "bincode", "bls12_381", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "log", "nym-api-requests", - "nym-coconut-interface", + "nym-credentials-interface", "nym-crypto", "nym-validator-client", "rand 0.7.3", + "serde", "thiserror", + "time", "zeroize", ] +[[package]] +name = "nym-credentials-interface" +version = "0.1.0" +dependencies = [ + "bls12_381", + "nym-coconut", + "serde", + "thiserror", +] + [[package]] name = "nym-crypto" version = "0.4.0" dependencies = [ "aes 0.8.3", "blake3", - "bs58 0.4.0", + "bs58 0.5.0", "cipher 0.4.4", "ctr 0.9.2", "digest 0.10.7", - "ed25519-dalek 1.0.1", + "ed25519-dalek", "generic-array 0.14.7", "hkdf 0.12.3", "hmac 0.12.1", @@ -6273,7 +5431,7 @@ version = "0.1.0" dependencies = [ "bitvec", "bls12_381", - "bs58 0.4.0", + "bs58 0.5.0", "criterion", "ff 0.13.0", "group 0.13.0", @@ -6353,7 +5511,7 @@ dependencies = [ "async-trait", "atty", "bip39", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "colored", "dashmap", @@ -6364,13 +5522,12 @@ dependencies = [ "humantime-serde", "hyper", "ipnetwork 0.16.0", - "lazy_static", "log", "nym-api-requests", "nym-bin-common", - "nym-coconut-interface", "nym-config", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-gateway-requests", "nym-ip-packet-router", @@ -6395,6 +5552,7 @@ dependencies = [ "sqlx", "subtle-encoding", "thiserror", + "time", "tokio", "tokio-stream", "tokio-tungstenite", @@ -6413,8 +5571,8 @@ dependencies = [ "gloo-utils", "log", "nym-bandwidth-controller", - "nym-coconut-interface", "nym-credential-storage", + "nym-credentials", "nym-crypto", "nym-gateway-requests", "nym-network-defaults", @@ -6440,12 +5598,12 @@ dependencies = [ name = "nym-gateway-requests" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "futures", "generic-array 0.14.7", "log", - "nym-coconut-interface", "nym-credentials", + "nym-credentials-interface", "nym-crypto", "nym-pemstore", "nym-sphinx", @@ -6497,12 +5655,11 @@ name = "nym-ip-packet-router" version = "0.1.0" dependencies = [ "bincode", - "bs58 0.4.0", + "bs58 0.5.0", "bytes", "clap 4.4.7", "etherparse", "futures", - "lazy_static", "log", "nym-bin-common", "nym-client-core", @@ -6571,7 +5728,7 @@ version = "1.1.35" dependencies = [ "anyhow", "axum", - "bs58 0.4.0", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "colored", @@ -6580,7 +5737,6 @@ dependencies = [ "dirs 4.0.0", "futures", "humantime-serde", - "lazy_static", "log", "nym-bin-common", "nym-config", @@ -6693,19 +5849,19 @@ dependencies = [ "anyhow", "async-file-watcher", "async-trait", - "bs58 0.4.0", + "bs58 0.5.0", "clap 4.4.7", "dirs 4.0.0", "futures", "humantime-serde", "ipnetwork 0.20.0", - "lazy_static", "log", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", "nym-config", "nym-credential-storage", + "nym-credentials", "nym-crypto", "nym-exit-policy", "nym-network-defaults", @@ -6729,9 +5885,11 @@ dependencies = [ "tap", "tempfile", "thiserror", + "time", "tokio", "tokio-tungstenite", "url", + "zeroize", ] [[package]] @@ -6917,7 +6075,7 @@ dependencies = [ "hex", "http", "httpcodec", - "libp2p 0.51.0", + "libp2p", "log", "nym-bandwidth-controller", "nym-bin-common", @@ -6983,12 +6141,11 @@ dependencies = [ name = "nym-socks5-client" version = "1.1.33" dependencies = [ + "bs58 0.5.0", "clap 4.4.7", - "lazy_static", "log", "nym-bin-common", "nym-client-core", - "nym-coconut-interface", "nym-config", "nym-credential-storage", "nym-credentials", @@ -7000,14 +6157,15 @@ dependencies = [ "nym-socks5-client-core", "nym-sphinx", "nym-topology", - "pretty_env_logger", "rand 0.7.3", "serde", "serde_json", "tap", "thiserror", + "time", "tokio", "url", + "zeroize", ] [[package]] @@ -7151,7 +6309,7 @@ dependencies = [ name = "nym-sphinx-anonymous-replies" version = "0.1.0" dependencies = [ - "bs58 0.4.0", + "bs58 0.5.0", "nym-crypto", "nym-sphinx-addressing", "nym-sphinx-params", @@ -7291,7 +6449,7 @@ name = "nym-topology" version = "0.1.0" dependencies = [ "async-trait", - "bs58 0.4.0", + "bs58 0.5.0", "log", "nym-api-requests", "nym-bin-common", @@ -7334,7 +6492,6 @@ dependencies = [ "hmac 0.12.1", "itertools 0.11.0", "log", - "nym-coconut-interface", "nym-config", "nym-crypto", "nym-mixnet-contract-common", @@ -7376,9 +6533,9 @@ dependencies = [ "itertools 0.10.5", "log", "nym-api-requests", + "nym-coconut", "nym-coconut-bandwidth-contract-common", "nym-coconut-dkg-common", - "nym-coconut-interface", "nym-config", "nym-contracts-common", "nym-ephemera-common", @@ -7548,6 +6705,7 @@ dependencies = [ "tendermint", "tendermint-rpc", "thiserror", + "time", "tokio", "tokio-stream", "tokio-util", @@ -7855,12 +7013,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" -[[package]] -name = "pathdiff" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd" - [[package]] name = "pbkdf2" version = "0.12.2" @@ -8417,28 +7569,6 @@ version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" -[[package]] -name = "quick-protobuf" -version = "0.8.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6da84cc204722a989e01ba2f6e1e276e190f22263d0cb6ce8526fcdb0d2e1f" -dependencies = [ - "byteorder", -] - -[[package]] -name = "quick-protobuf-codec" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1693116345026436eb2f10b677806169c1a1260c1c60eaaffe3fb5a29ae23d8b" -dependencies = [ - "asynchronous-codec", - "bytes", - "quick-protobuf", - "thiserror", - "unsigned-varint", -] - [[package]] name = "quicksink" version = "0.1.2" @@ -8800,50 +7930,6 @@ dependencies = [ "syn 2.0.38", ] -[[package]] -name = "refinery" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "529664dbccc0a296947615c997a857912d72d1c44be1fafb7bae54ecfa7a8c24" -dependencies = [ - "refinery-core", - "refinery-macros", -] - -[[package]] -name = "refinery-core" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e895cb870cf06e92318cbbeb701f274d022d5ca87a16fa8244e291cd035ef954" -dependencies = [ - "async-trait", - "cfg-if", - "lazy_static", - "log", - "regex", - "rusqlite", - "serde", - "siphasher", - "thiserror", - "time", - "toml 0.7.8", - "url", - "walkdir", -] - -[[package]] -name = "refinery-macros" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "123e8b80f8010c3ae38330c81e76938fc7adf6cdbfbaad20295bb8c22718b4f1" -dependencies = [ - "proc-macro2", - "quote", - "refinery-core", - "regex", - "syn 2.0.38", -] - [[package]] name = "regex" version = "1.10.2" @@ -8911,7 +7997,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.7", + "rustls 0.21.10", "rustls-native-certs", "rustls-pemfile", "serde", @@ -9079,7 +8165,7 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e" dependencies = [ - "cookie 0.18.0", + "cookie", "either", "futures", "http", @@ -9168,21 +8254,6 @@ dependencies = [ "webrtc-util", ] -[[package]] -name = "rusqlite" -version = "0.27.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85127183a999f7db96d1a976a309eebbfb6ea3b0b400ddd8340190129de6eb7a" -dependencies = [ - "bitflags 1.3.2", - "fallible-iterator", - "fallible-streaming-iterator", - "hashlink 0.7.0", - "libsqlite3-sys", - "memchr", - "smallvec", -] - [[package]] name = "rust-embed" version = "6.8.1" @@ -9311,12 +8382,12 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.7" +version = "0.21.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd8d6c9f025a446bc4d18ad9632e69aec8f287aa84499ee335599fabd20c3fd8" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" dependencies = [ "log", - "ring 0.16.20", + "ring 0.17.4", "rustls-webpki", "sct 0.7.0", ] @@ -9344,12 +8415,12 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.6" +version = "0.101.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3c7d5dece342910d9ba34d259310cae3e0154b873b35408b787b59bce53d34fe" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" dependencies = [ - "ring 0.16.20", - "untrusted 0.7.1", + "ring 0.17.4", + "untrusted 0.9.0", ] [[package]] @@ -9358,17 +8429,6 @@ version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" -[[package]] -name = "rw-stream-sink" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26338f5e09bb721b85b135ea05af7767c90b52f6de4f087d4f4a3a9d64e7dc04" -dependencies = [ - "futures", - "pin-project", - "static_assertions", -] - [[package]] name = "rw-stream-sink" version = "0.3.0" @@ -9526,6 +8586,7 @@ dependencies = [ "der 0.7.8", "generic-array 0.14.7", "pkcs8 0.10.2", + "serdect", "subtle 2.4.1", "zeroize", ] @@ -9601,15 +8662,6 @@ dependencies = [ "serde_derive", ] -[[package]] -name = "serde-big-array" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd31f59f6fe2b0c055371bb2f16d7f0aa7d8881676c04a55b1596d1a17cd10a4" -dependencies = [ - "serde", -] - [[package]] name = "serde-json-wasm" version = "0.5.0" @@ -9767,6 +8819,16 @@ dependencies = [ "unsafe-libyaml", ] +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct 0.2.0", + "serde", +] + [[package]] name = "sha-1" version = "0.9.8" @@ -9889,12 +8951,6 @@ dependencies = [ "rand_core 0.6.4", ] -[[package]] -name = "siphasher" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54ac45299ccbd390721be55b412d41931911f654fa99e2cb8bfb57184b2061fe" - [[package]] name = "slab" version = "0.4.9" @@ -10099,7 +9155,7 @@ dependencies = [ "futures-executor", "futures-intrusive", "futures-util", - "hashlink 0.8.4", + "hashlink", "hex", "indexmap 1.9.3", "itoa", @@ -10707,7 +9763,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.7", + "rustls 0.21.10", "tokio", ] @@ -10768,7 +9824,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", + "rustls 0.21.10", "tokio", "tungstenite", ] @@ -11200,7 +10256,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.7", + "rustls 0.21.10", "sha1", "thiserror", "url", @@ -11247,18 +10303,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uncased" version = "0.9.9" @@ -11457,7 +10501,6 @@ version = "3.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "84614caa239fb25b2bb373a52859ffd94605ceb256eeb1d63436325cf81e3653" dependencies = [ - "actix-web", "axum", "mime_guess", "regex", @@ -11481,7 +10524,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc" dependencies = [ "getrandom 0.2.10", - "serde", "wasm-bindgen", ] @@ -12404,32 +11446,3 @@ dependencies = [ "crossbeam-utils", "flate2", ] - -[[package]] -name = "zstd" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c" -dependencies = [ - "zstd-safe", -] - -[[package]] -name = "zstd-safe" -version = "6.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee98ffd0b48ee95e6c5168188e44a54550b1564d9d530ee21d5f0eaed1069581" -dependencies = [ - "libc", - "zstd-sys", -] - -[[package]] -name = "zstd-sys" -version = "2.0.9+zstd.1.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656" -dependencies = [ - "cc", - "pkg-config", -] From 8f8cd79a65313ccf119f6a84b646f56a019a82db Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Tue, 20 Feb 2024 19:45:22 +0100 Subject: [PATCH 102/394] amend workflow to input event instead --- .../workflows/ci-build-upload-binaries.yml | 30 +++++++++++-------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/.github/workflows/ci-build-upload-binaries.yml b/.github/workflows/ci-build-upload-binaries.yml index eb4a271afd..3700b0b058 100644 --- a/.github/workflows/ci-build-upload-binaries.yml +++ b/.github/workflows/ci-build-upload-binaries.yml @@ -13,6 +13,11 @@ on: required: true default: false type: boolean + enable_deb: + description: "True to enable cargo-deb installation and .deb package building" + required: false + default: false + type: boolean schedule: - cron: '14 0 * * *' pull_request: @@ -79,17 +84,17 @@ jobs: command: build args: --workspace --release ${{ env.CARGO_FEATURES }} - # - name: Install cargo-deb - # uses: actions-rs/cargo@v1 - # with: - # command: install - # args: cargo-deb + - name: Install cargo-deb + if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true + uses: actions-rs/cargo@v1 + with: + command: install + args: cargo-deb - # - name: Build deb packages - # shell: bash - # run: make deb - - # If this was a manual workflow_dispatch, publish binaries. + - name: Build deb packages + if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true + shell: bash + run: make deb - name: Upload Artifact if: github.event_name == 'workflow_dispatch' @@ -124,10 +129,11 @@ jobs: cp target/release/nym-network-statistics $OUTPUT_DIR cp target/release/nym-cli $OUTPUT_DIR cp target/release/explorer-api $OUTPUT_DIR - # cp target/debian/*.deb $OUTPUT_DIR + if [ ${{ github.event_name == 'workflow_dispatch' && inputs.enable_deb == true }} = true ]; then + cp target/debian/*.deb $OUTPUT_DIR + fi - name: Deploy branch to CI www - # if: github.event_name == 'schedule' || github.event_name == 'pull_request' continue-on-error: true uses: easingthemes/ssh-deploy@main env: From 5a770614dd7fe28a73a139ae2973b32f9a8855d6 Mon Sep 17 00:00:00 2001 From: Tommy Verrall Date: Tue, 20 Feb 2024 19:48:04 +0100 Subject: [PATCH 103/394] formatting --- .github/workflows/ci-build-upload-binaries.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci-build-upload-binaries.yml b/.github/workflows/ci-build-upload-binaries.yml index 3700b0b058..df17c7f981 100644 --- a/.github/workflows/ci-build-upload-binaries.yml +++ b/.github/workflows/ci-build-upload-binaries.yml @@ -9,7 +9,7 @@ on: default: false type: boolean enable_wireguard: - description: 'Add --features wireguard' + description: "Add --features wireguard" required: true default: false type: boolean @@ -19,7 +19,7 @@ on: default: false type: boolean schedule: - - cron: '14 0 * * *' + - cron: "14 0 * * *" pull_request: paths: - "clients/**" @@ -85,16 +85,16 @@ jobs: args: --workspace --release ${{ env.CARGO_FEATURES }} - name: Install cargo-deb - if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true uses: actions-rs/cargo@v1 with: command: install args: cargo-deb + if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true - name: Build deb packages - if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true shell: bash run: make deb + if: github.event_name == 'workflow_dispatch' && inputs.enable_deb == true - name: Upload Artifact if: github.event_name == 'workflow_dispatch' From ac23ef924adf59dc05824121b1a8ba548bd2d1e4 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:27:12 +0000 Subject: [PATCH 104/394] [DOC]: Publish Nymvisor guide (#4423) --- documentation/operators/src/SUMMARY.md | 3 +- .../operators/src/nodes/nymvisor-upgrade.md | 86 +++++++++---------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/documentation/operators/src/SUMMARY.md b/documentation/operators/src/SUMMARY.md index d3b403d5b9..53e58ab2a3 100644 --- a/documentation/operators/src/SUMMARY.md +++ b/documentation/operators/src/SUMMARY.md @@ -20,8 +20,7 @@ - [Nym API Setup](nodes/nym-api.md) - [Maintenance](nodes/maintenance.md) - [Manual Node Upgrade](nodes/manual-upgrade.md) - -[//]: # ( - [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md)) + - [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md) - [Troubleshooting](nodes/troubleshooting.md) # FAQ diff --git a/documentation/operators/src/nodes/nymvisor-upgrade.md b/documentation/operators/src/nodes/nymvisor-upgrade.md index e3722634ab..fcee0a1564 100644 --- a/documentation/operators/src/nodes/nymvisor-upgrade.md +++ b/documentation/operators/src/nodes/nymvisor-upgrade.md @@ -1,13 +1,13 @@ # Automatic Node Upgrade: Nymvisor Setup and Usage -> The Nymvisor binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first. You can build just Nymvisor with `cargo build --release --bin nymvisor`. +> The Nymvisor binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first. You can build just Nymvisor with `cargo build --release --bin nymvisor`. > Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets. ## What is Nymvisor? -Nymvisor is a process manager for Nym binaries that monitors the Nym release information for any newly released binaries. If it detects any changes, Nymvisor can automatically download the binary, stop the current binary, switch from the old binary to the new one, and finally restart the underlying process with the new binary. +Nymvisor is a process manager for Nym binaries that monitors the Nym release information for any newly released binaries. If it detects any changes, Nymvisor can automatically download the binary, stop the current binary, switch from the old binary to the new one, and finally restart the underlying process with the new binary. -In essence, it tries to mirror the behaviour of [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor), a tool used by Cosmos blockchain operators for managing/automating chain upgrades. Nymvisor, however, introduces some Nym-specific changes since, for example, upgrade information is obtained from our GitHub [releases page](https://github.com/nymtech/nym/releases) instead of (in the case of Cosmos blockchains) governance proposals. +In essence, it tries to mirror the behaviour of [Cosmovisor](https://github.com/cosmos/cosmos-sdk/tree/main/tools/cosmovisor), a tool used by Cosmos blockchain operators for managing/automating chain upgrades. Nymvisor, however, introduces some Nym-specific changes since, for example, upgrade information is obtained from our GitHub [releases page](https://github.com/nymtech/nym/releases) instead of (in the case of Cosmos blockchains) governance proposals. You can use Nymvisor to automate the upgrades of the following binaries: * `nym-api` @@ -26,12 +26,12 @@ Nymvisor is an early and experimental software. Users should use it at their own ``` -## Preliminary steps -You need to have at least one Mixnet node / client / Nym API instance already set up on the **same VPS** that you wish to run Nymvisor on. +## Preliminary steps +You need to have at least one Mixnet node / client / Nym API instance already set up on the **same VPS** that you wish to run Nymvisor on. > Using Nymvisor presumes your VPS is running an operating system that is compatible with the pre-compiled binaries avaliable on the [Github releases page](https://github.com/nymtech/nym/releases). If you're not, then until we're packaging for a greater variety of operating systems, you're stuck with [manually upgrading your node](manual-upgrade.md). -## Setup and Usage +## Setup and Usage ### Viewing command help You can check that your binaries are properly compiled with: @@ -53,16 +53,16 @@ You can also check the various arguments required for individual commands with: ./nymvisor --help ``` -### Initialising your Nymvisor Instance -> This example will use the Mix Node binary as an example - however replacing `nym-mixnode` with any other supported binary will work the same. +### Initialising your Nymvisor Instance +> This example will use the Mix Node binary as an example - however replacing `nym-mixnode` with any other supported binary will work the same. -Initialise your Nymvisor instance with the following command. You must initialise Nymvisor with the binary you wish to add upgrades for: +Initialise your Nymvisor instance with the following command. You must initialise Nymvisor with the binary you wish to add upgrades for: ``` -./nymvisor init --daemon-home ~/.nym// +./nymvisor init --daemon-home ~/.nym// ``` -Where the value of `--daemon-home` might be `~/.nym/mixnodes/my-node` and `` might be `/home/my_user/nym/target/release/nym-mixnode`, or wherever your node binary is located. +Where the value of `--daemon-home` might be `~/.nym/mixnodes/my-node` and `` might be `/home/my_user/nym/target/release/nym-mixnode`, or wherever your node binary is located. ~~~admonish example collapsible=true title="Console output" ``` @@ -70,17 +70,17 @@ Where the value of `--daemon-home` might be `~/.nym/mixnodes/my-node` and `-default/config/config.toml` as shown in the console output above. For config options look at the different `--flags` available, or the [environment variables](nymvisor-upgrade.md#environment-variables) section below. +By default this will create config files at `~/.nym/nymvisors/instances/-default/config/config.toml` as shown in the console output above. For config options look at the different `--flags` available, or the [environment variables](nymvisor-upgrade.md#environment-variables) section below. -### Running your Nymvisor Instance -Nymvisor acts as a wrapper around the specified node process - it has to do this in order to be able to pause and restart this process. As such, you need to run your node _via_ Nymvisor! +### Running your Nymvisor Instance +Nymvisor acts as a wrapper around the specified node process - it has to do this in order to be able to pause and restart this process. As such, you need to run your node _via_ Nymvisor! The interface to the `nymvisor run ` command is quite simple. Any argument passed after the `run` command will be passed directly to the underlying daemon, for example: `nymvisor run run --id my-mixnode` will run the `$DAEMON_NAME run --id my-mixnode` command (where `DAEMON_NAME` is the name of the binary itself (e.g. `nym-api`, `nym-mixnode`, etc.)). -`run` Nymvisor and start your node via the following command. Make sure to stop any existing node before running this command. +`run` Nymvisor and start your node via the following command. Make sure to stop any existing node before running this command. ``` -./nymvisor run run --id +./nymvisor run run --id ``` ~~~admonish example collapsible=true title="Console output" @@ -91,21 +91,21 @@ The interface to the `nymvisor run ` command is quite simple. Any argument Nymvisor will now manage your node process (for an in-depth overview of this command check the [in-depth command information](./nymvisor-upgrade.md#commands-in-depth) below). It will periodically poll [this endpoint](https://nymtech.net/.wellknown/nym-mixnode/upgrade-info.json) (replace `nym-mixnode` with whatever node you may actually be running via Nymvisor) and check for a new `version` of the binary it is watching. If this exists, it will then, using the information there: * pause your node process -* grab the new binary (`version`) -* verify it against the provided `checksum` +* grab the new binary (`version`) +* verify it against the provided `checksum` * perform a data backup of the existing node -* replace the old binary with the new one -* restart the process +* replace the old binary with the new one +* restart the process -And that's it! Check the [maintenance page](./maintenance.md#for-nymvisor) for information on Nymvisor process maintenance and automation, and you can find more in-depth information about the various aspects of Nymvisor such as what happens [under the hood](#commands-in-depth) for various commands. +And that's it! Check the [maintenance page](./maintenance.md#for-nymvisor) for information on Nymvisor process maintenance and automation, and you can find more in-depth information about the various aspects of Nymvisor such as what happens [under the hood](#commands-in-depth) for various commands. -### Creating an Adhoc Upgrade +### Creating an Adhoc Upgrade `nymvisor add-upgrade --upgrade-name= --arg1=value1 --arg2=value2 ...` can be used to amend an existing `upgrade-plan.json` by creating new entries or to add an executable to an existing scheduled upgrade so that it would not have to be downloaded. ->Generally users **will not have to use this command**. Situations in which this command might be used are: -> - an adhoc upgrade if e.g. a patched version of a binary was required +>Generally users **will not have to use this command**. Situations in which this command might be used are: +> - an adhoc upgrade if e.g. a patched version of a binary was required > - if a user doesn't trust the verification process of Nymvisor's pipeline and wishes to build/verify the binary themselves before using Nymvisor to perform the upgrade -> - if a user isn't using a currently supported operating system and needs to manually specify a binary they have built themselves +> - if a user isn't using a currently supported operating system and needs to manually specify a binary they have built themselves Similarly to `init`, `add-upgrade` requires a positional argument specifying a valid path to the upgrade binary. Furthermore, the `--upgrade-name` keyword argument must be set in order to declare the upgrade name. The remaining arguments are optional. They include: - `--force` - if specified, will allow Nymvisor to overwrite existing upgrade binary / `upgrade-info.json` files if they already exist @@ -115,7 +115,7 @@ Similarly to `init`, `add-upgrade` requires a positional argument specifying a v - `--upgrade-time` - specifies the time at which the provided upgrade will be performed (RFC3339 formatted). If left unset, the upgrade will be performed in 15 minutes. It can't be specified alongside either `--now` or `--upgrade-delay` arguments. - `--upgrade-delay` - specifies delay until the provided upgrade is going to get performed. If let unset, the upgrade will be performed in 15 minutes. It can't be specified alongside either `--upgrade_time` or `--now` arguments. -## Config +## Config The output format of `nymvisor config` can be further configured with `--output` argument. By default a human-readable text representation is used: ``` id: nym-mixnode-default @@ -141,12 +141,12 @@ Adding `--output=json` would format the same data into JSON which can be more ea ``` nymvisor config --output=json ``` -outputs: +outputs: ``` {"nymvisor":{"id":"nym-mixnode-default","upstream_base_upgrade_url":"https://nymtech.net/.wellknown/","upstream_polling_rate":"1h","disable_logs":false,"upgrade_data_directory":null},"daemon":{"name":"nym-mixnode","home":"/home/nym/.nym/mixnodes/my-mixnode","absolute_upstream_upgrade_url":null,"allow_binaries_download":true,"enforce_download_checksum":true,"restart_after_upgrade":true,"restart_on_failure":false,"failure_restart_delay":"10s","max_startup_failures":10,"startup_period_duration":"2m","shutdown_grace_period":"10s","backup_data_directory":null,"unsafe_skip_backup":false}} ``` -## CLI Overview +## CLI Overview Command options are: - `help`, `--help`, or `-h` - Output Nymvisor help information and display the available commands. - `config` - Display the current Nymvisor configuration, that means displaying the current configuration file that might have been overridden with environment variables value that Nymvisor is using. @@ -167,7 +167,7 @@ For commands that depend on Nymvisor config file (i.e. all but `init`), the conf Nymvisor attempts to load the file from the derived path. If it fails, it attempts to use one of the older schemas to and upgrade it as it goes, the loaded configuration is then overridden with any value that might have been set in the environment. -## Environment Variables +## Environment Variables > Please note environmental variables take precedence over any arguments passed, i.e. if one were to specify `--daemon_home="/foo"` and set `DAEMON_HOME="bar"`, the value of `"bar"` would end up being used. @@ -248,14 +248,14 @@ A sample full structure looks as follows: ## Commands In-Depth This section outlines what happens under the hood with the following commands: -### Init +### Init `init` does the following: - executes the `$DAEMON_NAME build-info` command on the daemon executable to check its validity and obtain its name - creates the required directory structure: - - `$DAEMON_HOME/nymvisor` folder if it doesn't yet exist - - `$DAEMON_BACKUP_DATA_DIRECTORY` folder if it doesn't yet exist - - `$NYMVISOR_UPGRADE_DATA_DIRECTORY` folder if it doesn't yet exist - - `$NYMVISOR_UPGRADE_DATA_DIRECTORY/$DAEMON_NAME/genesis/bin` folder if it doesn't yet exist + - `$DAEMON_HOME/nymvisor` folder if it doesn't yet exist + - `$DAEMON_BACKUP_DATA_DIRECTORY` folder if it doesn't yet exist + - `$NYMVISOR_UPGRADE_DATA_DIRECTORY` folder if it doesn't yet exist + - `$NYMVISOR_UPGRADE_DATA_DIRECTORY/$DAEMON_NAME/genesis/bin` folder if it doesn't yet exist - `$NYMVISOR_UPGRADE_DATA_DIRECTORY/$DAEMON_NAME/upgrades` folder if it doesn't yet exist - copies the provided executable to `$NYMVISOR_UPGRADE_DATA_DIRECTORY/$DAEMON_NAME/genesis/bin/$DAEMON_NAME` - generates initial `$NYMVISOR_UPGRADE_DATA_DIRECTORY/$DAEMON_NAME/genesis/upgrade-info.json` file based on the provided binary @@ -266,21 +266,21 @@ This section outlines what happens under the hood with the following commands: > `nymvisor init` is specifically for initializing Nymvisor, and should **not** be confused with a daemon's `init` command - such as `nym-mixnode init` (e.g. `cosmovisor run init`). -### Run +### Run `nymvisor run` is a lightweight wrapper around the underlying daemon. It uses only a single thread and spawns three simple tasks: - an upstream poller that checks the upstream source (as defined by `DAEMON_ABSOLUTE_UPSTREAM_UPGRADE_URL` or derived from `NYMVISOR_UPSTREAM_BASE_UPGRADE_URL`) for any recently released upgrades. It then creates appropriate `upgrade-info.json` file and updates the `upgrade-plan.json` - a file watcher for the `upgrade-plan.json` file that can notify the main run loop of upgrades that were added by either the above upstream poller task or via the `add-upgrade` command, - the daemon run loop that: - runs the `DAEMON_NAME` with the provided arguments until: - - it completes the execution (with any exit code), - - Nymvisor receives a `SIGINT`, `SIGTERM` or `SIGQUIT`, - - a new upgrade is scheduled to be performed (by other task watching for changes in `upgrade-plan.json` and waiting until the `upgrade_time`, - - if `DAEMON_UNSAFE_SKIP_BACKUP` is not set to `true`, it backups the content of `DAEMON_HOME` directory, + - it completes the execution (with any exit code), + - Nymvisor receives a `SIGINT`, `SIGTERM` or `SIGQUIT`, + - a new upgrade is scheduled to be performed (by other task watching for changes in `upgrade-plan.json` and waiting until the `upgrade_time`, + - if `DAEMON_UNSAFE_SKIP_BACKUP` is not set to `true`, it backups the content of `DAEMON_HOME` directory, - performs the binary upgrade by: - - creating a temporary, exclusive and non-blocking, `upgrade.lock` file for the `DAEMON_NAME`. `flock` with `LOCK_EX | LOCK_NB` is used for that purpose. The file is created in case users didn't read any warnings and attempted to run multiple instances of `nymvisor` managing the same `DAEMON_NAME`, - - downloading the upgrade binary for the runners architecture using one of the urls defined in `upgrade-info.json`. Note, however, that this is only done if the binary associated with the `` does not already exist and `DAEMON_ALLOW_DOWNLOAD_BINARIES` is set to `true`, + - creating a temporary, exclusive and non-blocking, `upgrade.lock` file for the `DAEMON_NAME`. `flock` with `LOCK_EX | LOCK_NB` is used for that purpose. The file is created in case users didn't read any warnings and attempted to run multiple instances of `nymvisor` managing the same `DAEMON_NAME`, + - downloading the upgrade binary for the runners architecture using one of the urls defined in `upgrade-info.json`. Note, however, that this is only done if the binary associated with the `` does not already exist and `DAEMON_ALLOW_DOWNLOAD_BINARIES` is set to `true`, - if the binary has been downloaded and `DAEMON_ENFORCE_DOWNLOAD_CHECKSUM` is set to true, the file checksum is verified using the specified algorithm, - - verifying the upgrade binary - checking if it's a valid executable with expected `build-info`. Note that this will also set `a+x` bits on the file if those permissions have not already been set, + - verifying the upgrade binary - checking if it's a valid executable with expected `build-info`. Note that this will also set `a+x` bits on the file if those permissions have not already been set, - removing the queued upgrade from `upgrade-plan.json`, - inserting new upgrade into the `upgrade-history.json`, - updating the `current-version-info.json`, @@ -292,7 +292,7 @@ This section outlines what happens under the hood with the following commands: ### Add-Upgrade `nymvisor add-upgrade` does the following: -- executes the `$DAEMON_NAME build-info` command on the daemon executable to check its validity and obtain its name +- executes the `$DAEMON_NAME build-info` command on the daemon executable to check its validity and obtain its name - attempts to load existing `upgrade-info.json` for the provided ``. If it already exists and neither `--force` nor `--add-binary` was specified, Nymvisor will terminate - checks if `upgrades//$DAEMON_NAME` binary already exists. If it does and `--force` flag was not specified, Nymvisor will terminate the provided upgrade binary is copied to its appropriate location - if applicable, new `upgrade-info.json` is created and written to its appropriate location From a6ebfb521dbc53eb9222d180f7fabc1a76cdf539 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:20:57 +0100 Subject: [PATCH 105/394] remove redundant part --- .../dev-portal/src/nymvpn/gui-linux.md | 46 ++------------ .../dev-portal/src/nymvpn/old-gui-mac.md | 61 +++++++++++++++++++ 2 files changed, 66 insertions(+), 41 deletions(-) create mode 100644 documentation/dev-portal/src/nymvpn/old-gui-mac.md diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 01c2b0438d..55c0b4bbae 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -26,55 +26,19 @@ tar -xvf # for example # tar -xvf nym-vpn-desktop_0.0.4_ubuntu-22.04_x86_64.tar.gz ``` -2. Make executable by running: -```sh -# possibly you may have to cd into a sub-directory -chmod u+x -``` -5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: -```sh -curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env -``` - -## Run NymVPN - -**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. - -Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary. - -1. Go to [nymvpn.com/en/alpha](https://nymvpn.com/en/alpha) to get the entire command with all the needed arguments' values and your wireguard private key for testing purposes -2. Run it as root with `sudo` - the command will look like this with specified arguments: -```sh -sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit-router-address --enable-wireguard --private-key --wg-ip -``` -3. To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) and pick one -4. See all possibilities in [command explanation](#cli-commands-and-options) section below - -In case of errors, see [troubleshooting section](troubleshooting.md). - -### CLI Commands and Options - -The basic syntax of `nym-vpn-cli` is: -```sh -sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id --exit-router-address --enable-wireguard --private-key --wg-ip -``` -* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) -* To see all possibilities run with `--help` flag: -```sh -./nym-vpn-cli --help -``` 4. If you prefer to run `.AppImage` make executable by running: ```sh -chmod u+x ./appimage/nym-vpn_0.0.2_amd64.AppImage +# make sure you cd into the right sub-directory after extraction +chmod u+x ./appimage/nym-vpn_0.0.4_amd64.AppImage ``` 5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run: ```sh cd deb -sudo dpkg -i ./nym-vpn_0.0.3_amd64.deb +sudo dpkg -i ./nym-vpn_0.0.4_amd64.deb # or -sudo apt-get install -f ./nym-vpn_0.0.3_amd64.deb +sudo apt-get install -f ./nym-vpn_0.0.4_amd64.deb ``` ### Configuration @@ -104,7 +68,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn_0.033_amd64.AppImage +sudo -E ./nym-vpn_0.0.4_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/old-gui-mac.md b/documentation/dev-portal/src/nymvpn/old-gui-mac.md new file mode 100644 index 0000000000..ba74a23f41 --- /dev/null +++ b/documentation/dev-portal/src/nymvpn/old-gui-mac.md @@ -0,0 +1,61 @@ +# NymVPN alpha - Desktop: Guide for Mac OS + +```admonish info +NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. +``` + +## Preparation + +> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. + +### Installation + +1. Create a directory `~/nym-vpn-latest` +```sh +mkdir -p "$HOME/nym-vpn-latest" +``` +2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS +3. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: +```sh +echo "" | shasum -a 256 -c + +# choose a correct one according to your binary, this is just an example +# echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c +``` +4. Extract files: +```sh +tar -xvf +# for example +# tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz +``` +5. Move to the application directory and make executable +```sh +cd "macos/nym-vpn.app/Contents/MacOS" + +chmod u+x nym-vpn +``` +6. Move `nym-vpn` to your `~/nym-vpn-latest` directory +```sh +mv nym-vpn "$HOME/nym-vpn-latest" +``` + +### Configuration + +7. Create the configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` +```toml +env_config_file = ".env" +``` +8. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` +```sh +curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "$HOME/nym-vpn-latest/.env" +``` +## Run NymVPN + +**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. + +Run: +```sh +sudo -E $HOME/nym-vpn-latest/nym-vpn +``` + +In case of errors check out the [troubleshooting](troubleshooting.html#installing-gui-on-macos-not-working) section. From 9ff37d2f9f27762d8900e353306029ed13abfb6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= Date: Wed, 21 Feb 2024 12:27:18 +0200 Subject: [PATCH 106/394] Propagate gateway ws fd into sdk (#4398) * Propagate gateway ws fd into sdk * Wrap fd in a more general struct --- .../client-core/src/client/base_client/mod.rs | 9 ++++++++ .../src/client/mix_traffic/transceiver.rs | 14 +++++++++++ .../client-libs/gateway-client/src/client.rs | 14 ++++++++++- .../gateway-client/src/socket_state.rs | 23 +++++++++++++++++++ sdk/rust/nym-sdk/src/mixnet/native_client.rs | 6 +++++ 5 files changed, 65 insertions(+), 1 deletion(-) diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 47b119261a..c2632f73ad 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -52,6 +52,7 @@ use nym_topology::provider_trait::TopologyProvider; use nym_topology::HardcodedTopologyProvider; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use std::fmt::Debug; +use std::os::raw::c_int as RawFd; use std::path::Path; use std::sync::Arc; use url::Url; @@ -103,6 +104,12 @@ pub struct ClientState { pub shared_lane_queue_lengths: LaneQueueLengths, pub reply_controller_sender: ReplyControllerSender, pub topology_accessor: TopologyAccessor, + pub gateway_connection: GatewayConnection, +} + +#[derive(Clone, Copy, Debug)] +pub struct GatewayConnection { + pub gateway_ws_fd: Option, } pub enum ClientInputStatus { @@ -666,6 +673,7 @@ where shutdown.fork("gateway_transceiver"), ) .await?; + let gateway_ws_fd = gateway_transceiver.ws_fd(); let reply_storage = Self::setup_persistent_reply_storage( reply_storage_backend, @@ -759,6 +767,7 @@ where shared_lane_queue_lengths, reply_controller_sender, topology_accessor: shared_topology_accessor, + gateway_connection: GatewayConnection { gateway_ws_fd }, }, task_handle: shutdown, }) diff --git a/common/client-core/src/client/mix_traffic/transceiver.rs b/common/client-core/src/client/mix_traffic/transceiver.rs index b078e02966..b6197fb490 100644 --- a/common/client-core/src/client/mix_traffic/transceiver.rs +++ b/common/client-core/src/client/mix_traffic/transceiver.rs @@ -8,6 +8,7 @@ use nym_gateway_client::GatewayClient; pub use nym_gateway_client::{GatewayPacketRouter, PacketRouter}; use nym_sphinx::forwarding::packet::MixPacket; use std::fmt::Debug; +use std::os::raw::c_int as RawFd; use thiserror::Error; #[cfg(not(target_arch = "wasm32"))] @@ -25,6 +26,7 @@ fn erase_err(err: E) -> ErasedGate /// This combines combines the functionalities of being able to send and receive mix packets. pub trait GatewayTransceiver: GatewaySender + GatewayReceiver { fn gateway_identity(&self) -> identity::PublicKey; + fn ws_fd(&self) -> Option; } /// This trait defines the functionality of sending `MixPacket` into the mixnet, @@ -66,6 +68,9 @@ impl GatewayTransceiver for Box { fn gateway_identity(&self) -> identity::PublicKey { (**self).gateway_identity() } + fn ws_fd(&self) -> Option { + (**self).ws_fd() + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -112,6 +117,9 @@ where fn gateway_identity(&self) -> identity::PublicKey { self.gateway_client.gateway_identity() } + fn ws_fd(&self) -> Option { + self.gateway_client.ws_fd() + } } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] @@ -187,6 +195,9 @@ mod nonwasm_sealed { fn gateway_identity(&self) -> identity::PublicKey { self.local_identity } + fn ws_fd(&self) -> Option { + None + } } #[async_trait] @@ -259,4 +270,7 @@ impl GatewayTransceiver for MockGateway { fn gateway_identity(&self) -> identity::PublicKey { self.dummy_identity } + fn ws_fd(&self) -> Option { + None + } } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 461e5ae4d0..da2ee34f96 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -6,7 +6,7 @@ use crate::packet_router::PacketRouter; pub use crate::packet_router::{ AcknowledgementReceiver, AcknowledgementSender, MixnetMessageReceiver, MixnetMessageSender, }; -use crate::socket_state::{PartiallyDelegated, SocketState}; +use crate::socket_state::{ws_fd, PartiallyDelegated, SocketState}; use crate::traits::GatewayPacketRouter; use crate::{cleanup_socket_message, try_decrypt_binary_message}; use futures::{SinkExt, StreamExt}; @@ -33,11 +33,15 @@ use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; +#[cfg(not(target_arch = "wasm32"))] +use std::os::fd::RawFd; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::connect_async; +#[cfg(target_arch = "wasm32")] +use std::os::raw::c_int as RawFd; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; #[cfg(target_arch = "wasm32")] @@ -153,6 +157,14 @@ impl GatewayClient { self.gateway_identity } + pub fn ws_fd(&self) -> Option { + match &self.connection { + SocketState::Available(conn) => ws_fd(conn.as_ref()), + SocketState::PartiallyDelegated(conn) => conn.ws_fd(), + _ => None, + } + } + pub fn remaining_bandwidth(&self) -> i64 { self.bandwidth_remaining } diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index 6f325b3520..c42e2d7d08 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -11,9 +11,12 @@ use futures::{SinkExt, StreamExt}; use log::*; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_task::TaskClient; +use std::os::raw::c_int as RawFd; use std::sync::Arc; use tungstenite::Message; +#[cfg(not(target_arch = "wasm32"))] +use std::os::fd::AsRawFd; #[cfg(not(target_arch = "wasm32"))] use tokio::net::TcpStream; #[cfg(not(target_arch = "wasm32"))] @@ -37,9 +40,22 @@ type WsConn = JSWebsocket; type SplitStreamReceiver = oneshot::Receiver, GatewayClientError>>; +pub(crate) fn ws_fd(_conn: &WsConn) -> Option { + #[cfg(not(target_arch = "wasm32"))] + match _conn.get_ref() { + MaybeTlsStream::Plain(stream) => Some(stream.as_raw_fd()), + &_ => unreachable!( + "If tls features are enabled, the inner stream needs to be unpacked into raw fd" + ), + } + #[cfg(target_arch = "wasm32")] + None +} + pub(crate) struct PartiallyDelegated { sink_half: SplitSink, delegated_stream: (SplitStreamReceiver, oneshot::Sender<()>), + ws_fd: Option, } impl PartiallyDelegated { @@ -92,6 +108,8 @@ impl PartiallyDelegated { let (notify_sender, notify_receiver) = oneshot::channel(); let (stream_sender, stream_receiver) = oneshot::channel(); + let ws_fd = ws_fd(&conn); + let (sink, mut stream) = conn.split(); let mixnet_receiver_future = async move { @@ -141,11 +159,16 @@ impl PartiallyDelegated { tokio::spawn(mixnet_receiver_future); PartiallyDelegated { + ws_fd, sink_half: sink, delegated_stream: (stream_receiver, notify_sender), } } + pub(crate) fn ws_fd(&self) -> Option { + self.ws_fd + } + // if we want to send a message and don't care about response, we can don't need to reunite the split, // the sink itself is enough pub(crate) async fn send_without_response( diff --git a/sdk/rust/nym-sdk/src/mixnet/native_client.rs b/sdk/rust/nym-sdk/src/mixnet/native_client.rs index 519961d6fd..e00322ec71 100644 --- a/sdk/rust/nym-sdk/src/mixnet/native_client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/native_client.rs @@ -4,6 +4,7 @@ use crate::{Error, Result}; use async_trait::async_trait; use futures::{ready, Stream, StreamExt}; use log::error; +use nym_client_core::client::base_client::GatewayConnection; use nym_client_core::client::{ base_client::{ClientInput, ClientOutput, ClientState}, inbound_messages::InputMessage, @@ -97,6 +98,11 @@ impl MixnetClient { &self.nym_address } + /// Get gateway connection information, like the file descriptor of the WebSocket + pub fn gateway_connection(&self) -> GatewayConnection { + self.client_state.gateway_connection + } + /// Get a shallow clone of [`MixnetClientSender`]. Useful if you want split the send and /// receive logic in different locations. pub fn split_sender(&self) -> MixnetClientSender { From 32c897f78915fc07d95225276dfad75dcc4cfee5 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:33:51 +0100 Subject: [PATCH 107/394] add mac desktop manual setup --- .../dev-portal/src/nymvpn/gui-mac.md | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index ba74a23f41..5829b4277e 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -14,38 +14,55 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ```sh mkdir -p "$HOME/nym-vpn-latest" ``` -2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS -3. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: + +2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for your version of MacOS + +3. Recommended (skip to next point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: ```sh echo "" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example # echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c ``` + 4. Extract files: ```sh tar -xvf # for example # tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz ``` -5. Move to the application directory and make executable + +5. Move to the application content directory: ```sh cd "macos/nym-vpn.app/Contents/MacOS" +# if it didn't work, try +cd "/Applications/nym-vpn.app/Contents/MacOS/" +``` + +6. Make executable +```sh chmod u+x nym-vpn ``` -6. Move `nym-vpn` to your `~/nym-vpn-latest` directory + +7. Move `nym-vpn` to your `~/nym-vpn-latest` directory ```sh mv nym-vpn "$HOME/nym-vpn-latest" ``` +Here you are basically done with the installation. NymVPN alpha version runs over Nym testnet (called sandbox), we need to do a little configuration: + ### Configuration -7. Create the configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` +8. Create the application configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` ```toml env_config_file = ".env" ``` -8. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` +Alternatively do it via a simple command: +```sh +echo "env_config_file = .env" > "$HOME/nym-vpn-latest/config.toml" +``` +9. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` ```sh curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "$HOME/nym-vpn-latest/.env" ``` From b6d57e2862c600501c71451760d1df2a128ebc8a Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Wed, 21 Feb 2024 17:56:36 +0530 Subject: [PATCH 108/394] nym-cli: delegate to mixnodes from input csv file nym-cli: delegate to mixnodes from input csv file --- .../delegate_to_multiple_mixnodes.rs | 313 ++++++++++++++++++ .../src/validator/mixnet/delegators/mod.rs | 3 + .../src/validator/mixnet/delegators/mod.rs | 3 + 3 files changed, 319 insertions(+) create mode 100644 common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs new file mode 100644 index 0000000000..7be38f19ea --- /dev/null +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -0,0 +1,313 @@ +// Copyright 2024 - Nym Technologies SA +// SPDX-License-Identifier: Apache-2.0 + +use std::cmp::Ordering; +use std::collections::HashMap; +use std::fs; +use std::fs::OpenOptions; + +use clap::Parser; +use comfy_table::Table; +use cosmrs::AccountId; +use csv::WriterBuilder; +use log::{info, warn}; + +use nym_mixnet_contract_common::PendingEpochEventKind::{Delegate, Undelegate}; +use nym_validator_client::nyxd::contract_traits::{MixnetSigningClient, PagedMixnetQueryClient}; +use nym_validator_client::nyxd::Coin; + +use crate::context::SigningClient; +use crate::utils::pretty_coin; + +#[derive(Debug, Parser)] +pub struct Args { + #[clap(long)] + pub memo: Option, + + #[clap(long, help = "Input csv files with delegation amounts")] + pub input: String, + + #[clap( + long, + help = "An output file path (CSV format) to create or append a log of results to", + + )] + pub output: Option, +} + +#[derive(Debug)] +pub struct InputFileRow { + pub mix_id: String, + pub amount: Coin, +} +#[derive(Debug)] +pub struct InputFileReader { + pub rows: Vec, +} + +impl InputFileReader { + pub fn new(path: &str) -> Result { + let mut rows: Vec = Vec::new(); + let file_contents = fs::read_to_string(path)?; + let mut mix_id_list: Vec = Vec::new(); + let lines: Vec = file_contents.lines().map(String::from).collect(); + for line in lines { + // Skip over blank lines without throwing an error + if line.trim().is_empty() { + continue; + } + + let tokens: Vec<_> = line.split(',').collect(); + // Return error if any of the line is malformed + if tokens.len() != 2 { + return Err(anyhow::anyhow!( + "Malformed input file, please make sure the file is in the correct format (mix_id,amount)" + )); + } + + let mix_id = tokens[0].trim().to_string(); + let token_input_raw = tokens[1].trim().parse::()?; + if token_input_raw > 1_000_000 { + warn!("Delegation amount exceeds 1,000,000. \ + Make sure the input amount is in nym and not unym denomination!"); + } + + let tokens_in_unym: u128 = token_input_raw * 1_000_000; + + let amount = Coin { + amount: tokens_in_unym, + denom: "unym".to_string(), + }; + if mix_id_list.contains(&mix_id) { + return Err(anyhow::anyhow!( + "Input document has duplicate delegation record for {}", + mix_id.clone() + )); + } else { + rows.push(InputFileRow { + mix_id: mix_id.clone(), + amount, + }); + mix_id_list.push(mix_id); + } + } + Ok(InputFileReader { rows }) + } +} + + +fn write_to_csv(output_details: Vec<[String; 4]>, output_file: Option) -> Result<(), anyhow::Error> { + if let Some(file_path) = output_file { + // Determine if the file exists and is not empty + let file_exists = fs::metadata(&file_path).map(|metadata| metadata.len() > 0).unwrap_or(false); + + // Open the file for appending or creation + let file = OpenOptions::new() + .write(true) + .append(true) + .create(true) + .open(&file_path)?; + + if !file_exists { + let mut wtr = csv::Writer::from_writer(&file); + wtr.write_record(["Operation", "Mix ID", "Amount", "tx hash"])?; + wtr.flush()?; + } + + let mut wtr = WriterBuilder::new().has_headers(!file_exists).from_writer(file); + + // Write the details to the CSV file + for detail in output_details { + wtr.write_record(&detail)?; + } + wtr.flush()?; + info!("All operations saved to output file"); + } + Ok(()) +} + +pub async fn delegate_to_multiple_mixnodes( + args: Args, + client: SigningClient, +) -> Result { + let address = client.address(); + let records = InputFileReader::new(&args.input)?; + // Fetch all delegations for the user + let delegations = client.get_all_delegator_delegations(&address).await?; + + // Build a map to make it easier to handle delegation data + let mut existing_delegation_map: HashMap = HashMap::new(); + let mut pending_delegation_map: HashMap = HashMap::new(); + + for delegation in delegations { + existing_delegation_map + .insert(delegation.mix_id.to_string(), Coin::from(delegation.amount)); + } + + // Look for pending delegate / undelegate events which might be of interest to us + let pending_events = client.get_all_pending_epoch_events().await?; + for event in pending_events { + match event.event.kind { + // If a pending undelegate tx is found, remove it from delegation map + Undelegate { owner, mix_id, .. } => { + if owner == client.address().as_ref() + && existing_delegation_map.get(&mix_id.to_string()).is_some() + { + existing_delegation_map.remove(&mix_id.to_string()); + } + } + + // If a pending delegation event is found, gather them to consolidate later + Delegate { + owner, + mix_id, + amount, + .. + } => { + if owner == client.address().as_ref() { + let mut amount = Coin::from(amount); + if let Some(pending_record) = pending_delegation_map.get(&mix_id.to_string()) { + amount.amount += pending_record.amount; + } + pending_delegation_map.insert(mix_id.to_string(), amount); + } + } + _ => {} + }; + } + + // Consolidate pending events into delegation map + for (mix_id, amount) in pending_delegation_map { + existing_delegation_map + .entry(mix_id) + .and_modify(|e| e.amount += amount.amount) + .or_insert(amount); + } + + let mut delegation_table = Table::new(); + let mut undelegation_table = Table::new(); + let mut delegations_to_be_made: Vec<(String, Coin)> = Vec::new(); + let mut undelegations_to_be_made = Vec::new(); + + delegation_table.set_header(["Mix ID", "Input Amount", "Adjusted Amount"]); + undelegation_table.set_header(["Mix ID"]); + + for row in records.rows.iter() { + // Check if there's an existing delegation for this mix_id + if let Some(existing_delegation_record) = existing_delegation_map.get(&row.mix_id) { + + let existing_delegation_amount = existing_delegation_record.amount; + let input_amount = row.amount.amount; + + match existing_delegation_amount.cmp(&input_amount) { + // Nothing to do if the delegation record matches, just continue + Ordering::Equal => continue, + + // If existing delegation is lesser, we need to delegate only remaining amount + Ordering::Less => { + let adjusted_amount = Coin { + amount: input_amount - existing_delegation_amount, + denom: existing_delegation_record.denom.clone(), + }; + + delegation_table.add_row([ + row.mix_id.clone(), + pretty_coin(&row.amount.clone()), + pretty_coin(&adjusted_amount), + ]); + delegations_to_be_made.push((row.mix_id.clone(), adjusted_amount)); + }, + + // If existing delegation is greater, we need to undelegate and delegate the specified amount + Ordering::Greater => { + undelegations_to_be_made.push(row.mix_id.clone()); + undelegation_table.add_row([row.mix_id.clone()]); + + delegations_to_be_made.push((row.mix_id.clone(), row.amount.clone())); + delegation_table.add_row([ + row.mix_id.clone(), + pretty_coin(&row.amount), + pretty_coin(&row.amount), + ]); + } + }; // match close + + } else { + delegations_to_be_made.push((row.mix_id.clone(), row.amount.clone())); + delegation_table.add_row([ + row.mix_id.clone(), + pretty_coin(&row.amount.clone()), + pretty_coin(&row.amount.clone()), + ]); + } + } + + if delegations_to_be_made.is_empty() && undelegations_to_be_made.is_empty() { + println!("Nothing to do. Delegations are up-to-date!"); + return Ok(address.clone()); + } + if !delegations_to_be_made.is_empty() { + println!("Delegation records : \n{}\n\n", delegation_table); + } + + if !undelegations_to_be_made.is_empty() { + println!("Undelegation records : \n{}\n\n", undelegation_table); + } + + let ans = inquire::Confirm::new("Do you want to continue with the shown operations?") + .with_default(false) + .with_help_message("You must confirm before the transactions are signed") + .prompt(); + + if let Err(e) = ans { + info!("Aborting, {}...", e); + return Err(anyhow::anyhow!("Aborted :: {}", e)); + } + + if let Ok(false) = ans { + info!("Aborting:: User denied proceeding with signing!"); + return Err(anyhow::anyhow!("Aborting:: User denied proceeding with signing!")); + } + + let mut output_details: Vec<[String;4]> = Vec::new(); + + // Perform undelegation operations + for mix_id in undelegations_to_be_made { + let res = client.undelegate_from_mixnode(mix_id.parse::()?, None).await.expect("Failed to undelegate from mixnode"); + info!("Delegation to {} successful. tx: {}", mix_id, &res.transaction_hash ); + if args.output.is_some() { + output_details.push([ + "Undelegate".into(), + mix_id.clone(), + "-".into(), + res.transaction_hash.to_string(), + ]); + } + } + + // Perform delegation operations + for (mix_id, amount) in delegations_to_be_made { + let res = client.delegate_to_mixnode(mix_id.parse::()?, amount.clone(), None) + .await + .expect("Failed to delegate to mixnode"); + + info!("Delegation to {} successful. tx: {}", mix_id, &res.transaction_hash ); + if args.output.is_some() { + output_details.push([ + "Delegate".into(), + mix_id.clone(), + pretty_coin(&amount), + res.transaction_hash.to_string(), + ]); + } + } + + if args.output.is_some() { + if let Err(e) = write_to_csv(output_details, args.output) { + info!("Failed to write to CSV, {}", e); + return Err(anyhow::anyhow!("Failed to write to CSV: {}", e)); + } + } + + Ok(address) +} diff --git a/common/commands/src/validator/mixnet/delegators/mod.rs b/common/commands/src/validator/mixnet/delegators/mod.rs index 61e87f119d..f2cf156c0c 100644 --- a/common/commands/src/validator/mixnet/delegators/mod.rs +++ b/common/commands/src/validator/mixnet/delegators/mod.rs @@ -6,6 +6,7 @@ use clap::{Args, Subcommand}; pub mod rewards; pub mod delegate_to_mixnode; +pub mod delegate_to_multiple_mixnodes; pub mod query_for_delegations; pub mod undelegate_from_mixnode; pub mod vesting_delegate_to_mixnode; @@ -26,6 +27,8 @@ pub enum MixnetDelegatorsCommands { Rewards(rewards::MixnetDelegatorsReward), /// Delegate to a mixnode Delegate(delegate_to_mixnode::Args), + /// Perform bulk delegations from an input file + DelegateMulti(delegate_to_multiple_mixnodes::Args), /// Undelegate from a mixnode Undelegate(undelegate_from_mixnode::Args), /// Delegate to a mixnode with locked tokens diff --git a/tools/nym-cli/src/validator/mixnet/delegators/mod.rs b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs index b7c561cf70..69e83a5993 100644 --- a/tools/nym-cli/src/validator/mixnet/delegators/mod.rs +++ b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs @@ -23,6 +23,9 @@ pub(crate) async fn execute( nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::DelegateVesting(args) => { nym_cli_commands::validator::mixnet::delegators::vesting_delegate_to_mixnode::vesting_delegate_to_mixnode(args, create_signing_client(global_args, network_details)?).await } + nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::DelegateMulti(args) => { + nym_cli_commands::validator::mixnet::delegators::delegate_to_multiple_mixnodes::delegate_to_multiple_mixnodes(args, create_signing_client(global_args, network_details)?).await.expect("TODO: panic message"); + } nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::Undelegate(args) => { nym_cli_commands::validator::mixnet::delegators::undelegate_from_mixnode::undelegate_from_mixnode(args, create_signing_client(global_args, network_details)?).await } From a3bc4af8fee309f63de6d6df862b3a16300332e9 Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Wed, 21 Feb 2024 19:12:02 +0530 Subject: [PATCH 109/394] fmt + clippy --- .../delegate_to_multiple_mixnodes.rs | 106 +++++++++++------- .../src/validator/mixnet/delegators/mod.rs | 2 +- 2 files changed, 68 insertions(+), 40 deletions(-) diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs index 7be38f19ea..3cdf9ee527 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -8,7 +8,6 @@ use std::fs::OpenOptions; use clap::Parser; use comfy_table::Table; -use cosmrs::AccountId; use csv::WriterBuilder; use log::{info, warn}; @@ -24,13 +23,12 @@ pub struct Args { #[clap(long)] pub memo: Option, - #[clap(long, help = "Input csv files with delegation amounts")] + #[clap(long, help = "Input csv files with delegation amounts. Format: mixid, amount in NYM")] pub input: String, #[clap( long, - help = "An output file path (CSV format) to create or append a log of results to", - + help = "An output file path (CSV format) to create or append a log of results to" )] pub output: Option, } @@ -61,18 +59,20 @@ impl InputFileReader { // Return error if any of the line is malformed if tokens.len() != 2 { return Err(anyhow::anyhow!( - "Malformed input file, please make sure the file is in the correct format (mix_id,amount)" + "Malformed input file, please make sure the file is in the correct format (mix_id, amount)" )); } let mix_id = tokens[0].trim().to_string(); let token_input_raw = tokens[1].trim().parse::()?; if token_input_raw > 1_000_000 { - warn!("Delegation amount exceeds 1,000,000. \ - Make sure the input amount is in nym and not unym denomination!"); + warn!( + "Delegation amount exceeds 1,000,000. \ + Make sure the input amount is in nym and not unym denomination!" + ); } - let tokens_in_unym: u128 = token_input_raw * 1_000_000; + let tokens_in_unym: u128 = token_input_raw * 1_000_000; let amount = Coin { amount: tokens_in_unym, @@ -95,11 +95,15 @@ impl InputFileReader { } } - -fn write_to_csv(output_details: Vec<[String; 4]>, output_file: Option) -> Result<(), anyhow::Error> { +fn write_to_csv( + output_details: Vec<[String; 4]>, + output_file: Option, +) -> Result<(), anyhow::Error> { if let Some(file_path) = output_file { // Determine if the file exists and is not empty - let file_exists = fs::metadata(&file_path).map(|metadata| metadata.len() > 0).unwrap_or(false); + let file_exists = fs::metadata(&file_path) + .map(|metadata| metadata.len() > 0) + .unwrap_or(false); // Open the file for appending or creation let file = OpenOptions::new() @@ -114,7 +118,9 @@ fn write_to_csv(output_details: Vec<[String; 4]>, output_file: Option) - wtr.flush()?; } - let mut wtr = WriterBuilder::new().has_headers(!file_exists).from_writer(file); + let mut wtr = WriterBuilder::new() + .has_headers(!file_exists) + .from_writer(file); // Write the details to the CSV file for detail in output_details { @@ -126,14 +132,24 @@ fn write_to_csv(output_details: Vec<[String; 4]>, output_file: Option) - Ok(()) } -pub async fn delegate_to_multiple_mixnodes( - args: Args, - client: SigningClient, -) -> Result { +pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { let address = client.address(); - let records = InputFileReader::new(&args.input)?; + let records = match InputFileReader::new(&args.input) { + Ok(records) => records, + Err(e) => { + println!("Error reading input file: {}", e); + return; + } + }; + // Fetch all delegations for the user - let delegations = client.get_all_delegator_delegations(&address).await?; + let delegations = match client.get_all_delegator_delegations(&address).await { + Ok(delegations) => delegations, + Err(e) => { + println!("Error fetching delegator delegations: {}", e); + return; + } + }; // Build a map to make it easier to handle delegation data let mut existing_delegation_map: HashMap = HashMap::new(); @@ -145,7 +161,14 @@ pub async fn delegate_to_multiple_mixnodes( } // Look for pending delegate / undelegate events which might be of interest to us - let pending_events = client.get_all_pending_epoch_events().await?; + let pending_events = match client.get_all_pending_epoch_events().await { + Ok(events) => events, + Err(e) => { + println!("Error fetching pending epoch events: {}", e); + return; + } + }; + for event in pending_events { match event.event.kind { // If a pending undelegate tx is found, remove it from delegation map @@ -195,7 +218,6 @@ pub async fn delegate_to_multiple_mixnodes( for row in records.rows.iter() { // Check if there's an existing delegation for this mix_id if let Some(existing_delegation_record) = existing_delegation_map.get(&row.mix_id) { - let existing_delegation_amount = existing_delegation_record.amount; let input_amount = row.amount.amount; @@ -216,7 +238,7 @@ pub async fn delegate_to_multiple_mixnodes( pretty_coin(&adjusted_amount), ]); delegations_to_be_made.push((row.mix_id.clone(), adjusted_amount)); - }, + } // If existing delegation is greater, we need to undelegate and delegate the specified amount Ordering::Greater => { @@ -231,7 +253,6 @@ pub async fn delegate_to_multiple_mixnodes( ]); } }; // match close - } else { delegations_to_be_made.push((row.mix_id.clone(), row.amount.clone())); delegation_table.add_row([ @@ -244,7 +265,7 @@ pub async fn delegate_to_multiple_mixnodes( if delegations_to_be_made.is_empty() && undelegations_to_be_made.is_empty() { println!("Nothing to do. Delegations are up-to-date!"); - return Ok(address.clone()); + return; } if !delegations_to_be_made.is_empty() { println!("Delegation records : \n{}\n\n", delegation_table); @@ -255,26 +276,32 @@ pub async fn delegate_to_multiple_mixnodes( } let ans = inquire::Confirm::new("Do you want to continue with the shown operations?") - .with_default(false) - .with_help_message("You must confirm before the transactions are signed") - .prompt(); + .with_default(false) + .with_help_message("You must confirm before the transactions are signed") + .prompt(); - if let Err(e) = ans { + if let Err(e) = ans { info!("Aborting, {}...", e); - return Err(anyhow::anyhow!("Aborted :: {}", e)); + return; } if let Ok(false) = ans { info!("Aborting:: User denied proceeding with signing!"); - return Err(anyhow::anyhow!("Aborting:: User denied proceeding with signing!")); + return; } - let mut output_details: Vec<[String;4]> = Vec::new(); + let mut output_details: Vec<[String; 4]> = Vec::new(); // Perform undelegation operations for mix_id in undelegations_to_be_made { - let res = client.undelegate_from_mixnode(mix_id.parse::()?, None).await.expect("Failed to undelegate from mixnode"); - info!("Delegation to {} successful. tx: {}", mix_id, &res.transaction_hash ); + let res = client + .undelegate_from_mixnode(mix_id.parse::().unwrap(), None) + .await + .expect("Failed to undelegate from mixnode"); + info!( + "Undelegation from {} successful. tx: {}", + mix_id, &res.transaction_hash + ); if args.output.is_some() { output_details.push([ "Undelegate".into(), @@ -287,11 +314,15 @@ pub async fn delegate_to_multiple_mixnodes( // Perform delegation operations for (mix_id, amount) in delegations_to_be_made { - let res = client.delegate_to_mixnode(mix_id.parse::()?, amount.clone(), None) - .await - .expect("Failed to delegate to mixnode"); + let res = client + .delegate_to_mixnode(mix_id.parse::().unwrap(), amount.clone(), None) + .await + .expect("Failed to delegate to mixnode"); - info!("Delegation to {} successful. tx: {}", mix_id, &res.transaction_hash ); + info!( + "Delegation to {} successful. tx: {}", + mix_id, &res.transaction_hash + ); if args.output.is_some() { output_details.push([ "Delegate".into(), @@ -305,9 +336,6 @@ pub async fn delegate_to_multiple_mixnodes( if args.output.is_some() { if let Err(e) = write_to_csv(output_details, args.output) { info!("Failed to write to CSV, {}", e); - return Err(anyhow::anyhow!("Failed to write to CSV: {}", e)); } } - - Ok(address) } diff --git a/tools/nym-cli/src/validator/mixnet/delegators/mod.rs b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs index 69e83a5993..8ccfbd59a3 100644 --- a/tools/nym-cli/src/validator/mixnet/delegators/mod.rs +++ b/tools/nym-cli/src/validator/mixnet/delegators/mod.rs @@ -24,7 +24,7 @@ pub(crate) async fn execute( nym_cli_commands::validator::mixnet::delegators::vesting_delegate_to_mixnode::vesting_delegate_to_mixnode(args, create_signing_client(global_args, network_details)?).await } nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::DelegateMulti(args) => { - nym_cli_commands::validator::mixnet::delegators::delegate_to_multiple_mixnodes::delegate_to_multiple_mixnodes(args, create_signing_client(global_args, network_details)?).await.expect("TODO: panic message"); + nym_cli_commands::validator::mixnet::delegators::delegate_to_multiple_mixnodes::delegate_to_multiple_mixnodes(args, create_signing_client(global_args, network_details)?).await } nym_cli_commands::validator::mixnet::delegators::MixnetDelegatorsCommands::Undelegate(args) => { nym_cli_commands::validator::mixnet::delegators::undelegate_from_mixnode::undelegate_from_mixnode(args, create_signing_client(global_args, network_details)?).await From ad052ef498e1bca45b6922689ab6b053740e404c Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Wed, 21 Feb 2024 19:14:12 +0530 Subject: [PATCH 110/394] fmt + clippy --- .../mixnet/delegators/delegate_to_multiple_mixnodes.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs index 3cdf9ee527..ca98e24275 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -23,7 +23,10 @@ pub struct Args { #[clap(long)] pub memo: Option, - #[clap(long, help = "Input csv files with delegation amounts. Format: mixid, amount in NYM")] + #[clap( + long, + help = "Input csv files with delegation amounts. Format: mixid, amount in NYM" + )] pub input: String, #[clap( From e83be64a523f5a3be20f88954c5e83df2a8c0f08 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 22 Feb 2024 06:23:18 +0100 Subject: [PATCH 111/394] mac desktop manual steps --- .../dev-portal/src/nymvpn/gui-mac.md | 42 ++++++++++++------- 1 file changed, 26 insertions(+), 16 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 5829b4277e..4abba4a4e6 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -10,14 +10,16 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ### Installation + -2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for your version of MacOS +1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for your version of MacOS -3. Recommended (skip to next point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: +2. Recommended (skip this point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: ```sh echo "" | shasum -a 256 -c @@ -25,13 +27,13 @@ echo "" | shasum -a 256 -c # echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c ``` -4. Extract files: +3. Extract the downloaded file manually or by a command: ```sh tar -xvf # for example # tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz ``` - + +4. Mount the `.dmg` image you extracted by double clicking on it -Here you are basically done with the installation. NymVPN alpha version runs over Nym testnet (called sandbox), we need to do a little configuration: + +NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. ### Configuration -8. Create the application configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` +To test NymVPN alspha two configuration files are needed. An environment config file `sandbox.env` and `config.toml` file pointing the application to run over the testnet environment. + +5. Create testnet configuration file: Open a text editor, copy-paste [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) and save it as `sandbox.env` in `/Applications/nym-vpn.app/Contents/MacOS/`. Alternatively use this command: +```sh +curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "/Applications/nym-vpn.app/Contents/MacOS/sandbox.env" +``` + +6. Create application configuration file: Open a text editor, copy-paste the line below and save as `config.toml` in the same directory `/Applications/nym-vpn.app/Contents/MacOS/` ```toml -env_config_file = ".env" +env_config_file = "sandbox.env" ``` -Alternatively do it via a simple command: +Alternatively do it by using this command: ```sh -echo "env_config_file = .env" > "$HOME/nym-vpn-latest/config.toml" -``` -9. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` -```sh -curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "$HOME/nym-vpn-latest/.env" +echo "env_config_file = sandbox.env" > /Applications/nym-vpn.app/Contents/MacOS//config.toml ``` ## Run NymVPN @@ -72,7 +79,10 @@ curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" Run: ```sh -sudo -E $HOME/nym-vpn-latest/nym-vpn +sudo /Applications/nym-vpn.app/Contents/MacOS/nym-vpn + +# If it didn't start try to run with -E flag +sudo -E /Applications/nym-vpn.app/Contents/MacOS/nym-vpn ``` -In case of errors check out the [troubleshooting](troubleshooting.html#installing-gui-on-macos-not-working) section. +In case of errors check out the [troubleshooting](troubleshooting.md#running-gui-failed-due-to-toml-parse-error) section. From ffb053fe4abe6032502bea72df32d8a53a77ee09 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 22 Feb 2024 06:28:12 +0100 Subject: [PATCH 112/394] desktop auto script update --- documentation/dev-portal/src/nymvpn/gui.md | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index 2f06b22dd9..1a027f4f5c 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -8,30 +8,20 @@ Our alpha testing round is done with participants at live workshop events. This This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users. -Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md). +Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for yur distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . Visit NymVPN alpha latest [release page]({{nym_vpn_latest_binary_url}}) to check sha sums or download the binaries directly. ## Automated Script for GUI Installation -We wrote a [script](https://gist.github.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: +We wrote a [script](https://gist.github.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically. Turn off all VPNs and follow the steps below. -1. Open a terminal window in a directory where you want the script and NymVPN binary be downloaded and run +1. Open a terminal window in a directory where you want the script to be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/227c8c348a1e58f68cb500e4504b22412177c680/nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/227c8c348a1e58f68cb500e4504b22412177c680/nym-vpn-desktop-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh ``` -2. Make the script executable -```sh -chmod u+x nym-vpn-desktop-install-run.sh -``` - -3. Start the script, turn off any VPN and run -```sh -sudo -E ./nym-vpn-desktop-install-run.sh -``` - -4. Follow the prompts in the program +2. Follow the prompts in the program To start the application again, reconnect your wifi and run ```sh From 90680ceb16c2d3b95796958b5b453a4fb2ffd540 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:14:14 +0100 Subject: [PATCH 113/394] add moving application step --- documentation/dev-portal/src/nymvpn/gui-mac.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 4abba4a4e6..769e3040da 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -51,7 +51,7 @@ chmod u+x nym-vpn mv nym-vpn "$HOME/nym-vpn-latest" ``` --> -4. Mount the `.dmg` image you extracted by double clicking on it +4. Mount the `.dmg` image you extracted by double clicking on it and move it (drag it) to your `/Application` folder NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. From bfac3e0b899c91323ce281eff76f043121e8e44b Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:23:00 +0100 Subject: [PATCH 114/394] add gui-mac to summary --- documentation/dev-portal/src/SUMMARY.md | 1 + documentation/dev-portal/src/nymvpn/gui-linux.md | 10 +++++++--- documentation/dev-portal/src/nymvpn/gui-mac.md | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index e98304dea0..db47668d2f 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -21,6 +21,7 @@ - [NymVPN alpha](nymvpn/intro.md) - [GUI](nymvpn/gui.md) - [Linux](nymvpn/gui-linux.md) + - [MacOS](nymvpn/gui-mac.md) - [CLI](nymvpn/cli.md) - [Linux](nymvpn/cli-linux.md) - [MacOS](nymvpn/cli-mac.md) diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 55c0b4bbae..713142c2eb 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -13,7 +13,7 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ### Installation 1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for Debian based Linux -2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: +2. Required (if you don't want to check shasum, skip this point): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `` with the one of your binary, like in the example: ```sh echo "" | shasum -a 256 -c @@ -41,18 +41,22 @@ sudo dpkg -i ./nym-vpn_0.0.4_amd64.deb sudo apt-get install -f ./nym-vpn_0.0.4_amd64.deb ``` +NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. + ### Configuration +To test NymVPN alpha we must create two configuration files: an environment config file `sandbox.env` and `config.toml` file pointing the application to run over the testnet environment. + 6. Create a NymVPN config directory called `nym-vpn` in your `~/.config`, either manually or by a command: ```sh mkdir $HOME/.config/nym-vpn/ ``` -7. Create the network config by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the directory `~/.config/nym-vpn/` you just created by running: +7. Create the network testnet config: copy-paste [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) and save as `sandbox.env` in the directory `~/.config/nym-vpn/` you just created. Aternatively do it by runnin a command ```sh curl -o $HOME/.config/nym-vpn/sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env ``` -8. Create NymVPN main config file called `config.toml` in the same directory `~/.config/nym-vpn/` with this content: +8. Create NymVPN main config file: copy-paste the line below and save it as `config.toml` in the same directory `~/.config/nym-vpn/`: ```toml # change to your username env_config_file = "/home//.config/nym-vpn/sandbox.env" diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 769e3040da..336a0cede2 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -58,7 +58,7 @@ NymVPN alpha version runs over Nym testnet (called sandbox), a little extra conf ### Configuration -To test NymVPN alspha two configuration files are needed. An environment config file `sandbox.env` and `config.toml` file pointing the application to run over the testnet environment. +To test NymVPN alpha we must create two configuration files: an environment config file `sandbox.env` and `config.toml` file pointing the application to run over the testnet environment. 5. Create testnet configuration file: Open a text editor, copy-paste [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) and save it as `sandbox.env` in `/Applications/nym-vpn.app/Contents/MacOS/`. Alternatively use this command: ```sh From 2eed8e3f6c3cc9e838a29f40fbbb5c4ab527407f Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 22 Feb 2024 10:40:38 +0100 Subject: [PATCH 115/394] syntax edit --- documentation/dev-portal/src/SUMMARY.md | 2 +- documentation/dev-portal/src/nymvpn/gui.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index db47668d2f..3a14919b99 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -21,7 +21,7 @@ - [NymVPN alpha](nymvpn/intro.md) - [GUI](nymvpn/gui.md) - [Linux](nymvpn/gui-linux.md) - - [MacOS](nymvpn/gui-mac.md) + - [MacOS](nymvpn/gui-mac.md) - [CLI](nymvpn/cli.md) - [Linux](nymvpn/cli-linux.md) - [MacOS](nymvpn/cli-mac.md) diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index 1a027f4f5c..779ddab4dd 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -8,7 +8,7 @@ Our alpha testing round is done with participants at live workshop events. This This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users. -Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for yur distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . +Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for your distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . Visit NymVPN alpha latest [release page]({{nym_vpn_latest_binary_url}}) to check sha sums or download the binaries directly. From b54d82a01a131f73c5f369c174b7ed9a613a85c4 Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Thu, 22 Feb 2024 17:55:35 +0530 Subject: [PATCH 116/394] nym-cli: batch transactions --- Cargo.lock | 14 + common/commands/Cargo.toml | 1 + .../delegate_to_multiple_mixnodes.rs | 278 ++++++++++-------- 3 files changed, 164 insertions(+), 129 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7dcb192b24..e9d127ddc5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,6 +646,19 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "bigdecimal" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06619be423ea5bb86c95f087d5707942791a08a85530df0db2209a3ecfb8bc9" +dependencies = [ + "autocfg 1.1.0", + "libm", + "num-bigint", + "num-integer", + "num-traits", +] + [[package]] name = "binascii" version = "0.1.4" @@ -5101,6 +5114,7 @@ version = "1.0.0" dependencies = [ "anyhow", "base64 0.13.1", + "bigdecimal", "bip39", "bs58 0.5.0", "cfg-if", diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index b2ef8bc3ea..83c1d45fc4 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -8,6 +8,7 @@ license.workspace = true [dependencies] anyhow = { workspace = true } base64 = "0.13.0" +bigdecimal = "0.4.2" bip39 = { workspace = true } bs58 = { workspace = true } comfy-table = "6.0.0" diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs index ca98e24275..2f36ed91f3 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -1,8 +1,9 @@ // Copyright 2024 - Nym Technologies SA // SPDX-License-Identifier: Apache-2.0 +use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive}; use std::cmp::Ordering; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::fs; use std::fs::OpenOptions; @@ -10,9 +11,11 @@ use clap::Parser; use comfy_table::Table; use csv::WriterBuilder; use log::{info, warn}; +use nym_mixnet_contract_common::ExecuteMsg; +use nym_mixnet_contract_common::ExecuteMsg::{DelegateToMixnode, UndelegateFromMixnode}; use nym_mixnet_contract_common::PendingEpochEventKind::{Delegate, Undelegate}; -use nym_validator_client::nyxd::contract_traits::{MixnetSigningClient, PagedMixnetQueryClient}; +use nym_validator_client::nyxd::contract_traits::{NymContractsProvider, PagedMixnetQueryClient}; use nym_validator_client::nyxd::Coin; use crate::context::SigningClient; @@ -25,7 +28,7 @@ pub struct Args { #[clap( long, - help = "Input csv files with delegation amounts. Format: mixid, amount in NYM" + help = "Input csv files with delegation amounts. Format: (mixID, amount(in NYM))" )] pub input: String, @@ -48,58 +51,53 @@ pub struct InputFileReader { impl InputFileReader { pub fn new(path: &str) -> Result { - let mut rows: Vec = Vec::new(); let file_contents = fs::read_to_string(path)?; - let mut mix_id_list: Vec = Vec::new(); - let lines: Vec = file_contents.lines().map(String::from).collect(); - for line in lines { - // Skip over blank lines without throwing an error - if line.trim().is_empty() { - continue; - } + let mut rows = Vec::new(); + let mut mix_id_set = HashSet::new(); + for line in file_contents + .lines() + .map(str::trim) + .filter(|line| !line.is_empty()) + { let tokens: Vec<_> = line.split(',').collect(); - // Return error if any of the line is malformed if tokens.len() != 2 { - return Err(anyhow::anyhow!( - "Malformed input file, please make sure the file is in the correct format (mix_id, amount)" - )); + anyhow::bail!("Incorrect format: {}", line); } - let mix_id = tokens[0].trim().to_string(); - let token_input_raw = tokens[1].trim().parse::()?; - if token_input_raw > 1_000_000 { - warn!( - "Delegation amount exceeds 1,000,000. \ - Make sure the input amount is in nym and not unym denomination!" - ); + let input_amount = BigDecimal::parse_bytes(tokens[1].trim().as_bytes(), 10) + .ok_or_else(|| anyhow::anyhow!("Invalid number format"))?; + let scaled_amount = input_amount.with_scale(6); + + if scaled_amount > BigDecimal::from(1_000_000) { + warn!("Delegation amount is high. Please make sure your input is in NYM and not unym denomination"); } - let tokens_in_unym: u128 = token_input_raw * 1_000_000; + let smallest_unit_multiplier = BigDecimal::from_u64(1_000_000).unwrap(); // For 6 decimal places + let amount_in_smallest_unit = scaled_amount * smallest_unit_multiplier; - let amount = Coin { - amount: tokens_in_unym, - denom: "unym".to_string(), - }; - if mix_id_list.contains(&mix_id) { - return Err(anyhow::anyhow!( - "Input document has duplicate delegation record for {}", - mix_id.clone() - )); - } else { - rows.push(InputFileRow { - mix_id: mix_id.clone(), + let amount = amount_in_smallest_unit.to_u128().ok_or_else(|| { + anyhow::anyhow!("Amount after scaling cannot be represented in u128") + })?; + + if !mix_id_set.insert(mix_id.clone()) { + anyhow::bail!("Duplicate mix_id found: {}", mix_id); + } + + rows.push(InputFileRow { + mix_id, + amount: Coin { amount, - }); - mix_id_list.push(mix_id); - } + denom: "unym".to_string(), + }, + }); } Ok(InputFileReader { rows }) } } fn write_to_csv( - output_details: Vec<[String; 4]>, + output_details: Vec<[String; 3]>, output_file: Option, ) -> Result<(), anyhow::Error> { if let Some(file_path) = output_file { @@ -117,7 +115,7 @@ fn write_to_csv( if !file_exists { let mut wtr = csv::Writer::from_writer(&file); - wtr.write_record(["Operation", "Mix ID", "Amount", "tx hash"])?; + wtr.write_record(["Operation", "Transaction Hash", "Timestamp"])?; wtr.flush()?; } @@ -135,22 +133,15 @@ fn write_to_csv( Ok(()) } -pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { +async fn fetch_delegation_data( + client: &SigningClient, +) -> Result, anyhow::Error> { let address = client.address(); - let records = match InputFileReader::new(&args.input) { - Ok(records) => records, - Err(e) => { - println!("Error reading input file: {}", e); - return; - } - }; - // Fetch all delegations for the user let delegations = match client.get_all_delegator_delegations(&address).await { Ok(delegations) => delegations, Err(e) => { - println!("Error fetching delegator delegations: {}", e); - return; + anyhow::bail!("Error fetching delegations: {}", e) } }; @@ -167,8 +158,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { let pending_events = match client.get_all_pending_epoch_events().await { Ok(events) => events, Err(e) => { - println!("Error fetching pending epoch events: {}", e); - return; + anyhow::bail!("Error fetching pending epoch events: {}", e); } }; @@ -176,7 +166,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { match event.event.kind { // If a pending undelegate tx is found, remove it from delegation map Undelegate { owner, mix_id, .. } => { - if owner == client.address().as_ref() + if owner == address.as_ref() && existing_delegation_map.get(&mix_id.to_string()).is_some() { existing_delegation_map.remove(&mix_id.to_string()); @@ -190,7 +180,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { amount, .. } => { - if owner == client.address().as_ref() { + if owner == address.as_ref() { let mut amount = Coin::from(amount); if let Some(pending_record) = pending_delegation_map.get(&mix_id.to_string()) { amount.amount += pending_record.amount; @@ -210,72 +200,83 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { .or_insert(amount); } + Ok(existing_delegation_map) +} + +pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { + let records = match InputFileReader::new(&args.input) { + Ok(records) => records, + Err(e) => { + println!("Error reading input file: {}", e); + return; + } + }; + + let existing_delegation_map = fetch_delegation_data(&client) + .await + .expect("Could not fetch existing delegations"); + let mut delegation_table = Table::new(); let mut undelegation_table = Table::new(); - let mut delegations_to_be_made: Vec<(String, Coin)> = Vec::new(); - let mut undelegations_to_be_made = Vec::new(); + let mut delegation_msgs: Vec<(ExecuteMsg, Vec)> = Vec::new(); + let mut undelegation_msgs: Vec<(ExecuteMsg, Vec)> = Vec::new(); delegation_table.set_header(["Mix ID", "Input Amount", "Adjusted Amount"]); undelegation_table.set_header(["Mix ID"]); - for row in records.rows.iter() { - // Check if there's an existing delegation for this mix_id - if let Some(existing_delegation_record) = existing_delegation_map.get(&row.mix_id) { - let existing_delegation_amount = existing_delegation_record.amount; - let input_amount = row.amount.amount; + for row in &records.rows { + let input_amount = row.amount.amount; + let existing_delegation_amount = existing_delegation_map + .get(&row.mix_id) + .map_or(0, |coin| coin.amount); - match existing_delegation_amount.cmp(&input_amount) { - // Nothing to do if the delegation record matches, just continue - Ordering::Equal => continue, + match existing_delegation_amount.cmp(&input_amount) { + Ordering::Equal => continue, // No action needed if amounts are equal - // If existing delegation is lesser, we need to delegate only remaining amount - Ordering::Less => { - let adjusted_amount = Coin { - amount: input_amount - existing_delegation_amount, - denom: existing_delegation_record.denom.clone(), - }; + Ordering::Less => { + // Delegate the difference if the existing delegation is less + let difference = Coin { + amount: input_amount - existing_delegation_amount, + denom: row.amount.denom.clone(), + }; + let mix_id = row.mix_id.clone().parse::().unwrap(); + delegation_msgs.push((DelegateToMixnode { mix_id }, vec![difference.clone()])); + delegation_table.add_row(&[ + row.mix_id.clone(), + pretty_coin(&row.amount), + pretty_coin(&difference), + ]); + } - delegation_table.add_row([ - row.mix_id.clone(), - pretty_coin(&row.amount.clone()), - pretty_coin(&adjusted_amount), - ]); - delegations_to_be_made.push((row.mix_id.clone(), adjusted_amount)); - } + Ordering::Greater => { + let mix_id = row.mix_id.clone().parse::().unwrap(); + let coins: Vec = vec![]; + undelegation_msgs.push((UndelegateFromMixnode { mix_id }, coins)); + undelegation_table.add_row(&[row.mix_id.clone()]); - // If existing delegation is greater, we need to undelegate and delegate the specified amount - Ordering::Greater => { - undelegations_to_be_made.push(row.mix_id.clone()); - undelegation_table.add_row([row.mix_id.clone()]); - - delegations_to_be_made.push((row.mix_id.clone(), row.amount.clone())); - delegation_table.add_row([ + if row.amount.amount > 0 { + delegation_msgs.push((DelegateToMixnode { mix_id }, vec![row.amount.clone()])); + delegation_table.add_row(&[ row.mix_id.clone(), pretty_coin(&row.amount), pretty_coin(&row.amount), ]); } - }; // match close - } else { - delegations_to_be_made.push((row.mix_id.clone(), row.amount.clone())); - delegation_table.add_row([ - row.mix_id.clone(), - pretty_coin(&row.amount.clone()), - pretty_coin(&row.amount.clone()), - ]); + } } } - if delegations_to_be_made.is_empty() && undelegations_to_be_made.is_empty() { + if delegation_msgs.is_empty() && undelegation_msgs.is_empty() { println!("Nothing to do. Delegations are up-to-date!"); return; } - if !delegations_to_be_made.is_empty() { - println!("Delegation records : \n{}\n\n", delegation_table); + + if !undelegation_msgs.is_empty() { + println!("Undelegation records : \n{}\n\n", undelegation_table); } - if !undelegations_to_be_made.is_empty() { - println!("Undelegation records : \n{}\n\n", undelegation_table); + if !delegation_msgs.is_empty() { + println!("Delegation records : \n{}\n\n", delegation_table); } let ans = inquire::Confirm::new("Do you want to continue with the shown operations?") @@ -293,47 +294,66 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { return; } - let mut output_details: Vec<[String; 4]> = Vec::new(); + let mut output_details: Vec<[String; 3]> = Vec::new(); + let now = time::OffsetDateTime::now_utc(); + let now = now + .format(&time::format_description::well_known::Rfc3339) + .unwrap(); - // Perform undelegation operations - for mix_id in undelegations_to_be_made { + let mixnet_contract = client + .mixnet_contract_address() + .expect("mixnet contract address is not available"); + + // Execute all undelegation transactions + if !undelegation_msgs.is_empty() { let res = client - .undelegate_from_mixnode(mix_id.parse::().unwrap(), None) + .execute_multiple( + mixnet_contract, + undelegation_msgs.clone(), + None, + format!( + "Undelegate from {} nodes via nym-cli", + undelegation_msgs.len() + ), + ) .await - .expect("Failed to undelegate from mixnode"); - info!( - "Undelegation from {} successful. tx: {}", - mix_id, &res.transaction_hash + .expect("Could not undelegate!"); + + println!( + "Undelegation transaction successful : {}", + res.transaction_hash ); - if args.output.is_some() { - output_details.push([ - "Undelegate".into(), - mix_id.clone(), - "-".into(), - res.transaction_hash.to_string(), - ]); - } + output_details.push([ + "Undelegate".to_string(), + res.transaction_hash.to_string(), + now.clone(), + ]); } - // Perform delegation operations - for (mix_id, amount) in delegations_to_be_made { + // Execute all delegation delegations + if !delegation_msgs.is_empty() { let res = client - .delegate_to_mixnode(mix_id.parse::().unwrap(), amount.clone(), None) + .execute_multiple( + mixnet_contract, + delegation_msgs, + None, + format!( + "Delegatations to {} nodes via nym-cli", + undelegation_msgs.len() + ), + ) .await - .expect("Failed to delegate to mixnode"); + .expect("Could not delegate"); - info!( - "Delegation to {} successful. tx: {}", - mix_id, &res.transaction_hash + println!( + "Delegation transaction successful : {}", + res.transaction_hash ); - if args.output.is_some() { - output_details.push([ - "Delegate".into(), - mix_id.clone(), - pretty_coin(&amount), - res.transaction_hash.to_string(), - ]); - } + output_details.push([ + "Delegate".to_string(), + res.transaction_hash.to_string(), + now.clone(), + ]); } if args.output.is_some() { From 377e06daabb932a680150defb97c1840133e6ef7 Mon Sep 17 00:00:00 2001 From: Sachin Kamath Date: Thu, 22 Feb 2024 18:10:41 +0530 Subject: [PATCH 117/394] nym-cli: clippy fixes --- .../validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs index 2f36ed91f3..3488824052 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -108,7 +108,6 @@ fn write_to_csv( // Open the file for appending or creation let file = OpenOptions::new() - .write(true) .append(true) .create(true) .open(&file_path)?; From cb3e73fbd7a4b0f6e35342df4860b03698b61ca3 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Tue, 27 Feb 2024 14:17:44 +0000 Subject: [PATCH 118/394] [DOC]/operators: Validator rewards (#4427) * initialise token economics chapter * initialise validator rewards page * add todo points * syntax edits * docs: minor fixes * add currency overview * create bash scripts for nyx stake * add nymvisor url * final version of validator rewards * final version of validator rewards * final version of validator rewards --------- Co-authored-by: Sachin Kamath --- documentation/operators/book.toml | 9 ++- documentation/operators/src/SUMMARY.md | 6 ++ .../operators/src/nodes/manual-upgrade.md | 3 +- .../src/scripts/nyx-percent-stake.sh | 7 +++ .../operators/src/scripts/nyx-total-stake.sh | 4 ++ .../src/tokenomics/validator-rewards.md | 55 +++++++++++++++++++ 6 files changed, 79 insertions(+), 5 deletions(-) create mode 100755 documentation/operators/src/scripts/nyx-percent-stake.sh create mode 100755 documentation/operators/src/scripts/nyx-total-stake.sh create mode 100644 documentation/operators/src/tokenomics/validator-rewards.md diff --git a/documentation/operators/book.toml b/documentation/operators/book.toml index 0f2732e7f3..ba325763ad 100644 --- a/documentation/operators/book.toml +++ b/documentation/operators/book.toml @@ -1,7 +1,7 @@ [book] -title = "Nym Docs" +title = "Nym Operators Guide" authors = ["Max Hampshire, Serinko, Alexia Lorenza Martinel"] -description = "Nym technical documentation" +description = "Everything needed to run Nym Mixnet components" language = "en" multilingual = false # for the moment - ideally work on chinese, brazillian portugese, spanish next src = "src" @@ -31,7 +31,7 @@ assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install` minimum_rust_version = "1.66" wallet_release_version = "1.2.8" # nym-vpn related variables -nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.3" +nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.4" nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" [preprocessor.last-changed] @@ -44,6 +44,9 @@ renderer = ["html"] # more pre-processor plugins to look into from https://github.com/rust-lang/mdBook/wiki/Third-party-plugins & https://lib.rs/keywords/mdbook-preprocessor # mdbook-i18n +# [preprocessor.api-call] +# command = "$(tokens=$(curl -L https://api.nymtech.net/cosmos/staking/v1beta1/pool | jq 'values[\"pool\"][\"bonded_tokens\"]') && echo ${tokens:0:2},${tokens:2:2})" + ######### # BUILD # ######### diff --git a/documentation/operators/src/SUMMARY.md b/documentation/operators/src/SUMMARY.md index 53e58ab2a3..6afd7c893c 100644 --- a/documentation/operators/src/SUMMARY.md +++ b/documentation/operators/src/SUMMARY.md @@ -23,6 +23,12 @@ - [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md) - [Troubleshooting](nodes/troubleshooting.md) +# Token Economics + + + +- [Nyx: Validator Rewards](tokenomics/validator-rewards.md) + # FAQ - [Mix Nodes](faq/mixnodes-faq.md) diff --git a/documentation/operators/src/nodes/manual-upgrade.md b/documentation/operators/src/nodes/manual-upgrade.md index 75f715b635..a9f8349736 100644 --- a/documentation/operators/src/nodes/manual-upgrade.md +++ b/documentation/operators/src/nodes/manual-upgrade.md @@ -23,7 +23,7 @@ systemctl start .service journalctl -f -u .service # to monitor log of you node ``` -If these steps are too difficult and you prefer to just run a script, you can use [ExploreNYM script](https://github.com/ExploreNYM/bash-tool) or one done by [Nym developers](https://gist.github.com/tommyv1987/4dca7cc175b70742c9ecb3d072eb8539). +If these steps are too difficult and you prefer to automate the process, try to setup your flow with [Nymvisor](nymvisor-upgrade.md). > In case of a Network Requester this is all, the following step is only for Mix Nodes and Gateways. @@ -98,4 +98,3 @@ The most common reason for your validator being jailed is that your validator is Running the command `df -H` will return the size of the various partitions of your VPS. If the `/dev/sda` partition is almost full, try pruning some of the `.gz` syslog archives and restart your validator process. - diff --git a/documentation/operators/src/scripts/nyx-percent-stake.sh b/documentation/operators/src/scripts/nyx-percent-stake.sh new file mode 100755 index 0000000000..89b85f929c --- /dev/null +++ b/documentation/operators/src/scripts/nyx-percent-stake.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +stake_unyx=$(curl -s -L https://api.nymtech.net/cosmos/staking/v1beta1/pool | jq 'values["pool"]["bonded_tokens"]') +stake_unyx=$(python -c "print(int($stake_unyx))") +stake_nyx=$(python -c "print($stake_unyx / 1000000)") +voting288k_percent=$(python -c "print(288000 / $stake_nyx * 100)") +echo ${voting288k_percent:0:4}% diff --git a/documentation/operators/src/scripts/nyx-total-stake.sh b/documentation/operators/src/scripts/nyx-total-stake.sh new file mode 100755 index 0000000000..1f000428cf --- /dev/null +++ b/documentation/operators/src/scripts/nyx-total-stake.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +stake=$(curl -s -L https://api.nymtech.net/cosmos/staking/v1beta1/pool | jq 'values["pool"]["bonded_tokens"]') +echo ${stake:1:2}.${stake:3:3} diff --git a/documentation/operators/src/tokenomics/validator-rewards.md b/documentation/operators/src/tokenomics/validator-rewards.md new file mode 100644 index 0000000000..f4b1210704 --- /dev/null +++ b/documentation/operators/src/tokenomics/validator-rewards.md @@ -0,0 +1,55 @@ +# Nyx Validator Rewards + +## Summary + +* Nyx Validators are rewarded in NYM tokens from the Nym mixmining pool and increasingly from apps that run on the Nym mixnet, the first of which is the NymVPN. +* Validators are rewarded for two different types of work: signing blocks in the Nyx chain and running the NymAPI to monitor mixnet routing and sign zk-nym credentials. +* New validators can join via a NYM-to-NYX swap contract. The contract will not allow more than 1% of total stake increase per month to prevent sudden hostile takeovers. Current stake is million Nyx. Rate: 1:4.8 ~ 288k NYX for 60k NYM => voting power +* NYX tokens serve no other purpose than self-delegation for voting power and governance. All rewards are in NYM and distributed directly to the validators self-delegation address and are not distributed to stakers. +* The contract will only allow swapping NYM to NYX and will **not** allow exchanging NYX back to NYM. A NYX holder who wishes to sell their NYX stake will have to do so via OTC trades. + +## Validator Rewards + +Nyx Validators perform two types of work for which they will be rewarded: + +### 1. Signing blocks in the Nyx chain + +A “block signing monitor" monitors blocks being produced on the Nyx chain and gathers the signatures present on every block. After an epoch ends, the monitor will assess performance of a validator and distribute tokens (to the self-delegation wallet) proportional to the voting period and uptime of the validator. + +### 2. Running the NymAPI to monitor Mixnet routing and sign zk-nyms (Nym’s anonymous credentials) + +Validator rewards initially come from the Nym mixmining pool with additional rewards increasingly coming from paid applications running on the Nym mixnet. The first paid application is the NymVPN. Nyx validators will be rewarded for their work directly in NYM tokens to their validator self-delegation address. + +1. **From mixmining pool** - at a rate of 1000 NYM per hour, of which 2/3 are distributed for signing blocks and 1/3 for zk-nyms. These are stable in NYM, and therefore will fluctuate in their fiat value depending on exchange rate. + +2. **From vpn user subscriptions** - the rate is tied to the growth of NymVPN subscriptions and will be stable in fiat, fluctuating in NYM depending on exchange rate. 1/3 will be distributed for signing blocks and 2/3 for zk-nyms. + +| Source | Signing blocks | Running NymAPI | Currency | +| :-- | --: | --: | :---: | +| Mixmining pool | 2/3 | 1/3 | NYM | +| NymVPN | 1/3 | 2/3 | fiat | + +#### zk-nyms + +The zk-nyms enable people to anonymously prove access rights to the upcoming NymVPN client without having to reveal payment details that might compromise their privacy. This is the first of what we imagine to be many possible use-cases for the zk-nym scheme. + +### Allocation of Rewards from Nym mixmining pool + +Rewards for validators will be distributed at an hourly rate from the mixmining pool. The amount is 1000 NYM per hour to be distributed among all validators. The fraction of mixmining rewards received by each individual validator is proportional to its contributions to the network. + +Two thirds of the available rewards (670 NYM per hour) are distributed proportionally to each validator’s share when signing blocks in the chain, for which tx fees are also received in the same proportion; while the last third (330 NYM per hour) is allocated to validators running the NymAPI, proportionally to their contribution to signing zk-nym credentials. + +The rewards are stable in NYM and fluctuate in their fiat value depending on the exchange rate of NYM tokens. + +## Permissionless Nyx Chain + +To allow new validators to join Nyx chain a new smart contract will be set up to release NYX in exchange for NYM. This contract allows a limited amount of NYM tokens to be deposited per month. The deposited NYM tokens are added to the mixmining pool and thus contribute to future rewards of all nodes and validators. + +The smart contract will have two parameters: + +1. the maximum amount of NYX available for purchase per month +2. the NYM-to-NYX exchange rate offered by the contract + +### Maximum Amount of NYX Available for Purchase per Month + +The contract will not allow more than 1% of total stake increase per month to prevent sudden hostile takeovers. Current stake level is million Nyx. From 19de5cb792a45161b3c981af6d772cee3a03acbe Mon Sep 17 00:00:00 2001 From: Yana Date: Mon, 30 Oct 2023 15:03:24 +0100 Subject: [PATCH 119/394] WIP WIP --- explorer/package.json | 9 +- .../src/components/ConnectKeplrWallet.tsx | 100 + explorer/src/components/Nav.tsx | 34 + explorer/webpack.config.js | 3 + yarn.lock | 3003 ++++++++++++----- 5 files changed, 2275 insertions(+), 874 deletions(-) create mode 100644 explorer/src/components/ConnectKeplrWallet.tsx diff --git a/explorer/package.json b/explorer/package.json index 885f378254..7a3ac0e785 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -19,6 +19,8 @@ }, "dependencies": { "@cosmjs/math": "^0.26.2", + "@cosmos-kit/keplr": "^2.3.11", + "@cosmos-kit/react": "^2.8.2", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@mui/icons-material": "^5.0.0", @@ -30,10 +32,12 @@ "@nymproject/nym-validator-client": "^0.18.0", "@nymproject/react": "^1.0.0", "big.js": "^6.2.1", + "buffer": "^6.0.3", + "chain-registry": "^1.19.0", "d3-scale": "^4.0.0", "date-fns": "^2.24.0", - "lodash": "^4.17.21", "i18n-iso-countries": "^6.8.0", + "lodash": "^4.17.21", "react": "^18.2.0", "react-dom": "^18.2.0", "react-error-boundary": "^3.1.4", @@ -110,6 +114,9 @@ "webpack-favicons": "^1.3.8", "webpack-merge": "^5.8.0" }, + + + "browserslist": { "production": [ ">0.2%", diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx new file mode 100644 index 0000000000..9541b6fcf9 --- /dev/null +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -0,0 +1,100 @@ +import { useChain } from '@cosmos-kit/react'; +import { Box, Button, Card } from '@mui/material'; +import Big from 'big.js'; + +import { useEffect, useState, useMemo } from 'react'; + +import '@interchain-ui/react/styles'; + +export function useIsClient() { + const [isClient, setIsClient] = useState(false); + + useEffect(() => { + setIsClient(true); + }, []); + + return isClient; +} + +export const uNYMtoNYM = (unym: string, rounding = 6) => { + const nym = Big(unym).div(1000000).toFixed(rounding); + + return { + asString: () => { + return nym; + }, + asNumber: () => { + return Number(nym); + }, + }; +}; + +export default function ConnectKeplrWallet() { + const { username, connect, disconnect, wallet, openView, address, getCosmWasmClient, isWalletConnected } = + useChain('nyx'); + const isClient = useIsClient(); + + const [balance, setBalance] = useState<{ + status: 'loading' | 'success'; + data?: string; + }>({ status: 'loading', data: undefined }); + + useEffect(() => { + const getBalance = async (walletAddress: string) => { + setBalance({ status: 'loading', data: undefined }); + + const account = await getCosmWasmClient(); + const uNYMBalance = await account.getBalance(walletAddress, 'unym'); + const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); + + setBalance({ status: 'success', data: NYMBalance }); + }; + + if (address) { + getBalance(address); + } + }, [address, getCosmWasmClient]); + + console.log('balance :>> ', balance); + + if (!isClient) return null; + + const getGlobalbutton = () => { + // if (globalStatus === 'Connecting') { + // return ; + // } + if (isWalletConnected) { + return ( + + + + {address} + Balance: {balance.data} NYM + + + + ); + } + + return ; + }; + + return ( + + +
{getGlobalbutton()}
+
+
+ ); +} diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx index c4d065aea6..9a0ac5f3d4 100644 --- a/explorer/src/components/Nav.tsx +++ b/explorer/src/components/Nav.tsx @@ -25,6 +25,13 @@ import { Footer } from './Footer'; import { NymVpnIcon } from '../icons/NymVpn'; import { DarkLightSwitchDesktop } from './Switch'; import { NavOptionType } from '../context/nav'; +import ConnectKeplrWallet from './ConnectKeplrWallet'; +import { assets, chains } from 'chain-registry'; +import { ChainProvider } from '@cosmos-kit/react'; +import { wallets as keplr } from '@cosmos-kit/keplr'; +import { useMemo } from 'react'; + +import '@interchain-ui/react/styles'; const drawerWidth = 255; const bannerHeight = 80; @@ -273,6 +280,33 @@ export const Nav: FCWithChildren = ({ children }) => { } }; + const assetsFixedUp = useMemo(() => { + const nyx = assets.find((a) => a.chain_name === 'nyx'); + if (nyx) { + const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); + if (nyxCoin) { + nyxCoin.coingecko_id = 'nyx'; + } + nyx.assets = nyx.assets.reverse(); + } + return assets; + }, [assets]); + + const chainsFixedUp = useMemo(() => { + const nyx = chains.find((c) => c.chain_id === 'nyx'); + if (nyx) { + if (!nyx.staking) { + nyx.staking = { + staking_tokens: [{ denom: 'unyx' }], + lock_duration: { + blocks: 10000, + }, + }; + } + } + return chains; + }, [chains]); + return ( =16.5.1 < 17" "@octokit/plugin-enterprise-rest" "6.0.1" @@ -2368,92 +2680,92 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@mui/base@5.0.0-beta.18": - version "5.0.0-beta.18" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.18.tgz#f95d393cf80974e77c0823170cc15c854d5af84b" - integrity sha512-e9ZCy/ndhyt5MTshAS3qAUy/40UiO0jX+kAo6a+XirrPJE+rrQW+mKPSI0uyp+5z4Vh+z0pvNoJ2S2gSrNz3BQ== +"@mui/base@5.0.0-beta.22": + version "5.0.0-beta.22" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.22.tgz#9ea6be6c8bfc4d8f825660da36d228f5315d4706" + integrity sha512-l4asGID5tmyerx9emJfXOKLyXzaBtdXNIFE3M+IrSZaFtGFvaQKHhc3+nxxSxPf1+G44psjczM0ekRQCdXx9HA== dependencies: - "@babel/runtime" "^7.23.1" + "@babel/runtime" "^7.23.2" "@floating-ui/react-dom" "^2.0.2" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.16" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.12.tgz#7be13094ef0c2fc7c3854da2b90a7eae456ebefd" - integrity sha512-WZhCkKqhrXaSVBzoC6LNcVkIawS000OOt7gmnp4g9HhyvN0PSclRXc/JrkC7EwfzUAZJh+hiK2LaVsbtOpNuOg== +"@mui/core-downloads-tracker@^5.14.16": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.16.tgz#03ceb422d69a33e6c1cbd7e943cf60816878be2a" + integrity sha512-97isBjzH2v1K7oB4UH2f4NOkBShOynY6dhnoR2XlUk/g6bb7ZBv2I3D1hvvqPtpEigKu93e7f/jAYr5d9LOc5w== "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.12.tgz#6634cdc3198bc438e8d38ce591c96d63d5df99a0" - integrity sha512-aFm6g/AIB3RQN9h/4MKoBoBybLZXeR3aDHWNx6KzemEpIlElUxv5uXRX5Qk1VC6v/YPkhbaPsiLLjsRSTiZF3w== + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.16.tgz#bd394183b0cfb068d4fa48292cd8d329be8d6b16" + integrity sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg== dependencies: - "@babel/runtime" "^7.23.1" + "@babel/runtime" "^7.23.2" "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.147" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.147.tgz#5586ef727c355617c499d0e13ab7dbd33ece1e09" - integrity sha512-AZjDEl31/co9baYrOBHMlXI8BCrV9JTCGDE2+IswVm32HNPYL5V2gHL3wKqn+MIFeCEg+z2es+8CU/Bau0JNSQ== + version "5.0.0-alpha.151" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.151.tgz#4f0e904f0db8088c5c9a3c3da5bde676cb3ce7ca" + integrity sha512-EAIzoDZ0WATa31m71juG1LnURjsmdkUOjNqy2j5WUp4y80obdGYKTT1Yh1hdI5SKND6621vaBPiGoKITjCZJ8A== dependencies: - "@babel/runtime" "^7.23.1" - "@mui/base" "5.0.0-beta.18" - "@mui/system" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@babel/runtime" "^7.23.2" + "@mui/base" "5.0.0-beta.22" + "@mui/system" "^5.14.16" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.16" "@mui/x-tree-view" "6.0.0-alpha.1" clsx "^2.0.0" prop-types "^15.8.1" "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.12.tgz#8fa5bebd1a096796a288b548f1ba867e068601c8" - integrity sha512-EelF2L46VcVqhg3KjzIGBBpOtcBgRh0MMy9Efuk6Do81QdcZsFC9RebCVAflo5jIdbHiBmxBs5/l5Q9NjONozg== + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.16.tgz#45cd62d312d10399d3813ee6dc43bd1f11179bf4" + integrity sha512-W4zZ4vnxgGk6/HqBwgsDHKU7x2l2NhX+r8gAwfg58Rhu3ikfY7NkIS6y8Gl3NkATc4GG1FNaGjjpQKfJx3U6Jw== dependencies: - "@babel/runtime" "^7.23.1" - "@mui/base" "5.0.0-beta.18" - "@mui/core-downloads-tracker" "^5.14.12" - "@mui/system" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" - "@types/react-transition-group" "^4.4.6" + "@babel/runtime" "^7.23.2" + "@mui/base" "5.0.0-beta.22" + "@mui/core-downloads-tracker" "^5.14.16" + "@mui/system" "^5.14.16" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.16" + "@types/react-transition-group" "^4.4.8" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.12.tgz#b07f710b9794c928052ee4c91bf67fc3e0a442ea" - integrity sha512-TWwm+9+BgHFpoR3w04FG+IqID4ALa74A27RuKq2CEaWgxliBZB24EVeI6djfjFt5t4FYmIb8BMw2ZJEir7YjLQ== +"@mui/private-theming@^5.14.16": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.16.tgz#ffdc9a9d3deaa46af000f04c0a9cc3a982f73071" + integrity sha512-FNlL0pTSEBh8nXsVWreCHDSHk+jG8cBx1sxRbT8JVtL+PYbYPi802zfV4B00Kkf0LNRVRvAVQwojMWSR/MYGng== dependencies: - "@babel/runtime" "^7.23.1" - "@mui/utils" "^5.14.12" + "@babel/runtime" "^7.23.2" + "@mui/utils" "^5.14.16" prop-types "^15.8.1" -"@mui/styled-engine@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.12.tgz#bfacc045f14f8f8bef735c76ecfd90bc99427c43" - integrity sha512-bocxt1nDmXfB3gpLfCCmFCyJ7sVmscFs+PuheO210QagZwHVp47UIRT1AiswLDYSQo1ZqmVGn7KLEJEYK0d4Xw== +"@mui/styled-engine@^5.14.16": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.16.tgz#a4a78a9980f138c2e705d04d67d44051f5005f22" + integrity sha512-FfvYvTG/Zd+KXMMImbcMYEeQAbONGuX5Vx3gBmmtB6KyA7Mvm9Pma1ly3R0gc44yeoFd+2wBjn1feS8h42HW5w== dependencies: - "@babel/runtime" "^7.23.1" + "@babel/runtime" "^7.23.2" "@emotion/cache" "^11.11.0" csstype "^3.1.2" prop-types "^15.8.1" "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.12.tgz#8a2e9b1165dd0a746fb15e64591bffab398122d7" - integrity sha512-nrtF23SRd7eRHTRebE1qnBQ4u5XojNlp3kvL54xIhuAi+mMuSXtJgwkRL04uoz0NZPalfdF8RaeFVN2INIkHKg== + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.16.tgz#663e5f2317c2b631d9d8bd873f23344ab0729815" + integrity sha512-pBA2eLBEfqLv/jmu9qGcErwml27upH2YBFRuRU2loZm5R57di5y/GjpM9EWc77+49axaTlHfO8LWbic4kPvxoQ== dependencies: - "@babel/runtime" "^7.23.1" + "@babel/runtime" "^7.23.2" "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@mui/private-theming" "^5.14.16" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.16" clsx "^2.0.0" csstype "^3.1.2" hoist-non-react-statics "^3.3.2" @@ -2467,32 +2779,32 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.12": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.12.tgz#da5b32c2a10bbe58f8b4839c5d5de449dc35e425" - integrity sha512-6DXfjjLhW0/ia5qU3Crke7j+MnfDbMBOHlLIrqbrEqNs0AuSBv8pXniEGb+kqO0H804NJreRTEJRjCngwOX5CA== +"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.16": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.16.tgz#5c30c5123767416358c3b73774eb985e189119a4" + integrity sha512-uKnPfsDqDs8bbN54TviAuoGWOmFiQLwNZ3Wvj+OBkJCzwA6QnLb/sSeCB7Pk3ilH4h4jQ0BHtbR+Xpjy9wlOuA== dependencies: - "@babel/runtime" "^7.23.1" - "@mui/private-theming" "^5.14.12" - "@mui/styled-engine" "^5.14.12" - "@mui/types" "^7.2.5" - "@mui/utils" "^5.14.12" + "@babel/runtime" "^7.23.2" + "@mui/private-theming" "^5.14.16" + "@mui/styled-engine" "^5.14.16" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.16" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" -"@mui/types@^7.2.5": - version "7.2.5" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.5.tgz#cd62a1fc5eb1044137ccab2053b431dd7cfc3cb8" - integrity sha512-S2BwfNczr7VwS6ki8GoAXJyARoeSJDLuxOEPs3vEMyTALlf9PrdHv+sluX7kk3iKrCg/ML2mIWwapZvWbkMCQA== +"@mui/types@^7.2.8": + version "7.2.8" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" + integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== -"@mui/utils@^5.10.3", "@mui/utils@^5.14.12", "@mui/utils@^5.14.3", "@mui/utils@^5.7.0": - version "5.14.12" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.12.tgz#58b570839e22e0fba71e17d37d9c083fe233704d" - integrity sha512-RFNXnhKQlzIkIUig6mmv0r5VbtjPdWoaBPYicq25LETdZux59HAqoRdWw15T7lp3c7gXOoE8y67+hTB8C64m2g== +"@mui/utils@^5.10.3", "@mui/utils@^5.14.16", "@mui/utils@^5.14.3", "@mui/utils@^5.7.0": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.16.tgz#09a15fd45530cadc642c5c08eb6cc660ea230506" + integrity sha512-3xV31GposHkwRbQzwJJuooWpK2ybWdEdeUPtRjv/6vjomyi97F3+68l+QVj9tPTvmfSbr2sx5c/NuvDulrdRmA== dependencies: - "@babel/runtime" "^7.23.1" - "@types/prop-types" "^15.7.7" + "@babel/runtime" "^7.23.2" + "@types/prop-types" "^15.7.9" prop-types "^15.8.1" react-is "^18.2.0" @@ -2558,6 +2870,14 @@ "@gar/promisify" "^1.0.1" semver "^7.3.5" +"@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + "@npmcli/fs@^3.1.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" @@ -2595,6 +2915,14 @@ mkdirp "^1.0.4" rimraf "^3.0.2" +"@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + "@npmcli/node-gyp@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" @@ -2914,10 +3242,178 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== -"@remix-run/router@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.9.0.tgz#9033238b41c4cbe1e961eccb3f79e2c588328cf6" - integrity sha512-bV63itrKBC0zdT27qYm6SDZHlkXwFL1xMBuhkn+X7l0+IIhNaH5wuuvZKp6eKhCD4KFhujhfhCT1YxXW6esUIA== +"@react-aria/focus@^3.14.3": + version "3.14.3" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.14.3.tgz#5e66dbf47e1d92aebf67d52b3b08d1631591f5b6" + integrity sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + +"@react-aria/i18n@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.8.4.tgz#e7ecd3edcaa66ceaf9ebb1034395e021685163af" + integrity sha512-YlTJn7YJlUxds/T5dNtme551qc118NoDQhK+IgGpzcmPQ3xSnwBAQP4Zwc7wCpAU+xEwnNcsGw+L1wJd49He/A== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/message" "^3.1.1" + "@internationalized/number" "^3.3.0" + "@internationalized/string" "^3.1.1" + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/interactions@^3.19.1": + version "3.19.1" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.19.1.tgz#b17b1f9dc84624d4222c7fa0a4fa6b4c14fe125a" + integrity sha512-2QFOvq/rJfMGEezmtYcGcJmfaD16kHKcSTLFrZ8aeBK6hYFddGVZJZk+dXf+G7iNaffa8rMt6uwzVe/malJPBA== + dependencies: + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/label@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.2.tgz#6563495cad2af9262e722514e88406baede48852" + integrity sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/label" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/live-announcer@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz#bf864b8820fb02daaeefc1c972782a0174fd60b9" + integrity sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-aria/numberfield@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.9.1.tgz#de8bbcfbd971c22311a85a3ab34165c53ff96519" + integrity sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/spinbutton" "^3.5.4" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/numberfield" "^3.6.2" + "@react-types/button" "^3.9.0" + "@react-types/numberfield" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/spinbutton@^3.5.4": + version "3.5.4" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz#d1c317838f4ae55d6a2e6c698581e4cf0f2b0c89" + integrity sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/utils" "^3.21.1" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/ssr@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.8.0.tgz#e7f467ac42f72504682724304ce221f785d70d49" + integrity sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-aria/textfield@^3.12.2": + version "3.12.2" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.12.2.tgz#e1ae5abaf72ed9c800e6a8afface3b2fd58258ca" + integrity sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + "@swc/helpers" "^0.5.0" + +"@react-aria/utils@^3.21.1": + version "3.21.1" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.21.1.tgz#35f5d545757ea38f05a0d2f5492f13217ebb03ce" + integrity sha512-tySfyWHXOhd/b6JSrSOl7krngEXN3N6pi1hCAXObRu3+MZlaZOMDf/j18aoteaIF2Jpv8HMWUJUJtQKGmBJGRA== + dependencies: + "@react-aria/ssr" "^3.8.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + +"@react-icons/all-files@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" + integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== + +"@react-stately/numberfield@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.6.2.tgz#2102d956239721fbf629891d2de46920416492fc" + integrity sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ== + dependencies: + "@internationalized/number" "^3.3.0" + "@react-stately/utils" "^3.8.0" + "@react-types/numberfield" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/utils@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.8.0.tgz#88a45742c58bde804f6cbecb20ea3833915cfdf0" + integrity sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-types/button@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.0.tgz#66df80cafaa98aaa34c331e927d21fdf4a0bdc4a" + integrity sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/label@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.8.1.tgz#b076a0fb955051307bfa3fed7e18ce0dc76d8c7b" + integrity sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/numberfield@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.6.1.tgz#da13f9086181a64a7e2e39f500584bdca20097b3" + integrity sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/shared@^3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.21.0.tgz#1af41fdf7dfbdbd33bbc1210617c43ed0d4ef20c" + integrity sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg== + +"@react-types/textfield@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.8.1.tgz#433c82d8f696ed77b1d5e71aadc40cbe378b536c" + integrity sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg== + dependencies: + "@react-types/shared" "^3.21.0" + +"@remix-run/router@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.11.0.tgz#e0e45ac3fff9d8a126916f166809825537e9f955" + integrity sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -2959,9 +3455,9 @@ resolve "^1.22.1" "@rollup/pluginutils@^5.0.1": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.4.tgz#74f808f9053d33bafec0cc98e7b835c9667d32ba" - integrity sha512-0KJnIoRI8A+a1dqOYLxH8vBf8bphDmty5QvIm2hqm7oFCFYKCAZWWd2hXgMibaPsNDhI0AtpYfQZJG47pt/k4g== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz#bbb4c175e19ebfeeb8c132c2eea0ecb89941a66c" + integrity sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -2972,80 +3468,75 @@ resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== -"@sentry-internal/tracing@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.73.0.tgz#4838f31e41d23a6041ef4520519b80f788bf1cac" - integrity sha512-ig3WL/Nqp8nRQ52P205NaypGKNfIl/G+cIqge9xPW6zfRb5kJdM1YParw9GSJ1SPjEZBkBORGAML0on5H2FILw== +"@sentry-internal/tracing@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.77.0.tgz#f3d82486f8934a955b3dd2aa54c8d29586e42a37" + integrity sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw== dependencies: - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" - tslib "^2.4.1 || ^1.9.3" + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" -"@sentry/browser@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.73.0.tgz#a8eaeb50cf16ca32f0039a81719c503d7045495f" - integrity sha512-e301hUixcJ5+HNKCJwajFF5smF4opXEFSclyWsJuFNufv5J/1C1SDhbwG2JjBt5zzdSoKWJKT1ewR6vpICyoDw== +"@sentry/browser@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.77.0.tgz#155440f1a0d3a1bbd5d564c28d6b0c9853a51d72" + integrity sha512-nJ2KDZD90H8jcPx9BysQLiQW+w7k7kISCWeRjrEMJzjtge32dmHA8G4stlUTRIQugy5F+73cOayWShceFP7QJQ== dependencies: - "@sentry-internal/tracing" "7.73.0" - "@sentry/core" "7.73.0" - "@sentry/replay" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" - tslib "^2.4.1 || ^1.9.3" + "@sentry-internal/tracing" "7.77.0" + "@sentry/core" "7.77.0" + "@sentry/replay" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" -"@sentry/core@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.73.0.tgz#1caeeec44f42c4d58c06cc05dec39e5497b65aa3" - integrity sha512-9FEz4Gq848LOgVN2OxJGYuQqxv7cIVw69VlAzWHEm3njt8mjvlTq+7UiFsGRo84+59V2FQuHxzA7vVjl90WfSg== +"@sentry/core@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.77.0.tgz#21100843132beeeff42296c8370cdcc7aa1d8510" + integrity sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg== dependencies: - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" - tslib "^2.4.1 || ^1.9.3" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" "@sentry/integrations@^7.54.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.73.0.tgz#f12d4a6422787cc6d50471bbdec52ed32611a444" - integrity sha512-IjVpn4d+aSL9L1Ntu/oAdRwujz4BzzavDsZf96Xgc/AjBnjAEUT+wT1dAwluThfuKDXmWOJHhZ2cHHMfqI+7vw== + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.77.0.tgz#f2717e05cb7c69363316ccd34096b2ea07ae4c59" + integrity sha512-P055qXgBHeZNKnnVEs5eZYLdy6P49Zr77A1aWJuNih/EenzMy922GOeGy2mF6XYrn1YJSjEwsNMNsQkcvMTK8Q== dependencies: - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" localforage "^1.8.1" - tslib "^2.4.1 || ^1.9.3" "@sentry/react@^7.54.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.73.0.tgz#8591bb70ac683b43fbe41736c2c321a4661ce22d" - integrity sha512-RCGlxW0Xp5vsC38LGxUO0Xf11LBzfg75VN+KS3D2FS5GXl0R0JwgUyPNVlod7YMCfwytsKGhfP+YpQvHGQAVwg== + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.77.0.tgz#9da14e4b21eae4b5a6306d39bb7c42ef0827d2c2" + integrity sha512-Q+htKzib5em0MdaQZMmPomaswaU3xhcVqmLi2CxqQypSjbYgBPPd+DuhrXKoWYLDDkkbY2uyfe4Lp3yLRWeXYw== dependencies: - "@sentry/browser" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry/browser" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" hoist-non-react-statics "^3.3.2" - tslib "^2.4.1 || ^1.9.3" -"@sentry/replay@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.73.0.tgz#4e6c522bac5c12f596ef76afe15ecb3807407669" - integrity sha512-a8IC9SowBisLYD2IdLkXzx7gN4iVwHDJhQvLp2B8ARs1PyPjJ7gCxSMHeGrYp94V0gOXtorNYkrxvuX8ayPROA== +"@sentry/replay@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.77.0.tgz#21d242c9cd70a7235237216174873fd140b6eb80" + integrity sha512-M9Ik2J5ekl+C1Och3wzLRZVaRGK33BlnBwfwf3qKjgLDwfKW+1YkwDfTHbc2b74RowkJbOVNcp4m8ptlehlSaQ== dependencies: - "@sentry/core" "7.73.0" - "@sentry/types" "7.73.0" - "@sentry/utils" "7.73.0" + "@sentry-internal/tracing" "7.77.0" + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" -"@sentry/types@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.73.0.tgz#6d811bbe413d319df0a592a672d6d72a94a8e716" - integrity sha512-/v8++bly8jW7r4cP2wswYiiVpn7eLLcqwnfPUMeCQze4zj3F3nTRIKc9BGHzU0V+fhHa3RwRC2ksqTGq1oJMDg== +"@sentry/types@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144" + integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA== -"@sentry/utils@7.73.0": - version "7.73.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.73.0.tgz#530cf023f7c395aa7708cd3824e5a45948449c10" - integrity sha512-h3ZK/qpf4k76FhJV9uiSbvMz3V/0Ovy94C+5/9UgPMVCJXFmVsdw8n/dwANJ7LupVPfYP23xFGgebDMFlK1/2w== +"@sentry/utils@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.77.0.tgz#1f88501f0b8777de31b371cf859d13c82ebe1379" + integrity sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g== dependencies: - "@sentry/types" "7.73.0" - tslib "^2.4.1 || ^1.9.3" + "@sentry/types" "7.77.0" "@sideway/address@^4.1.3": version "4.1.4" @@ -3117,6 +3608,140 @@ dependencies: "@sinonjs/commons" "^1.7.0" +"@stablelib/aead@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" + integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== + +"@stablelib/binary@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" + integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== + dependencies: + "@stablelib/int" "^1.0.1" + +"@stablelib/bytes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== + +"@stablelib/chacha20poly1305@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" + integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== + dependencies: + "@stablelib/aead" "^1.0.1" + "@stablelib/binary" "^1.0.1" + "@stablelib/chacha" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/poly1305" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/chacha@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" + integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/constant-time@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== + +"@stablelib/ed25519@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" + integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== + dependencies: + "@stablelib/random" "^1.0.2" + "@stablelib/sha512" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/hash@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" + integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== + +"@stablelib/hkdf@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" + integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== + dependencies: + "@stablelib/hash" "^1.0.1" + "@stablelib/hmac" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/hmac@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" + integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/int@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" + integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== + +"@stablelib/keyagreement@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== + dependencies: + "@stablelib/bytes" "^1.0.1" + +"@stablelib/poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" + integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/sha256@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" + integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/sha512@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" + integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + +"@stablelib/wipe@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" + integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== + +"@stablelib/x25519@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== + dependencies: + "@stablelib/keyagreement" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + "@storybook/addon-actions@6.5.16", "@storybook/addon-actions@^6.5.8": version "6.5.16" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" @@ -3503,13 +4128,13 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channels@7.4.6": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.4.6.tgz#cadd16b91db08005c2b9e4938d3e1d1290d27a40" - integrity sha512-yPv/sfo2c18fM3fvG0i1xse63vG8l33Al/OU0k/dtovltPu001/HVa1QgBgsb/QrEfZtvGjGhmtdVeYb39fv3A== +"@storybook/channels@7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.2.tgz#f5ea597a799e13b7307fe79067faede5e13e6619" + integrity sha512-3SgqWq9NS0XX1QxK3riuaOLrReHWwVhI63u6q1ryDD3SttpmAezZETibOAtzDuk2FKgsyHTmAlmcGQf4ZxhOJA== dependencies: - "@storybook/client-logger" "7.4.6" - "@storybook/core-events" "7.4.6" + "@storybook/client-logger" "7.5.2" + "@storybook/core-events" "7.5.2" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -3549,10 +4174,10 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/client-logger@7.4.6", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.4.6.tgz#3346f3ae51abb3ce61bf1a7d083d32f27b8f718f" - integrity sha512-XDw31ZziU//86PKuMRnmc+L/G0VopaGKENQOGEpvAXCU9IZASwGKlKAtcyosjrpi+ZiUXlMgUXCpXM7x3b1Ehw== +"@storybook/client-logger@7.5.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.2.tgz#ffe6fd3cb336fc7dac6670412c4c8bf70e89c1d1" + integrity sha512-7YgLItlmiYDzWYexTaRNuHhtFarh9krsI+8l7Yjn9ryoHSTJUcTWx+yPJm1II+PQR8v/x5UgsxzultjgEurfRQ== dependencies: "@storybook/global" "^5.0.0" @@ -3659,10 +4284,10 @@ dependencies: core-js "^3.8.2" -"@storybook/core-events@7.4.6": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.4.6.tgz#f0b652c623c1afebda42d1702d631cecc1c137bf" - integrity sha512-r5vrE+32lwrJh1NGFr1a0mWjvxo7q8FXYShylcwRWpacmL5NTtLkrXOoJSeGvJ4yKNYkvxQFtOPId4lzDxa32w== +"@storybook/core-events@7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.2.tgz#e5185e39fdcb7ab93510f6174798d5f242e1041b" + integrity sha512-DV8bFEFVKDEvaH87KYPXDE0YEV+Y9yjFv2xxmC9pF8l+MWCtVW72RBLhB+gU5NM1bkHrRDNb0lOJfVGKlhxOog== dependencies: ts-dedent "^2.0.0" @@ -3796,15 +4421,15 @@ global "^4.4.0" "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.4.6.tgz#7a941a31aeae6cc1864689288d66cb282368b602" - integrity sha512-K5atRoVFCl6HEgkSxIbwygpzgE/iROc7BrtJ3z3a7E70sanFr6Jxt6Egu6fz2QkL3ef4EWpXMnle2vhEfG29pA== + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.2.tgz#1a88c0e4e30d4b8d79c0aeaf106048e3ac9ecfa0" + integrity sha512-1l36cc7GaVeTiknhToZcaqI6RsIOfcBgdnvgJ0tiL1naN1GkneCMr+1oLWnlHVrWIOXgh6vNyD792kE3uTLkFg== dependencies: - "@storybook/channels" "7.4.6" - "@storybook/client-logger" "7.4.6" - "@storybook/core-events" "7.4.6" + "@storybook/channels" "7.5.2" + "@storybook/client-logger" "7.5.2" + "@storybook/core-events" "7.5.2" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.4.6" + "@storybook/preview-api" "7.5.2" "@storybook/manager-webpack4@6.5.16": version "6.5.16" @@ -3920,17 +4545,17 @@ dependencies: core-js "^3.8.2" -"@storybook/preview-api@7.4.6": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.4.6.tgz#a42749ff867216b89849ada6ac0f49f4fa8f03a8" - integrity sha512-byUS/Opt3ytWD4cWz3sNEKw5Yks8MkQgRN+GDSyIomaEAQkLAM0rchPC0MYjwCeUSecV7IIQweNX5RbV4a34BA== +"@storybook/preview-api@7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.2.tgz#72512c11369975904894c6f50036f10d3c329e59" + integrity sha512-rpmHR/09UBSnorDBTcE7JgHUQjZLO146NCI+vbI7Pqfb4QX/8lhwkFr4cuHRAR16mv6DAJbDVoPETO0Z/CH9aw== dependencies: - "@storybook/channels" "7.4.6" - "@storybook/client-logger" "7.4.6" - "@storybook/core-events" "7.4.6" + "@storybook/channels" "7.5.2" + "@storybook/client-logger" "7.5.2" + "@storybook/core-events" "7.5.2" "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/types" "7.4.6" + "@storybook/types" "7.5.2" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -4111,12 +4736,12 @@ memoizerific "^1.11.3" regenerator-runtime "^0.13.7" -"@storybook/types@7.4.6": - version "7.4.6" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.4.6.tgz#536f21b82e1f809052b4d09802f99a580e960175" - integrity sha512-6QLXtMVsFZFpzPkdGWsu/iuc8na9dnS67AMOBKm5qCLPwtUJOYkwhMdFRSSeJthLRpzV7JLAL8Kwvl7MFP3QSw== +"@storybook/types@7.5.2": + version "7.5.2" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.2.tgz#38f2e4a4cb0bb402b840d9e7f7762c0d113dc63b" + integrity sha512-RDKHo6WUES+4nt7uZMfankjxdpYX2EI2GpJ2n2RPcnhzmb/ub1huNTjbzDEYMqY24SppljZeIN57m3Ar6L6f9A== dependencies: - "@storybook/channels" "7.4.6" + "@storybook/channels" "7.5.2" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -4247,10 +4872,17 @@ "@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1" +"@swc/helpers@^0.5.0": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" + integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== + dependencies: + tslib "^2.4.0" + "@tauri-apps/api@^1.2.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.0.tgz#46a0f9b6edd4bfc39be32afc4ad242e0b8cca3ea" - integrity sha512-yQY9wpVNuiYhLLuyDlu1nBpqJELT1fGp7OctN4rW9I2W1T2p7A3tqPxsEzQprEwneQRBAlPM9vC8NsnMbct+pg== + version "1.5.1" + resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.1.tgz#9074476c4323f71351db624e9711c99277cdfb99" + integrity sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA== "@tauri-apps/cli-darwin-arm64@1.5.6": version "1.5.6" @@ -4429,14 +5061,14 @@ "@types/estree" "*" "@types/aria-query@^5.0.1": - version "5.0.2" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.2.tgz#6f1225829d89794fd9f891989c9ce667422d7f64" - integrity sha512-PHKZuMN+K5qgKIWhBodXzQslTo5P+K/6LqeKXS6O/4liIDdZqaX5RXrCK++LAw+y/nptN48YmUMFiQHRSWYwtQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.3.tgz#07570ebd25f9b516c910a91f7244052c9b58eabc" + integrity sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.2.tgz#215db4f4a35d710256579784a548907237728756" - integrity sha512-pNpr1T1xLUc2l3xJKuPtsEky3ybxN3m4fJkknfIpTCTfIZCDW57oAg+EfCgIIp2rvCe0Wn++/FfodDS4YXxBwA== + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" + integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -4445,205 +5077,206 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.5" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.5.tgz#281f4764bcbbbc51fdded0f25aa587b4ce14da95" - integrity sha512-h9yIuWbJKdOPLJTbmSpPzkF67e659PbQDba7ifWm5BJ8xTv+sDmS7rFmywkWOvXedGTivCdeGSIIX8WLcRTz8w== + version "7.6.6" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" + integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.2.tgz#843e9f1f47c957553b0c374481dc4772921d6a6b" - integrity sha512-/AVzPICMhMOMYoSx9MoKpGDKdBRsIXMNByh1PXSZoa+v6ZoLa8xxtsT/uLQ/NJm0XVAWl/BvId4MlDeXJaeIZQ== + version "7.4.3" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" + integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.20.2" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.2.tgz#4ddf99d95cfdd946ff35d2b65c978d9c9bf2645d" - integrity sha512-ojlGK1Hsfce93J0+kn3H5R73elidKUaZonirN33GSmgTUMpzI/MIFfSpF3haANe3G1bEBS9/9/QEqwTzwqFsKw== + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" + integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== dependencies: "@babel/types" "^7.20.7" "@types/big.js@^6.1.6": - version "6.2.0" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.0.tgz#e1f6a9a6ce64bc7c131137e71fbad34a5574f987" - integrity sha512-ubLURWoc4tCw/8Yds0P3CE9cBG5q+aoycwWBiXXx4gp7XPYZy9ch0L9+Pv6osSoSRgvuQNqJdlwEhP5QhKKl6w== + version "6.2.1" + resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.1.tgz#0e5eda9b8ffe33e2cc4540fad6e91a4c7255ca88" + integrity sha512-dKzZVT10m3ELZgYIShPJ+3Os/E1s3aDQS+wr1ne7VCLU/8hc/R+z/+gkm9WabxSkV9E8wJhTl5wC+0fD9nitsw== "@types/body-parser@*": - version "1.19.3" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.3.tgz#fb558014374f7d9e56c8f34bab2042a3a07d25cd" - integrity sha512-oyl4jvAfTGX9Bt6Or4H9ni1Z447/tQuxnZsytsCaExKlmJiU8sFgnIBRzJUpKwB5eWn9HuBYlUlVA74q/yN0eQ== + version "1.19.4" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462" + integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA== dependencies: "@types/connect" "*" "@types/node" "*" "@types/bonjour@^3.5.9": - version "3.5.11" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.11.tgz#fbaa46a1529ea5c5e46cde36e4be6a880db55b84" - integrity sha512-isGhjmBtLIxdHBDl2xGwUzEM8AOyOvWsADWq7rqirdi/ZQoHnLWErHvsThcEzTX8juDRiZtzp2Qkv5bgNh6mAg== + version "3.5.12" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8" + integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg== dependencies: "@types/node" "*" "@types/bs58@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.2.tgz#2f266fb45d19aab4028a9488e7941aa39a537e9a" - integrity sha512-ytn3FpvB9LRQGxK2vMHD12tgmUhx7TUTbA8A2VbhDVC0eqzgfvoU1rYBOeCl7hJDtTMaOg/Sl9xIOQhkY0G4uw== + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.3.tgz#0ccc90341c886acb7abeb42c6f848403a6a021af" + integrity sha512-yVMwEsD7S5YU372eUWAmFRmTqF6EUSqs1Tj2X1kD0hiA4YlE33BhC3tELKLVYpZQEc5gLIQX2BAXmJdXaBARXA== dependencies: + "@types/node" "*" base-x "^3.0.6" "@types/connect-history-api-fallback@^1.3.5": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.1.tgz#6e5e3602d93bda975cebc3449e1a318340af9e20" - integrity sha512-iaQslNbARe8fctL5Lk+DsmgWOM83lM+7FzP0eQUJs1jd3kBE8NWqBTIT2S8SqQOJjxvt2eyIjpOuYeRXq2AdMw== + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc" + integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" "@types/connect@*": - version "3.4.36" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.36.tgz#e511558c15a39cb29bd5357eebb57bd1459cd1ab" - integrity sha512-P63Zd/JUGq+PdrM1lv0Wv5SBYeA2+CORvbrXbngriYY0jzLUWfQMQQxOhjONEz/wlHOAxOdY7CY65rgQdTjq2w== + version "3.4.37" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5" + integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q== dependencies: "@types/node" "*" "@types/d3-array@^3.0.3": - version "3.0.8" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.8.tgz#a5d0687a12b48142c6f124d5e3796054e91bcea5" - integrity sha512-2xAVyAUgaXHX9fubjcCbGAUOqYfRJN1em1EKR2HfzWBpObZhwfnZKvofTN4TplMqJdFQao61I+NVSai/vnBvDQ== + version "3.0.9" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.9.tgz#54feabd29d1f15940d422c16008c63c1e4e3d188" + integrity sha512-mZowFN3p64ajCJJ4riVYlOjNlBJv3hctgAY01pjw3qTnJePD8s9DZmYDzhHKvzfCYvdjwylkU38+Vdt7Cu2FDA== "@types/d3-color@*": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.1.tgz#43a2aa7836fdae19ce32fabe97742e787f4b2e08" - integrity sha512-CSAVrHAtM9wfuLJ2tpvvwCU/F22sm7rMHNN+yh9D6O6hyAms3+O0cgMpC1pm6UEUMOntuZC8bMt74PteiDUdCg== + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.2.tgz#7939eed011a908287cd1bcfd11580c17b2ac7f8a" + integrity sha512-At+Ski7dL8Bs58E8g8vPcFJc8tGcaC12Z4m07+p41+DRqnZQcAlp3NfYjLrhNYv+zEyQitU1CUxXNjqUyf+c0g== "@types/d3-color@^1": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.3.tgz#147ef0d582ef7c0ee2b4e4a24b862af553dcc54b" - integrity sha512-jcHMwBcuuQ1LPt43jdbOhdOFczfDfhzvAZ1+1L0KiXPv4VqGsWAltxfxUDvtSuIMsvTZ2eeua+tOtxI6qqxYUg== + version "1.4.4" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.4.tgz#d8a270d6fd864977ea339899a0dfb35974da93a4" + integrity sha512-KsjVf5gjylqqZIsRxYPiFQIY8NvmJEmA9nMrJT0yCcpABhvYzhjoCCPCjaYMANp96GBdS4VXRfhHWnCTudDdJg== "@types/d3-dsv@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.4.tgz#f2706ed90f72e8c16d3858b3c3060dfd47b7f161" - integrity sha512-YxfUVJ55HxR8oq88136w09mBMPNhgH7PZjteq72onWXWOohGif/cLQnQv8V4A5lEGjXF04LhwSTpmzpY9wyVyA== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.5.tgz#c12df56be81d0b457d167842fa87276d0d6eb880" + integrity sha512-73WZR3QFOaSRVz9iOrebTbTnbo7xjcgS/i0Cq5zy0jMXPO3v/JbkTD3Zqii1eYE6v4EJ78g5VP407rm+p8fdlA== "@types/d3-ease@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.0.tgz#c29926f8b596f9dadaeca062a32a45365681eae0" - integrity sha512-aMo4eaAOijJjA6uU+GIeW018dvy9+oH5Y2VPPzjjfxevvGQ/oRDs+tfYC9b50Q4BygRR8yE2QCLsrT0WtAVseA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.1.tgz#ef386d2f28602dba82206888047f97f7f7f7558a" + integrity sha512-VZofjpEt8HWv3nxUAosj5o/+4JflnJ7Bbv07k17VO3T2WRuzGdZeookfaF60iVh5RdhVG49LE5w6LIshVUC6rg== "@types/d3-fetch@^3.0.1": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.4.tgz#e54ab1286f859c8f0edb261c3ce4b155a3232c37" - integrity sha512-RleYajubALkGjrvatxWhlygfvB1KNF0Uzz9guRUeeA+M/2B7l8rxObYdktaX9zU1st04lMCHjZWe4vbl+msH2Q== + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.5.tgz#0bec3763a04d199ad8bce2756b6f6818ee188b32" + integrity sha512-Rc8pb6H0RRLpAV2hEXduykUgcDUOhjSLTLmCIeo6ejzgs4SaITh/EteMb3p5Env3Hqjsqw0fCksyqopHHzMkMg== dependencies: "@types/d3-dsv" "*" "@types/d3-geo@^1": - version "1.12.5" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.5.tgz#49eeec89e0816c5e47dd2faca65072948bff39ce" - integrity sha512-YRqBbphH5XZuNtsVsjWKDZZYparpwxDlEiQSdROePXJYZ+Ibi4UwCkSA3hIH484c/kvUv8Dpx5ViefKTLsC1Ow== + version "1.12.6" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.6.tgz#127802904cd656e9a8c45489d3110a1f87fbacb7" + integrity sha512-ZUjOG+unedpNb2IGYau7WdQcoGQjrVnVrpAdJTcIE1g7wD4kR4rHQy7JYPu+5iZ2C8DOXQnbtsyimo2fP2AykA== dependencies: "@types/geojson" "*" "@types/d3-geo@^3.0.2": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.5.tgz#4407202458b306c97c90c9a5271b3b7e1fc687af" - integrity sha512-ysEEU93Wv9p2UZBxTK3kUP7veHgyhTA0qYtI7bxK5EMXb3JxGv0D4IH54PxprAF26n+uHci24McVmzwIdLgvgQ== + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.6.tgz#138821c463c67551e1cc13729f0211986c5c3cce" + integrity sha512-wblAES3b+C3hvp4VakwECEKtHquT/xc6K4HOna95LM1j1fd7s7WmU4V+JMQZfKhNCMkV2vWD+ZUgY2Uj6gqfuA== dependencies: "@types/geojson" "*" "@types/d3-interpolate@^1": - version "1.4.3" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.3.tgz#a4d58d84b0b0feb5a6e25de4df4e1e9bb647bcb3" - integrity sha512-eosrP1F0BPnpok+3/dK12/ZusskELe2mZBJfuynIhTw6oCpNcBsVHEJ2dyfTMkm1mv+OX7vQ4G89sYqh9+jHWg== + version "1.4.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.4.tgz#cae4c7e7da8649a869cb4f25e62f289b43c86167" + integrity sha512-iZOtsYamYn0qP8f4U7EtQV4JqR/2z0Mp9AxUdPnuC+D8ovmnw/ZFvpoC0mVKJ9eZzrA/fscGr3/R9892F5RRxg== dependencies: "@types/d3-color" "^1" "@types/d3-interpolate@^3.0.1": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.2.tgz#b5928cca26fc20dbfe689ff37d62f7bac434c74e" - integrity sha512-zAbCj9lTqW9J9PlF4FwnvEjXZUy75NQqPm7DMHZXuxCFTpuTrdK2NMYGQekf4hlasL78fCYOLu4EE3/tXElwow== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.3.tgz#e10c06c4bf11bd770ed56184a0d76cd516ff4ded" + integrity sha512-6OZ2EIB4lLj+8cUY7I/Cgn9Q+hLdA4DjJHYOQDiHL0SzqS1K9DL5xIOVBSIHgF+tiuO9MU1D36qvdIvRDRPh+Q== dependencies: "@types/d3-color" "*" "@types/d3-path@*": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.0.tgz#939e3a784ae4f80b1fde8098b91af1776ff1312b" - integrity sha512-0g/A+mZXgFkQxN3HniRDbXMN79K3CdTpLsevj+PXiTcb2hVyvkZUBg37StmgCQkaD84cUJ4uaDAWq7UJOQy2Tg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.1.tgz#6171c9e388904014764661a37613e3c4ab8df22d" + integrity sha512-blRhp7ki7pVznM8k6lk5iUU9paDbVRVq+/xpf0RRgSJn5gr6SE7RcFtxooYGMBOc1RZiGyqRpVdu5AD0z0ooMA== "@types/d3-scale@^4.0.1", "@types/d3-scale@^4.0.2": - version "4.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.5.tgz#daa4faa5438315a37a1f5eb1bcdc5aeb3d3e5a2d" - integrity sha512-w/C++3W394MHzcLKO2kdsIn5KKNTOqeQVzyPSGPLzQbkPw/jpeaGtSRlakcKevGgGsjJxGsbqS0fPrVFDbHrDA== + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.6.tgz#9d221949f37b90b52696ec99f9b1e972d55fe10d" + integrity sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ== dependencies: "@types/d3-time" "*" "@types/d3-selection@^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.4.tgz#7d1f4c75678ec7c04b42653438000a9afedf769c" - integrity sha512-nbt9x1vP2C1Wz0JxZ2aSYFvJQIukc1QdL1zGHe5O989bDHpgrVz1mgmA/8n+vapb7g3mjUPe2YoLrqEalmtxKA== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.5.tgz#a0f436406ec3586f705fbe5d64cf1b5b28b25119" + integrity sha512-87ZWS/UZ+t1gJ0Ras1iWcyWOxOuzPhPfeEdTN19IyEHK28ssS3KI7orQZ3Eqyijhuvm7vxePh+U0cL79H9g41Q== "@types/d3-shape@^3.1.0": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.3.tgz#20eee7aad70f2562041af18e305fec6b48fd511d" - integrity sha512-cHMdIq+rhF5IVwAV7t61pcEXfEHsEsrbBUPkFGBwTXuxtTAkBBrnrNA8++6OWm3jwVsXoZYQM8NEekg6CPJ3zw== + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.4.tgz#748a256d5e499cdfb3e48beca9c557f3ea0ff15c" + integrity sha512-M2/xsWPsjaZc5ifMKp1EBp0gqJG0eO/zlldJNOC85Y/5DGsBQ49gDkRJ2h5GY7ZVD6KUumvZWsylSbvTaJTqKg== dependencies: "@types/d3-path" "*" "@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.1.tgz#f0c8f9037632cc4511ae55e7e1459dcb95fb3619" - integrity sha512-5j/AnefKAhCw4HpITmLDTPlf4vhi8o/dES+zbegfPb7LaGfNyqkLxBR6E+4yvTAgnJLmhe80EXFMzUs38fw4oA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.2.tgz#f4425b2ebcb04495a7b2390da03633ef1a8adbe5" + integrity sha512-kbdRXTmUgNfw5OTE3KZnFQn6XdIc4QGroN5UixgdrXATmYsdlPQS6pEut9tVlIojtzuFD4txs/L+Rq41AHtLpg== "@types/d3-timer@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.0.tgz#e2505f1c21ec08bda8915238e397fb71d2fc54ce" - integrity sha512-HNB/9GHqu7Fo8AQiugyJbv6ZxYz58wef0esl4Mv828w1ZKpAshw/uFWVDUcIB9KKFeFKoxS3cHY07FFgtTRZ1g== + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.1.tgz#8dac23292df0e559a3aa459d8efca78a734c3fbe" + integrity sha512-GGTvzKccVEhxmRfJEB6zhY9ieT4UhGVUIQaBzFpUO9OXy2ycAlnPCSJLzmGGgqt3KVjqN3QCQB4g1rsZnHsWhg== "@types/d3-zoom@^1": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.5.tgz#7461f8cb2201e7e4fee3e6c18db1d5d58ef993e0" - integrity sha512-h79/ayrjJUaXNuTvO1L4pAwBCe1kzLywoE1zjRmHsFftxtHzWco5od9Lv7FCtcwuhSOp1SKS2q3RWolcdJhLOw== + version "1.8.6" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.6.tgz#3c29d9549789419c55f98f2dccc52349838c5e15" + integrity sha512-MBQ34pRegwb+I59RexzTLTX09QqN1bJlXUd8oTbQjlUOWfuh0Fo0DV/D8Y6Lly+x3rfbVqIP61vdY/LhzQf6DA== dependencies: "@types/d3-interpolate" "^1" "@types/d3-selection" "^1" "@types/debug@^4.0.0": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.9.tgz#906996938bc672aaf2fb8c0d3733ae1dda05b005" - integrity sha512-8Hz50m2eoS56ldRlepxSBa6PWEVCtzUo/92HgLc2qTMnotJNIm7xP+UZhyWoYsyOdd5dxZ+NZLb24rsKyFs2ow== + version "4.1.10" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.10.tgz#f23148a6eb771a34c466a4fc28379d8101e84494" + integrity sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA== dependencies: "@types/ms" "*" "@types/eslint-scope@^3.7.3": - version "3.7.5" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.5.tgz#e28b09dbb1d9d35fdfa8a884225f00440dfc5a3e" - integrity sha512-JNvhIEyxVW6EoMIFIvj93ZOywYFatlpu9deeH6eSx6PE3WHYvHaQtmHmQeNw7aA81bYGBPPQqdtBm6b1SsQMmA== + version "3.7.6" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" + integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.44.3" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.3.tgz#96614fae4875ea6328f56de38666f582d911d962" - integrity sha512-iM/WfkwAhwmPff3wZuPLYiHX18HI24jU8k1ZSH7P8FHwxTjZ2P6CoX2wnF43oprR+YXJM6UUxATkNvyv/JHd+g== + version "8.44.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" + integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree-jsx@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.1.tgz#cc26c8566c67f27795bbc025f57cf0499d7cedd6" - integrity sha512-sHyakZlAezNFxmYRo0fopDZW+XvK6ipeZkkp5EAOLjdPfZp8VjZBJ67vSRI99RSCAoqXVmXOHS4fnWoxpuGQtQ== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.2.tgz#758bcb4f35f2a970362b2bd2b7021fe2ae6e8509" + integrity sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA== dependencies: "@types/estree" "*" "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" - integrity sha512-VeiPZ9MMwXjO32/Xu7+OwflfmeoRwkE/qzndw42gGtgJwZopBnzy2gD//NN1+go1mADzkDcqf/KnFRSjTJ8xJA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" + integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== "@types/estree@^0.0.51": version "0.0.51" @@ -4651,9 +5284,9 @@ integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.37" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.37.tgz#7e4b7b59da9142138a2aaa7621f5abedce8c7320" - integrity sha512-ZohaCYTgGFcOP7u6aJOhY9uIZQgZ2vxC2yWoArY+FeDXlqeH66ZVBjgvg+RLVAS/DWNq4Ap9ZXu1+SUQiiWYMg== + version "4.17.39" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8" + integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ== dependencies: "@types/node" "*" "@types/qs" "*" @@ -4661,9 +5294,9 @@ "@types/send" "*" "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": - version "4.17.18" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.18.tgz#efabf5c4495c1880df1bdffee604b143b29c4a95" - integrity sha512-Sxv8BSLLgsBYmcnGdGjjEjqET2U+AKAdCRODmMiq02FgjwuV75Ut85DRpvFjyw/Mk0vgUOliGRU0UUmuuZHByQ== + version "4.17.20" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433" + integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -4678,14 +5311,14 @@ "@types/node" "*" "@types/flat@^5.0.2": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.3.tgz#1f8045859a7e0955acf2a50e8c2979899e7b1801" - integrity sha512-uG/4x6EXYbq4VDsBJLNDHQAQmtRPg3x4tAXcBspxlnEknz8NiJxnHoxSiJKGNExiS00q4mJNvuEBgVA3jsDIdQ== + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.4.tgz#d8262918655d942cb0b79f09020240d5ff668557" + integrity sha512-Qy8SOE+x5F40jebCj4vPoA/Y6J2Zd6h9ihMPYP8U8//dDEOK4Yu0ShOTKqEmWPR+4AdV4sls/VCaR6azEFvKKg== "@types/geojson@*", "@types/geojson@^7946.0.8": - version "7946.0.11" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.11.tgz#012c17cb2256ad8de78560da851ab914a7b9b40e" - integrity sha512-L7A0AINMXQpVwxHJ4jxD6/XjZ4NDufaRlUJHjNIFKYUFBH1SvOW+neaqb0VTRSLW5suSrSu19ObFEFnfNcr+qg== + version "7946.0.12" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.12.tgz#0307536218d32e6b970bccd1d148b9c4e5b6f10d" + integrity sha512-uK2z1ZHJyC0nQRbuovXFt4mzXDwf27vQeUWNhfKGwRcWW429GOhP8HxUHlM6TLH4bzmlv/HlEjpvJh3JfmGsAA== "@types/glob@*": version "8.1.0" @@ -4704,16 +5337,16 @@ "@types/node" "*" "@types/graceful-fs@^4.1.2": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.6.tgz#e14b2576a1c25026b7f02ede1de3b84c3a1efeae" - integrity sha512-Sig0SNORX9fdW+bQuTEovKj3uHcUL6LQKbCrrqb1X7J6/ReAbhCXRAhc+SMejhLELFj2QcyuxmUooZ4bt5ReSw== + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" + integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== dependencies: "@types/node" "*" "@types/hast@^2.0.0": - version "2.3.6" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.6.tgz#bb8b05602112a26d22868acb70c4b20984ec7086" - integrity sha512-47rJE80oqPmFdVDCD7IheXBrVdwuBgsYwoczFvKmwfo2Mzsnt+V9OONsYauFmICb6lQPpCuXYJWejBNs4pDJRg== + version "2.3.7" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.7.tgz#5e9bd7ab4452d5313aeec9d38fbc193a70f8d810" + integrity sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw== dependencies: "@types/unist" "^2" @@ -4728,45 +5361,45 @@ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-errors@*": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.2.tgz#a86e00bbde8950364f8e7846687259ffcd96e8c2" - integrity sha512-lPG6KlZs88gef6aD85z3HNkztpj7w2R7HmR3gygjfXCQmsLloWNARFkMuzKiiY8FGdh1XDpgBdrSf4aKDiA7Kg== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62" + integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== "@types/http-proxy@^1.17.8": - version "1.17.12" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.12.tgz#86e849e9eeae0362548803c37a0a1afc616bd96b" - integrity sha512-kQtujO08dVtQ2wXAuSFfk9ASy3sug4+ogFR8Kd8UgP8PEuc1/G/8yjYRmp//PcDNJEUKOza/MrQu15bouEUCiw== + version "1.17.13" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465" + integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw== dependencies: "@types/node" "*" "@types/is-function@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" - integrity sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.2.tgz#1f29acd54f5473f0b4822548e27078eac4e450d2" + integrity sha512-Je5TaQzK7H06pt4e88WsjXwRC64EkmxsdqirUI+4GPVMjhs68Dmm8hr+yqf8tmpYlfR6zPlsJC5xs14dlVUehw== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" - integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" + integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== "@types/istanbul-lib-report@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#412e0725ef41cde73bfa03e0e833eaff41e0fd63" - integrity sha512-gPQuzaPR5h/djlAv2apEG1HVOyj1IUs7GpfMZixU0/0KXT3pm64ylHuMUI1/Akh+sq/iikxg6Z2j+fcMDXaaTQ== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" + integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.2.tgz#edc8e421991a3b4df875036d381fc0a5a982f549" - integrity sha512-kv43F9eb3Lhj+lr/Hn6OcLCs/sSM8bt+fIaP11rCYngfV6NVjzWXJ17owQtDQTL9tQ8WSLUrGsSJ6rJz0F1w1A== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" + integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@*": - version "29.5.5" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.5.tgz#727204e06228fe24373df9bae76b90f3e8236a2a" - integrity sha512-ebylz2hnsWR9mYvmBFbXJXr+33UPc4+ZdxyDXh5w0FlPBTfCVN3wPL+kuOiQt3xvrK419v7XWeAs+AeOksafXg== + version "29.5.7" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036" + integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -4780,9 +5413,9 @@ pretty-format "^27.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.13" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.13.tgz#02c24f4363176d2d18fc8b70b9f3c54aba178a85" - integrity sha512-RbSSoHliUbnXj3ny0CNFOoxrIDV6SUGyStHsvDqosw6CkdPV8TtWGlfecuK4ToyMEAql6pzNxgCFKanovUzlgQ== + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== "@types/json5@^0.0.29": version "0.0.29" @@ -4790,9 +5423,9 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.167", "@types/lodash@^4.14.175": - version "4.14.199" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.199.tgz#c3edb5650149d847a277a8961a7ad360c474e9bf" - integrity sha512-Vrjz5N5Ia4SEzWWgIVwnHNEnb1UE1XMkvY5DGXrAeOGE9imk0hgTHh5GyDjLDJi9OTCn9oo9dXH1uToK1VRfrg== + version "4.14.200" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149" + integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q== "@types/long@^4.0.1": version "4.0.2" @@ -4805,26 +5438,26 @@ integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== "@types/mdast@^3.0.0": - version "3.0.13" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.13.tgz#b7ba6e52d0faeb9c493e32c205f3831022be4e1b" - integrity sha512-HjiGiWedR0DVFkeNljpa6Lv4/IZU1+30VY5d747K7lBudFc3R0Ibr6yJ9lN3BE28VnZyDfLF/VB1Ql1ZIbKrmg== + version "3.0.14" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.14.tgz#0735473a5b35be032b9f2685b7413cbab1b8a639" + integrity sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw== dependencies: "@types/unist" "^2" "@types/mdx@^2.0.0": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.8.tgz#585229ff7057ab30c5e4a23fe126858881d818e5" - integrity sha512-r7/zWe+f9x+zjXqGxf821qz++ld8tp6Z4jUS6qmPZUXH6tfh4riXOhAqb12tWGWAevCFtMt1goLWkQMqIJKpsA== + version "2.0.9" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.9.tgz#80971e367bb884350ab5b2ce8fc06b34960170e7" + integrity sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg== "@types/mime@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.2.tgz#c1ae807f13d308ee7511a5b81c74f327028e66e8" - integrity sha512-Wj+fqpTLtTbG7c0tH47dkahefpLKEbB+xAZuLq7b4/IDHPl/n6VoXcyUQ2bypFlbSwvCr0y+bD4euTTqTJsPxQ== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91" + integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ== "@types/mime@^1": - version "1.3.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.3.tgz#bbe64987e0eb05de150c305005055c7ad784a9ce" - integrity sha512-Ys+/St+2VF4+xuY6+kDIXGxbNRO0mesVg0bbxEfB97Od1Vjpjx9KD1qxs64Gcb3CWPirk9Xe+PT4YiiHQ9T+eg== + version "1.3.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9" + integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw== "@types/minimatch@*", "@types/minimatch@^5.1.2": version "5.1.2" @@ -4837,29 +5470,41 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.3.tgz#dd249cef80c6fff2ba6a0d4e5beca913e04e25f8" - integrity sha512-ZYFzrvyWUNhaPomn80dsMNgMeXxNWZBdkuG/hWlUvXvbdUH8ZERNBGXnU87McuGcWDsyzX2aChCv/SVN348k3A== + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.4.tgz#81f886786411c45bba3f33e781ab48bd56bfca2e" + integrity sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ== "@types/ms@*": - version "0.7.32" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.32.tgz#f6cd08939ae3ad886fcc92ef7f0109dacddf61ab" - integrity sha512-xPSg0jm4mqgEkNhowKgZFBNtwoEwF6gJ4Dhww+GFpm3IgtNseHQZ5IqdNwnquZEoANxyDAKDRAdVo4Z72VvD/g== + version "0.7.33" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" + integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== "@types/node-fetch@^2.5.7": - version "2.6.6" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.6.tgz#b72f3f4bc0c0afee1c0bc9cff68e041d01e3e779" - integrity sha512-95X8guJYhfqiuVVhRFxVQcf4hW/2bCuoPwDasMf/531STFoNoWTT7YDnWdXHEZKqAGUigmpG31r2FE70LwnzJw== + version "2.6.8" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.8.tgz#9a2993583975849c2e1f360b6ca2f11755b2c504" + integrity sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA== dependencies: "@types/node" "*" form-data "^4.0.0" -"@types/node@*", "@types/node@>=13.7.0": - version "20.8.4" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.4.tgz#0e9ebb2ff29d5c3302fc84477d066fa7c6b441aa" - integrity sha512-ZVPnqU58giiCjSxjVUESDtdPk4QR5WQhhINbc9UBrKLU68MX5BF6kbQzTrkwbolyr0X8ChBpXfavr5mZFKZQ5A== +"@types/node-forge@^1.3.0": + version "1.3.8" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb" + integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg== dependencies: - undici-types "~5.25.1" + "@types/node" "*" + +"@types/node@*", "@types/node@>=13.7.0": + version "20.8.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" + integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== + dependencies: + undici-types "~5.26.4" + +"@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== "@types/node@^13.7.0": version "13.13.52" @@ -4867,24 +5512,26 @@ integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.58" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.58.tgz#bf66f63983104ed57c754f4e84ccaf16f8235adb" - integrity sha512-YGncyA25/MaVtQkjWW9r0EFBukZ+JulsLcVZBlGUfIb96OBMjkoRWwQo5IEWJ8Fj06Go3GHw+bjYDitv6BaGsA== + version "16.18.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.60.tgz#0b0f4316906f1bd0e03b640363f67bd4e86958bd" + integrity sha512-ZUGPWx5vKfN+G2/yN7pcSNLkIkXEvlwNaJEd4e0ppX7W2S8XAkdc/37hM4OUNJB9sa0p12AOvGvxL4JCPiz9DA== "@types/normalize-package-data@^2.4.0": - version "2.4.2" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.2.tgz#9b0e3e8533fe5024ad32d6637eb9589988b6fdca" - integrity sha512-lqa4UEhhv/2sjjIQgjX8B+RBjj47eo0mzGasklVJ78UKGQY1r0VpB9XHDaZZO9qzEFDdy4MrXLuEaSmPrPSe/A== + version "2.4.3" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" + integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== "@types/npmlog@^4.1.2": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" - integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.5.tgz#41f1b95437f9c86cbb326bb07f0d5683f905bf4f" + integrity sha512-Fl3TEbwPoR7V1z6CMJ18whXOUkOYqF5eCkGKTir2VuevdLYUmcwj9mQdvXzuY0oagZBbsy0J7df41jn+ZcwGRA== + dependencies: + "@types/node" "*" "@types/parse-json@^4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" - integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" + integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== "@types/parse5@^5.0.0": version "5.0.3" @@ -4897,43 +5544,43 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/pretty-hrtime@^1.0.0": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" - integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.2.tgz#9b6e102bc2e1eea1c1c7fadf144483ce2687f233" + integrity sha512-vyv9knII8XeW8TnXDcGH7HqG6FeR56ESN6ExM34d/U8Zvs3xuG34euV6CVyB7KEYI7Ts4lQM8b4NL72e7UadnA== -"@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.7": - version "15.7.8" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.8.tgz#805eae6e8f41bd19e88917d2ea200dc992f405d3" - integrity sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ== +"@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.9": + version "15.7.9" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" + integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== "@types/qrcode.react@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.3.tgz#ce6852ebc1bbe4f43d1854eb19982cff30351025" - integrity sha512-gl7Ozf3BRQwfDUAU2xx7sWRBe/s7TqO0HAJukSQHbEVfQrFo5WKgZl0BHlN8u9W1DHXb4elgKRolHLZkgETXyA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.4.tgz#4e6739769a21ee6072bceaab3ec0c866c6a79a17" + integrity sha512-O35T9AJk0wg7ffkgpSQ4Zr7I7eEfEsTCD5u7V2dsvYnZLfUpQz2rLg5ZG2FM/zLmOF4sEE0FY6mxT9WleUDb3Q== dependencies: "@types/react" "*" "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.8" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.8.tgz#f2a7de3c107b89b441e071d5472e6b726b4adf45" - integrity sha512-u95svzDlTysU5xecFNTgfFG5RUWu1A9P0VzgpcIiGZA9iraHOdSzcxMxQ55DyeRaGCSxQi7LxXDI4rzq/MYfdg== + version "6.9.9" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" + integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== "@types/range-parser@*": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.5.tgz#38bd1733ae299620771bd414837ade2e57757498" - integrity sha512-xrO9OoVPqFuYyR/loIHjnbvvyRZREYKLjxV4+dY6v3FQR3stQ9ZxIGkaclF7YhI9hfjpuTbu14hZEy94qKLtOA== + version "1.2.6" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a" + integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA== "@types/react-dom@<18.0.0": - version "17.0.21" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.21.tgz#85d56965483ce4850f5f03f9234e54a1f47786e5" - integrity sha512-3rQEFUNUUz2MYiRwJJj6UekcW7rFLOtmK7ajQP7qJpjNdggInl3I/xM4I3Hq1yYPdCGVMgax1gZsB7BBTtayXg== + version "17.0.22" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.22.tgz#34317e08be27b33fa9e7cdb56125b22538261bad" + integrity sha512-wHt4gkdSMb4jPp1vc30MLJxoWGsZs88URfmt3FRXoOEYrrqK3I8IuZLE/uFBb4UT6MRfI0wXFu4DS7LS0kUC7Q== dependencies: "@types/react" "^17" "@types/react-dom@^18.0.10": - version "18.2.12" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.12.tgz#58479c463d1e0b7f1ee7cd80e09186189f9ec32d" - integrity sha512-QWZuiA/7J/hPIGocXreCRbx7wyoeet9ooxfbSA+zbIWqyQEE7GMtRn4A37BdYyksnN+/NDnWgfxZH9UVGDw1hg== + version "18.2.14" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" + integrity sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ== dependencies: "@types/react" "*" @@ -4954,26 +5601,26 @@ dependencies: react-tooltip "*" -"@types/react-transition-group@^4.4.6": - version "4.4.7" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.7.tgz#bf69f269d74aa78b99097673ca6dd6824a68ef1c" - integrity sha512-ICCyBl5mvyqYp8Qeq9B5G/fyBSRC0zx3XM3sCC6KkcMsNeAHqXBKkmat4GqdJET5jtYUpZXrxI5flve5qhi2Eg== +"@types/react-transition-group@^4.4.6", "@types/react-transition-group@^4.4.8": + version "4.4.8" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" + integrity sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg== dependencies: "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.27" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.27.tgz#746e52b06f3ccd5d7a724fd53769b70792601440" - integrity sha512-Wfv7B7FZiR2r3MIqbAlXoY1+tXm4bOqfz4oRr+nyXdBqapDBZ0l/IGcSlAfvxIHEEJjkPU0MYAc/BlFPOcrgLw== + version "18.2.33" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.33.tgz#055356243dc4350a9ee6c6a2c07c5cae12e38877" + integrity sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/react@^17": - version "17.0.67" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.67.tgz#1c224738f203829a4692aa48e33a732c34fd014a" - integrity sha512-zE76EIJ0Y58Oy9yDX/9csb/NuKjt0Eq2YgWb/8Wxo91YmuLzzbyiRoaqJE9h8iDlsT7n35GdpoLomHlaB1kFbg== + version "17.0.69" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.69.tgz#245a0cf2f5b0fb1d645691d3083e3c7d4409b98f" + integrity sha512-klEeru//GhiQvXUBayz0Q4l3rKHWsBR/EUOhOeow6hK2jV7MlO44+8yEk6+OtPeOlRfnpUnrLXzGK+iGph5aeg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -4990,60 +5637,60 @@ integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/scheduler@*": - version "0.16.4" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.4.tgz#fedc3e5b15c26dc18faae96bf1317487cb3658cf" - integrity sha512-2L9ifAGl7wmXwP4v3pN4p2FLhD0O1qsJpvKmNin5VA8+UvNVb447UDaAEV6UdrkA+m/Xs58U1RFps44x6TFsVQ== + version "0.16.5" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" + integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== "@types/semver@^7.3.12", "@types/semver@^7.3.8": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.3.tgz#9a726e116beb26c24f1ccd6850201e1246122e04" - integrity sha512-OxepLK9EuNEIPxWNME+C6WwbRAOOI2o2BaQEGzz5Lu2e4Z5eDnEo+/aVEDMIXywoJitJ7xWd641wrGLZdtwRyw== + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== "@types/send@*": - version "0.17.2" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.2.tgz#af78a4495e3c2b79bfbdac3955fdd50e03cc98f2" - integrity sha512-aAG6yRf6r0wQ29bkS+x97BIs64ZLxeE/ARwyS6wrldMm3C1MdKwCcnnEwMC1slI8wuxJOpiUH9MioC0A0i+GJw== + version "0.17.3" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b" + integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug== dependencies: "@types/mime" "^1" "@types/node" "*" "@types/serve-index@^1.9.1": - version "1.9.2" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.2.tgz#cb26e775678a8526b73a5d980a147518740aaecd" - integrity sha512-asaEIoc6J+DbBKXtO7p2shWUpKacZOoMBEGBgPG91P8xhO53ohzHWGCs4ScZo5pQMf5ukQzVT9fhX1WzpHihig== + version "1.9.3" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9" + integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg== dependencies: "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.3" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.3.tgz#2cfacfd1fd4520bbc3e292cca432d5e8e2e3ee61" - integrity sha512-yVRvFsEMrv7s0lGhzrggJjNOSmZCdgCjw9xWrPr/kNNLp6FaDfMC1KaYl3TSJ0c58bECwNBMoQrZJ8hA8E1eFg== + version "1.15.4" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2" + integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw== dependencies: "@types/http-errors" "*" "@types/mime" "*" "@types/node" "*" "@types/sockjs@^0.3.33": - version "0.3.34" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.34.tgz#43e10e549b36d2ba2589278f00f81b5d7ccda167" - integrity sha512-R+n7qBFnm/6jinlteC9DBL5dGiDGjWAvjo4viUanpnc/dG1y7uDoacXPIQ/PQEg1fI912SMHIa014ZjRpvDw4g== + version "0.3.35" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21" + integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw== dependencies: "@types/node" "*" "@types/source-list-map@*": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.3.tgz#077e15c87fe06520e30396a533bd9848e735ce9b" - integrity sha512-I9R/7fUjzUOyDy6AFkehCK711wWoAXEaBi80AfjZt1lIkbe6AcXKd3ckQc3liMvQExWvfOeh/8CtKzrfUFN5gA== + version "0.1.4" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.4.tgz#a3d4e4791606f40a833ab1caf41f77463c8d72ff" + integrity sha512-Kdfm7Sk5VX8dFW7Vbp18+fmAatBewzBILa1raHYxrGEFXT0jNl9x3LWfuW7bTbjEKFNey9Dfkj/UzT6z/NvRlg== "@types/stack-utils@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.1.tgz#20f18294f797f2209b5f65c8e3b5c8e8261d127c" - integrity sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw== + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" + integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== "@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.9.tgz#1481a4236267dd2d0ca2a637adb90f0ccb3d69c4" - integrity sha512-fOHIwZua0sRltqWzODGUM6b4ffZrf/vzGUmNXdR+4DzuJP42PMbM5dLKcdzlYvv8bMJ3GALOzkk1q7cDm2zPyA== + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.10.tgz#5203aad08455c6988f7b2347715023e3935b1056" + integrity sha512-q8F20SdXG5fdVJQ5yxsVlH+f+oekP42QeHv4s5KlrxTMT0eopXn7ol1rhxMcksf8ph7XNv811iVDE2hOpUvEPg== "@types/testing-library__jest-dom@^5.9.1": version "5.14.9" @@ -5053,31 +5700,31 @@ "@types/jest" "*" "@types/topojson-client@^3.1.0": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.2.tgz#57b02c68d8fa8797f0d2ad046736be5e6700337a" - integrity sha512-Lp6ZDxSQf9Tr4IcV/aJ72Zk1Fso7oPg1AbLKF4b6Jc5k05z+WK7nmmpfneKsnbj1NNUwj2SgydBZyJzc4O865w== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.3.tgz#d710e90f0a4a25bbdbf4fc0c1863f9a6b5023e26" + integrity sha512-liC+dHCxoqQy5bbJMsF59Cx1WZZwbcT084v/5bdp3NWSFUuzQpsm4gbLQh+wlv58Mng4jCsO4p8hWelqGlb7rg== dependencies: "@types/geojson" "*" "@types/topojson-specification" "*" "@types/topojson-specification@*": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.3.tgz#40e7a1b754c244f1daf68c3334a88d22883ad40c" - integrity sha512-0rGL/Buelb+H2SVfmDRSDNxWgYQk4U/R18wrFc2DOfBKHaKOSz9bXbLQxAFY7j16e1E182bGwoSJdUhRq9fqBA== + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.4.tgz#df2d2738a11bacda3b88f5b4630e3da80a12a609" + integrity sha512-LG/a8kJi4X6MsFhZKiBAIC/a+yCFtjkHsDMwuQqSoB1az8D2bR2xRKU3aczizfcqdt2lVqnS+aJBFMrO+rO5Aw== dependencies: "@types/geojson" "*" "@types/uglify-js@*": - version "3.17.2" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.2.tgz#a2ba86fd524f6281a7655463338c546f845b29c3" - integrity sha512-9SjrHO54LINgC/6Ehr81NjAxAYvwEZqjUHLjJYvC4Nmr9jbLQCIZbWSvl4vXQkkmR1UAuaKDycau3O1kWGFyXQ== + version "3.17.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.3.tgz#784efb40320d248588e1748dd12e1f43733f1416" + integrity sha512-ToldSfJ6wxO21cakcz63oFD1GjqQbKzhZCD57eH7zWuYT5UEZvfUoqvrjX5d+jB9g4a/sFO0n6QSVzzn5sMsjg== dependencies: source-map "^0.6.1" "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.8" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.8.tgz#bb197b9639aa1a04cf464a617fe800cccd92ad5c" - integrity sha512-d0XxK3YTObnWVp6rZuev3c49+j4Lo8g4L1ZRm9z5L0xpoZycUPshHgczK5gsUMaZOstjVYYi09p5gYvUtfChYw== + version "2.0.9" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.9.tgz#72e164381659a49557b0a078b28308f2c6a3e1ce" + integrity sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ== "@types/uuid@^8.3.4": version "8.3.4" @@ -5085,23 +5732,23 @@ integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== "@types/webpack-env@^1.16.0": - version "1.18.2" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.2.tgz#0264bc30c0c4a073118ce5b26c5ef143da4374df" - integrity sha512-BFqcTHHTrrI8EBmIzNAmLPP3IqtEG9J1IPFWbPeS/F0/TGNmo0pI5svOa7JbMF9vSCXQCvJWT2gxLJNVuf9blw== + version "1.18.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f" + integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q== "@types/webpack-sources@*": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.1.tgz#98670b35fa799c44ac235910f3fda9bfdcdbc2c6" - integrity sha512-iLC3Fsx62ejm3ST3PQ8vBMC54Rb3EoCprZjeJGI5q+9QjfDLGt9jeg/k245qz1G9AQnORGk0vqPicJFPT1QODQ== + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.2.tgz#6e6027cad8b54d2a4e5735df49af559bb4de2db0" + integrity sha512-acCzhuVe+UJy8abiSFQWXELhhNMZjQjQKpLNEi1pKGgKXZj0ul614ATcx4kkhunPost6Xw+aCq8y8cn1/WwAiA== dependencies: "@types/node" "*" "@types/source-list-map" "*" source-map "^0.7.3" "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.34" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.34.tgz#8cf616be84b39c8fb26f9459d4470a5514df2477" - integrity sha512-CN2aOGrR3zbMc2v+cKqzaClYP1ldkpPOgtdNvgX+RmlWCSWxHxpzz6WSCVQZRkF8D60ROlkRzAoEpgjWQ+bd2g== + version "4.41.35" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.35.tgz#32903809685caf87ea612e4e74577874359c3749" + integrity sha512-XRC6HLGHtNfN8/xWeu1YUQV1GSE+28q8lSqvcJ+0xt/zW9Wmn4j9pCSvaXPyRlCKrl5OuqECQNEJUy2vo8oWqg== dependencies: "@types/node" "*" "@types/tapable" "^1" @@ -5111,42 +5758,42 @@ source-map "^0.6.0" "@types/ws@^8.5.5": - version "8.5.6" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.6.tgz#e9ad51f0ab79b9110c50916c9fcbddc36d373065" - integrity sha512-8B5EO9jLVCy+B58PLHvLDuOD8DRVMgQzq8d55SjLCOn9kqGyqOvy27exVaTio1q1nX5zLu8/6N0n2ThSxOM6tg== + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" + integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== dependencies: "@types/node" "*" "@types/yargs-parser@*": - version "21.0.1" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.1.tgz#07773d7160494d56aa882d7531aac7319ea67c3b" - integrity sha512-axdPBuLuEJt0c4yI5OZssC19K2Mq1uKdrfZBzuxLvaztgqUtFYZUNw7lETExPYJR9jdEoIg4mb7RQKRQzOkeGQ== + version "21.0.2" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" + integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== "@types/yargs@^15.0.0": - version "15.0.16" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.16.tgz#258009dc52907e8f03041eb64ffdac297ba4b208" - integrity sha512-2FeD5qezW3FvLpZ0JpfuaEWepgNLl9b2gQYiz/ce0NhoB1W/D+VZu98phITXkADYerfr/jb7JcDcVhITsc9bwg== + version "15.0.17" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.17.tgz#bea870ba551b43831bfaa75de2e4a3849c39322b" + integrity sha512-cj53I8GUcWJIgWVTSVe2L7NJAB5XWGdsoMosVvUgv1jEnMbAcsbaCzt1coUcyi8Sda5PgTWAooG8jNyDTD+CWA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.6" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.6.tgz#cc0c63684d68d23498cf0b5f32aa4c3fb437c638" - integrity sha512-oTP7/Q13GSPrgcwEwdlnkoZSQ1Hg9THe644qq8PG6hhJzjZ3qj1JjEFPIwWV/IXVs5XGIVqtkNOS9kh63WIJ+A== + version "16.0.7" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.7.tgz#b0d0502cb5f6c17994df72a600049f10bbf17203" + integrity sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.28" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.28.tgz#d106e4301fbacde3d1796ab27374dd16588ec851" - integrity sha512-N3e3fkS86hNhtk6BEnc0rj3zcehaxx8QWhCROJkqpl5Zaoi7nAic3jH8q94jVD3zu5LGk+PUB6KAiDmimYOEQw== + version "17.0.29" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" + integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== dependencies: "@types/yargs-parser" "*" "@types/zxcvbn@^4.4.1": - version "4.4.2" - resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.2.tgz#7b16c35330a15471cd7b9d3576503a40b6bd2416" - integrity sha512-T7SEL8b/eN7AEhHQ8oFt7c6Y+l3p8OpH7KwJIe+5oBOPLMMioPeMsUTB3huNgEnXhiittV8Ohdw21Jg8E/f70Q== + version "4.4.3" + resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.3.tgz#c323d8bf07673a782ef07950d4b6a878e56181fe" + integrity sha512-AxZBi8J3V3lm+f2Vgg06D8y0womXpLf3ZEDYeLPGGK0ydR724sQH83T5tYgN+CN6VTRnAlevFKJkWTecCnk8ug== "@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.7.0": version "5.62.0" @@ -5239,6 +5886,257 @@ "@typescript-eslint/types" "5.62.0" eslint-visitor-keys "^3.3.0" +"@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + +"@vanilla-extract/css-utils@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css-utils/-/css-utils-0.1.3.tgz#cadeb6bc563547b20e9b903647d8b334d3a79ef8" + integrity sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw== + +"@vanilla-extract/css@^1.12.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.13.0.tgz#85f521d428f55b0e9599675033caba81194cc6c0" + integrity sha512-JFFBXhnJrPlGqHBabagXqo5ghXw9mtV270ycIGyLDZG8NAK5eRwAYkMowAxuzK7wZSm67GnETWYB7b0AUmyttg== + dependencies: + "@emotion/hash" "^0.9.0" + "@vanilla-extract/private" "^1.0.3" + ahocorasick "1.0.2" + chalk "^4.1.1" + css-what "^6.1.0" + cssesc "^3.0.0" + csstype "^3.0.7" + deep-object-diff "^1.1.9" + deepmerge "^4.2.2" + media-query-parser "^2.0.2" + outdent "^0.8.0" + +"@vanilla-extract/dynamic@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.0.3.tgz#44b4e018cbdfb6af3d27e73c78b38617dfe419ad" + integrity sha512-Rglfw2gXAYiBzAQ4jgUG7rBgE2c88e/zcG27ZVoIqMHVq56wf2C1katGMm1yFMNBgzqM7oBNYzz4YOMzznydkg== + dependencies: + "@vanilla-extract/private" "^1.0.3" + +"@vanilla-extract/private@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" + integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== + +"@vanilla-extract/recipes@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.4.0.tgz#7bb2edb0757b6f40c244d72569da7f74d6afa427" + integrity sha512-gFgB7BofUYbtbxINHK6DhMv1JDFDXp/YI/Xm+cqKar+1I/2dfxPepeDxSexL6YB4ftfeaDw8Kn5zydMvHcGOEQ== + +"@walletconnect/core@2.10.4": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.4.tgz#da9396b56f63806c165389cbf98d2373d36854df" + integrity sha512-MGdw5a4dIlQFPxVHEw2neIpHPAw3gtrsJYyUqm6rI+1c1SfmZyOPCaYTr6zPU2cnoWQUjv2ePMLeO/JKy3Yh5g== + dependencies: + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-provider" "1.0.13" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/jsonrpc-ws-connection" "1.0.13" + "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/relay-auth" "^1.0.4" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/utils" "2.10.4" + events "^3.3.0" + lodash.isequal "4.5.0" + uint8arrays "^3.1.0" + +"@walletconnect/environment@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" + integrity sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg== + dependencies: + tslib "1.14.1" + +"@walletconnect/events@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" + integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== + dependencies: + keyvaluestorage-interface "^1.0.0" + tslib "1.14.1" + +"@walletconnect/heartbeat@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" + integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" + +"@walletconnect/jsonrpc-provider@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" + integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.8" + "@walletconnect/safe-json" "^1.0.2" + tslib "1.14.1" + +"@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" + integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== + dependencies: + keyvaluestorage-interface "^1.0.0" + tslib "1.14.1" + +"@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" + integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== + dependencies: + "@walletconnect/environment" "^1.0.1" + "@walletconnect/jsonrpc-types" "^1.0.3" + tslib "1.14.1" + +"@walletconnect/jsonrpc-ws-connection@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.13.tgz#23b0cdd899801bfbb44a6556936ec2b93ef2adf4" + integrity sha512-mfOM7uFH4lGtQxG+XklYuFBj6dwVvseTt5/ahOkkmpcAEgz2umuzu7fTR+h5EmjQBdrmYyEBOWADbeaFNxdySg== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.2" + events "^3.3.0" + tslib "1.14.1" + ws "^7.5.1" + +"@walletconnect/keyvaluestorage@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz#92f5ca0f54c1a88a093778842ce0c874d86369c8" + integrity sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ== + dependencies: + safe-json-utils "^1.1.1" + tslib "1.14.1" + +"@walletconnect/logger@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.0.1.tgz#7f489b96e9a1ff6bf3e58f0fbd6d69718bf844a8" + integrity sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ== + dependencies: + pino "7.11.0" + tslib "1.14.1" + +"@walletconnect/relay-api@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" + integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== + dependencies: + "@walletconnect/jsonrpc-types" "^1.0.2" + tslib "1.14.1" + +"@walletconnect/relay-auth@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" + integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== + dependencies: + "@stablelib/ed25519" "^1.0.2" + "@stablelib/random" "^1.0.1" + "@walletconnect/safe-json" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" + uint8arrays "^3.0.0" + +"@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" + integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== + dependencies: + tslib "1.14.1" + +"@walletconnect/sign-client@^2.9.0": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.4.tgz#4e3b14ebe900472874f4cae5f53c74a6077c85da" + integrity sha512-C5VHkK59/DQNrJS91UXLn5OSr0drXHkKjajhl2a9hb3h6kxuSdlWbyC0yRPKT1sD0fQho8+EWZHBiV063yBePw== + dependencies: + "@walletconnect/core" "2.10.4" + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/utils" "2.10.4" + events "^3.3.0" + +"@walletconnect/time@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" + integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== + dependencies: + tslib "1.14.1" + +"@walletconnect/types@2.10.4", "@walletconnect/types@^2.9.0": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.4.tgz#23f6e4bd785671812dc6ea96848a6bd7ea78f038" + integrity sha512-eQpOElyiwJp3tepuOS3TS9dXTl9jVVlrC3iVA8bytnbLagkAUxmiv/s7PyDFx+ndXwQVh8PFBkWg1oxGwgCSBA== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + +"@walletconnect/types@2.7.2": + version "2.7.2" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.7.2.tgz#508d1755110864dee294f955e09b7da3f8ee0064" + integrity sha512-1O2UefakZpT0ErRfEAXY7Ls3qdUrKDky/DsK088xR6klyfkQOx+aSVH0fJYLhmnqPTuvp3lrqNbsDc0s6/6nvg== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "^1.0.2" + "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + +"@walletconnect/utils@2.10.4", "@walletconnect/utils@^2.9.0": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.4.tgz#5f17938e7ea481541ec2dbae0df5cd494c72523f" + integrity sha512-XbrKgnQ0hC9DC9wjFb468MEYMoJxnCVmOj2gi01DA4FSr8fJi7wwNRUnlnZzLWrUWrHuaPReYe4PgBAgIv363g== + dependencies: + "@stablelib/chacha20poly1305" "1.0.1" + "@stablelib/hkdf" "1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/sha256" "1.0.1" + "@stablelib/x25519" "^1.0.3" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/window-getters" "^1.0.1" + "@walletconnect/window-metadata" "^1.0.1" + detect-browser "5.3.0" + query-string "7.1.3" + uint8arrays "^3.1.0" + +"@walletconnect/window-getters@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" + integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== + dependencies: + tslib "1.14.1" + +"@walletconnect/window-metadata@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" + integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== + dependencies: + "@walletconnect/window-getters" "^1.0.1" + tslib "1.14.1" + "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" @@ -5602,9 +6500,9 @@ acorn-walk@^7.1.1, acorn-walk@^7.2.0: integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== acorn-walk@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.2.0.tgz#741210f2e2426454508853a2f44d0ab83b7f69c1" - integrity sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA== + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== acorn@^6.4.1: version "6.4.2" @@ -5617,9 +6515,9 @@ acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.0.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" - integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== add-stream@^1.0.0: version "1.0.0" @@ -5653,6 +6551,11 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +ahocorasick@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ahocorasick/-/ahocorasick-1.0.2.tgz#9eee93aef9d02bfb476d9b648d9b7a40ef2fd500" + integrity sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA== + airbnb-js-shims@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" @@ -5720,6 +6623,11 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: require-from-string "^2.0.2" uri-js "^4.2.2" +animejs@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.1.tgz#de9fe2e792f44a777a7fdf6ae160e26604b0cdda" + integrity sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A== + ansi-align@^3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" @@ -5926,7 +6834,7 @@ array-ify@^1.0.0: resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== -array-includes@^3.0.3, array-includes@^3.1.6: +array-includes@^3.0.3, array-includes@^3.1.6, array-includes@^3.1.7: version "3.1.7" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== @@ -5959,7 +6867,7 @@ array-unique@^0.3.2: resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== -array.prototype.findlastindex@^1.2.2: +array.prototype.findlastindex@^1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== @@ -5970,7 +6878,7 @@ array.prototype.findlastindex@^1.2.2: es-shim-unscopables "^1.0.0" get-intrinsic "^1.2.1" -array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1: +array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== @@ -5980,7 +6888,7 @@ array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.1: +array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== @@ -6123,6 +7031,11 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + author-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" @@ -6258,13 +7171,13 @@ babel-plugin-named-exports-order@^0.0.2: resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== -babel-plugin-polyfill-corejs2@^0.4.5: - version "0.4.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.5.tgz#8097b4cb4af5b64a1d11332b6fb72ef5e64a054c" - integrity sha512-19hwUH5FKl49JEsvyTcoHakh6BE0wgXLLptIyKZ3PijHc/Ci521wygORCUCCred+E/twuqRyAkE02BAWPmsHOg== +babel-plugin-polyfill-corejs2@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" + integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== dependencies: "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.2" + "@babel/helper-define-polyfill-provider" "^0.4.3" semver "^6.3.1" babel-plugin-polyfill-corejs3@^0.1.0: @@ -6275,20 +7188,20 @@ babel-plugin-polyfill-corejs3@^0.1.0: "@babel/helper-define-polyfill-provider" "^0.1.5" core-js-compat "^3.8.1" -babel-plugin-polyfill-corejs3@^0.8.3: - version "0.8.4" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.4.tgz#1fac2b1dcef6274e72b3c72977ed8325cb330591" - integrity sha512-9l//BZZsPR+5XjyJMPtZSK4jv0BsTO1zDac2GC6ygx9WLGlcsnRd1Co0B2zT5fF5Ic6BZy+9m3HNZ3QcOeDKfg== +babel-plugin-polyfill-corejs3@^0.8.5: + version "0.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" + integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" - core-js-compat "^3.32.2" + "@babel/helper-define-polyfill-provider" "^0.4.3" + core-js-compat "^3.33.1" -babel-plugin-polyfill-regenerator@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.2.tgz#80d0f3e1098c080c8b5a65f41e9427af692dc326" - integrity sha512-tAlOptU0Xj34V1Y2PNTL4Y0FOJMDB6bZmoW39FeCQIhigGLkqu3Fj6uiXpxIf6Ij274ENdYx64y6Au+ZKlb1IA== +babel-plugin-polyfill-regenerator@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" + integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.2" + "@babel/helper-define-polyfill-provider" "^0.4.3" babel-plugin-react-docgen@^4.2.1: version "4.2.1" @@ -6401,7 +7314,7 @@ better-opn@^2.1.1: dependencies: open "^7.0.3" -big-integer@^1.6.7: +big-integer@^1.6.48, big-integer@^1.6.7: version "1.6.51" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== @@ -6416,6 +7329,11 @@ big.js@^6.2.1: resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== +bignumber.js@^9.1.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -6426,14 +7344,27 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -bindings@^1.5.0: +bindings@^1.3.0, bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== dependencies: file-uri-to-path "1.0.0" -bip39@^3.0.2: +bip32@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" + integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + +bip39@^3.0.2, bip39@^3.0.3: version "3.1.0" resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== @@ -6497,6 +7428,11 @@ boolbase@^1.0.0: resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== +bowser@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + boxen@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" @@ -6637,7 +7573,7 @@ browserify-zlib@^0.2.0: dependencies: pako "~1.0.5" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.10, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: version "4.22.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== @@ -6654,13 +7590,22 @@ bs-logger@0.x: dependencies: fast-json-stable-stringify "2.x" -bs58@^4.0.1: +bs58@^4.0.0, bs58@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== dependencies: base-x "^3.0.2" +bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + bser@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" @@ -6695,6 +7640,14 @@ buffer@^5.5.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -6795,6 +7748,30 @@ cacache@^15.0.5: tar "^6.0.2" unique-filename "^1.1.1" +cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + cacache@^17.0.0: version "17.1.4" resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" @@ -6828,13 +7805,14 @@ cache-base@^1.0.1: union-value "^1.0.0" unset-value "^1.0.0" -call-bind@^1.0.0, call-bind@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.2.tgz#b1d4e89e688119c3c9a903ad30abb2f6a919be3c" - integrity sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA== +call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== dependencies: - function-bind "^1.1.1" - get-intrinsic "^1.0.2" + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" call-me-maybe@^1.0.1: version "1.0.2" @@ -6902,9 +7880,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001547" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001547.tgz#d4f92efc488aab3c7f92c738d3977c2a3180472b" - integrity sha512-W7CrtIModMAxobGhz8iXmDfuJiiKg1WADMO/9x7/CLNin5cpSbuBjooyoIUVB5eyCc36QuTVlkVa1iB2S5+/eA== + version "1.0.30001559" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001559.tgz#95a982440d3d314c471db68d02664fb7536c5a30" + integrity sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA== capture-exit@^2.0.0: version "2.0.0" @@ -6928,6 +7906,14 @@ ccount@^2.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== +chain-registry@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.20.0.tgz#1442a1d715a7ebf57781aeb185e3cbaa7b08196c" + integrity sha512-kBeQVdopECXasauhaA+HiJNSB0UpzNmxtv5AvIpJBAZc3nuM2wzPxaHAiPz1OG5ifYwMraOkvPNxwOnXd1nZzw== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.17.0" + chalk@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" @@ -7489,10 +8475,10 @@ content-type@~1.0.4: resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== -conventional-changelog-angular@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-6.0.0.tgz#a9a9494c28b7165889144fd5b91573c4aa9ca541" - integrity sha512-6qLgrBF4gueoC7AFVHu51nHL9pF9FRjXrH+ceVf7WmAfH3gs+gEYOkvxhjMPjZu57I4AGUGoNTY8V7Hrgf1uqg== +conventional-changelog-angular@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" + integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== dependencies: compare-func "^2.0.0" @@ -7567,6 +8553,11 @@ convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== +convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -7594,29 +8585,29 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -core-js-compat@^3.31.0, core-js-compat@^3.8.1: - version "3.32.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.32.2.tgz#8047d1a8b3ac4e639f0d4f66d4431aa3b16e004c" - integrity sha512-+GjlguTDINOijtVRUxrQOv3kfu9rl+qPNdX2LTbJ/ZyVTuxK+ksVSAGX1nHstu4hrv1En/uPTtWgq2gI5wt4AQ== +copy-to-clipboard@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== dependencies: - browserslist "^4.21.10" + toggle-selection "^1.0.6" -core-js-compat@^3.32.2: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.0.tgz#24aa230b228406450b2277b7c8bfebae932df966" - integrity sha512-0w4LcLXsVEuNkIqwjjf9rjCoPhK8uqA4tMRh4Ge26vfLtUutshn+aRJU21I9LCJlh2QQHfisNToLjw1XEJLTWw== +core-js-compat@^3.31.0, core-js-compat@^3.33.1, core-js-compat@^3.8.1: + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" + integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw== dependencies: browserslist "^4.22.1" core-js-pure@^3.23.3: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.0.tgz#938a28754b4d82017a7a8cbd2727b1abecc63591" - integrity sha512-FKSIDtJnds/YFIEaZ4HszRX7hkxGpNKM7FC9aJ9WLJbSd3lD4vOltFuVIBLR8asSx9frkTSqL0dw90SKQxgKrg== + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" + integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.33.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.0.tgz#70366dbf737134761edb017990cf5ce6c6369c40" - integrity sha512-HoZr92+ZjFEKar5HS6MC776gYslNOKHt75mEBKWKnPeFDpZ6nH5OeF3S6HFT1mUAUZKrzkez05VboaX8myjSuw== + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" + integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== core-util-is@~1.0.0: version "1.0.3" @@ -7769,6 +8760,11 @@ crypto-browserify@^3.11.0: randombytes "^2.0.0" randomfill "^1.0.3" +crypto-js@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + css-declaration-sorter@^6.3.1: version "6.4.1" resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" @@ -7854,11 +8850,6 @@ css-tree@^1.1.2, css-tree@^1.1.3: mdn-data "2.0.14" source-map "^0.6.1" -css-unit-converter@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21" - integrity sha512-IiJwMC8rdZE0+xiEZHeru6YoONC4rfPMqGm2W85jMIbkFvv5nFTwJVFHam2eFrN6txmoUYFAFXiv8ICVeTO0MA== - css-vendor@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" @@ -7867,7 +8858,7 @@ css-vendor@^2.0.8: "@babel/runtime" "^7.8.3" is-in-browser "^1.0.2" -css-what@^6.0.1: +css-what@^6.0.1, css-what@^6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== @@ -7955,7 +8946,7 @@ cssstyle@^2.3.0: dependencies: cssom "~0.3.6" -csstype@^3.0.2, csstype@^3.1.2: +csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== @@ -8206,7 +9197,7 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" -decode-uri-component@^0.2.0: +decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== @@ -8257,6 +9248,11 @@ deep-is@^0.1.3: resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== +deep-object-diff@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.9.tgz#6df7ef035ad6a0caa44479c536ed7b02570f4595" + integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== + deepmerge@^4.2.2: version "4.3.1" resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" @@ -8285,10 +9281,10 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" -define-data-property@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.0.tgz#0db13540704e1d8d479a0656cf781267531b9451" - integrity sha512-UzGwzcjyv3OtAvolTj1GoyNYzfFR+iqbGjcnBEENZVCpM4/Ng1yhGNvS3lR/xDS74Tb2wGG9WzNSNIOS9UVb2g== +define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== dependencies: get-intrinsic "^1.2.1" gopd "^1.0.1" @@ -8343,6 +9339,11 @@ del@^4.1.1: pify "^4.0.1" rimraf "^2.6.3" +delay@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.4.1.tgz#6e02d02946a1b6ab98b39262ced965acba2ac4d1" + integrity sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ== + delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -8393,6 +9394,11 @@ detab@2.0.4: dependencies: repeat-string "^1.5.4" +detect-browser@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" + integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== + detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" @@ -8660,6 +9666,16 @@ duplexify@^3.4.2, duplexify@^3.6.0: readable-stream "^2.0.0" stream-shift "^1.0.0" +duplexify@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" @@ -8678,11 +9694,11 @@ ejs@^3.1.7: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.548" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.548.tgz#e695d769e0e801fa6d438b63f6bc9b80372000d6" - integrity sha512-R77KD6mXv37DOyKLN/eW1rGS61N6yHOfapNSX9w+y9DdPG83l9Gkuv7qkCFZ4Ta4JPhrjgQfYbv4Y3TnM1Hi2Q== + version "1.4.571" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.571.tgz#8aa71539eb82db98740c3ec861256cc34e0356fd" + integrity sha512-Sc+VtKwKCDj3f/kLBjdyjMpNzoZsU6WuL/wFb6EH8USmHEcebxRXcRrVpOpayxd52tuey4RUDpUsw5OS5LhJqg== -elliptic@^6.5.3, elliptic@^6.5.4: +elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== @@ -8827,25 +9843,25 @@ error-stack-parser@^2.0.6: stackframe "^1.3.4" es-abstract@^1.22.1: - version "1.22.2" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.2.tgz#90f7282d91d0ad577f505e423e52d4c1d93c1b8a" - integrity sha512-YoxfFcDmhjOgWPWsV13+2RNjq1F6UQnfs+8TftwNqtzlmFzEXvlUwdrNrYeaizfjQzRMxkZ6ElWMOJIFKdVqwA== + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== dependencies: array-buffer-byte-length "^1.0.0" arraybuffer.prototype.slice "^1.0.2" available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.5" es-set-tostringtag "^2.0.1" es-to-primitive "^1.2.1" function.prototype.name "^1.1.6" - get-intrinsic "^1.2.1" + get-intrinsic "^1.2.2" get-symbol-description "^1.0.0" globalthis "^1.0.3" gopd "^1.0.1" - has "^1.0.3" has-property-descriptors "^1.0.0" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" internal-slot "^1.0.5" is-array-buffer "^3.0.2" is-callable "^1.2.7" @@ -8855,7 +9871,7 @@ es-abstract@^1.22.1: is-string "^1.0.7" is-typed-array "^1.1.12" is-weakref "^1.0.2" - object-inspect "^1.12.3" + object-inspect "^1.13.1" object-keys "^1.1.1" object.assign "^4.1.4" regexp.prototype.flags "^1.5.1" @@ -8869,7 +9885,7 @@ es-abstract@^1.22.1: typed-array-byte-offset "^1.0.0" typed-array-length "^1.0.4" unbox-primitive "^1.0.2" - which-typed-array "^1.1.11" + which-typed-array "^1.1.13" es-array-method-boxes-properly@^1.0.0: version "1.0.0" @@ -8917,20 +9933,20 @@ es-module-lexer@^1.2.1: integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== es-set-tostringtag@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz#338d502f6f674301d710b80c8592de8a15f09cd8" - integrity sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg== + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== dependencies: - get-intrinsic "^1.1.3" - has "^1.0.3" + get-intrinsic "^1.2.2" has-tostringtag "^1.0.0" + hasown "^2.0.0" es-shim-unscopables@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" - integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== dependencies: - has "^1.0.3" + hasown "^2.0.0" es-to-primitive@^1.2.1: version "1.2.1" @@ -9018,7 +10034,7 @@ eslint-config-prettier@^8.3.0, eslint-config-prettier@^8.5.0: resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== -eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.7: +eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.9: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== @@ -9043,25 +10059,25 @@ eslint-module-utils@^2.8.0: debug "^3.2.7" eslint-plugin-import@^2.25.4: - version "2.28.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.28.1.tgz#63b8b5b3c409bfc75ebaf8fb206b07ab435482c4" - integrity sha512-9I9hFlITvOV55alzoKBI+K9q74kv0iKMeY6av5+umsNwayt59fz692daGyjR+oStBQgx6nwR9rXldDev3Clw+A== + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== dependencies: - array-includes "^3.1.6" - array.prototype.findlastindex "^1.2.2" - array.prototype.flat "^1.3.1" - array.prototype.flatmap "^1.3.1" + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.7" + eslint-import-resolver-node "^0.3.9" eslint-module-utils "^2.8.0" - has "^1.0.3" - is-core-module "^2.13.0" + hasown "^2.0.0" + is-core-module "^2.13.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.fromentries "^2.0.6" - object.groupby "^1.0.0" - object.values "^1.1.6" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" semver "^6.3.1" tsconfig-paths "^3.14.2" @@ -9245,17 +10261,18 @@ eslint@^7.18.0: v8-compile-cache "^2.0.3" eslint@^8.10.0: - version "8.51.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.51.0.tgz#4a82dae60d209ac89a5cff1604fea978ba4950f3" - integrity sha512-2WuxRZBrlwnXi+/vFSJyjMqrNjtJqiasMzehF0shoLaW7DzS3/9Yvrmq5JiT66+pNjiX4UBnLDiKHcWAr/OInA== + version "8.52.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" + integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.51.0" - "@humanwhocodes/config-array" "^0.11.11" + "@eslint/js" "8.52.0" + "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" ajv "^6.12.4" chalk "^4.0.0" cross-spawn "^7.0.2" @@ -9413,7 +10430,7 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.0.0, events@^3.2.0: +events@3.3.0, events@^3.0.0, events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -9672,6 +10689,11 @@ fast-levenshtein@^2.0.6: resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-redact@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" + integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + fastest-levenshtein@^1.0.12: version "1.0.16" resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" @@ -9809,6 +10831,11 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" +filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + finalhandler@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" @@ -10076,7 +11103,7 @@ fs-extra@^9.0.0, fs-extra@^9.0.1: jsonfile "^6.0.1" universalify "^2.0.0" -fs-minipass@^2.0.0: +fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== @@ -10123,10 +11150,10 @@ fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== -function-bind@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" - integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== +function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== function.prototype.name@^1.1.0, function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: version "1.1.6" @@ -10187,15 +11214,15 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== -get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.1.tgz#d295644fed4505fc9cde952c37ee12b477a83d82" - integrity sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw== +get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== dependencies: - function-bind "^1.1.1" - has "^1.0.3" + function-bind "^1.1.2" has-proto "^1.0.1" has-symbols "^1.0.3" + hasown "^2.0.0" get-package-type@^0.1.0: version "0.1.0" @@ -10542,11 +11569,11 @@ has-glob@^1.0.0: is-glob "^3.0.0" has-property-descriptors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" - integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== dependencies: - get-intrinsic "^1.1.1" + get-intrinsic "^1.2.2" has-proto@^1.0.1: version "1.0.1" @@ -10623,6 +11650,13 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + hast-to-hyperscript@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" @@ -10868,7 +11902,7 @@ htmlparser2@^6.1.0: domutils "^2.5.2" entities "^2.0.0" -http-cache-semantics@^4.1.1: +http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -11005,7 +12039,7 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.13, ieee754@^1.1.4: +ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -11049,6 +12083,11 @@ immediate@~3.0.5: resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== +immer@^9.0.19: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" @@ -11150,12 +12189,12 @@ inquirer@^8.2.4: wrap-ansi "^6.0.1" internal-slot@^1.0.4, internal-slot@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.5.tgz#f2a2ee21f668f8627a4667f309dc0f4fb6674986" - integrity sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ== + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== dependencies: - get-intrinsic "^1.2.0" - has "^1.0.3" + get-intrinsic "^1.2.2" + hasown "^2.0.0" side-channel "^1.0.4" "internmap@1 - 2": @@ -11173,6 +12212,16 @@ interpret@^2.2.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== +intl-messageformat@^10.1.0: + version "10.5.4" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.4.tgz#7b212b083f1b354d7e282518e78057e025134af9" + integrity sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w== + dependencies: + "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.7.0" + tslib "^2.4.0" + ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" @@ -11193,19 +12242,12 @@ is-absolute-url@^3.0.0: resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== -is-accessor-descriptor@^0.1.6: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== +is-accessor-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" + integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== dependencies: - kind-of "^3.0.2" - -is-accessor-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" - integrity sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ== - dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" is-alphabetical@1.0.4, is-alphabetical@^1.0.0: version "1.0.4" @@ -11332,26 +12374,19 @@ is-ci@^2.0.0: dependencies: ci-info "^2.0.0" -is-core-module@^2.13.0, is-core-module@^2.5.0, is-core-module@^2.8.1, is-core-module@^2.9.0: - version "2.13.0" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.0.tgz#bb52aa6e2cbd49a30c2ba68c42bf3435ba6072db" - integrity sha512-Z7dk6Qo8pOCp3l4tsX2C5ZVas4V+UxwQodwZhLopL91TX8UyyHEXafPcyoeeWuLrwzHcr3igO78wNLwHJHsMCQ== +is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== dependencies: - has "^1.0.3" + hasown "^2.0.0" -is-data-descriptor@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== +is-data-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" + integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== dependencies: - kind-of "^3.0.2" - -is-data-descriptor@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" - integrity sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ== - dependencies: - kind-of "^6.0.0" + hasown "^2.0.0" is-date-object@^1.0.1, is-date-object@^1.0.5: version "1.0.5" @@ -11371,22 +12406,20 @@ is-decimal@^2.0.0: integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== is-descriptor@^0.1.0: - version "0.1.6" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" - integrity sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg== + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" + integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== dependencies: - is-accessor-descriptor "^0.1.6" - is-data-descriptor "^0.1.4" - kind-of "^5.0.0" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" - integrity sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg== + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" + integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== dependencies: - is-accessor-descriptor "^1.0.0" - is-data-descriptor "^1.0.0" - kind-of "^6.0.2" + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" is-docker@^2.0.0, is-docker@^2.1.1: version "2.2.1" @@ -12446,18 +13479,7 @@ jest@^27.1.0: import-local "^3.0.2" jest-cli "^27.5.1" -joi@^17.11.0: - version "17.11.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" - integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - -js-sha3@^0.8.0: +js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== @@ -12693,6 +13715,11 @@ keyv@^4.5.3: dependencies: json-buffer "3.0.1" +keyvaluestorage-interface@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" + integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" @@ -12707,12 +13734,7 @@ kind-of@^4.0.0: dependencies: is-buffer "^1.1.5" -kind-of@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" - integrity sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw== - -kind-of@^6.0.0, kind-of@^6.0.2, kind-of@^6.0.3: +kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== @@ -12764,12 +13786,12 @@ lazy-universal-dotenv@^3.0.1: dotenv-expand "^5.1.0" lerna@^7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.3.0.tgz#efecafbdce15694e2f6841256e073a3a2061053e" - integrity sha512-Dt8TH+J+c9+3MhTYcm5OxnNzXb87WG7GPNj3kidjYJjJY7KxIMDNU37qBTYRWA1h3wAeNKBplXVQYUPkGcYgkQ== + version "7.4.2" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" + integrity sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA== dependencies: - "@lerna/child-process" "7.3.0" - "@lerna/create" "7.3.0" + "@lerna/child-process" "7.4.2" + "@lerna/create" "7.4.2" "@npmcli/run-script" "6.0.2" "@nx/devkit" ">=16.5.1 < 17" "@octokit/plugin-enterprise-rest" "6.0.1" @@ -12779,7 +13801,7 @@ lerna@^7.3.0: clone-deep "4.0.1" cmd-shim "6.0.1" columnify "1.6.0" - conventional-changelog-angular "6.0.0" + conventional-changelog-angular "7.0.0" conventional-changelog-core "5.0.1" conventional-recommended-bump "7.0.1" cosmiconfig "^8.2.0" @@ -13024,6 +14046,11 @@ lodash.defaultsdeep@^4.6.1: resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== +lodash.isequal@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -13163,9 +14190,9 @@ magic-string@^0.27.0: "@jridgewell/sourcemap-codec" "^1.4.13" magic-string@^0.30.2: - version "0.30.4" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.4.tgz#c2c683265fc18dda49b56fc7318d33ca0332c98c" - integrity sha512-Q/TKtsC5BPm0kGqgBIF9oXAs/xEf2vRKiIB4wCRQTJOQIByZ1d+NnUOotvJOvNpi5RNIgVOMC3pOuaP1ZTDlVg== + version "0.30.5" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" + integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== dependencies: "@jridgewell/sourcemap-codec" "^1.4.15" @@ -13196,7 +14223,29 @@ make-error@1.x, make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.0.3, make-fetch-happen@^11.1.1: +make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + +make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== @@ -13446,6 +14495,13 @@ mdurl@^1.0.0: resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== +media-query-parser@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" + integrity sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w== + dependencies: + "@babel/runtime" "^7.12.5" + media-typer@0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" @@ -14004,6 +15060,17 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" +minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + minipass-fetch@^3.0.0: version "3.0.4" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" @@ -14044,7 +15111,7 @@ minipass-sized@^1.0.3: dependencies: minipass "^3.0.0" -minipass@^3.0.0, minipass@^3.1.1: +minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: version "3.3.6" resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== @@ -14115,6 +15182,11 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mobx@^6.1.7: + version "6.10.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.10.2.tgz#96e123deef140750360ca9a5b02a8b91fbffd4d9" + integrity sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ== + mocha@^10.0.0: version "10.2.0" resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" @@ -14199,6 +15271,11 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" +multiformats@^9.4.2: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== + multimatch@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -14220,7 +15297,7 @@ mute-stream@~1.0.0: resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== -nan@^2.12.1: +nan@^2.12.1, nan@^2.13.2: version "2.18.0" resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== @@ -14301,9 +15378,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-abi@^3.3.0: - version "3.48.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.48.0.tgz#122d132ae1ac097b0d711144560b17922de026ab" - integrity sha512-uWR/uwQyVV2iN5+Wkf1/oQxOR9YjU7gBclJLg2qK7GDvVohcnY6LaBXKV89N79EQFyN4/e43O32yQYE5QdFYTA== + version "3.51.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" + integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== dependencies: semver "^7.3.5" @@ -14359,15 +15436,15 @@ node-gyp-build@^4.3.0: integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== node-gyp@^9.0.0, node-gyp@^9.3.1: - version "9.4.0" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.0.tgz#2a7a91c7cba4eccfd95e949369f27c9ba704f369" - integrity sha512-dMXsYP6gc9rRbejLXmTbVRYjAHw7ppswsKyMxuxJxxOHzluIO1rGp9TOQgjFJ+2MCqcOcQTOPB/8Xwhr+7s4Eg== + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== dependencies: env-paths "^2.2.0" exponential-backoff "^3.1.1" glob "^7.1.4" graceful-fs "^4.2.6" - make-fetch-happen "^11.0.3" + make-fetch-happen "^10.0.3" nopt "^6.0.0" npmlog "^6.0.0" rimraf "^3.0.2" @@ -14732,10 +15809,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" -object-inspect@^1.12.3, object-inspect@^1.9.0: - version "1.12.3" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.3.tgz#ba62dffd67ee256c8c086dfae69e016cd1f198b9" - integrity sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g== +object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== object-is@^1.1.5: version "1.1.5" @@ -14776,7 +15853,7 @@ object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.6: define-properties "^1.2.0" es-abstract "^1.22.1" -"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.6: +"object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.6, object.fromentries@^2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== @@ -14796,7 +15873,7 @@ object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2 es-abstract "^1.22.1" safe-array-concat "^1.0.0" -object.groupby@^1.0.0: +object.groupby@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== @@ -14821,7 +15898,7 @@ object.pick@^1.3.0: dependencies: isobject "^3.0.1" -object.values@^1.1.0, object.values@^1.1.6: +object.values@^1.1.0, object.values@^1.1.6, object.values@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== @@ -14840,6 +15917,11 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" @@ -14925,6 +16007,11 @@ os-tmpdir@~1.0.2: resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== +outdent@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.8.0.tgz#2ebc3e77bf49912543f1008100ff8e7f44428eb0" + integrity sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A== + p-all@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" @@ -15406,6 +16493,36 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" + +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino@7.11.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" + integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.15.1" + pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: version "4.0.6" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" @@ -15735,11 +16852,6 @@ postcss-unique-selectors@^5.1.1: dependencies: postcss-selector-parser "^6.0.5" -postcss-value-parser@^3.3.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz#9ff822547e2893213cf1c30efa51ac5fd1ba8281" - integrity sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ== - postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" @@ -15754,9 +16866,9 @@ postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0 source-map "^0.6.1" postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.21: - version "8.4.29" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.29.tgz#33bc121cf3b3688d4ddef50be869b2a54185a1dd" - integrity sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw== + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== dependencies: nanoid "^3.3.6" picocolors "^1.0.0" @@ -15866,6 +16978,11 @@ process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + process@^0.11.10: version "0.11.10" resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" @@ -15937,9 +17054,9 @@ prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, react-is "^16.13.1" property-expr@^2.0.4, property-expr@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.5.tgz#278bdb15308ae16af3e3b9640024524f4dc02cb4" - integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== property-information@^5.0.0, property-information@^5.3.0: version "5.6.0" @@ -15953,7 +17070,7 @@ property-information@^6.0.0: resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.3.0.tgz#ba4a06ec6b4e1e90577df9931286953cdf4282c3" integrity sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg== -protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: +protobufjs@^6.11.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: version "6.11.4" resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== @@ -16067,9 +17184,9 @@ punycode@^1.2.4, punycode@^1.4.1: integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1: - version "2.3.0" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.0.tgz#f67fa67c94da8f4d0cfff981aee4118064199b8f" - integrity sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA== + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== qr.js@0.0.0: version "0.0.0" @@ -16099,6 +17216,16 @@ qs@^6.10.0, qs@^6.11.2: dependencies: side-channel "^1.0.4" +query-string@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== + dependencies: + decode-uri-component "^0.2.2" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -16119,11 +17246,21 @@ queue-tick@^1.0.1: resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +rainbow-sprinkles@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.0.tgz#6ee06c6decc767b89bf01fc5fe87ecf859fd4c2f" + integrity sha512-ok3NrylQ0szvJtuBYaB/w09L9zOvvqcSQrvycT2A5XJxQNvwvkeADvTqQWGOQ3b6MkO8UmYccBPt8g8vVvxM9A== + rambda@^7.4.0: version "7.5.0" resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.5.0.tgz#1865044c59bc0b16f63026c6e5a97e4b1bbe98fe" @@ -16337,19 +17474,19 @@ react-resize-detector@^8.0.4: lodash "^4.17.21" react-router-dom@6, react-router-dom@^6.7.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.16.0.tgz#86f24658da35eb66727e75ecbb1a029e33ee39d9" - integrity sha512-aTfBLv3mk/gaKLxgRDUPbPw+s4Y/O+ma3rEN1u8EgEpLpPe6gNjIsWt9rxushMHHMb7mSwxRGdGlGdvmFsyPIg== + version "6.18.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.18.0.tgz#0a50c167209d6e7bd2ed9de200a6579ea4fb1dca" + integrity sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw== dependencies: - "@remix-run/router" "1.9.0" - react-router "6.16.0" + "@remix-run/router" "1.11.0" + react-router "6.18.0" -react-router@6.16.0: - version "6.16.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.16.0.tgz#abbf3d5bdc9c108c9b822a18be10ee004096fb81" - integrity sha512-VT4Mmc4jj5YyjpOi5jOf0I+TYzGpvzERy4ckNSvSh2RArv8LLoCxlsZ2D+tc7zgjxcY34oTz2hZaeX5RVprKqA== +react-router@6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.18.0.tgz#32e2bedc318e095a48763b5ed7758e54034cd36a" + integrity sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg== dependencies: - "@remix-run/router" "1.9.0" + "@remix-run/router" "1.11.0" react-simple-maps@^2.3.0: version "2.3.0" @@ -16361,18 +17498,18 @@ react-simple-maps@^2.3.0: d3-zoom "^2.0.0" topojson-client "^3.1.0" -react-smooth@^2.0.2: - version "2.0.4" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.4.tgz#95187126265970a1490e2aea5690365203ee555f" - integrity sha512-OkFsrrMBTvQUwEJthE1KXSOj79z57yvEWeFefeXPib+RmQEI9B1Ub1PgzlzzUyBOvl/TjXt5nF2hmD4NsgAh8A== +react-smooth@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" + integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== dependencies: fast-equals "^5.0.0" react-transition-group "2.9.0" react-tooltip@*: - version "5.21.5" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.21.5.tgz#3e1bc02a0e674369dea81bb201d6106724dd60cf" - integrity sha512-ey70qf6pBGi4U6xpyNlZAHobAhlo2dfxmImR2Bzd/DbLTsAYWz3TEaK+RMFuUZMq6hSPRbUHQSkP2rHBq4uFVg== + version "5.21.6" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.21.6.tgz#2287b12010c6b931ffe2b432d9961691a8cc74b3" + integrity sha512-WbND5ee8Kr5HaSuDDiAmSyRp5jH77PSk8M0CUzmVfD+1WST8XOm1StJndK/wOQIP5GPvDVPy96ylLxY/V+VpqA== dependencies: "@floating-ui/dom" "^1.0.0" classnames "^2.3.0" @@ -16538,6 +17675,11 @@ readonly-date@^1.0.0: resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + recharts-scale@^0.4.4: version "0.4.5" resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" @@ -16546,18 +17688,18 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.1.13: - version "2.8.0" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.8.0.tgz#90c95136e2cb6930224c94a51adce607701284fc" - integrity sha512-nciXqQDh3aW8abhwUlA4EBOBusRHLNiKHfpRZiG/yjups1x+auHb2zWPuEcTn/IMiN47vVMMuF8Sr+vcQJtsmw== + version "2.9.1" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.1.tgz#8c692877b0ef158c4d72fcb5e22e3bd4845fe32f" + integrity sha512-GqHrQVMgDIktzNIIlhtvZnjYurr6Wy+KMSDxO1MEp3CrZZbvisUmnBojSWAZ7j8cjwhD4uRRFga2s5wcd/w9sQ== dependencies: classnames "^2.2.5" eventemitter3 "^4.0.1" lodash "^4.17.19" react-is "^16.10.2" react-resize-detector "^8.0.4" - react-smooth "^2.0.2" + react-smooth "^2.0.4" recharts-scale "^0.4.4" - reduce-css-calc "^2.1.8" + tiny-invariant "^1.3.1" victory-vendor "^36.6.8" rechoir@^0.7.0: @@ -16583,14 +17725,6 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" -reduce-css-calc@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/reduce-css-calc/-/reduce-css-calc-2.1.8.tgz#7ef8761a28d614980dc0c982f772c93f7a99de03" - integrity sha512-8liAVezDmUcH+tdzoEGrhfbGcP7nOV4NkGE3a74+qqvE7nt9i4sKLGBuZNOnpI4WiGksiNPklZxva80061QiPg== - dependencies: - css-unit-converter "^1.1.1" - postcss-value-parser "^3.3.0" - reflect.getprototypeof@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" @@ -16875,20 +18009,20 @@ resolve.exports@^1.1.0: integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.3.2, resolve@^1.9.0: - version "1.22.6" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.6.tgz#dd209739eca3aef739c626fea1b4f3c506195362" - integrity sha512-njhxM7mV12JfufShqGy3Rz8j11RPdLy4xi15UurGJeoHLfJpVXKdh3ueuOqbYUcDZnffr6X739JBo5LzyahEsw== + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== dependencies: is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" resolve@^2.0.0-next.4: - version "2.0.0-next.4" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.4.tgz#3d37a113d6429f496ec4752d2a2e58efb1fd4660" - integrity sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ== + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== dependencies: - is-core-module "^2.9.0" + is-core-module "^2.13.0" path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" @@ -16987,9 +18121,9 @@ rollup-pluginutils@^2.8.1: estree-walker "^0.6.1" rollup@^3.17.2, rollup@^3.2.1: - version "3.29.1" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.1.tgz#ba53a179d46ac3cd79e162dca6ab70d93cd26f78" - integrity sha512-c+ebvQz0VIH4KhhCpDsI+Bik0eT8ZFEVZEYw0cGMVqIP8zc+gnwl7iXCamTw7vzv2MeuZFZfdx5JJIq+ehzDlg== + version "3.29.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" + integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== optionalDependencies: fsevents "~2.3.2" @@ -17056,6 +18190,11 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== +safe-json-utils@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" + integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== + safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -17072,6 +18211,11 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" +safe-stable-stringify@^2.1.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -17163,10 +18307,11 @@ select-hose@^2.0.0: integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== selfsigned@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.1.1.tgz#18a7613d714c0cd3385c48af0075abf3f266af61" - integrity sha512-GSL3aowiF7wa/WtSFwnUrludWFoNhftq8bUkH9pkzjpN2XSPOAYEgg6e0sS9s0rZwgJzJiQRPU18A6clnoW5wQ== + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== dependencies: + "@types/node-forge" "^1.3.0" node-forge "^1" "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: @@ -17181,7 +18326,7 @@ semver@7.5.3: dependencies: lru-cache "^6.0.0" -semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@^7.5.4: +semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4: version "7.5.4" resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== @@ -17284,6 +18429,16 @@ set-blocking@^2.0.0: resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== +set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + set-function-name@^2.0.0, set-function-name@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" @@ -17547,6 +18702,13 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" +sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" + sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -17598,7 +18760,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.0, source-map@^0.7.3: +source-map@^0.7.0, source-map@^0.7.3, source-map@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== @@ -17667,6 +18829,11 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" +split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -17681,6 +18848,11 @@ split2@^3.2.2: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + split@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" @@ -17714,7 +18886,7 @@ ssri@^8.0.1: dependencies: minipass "^3.1.1" -ssri@^9.0.1: +ssri@^9.0.0, ssri@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== @@ -17806,13 +18978,18 @@ stream-shift@^1.0.0: integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== streamx@^2.15.0: - version "2.15.1" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.1.tgz#396ad286d8bc3eeef8f5cea3f029e81237c024c6" - integrity sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA== + version "2.15.2" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.2.tgz#680eacebdc9c43ede7362c2e6695b34dd413c741" + integrity sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg== dependencies: fast-fifo "^1.1.0" queue-tick "^1.0.1" +strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -18043,9 +19220,9 @@ style-to-object@0.3.0, style-to-object@^0.3.0: inline-style-parser "0.1.1" style-to-object@^0.4.0, style-to-object@^0.4.1: - version "0.4.2" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.2.tgz#a8247057111dea8bd3b8a1a66d2d0c9cf9218a54" - integrity sha512-1JGpfPB3lo42ZX8cuPrheZbfQ6kqPPnPHlKMyeRYtfKD+0jG+QsXgXN57O/dvJlzlB2elI6dGmrPnl5VPQFPaA== + version "0.4.4" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" + integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg== dependencies: inline-style-parser "0.1.1" @@ -18139,6 +19316,11 @@ synchronous-promise@^2.0.15: resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== +tabbable@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== + table@^6.0.9: version "6.8.1" resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" @@ -18308,9 +19490,9 @@ terser@^4.1.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.10.0, terser@^5.16.8, terser@^5.3.4: - version "5.19.4" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.19.4.tgz#941426fa482bf9b40a0308ab2b3cd0cf7c775ebd" - integrity sha512-6p1DjHeuluwxDXcuT9VR8p64klWJKo1ILiy19s6C9+0Bh2+NWTX6nD9EPppiER4ICkHDVB1RkVpin/YW2nQn/g== + version "5.24.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" + integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -18347,6 +19529,13 @@ thread-loader@^3.0.4: neo-async "^2.6.2" schema-utils "^3.0.0" +thread-stream@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" + integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== + dependencies: + real-require "^0.1.0" + throat@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" @@ -18394,6 +19583,17 @@ tiny-invariant@^1.3.1: resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== +tiny-secp256k1@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + tiny-warning@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" @@ -18460,6 +19660,11 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" +toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + toidentifier@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" @@ -18561,14 +19766,15 @@ ts-jest@^27.0.5: yargs-parser "20.x" ts-loader@^9.4.2: - version "9.4.4" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.4.tgz#6ceaf4d58dcc6979f84125335904920884b7cee4" - integrity sha512-MLukxDHBl8OJ5Dk3y69IsKVFRA/6MwzEqBgh+OXMPB/OD01KQuWPFd1WAQP8a5PeSCAxfnkhiuWqfmFJzJQt9w== + version "9.5.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" + integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" micromatch "^4.0.0" semver "^7.3.4" + source-map "^0.7.4" ts-mocha@^10.0.0: version "10.0.0" @@ -18645,17 +19851,17 @@ tsconfig-paths@^4.1.2: minimist "^1.2.6" strip-bom "^3.0.0" +tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + tslib@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0, "tslib@^2.4.1 || ^1.9.3": +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: version "2.6.2" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== @@ -18822,6 +20028,11 @@ typedoc@^0.22.13: minimatch "^5.1.0" shiki "^0.10.1" +typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + "typescript@>=3 < 6": version "5.2.2" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" @@ -18837,6 +20048,13 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== +uint8arrays@^3.0.0, uint8arrays@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== + dependencies: + multiformats "^9.4.2" + unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -18852,10 +20070,10 @@ undefsafe@^2.0.5: resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== -undici-types@~5.25.1: - version "5.25.3" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.25.3.tgz#e044115914c85f0bcbb229f346ab739f064998c3" - integrity sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA== +undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== unfetch@^4.2.0: version "4.2.0" @@ -18935,6 +20153,13 @@ unique-filename@^1.1.1: dependencies: unique-slug "^2.0.0" +unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + unique-filename@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" @@ -18949,6 +20174,13 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + unique-slug@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" @@ -19169,6 +20401,11 @@ use-clipboard-copy@^0.2.0: dependencies: clipboard-copy "^3.0.0" +use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + use@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" @@ -19206,6 +20443,11 @@ utila@~0.4: resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== +utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" @@ -19231,7 +20473,7 @@ uuid@^8.3.2: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== -uuid@^9.0.0: +uuid@^9.0.0, uuid@^9.0.1: version "9.0.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== @@ -19271,13 +20513,13 @@ v8-to-istanbul@^8.1.0: source-map "^0.7.3" v8-to-istanbul@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" - integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + version "9.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" + integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" + convert-source-map "^2.0.0" validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: version "3.0.4" @@ -19593,11 +20835,12 @@ webpack-log@^2.0.0: uuid "^3.3.2" webpack-merge@^5.7.3, webpack-merge@^5.8.0: - version "5.9.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.9.0.tgz#dc160a1c4cf512ceca515cc231669e9ddb133826" - integrity sha512-6NbRQw4+Sy50vYNTw7EyOn41OZItPiXB8GNv3INSoe3PSFaHJEz3SHTrYVaRm2LilNGnFUzh0FAwqPEmU/CwDg== + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== dependencies: clone-deep "^4.0.1" + flat "^5.0.2" wildcard "^2.0.0" webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: @@ -19655,9 +20898,9 @@ webpack@4: webpack-sources "^1.4.1" "webpack@>=4.43.0 <6.0.0", webpack@^5.75.0, webpack@^5.9.0: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== + version "5.89.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" + integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== dependencies: "@types/eslint-scope" "^3.7.3" "@types/estree" "^1.0.0" @@ -19766,13 +21009,13 @@ which-collection@^1.0.1: is-weakmap "^2.0.1" is-weakset "^2.0.1" -which-typed-array@^1.1.11, which-typed-array@^1.1.9: - version "1.1.11" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.11.tgz#99d691f23c72aab6768680805a271b69761ed61a" - integrity sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew== +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== dependencies: available-typed-arrays "^1.0.5" - call-bind "^1.0.2" + call-bind "^1.0.4" for-each "^0.3.3" gopd "^1.0.1" has-tostringtag "^1.0.0" @@ -19812,6 +21055,13 @@ widest-line@^3.1.0: dependencies: string-width "^4.0.0" +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== + dependencies: + bs58check "<3.0.0" + wildcard@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" @@ -19921,7 +21171,7 @@ write-pkg@4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@^7, ws@^7.4.6: +ws@^7, ws@^7.4.6, ws@^7.5.1: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== @@ -20017,9 +21267,9 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.0.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.2.tgz#f522db4313c671a0ca963a75670f1c12ea909144" - integrity sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg== + version "2.3.3" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.3.tgz#01f6d18ef036446340007db8e016810e5d64aad9" + integrity sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ== yargs-parser@20.2.4: version "20.2.4" @@ -20110,6 +21360,13 @@ yup@^1.2.0: toposort "^2.0.2" type-fest "^2.19.0" +zustand@^4.3.8: + version "4.4.5" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.5.tgz#0d5571affb30906b0c07c16557f2779ede9f4d8c" + integrity sha512-jgIrBBLKncQW74PA2Lclct3gwD4aPughwGE4FqlXrv3rDqQox7JCn8rwUiFK6ygJcbBAvfTf8fF+ICg7HLD2FQ== + dependencies: + use-sync-external-store "1.2.0" + zwitch@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" From 40dc0d2cc78a0d875809a236cd352ff3a33ba03a Mon Sep 17 00:00:00 2001 From: Yana Date: Sun, 5 Nov 2023 09:35:25 +0000 Subject: [PATCH 120/394] fix ui bug in ts.config --- explorer/package.json | 4 +- .../src/components/ConnectKeplrWallet.tsx | 1 + explorer/tsconfig.json | 3 +- yarn.lock | 227 +++++++++--------- 4 files changed, 116 insertions(+), 119 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index 7a3ac0e785..5b363a0f55 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -19,8 +19,8 @@ }, "dependencies": { "@cosmjs/math": "^0.26.2", - "@cosmos-kit/keplr": "^2.3.11", - "@cosmos-kit/react": "^2.8.2", + "@cosmos-kit/keplr": "^2.4.7", + "@cosmos-kit/react": "^2.9.6", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@mui/icons-material": "^5.0.0", diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx index 9541b6fcf9..7077577ebe 100644 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -1,3 +1,4 @@ +import React from 'react'; import { useChain } from '@cosmos-kit/react'; import { Box, Button, Card } from '@mui/material'; import Big from 'big.js'; diff --git a/explorer/tsconfig.json b/explorer/tsconfig.json index be2f94515f..95ed0edbaf 100644 --- a/explorer/tsconfig.json +++ b/explorer/tsconfig.json @@ -2,7 +2,8 @@ "extends": "../ts-packages/tsconfig.json", "compilerOptions": { "jsx": "react-jsx", - "outDir": "./dist" + "outDir": "./dist", + "module": "CommonJS", }, "include": [ "./src/**/*.ts", diff --git a/yarn.lock b/yarn.lock index 7ad502c716..577735f153 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1190,7 +1190,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.20.7", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== @@ -1593,10 +1593,10 @@ events "3.3.0" uuid "^9.0.1" -"@cosmos-kit/keplr-extension@^2.5.6": - version "2.5.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.6.tgz#f918e9f1cd4d29ca89c8764cf6314bfb41d22329" - integrity sha512-RAnoYJVeufGb9wxknMimqhkntxZKofSeHW6ChjpzGLE2WScHTmWBdgcdxtGxdNe2Yua3wtjAzyiGSuUq64b1OA== +"@cosmos-kit/keplr-extension@^2.5.7": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.7.tgz#e8fef3c4f43d3402aa3d0320936cdaf03fb8a811" + integrity sha512-Bwh1nJz/1l9mGtcjh0qUcZtMRjkOoTNUkMRbUoV8PqQtwcVvgB5DefmiXAcFxH+sB7ObPjjSNp2bN0o7gpHE0g== dependencies: "@chain-registry/keplr" "1.25.0" "@cosmos-kit/core" "^2.7.4" @@ -1610,12 +1610,12 @@ "@cosmos-kit/core" "^2.7.4" "@cosmos-kit/walletconnect" "^2.4.5" -"@cosmos-kit/keplr@^2.3.11": - version "2.4.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.6.tgz#be323aeb4ad9165b397dd57847b6bb1bf0dd2161" - integrity sha512-bUjgEePB0u2jbWJ7oZfr5J9O/00pRbyMeZQHN1TWh3KIcxBLMZcQdeglWMwep8V/ETond0Mr5hKR8S/ZsLgCuA== +"@cosmos-kit/keplr@^2.4.7": + version "2.4.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.7.tgz#512ca3ca1ecf87b7219186be81127d0a021319f1" + integrity sha512-56HTflompCUZ3yg86cqgRl91Crpy1JInLJ1UbPgNbiHm7pVUR6/davfnMcZ6AN559MTxs5PCU9v0zW7mlEC0pg== dependencies: - "@cosmos-kit/keplr-extension" "^2.5.6" + "@cosmos-kit/keplr-extension" "^2.5.7" "@cosmos-kit/keplr-mobile" "^2.4.5" "@cosmos-kit/react-lite@^2.5.5": @@ -1626,10 +1626,10 @@ "@chain-registry/types" "0.17.0" "@cosmos-kit/core" "^2.7.4" -"@cosmos-kit/react@^2.8.2": - version "2.9.5" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.5.tgz#937ee4f5b9f4071d5c5efba2f170eb8c03213b59" - integrity sha512-AYtDY5bC1OUMMyfNbwRzxIfx6aqpdRWMxrsZApQBLaVvzbQwwfZx0FUwWLN4BZ+CaSOm7F1RssbysF+6S405hg== +"@cosmos-kit/react@^2.9.6": + version "2.9.6" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.6.tgz#8c6cba92ffb342c0c6555da64c87d9c421f6586d" + integrity sha512-bHBZ4SSlRWuQ3pd3run8N57AhKJ1Jime06njEmuFnNPeoC42abKAxpQAFckSeKpuN2hgxj8TAtzPgJMbhwNbnQ== dependencies: "@chain-registry/types" "0.17.0" "@cosmos-kit/core" "^2.7.4" @@ -1840,10 +1840,10 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@eslint/eslintrc@^2.1.2": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.2.tgz#c6936b4b328c64496692f76944e755738be62396" - integrity sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g== +"@eslint/eslintrc@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" + integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1855,10 +1855,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.52.0": - version "8.52.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.52.0.tgz#78fe5f117840f69dc4a353adf9b9cd926353378c" - integrity sha512-mjZVbpaeMZludF2fsWLD0Z9gCref1Tk4i9+wddjRvpUNqqcndPkBD09N/Mapey0b3jaXbLm2kICwFv2E64QinA== +"@eslint/js@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" + integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== "@ethersproject/address@^5.6.0": version "5.7.0" @@ -3024,10 +3024,10 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== -"@nymproject/node-tester@^1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" - integrity sha512-VDFdH2ddIcXXamwkMbeHA88Xa/S2iPWh9QxkFggppvHS1d6gmnNHAZxXm3Uuhx7pCpzKldA0OT7qohMg9GW9xg== +"@nymproject/node-tester@^1.0.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.2.tgz#7854fb7048b1fd2cf7665dad2b4a08ef0a2fcd39" + integrity sha512-Epn48utGII5QAE9bG7AaNuIE3YA2gsTNNvs11AyYB1B4cXk7RLGORcrZ6QBLUn4S+vxqbiPlX4D5G1CdZZVISQ== "@nymproject/nym-validator-client@^0.18.0": version "0.18.0" @@ -5142,9 +5142,9 @@ "@types/node" "*" "@types/d3-array@^3.0.3": - version "3.0.9" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.0.9.tgz#54feabd29d1f15940d422c16008c63c1e4e3d188" - integrity sha512-mZowFN3p64ajCJJ4riVYlOjNlBJv3hctgAY01pjw3qTnJePD8s9DZmYDzhHKvzfCYvdjwylkU38+Vdt7Cu2FDA== + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.0.tgz#603b85d0072962bdecaf8391f60eea465c8dc282" + integrity sha512-tjU8juPSfhMnu6mJZPOCVVGba4rZoE0tjHDPb81PYwA8CzbaFscGjgkUM7juUJu6iWA1cCVWNEVwxZ5HN9Jj8Q== "@types/d3-color@*": version "3.1.2" @@ -5609,9 +5609,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.33" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.33.tgz#055356243dc4350a9ee6c6a2c07c5cae12e38877" - integrity sha512-v+I7S+hu3PIBoVkKGpSYYpiBT1ijqEzWpzQD62/jm4K74hPpSP7FF9BnKG6+fg2+62weJYkkBWDJlZt5JO/9hg== + version "18.2.34" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.34.tgz#aed20f19473721ba328feb99d1ec3307ebc1a8dd" + integrity sha512-U6eW/alrRk37FU/MS2RYMjx0Va2JGIVXELTODaTIYgvWGCV4Y4TfTUzG8DdmpDNIT0Xpj/R7GfyHOJJrDttcvg== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -6779,7 +6779,7 @@ aria-query@5.1.3: dependencies: deep-equal "^2.0.5" -aria-query@^5.0.0, aria-query@^5.1.3: +aria-query@^5.0.0, aria-query@^5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== @@ -6977,10 +6977,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== -ast-types-flow@^0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" - integrity sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag== +ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== ast-types@^0.14.2: version "0.14.2" @@ -7005,9 +7005,9 @@ async-each@^1.0.1: integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== async@^3.2.3: - version "3.2.4" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.4.tgz#2d22e00f8cddeb5fde5dd33522b56d1cf569a81c" - integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== asynciterator.prototype@^1.0.0: version "1.0.0" @@ -7059,10 +7059,10 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -axe-core@^4.6.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.8.2.tgz#2f6f3cde40935825cf4465e3c1c9e77b240ff6ae" - integrity sha512-/dlp0fxyM3R8YW7MFzaHWXrf4zzbr0vaYb23VBFCl83R7nWNPg/yaQw2Dc8jzCMmDVLhSdzH8MjrsuIUuvX+6g== +axe-core@=4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== axios@^0.21.1, axios@^0.21.2: version "0.21.4" @@ -7080,7 +7080,7 @@ axios@^1.0.0, axios@^1.3.3: form-data "^4.0.0" proxy-from-env "^1.1.0" -axobject-query@^3.1.1: +axobject-query@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== @@ -7880,9 +7880,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001559" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001559.tgz#95a982440d3d314c471db68d02664fb7536c5a30" - integrity sha512-cPiMKZgqgkg5LY3/ntGeLFUpi6tzddBNS58A4tnTgQw1zON7u2sZMU7SzOeVH4tj20++9ggL+V6FDOFMTaFFYA== + version "1.0.30001561" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" + integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== capture-exit@^2.0.0: version "2.0.0" @@ -9694,9 +9694,9 @@ ejs@^3.1.7: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.571" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.571.tgz#8aa71539eb82db98740c3ec861256cc34e0356fd" - integrity sha512-Sc+VtKwKCDj3f/kLBjdyjMpNzoZsU6WuL/wFb6EH8USmHEcebxRXcRrVpOpayxd52tuey4RUDpUsw5OS5LhJqg== + version "1.4.576" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" + integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -9812,9 +9812,9 @@ envinfo@7.8.1: integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== envinfo@^7.7.3: - version "7.10.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.10.0.tgz#55146e3909cc5fe63c22da63fb15b05aeac35b13" - integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== + version "7.11.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f" + integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg== err-code@^2.0.2: version "2.0.3" @@ -9907,7 +9907,7 @@ es-get-iterator@^1.0.2, es-get-iterator@^1.1.3: isarray "^2.0.5" stop-iteration-iterator "^1.0.0" -es-iterator-helpers@^1.0.12: +es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: version "1.0.15" resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== @@ -10089,26 +10089,26 @@ eslint-plugin-jest@^26.1.1: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsx-a11y@^6.5.1: - version "6.7.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.7.1.tgz#fca5e02d115f48c9a597a6894d5bcec2f7a76976" - integrity sha512-63Bog4iIethyo8smBklORknVjB0T2dwB8Mr/hIC+fBS0uyHdYYpzM/Ed+YC8VxTjlXHEWFOdmgwcDn1U2L9VCA== + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" + integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== dependencies: - "@babel/runtime" "^7.20.7" - aria-query "^5.1.3" - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - ast-types-flow "^0.0.7" - axe-core "^4.6.2" - axobject-query "^3.1.1" + "@babel/runtime" "^7.23.2" + aria-query "^5.3.0" + array-includes "^3.1.7" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "=4.7.0" + axobject-query "^3.2.1" damerau-levenshtein "^1.0.8" emoji-regex "^9.2.2" - has "^1.0.3" - jsx-ast-utils "^3.3.3" - language-tags "=1.0.5" + es-iterator-helpers "^1.0.15" + hasown "^2.0.0" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - semver "^6.3.0" + object.entries "^1.1.7" + object.fromentries "^2.0.7" eslint-plugin-mocha@^10.0.3: version "10.2.0" @@ -10261,14 +10261,14 @@ eslint@^7.18.0: v8-compile-cache "^2.0.3" eslint@^8.10.0: - version "8.52.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.52.0.tgz#d0cd4a1fac06427a61ef9242b9353f36ea7062fc" - integrity sha512-zh/JHnaixqHZsolRB/w9/02akBk9EPrOs9JwcTP2ek7yL5bVvXuRariiaAjjoJ5DvuwQ1WAE/HsMz+w17YgBCg== + version "8.53.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" + integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.2" - "@eslint/js" "8.52.0" + "@eslint/eslintrc" "^2.1.3" + "@eslint/js" "8.53.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -11628,11 +11628,6 @@ has-values@^1.0.0: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/has/-/has-1.0.4.tgz#2eb2860e000011dae4f1406a86fe80e530fb2ec6" - integrity sha512-qdSAmqLF6209RFj4VVItywPMbm3vWylknmB3nvNiUIs72xAimcM8nVYxYr7ncvZq5qzk9MKIZR8ijqD/1QuYjQ== - hash-base@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" @@ -13693,7 +13688,7 @@ jss@10.10.0, jss@^10.10.0: is-in-browser "^1.1.3" tiny-warning "^1.0.2" -"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.3: +"jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: version "3.3.5" resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== @@ -13754,17 +13749,17 @@ klona@^2.0.4: resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== -language-subtag-registry@~0.3.2: +language-subtag-registry@^0.3.20: version "0.3.22" resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== -language-tags@=1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.5.tgz#d321dbc4da30ba8bf3024e040fa5c14661f9193a" - integrity sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ== +language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== dependencies: - language-subtag-registry "~0.3.2" + language-subtag-registry "^0.3.20" launch-editor@^2.6.0: version "2.6.1" @@ -15844,7 +15839,7 @@ object.assign@^4.1.2, object.assign@^4.1.4: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.6: +object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.6, object.entries@^1.1.7: version "1.1.7" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== @@ -17066,9 +17061,9 @@ property-information@^5.0.0, property-information@^5.3.0: xtend "^4.0.0" property-information@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.3.0.tgz#ba4a06ec6b4e1e90577df9931286953cdf4282c3" - integrity sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg== + version "6.4.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.4.0.tgz#6bc4c618b0c2d68b3bb8b552cbb97f8e300a0f82" + integrity sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ== protobufjs@^6.11.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: version "6.11.4" @@ -17382,9 +17377,9 @@ react-google-charts@^3.0.15: react-load-script "^0.0.6" react-hook-form@^7.14.2: - version "7.47.0" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.47.0.tgz#a42f07266bd297ddf1f914f08f4b5f9783262f31" - integrity sha512-F/TroLjTICipmHeFlMrLtNLceO2xr1jU3CyiNla5zdwsGUGu2UOxxR4UyJgLlhMwLW/Wzp4cpJ7CPfgJIeKdSg== + version "7.48.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" + integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== react-identicons@^1.2.5: version "1.2.5" @@ -17507,9 +17502,9 @@ react-smooth@^2.0.4: react-transition-group "2.9.0" react-tooltip@*: - version "5.21.6" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.21.6.tgz#2287b12010c6b931ffe2b432d9961691a8cc74b3" - integrity sha512-WbND5ee8Kr5HaSuDDiAmSyRp5jH77PSk8M0CUzmVfD+1WST8XOm1StJndK/wOQIP5GPvDVPy96ylLxY/V+VpqA== + version "5.22.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.22.0.tgz#3082065b1efbd207813f484b617b1b75325f15d5" + integrity sha512-xbJBRY1LyHYd7j00UeBOqZR9SH/1S47Pe+m8vM1a+ZXglkeSNnBt5YYoPttU/amjC/VZJAPQ8+2B9x8Fl8U1qA== dependencies: "@floating-ui/dom" "^1.0.0" classnames "^2.3.0" @@ -17688,9 +17683,9 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.1.13: - version "2.9.1" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.1.tgz#8c692877b0ef158c4d72fcb5e22e3bd4845fe32f" - integrity sha512-GqHrQVMgDIktzNIIlhtvZnjYurr6Wy+KMSDxO1MEp3CrZZbvisUmnBojSWAZ7j8cjwhD4uRRFga2s5wcd/w9sQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.2.tgz#a6a4e4c2887467ea57abde7e3af5c8021355a606" + integrity sha512-ig0zYgO5nUP/896GW16b9yy2sHIRW1AHB90x48hypFTSjjxQt/J9rPzlLJjgNupzJKEHPCwMi1VnvN/k20K45w== dependencies: classnames "^2.2.5" eventemitter3 "^4.0.1" @@ -20305,9 +20300,9 @@ unist-util-visit@^4.0.0: unist-util-visit-parents "^5.1.1" universal-user-agent@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.0.tgz#3381f8503b251c0d9cd21bc1de939ec9df5480ee" - integrity sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w== + version "6.0.1" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" + integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== universalify@^0.2.0: version "0.2.0" @@ -20315,9 +20310,9 @@ universalify@^0.2.0: integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== universalify@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" - integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" @@ -20590,9 +20585,9 @@ vfile@^5.0.0: vfile-message "^3.0.0" victory-vendor@^36.6.8: - version "36.6.11" - resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.11.tgz#acae770717c2dae541a54929c304ecab5ab6ac2a" - integrity sha512-nT8kCiJp8dQh8g991J/R5w5eE2KnO8EAIP0xocWlh9l2okngMWglOPoMZzJvek8Q1KUc4XE/mJxTZnvOB1sTYg== + version "36.6.12" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.12.tgz#17fa4d79d266a6e2bde0291c60c5002c55008164" + integrity sha512-pJrTkNHln+D83vDCCSUf0ZfxBvIaVrFHmrBOsnnLAbdqfudRACAj51He2zU94/IWq9464oTADcPVkmWAfNMwgA== dependencies: "@types/d3-array" "^3.0.3" "@types/d3-ease" "^3.0.0" @@ -21267,9 +21262,9 @@ yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== yaml@^2.0.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.3.tgz#01f6d18ef036446340007db8e016810e5d64aad9" - integrity sha512-zw0VAJxgeZ6+++/su5AFoqBbZbrEakwu+X0M5HmcwUiBL7AzcuPKjj5we4xfQLp78LkEMpD0cOnUhmgOVy3KdQ== + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== yargs-parser@20.2.4: version "20.2.4" @@ -21361,9 +21356,9 @@ yup@^1.2.0: type-fest "^2.19.0" zustand@^4.3.8: - version "4.4.5" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.5.tgz#0d5571affb30906b0c07c16557f2779ede9f4d8c" - integrity sha512-jgIrBBLKncQW74PA2Lclct3gwD4aPughwGE4FqlXrv3rDqQox7JCn8rwUiFK6ygJcbBAvfTf8fF+ICg7HLD2FQ== + version "4.4.6" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" + integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== dependencies: use-sync-external-store "1.2.0" From 9be7b8ab5637d12740d85c2709164524283115b2 Mon Sep 17 00:00:00 2001 From: Yana Date: Mon, 6 Nov 2023 10:50:24 +0000 Subject: [PATCH 121/394] Add TokenSVG --- .../src/components/ConnectKeplrWallet.tsx | 6 ++--- explorer/src/icons/TokenSVG.tsx | 27 +++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) create mode 100644 explorer/src/icons/TokenSVG.tsx diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx index 7077577ebe..1d46336ed7 100644 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -6,6 +6,7 @@ import Big from 'big.js'; import { useEffect, useState, useMemo } from 'react'; import '@interchain-ui/react/styles'; +import { TokenSVG } from '../icons/TokenSVG'; export function useIsClient() { const [isClient, setIsClient] = useState(false); @@ -56,8 +57,6 @@ export default function ConnectKeplrWallet() { } }, [address, getCosmWasmClient]); - console.log('balance :>> ', balance); - if (!isClient) return null; const getGlobalbutton = () => { @@ -74,7 +73,8 @@ export default function ConnectKeplrWallet() { {address} - Balance: {balance.data} NYM + + {balance.data} NYM - - {address} - - {balance.data} NYM - - + + ); } @@ -92,10 +104,8 @@ export default function ConnectKeplrWallet() { }; return ( - - -
{getGlobalbutton()}
-
-
+ +
{getGlobalbutton()}
+
); } diff --git a/explorer/src/components/Delegations/ConfirmationModal.tsx b/explorer/src/components/Delegations/ConfirmationModal.tsx new file mode 100644 index 0000000000..7cc8cc62ca --- /dev/null +++ b/explorer/src/components/Delegations/ConfirmationModal.tsx @@ -0,0 +1,83 @@ +import React from 'react'; +import { + Breakpoint, + Button, + Paper, + Dialog, + DialogActions, + DialogContent, + DialogTitle, + SxProps, + Typography, +} from '@mui/material'; + +export interface ConfirmationModalProps { + open: boolean; + onConfirm: () => void; + onClose?: () => void; + children?: React.ReactNode; + title: React.ReactNode | string; + subTitle?: React.ReactNode | string; + confirmButton: React.ReactNode | string; + disabled?: boolean; + sx?: SxProps; + fullWidth?: boolean; + maxWidth?: Breakpoint; + backdropProps?: object; +} + +export const ConfirmationModal = ({ + open, + onConfirm, + onClose, + children, + title, + subTitle, + confirmButton, + disabled, + sx, + fullWidth, + maxWidth, + backdropProps, +}: ConfirmationModalProps) => { + const Title = ( + + {title} + {subTitle && + (typeof subTitle === 'string' ? ( + + {subTitle} + + ) : ( + subTitle + ))} + + ); + const ConfirmButton = + typeof confirmButton === 'string' ? ( + + ) : ( + confirmButton + ); + return ( + + {Title} + {children} + {ConfirmButton} + + ); +}; diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx new file mode 100644 index 0000000000..50b7276aa5 --- /dev/null +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -0,0 +1,322 @@ +import React, { useCallback, useContext, useState } from 'react'; +import { Box, Typography, SxProps } from '@mui/material'; +import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; +import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; +import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types'; +// import { Console } from 'src/utils/console'; +// import { useGetFee } from 'src/hooks/useGetFee'; +// import { simulateDelegateToMixnode, simulateVestingDelegateToMixnode, tryConvertIdentityToMixId } from 'src/requests'; +import { debounce } from 'lodash'; +import { SimpleModal } from './SimpleModal'; +import { ModalListItem } from './ModalListItem'; +// import { AppContext } from 'src/context'; +// import { SimpleModal } from '../Modals/SimpleModal'; +// import { ModalListItem } from '../Modals/ModalListItem'; +// import { checkTokenBalance, validateAmount, validateKey } from '../../utils'; +// import { TokenPoolSelector, TPoolOption } from '../TokenPoolSelector'; +// import { ConfirmTx } from '../ConfirmTX'; + +// import { getMixnodeStakeSaturation } from '../../requests'; +// import { ErrorModal } from '../Modals/ErrorModal'; +// import { BalanceWarning } from '../FeeWarning'; + +const MIN_AMOUNT_TO_DELEGATE = 10; + +export const DelegateModal: FCWithChildren<{ + open: boolean; + onClose: () => void; + onOk?: ( + mixId: number, + identityKey: string, + amount: DecCoin, + // tokenPool: TPoolOption, + // fee?: FeeDetails, + ) => Promise; + identityKey?: string; + onIdentityKeyChanged?: (identityKey: string) => void; + onAmountChanged?: (amount: string) => void; + header?: string; + buttonText?: string; + rewardInterval: string; + accountBalance?: string; + estimatedReward?: number; + profitMarginPercentage?: string | null; + nodeUptimePercentage?: number | null; + denom: CurrencyDenom; + initialAmount?: string; + hasVestingContract: boolean; + sx?: SxProps; + backdropProps?: object; +}> = ({ + open, + onIdentityKeyChanged, + onAmountChanged, + onClose, + onOk, + header, + buttonText, + identityKey: initialIdentityKey, + rewardInterval, + accountBalance, + estimatedReward, + denom, + profitMarginPercentage, + nodeUptimePercentage, + initialAmount, + hasVestingContract, + sx, + backdropProps, +}) => { + const [mixId, setMixId] = useState(); + const [identityKey, setIdentityKey] = useState(initialIdentityKey); + const [amount, setAmount] = useState(initialAmount); + const [isValidated, setValidated] = useState(false); + const [errorAmount, setErrorAmount] = useState(); + // const [tokenPool, setTokenPool] = useState('balance'); + const [errorIdentityKey, setErrorIdentityKey] = useState(); + const [mixIdError, setMixIdError] = useState(); + + // const { fee, getFee, resetFeeState, feeError } = useGetFee(); + // const { userBalance } = useContext(AppContext); + + // const handleCheckStakeSaturation = async (newMixId: number) => { + // try { + // const newSaturation = decimalToFloatApproximation( + // (await getMixnodeStakeSaturation(newMixId)).uncapped_saturation, + // ); + // if (newSaturation && newSaturation > 1) { + // const saturationPercentage = Math.round(newSaturation * 100); + // return { isOverSaturated: true, saturationPercentage }; + // } + // return { isOverSaturated: false, saturationPercentage: undefined }; + // } catch (e) { + // Console.error('Error fetching the saturation, error:', e); + // return { isOverSaturated: false, saturationPercentage: undefined }; + // } + // }; + + const validate = async () => { + let newValidatedValue = true; + let errorAmountMessage; + let errorIdentityKeyMessage; + + // if (!identityKey || !validateKey(identityKey, 32)) { + // newValidatedValue = false; + // errorIdentityKeyMessage = undefined; + // } + + // if (identityKey && mixId && validateKey(identityKey, 32)) { + // const { isOverSaturated, saturationPercentage } = await handleCheckStakeSaturation(mixId); + // if (isOverSaturated) { + // newValidatedValue = false; + // errorIdentityKeyMessage = `This node is over saturated (${saturationPercentage}%), please select another node`; + // } + // } + + // if (amount && !(await validateAmount(amount, '0'))) { + // newValidatedValue = false; + // errorAmountMessage = 'Please enter a valid amount'; + // } + + if (amount && Number(amount) < MIN_AMOUNT_TO_DELEGATE) { + errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`; + newValidatedValue = false; + } + + if (!amount?.length) { + newValidatedValue = false; + } + + if (!mixId) { + newValidatedValue = false; + } + + setErrorIdentityKey(errorIdentityKeyMessage); + if (mixIdError && !errorIdentityKeyMessage) { + setErrorIdentityKey(mixIdError); + } + setErrorAmount(errorAmountMessage); + setValidated(newValidatedValue); + }; + + const handleOk = async () => { + if (onOk && amount && identityKey && mixId) { + onOk(mixId, identityKey, { amount, denom }); //tokenPool, fee); + } + }; + + const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { + const hasEnoughTokens = true; // await checkTokenBalance(tokenPool, value.amount); + + if (!hasEnoughTokens) { + setErrorAmount('Not enough funds'); + return; + } + + // if (tokenPool === 'balance') { + // getFee(simulateDelegateToMixnode, { mixId: id, amount: value }); + // } + + // if (tokenPool === 'locked') { + // getFee(simulateVestingDelegateToMixnode, { mixId: id, amount: value }); + // } + }; + + const handleIdentityKeyChanged = (newIdentityKey: string) => { + setIdentityKey(newIdentityKey); + + if (onIdentityKeyChanged) { + onIdentityKeyChanged(newIdentityKey); + } + }; + + const handleAmountChanged = (newAmount: DecCoin) => { + setAmount(newAmount.amount); + + if (onAmountChanged) { + onAmountChanged(newAmount.amount); + } + }; + + React.useEffect(() => { + validate(); + }, [amount, identityKey, mixIdError]); + + const resolveMixId = useCallback( + debounce(async (idKey) => { + if (!idKey) { + //|| !validateKey(idKey, 32)) + return; + } + let res; + try { + // res = await tryConvertIdentityToMixId(idKey); + } catch (e) { + // Console.warn(`failed to resolve mix_id for "${idKey}": ${e}`); + return; + } + if (res) { + setMixId(res); + setMixIdError(undefined); + } else { + setMixIdError('Mixnode with this identity does not seem to be currently bonded'); + } + }, 500), + [], + ); + + React.useEffect(() => { + resolveMixId(identityKey); + }, [identityKey]); + + // if (fee) { + // return ( + // + // {userBalance.balance?.amount.amount && fee?.amount?.amount && ( + // + // + // + // )} + // + // + // + // ); + // } + + // if (feeError) { + // return ( + // + // ); + // } + + return ( + { + if (mixId && amount) { + handleConfirm({ mixId, value: { amount, denom } }); + } + }} + header={header || 'Delegate'} + okLabel={buttonText || 'Delegate stake'} + okDisabled={!isValidated} + sx={sx} + backdropProps={backdropProps} + > + + + + + {errorIdentityKey} + + + {/* {hasVestingContract && setTokenPool(pool)} />} */} + + + + + + + + ); +}; diff --git a/explorer/src/components/Delegations/ErrorModal.tsx b/explorer/src/components/Delegations/ErrorModal.tsx new file mode 100644 index 0000000000..299760edcc --- /dev/null +++ b/explorer/src/components/Delegations/ErrorModal.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import { Box, Button, Modal, SxProps, Typography } from '@mui/material'; +import { modalStyle } from '../../../../nym-wallet/src/components/Modals/styles'; + +export const ErrorModal: FCWithChildren<{ + open: boolean; + title?: string; + message?: string; + sx?: SxProps; + backdropProps?: object; + onClose: () => void; + children?: React.ReactNode; +}> = ({ children, open, title, message, sx, backdropProps, onClose }) => ( + + `1px solid #fff`, ...modalStyle, ...sx }} textAlign="center"> + theme.palette.error.main} mb={1}> + {title || 'Oh no! Something went wrong...'} + + + {message} + + {children} + + + +); diff --git a/explorer/src/components/Delegations/ModalListItem.tsx b/explorer/src/components/Delegations/ModalListItem.tsx new file mode 100644 index 0000000000..c1fcc4bf4c --- /dev/null +++ b/explorer/src/components/Delegations/ModalListItem.tsx @@ -0,0 +1,32 @@ +import React from 'react'; +import { Box, Stack, SxProps, Typography, TypographyProps } from '@mui/material'; +import { ModalDivider } from '../../../../nym-wallet/src/components/Modals/ModalDivider'; + +export const ModalListItem: FCWithChildren<{ + label: string; + divider?: boolean; + hidden?: boolean; + fontWeight?: TypographyProps['fontWeight']; + fontSize?: TypographyProps['fontSize']; + light?: boolean; + value?: React.ReactNode; + sxValue?: SxProps; +}> = ({ label, value, hidden, fontWeight, fontSize, divider, sxValue }) => ( + +); diff --git a/explorer/src/components/Delegations/SimpleModal.tsx b/explorer/src/components/Delegations/SimpleModal.tsx new file mode 100644 index 0000000000..3db21c855f --- /dev/null +++ b/explorer/src/components/Delegations/SimpleModal.tsx @@ -0,0 +1,106 @@ +import React from 'react'; +import { Box, Button, Modal, Stack, SxProps, Typography } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import ErrorOutline from '@mui/icons-material/ErrorOutline'; +import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; +import { modalStyle } from '../../../../nym-wallet/src/components/Modals/styles'; + +import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; + +export const StyledBackButton = ({ + onBack, + label, + fullWidth, + sx, +}: { + onBack: () => void; + label?: string; + fullWidth?: boolean; + sx?: SxProps; +}) => ( + +); + +export const SimpleModal: FCWithChildren<{ + open: boolean; + hideCloseIcon?: boolean; + displayErrorIcon?: boolean; + displayInfoIcon?: boolean; + headerStyles?: SxProps; + subHeaderStyles?: SxProps; + buttonFullWidth?: boolean; + onClose?: () => void; + onOk?: () => Promise; + onBack?: () => void; + header: string | React.ReactNode; + subHeader?: string; + okLabel: string; + backLabel?: string; + backButtonFullWidth?: boolean; + okDisabled?: boolean; + sx?: SxProps; + backdropProps?: object; + children?: React.ReactNode; +}> = ({ + open, + hideCloseIcon, + displayErrorIcon, + displayInfoIcon, + headerStyles, + subHeaderStyles, + buttonFullWidth, + onClose, + okDisabled, + onOk, + onBack, + header, + subHeader, + okLabel, + backLabel, + backButtonFullWidth, + sx, + children, + backdropProps, +}) => ( + + `1px solid #fff`, ...modalStyle, ...sx }}> + {displayErrorIcon && } + {displayInfoIcon && } + + {typeof header === 'string' ? ( + + {header} + + ) : ( + header + )} + {!hideCloseIcon && } + + + theme.palette.text.secondary} + // sx={{ color: (theme) => theme.palette.nym.nymWallet.text.muted, ...subHeaderStyles }} + > + {subHeader} + + + {children} + + {(onOk || onBack) && ( + + {onBack && } + {onOk && ( + + )} + + )} + + +); diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index a1f63d4006..c2c0951b9f 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -1,8 +1,10 @@ import * as React from 'react'; -import { Box, TextField, MenuItem, FormControl } from '@mui/material'; +import { Box, TextField, MenuItem, FormControl, Button } from '@mui/material'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import { Filters } from './Filters/Filters'; import { useIsMobile } from '../hooks/useIsMobile'; +import { useState } from 'react'; +import { DelegateModal } from './Delegations/DelegateModal'; const fieldsHeight = '42.25px'; @@ -25,6 +27,8 @@ export const TableToolbar: FCWithChildren = ({ childrenAfter, withFilters, }) => { + const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); + const isMobile = useIsMobile(); return ( = ({ /> )} + = ({ marginTop: isMobile ? 2 : 0, }} > + {withFilters && } {childrenAfter} + + {showNewDelegationModal && ( + setShowNewDelegationModal(false)} + onOk={undefined} + header="Delegate" + buttonText="Delegate stake" + denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} + accountBalance={'balance?.printable_balance'} + rewardInterval="weekly" + hasVestingContract={true} + // {...storybookStyles(theme, isStorybook)} + /> + )} ); }; diff --git a/explorer/src/icons/ElipsSVG.tsx b/explorer/src/icons/ElipsSVG.tsx new file mode 100644 index 0000000000..05fdc6282c --- /dev/null +++ b/explorer/src/icons/ElipsSVG.tsx @@ -0,0 +1,26 @@ +import * as React from 'react'; +import { useTheme } from '@mui/material/styles'; + +export const ElipsSVG: FCWithChildren = () => { + const theme = useTheme(); + const color = theme.palette.text.primary; + + return ( + + + + + + + + + + ); +}; diff --git a/explorer/src/icons/TokenSVG.tsx b/explorer/src/icons/TokenSVG.tsx index 780c3bc271..00c74d8a44 100644 --- a/explorer/src/icons/TokenSVG.tsx +++ b/explorer/src/icons/TokenSVG.tsx @@ -3,18 +3,18 @@ import { useTheme } from '@mui/material/styles'; export const TokenSVG: FCWithChildren = () => { const theme = useTheme(); - const color = theme.palette.text.primary; + const color = 'white'; return ( diff --git a/explorer/yarn-error.log b/explorer/yarn-error.log new file mode 100644 index 0000000000..2c269e3be9 --- /dev/null +++ b/explorer/yarn-error.log @@ -0,0 +1,22434 @@ +Arguments: + /Users/ianamatrosova/.nvm/versions/node/v18.18.2/bin/node /Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/bin/yarn.js add @nymproject/types + +PATH: + /Users/ianamatrosova/.nvm/versions/node/v18.18.2/bin:/Users/ianamatrosova/.nvm/versions/node/v16.16.0/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/usr/local/go/bin:/Users/ianamatrosova/.nvm/versions/node/v16.16.0/bin:/Users/ianamatrosova/.cargo/bin:/Users/ianamatrosova/bash_course/scripts:~/dev/flutter/bin:/Users/ianamatrosova/bash_course/scripts:~/dev/flutter/bin + +Yarn version: + 1.22.19 + +Node version: + 18.18.2 + +Platform: + darwin arm64 + +Trace: + Error: https://registry.yarnpkg.com/@nymproject%2ftypes: Not found + at params.callback [as _callback] (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:66145:18) + at self.callback (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:140890:22) + at Request.emit (node:events:517:28) + at Request. (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:141862:10) + at Request.emit (node:events:517:28) + at IncomingMessage. (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:141784:12) + at Object.onceWrapper (node:events:631:28) + at IncomingMessage.emit (node:events:529:35) + at endReadableNT (node:internal/streams/readable:1368:12) + at process.processTicksAndRejections (node:internal/process/task_queues:82:21) + +npm manifest: + { + "name": "@nym/network-explorer", + "version": "1.0.7", + "private": true, + "license": "Apache-2.0", + "scripts": { + "start": "webpack serve --progress --port 3000", + "build": "webpack build --progress --config webpack.prod.js", + "build:serve": "npx serve dist", + "test": "jest", + "test:watch": "jest --watch", + "tsc": "tsc --noEmit true", + "tsc:watch": "tsc --watch --noEmit true", + "lint": "eslint src", + "lint:fix": "eslint src --fix", + "prestorybook": "yarn --cwd .. build", + "storybook": "start-storybook -p 6006", + "storybook:build": "build-storybook" + }, + "dependencies": { + "@cosmjs/math": "^0.26.2", + "@cosmos-kit/keplr": "^2.4.7", + "@cosmos-kit/react": "^2.9.6", + "@emotion/react": "^11.4.1", + "@emotion/styled": "^11.3.0", + "@mui/icons-material": "^5.0.0", + "@mui/material": "^5.0.1", + "@mui/styles": "^5.0.1", + "@mui/system": "^5.0.1", + "@mui/x-data-grid": "^5.0.0-beta.5", + "@nymproject/mui-theme": "^1.0.0", + "@nymproject/nym-validator-client": "^0.18.0", + "@nymproject/react": "^1.0.0", + "@tauri-apps/api": "^1.5.1", + "big.js": "^6.2.1", + "buffer": "^6.0.3", + "chain-registry": "^1.19.0", + "d3-scale": "^4.0.0", + "date-fns": "^2.24.0", + "i18n-iso-countries": "^6.8.0", + "lodash": "^4.17.21", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-error-boundary": "^3.1.4", + "react-google-charts": "^3.0.15", + "react-identicons": "^1.2.5", + "react-router-dom": "6", + "react-simple-maps": "^2.3.0", + "react-tooltip": "^4.2.21", + "semver": "^7.3.8", + "use-clipboard-copy": "^0.2.0" + }, + "devDependencies": { + "@babel/core": "^7.15.0", + "@nymproject/eslint-config-react-typescript": "^1.0.0", + "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", + "@storybook/addon-actions": "^6.5.8", + "@storybook/addon-essentials": "^6.5.8", + "@storybook/addon-interactions": "^6.5.8", + "@storybook/addon-links": "^6.5.8", + "@storybook/react": "^6.5.15", + "@storybook/testing-library": "^0.0.9", + "@svgr/webpack": "^6.1.1", + "@testing-library/jest-dom": "^5.14.1", + "@testing-library/react": "^12.0.0", + "@types/d3-fetch": "^3.0.1", + "@types/d3-geo": "^3.0.2", + "@types/d3-scale": "^4.0.1", + "@types/geojson": "^7946.0.8", + "@types/jest": "^27.0.1", + "@types/node": "^16.7.13", + "@types/react": "^18.0.26", + "@types/react-dom": "^18.0.10", + "@types/react-simple-maps": "^1.0.6", + "@types/react-tooltip": "^4.2.4", + "@types/topojson-client": "^3.1.0", + "@typescript-eslint/eslint-plugin": "^5.13.0", + "@typescript-eslint/parser": "^5.13.0", + "babel-loader": "^8.3.0", + "babel-plugin-root-import": "^6.6.0", + "clean-webpack-plugin": "^4.0.0", + "css-loader": "^6.7.3", + "css-minimizer-webpack-plugin": "^3.0.2", + "dotenv-webpack": "^7.0.3", + "eslint": "^8.10.0", + "eslint-config-airbnb": "^19.0.4", + "eslint-config-airbnb-typescript": "^16.1.0", + "eslint-config-prettier": "^8.5.0", + "eslint-import-resolver-root-import": "^1.0.4", + "eslint-plugin-import": "^2.25.4", + "eslint-plugin-jest": "^26.1.1", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-prettier": "^4.0.0", + "eslint-plugin-react": "^7.29.2", + "eslint-plugin-react-hooks": "^4.3.0", + "eslint-plugin-storybook": "^0.5.12", + "favicons-webpack-plugin": "^5.0.2", + "file-loader": "^6.2.0", + "fork-ts-checker-webpack-plugin": "^7.2.1", + "html-webpack-plugin": "^5.3.2", + "jest": "^27.1.0", + "mini-css-extract-plugin": "^2.2.2", + "prettier": "^2.8.7", + "react-refresh": "^0.10.0", + "react-refresh-typescript": "^2.0.2", + "style-loader": "^3.3.1", + "ts-jest": "^27.0.5", + "ts-loader": "^9.4.2", + "tsconfig-paths-webpack-plugin": "^3.5.2", + "typescript": "^4.6.2", + "url-loader": "^4.1.1", + "webpack": "^5.75.0", + "webpack-cli": "^4.8.0", + "webpack-dev-server": "^4.5.0", + "webpack-favicons": "^1.3.8", + "webpack-merge": "^5.8.0" + }, + "browserslist": { + "production": [ + ">0.2%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + } + } + +yarn manifest: + No manifest + +Lockfile: + # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + # yarn lockfile v1 + + + "@aashutoshrathi/word-wrap@^1.2.3": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" + integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== + + "@adobe/css-tools@^4.0.1": + version "4.3.1" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28" + integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg== + + "@ampproject/remapping@^2.2.0": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" + integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + + "@babel/code-frame@7.12.11": + version "7.12.11" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" + integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== + dependencies: + "@babel/highlight" "^7.10.4" + + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.22.13" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" + integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + dependencies: + "@babel/highlight" "^7.22.13" + chalk "^2.4.2" + + "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" + integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== + + "@babel/core@7.12.9": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" + 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" + + "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.17.5", "@babel/core@^7.19.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" + integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helpers" "^7.23.2" + "@babel/parser" "^7.23.0" + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + convert-source-map "^2.0.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.3" + semver "^6.3.1" + + "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.0", "@babel/generator@^7.7.2": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" + integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + dependencies: + "@babel/types" "^7.23.0" + "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" + jsesc "^2.5.1" + + "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" + integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" + integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== + dependencies: + "@babel/types" "^7.22.15" + + "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" + integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-validator-option" "^7.22.15" + browserslist "^4.21.9" + lru-cache "^5.1.1" + semver "^6.3.1" + + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" + integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + semver "^6.3.1" + + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" + integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + regexpu-core "^5.3.1" + semver "^6.3.1" + + "@babel/helper-define-polyfill-provider@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" + integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== + dependencies: + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + + "@babel/helper-define-polyfill-provider@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" + integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== + dependencies: + "@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" + + "@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" + integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== + + "@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" + integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== + dependencies: + "@babel/template" "^7.22.15" + "@babel/types" "^7.23.0" + + "@babel/helper-hoist-variables@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" + integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-member-expression-to-functions@^7.22.15": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" + integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== + dependencies: + "@babel/types" "^7.23.0" + + "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" + integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== + dependencies: + "@babel/types" "^7.22.15" + + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" + integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-simple-access" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/helper-validator-identifier" "^7.22.20" + + "@babel/helper-optimise-call-expression@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" + integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-plugin-utils@7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + + "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" + integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== + + "@babel/helper-remap-async-to-generator@^7.22.20", "@babel/helper-remap-async-to-generator@^7.22.5": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" + integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-wrap-function" "^7.22.20" + + "@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" + integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-optimise-call-expression" "^7.22.5" + + "@babel/helper-simple-access@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" + integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" + integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-split-export-declaration@^7.22.6": + version "7.22.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" + integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== + dependencies: + "@babel/types" "^7.22.5" + + "@babel/helper-string-parser@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" + integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + + "@babel/helper-validator-identifier@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" + integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== + + "@babel/helper-validator-option@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" + integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + + "@babel/helper-wrap-function@^7.22.20": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" + integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== + dependencies: + "@babel/helper-function-name" "^7.22.5" + "@babel/template" "^7.22.15" + "@babel/types" "^7.22.19" + + "@babel/helpers@^7.12.5", "@babel/helpers@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" + integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== + dependencies: + "@babel/template" "^7.22.15" + "@babel/traverse" "^7.23.2" + "@babel/types" "^7.23.0" + + "@babel/highlight@^7.10.4", "@babel/highlight@^7.22.13": + version "7.22.20" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" + integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + dependencies: + "@babel/helper-validator-identifier" "^7.22.20" + chalk "^2.4.2" + js-tokens "^4.0.0" + + "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" + integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" + integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" + integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-transform-optional-chaining" "^7.22.15" + + "@babel/plugin-proposal-class-properties@^7.12.1": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + 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" + + "@babel/plugin-proposal-decorators@^7.12.12": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.2.tgz#0b345a5754f48309fa50b7cd99075ef0295b12c8" + integrity sha512-eR0gJQc830fJVGz37oKLvt9W9uUIQSAovUl0e9sJ3YeO09dlcoBVYD3CLrjCj4qHdXmfiyTyFt8yeQYSN5fxLg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/plugin-syntax-decorators" "^7.22.10" + + "@babel/plugin-proposal-export-default-from@^7.12.1": + version "7.22.17" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.17.tgz#91b60cd338f501cccdf549af2308768911ec5fbb" + integrity sha512-cop/3quQBVvdz6X5SJC6AhUv3C9DrVTM06LUEXimEdWAhCSyOJIr9NiZDU9leHZ0/aiG0Sh7Zmvaku5TWYNgbA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-default-from" "^7.22.5" + + "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + + "@babel/plugin-proposal-object-rest-spread@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" + + "@babel/plugin-proposal-object-rest-spread@^7.12.1": + version "7.20.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" + integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== + 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/plugin-proposal-optional-chaining@^7.12.7": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" + integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== + 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/plugin-proposal-private-methods@^7.12.1": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + + "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": + version "7.21.0-placeholder-for-preset-env.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" + integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== + + "@babel/plugin-proposal-private-property-in-object@^7.12.1": + version "7.21.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" + integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== + 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/plugin-syntax-async-generators@^7.8.4": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-bigint@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" + integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": + version "7.12.13" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" + integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== + dependencies: + "@babel/helper-plugin-utils" "^7.12.13" + + "@babel/plugin-syntax-class-static-block@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" + integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + + "@babel/plugin-syntax-decorators@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz#7d83ea04d893c442b78ebf4c3cbac59a7211deff" + integrity sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-export-default-from@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.22.5.tgz#ac3a24b362a04415a017ab96b9b4483d0e2a6e44" + integrity sha512-ODAqWWXB/yReh/jVQDag/3/tl6lgBueQkk/TcfW/59Oykm4c8a55XloX0CTk2k2VJiFWMgHby9xNX29IbCv9dQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.3" + + "@babel/plugin-syntax-flow@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" + integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-import-assertions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" + integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-import-attributes@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" + integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + + "@babel/plugin-syntax-json-strings@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-jsx@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + + "@babel/plugin-syntax-jsx@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" + integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + + "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + + "@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-optional-catch-binding@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-optional-chaining@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== + dependencies: + "@babel/helper-plugin-utils" "^7.8.0" + + "@babel/plugin-syntax-private-property-in-object@^7.14.5": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" + integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + + "@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": + version "7.14.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" + integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== + dependencies: + "@babel/helper-plugin-utils" "^7.14.5" + + "@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" + integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" + integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + + "@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" + integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-async-generator-functions@^7.23.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" + integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" + "@babel/plugin-syntax-async-generators" "^7.8.4" + + "@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" + integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + dependencies: + "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.5" + + "@babel/plugin-transform-block-scoped-functions@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" + integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" + integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-class-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" + integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-class-static-block@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" + integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + + "@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" + integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-optimise-call-expression" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-split-export-declaration" "^7.22.6" + globals "^11.1.0" + + "@babel/plugin-transform-computed-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" + integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/template" "^7.22.5" + + "@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" + integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-dotall-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" + integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-duplicate-keys@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" + integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-dynamic-import@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" + integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + + "@babel/plugin-transform-exponentiation-operator@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" + integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + dependencies: + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-export-namespace-from@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" + integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + + "@babel/plugin-transform-flow-strip-types@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" + integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.22.5" + + "@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" + integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-function-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" + integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== + dependencies: + "@babel/helper-compilation-targets" "^7.22.5" + "@babel/helper-function-name" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-json-strings@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" + integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-json-strings" "^7.8.3" + + "@babel/plugin-transform-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" + integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-logical-assignment-operators@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" + integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + + "@babel/plugin-transform-member-expression-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" + integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-modules-amd@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" + integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== + dependencies: + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-modules-commonjs@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" + integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== + dependencies: + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-simple-access" "^7.22.5" + + "@babel/plugin-transform-modules-systemjs@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" + integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== + dependencies: + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + + "@babel/plugin-transform-modules-umd@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" + integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== + dependencies: + "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" + integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-new-target@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" + integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" + integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + + "@babel/plugin-transform-numeric-separator@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" + integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + + "@babel/plugin-transform-object-rest-spread@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" + integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== + dependencies: + "@babel/compat-data" "^7.22.9" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.22.15" + + "@babel/plugin-transform-object-super@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" + integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.5" + + "@babel/plugin-transform-optional-catch-binding@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" + integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + + "@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" + integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + + "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" + integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-private-methods@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" + integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-private-property-in-object@^7.22.11": + version "7.22.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" + integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + + "@babel/plugin-transform-property-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" + integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-react-constant-elements@^7.18.12": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz#6dfa7c1c37f7d7279e417ceddf5a04abb8bb9c29" + integrity sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-react-display-name@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" + integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-react-jsx-development@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" + integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.22.5" + + "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6" + integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/types" "^7.22.15" + + "@babel/plugin-transform-react-pure-annotations@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" + integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-regenerator@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" + integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + regenerator-transform "^0.15.2" + + "@babel/plugin-transform-reserved-words@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" + integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" + integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" + integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" + + "@babel/plugin-transform-sticky-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" + integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" + integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-typeof-symbol@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" + integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-typescript@^7.22.15": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" + integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.22.5" + + "@babel/plugin-transform-unicode-escapes@^7.22.10": + version "7.22.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" + integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-unicode-property-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" + integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-unicode-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" + integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/plugin-transform-unicode-sets-regex@^7.22.5": + version "7.22.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" + integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-plugin-utils" "^7.22.5" + + "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.19.4": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" + integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ== + dependencies: + "@babel/compat-data" "^7.23.2" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" + "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" + "@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.22.5" + "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@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-syntax-unicode-sets-regex" "^7.18.6" + "@babel/plugin-transform-arrow-functions" "^7.22.5" + "@babel/plugin-transform-async-generator-functions" "^7.23.2" + "@babel/plugin-transform-async-to-generator" "^7.22.5" + "@babel/plugin-transform-block-scoped-functions" "^7.22.5" + "@babel/plugin-transform-block-scoping" "^7.23.0" + "@babel/plugin-transform-class-properties" "^7.22.5" + "@babel/plugin-transform-class-static-block" "^7.22.11" + "@babel/plugin-transform-classes" "^7.22.15" + "@babel/plugin-transform-computed-properties" "^7.22.5" + "@babel/plugin-transform-destructuring" "^7.23.0" + "@babel/plugin-transform-dotall-regex" "^7.22.5" + "@babel/plugin-transform-duplicate-keys" "^7.22.5" + "@babel/plugin-transform-dynamic-import" "^7.22.11" + "@babel/plugin-transform-exponentiation-operator" "^7.22.5" + "@babel/plugin-transform-export-namespace-from" "^7.22.11" + "@babel/plugin-transform-for-of" "^7.22.15" + "@babel/plugin-transform-function-name" "^7.22.5" + "@babel/plugin-transform-json-strings" "^7.22.11" + "@babel/plugin-transform-literals" "^7.22.5" + "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" + "@babel/plugin-transform-member-expression-literals" "^7.22.5" + "@babel/plugin-transform-modules-amd" "^7.23.0" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-modules-systemjs" "^7.23.0" + "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.22.5" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" + "@babel/plugin-transform-numeric-separator" "^7.22.11" + "@babel/plugin-transform-object-rest-spread" "^7.22.15" + "@babel/plugin-transform-object-super" "^7.22.5" + "@babel/plugin-transform-optional-catch-binding" "^7.22.11" + "@babel/plugin-transform-optional-chaining" "^7.23.0" + "@babel/plugin-transform-parameters" "^7.22.15" + "@babel/plugin-transform-private-methods" "^7.22.5" + "@babel/plugin-transform-private-property-in-object" "^7.22.11" + "@babel/plugin-transform-property-literals" "^7.22.5" + "@babel/plugin-transform-regenerator" "^7.22.10" + "@babel/plugin-transform-reserved-words" "^7.22.5" + "@babel/plugin-transform-shorthand-properties" "^7.22.5" + "@babel/plugin-transform-spread" "^7.22.5" + "@babel/plugin-transform-sticky-regex" "^7.22.5" + "@babel/plugin-transform-template-literals" "^7.22.5" + "@babel/plugin-transform-typeof-symbol" "^7.22.5" + "@babel/plugin-transform-unicode-escapes" "^7.22.10" + "@babel/plugin-transform-unicode-property-regex" "^7.22.5" + "@babel/plugin-transform-unicode-regex" "^7.22.5" + "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/preset-modules" "0.1.6-no-external-plugins" + "@babel/types" "^7.23.0" + babel-plugin-polyfill-corejs2 "^0.4.6" + babel-plugin-polyfill-corejs3 "^0.8.5" + babel-plugin-polyfill-regenerator "^0.5.3" + core-js-compat "^3.31.0" + semver "^6.3.1" + + "@babel/preset-flow@^7.12.1": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.15.tgz#30318deb9b3ebd9f5738e96da03a531e0cd3165d" + integrity sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-flow-strip-types" "^7.22.5" + + "@babel/preset-modules@0.1.6-no-external-plugins": + version "0.1.6-no-external-plugins" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" + integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" + + "@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.18.6": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc" + integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-jsx" "^7.22.15" + "@babel/plugin-transform-react-jsx-development" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.22.5" + + "@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.18.6": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz#c8de488130b7081f7e1482936ad3de5b018beef4" + integrity sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA== + dependencies: + "@babel/helper-plugin-utils" "^7.22.5" + "@babel/helper-validator-option" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.22.5" + "@babel/plugin-transform-modules-commonjs" "^7.23.0" + "@babel/plugin-transform-typescript" "^7.22.15" + + "@babel/register@^7.12.1": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.15.tgz#c2c294a361d59f5fa7bcc8b97ef7319c32ecaec7" + integrity sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg== + dependencies: + clone-deep "^4.0.1" + find-cache-dir "^2.0.0" + make-dir "^2.1.0" + pirates "^4.0.5" + source-map-support "^0.5.16" + + "@babel/regjsgen@^0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" + integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + + "@babel/runtime@7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== + dependencies: + regenerator-runtime "^0.13.2" + + "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" + integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + dependencies: + regenerator-runtime "^0.14.0" + + "@babel/runtime@~7.5.4": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== + dependencies: + regenerator-runtime "^0.13.2" + + "@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3": + version "7.22.15" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" + integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/parser" "^7.22.15" + "@babel/types" "^7.22.15" + + "@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.2", "@babel/traverse@^7.7.2": + version "7.23.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" + integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + dependencies: + "@babel/code-frame" "^7.22.13" + "@babel/generator" "^7.23.0" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-hoist-variables" "^7.22.5" + "@babel/helper-split-export-declaration" "^7.22.6" + "@babel/parser" "^7.23.0" + "@babel/types" "^7.23.0" + debug "^4.1.0" + globals "^11.1.0" + + "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.23.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" + integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + dependencies: + "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-validator-identifier" "^7.22.20" + to-fast-properties "^2.0.0" + + "@base2/pretty-print-object@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" + integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== + + "@bcoe/v8-coverage@^0.2.3": + version "0.2.3" + resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" + integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== + + "@chain-registry/keplr@1.25.0": + version "1.25.0" + resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.25.0.tgz#581a10760951c1d1185c6874199df08283a21d46" + integrity sha512-mEr5HypYEaQnYcuGp3PBTqo67WV0MQyBP2dOtl+ab2fkyB5PYa01D5B2Yu5V6V7eXLmKDvvvfiRO23NWQzFHxg== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.17.0" + "@keplr-wallet/cosmos" "0.12.28" + "@keplr-wallet/crypto" "0.12.28" + semver "^7.5.0" + + "@chain-registry/types@0.17.0", "@chain-registry/types@^0.17.0": + version "0.17.0" + resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.17.0.tgz#bbe9176a6d30a491259fab1fcdcee2b7edf6141f" + integrity sha512-lavACU4oDxioUy8lZOFZN0Vrr2qR+Dg2yEh/mkrPfOldcioavREXJou0elDyyXwq4pGLC5YQ+IISCtQ4Du0bdw== + dependencies: + "@babel/runtime" "^7.21.0" + + "@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + + "@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + + "@confio/ics23@^0.6.3", "@confio/ics23@^0.6.8": + version "0.6.8" + resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" + integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== + dependencies: + "@noble/hashes" "^1.0.0" + protobufjs "^6.8.8" + + "@cosmjs/amino@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.25.6.tgz#cdf9632253bfab7b1d2ef967124953d7bf16351f" + integrity sha512-9dXN2W7LHjDtJUGNsQ9ok0DfxeN3ca/TXnxCR3Ikh/5YqBqxI8Gel1J9PQO9L6EheYyh045Wff4bsMaLjyEeqQ== + dependencies: + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + + "@cosmjs/amino@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.29.5.tgz#053b4739a90b15b9e2b781ccd484faf64bd49aec" + integrity sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + + "@cosmjs/cosmwasm-launchpad@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.6.tgz#b03a96c8d5b5b4742ec4c56b4a01b1f4f33f7f57" + integrity sha512-rzpYg/A8tvXbY6p89LabPB1mqCtTUv+33nN+s+VWMH0oOl0LSIgLE0yIT61kwTaf2dWQvRVeFaiRLFC72/w/zw== + dependencies: + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/launchpad" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + pako "^2.0.2" + + "@cosmjs/cosmwasm-stargate@^0.25.5": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.25.6.tgz#26a788213833aaffc4bc1a87df650741e0b8fd63" + integrity sha512-STaxur5Xk5hqndLEztpa1TqvpdQyg2xD//2ZNFw2fgxf1JQtP0RfFbA3bnBkYwbGARx5cnng8QeZmSUcXnTVxA== + dependencies: + "@cosmjs/amino" "^0.25.6" + "@cosmjs/cosmwasm-launchpad" "^0.25.6" + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/proto-signing" "^0.25.6" + "@cosmjs/stargate" "^0.25.6" + "@cosmjs/tendermint-rpc" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + long "^4.0.0" + pako "^2.0.2" + protobufjs "~6.10.2" + + "@cosmjs/cosmwasm-stargate@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" + integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== + dependencies: + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stargate" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + pako "^2.0.2" + + "@cosmjs/crypto@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.25.6.tgz#695d2d0d2195bdbdd5825d415385646244900bbb" + integrity sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw== + dependencies: + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + bip39 "^3.0.2" + bn.js "^4.11.8" + elliptic "^6.5.3" + js-sha3 "^0.8.0" + libsodium-wrappers "^0.7.6" + ripemd160 "^2.0.2" + sha.js "^2.4.11" + + "@cosmjs/crypto@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.29.5.tgz#ab99fc382b93d8a8db075780cf07487a0f9519fd" + integrity sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ== + dependencies: + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers "^0.7.6" + + "@cosmjs/encoding@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" + integrity sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + + "@cosmjs/encoding@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2" + integrity sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + + "@cosmjs/json-rpc@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.25.6.tgz#4f888630e84ee114b164758ec5b48f134068656c" + integrity sha512-Mn9og3/IEzC6jWoYXs0ONqFJc8HxVjXzrZPLgaRRdMZEUBvctxdhynau1wbE4LdkYQHbu4aiRu1q1jMYGFAj4A== + dependencies: + "@cosmjs/stream" "^0.25.6" + xstream "^11.14.0" + + "@cosmjs/json-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz#5e483a9bd98a6270f935adf0dfd8a1e7eb777fe4" + integrity sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w== + dependencies: + "@cosmjs/stream" "^0.29.5" + xstream "^11.14.0" + + "@cosmjs/launchpad@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.25.6.tgz#c75f5d21be57af55fcb892f929520fa97f2d5bcc" + integrity sha512-4Yhn4cX50UE6jZz/hWqKeeCmvrlrz0BBwOdYX/29k25FqP+oLAow1xKm6UxgYuuAq8Pg/bUvswxSqwegZJTb6g== + dependencies: + "@cosmjs/amino" "^0.25.6" + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + axios "^0.21.1" + fast-deep-equal "^3.1.3" + + "@cosmjs/math@^0.25.5", "@cosmjs/math@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.25.6.tgz#25c7b106aaded889a5b80784693caa9e654b0c28" + integrity sha512-Fmyc9FJ8KMU34n7rdapMJrT/8rx5WhMw2F7WLBu7AVLcBh0yWsXIcMSJCoPHTOnMIiABjXsnrrwEaLrOOBfu6A== + dependencies: + bn.js "^4.11.8" + + "@cosmjs/math@^0.26.2": + version "0.26.8" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.26.8.tgz#29d7fc8df96a0da25f8b110482d510af93505b0d" + integrity sha512-AfooIaqhOks5xPDc4kDEXje/90iPm2STu+0YWvDStEEib2xxPTtXU3OuK+KpJ3CCFfQwbKCrzEIzJWCYmTs7mw== + dependencies: + bn.js "^5.2.0" + + "@cosmjs/math@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.29.5.tgz#722c96e080d6c2b62215ce9f4c70da7625b241b6" + integrity sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q== + dependencies: + bn.js "^5.2.0" + + "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" + integrity sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA== + dependencies: + "@cosmjs/amino" "^0.25.6" + long "^4.0.0" + protobufjs "~6.10.2" + + "@cosmjs/proto-signing@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz#af3b62a46c2c2f1d2327d678b13b7262db1fe87c" + integrity sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA== + dependencies: + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + + "@cosmjs/socket@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.25.6.tgz#7876bc24e1f16315fbb9e97bd63dea65ba90647d" + integrity sha512-hu+pW3Fy0IuhstXgxnZ2Iq0RUnGYoTWfqrxbTsgXBJge4MpEQs2YwGXgJZPMJXedBQivG0tU3r/Wvam0EWuRkQ== + dependencies: + "@cosmjs/stream" "^0.25.6" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + + "@cosmjs/socket@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.29.5.tgz#a48df6b4c45dc6a6ef8e47232725dd4aa556ac2d" + integrity sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ== + dependencies: + "@cosmjs/stream" "^0.29.5" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + + "@cosmjs/stargate@^0.25.5", "@cosmjs/stargate@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.25.6.tgz#ed7428aafd8fe1c12dc4b86f7967deb88117f61a" + integrity sha512-+LM1sK6vGuotJF9fBCBlaDL/yJhfzCV6KbsaWt3teHAKZhKYOd/9mKGiB4H9bfg4h3r+e+FZGiNkH/mdXkcgEw== + dependencies: + "@confio/ics23" "^0.6.3" + "@cosmjs/amino" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/proto-signing" "^0.25.6" + "@cosmjs/stream" "^0.25.6" + "@cosmjs/tendermint-rpc" "^0.25.6" + "@cosmjs/utils" "^0.25.6" + long "^4.0.0" + protobufjs "~6.10.2" + + "@cosmjs/stargate@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.29.5.tgz#d597af1c85a3c2af7b5bdbec34d5d40692cc09e4" + integrity sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + protobufjs "~6.11.3" + xstream "^11.14.0" + + "@cosmjs/stream@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.25.6.tgz#1bf7536ed919be3fd7fbffa477c98ef5a93eac70" + integrity sha512-2mXIzf+WaFd+GSrRaJJETVXeZoC5sosuKChFERxSY8zXQ/f3OaG9J6m+quHpPbU3nAIEtnF1jgBVqJiD+NKwGQ== + dependencies: + xstream "^11.14.0" + + "@cosmjs/stream@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.29.5.tgz#350981cac496d04939b92ee793b9b19f44bc1d4e" + integrity sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA== + dependencies: + xstream "^11.14.0" + + "@cosmjs/tendermint-rpc@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" + integrity sha512-wsvxTI7DReWJu+SVlXLblzh5NJppnh1mljuaTHodMf7HBxrXdbcCcBAO8oMbMgEqOASEY5G+z51wktxhrn9RtA== + dependencies: + "@cosmjs/crypto" "^0.25.6" + "@cosmjs/encoding" "^0.25.6" + "@cosmjs/json-rpc" "^0.25.6" + "@cosmjs/math" "^0.25.6" + "@cosmjs/socket" "^0.25.6" + "@cosmjs/stream" "^0.25.6" + axios "^0.21.1" + readonly-date "^1.0.0" + xstream "^11.14.0" + + "@cosmjs/tendermint-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" + integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/json-rpc" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/socket" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + axios "^0.21.2" + readonly-date "^1.0.0" + xstream "^11.14.0" + + "@cosmjs/utils@^0.25.6": + version "0.25.6" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" + integrity sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg== + + "@cosmjs/utils@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" + integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== + + "@cosmos-kit/core@^2.7.6": + version "2.7.6" + resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.6.tgz#391f64b92be667e932859ab22092e91a8b087a23" + integrity sha512-9ORAoY0RLB14ppwMO8I5kvjK9dZUCG/2tMUoMZKtHrLvGnW4vE+tC4FuQW9v23xBwV6MGkoFDxNn1b4j29a2IA== + dependencies: + "@chain-registry/types" "0.17.0" + "@walletconnect/types" "2.10.4" + bowser "2.11.0" + events "3.3.0" + uuid "^9.0.1" + + "@cosmos-kit/keplr-extension@^2.5.9": + version "2.5.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.9.tgz#398175e7d60ff11627825f1c27389f3342ba0935" + integrity sha512-9c2XAbKLtnMnWH+pNtSYXeqqSkIsWFW/zL9L7tf6jOov+Y9d6mLmHKfGOadbly3GX9l2RZfvYuZ1NZbCvC5u/w== + dependencies: + "@chain-registry/keplr" "1.25.0" + "@cosmos-kit/core" "^2.7.6" + + "@cosmos-kit/keplr-mobile@^2.4.8": + version "2.4.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.8.tgz#6692ed5290e0eb3be3c51ce7d2972252ce569ce4" + integrity sha512-KUkUuSC9kPyVAJIlLyewwwKmkoUV0otVSy4IyOAbhobf9N6Vun08zh5YVz8xfqM8jdzG6F8saoYDBRWqi4xPWA== + dependencies: + "@chain-registry/keplr" "1.25.0" + "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/walletconnect" "^2.4.8" + + "@cosmos-kit/keplr@^2.4.7": + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.10.tgz#148e8d63c2ad5545da5ef54943a31ed1d37ae2d5" + integrity sha512-LBiAZkG9sQ9+efVuIb/afK8JvW0OgJigkkAGA2DIGcwqA7k+b2XbvHLNU6octTYLyR32JoiB7M3xkGeIxBfpNw== + dependencies: + "@cosmos-kit/keplr-extension" "^2.5.9" + "@cosmos-kit/keplr-mobile" "^2.4.8" + + "@cosmos-kit/react-lite@^2.5.7": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.7.tgz#2a6c4e2c9a4712320e72307b7be4d87b012ffb96" + integrity sha512-CHpHw6G0Utf3LhSyONEJUkxuu5wDb9O/C2H+PdYZx50lAn/lBnNaeelQEGQUct0mVdi8XRcjsccjz5JbdjvkBQ== + dependencies: + "@chain-registry/types" "0.17.0" + "@cosmos-kit/core" "^2.7.6" + + "@cosmos-kit/react@^2.9.6": + version "2.9.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.8.tgz#95d1515bd808b76526816dc8d606eca96d5751d5" + integrity sha512-DNmFwoW9TO2a+MvXeJiBfoh+03fFKKQ4jBN4nodKC6CvwTM8i+MnGm2/46gGB/q9iLu2qyVKRkg47uiGqTQZXQ== + dependencies: + "@chain-registry/types" "0.17.0" + "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/react-lite" "^2.5.7" + "@interchain-ui/react" "^1.11.0" + "@react-icons/all-files" "^4.1.0" + + "@cosmos-kit/walletconnect@^2.4.8": + version "2.4.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.8.tgz#62630f06999d1b59fbe4764ae4cb6912a50cf107" + integrity sha512-SUb21ZiK7UTJ6A8Y5GcD6MfS+iy+hrPUYIpTRLobEKt2uwbmMeRP9hIkhvKxN97iTqXK5ay6BPAtmoJunTpv9g== + dependencies: + "@cosmos-kit/core" "^2.7.6" + "@walletconnect/sign-client" "^2.9.0" + "@walletconnect/types" "2.10.4" + "@walletconnect/utils" "^2.9.0" + events "3.3.0" + + "@cspotcode/source-map-support@^0.8.0": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" + integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== + dependencies: + "@jridgewell/trace-mapping" "0.3.9" + + "@design-systems/utils@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@design-systems/utils/-/utils-2.12.0.tgz#955c108be07cb8f01532207cbfea8f848fa760c9" + integrity sha512-Y/d2Zzr+JJfN6u1gbuBUb1ufBuLMJJRZQk+dRmw8GaTpqKx5uf7cGUYGTwN02dIb3I+Tf+cW8jcGBTRiFxdYFg== + dependencies: + "@babel/runtime" "^7.11.2" + clsx "^1.0.4" + focus-lock "^0.8.0" + react-merge-refs "^1.0.0" + + "@devtools-ds/object-inspector@^1.1.2": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@devtools-ds/object-inspector/-/object-inspector-1.2.1.tgz#2b380ed475d898d2828e7855c2dc2c82f091d326" + integrity sha512-nrAVVj4c4Iv9958oE4HA7Mk6T+4Mn/4xBRlFDeX4Ps6SMzsqO8bKhw/y6+bOfNyb/TYHmC0/pnPS68GDVZcg5Q== + dependencies: + "@babel/runtime" "7.7.2" + "@devtools-ds/object-parser" "^1.2.1" + "@devtools-ds/themes" "^1.2.1" + "@devtools-ds/tree" "^1.2.1" + clsx "1.1.0" + + "@devtools-ds/object-parser@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@devtools-ds/object-parser/-/object-parser-1.2.1.tgz#5ab709a2db807ce99cb12bf35511379d6e47a3b8" + integrity sha512-6qB+THhQfJqXyHn8wpJ1KFxXcbpLTlRyCVmkelhr0c1+MPLZcC+0XJxpVZ1AOEXPa6CWVZThBYSCvnYQEvfCqw== + dependencies: + "@babel/runtime" "~7.5.4" + + "@devtools-ds/themes@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@devtools-ds/themes/-/themes-1.2.1.tgz#060a0a1a2b38f68b01deca62240d2c94585f00dd" + integrity sha512-4/KFsHnokGxUq8CSCchINcVBb6fQ74HtEfNtMuitGtGg3VCRV0kaVSOsz6wzShzhLEaVLd5coSRQKaZj7yx72w== + dependencies: + "@babel/runtime" "~7.5.4" + "@design-systems/utils" "2.12.0" + clsx "1.1.0" + + "@devtools-ds/tree@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@devtools-ds/tree/-/tree-1.2.1.tgz#88d44dbbf96101fd8f18af92e514ed9dd00c8ceb" + integrity sha512-2ZHG28oWJno0gD+20EoSJO0yffm6JS5r7YzYhGMkrnLGvcCRZuwXSxMmIshSPLIR0cjidiAfGCqsrigHIR4ZQA== + dependencies: + "@babel/runtime" "7.7.2" + "@devtools-ds/themes" "^1.2.1" + clsx "1.1.0" + + "@discoveryjs/json-ext@^0.5.0", "@discoveryjs/json-ext@^0.5.3": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + + "@emotion/babel-plugin@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" + integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/runtime" "^7.18.3" + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/serialize" "^1.1.2" + babel-plugin-macros "^3.1.0" + convert-source-map "^1.5.0" + escape-string-regexp "^4.0.0" + find-root "^1.1.0" + source-map "^0.5.7" + stylis "4.2.0" + + "@emotion/cache@^11.11.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" + integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== + dependencies: + "@emotion/memoize" "^0.8.1" + "@emotion/sheet" "^1.2.2" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + stylis "4.2.0" + + "@emotion/hash@^0.9.0", "@emotion/hash@^0.9.1": + version "0.9.1" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" + integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== + + "@emotion/is-prop-valid@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" + integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== + dependencies: + "@emotion/memoize" "^0.8.1" + + "@emotion/memoize@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" + integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== + + "@emotion/react@^11.4.1", "@emotion/react@^11.7.0": + version "11.11.1" + resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" + integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/cache" "^11.11.0" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + "@emotion/weak-memoize" "^0.3.1" + hoist-non-react-statics "^3.3.1" + + "@emotion/serialize@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" + integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== + dependencies: + "@emotion/hash" "^0.9.1" + "@emotion/memoize" "^0.8.1" + "@emotion/unitless" "^0.8.1" + "@emotion/utils" "^1.2.1" + csstype "^3.0.2" + + "@emotion/sheet@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" + integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== + + "@emotion/styled@^11.3.0", "@emotion/styled@^11.6.0": + version "11.11.0" + resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" + integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== + dependencies: + "@babel/runtime" "^7.18.3" + "@emotion/babel-plugin" "^11.11.0" + "@emotion/is-prop-valid" "^1.2.1" + "@emotion/serialize" "^1.1.2" + "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" + "@emotion/utils" "^1.2.1" + + "@emotion/unitless@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" + integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== + + "@emotion/use-insertion-effect-with-fallbacks@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" + integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== + + "@emotion/utils@^1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" + integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== + + "@emotion/weak-memoize@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" + integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== + + "@eslint-community/eslint-utils@^4.2.0": + version "4.4.0" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" + integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== + dependencies: + eslint-visitor-keys "^3.3.0" + + "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": + version "4.10.0" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" + integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== + + "@eslint/eslintrc@^0.4.3": + version "0.4.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" + integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== + dependencies: + ajv "^6.12.4" + debug "^4.1.1" + espree "^7.3.0" + globals "^13.9.0" + ignore "^4.0.6" + import-fresh "^3.2.1" + js-yaml "^3.13.1" + minimatch "^3.0.4" + strip-json-comments "^3.1.1" + + "@eslint/eslintrc@^2.1.3": + version "2.1.3" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" + integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== + dependencies: + ajv "^6.12.4" + debug "^4.3.2" + espree "^9.6.0" + globals "^13.19.0" + ignore "^5.2.0" + import-fresh "^3.2.1" + js-yaml "^4.1.0" + minimatch "^3.1.2" + strip-json-comments "^3.1.1" + + "@eslint/js@8.53.0": + version "8.53.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" + integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== + + "@ethersproject/address@^5.6.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" + integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== + dependencies: + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/keccak256" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/rlp" "^5.7.0" + + "@ethersproject/bignumber@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" + integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + bn.js "^5.2.1" + + "@ethersproject/bytes@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" + integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== + dependencies: + "@ethersproject/logger" "^5.7.0" + + "@ethersproject/keccak256@^5.5.0", "@ethersproject/keccak256@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" + integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== + dependencies: + "@ethersproject/bytes" "^5.7.0" + js-sha3 "0.8.0" + + "@ethersproject/logger@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" + integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== + + "@ethersproject/rlp@^5.7.0": + version "5.7.0" + resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" + integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== + dependencies: + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + + "@fastify/deepmerge@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@fastify/deepmerge/-/deepmerge-1.3.0.tgz#8116858108f0c7d9fd460d05a7d637a13fe3239a" + integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A== + + "@favware/rollup-type-bundler@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@favware/rollup-type-bundler/-/rollup-type-bundler-2.0.0.tgz#5594ee64b40dc64eb02eb68a30943ff4255d25dd" + integrity sha512-RTMvx6v3b4D9V9iXHTogYjHa5fCmcUR3Bu0pFreo+80v2tD+7MSJm24nR1P/SkeTCy+zHKC1JOFQa04fcWZozg== + dependencies: + "@sapphire/utilities" "^3.11.0" + colorette "^2.0.19" + commander "^9.4.1" + js-yaml "^4.1.0" + rollup "^3.2.1" + rollup-plugin-dts "^5.0.0" + typescript "^4.8.4" + + "@floating-ui/core@^1.4.2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" + integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== + dependencies: + "@floating-ui/utils" "^0.1.3" + + "@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.5.1", "@floating-ui/dom@^1.5.2": + version "1.5.3" + resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa" + integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== + dependencies: + "@floating-ui/core" "^1.4.2" + "@floating-ui/utils" "^0.1.3" + + "@floating-ui/react-dom@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" + integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + dependencies: + "@floating-ui/dom" "^1.5.1" + + "@floating-ui/react@^0.26.0": + version "0.26.1" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.1.tgz#a790bd3cff5f334d9e87d3ec132a3dc39d937800" + integrity sha512-5gyJIJ2tZOPMgmZ/vEcVhdmQiy75b7LPO71sYIiDsxGcZ4hxLuygQWCuT0YXHqppt//Eese+L6t5KnX/gZ3tVA== + dependencies: + "@floating-ui/react-dom" "^2.0.2" + "@floating-ui/utils" "^0.1.5" + tabbable "^6.0.1" + + "@floating-ui/utils@^0.1.3", "@floating-ui/utils@^0.1.5": + version "0.1.6" + resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" + integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== + + "@formatjs/ecma402-abstract@1.17.2": + version "1.17.2" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz#d197c6e26b9fd96ff7ba3b3a0cc2f25f1f2dcac3" + integrity sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg== + dependencies: + "@formatjs/intl-localematcher" "0.4.2" + tslib "^2.4.0" + + "@formatjs/fast-memoize@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" + integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== + dependencies: + tslib "^2.4.0" + + "@formatjs/icu-messageformat-parser@2.7.0": + version "2.7.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz#9b13f2710a3b4efddfeb544480f684f27a53483b" + integrity sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q== + dependencies: + "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/icu-skeleton-parser" "1.6.2" + tslib "^2.4.0" + + "@formatjs/icu-skeleton-parser@1.6.2": + version "1.6.2" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz#00303034dc08583973c8aa67b96534c49c0bad8d" + integrity sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA== + dependencies: + "@formatjs/ecma402-abstract" "1.17.2" + tslib "^2.4.0" + + "@formatjs/intl-localematcher@0.4.2": + version "0.4.2" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz#7e6e596dbaf2f0c5a7c22da5a01d5c55f4c37e9a" + integrity sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA== + dependencies: + tslib "^2.4.0" + + "@formkit/auto-animate@1.0.0-beta.6": + version "1.0.0-beta.6" + resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz#ed7f8bc47d774a7764756646e9e3432e8be51cb3" + integrity sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w== + + "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + + "@hookform/resolvers@^2.8.0": + version "2.9.11" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.11.tgz#9ce96e7746625a89239f68ca57c4f654264c17ef" + integrity sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ== + + "@humanwhocodes/config-array@^0.11.13": + version "0.11.13" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" + integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== + dependencies: + "@humanwhocodes/object-schema" "^2.0.1" + debug "^4.1.1" + minimatch "^3.0.5" + + "@humanwhocodes/config-array@^0.5.0": + version "0.5.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" + integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== + dependencies: + "@humanwhocodes/object-schema" "^1.2.0" + debug "^4.1.1" + minimatch "^3.0.4" + + "@humanwhocodes/module-importer@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" + integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== + + "@humanwhocodes/object-schema@^1.2.0": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" + integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== + + "@humanwhocodes/object-schema@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" + integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== + + "@hutson/parse-repository-url@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" + integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== + + "@interchain-ui/react@^1.11.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.13.0.tgz#b9430c6e9fd5d94a81c3f6ce574b0d0142c491d5" + integrity sha512-samY/4jYEeKLf88AUabxnDpGMFm8V3y+xQCDTjecEn2KkNu23J2fonKUQA8F2Rnj7vsTBHxdjZDeT2wLxlcJFA== + dependencies: + "@fastify/deepmerge" "^1.3.0" + "@floating-ui/dom" "^1.5.2" + "@floating-ui/react" "^0.26.0" + "@formkit/auto-animate" "1.0.0-beta.6" + "@react-aria/utils" "^3.21.1" + "@vanilla-extract/css" "^1.12.0" + "@vanilla-extract/css-utils" "^0.1.3" + "@vanilla-extract/dynamic" "^2.0.3" + "@vanilla-extract/recipes" "^0.4.0" + animejs "^3.2.1" + bignumber.js "^9.1.1" + client-only "^0.0.1" + clsx "^1.2.1" + copy-to-clipboard "^3.3.3" + immer "^9.0.19" + lodash "^4.17.21" + rainbow-sprinkles "^0.17.0" + react-aria "^3.29.1" + react-stately "^3.27.1" + zustand "4.4.6" + + "@internationalized/date@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.0.tgz#67f1dd62355f05140cc80e324842e9bfb4553abe" + integrity sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ== + dependencies: + "@swc/helpers" "^0.5.0" + + "@internationalized/message@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@internationalized/message/-/message-3.1.1.tgz#0f29c5a239b5dcd457b55f21dcd38d1a44a1236a" + integrity sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw== + dependencies: + "@swc/helpers" "^0.5.0" + intl-messageformat "^10.1.0" + + "@internationalized/number@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.3.0.tgz#92233d130a0591085f93be86a9e6356cfa0e2de2" + integrity sha512-PuxgnKE5NJMOGKUcX1QROo8jq7sW7UWLrL5B6Rfe8BdWgU/be04cVvLyCeALD46vvbAv3d1mUvyHav/Q9a237g== + dependencies: + "@swc/helpers" "^0.5.0" + + "@internationalized/string@^3.1.1": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@internationalized/string/-/string-3.1.1.tgz#2ab7372d58bbb7ffd3de62fc2a311e4690186981" + integrity sha512-fvSr6YRoVPgONiVIUhgCmIAlifMVCeej/snPZVzbzRPxGpHl3o1GRe+d/qh92D8KhgOciruDUH8I5mjdfdjzfA== + dependencies: + "@swc/helpers" "^0.5.0" + + "@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + + "@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + + "@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" + integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== + + "@jest/console@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" + integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + + "@jest/core@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" + integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/reporters" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + emittery "^0.8.1" + exit "^0.1.2" + graceful-fs "^4.2.9" + jest-changed-files "^27.5.1" + jest-config "^27.5.1" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-resolve-dependencies "^27.5.1" + jest-runner "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + jest-watcher "^27.5.1" + micromatch "^4.0.4" + rimraf "^3.0.0" + slash "^3.0.0" + strip-ansi "^6.0.0" + + "@jest/environment@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" + integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== + dependencies: + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + + "@jest/expect-utils@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" + integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== + dependencies: + jest-get-type "^28.0.2" + + "@jest/expect-utils@^29.7.0": + version "29.7.0" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" + integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== + dependencies: + jest-get-type "^29.6.3" + + "@jest/fake-timers@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" + integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== + dependencies: + "@jest/types" "^27.5.1" + "@sinonjs/fake-timers" "^8.0.1" + "@types/node" "*" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-util "^27.5.1" + + "@jest/globals@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" + integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/types" "^27.5.1" + expect "^27.5.1" + + "@jest/reporters@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" + integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@jest/console" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + collect-v8-coverage "^1.0.0" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.2.9" + istanbul-lib-coverage "^3.0.0" + istanbul-lib-instrument "^5.1.0" + istanbul-lib-report "^3.0.0" + istanbul-lib-source-maps "^4.0.0" + istanbul-reports "^3.1.3" + jest-haste-map "^27.5.1" + jest-resolve "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + slash "^3.0.0" + source-map "^0.6.0" + string-length "^4.0.1" + terminal-link "^2.0.0" + v8-to-istanbul "^8.1.0" + + "@jest/schemas@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" + integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== + dependencies: + "@sinclair/typebox" "^0.24.1" + + "@jest/schemas@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" + integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== + dependencies: + "@sinclair/typebox" "^0.27.8" + + "@jest/source-map@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" + integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== + dependencies: + callsites "^3.0.0" + graceful-fs "^4.2.9" + source-map "^0.6.0" + + "@jest/test-result@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" + integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== + dependencies: + "@jest/console" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/istanbul-lib-coverage" "^2.0.0" + collect-v8-coverage "^1.0.0" + + "@jest/test-sequencer@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" + integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== + dependencies: + "@jest/test-result" "^27.5.1" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-runtime "^27.5.1" + + "@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + + "@jest/transform@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" + integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^27.5.1" + babel-plugin-istanbul "^6.1.1" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-regex-util "^27.5.1" + jest-util "^27.5.1" + micromatch "^4.0.4" + pirates "^4.0.4" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" + + "@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + + "@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + + "@jest/types@^28.1.3": + version "28.1.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" + integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== + dependencies: + "@jest/schemas" "^28.1.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + + "@jest/types@^29.6.3": + version "29.6.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" + integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== + dependencies: + "@jest/schemas" "^29.6.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + + "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": + version "0.3.3" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" + integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": + version "3.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" + integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== + + "@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + + "@jridgewell/source-map@^0.3.3": + version "0.3.5" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" + integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== + dependencies: + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" + + "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": + version "1.4.15" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" + integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== + + "@jridgewell/trace-mapping@0.3.9": + version "0.3.9" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" + integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + + "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": + version "0.3.20" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" + integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== + dependencies: + "@jridgewell/resolve-uri" "^3.1.0" + "@jridgewell/sourcemap-codec" "^1.4.14" + + "@keplr-wallet/common@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/common/-/common-0.12.28.tgz#1d5d985070aced31a34a6426c9ac4b775081acca" + integrity sha512-ESQorPZw8PRiUXhsrxED+E1FEWkAdc6Kwi3Az7ce204gMBQDI2j0XJtTd4uCUp+C24Em9fk0samdHzdoB4caIg== + dependencies: + "@keplr-wallet/crypto" "0.12.28" + "@keplr-wallet/types" "0.12.28" + buffer "^6.0.3" + delay "^4.4.0" + mobx "^6.1.7" + + "@keplr-wallet/cosmos@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.12.28.tgz#d56e73468256e7276a66bb41f145449dbf11efa1" + integrity sha512-IuqmSBgKgIeWBA0XGQKKs28IXFeFMCrfadCbtiZccNc7qnNr5Y/Cyyk01BPC8Dd1ZyEyAByoICgrxvtGN0GGvA== + dependencies: + "@ethersproject/address" "^5.6.0" + "@keplr-wallet/common" "0.12.28" + "@keplr-wallet/crypto" "0.12.28" + "@keplr-wallet/proto-types" "0.12.28" + "@keplr-wallet/simple-fetch" "0.12.28" + "@keplr-wallet/types" "0.12.28" + "@keplr-wallet/unit" "0.12.28" + bech32 "^1.1.4" + buffer "^6.0.3" + long "^4.0.0" + protobufjs "^6.11.2" + + "@keplr-wallet/crypto@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/crypto/-/crypto-0.12.28.tgz#28410ba1f707fa5a1506f111f6fd8baf071c394d" + integrity sha512-le1je+78/4213qshSMgQTYqhCCvzsL9+YfhjXg1kd/ali69MLWK8L8Z09ducHPS6C+LqQXXTNJQpbH2uiFSd5w== + dependencies: + "@ethersproject/keccak256" "^5.5.0" + bip32 "^2.0.6" + bip39 "^3.0.3" + bs58check "^2.1.2" + buffer "^6.0.3" + crypto-js "^4.0.0" + elliptic "^6.5.3" + sha.js "^2.4.11" + + "@keplr-wallet/proto-types@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.12.28.tgz#2fb2c37749ce7db974f01d07387e966c9b99027d" + integrity sha512-ukti/eCTltPUP64jxtk5TjtwJogyfKPqlBIT3KGUCGzBLIPeYMsffL5w5aoHsMjINzOITjYqzXyEF8LTIK/fmw== + dependencies: + long "^4.0.0" + protobufjs "^6.11.2" + + "@keplr-wallet/simple-fetch@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.28.tgz#44225df5b329c823076280df1ec9930a21b1373e" + integrity sha512-T2CiKS2B5n0ZA7CWw0CA6qIAH0XYI1siE50MP+i+V0ZniCGBeL+BMcDw64vFJUcEH+1L5X4sDAzV37fQxGwllA== + + "@keplr-wallet/types@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.28.tgz#eac3c2c9d4560856c5c403a87e67925992a04fbf" + integrity sha512-EcM9d46hYDm3AO4lf4GUbTSLRySONtTmhKb7p88q56OQOgJN3MMjRacEo2p9jX9gpPe7gRIjMUalhAfUiFpZoQ== + dependencies: + long "^4.0.0" + + "@keplr-wallet/unit@0.12.28": + version "0.12.28" + resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.28.tgz#907c7fa0b49a729cda207fca14fc0a38871cc6c4" + integrity sha512-kpXigHDBJGOmhtPkv9hqsQid9zkFo7OQPeKgO2n8GUlOINIXW6kWG5LXYTi/Yg9Uiw1CQF69gFMuZCJ8IzVHlA== + dependencies: + "@keplr-wallet/types" "0.12.28" + big-integer "^1.6.48" + utility-types "^3.10.0" + + "@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + + "@lerna/child-process@7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-7.4.2.tgz#a2fd013ac2150dc288270d3e0d0b850c06bec511" + integrity sha512-je+kkrfcvPcwL5Tg8JRENRqlbzjdlZXyaR88UcnCdNW0AJ1jX9IfHRys1X7AwSroU2ug8ESNC+suoBw1vX833Q== + dependencies: + chalk "^4.1.0" + execa "^5.0.0" + strong-log-transformer "^2.1.0" + + "@lerna/create@7.4.2": + version "7.4.2" + resolved "https://registry.yarnpkg.com/@lerna/create/-/create-7.4.2.tgz#f845fad1480e46555af98bd39af29571605dddc9" + integrity sha512-1wplFbQ52K8E/unnqB0Tq39Z4e+NEoNrpovEnl6GpsTUrC6WDp8+w0Le2uCBV0hXyemxChduCkLz4/y1H1wTeg== + dependencies: + "@lerna/child-process" "7.4.2" + "@npmcli/run-script" "6.0.2" + "@nx/devkit" ">=16.5.1 < 17" + "@octokit/plugin-enterprise-rest" "6.0.1" + "@octokit/rest" "19.0.11" + byte-size "8.1.1" + chalk "4.1.0" + clone-deep "4.0.1" + cmd-shim "6.0.1" + columnify "1.6.0" + conventional-changelog-core "5.0.1" + conventional-recommended-bump "7.0.1" + cosmiconfig "^8.2.0" + dedent "0.7.0" + execa "5.0.0" + fs-extra "^11.1.1" + get-stream "6.0.0" + git-url-parse "13.1.0" + glob-parent "5.1.2" + globby "11.1.0" + graceful-fs "4.2.11" + has-unicode "2.0.1" + ini "^1.3.8" + init-package-json "5.0.0" + inquirer "^8.2.4" + is-ci "3.0.1" + is-stream "2.0.0" + js-yaml "4.1.0" + libnpmpublish "7.3.0" + load-json-file "6.2.0" + lodash "^4.17.21" + make-dir "4.0.0" + minimatch "3.0.5" + multimatch "5.0.0" + node-fetch "2.6.7" + npm-package-arg "8.1.1" + npm-packlist "5.1.1" + npm-registry-fetch "^14.0.5" + npmlog "^6.0.2" + nx ">=16.5.1 < 17" + p-map "4.0.0" + p-map-series "2.1.0" + p-queue "6.6.2" + p-reduce "^2.1.0" + pacote "^15.2.0" + pify "5.0.0" + read-cmd-shim "4.0.0" + read-package-json "6.0.4" + resolve-from "5.0.0" + rimraf "^4.4.1" + semver "^7.3.4" + signal-exit "3.0.7" + slash "^3.0.0" + ssri "^9.0.1" + strong-log-transformer "2.1.0" + tar "6.1.11" + temp-dir "1.0.0" + upath "2.0.1" + uuid "^9.0.0" + validate-npm-package-license "^3.0.4" + validate-npm-package-name "5.0.0" + write-file-atomic "5.0.1" + write-pkg "4.0.0" + yargs "16.2.0" + yargs-parser "20.2.4" + + "@mdx-js/loader@^2.1.5": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-2.3.0.tgz#56a6b07eb0027b6407e953a97c52bd8619601161" + integrity sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg== + dependencies: + "@mdx-js/mdx" "^2.0.0" + source-map "^0.7.0" + + "@mdx-js/mdx@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" + 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" + + "@mdx-js/mdx@^2.0.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-2.3.0.tgz#d65d8c3c28f3f46bb0e7cb3bf7613b39980671a9" + integrity sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/mdx" "^2.0.0" + estree-util-build-jsx "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-util-to-js "^1.1.0" + estree-walker "^3.0.0" + hast-util-to-estree "^2.0.0" + markdown-extensions "^1.0.0" + periscopic "^3.0.0" + remark-mdx "^2.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + unified "^10.0.0" + unist-util-position-from-estree "^1.0.0" + unist-util-stringify-position "^3.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + + "@mdx-js/react@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" + integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== + + "@mdx-js/util@1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" + integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== + + "@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + + "@mui/base@5.0.0-beta.23": + version "5.0.0-beta.23" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.23.tgz#dd10dfc609d8937749521f940965f757fa3c0f2c" + integrity sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw== + dependencies: + "@babel/runtime" "^7.23.2" + "@floating-ui/react-dom" "^2.0.2" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.17" + "@popperjs/core" "^2.11.8" + clsx "^2.0.0" + prop-types "^15.8.1" + + "@mui/core-downloads-tracker@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.17.tgz#68ec40ea00832fb685f09bd493648b1f68f5baf4" + integrity sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ== + + "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": + version "5.14.16" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.16.tgz#bd394183b0cfb068d4fa48292cd8d329be8d6b16" + integrity sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg== + dependencies: + "@babel/runtime" "^7.23.2" + + "@mui/lab@^5.0.0-alpha.72": + version "5.0.0-alpha.152" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.152.tgz#22efc0dc0e19325759691c81db1ac32da1250481" + integrity sha512-P81QbS/FolrTAjm72N8ndTCYCdPufxJeftNcuc/L4ENHrAo8bV4wcweEyL2AcetfvTgpmGf3QaITrQv8Ts067A== + dependencies: + "@babel/runtime" "^7.23.2" + "@mui/base" "5.0.0-beta.23" + "@mui/system" "^5.14.17" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.17" + clsx "^2.0.0" + prop-types "^15.8.1" + + "@mui/material@^5.0.1", "@mui/material@^5.2.2": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.17.tgz#8e11098e52965be3e9ed117d6c107bbe511fac46" + integrity sha512-+y0VeOLWfEA4Z98We/UH6KCo8+f2HLZDK45FY+sJf8kSojLy3VntadKtC/u0itqnXXb1Pr4wKB2tSIBW02zY4Q== + dependencies: + "@babel/runtime" "^7.23.2" + "@mui/base" "5.0.0-beta.23" + "@mui/core-downloads-tracker" "^5.14.17" + "@mui/system" "^5.14.17" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.17" + "@types/react-transition-group" "^4.4.8" + clsx "^2.0.0" + csstype "^3.1.2" + prop-types "^15.8.1" + react-is "^18.2.0" + react-transition-group "^4.4.5" + + "@mui/private-theming@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.17.tgz#2fdf9d7df54dcb27e8ae7e00f440eb8310376ec3" + integrity sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g== + dependencies: + "@babel/runtime" "^7.23.2" + "@mui/utils" "^5.14.17" + prop-types "^15.8.1" + + "@mui/styled-engine@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.17.tgz#7f79d863604076db5278bd38a2eeac44cd2ed336" + integrity sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw== + dependencies: + "@babel/runtime" "^7.23.2" + "@emotion/cache" "^11.11.0" + csstype "^3.1.2" + prop-types "^15.8.1" + + "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.17.tgz#441afdd9425b4aad3dea727b0067d367a41f4b58" + integrity sha512-CsftJtCxF3ABigNXikmBJEsI6XQDmeTQNmjaA6wbjYA+29xPMUEQD4Coe+VXGkcc2jrE6Vy8qZ3ytO8QaM9KAw== + dependencies: + "@babel/runtime" "^7.23.2" + "@emotion/hash" "^0.9.1" + "@mui/private-theming" "^5.14.17" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.17" + clsx "^2.0.0" + csstype "^3.1.2" + hoist-non-react-statics "^3.3.2" + jss "^10.10.0" + jss-plugin-camel-case "^10.10.0" + jss-plugin-default-unit "^10.10.0" + jss-plugin-global "^10.10.0" + jss-plugin-nested "^10.10.0" + jss-plugin-props-sort "^10.10.0" + jss-plugin-rule-value-function "^10.10.0" + jss-plugin-vendor-prefixer "^10.10.0" + prop-types "^15.8.1" + + "@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.17.tgz#3e212d1e699d4c777bbe5c6584ae129b1ef7d8bc" + integrity sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg== + dependencies: + "@babel/runtime" "^7.23.2" + "@mui/private-theming" "^5.14.17" + "@mui/styled-engine" "^5.14.17" + "@mui/types" "^7.2.8" + "@mui/utils" "^5.14.17" + clsx "^2.0.0" + csstype "^3.1.2" + prop-types "^15.8.1" + + "@mui/types@^7.2.8": + version "7.2.8" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" + integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== + + "@mui/utils@^5.10.3", "@mui/utils@^5.14.17", "@mui/utils@^5.7.0": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.17.tgz#8e2e7ca58865119eec8c6bdb359f539c25aaf576" + integrity sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ== + dependencies: + "@babel/runtime" "^7.23.2" + "@types/prop-types" "^15.7.9" + prop-types "^15.8.1" + react-is "^18.2.0" + + "@mui/x-data-grid@^5.0.0-beta.5": + version "5.17.26" + resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.17.26.tgz#1f7fa73dd3986cf052e2fd2cb56eb4678a7bd913" + integrity sha512-eGJq9J0g9cDGLFfMmugOadZx0mJeOd/yQpHwEa5gUXyONS6qF0OhXSWyDOhDdA3l2TOoQzotMN5dY/T4Wl1KYA== + dependencies: + "@babel/runtime" "^7.18.9" + "@mui/utils" "^5.10.3" + clsx "^1.2.1" + prop-types "^15.8.1" + reselect "^4.1.6" + + "@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" + integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== + + "@nodelib/fs.scandir@2.1.5": + version "2.1.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" + integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== + dependencies: + "@nodelib/fs.stat" "2.0.5" + run-parallel "^1.1.9" + + "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" + integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== + + "@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + + "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": + version "1.2.8" + resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" + integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== + dependencies: + "@nodelib/fs.scandir" "2.1.5" + fastq "^1.6.0" + + "@npmcli/fs@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" + integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== + dependencies: + "@gar/promisify" "^1.0.1" + semver "^7.3.5" + + "@npmcli/fs@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" + integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== + dependencies: + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + + "@npmcli/fs@^3.1.0": + version "3.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" + integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== + dependencies: + semver "^7.3.5" + + "@npmcli/git@^4.0.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" + integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== + dependencies: + "@npmcli/promise-spawn" "^6.0.0" + lru-cache "^7.4.4" + npm-pick-manifest "^8.0.0" + proc-log "^3.0.0" + promise-inflight "^1.0.1" + promise-retry "^2.0.1" + semver "^7.3.5" + which "^3.0.0" + + "@npmcli/installed-package-contents@^2.0.1": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" + integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== + dependencies: + npm-bundled "^3.0.0" + npm-normalize-package-bin "^3.0.0" + + "@npmcli/move-file@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" + integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + + "@npmcli/move-file@^2.0.0": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" + integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" + + "@npmcli/node-gyp@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" + integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== + + "@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" + integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== + dependencies: + which "^3.0.0" + + "@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0": + version "6.0.2" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" + integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== + dependencies: + "@npmcli/node-gyp" "^3.0.0" + "@npmcli/promise-spawn" "^6.0.0" + node-gyp "^9.0.0" + read-package-json-fast "^3.0.0" + which "^3.0.0" + + "@nrwl/devkit@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-16.10.0.tgz#ac8c5b4db00f12c4b817c937be2f7c4eb8f2593c" + integrity sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ== + dependencies: + "@nx/devkit" "16.10.0" + + "@nrwl/tao@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.10.0.tgz#94642a0380709b8e387e1e33705a5a9624933375" + integrity sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q== + dependencies: + nx "16.10.0" + tslib "^2.3.0" + + "@nx/devkit@16.10.0", "@nx/devkit@>=16.5.1 < 17": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-16.10.0.tgz#7e466be2dee2dcb1ccaf286786ca2a0a639aa007" + integrity sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w== + dependencies: + "@nrwl/devkit" "16.10.0" + ejs "^3.1.7" + enquirer "~2.3.6" + ignore "^5.0.4" + semver "7.5.3" + tmp "~0.2.1" + tslib "^2.3.0" + + "@nx/nx-darwin-arm64@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.10.0.tgz#0c73010cac7a502549483b12bad347da9014e6f1" + integrity sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ== + + "@nx/nx-darwin-x64@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz#2ccf270418d552fd0a8e0d6089aee4944315adaa" + integrity sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg== + + "@nx/nx-freebsd-x64@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz#c3ee6914256e69493fed9355b0d6661d0e86da44" + integrity sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw== + + "@nx/nx-linux-arm-gnueabihf@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz#a961eccbb38acb2da7fc125b29d1fead0b39152f" + integrity sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA== + + "@nx/nx-linux-arm64-gnu@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz#795f20072549d03822b5c4639ef438e473dbb541" + integrity sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g== + + "@nx/nx-linux-arm64-musl@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz#f2428ee6dbe2b2c326e8973f76c97666def33607" + integrity sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ== + + "@nx/nx-linux-x64-gnu@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz#d36c2bcf94d49eaa24e3880ddaf6f1f617de539b" + integrity sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA== + + "@nx/nx-linux-x64-musl@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz#78bd2ab97a583b3d4ea3387b67fd7b136907493c" + integrity sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q== + + "@nx/nx-win32-arm64-msvc@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz#ef20ec8d0c83d66e73e20df12d2c788b8f866396" + integrity sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA== + + "@nx/nx-win32-x64-msvc@16.10.0": + version "16.10.0" + resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" + integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== + + "@nymproject/node-tester@^1.0.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.2.tgz#7854fb7048b1fd2cf7665dad2b4a08ef0a2fcd39" + integrity sha512-Epn48utGII5QAE9bG7AaNuIE3YA2gsTNNvs11AyYB1B4cXk7RLGORcrZ6QBLUn4S+vxqbiPlX4D5G1CdZZVISQ== + + "@nymproject/nym-validator-client@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@nymproject/nym-validator-client/-/nym-validator-client-0.18.0.tgz#4dd72bafdf6c72b603242f32c0bb9a1f9e475b98" + integrity sha512-FO1T15S2BJVuMoPA2yOaH40aD3hKJPKJVyX5ix7eJEbBWIdsYNoVeVc/soHhaAU1FIy2uU0G/FZQkaUYJGGb7Q== + dependencies: + "@cosmjs/cosmwasm-stargate" "^0.25.5" + "@cosmjs/math" "^0.25.5" + "@cosmjs/proto-signing" "^0.25.5" + "@cosmjs/stargate" "^0.25.5" + axios "^0.21.1" + + "@octokit/auth-token@^3.0.0": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" + integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== + + "@octokit/core@^4.2.1": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" + integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== + dependencies: + "@octokit/auth-token" "^3.0.0" + "@octokit/graphql" "^5.0.0" + "@octokit/request" "^6.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^9.0.0" + before-after-hook "^2.2.0" + universal-user-agent "^6.0.0" + + "@octokit/endpoint@^7.0.0": + version "7.0.6" + resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" + integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== + dependencies: + "@octokit/types" "^9.0.0" + is-plain-object "^5.0.0" + universal-user-agent "^6.0.0" + + "@octokit/graphql@^5.0.0": + version "5.0.6" + resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" + integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== + dependencies: + "@octokit/request" "^6.0.0" + "@octokit/types" "^9.0.0" + universal-user-agent "^6.0.0" + + "@octokit/openapi-types@^18.0.0": + version "18.1.1" + resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" + integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== + + "@octokit/plugin-enterprise-rest@6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" + integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== + + "@octokit/plugin-paginate-rest@^6.1.2": + version "6.1.2" + resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" + integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== + dependencies: + "@octokit/tsconfig" "^1.0.2" + "@octokit/types" "^9.2.3" + + "@octokit/plugin-request-log@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" + integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== + + "@octokit/plugin-rest-endpoint-methods@^7.1.2": + version "7.2.3" + resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" + integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA== + dependencies: + "@octokit/types" "^10.0.0" + + "@octokit/request-error@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" + integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== + dependencies: + "@octokit/types" "^9.0.0" + deprecation "^2.0.0" + once "^1.4.0" + + "@octokit/request@^6.0.0": + version "6.2.8" + resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" + integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== + dependencies: + "@octokit/endpoint" "^7.0.0" + "@octokit/request-error" "^3.0.0" + "@octokit/types" "^9.0.0" + is-plain-object "^5.0.0" + node-fetch "^2.6.7" + universal-user-agent "^6.0.0" + + "@octokit/rest@19.0.11": + version "19.0.11" + resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" + integrity sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw== + dependencies: + "@octokit/core" "^4.2.1" + "@octokit/plugin-paginate-rest" "^6.1.2" + "@octokit/plugin-request-log" "^1.0.4" + "@octokit/plugin-rest-endpoint-methods" "^7.1.2" + + "@octokit/tsconfig@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7" + integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== + + "@octokit/types@^10.0.0": + version "10.0.0" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a" + integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg== + dependencies: + "@octokit/openapi-types" "^18.0.0" + + "@octokit/types@^9.0.0", "@octokit/types@^9.2.3": + version "9.3.2" + resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" + integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== + dependencies: + "@octokit/openapi-types" "^18.0.0" + + "@parcel/watcher@2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" + integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== + dependencies: + node-addon-api "^3.2.1" + node-gyp-build "^4.3.0" + + "@pkgjs/parseargs@^0.11.0": + version "0.11.0" + resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" + integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== + + "@pmmmwh/react-refresh-webpack-plugin@^0.5.3", "@pmmmwh/react-refresh-webpack-plugin@^0.5.4": + version "0.5.11" + resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a" + integrity sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ== + dependencies: + ansi-html-community "^0.0.8" + common-path-prefix "^3.0.0" + core-js-pure "^3.23.3" + error-stack-parser "^2.0.6" + find-up "^5.0.0" + html-entities "^2.1.0" + loader-utils "^2.0.4" + schema-utils "^3.0.0" + source-map "^0.7.3" + + "@popperjs/core@^2.11.8": + version "2.11.8" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" + integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== + + "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" + integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== + + "@protobufjs/base64@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" + integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== + + "@protobufjs/codegen@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" + integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== + + "@protobufjs/eventemitter@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" + integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== + + "@protobufjs/fetch@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" + integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== + dependencies: + "@protobufjs/aspromise" "^1.1.1" + "@protobufjs/inquire" "^1.1.0" + + "@protobufjs/float@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" + integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== + + "@protobufjs/inquire@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" + integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== + + "@protobufjs/path@^1.1.2": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" + integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== + + "@protobufjs/pool@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" + integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== + + "@protobufjs/utf8@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" + integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== + + "@react-aria/breadcrumbs@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.7.tgz#1d7f5e01887c62516a3e705e59a92e96d315c6c6" + integrity sha512-z+L1gNyWrjZ4Fs0Vo4AkwJicPpEGIestww6r8CiTlt07eo0vCReNmB3oofI6nMJOSu51yef+qqBtFyr0tqBgiw== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/link" "^3.6.1" + "@react-aria/utils" "^3.21.1" + "@react-types/breadcrumbs" "^3.7.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/button@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.8.4.tgz#0f0afe45ad9dfc4f79b2755983a503e2de74f7f5" + integrity sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/calendar@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.2.tgz#a00b2337c0f6c8840aaa9bd5410e95452c5a5e2d" + integrity sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/calendar" "^3.4.1" + "@react-types/button" "^3.9.0" + "@react-types/calendar" "^3.4.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/checkbox@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.11.2.tgz#9e1045edf282298cb8337fd3fd1d953c6cf5f667" + integrity sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA== + dependencies: + "@react-aria/label" "^3.7.2" + "@react-aria/toggle" "^3.8.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/checkbox" "^3.5.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/combobox@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.7.1.tgz#8fc26008b54bd2d2c6eac6c126c1b2bba5a5e774" + integrity sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/listbox" "^3.11.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/combobox" "^3.7.1" + "@react-stately/layout" "^3.13.3" + "@react-types/button" "^3.9.0" + "@react-types/combobox" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/datepicker@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.8.1.tgz#7ad2ff17799b7601edfc2eef7d2f35086f182897" + integrity sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/number" "^3.3.0" + "@internationalized/string" "^3.1.1" + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/spinbutton" "^3.5.4" + "@react-aria/utils" "^3.21.1" + "@react-stately/datepicker" "^3.8.0" + "@react-types/button" "^3.9.0" + "@react-types/calendar" "^3.4.1" + "@react-types/datepicker" "^3.6.1" + "@react-types/dialog" "^3.5.6" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/dialog@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.7.tgz#e57eca98e95114d618d583f5cc5400bdcf1190b0" + integrity sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/overlays" "^3.18.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/overlays" "^3.6.3" + "@react-types/dialog" "^3.5.6" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/dnd@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.4.3.tgz#f13e438f6613f79988ffa5d6a79c5705c26428d4" + integrity sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA== + dependencies: + "@internationalized/string" "^3.1.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/dnd" "^3.2.5" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/focus@^3.14.3": + version "3.14.3" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.14.3.tgz#5e66dbf47e1d92aebf67d52b3b08d1631591f5b6" + integrity sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + + "@react-aria/grid@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.4.tgz#1f19df9b413e843c82a280a40cd863650e424dfd" + integrity sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/grid" "^3.8.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/checkbox" "^3.5.2" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/gridlist@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.1.tgz#0be67cd3f0d30a6fe76c0f73927f403ca416a555" + integrity sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/grid" "^3.8.4" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/i18n@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.8.4.tgz#e7ecd3edcaa66ceaf9ebb1034395e021685163af" + integrity sha512-YlTJn7YJlUxds/T5dNtme551qc118NoDQhK+IgGpzcmPQ3xSnwBAQP4Zwc7wCpAU+xEwnNcsGw+L1wJd49He/A== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/message" "^3.1.1" + "@internationalized/number" "^3.3.0" + "@internationalized/string" "^3.1.1" + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/interactions@^3.19.1": + version "3.19.1" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.19.1.tgz#b17b1f9dc84624d4222c7fa0a4fa6b4c14fe125a" + integrity sha512-2QFOvq/rJfMGEezmtYcGcJmfaD16kHKcSTLFrZ8aeBK6hYFddGVZJZk+dXf+G7iNaffa8rMt6uwzVe/malJPBA== + dependencies: + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/label@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.2.tgz#6563495cad2af9262e722514e88406baede48852" + integrity sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/label" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/link@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.1.tgz#1e196dc2e25af24a713c3bb6d653aae37b67a1a2" + integrity sha512-uVkuNHabxE11Eqeo0d1RA86EckOlfJ2Ld8uN8HnTxiLetXLZYUMBwlZfBJvT3RdwPtTG7jC3OK3BvwiyIJrtZw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/link" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/listbox@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.1.tgz#2a2c88daf6a67e07ab17440f72a859913161e6e8" + integrity sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-types/listbox" "^3.4.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/live-announcer@^3.3.1": + version "3.3.1" + resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz#bf864b8820fb02daaeefc1c972782a0174fd60b9" + integrity sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew== + dependencies: + "@swc/helpers" "^0.5.0" + + "@react-aria/menu@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.1.tgz#fb31c5533d5106c41ed73c14516ecbf74742976a" + integrity sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/menu" "^3.5.6" + "@react-stately/tree" "^3.7.3" + "@react-types/button" "^3.9.0" + "@react-types/menu" "^3.9.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/meter@^3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.7.tgz#33a7b2d4a0be56d147949bb36f3f32bc545c3a87" + integrity sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA== + dependencies: + "@react-aria/progress" "^3.4.7" + "@react-types/meter" "^3.3.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/numberfield@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.9.1.tgz#de8bbcfbd971c22311a85a3ab34165c53ff96519" + integrity sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/spinbutton" "^3.5.4" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/numberfield" "^3.6.2" + "@react-types/button" "^3.9.0" + "@react-types/numberfield" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + "@swc/helpers" "^0.5.0" + + "@react-aria/overlays@^3.18.1": + version "3.18.1" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.18.1.tgz#b53093b2e1004feff155c81730e0101179cd6c47" + integrity sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/overlays" "^3.6.3" + "@react-types/button" "^3.9.0" + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/progress@^3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.7.tgz#babee1f4775b7baa1b8e2250c861c98805e3d6ee" + integrity sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-types/progress" "^3.5.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/radio@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.8.2.tgz#318fb1bbdc67131181c03002a5d8458405239b85" + integrity sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/radio" "^3.9.1" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/searchfield@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.5.7.tgz#00f0be54375967f86e2b3365bd80ea602af021a3" + integrity sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/searchfield" "^3.4.6" + "@react-types/button" "^3.9.0" + "@react-types/searchfield" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/select@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.13.1.tgz#c6d7eda36b8f8887c9baf0f1dea06f30806d71fc" + integrity sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/listbox" "^3.11.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/select" "^3.5.5" + "@react-types/button" "^3.9.0" + "@react-types/select" "^3.8.4" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/selection@^3.17.1": + version "3.17.1" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.1.tgz#12df277b8806fd26093e16f6a2734bd1e6fbb3e2" + integrity sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/separator@^3.3.7": + version "3.3.7" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.7.tgz#258f52a64d9ec58d62d3257edac542007b54a142" + integrity sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/slider@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.2.tgz#e122bbf945c5ae0f72be1c8977ef9be957c4bdbf" + integrity sha512-io7yJm2jS0gK1ILE9kjClh9zylKsOLbRy748CyD66LDV0ZIjj2D/uZF6BtfKq7Zhc2OsMvDB9+e2IkrszKe8uw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/radio" "^3.9.1" + "@react-stately/slider" "^3.4.4" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@react-types/slider" "^3.6.2" + "@swc/helpers" "^0.5.0" + + "@react-aria/spinbutton@^3.5.4": + version "3.5.4" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz#d1c317838f4ae55d6a2e6c698581e4cf0f2b0c89" + integrity sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/utils" "^3.21.1" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/ssr@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.8.0.tgz#e7f467ac42f72504682724304ce221f785d70d49" + integrity sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A== + dependencies: + "@swc/helpers" "^0.5.0" + + "@react-aria/switch@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.6.tgz#2f3d4b4198f26848fac9876233981b232c151620" + integrity sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w== + dependencies: + "@react-aria/toggle" "^3.8.2" + "@react-stately/toggle" "^3.6.3" + "@react-types/switch" "^3.4.2" + "@swc/helpers" "^0.5.0" + + "@react-aria/table@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.1.tgz#843e377b62c695b6559dd0b6ef0d7bdb8f56c358" + integrity sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/grid" "^3.8.4" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/collections" "^3.10.2" + "@react-stately/flags" "^3.0.0" + "@react-stately/table" "^3.11.2" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/checkbox" "^3.5.2" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/tabs@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.1.tgz#89229734a5afccbb9a8a03ac8098b1b3653a948f" + integrity sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-stately/tabs" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@react-types/tabs" "^3.3.3" + "@swc/helpers" "^0.5.0" + + "@react-aria/tag@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.2.1.tgz#1fcfece4fc574f066d32aca005fbfc133ef3c247" + integrity sha512-i7Mj3IhB91sGp3NS6iNBVh25W+LR2XXpTmtn3OS4R62q3Oalw/1PKqPWqFc73Lb5IWF5rj3eh2yTf+rerWf3dw== + dependencies: + "@react-aria/gridlist" "^3.7.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/textfield@^3.12.2": + version "3.12.2" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.12.2.tgz#e1ae5abaf72ed9c800e6a8afface3b2fd58258ca" + integrity sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + "@swc/helpers" "^0.5.0" + + "@react-aria/toggle@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.8.2.tgz#4336f0d70e33347c7bcf43f3ec4e617ce449127b" + integrity sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@react-types/switch" "^3.4.2" + "@swc/helpers" "^0.5.0" + + "@react-aria/tooltip@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.4.tgz#1be90589f290b09c2a938907124cf72821fb277c" + integrity sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/tooltip" "^3.4.5" + "@react-types/shared" "^3.21.0" + "@react-types/tooltip" "^3.4.5" + "@swc/helpers" "^0.5.0" + + "@react-aria/utils@^3.21.1": + version "3.21.1" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.21.1.tgz#35f5d545757ea38f05a0d2f5492f13217ebb03ce" + integrity sha512-tySfyWHXOhd/b6JSrSOl7krngEXN3N6pi1hCAXObRu3+MZlaZOMDf/j18aoteaIF2Jpv8HMWUJUJtQKGmBJGRA== + dependencies: + "@react-aria/ssr" "^3.8.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + + "@react-aria/visually-hidden@^3.8.6": + version "3.8.6" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.6.tgz#9b149851ac41e9c72c7819f8d4ad47ddfb45b863" + integrity sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + + "@react-icons/all-files@^4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" + integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== + + "@react-stately/calendar@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.1.tgz#8982ca015c81f35154a23fb26a514a08f9b041a5" + integrity sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-stately/utils" "^3.8.0" + "@react-types/calendar" "^3.4.1" + "@react-types/datepicker" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/checkbox@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.5.1.tgz#a6f6ad01852aded85f4baa7c3e97e44d2c47a607" + integrity sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw== + dependencies: + "@react-stately/toggle" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/collections@^3.10.2": + version "3.10.2" + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.2.tgz#c739d9d596ecb744be15fde6f064ad85dd6145db" + integrity sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q== + dependencies: + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/combobox@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.7.1.tgz#d101280d406469479ba954cabd872188634033c4" + integrity sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/select" "^3.5.5" + "@react-stately/utils" "^3.8.0" + "@react-types/combobox" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/data@^3.10.3": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.10.3.tgz#4cdbb0f29489e6f74d2ae7ae032930336695eaa0" + integrity sha512-cC9mxCZU4N9GbdOB4g2/J8+W+860GvBd874to0ObSc/XOR4VbuIsxAFIabW5UwmJV+XaqqK4TUBG0C6YScXeWQ== + dependencies: + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/datepicker@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.8.0.tgz#f87eefb4c5dec937b9d5eb101dd4407457ecd0e7" + integrity sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/string" "^3.1.1" + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/datepicker" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/dnd@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.5.tgz#e18c9708133071df911792e85ef6edd2508b3a71" + integrity sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ== + dependencies: + "@react-stately/selection" "^3.14.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/flags@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-stately/flags/-/flags-3.0.0.tgz#c5a73965f8c90e8bf5981adddb4bdbb0ba2f5690" + integrity sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w== + dependencies: + "@swc/helpers" "^0.4.14" + + "@react-stately/grid@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.2.tgz#b2bd8614489a46ad7d0de13551507afd68d95de2" + integrity sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/layout@^3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@react-stately/layout/-/layout-3.13.3.tgz#65ca0ad8a4653122017c68ec2dc3a3d592296d02" + integrity sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/table" "^3.11.2" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/list@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.0.tgz#6b2c66778b687d8c197809059f102029a9bb5079" + integrity sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/menu@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.6.tgz#21861b7cfba579d69272509aef8197d3fad7463a" + integrity sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA== + dependencies: + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/menu" "^3.9.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/numberfield@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.6.2.tgz#2102d956239721fbf629891d2de46920416492fc" + integrity sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ== + dependencies: + "@internationalized/number" "^3.3.0" + "@react-stately/utils" "^3.8.0" + "@react-types/numberfield" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/overlays@^3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.3.tgz#cdfe5edb1ed6ad84fc1022af931586489cb23552" + integrity sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/overlays" "^3.8.3" + "@swc/helpers" "^0.5.0" + + "@react-stately/radio@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.9.1.tgz#c43c88e2bff23d3059b0ea22191337a1d644fe0c" + integrity sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/searchfield@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.4.6.tgz#8d2a394fc20fec559d669e5d63c0a4d7588cb4a0" + integrity sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/searchfield" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/select@^3.5.5": + version "3.5.5" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.5.5.tgz#e0b6dc9635bf46632efeba552e7ff3641c2f581f" + integrity sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/select" "^3.8.4" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/selection@^3.14.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.0.tgz#26a574bf2e35657db1988974df8bd2747b09f5c6" + integrity sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/slider@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.4.tgz#36a3f171077fb0e5bd7af7accdc228f5fd2fbe32" + integrity sha512-tFexbtN50zSo6e1Gi8K9MBfqgOo1eemF/VvFbde3PP9nG+ODcxEIajaYDPlMUuFw5cemJuoKo3+G5NBBn2/AjQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/utils" "^3.21.1" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@react-types/slider" "^3.6.2" + "@swc/helpers" "^0.5.0" + + "@react-stately/table@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.2.tgz#df78442355f3dd086042ad4bf6473a2aaf31f6c1" + integrity sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/flags" "^3.0.0" + "@react-stately/grid" "^3.8.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/tabs@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.1.tgz#61c010c82ba0d6fde7804245742e0569d6b9eafd" + integrity sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag== + dependencies: + "@react-stately/list" "^3.10.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@react-types/tabs" "^3.3.3" + "@swc/helpers" "^0.5.0" + + "@react-stately/toggle@^3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.6.3.tgz#4de25fd458890e37f6c363d058b018e5f11a9882" + integrity sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/tooltip@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.5.tgz#9ba147485d7d7123da91bb417d3722351e90394d" + integrity sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q== + dependencies: + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/tooltip" "^3.4.5" + "@swc/helpers" "^0.5.0" + + "@react-stately/tree@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.3.tgz#d0b3da5db553e64e8f3def5bae45f765f62a3fd8" + integrity sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/utils@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.8.0.tgz#88a45742c58bde804f6cbecb20ea3833915cfdf0" + integrity sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg== + dependencies: + "@swc/helpers" "^0.5.0" + + "@react-stately/virtualizer@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.4.tgz#fab655aa14d30a7241ff5751a0eb80552ac5d751" + integrity sha512-lf3+FDRnyLyY1IhLfwA6GuE/9F3nIEc5p245NkUSN1ngKlXI5PvLHNatiVbONC3wt90abkpMK+WMhu2S/B+4lA== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + + "@react-types/breadcrumbs@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.1.tgz#ec89a2acbae7c9637d087ed0a5f17dda76219d76" + integrity sha512-WWC5pQdWkAzJ2hkx4w7f+waDLLvuD9vowKey+bdLoEmKvdaHNLLVUQPEyFm6SQ5+E3pNBWkNx9a+0S9iW6wa+Q== + dependencies: + "@react-types/link" "^3.5.1" + "@react-types/shared" "^3.21.0" + + "@react-types/button@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.0.tgz#66df80cafaa98aaa34c331e927d21fdf4a0bdc4a" + integrity sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/calendar@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.1.tgz#fa12696b3aae5247b3b1dcf747cbc2c5d5d7c30c" + integrity sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/shared" "^3.21.0" + + "@react-types/checkbox@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.5.2.tgz#f463befdd37bc2c9e5c6febd62e53131e8983fa4" + integrity sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/combobox@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.8.1.tgz#ac9c7abcdde708b09fae78b0dd6d88993f6a8177" + integrity sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/datepicker@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.6.1.tgz#07debffdd611da13f6926266687c22b92624b7ab" + integrity sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/calendar" "^3.4.1" + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + + "@react-types/dialog@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.6.tgz#e874f0896d595e5a7f5924165b0db78e5f62fe9d" + integrity sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + + "@react-types/grid@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.2.tgz#9434d8ed0a80a64e38b2c95f8bbccfa794fd3888" + integrity sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/label@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.8.1.tgz#b076a0fb955051307bfa3fed7e18ce0dc76d8c7b" + integrity sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/link@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.1.tgz#042cd4f7e7929a53657a5432fd3497056c331b34" + integrity sha512-hX2KpjB7wSuJw5Pia63+WEgEql53VfVG1Vu2cTUJDxfrgUtawwHtxB8B0K3cs3jBanq69amgAInEx0FfqYY0uQ== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-types/shared" "^3.21.0" + + "@react-types/listbox@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.5.tgz#c18fbfe38412f7ce42b381fd4aa7bf443dcb6a59" + integrity sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/menu@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.5.tgz#9f67aebda9f491f0e94e2de7a15898c6cabf0772" + integrity sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + + "@react-types/meter@^3.3.5": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.5.tgz#274dc17b4de985063e74272d82c0052e13bb75e8" + integrity sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg== + dependencies: + "@react-types/progress" "^3.5.0" + "@react-types/shared" "^3.21.0" + + "@react-types/numberfield@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.6.1.tgz#da13f9086181a64a7e2e39f500584bdca20097b3" + integrity sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/overlays@^3.8.3": + version "3.8.3" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.3.tgz#47132f08ae3a115273036d98b9441a51d4a4ab09" + integrity sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/progress@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.0.tgz#5fa64897bcf93308c8386a3d0444585cb869e313" + integrity sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/radio@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.5.2.tgz#399e220e2529b2e7c93aa117d39adcca6dc24d1f" + integrity sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/searchfield@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.1.tgz#9e8d9b4ff16749a821cbba20e0069f5d77a8b9f2" + integrity sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ== + dependencies: + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + + "@react-types/select@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.8.4.tgz#564e6d89095d736ed580a733dd8baa7fadab05bc" + integrity sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/shared@^3.21.0": + version "3.21.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.21.0.tgz#1af41fdf7dfbdbd33bbc1210617c43ed0d4ef20c" + integrity sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg== + + "@react-types/slider@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.6.2.tgz#b401bbbd473b62edc394ac3c41ed6df329d111d4" + integrity sha512-LSvna1gpOvBxOBI5I/CYEtkAshWYwPlxE9F/jCaxCa9Q7E9xZp1hFFGY87iQ1A3vQM5SCa5PFStwOvXO7rA55w== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/switch@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.4.2.tgz#8c0a8f8dfcaae29ccd9409a2beaac0d31a131027" + integrity sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A== + dependencies: + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + + "@react-types/table@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.0.tgz#0053ce5b78f2214afaf7e38cdd96a57eecbd2ff9" + integrity sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg== + dependencies: + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + + "@react-types/tabs@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.3.tgz#8601d9cd03c6aa4cca1227df667ae8cedb58839c" + integrity sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/textfield@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.8.1.tgz#433c82d8f696ed77b1d5e71aadc40cbe378b536c" + integrity sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg== + dependencies: + "@react-types/shared" "^3.21.0" + + "@react-types/tooltip@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.5.tgz#f1edf9940bc3cde89ae9d49fda815e16f253dfd5" + integrity sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + + "@remix-run/router@1.11.0": + version "1.11.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.11.0.tgz#e0e45ac3fff9d8a126916f166809825537e9f955" + integrity sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ== + + "@rollup/plugin-commonjs@^24.0.1": + version "24.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz#79e54bd83bb64396761431eee6c44152ef322100" + integrity sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ== + dependencies: + "@rollup/pluginutils" "^5.0.1" + commondir "^1.0.1" + estree-walker "^2.0.2" + glob "^8.0.3" + is-reference "1.2.1" + magic-string "^0.27.0" + + "@rollup/plugin-json@^6.0.0": + version "6.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.0.1.tgz#7e2efcf5ed549963f1444e010611d22f463931c0" + integrity sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw== + dependencies: + "@rollup/pluginutils" "^5.0.1" + + "@rollup/plugin-node-resolve@^15.0.1": + version "15.2.3" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" + integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-builtin-module "^3.2.1" + is-module "^1.0.0" + resolve "^1.22.1" + + "@rollup/plugin-typescript@^11.0.0": + version "11.1.5" + resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz#039c763bf943a5921f3f42be255895e75764cb91" + integrity sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA== + dependencies: + "@rollup/pluginutils" "^5.0.1" + resolve "^1.22.1" + + "@rollup/pluginutils@^5.0.1": + version "5.0.5" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz#bbb4c175e19ebfeeb8c132c2eea0ecb89941a66c" + integrity sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + + "@sapphire/utilities@^3.11.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" + integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== + + "@sentry-internal/tracing@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.77.0.tgz#f3d82486f8934a955b3dd2aa54c8d29586e42a37" + integrity sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw== + dependencies: + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + + "@sentry/browser@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.77.0.tgz#155440f1a0d3a1bbd5d564c28d6b0c9853a51d72" + integrity sha512-nJ2KDZD90H8jcPx9BysQLiQW+w7k7kISCWeRjrEMJzjtge32dmHA8G4stlUTRIQugy5F+73cOayWShceFP7QJQ== + dependencies: + "@sentry-internal/tracing" "7.77.0" + "@sentry/core" "7.77.0" + "@sentry/replay" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + + "@sentry/core@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.77.0.tgz#21100843132beeeff42296c8370cdcc7aa1d8510" + integrity sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg== + dependencies: + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + + "@sentry/integrations@^7.54.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.77.0.tgz#f2717e05cb7c69363316ccd34096b2ea07ae4c59" + integrity sha512-P055qXgBHeZNKnnVEs5eZYLdy6P49Zr77A1aWJuNih/EenzMy922GOeGy2mF6XYrn1YJSjEwsNMNsQkcvMTK8Q== + dependencies: + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + localforage "^1.8.1" + + "@sentry/react@^7.54.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.77.0.tgz#9da14e4b21eae4b5a6306d39bb7c42ef0827d2c2" + integrity sha512-Q+htKzib5em0MdaQZMmPomaswaU3xhcVqmLi2CxqQypSjbYgBPPd+DuhrXKoWYLDDkkbY2uyfe4Lp3yLRWeXYw== + dependencies: + "@sentry/browser" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + hoist-non-react-statics "^3.3.2" + + "@sentry/replay@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.77.0.tgz#21d242c9cd70a7235237216174873fd140b6eb80" + integrity sha512-M9Ik2J5ekl+C1Och3wzLRZVaRGK33BlnBwfwf3qKjgLDwfKW+1YkwDfTHbc2b74RowkJbOVNcp4m8ptlehlSaQ== + dependencies: + "@sentry-internal/tracing" "7.77.0" + "@sentry/core" "7.77.0" + "@sentry/types" "7.77.0" + "@sentry/utils" "7.77.0" + + "@sentry/types@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144" + integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA== + + "@sentry/utils@7.77.0": + version "7.77.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.77.0.tgz#1f88501f0b8777de31b371cf859d13c82ebe1379" + integrity sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g== + dependencies: + "@sentry/types" "7.77.0" + + "@sigstore/bundle@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" + integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + + "@sigstore/protobuf-specs@^0.2.0": + version "0.2.1" + resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" + integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== + + "@sigstore/sign@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" + integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== + dependencies: + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + make-fetch-happen "^11.0.1" + + "@sigstore/tuf@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" + integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== + dependencies: + "@sigstore/protobuf-specs" "^0.2.0" + tuf-js "^1.1.7" + + "@sinclair/typebox@^0.24.1": + version "0.24.51" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" + integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== + + "@sinclair/typebox@^0.27.8": + version "0.27.8" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" + integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== + + "@sinonjs/commons@^1.7.0": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" + integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== + dependencies: + type-detect "4.0.8" + + "@sinonjs/fake-timers@^8.0.1": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" + integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== + dependencies: + "@sinonjs/commons" "^1.7.0" + + "@stablelib/aead@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" + integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== + + "@stablelib/binary@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" + integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== + dependencies: + "@stablelib/int" "^1.0.1" + + "@stablelib/bytes@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" + integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== + + "@stablelib/chacha20poly1305@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" + integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== + dependencies: + "@stablelib/aead" "^1.0.1" + "@stablelib/binary" "^1.0.1" + "@stablelib/chacha" "^1.0.1" + "@stablelib/constant-time" "^1.0.1" + "@stablelib/poly1305" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/chacha@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" + integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/constant-time@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" + integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== + + "@stablelib/ed25519@^1.0.2": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" + integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== + dependencies: + "@stablelib/random" "^1.0.2" + "@stablelib/sha512" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/hash@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" + integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== + + "@stablelib/hkdf@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" + integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== + dependencies: + "@stablelib/hash" "^1.0.1" + "@stablelib/hmac" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/hmac@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" + integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/int@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" + integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== + + "@stablelib/keyagreement@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" + integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== + dependencies: + "@stablelib/bytes" "^1.0.1" + + "@stablelib/poly1305@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" + integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== + dependencies: + "@stablelib/constant-time" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" + integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/sha256@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" + integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/sha512@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" + integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== + dependencies: + "@stablelib/binary" "^1.0.1" + "@stablelib/hash" "^1.0.1" + "@stablelib/wipe" "^1.0.1" + + "@stablelib/wipe@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" + integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== + + "@stablelib/x25519@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" + integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== + dependencies: + "@stablelib/keyagreement" "^1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/wipe" "^1.0.1" + + "@storybook/addon-actions@6.5.16", "@storybook/addon-actions@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" + integrity sha512-aADjilFmuD6TNGz2CRPSupnyiA/IGkPJHDBTqMpsDXTUr8xnuD122xkIhg6UxmCM2y1c+ncwYXy3WPK2xXK57g== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + polished "^4.2.2" + prop-types "^15.7.2" + react-inspector "^5.1.0" + regenerator-runtime "^0.13.7" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + uuid-browser "^3.1.0" + + "@storybook/addon-backgrounds@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.5.16.tgz#a93ea53955f714b4a4432dda1b88942cc87dd390" + integrity sha512-t7qooZ892BruhilFmzYPbysFwpULt/q4zYXNSmKVbAYta8UVvitjcU4F18p8FpWd9WvhiTr0SDlyhNZuzvDfug== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/addon-controls@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.5.16.tgz#5017805b8ca413edf6e9d87b90a9436e79eb5e59" + integrity sha512-kShSGjq1MjmmyL3l8i+uPz6yddtf82mzys0l82VKtcuyjrr5944wYFJ5NTXMfZxrO/U6FeFsfuFZE/k6ex3EMg== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/node-logger" "6.5.16" + "@storybook/store" "6.5.16" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + lodash "^4.17.21" + ts-dedent "^2.0.0" + + "@storybook/addon-docs@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.5.16.tgz#3de912f51fb8e48b9a53b11a5b1cede067acbe70" + integrity sha512-QM9WDZG9P02UvbzLu947a8ZngOrQeAKAT8jCibQFM/+RJ39xBlfm8rm+cQy3dm94wgtjmVkA3mKGOV/yrrsddg== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@jest/transform" "^26.6.2" + "@mdx-js/react" "^1.6.22" + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/docs-tools" "6.5.16" + "@storybook/mdx1-csf" "^0.0.1" + "@storybook/node-logger" "6.5.16" + "@storybook/postinstall" "6.5.16" + "@storybook/preview-web" "6.5.16" + "@storybook/source-loader" "6.5.16" + "@storybook/store" "6.5.16" + "@storybook/theming" "6.5.16" + babel-loader "^8.0.0" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + regenerator-runtime "^0.13.7" + remark-external-links "^8.0.0" + remark-slug "^6.0.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/addon-essentials@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.5.16.tgz#815991366a4a90b60bf0aa4022eb0bb0c2bb536d" + integrity sha512-TeoMr6tEit4Pe91GH6f8g/oar1P4M0JL9S6oMcFxxrhhtOGO7XkWD5EnfyCx272Ok2VYfE58FNBTGPNBVIqYKQ== + dependencies: + "@storybook/addon-actions" "6.5.16" + "@storybook/addon-backgrounds" "6.5.16" + "@storybook/addon-controls" "6.5.16" + "@storybook/addon-docs" "6.5.16" + "@storybook/addon-measure" "6.5.16" + "@storybook/addon-outline" "6.5.16" + "@storybook/addon-toolbars" "6.5.16" + "@storybook/addon-viewport" "6.5.16" + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/node-logger" "6.5.16" + core-js "^3.8.2" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + + "@storybook/addon-interactions@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-6.5.16.tgz#2855fe946c9d8595c3486ae696f1d99e7fca582b" + integrity sha512-DdTtyp3DgB/SpbM1GQgMnuSEBCkadxmj1mUcPk+Wp2iY+fDwsuoRDkr1H9Oe7IvlBKe7ciR79LEjoaABXNdw4w== + dependencies: + "@devtools-ds/object-inspector" "^1.1.2" + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/instrumenter" "6.5.16" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + jest-mock "^27.0.6" + polished "^4.2.2" + ts-dedent "^2.2.0" + + "@storybook/addon-links@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-6.5.16.tgz#cacb20cd0656f0681a874709d428d3f3577828c3" + integrity sha512-P/mmqK57NGXnR0i3d/T5B0rIt0Lg8Yq+qionRr3LK3AwG/4yGnYt4GNomLEknn/eEwABYq1Q/Z1aOpgIhNdq5A== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.16" + "@types/qs" "^6.9.5" + core-js "^3.8.2" + global "^4.4.0" + prop-types "^15.7.2" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + + "@storybook/addon-measure@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-6.5.16.tgz#7f7bfdc0b624fbf18386b20a5e460027bf87115c" + integrity sha512-DMwnXkmM2L6POTh4KaOWvOAtQ2p9Tr1UUNxz6VXiN5cKFohpCs6x0txdLU5WN8eWIq0VFsO7u5ZX34CGCc6gCg== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + global "^4.4.0" + + "@storybook/addon-outline@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-6.5.16.tgz#6985b6a0b0122db36561c81dde2aa851604657b7" + integrity sha512-0du96nha4qltexO0Xq1xB7LeRSbqjC9XqtZLflXG7/X3ABoPD2cXgOV97eeaXUodIyb2qYBbHUfftBeA75x0+w== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + + "@storybook/addon-toolbars@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.5.16.tgz#9de04f9cc64b68d6cb680aa1c4fbf874e11afa32" + integrity sha512-y3PuUKiwOWrAvqx1YdUvArg0UaAwmboXFeR2bkrowk1xcT+xnRO3rML4npFeUl26OQ1FzwxX/cw6nknREBBLEA== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + regenerator-runtime "^0.13.7" + + "@storybook/addon-viewport@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.5.16.tgz#226aa0ab93df68264269eb31adb104e7e48f6c68" + integrity sha512-1Vyqf1U6Qng6TXlf4SdqUKyizlw1Wn6+qW8YeA2q1lbkJqn3UlnHXIp8Q0t/5q1dK5BFtREox3+jkGwbJrzkmA== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + memoizerific "^1.11.3" + prop-types "^15.7.2" + regenerator-runtime "^0.13.7" + + "@storybook/addons@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.16.tgz#07e8f2205f86fa4c9dada719e3e096cb468e3cdd" + integrity sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ== + dependencies: + "@storybook/api" "6.5.16" + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.16" + "@storybook/theming" "6.5.16" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + + "@storybook/api@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.16.tgz#897915b76de05587fd702951d5d836f708043662" + integrity sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA== + dependencies: + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.16" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/builder-webpack4@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.16.tgz#ac468d244835a7f3bd01936398fee47244da35c1" + integrity sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/channel-postmessage" "6.5.16" + "@storybook/channels" "6.5.16" + "@storybook/client-api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/preview-web" "6.5.16" + "@storybook/router" "6.5.16" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.16" + "@storybook/theming" "6.5.16" + "@storybook/ui" "6.5.16" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/webpack" "^4.41.26" + autoprefixer "^9.8.6" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^3.6.0" + file-loader "^6.2.0" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^4.1.6" + glob "^7.1.6" + glob-promise "^3.4.0" + global "^4.4.0" + html-webpack-plugin "^4.0.0" + pnp-webpack-plugin "1.6.4" + postcss "^7.0.36" + postcss-flexbugs-fixes "^4.2.1" + postcss-loader "^4.2.0" + raw-loader "^4.0.2" + stable "^0.1.8" + style-loader "^1.3.0" + terser-webpack-plugin "^4.2.3" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-filter-warnings-plugin "^1.2.1" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.2.2" + + "@storybook/builder-webpack5@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-6.5.16.tgz#2f260e29fbc87f6f3bb3212459048ce37f3fb54e" + integrity sha512-kh8Sofm1sbijaHDWtm0sXabqACHVFjikU/fIkkW786kpjoPIPIec1a+hrLgDsZxMU3I7XapSOaCFzWt6FjVXjg== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/channel-postmessage" "6.5.16" + "@storybook/channels" "6.5.16" + "@storybook/client-api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/preview-web" "6.5.16" + "@storybook/router" "6.5.16" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.16" + "@storybook/theming" "6.5.16" + "@types/node" "^14.0.10 || ^16.0.0" + babel-loader "^8.0.0" + babel-plugin-named-exports-order "^0.0.2" + browser-assert "^1.2.1" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^5.0.1" + fork-ts-checker-webpack-plugin "^6.0.4" + glob "^7.1.6" + glob-promise "^3.4.0" + html-webpack-plugin "^5.0.0" + path-browserify "^1.0.1" + process "^0.11.10" + stable "^0.1.8" + style-loader "^2.0.0" + terser-webpack-plugin "^5.0.3" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "^5.9.0" + webpack-dev-middleware "^4.1.0" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.4.1" + + "@storybook/channel-postmessage@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.16.tgz#06167c0a66c06b2b5f8ff01d1dd436fff8119a15" + integrity sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw== + dependencies: + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + qs "^6.10.0" + telejson "^6.0.8" + + "@storybook/channel-websocket@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.16.tgz#41f69ca9444a4dfbf72580b4696900c5b1d2b817" + integrity sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg== + dependencies: + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + telejson "^6.0.8" + + "@storybook/channels@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.16.tgz#3fb9a3b5666ecb951a2d0cf8b0699b084ef2d3c6" + integrity sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg== + dependencies: + core-js "^3.8.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/channels@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" + integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== + dependencies: + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/global" "^5.0.0" + qs "^6.10.0" + telejson "^7.2.0" + tiny-invariant "^1.3.1" + + "@storybook/client-api@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.16.tgz#13e5a7c3d1f0f951ec4ef51cfcf2c5aafb560e12" + integrity sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/channel-postmessage" "6.5.16" + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.16" + "@types/qs" "^6.9.5" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/client-logger@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.16.tgz#955cc46b389e7151c9eb1585a75e6a0605af61a1" + integrity sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + + "@storybook/client-logger@7.5.3", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" + integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== + dependencies: + "@storybook/global" "^5.0.0" + + "@storybook/components@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.16.tgz#f8dc51213bc08fe32154be964e1e8b0e2f670ed6" + integrity sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA== + dependencies: + "@storybook/client-logger" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + util-deprecate "^1.0.2" + + "@storybook/core-client@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.16.tgz#ed2328fd38c6111fe887f6a91b28d9dc2b17092a" + integrity sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/channel-postmessage" "6.5.16" + "@storybook/channel-websocket" "6.5.16" + "@storybook/client-api" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/preview-web" "6.5.16" + "@storybook/store" "6.5.16" + "@storybook/ui" "6.5.16" + airbnb-js-shims "^2.2.1" + ansi-to-html "^0.6.11" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.21" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" + + "@storybook/core-common@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.16.tgz#db80aa6f220a576a83db821f720e103190a914ae" + integrity sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-private-property-in-object" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" + "@babel/register" "^7.12.1" + "@storybook/node-logger" "6.5.16" + "@storybook/semver" "^7.3.2" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/pretty-hrtime" "^1.0.0" + babel-loader "^8.0.0" + babel-plugin-macros "^3.0.1" + babel-plugin-polyfill-corejs3 "^0.1.0" + chalk "^4.1.0" + core-js "^3.8.2" + express "^4.17.1" + file-system-cache "^1.0.5" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.0.4" + fs-extra "^9.0.1" + glob "^7.1.6" + handlebars "^4.7.7" + interpret "^2.2.0" + json5 "^2.2.3" + lazy-universal-dotenv "^3.0.1" + picomatch "^2.3.0" + pkg-dir "^5.0.0" + pretty-hrtime "^1.0.3" + resolve-from "^5.0.0" + slash "^3.0.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "4" + + "@storybook/core-events@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.16.tgz#b1c265dac755007dae172d9d4b72656c9e5d7bb3" + integrity sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g== + dependencies: + core-js "^3.8.2" + + "@storybook/core-events@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" + integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== + dependencies: + ts-dedent "^2.0.0" + + "@storybook/core-server@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.16.tgz#f40de3413de49388129d29c74e5e48321af03f12" + integrity sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA== + dependencies: + "@discoveryjs/json-ext" "^0.5.3" + "@storybook/builder-webpack4" "6.5.16" + "@storybook/core-client" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/csf-tools" "6.5.16" + "@storybook/manager-webpack4" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.16" + "@storybook/telemetry" "6.5.16" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/node-fetch" "^2.5.7" + "@types/pretty-hrtime" "^1.0.0" + "@types/webpack" "^4.41.26" + better-opn "^2.1.1" + boxen "^5.1.2" + chalk "^4.1.0" + cli-table3 "^0.6.1" + commander "^6.2.1" + compression "^1.7.4" + core-js "^3.8.2" + cpy "^8.1.2" + detect-port "^1.3.0" + express "^4.17.1" + fs-extra "^9.0.1" + global "^4.4.0" + globby "^11.0.2" + ip "^2.0.0" + lodash "^4.17.21" + node-fetch "^2.6.7" + open "^8.4.0" + pretty-hrtime "^1.0.3" + prompts "^2.4.0" + regenerator-runtime "^0.13.7" + serve-favicon "^2.5.0" + slash "^3.0.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + watchpack "^2.2.0" + webpack "4" + ws "^8.2.3" + x-default-browser "^0.4.0" + + "@storybook/core@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.16.tgz#ae994f01327fe81b6e652963c35bac7a74f0da06" + integrity sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA== + dependencies: + "@storybook/core-client" "6.5.16" + "@storybook/core-server" "6.5.16" + + "@storybook/csf-tools@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.16.tgz#367889a3ddb33c93261129104ec2958215ec5459" + integrity sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A== + dependencies: + "@babel/core" "^7.12.10" + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@babel/traverse" "^7.12.11" + "@babel/types" "^7.12.11" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/mdx1-csf" "^0.0.1" + core-js "^3.8.2" + fs-extra "^9.0.1" + global "^4.4.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + + "@storybook/csf@0.0.2--canary.4566f4d.1": + version "0.0.2--canary.4566f4d.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz#dac52a21c40ef198554e71fe4d20d61e17f65327" + integrity sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ== + dependencies: + lodash "^4.17.15" + + "@storybook/csf@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" + integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== + dependencies: + lodash "^4.17.15" + + "@storybook/csf@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.1.tgz#abccc8c3e49aed0a6a7e87beb0d1c262b1921c06" + integrity sha512-4hE3AlNVxR60Wc5KSC68ASYzUobjPqtSKyhV6G+ge0FIXU55N5nTY7dXGRZHQGDBPq+XqchMkIdlkHPRs8nTHg== + dependencies: + type-fest "^2.19.0" + + "@storybook/docs-tools@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.16.tgz#1ec5433eeab63a214d37ffc4660cdaec9704ac39" + integrity sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.16" + core-js "^3.8.2" + doctrine "^3.0.0" + lodash "^4.17.21" + regenerator-runtime "^0.13.7" + + "@storybook/global@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" + integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== + + "@storybook/instrumenter@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-6.5.16.tgz#62acd94e35f1ec403dbc0145b026dfc042ca2f65" + integrity sha512-q8/GaBk8PA/cL7m5OW+ec5t63+Zja9YvYSPGXrYtW17koSv7OnNPmk6RvI7tIHHO0mODBYnaHjF4zQfEGoyR5Q== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + core-js "^3.8.2" + global "^4.4.0" + + "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.3.tgz#de875ba10db3b5a06a1acbc27a8b1f8fb1d875ff" + integrity sha512-p6b+/6ohTCKxWn00bXT8KBqVjXUOxeILnJtLlG83USLQCpI+XVkpmK57HYuydqEwy/1XjG+4S4ntPk9VVz3u7w== + dependencies: + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/global" "^5.0.0" + "@storybook/preview-api" "7.5.3" + + "@storybook/manager-webpack4@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.16.tgz#7033228d38f048ceff3d403ba918d7f206b926a5" + integrity sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.5.16" + "@storybook/core-client" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/theming" "6.5.16" + "@storybook/ui" "6.5.16" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/webpack" "^4.41.26" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + core-js "^3.8.2" + css-loader "^3.6.0" + express "^4.17.1" + file-loader "^6.2.0" + find-up "^5.0.0" + fs-extra "^9.0.1" + html-webpack-plugin "^4.0.0" + node-fetch "^2.6.7" + pnp-webpack-plugin "1.6.4" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + style-loader "^1.3.0" + telejson "^6.0.8" + terser-webpack-plugin "^4.2.3" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-virtual-modules "^0.2.2" + + "@storybook/manager-webpack5@^6.5.8": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/manager-webpack5/-/manager-webpack5-6.5.16.tgz#48b223557d9633614ff8c6e3227c01a57ab4eb55" + integrity sha512-OtxXv8JCe0r/0rE5HxaFicsNsXA+fqZxzokxquFFgrYf/1Jg4d7QX6/pG5wINF+5qInJfVkRG6xhPzv1s5bk9Q== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.5.16" + "@storybook/core-client" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/theming" "6.5.16" + "@storybook/ui" "6.5.16" + "@types/node" "^14.0.10 || ^16.0.0" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + core-js "^3.8.2" + css-loader "^5.0.1" + express "^4.17.1" + find-up "^5.0.0" + fs-extra "^9.0.1" + html-webpack-plugin "^5.0.0" + node-fetch "^2.6.7" + process "^0.11.10" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + style-loader "^2.0.0" + telejson "^6.0.8" + terser-webpack-plugin "^5.0.3" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "^5.9.0" + webpack-dev-middleware "^4.1.0" + webpack-virtual-modules "^0.4.1" + + "@storybook/mdx1-csf@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz#d4184e3f6486fade9f7a6bfaf934d9bc07718d5b" + integrity sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg== + dependencies: + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/preset-env" "^7.12.11" + "@babel/types" "^7.12.11" + "@mdx-js/mdx" "^1.6.22" + "@types/lodash" "^4.14.167" + js-string-escape "^1.0.1" + loader-utils "^2.0.0" + lodash "^4.17.21" + prettier ">=2.2.1 <=2.3.0" + ts-dedent "^2.0.0" + + "@storybook/node-logger@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.16.tgz#d57fd6204c2abfbc297551d98ad5475dd73207cc" + integrity sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg== + dependencies: + "@types/npmlog" "^4.1.2" + chalk "^4.1.0" + core-js "^3.8.2" + npmlog "^5.0.1" + pretty-hrtime "^1.0.3" + + "@storybook/postinstall@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.16.tgz#20aa02fd4513fa0b60ed838b413c46f351f64f60" + integrity sha512-08K2q+qN6pqyPW7PHLCZ5G5Xa6Wosd6t0F16PQ4abX2ItlJLabVoJN5mZ0gm/aeLTjD8QYr8IDvacu4eXh0SVA== + dependencies: + core-js "^3.8.2" + + "@storybook/preview-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" + integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== + dependencies: + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" + "@storybook/csf" "^0.1.0" + "@storybook/global" "^5.0.0" + "@storybook/types" "7.5.3" + "@types/qs" "^6.9.5" + dequal "^2.0.2" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/preview-web@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.16.tgz#1d32a72be25776f9597e33ffc1914f3430fae689" + integrity sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/channel-postmessage" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.16" + ansi-to-html "^0.6.11" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.21" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" + + "@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0": + version "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" + resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.tgz#3103532ff494fb7dc3cf835f10740ecf6a26c0f9" + integrity sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + find-cache-dir "^3.3.1" + flat-cache "^3.0.4" + micromatch "^4.0.2" + react-docgen-typescript "^2.1.1" + tslib "^2.0.0" + + "@storybook/react@^6.5.15": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.5.16.tgz#f7b82ba87f5bb73b4e4e83cce298a98710a88398" + integrity sha512-cBtNlOzf/MySpNLBK22lJ8wFU22HnfTB2xJyBk7W7Zi71Lm7Uxkhv1Pz8HdiQndJ0SlsAAQOWjQYsSZsGkZIaA== + dependencies: + "@babel/preset-flow" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" + "@storybook/addons" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core" "6.5.16" + "@storybook/core-common" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/docs-tools" "6.5.16" + "@storybook/node-logger" "6.5.16" + "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.16" + "@types/estree" "^0.0.51" + "@types/node" "^14.14.20 || ^16.0.0" + "@types/webpack-env" "^1.16.0" + acorn "^7.4.1" + acorn-jsx "^5.3.1" + acorn-walk "^7.2.0" + babel-plugin-add-react-displayname "^0.0.5" + babel-plugin-react-docgen "^4.2.1" + core-js "^3.8.2" + escodegen "^2.0.0" + fs-extra "^9.0.1" + global "^4.4.0" + html-tags "^3.1.0" + lodash "^4.17.21" + prop-types "^15.7.2" + react-element-to-jsx-string "^14.3.4" + react-refresh "^0.11.0" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack ">=4.43.0 <6.0.0" + + "@storybook/router@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.16.tgz#28fb4d34e8219351a40bee1fc94dcacda6e1bd8b" + integrity sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ== + dependencies: + "@storybook/client-logger" "6.5.16" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + + "@storybook/semver@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" + integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== + dependencies: + core-js "^3.6.5" + find-up "^4.1.0" + + "@storybook/source-loader@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.5.16.tgz#b691a024e6ff36bbd1144ecb4a65986f0e149741" + integrity sha512-fyVl4jrM/5JLrb48aqXPu7sTsmySQaVGFp1zfeqvPPlJRFMastDrePm5XGPN7Qjv1wsKmpuBvuweFKOT1pru3g== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + estraverse "^5.2.0" + global "^4.4.0" + loader-utils "^2.0.4" + lodash "^4.17.21" + prettier ">=2.2.1 <=2.3.0" + regenerator-runtime "^0.13.7" + + "@storybook/store@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.16.tgz#b308701293a3a11bfcc766770584495874fd17da" + integrity sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + slash "^3.0.0" + stable "^0.1.8" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + + "@storybook/telemetry@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.16.tgz#b13c8133e02c28e37b7716c987e7414b1ddc5363" + integrity sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA== + dependencies: + "@storybook/client-logger" "6.5.16" + "@storybook/core-common" "6.5.16" + chalk "^4.1.0" + core-js "^3.8.2" + detect-package-manager "^2.0.1" + fetch-retry "^5.0.2" + fs-extra "^9.0.1" + global "^4.4.0" + isomorphic-unfetch "^3.1.0" + nanoid "^3.3.1" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + + "@storybook/testing-library@^0.0.9": + version "0.0.9" + resolved "https://registry.yarnpkg.com/@storybook/testing-library/-/testing-library-0.0.9.tgz#e3d6e8077d58305bb352903e820dcae9306e7a7f" + integrity sha512-X4/Tk7RryB0tZ/9NLUHYTBXW01zRpf6+IhdhqsVl6WOWRyUaIv3zEhr43gQyZhBe4ZZyt5d90FJC9qWmY1oFKg== + dependencies: + "@storybook/client-logger" "^6.4.0 || >=6.5.0-0" + "@storybook/instrumenter" "^6.4.0 || >=6.5.0-0" + "@testing-library/dom" "^8.3.0" + "@testing-library/user-event" "^13.2.1" + ts-dedent "^2.2.0" + + "@storybook/theming@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.16.tgz#b999bdb98945b605b93b9dfdf7408535b701e2aa" + integrity sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ== + dependencies: + "@storybook/client-logger" "6.5.16" + core-js "^3.8.2" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + + "@storybook/types@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" + integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== + dependencies: + "@storybook/channels" "7.5.3" + "@types/babel__core" "^7.0.0" + "@types/express" "^4.7.0" + file-system-cache "2.3.0" + + "@storybook/ui@6.5.16": + version "6.5.16" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.16.tgz#c73bf456e672ecf2370b4365070088487fc0ce57" + integrity sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A== + dependencies: + "@storybook/addons" "6.5.16" + "@storybook/api" "6.5.16" + "@storybook/channels" "6.5.16" + "@storybook/client-logger" "6.5.16" + "@storybook/components" "6.5.16" + "@storybook/core-events" "6.5.16" + "@storybook/router" "6.5.16" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.5.16" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + + "@svgr/babel-plugin-add-jsx-attribute@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" + integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== + + "@svgr/babel-plugin-remove-jsx-attribute@*": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" + integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== + + "@svgr/babel-plugin-remove-jsx-empty-expression@*": + version "8.0.0" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" + integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== + + "@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" + integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== + + "@svgr/babel-plugin-svg-dynamic-title@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" + integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== + + "@svgr/babel-plugin-svg-em-dimensions@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" + integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== + + "@svgr/babel-plugin-transform-react-native-svg@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" + integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== + + "@svgr/babel-plugin-transform-svg-component@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" + integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== + + "@svgr/babel-preset@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" + integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== + 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/core@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" + integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/plugin-jsx" "^6.5.1" + camelcase "^6.2.0" + cosmiconfig "^7.0.1" + + "@svgr/hast-util-to-babel-ast@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" + integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== + dependencies: + "@babel/types" "^7.20.0" + entities "^4.4.0" + + "@svgr/plugin-jsx@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" + integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== + dependencies: + "@babel/core" "^7.19.6" + "@svgr/babel-preset" "^6.5.1" + "@svgr/hast-util-to-babel-ast" "^6.5.1" + svg-parser "^2.0.4" + + "@svgr/plugin-svgo@^6.5.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" + integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== + dependencies: + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + svgo "^2.8.0" + + "@svgr/webpack@^6.1.1": + version "6.5.1" + resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" + integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== + dependencies: + "@babel/core" "^7.19.6" + "@babel/plugin-transform-react-constant-elements" "^7.18.12" + "@babel/preset-env" "^7.19.4" + "@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" + + "@swc/helpers@^0.4.14": + version "0.4.36" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.36.tgz#fcfff76ed52c214f357e8e9d3f37b568908072d9" + integrity sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q== + dependencies: + legacy-swc-helpers "npm:@swc/helpers@=0.4.14" + tslib "^2.4.0" + + "@swc/helpers@^0.5.0": + version "0.5.3" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" + integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== + dependencies: + tslib "^2.4.0" + + "@tauri-apps/api@^1.2.0", "@tauri-apps/api@^1.5.1": + version "1.5.1" + resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.1.tgz#9074476c4323f71351db624e9711c99277cdfb99" + integrity sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA== + + "@tauri-apps/cli-darwin-arm64@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.6.tgz#0d68eaf6fa1b35197a9d4991ac5377e6085a569a" + integrity sha512-NNvG3XLtciCMsBahbDNUEvq184VZmOveTGOuy0So2R33b/6FDkuWaSgWZsR1mISpOuP034htQYW0VITCLelfqg== + + "@tauri-apps/cli-darwin-x64@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.6.tgz#a48e1f66b12c33cf6c9c216865f2e9a3ff18a923" + integrity sha512-nkiqmtUQw3N1j4WoVjv81q6zWuZFhBLya/RNGUL94oafORloOZoSY0uTZJAoeieb3Y1YK0rCHSDl02MyV2Fi4A== + + "@tauri-apps/cli-linux-arm-gnueabihf@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.6.tgz#385cd8054be7722cc07acc2d6d86f8e20c6265ef" + integrity sha512-z6SPx+axZexmWXTIVPNs4Tg7FtvdJl9EKxYN6JPjOmDZcqA13iyqWBQal2DA/GMZ1Xqo3vyJf6EoEaKaliymPQ== + + "@tauri-apps/cli-linux-arm64-gnu@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.6.tgz#bd3f8f61637a1073909cb2d663aa0c6e8e036337" + integrity sha512-QuQjMQmpsCbzBrmtQiG4uhnfAbdFx3nzm+9LtqjuZlurc12+Mj5MTgqQ3AOwQedH3f7C+KlvbqD2AdXpwTg7VA== + + "@tauri-apps/cli-linux-arm64-musl@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.6.tgz#77fb4a804b77447bffba725a4b8b62df45f9ff97" + integrity sha512-8j5dH3odweFeom7bRGlfzDApWVOT4jIq8/214Wl+JeiNVehouIBo9lZGeghZBH3XKFRwEvU23i7sRVjuh2s8mg== + + "@tauri-apps/cli-linux-x64-gnu@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.6.tgz#e70a6c9dd243c2a3fa1fec69de9ebc9abf4dc795" + integrity sha512-gbFHYHfdEGW0ffk8SigDsoXks6USpilF6wR0nqB/JbWzbzFR/sBuLVNQlJl1RKNakyJHu+lsFxGy0fcTdoX8xA== + + "@tauri-apps/cli-linux-x64-musl@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.6.tgz#f25dad778b2da6ab7b2b81f81c0805026d742c33" + integrity sha512-9v688ogoLkeFYQNgqiSErfhTreLUd8B3prIBSYUt+x4+5Kcw91zWvIh+VSxL1n3KCGGsM7cuXhkGPaxwlEh1ug== + + "@tauri-apps/cli-win32-arm64-msvc@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.6.tgz#47d0f359e04d93c1fd0b527e18a56606f3df9bed" + integrity sha512-DRNDXFNZb6y5IZrw+lhTTA9l4wbzO4TNRBAlHAiXUrH+pRFZ/ZJtv5WEuAj9ocVSahVw2NaK5Yaold4NPAxHog== + + "@tauri-apps/cli-win32-ia32-msvc@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.6.tgz#54c7ec152065e8167068411b82748a25a483d948" + integrity sha512-oUYKNR/IZjF4fsOzRpw0xesl2lOjhsQEyWlgbpT25T83EU113Xgck9UjtI7xemNI/OPCv1tPiaM1e7/ABdg5iA== + + "@tauri-apps/cli-win32-x64-msvc@1.5.6": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.6.tgz#963280a4f7001c27d4e4745f302728297c007deb" + integrity sha512-RmEf1os9C8//uq2hbjXi7Vgz9ne7798ZxqemAZdUwo1pv3oLVZSz1/IvZmUHPdy2e6zSeySqWu1D0Y3QRNN+dg== + + "@tauri-apps/cli@^1.0.5", "@tauri-apps/cli@^1.2.2": + version "1.5.6" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.5.6.tgz#5011c9dd3a36dc89073fed7d4cb429d38b37862b" + integrity sha512-k4Y19oVCnt7WZb2TnDzLqfs7o98Jq0tUoVMv+JQSzuRDJqaVu2xMBZ8dYplEn+EccdR5SOMyzaLBJWu38TVK1A== + optionalDependencies: + "@tauri-apps/cli-darwin-arm64" "1.5.6" + "@tauri-apps/cli-darwin-x64" "1.5.6" + "@tauri-apps/cli-linux-arm-gnueabihf" "1.5.6" + "@tauri-apps/cli-linux-arm64-gnu" "1.5.6" + "@tauri-apps/cli-linux-arm64-musl" "1.5.6" + "@tauri-apps/cli-linux-x64-gnu" "1.5.6" + "@tauri-apps/cli-linux-x64-musl" "1.5.6" + "@tauri-apps/cli-win32-arm64-msvc" "1.5.6" + "@tauri-apps/cli-win32-ia32-msvc" "1.5.6" + "@tauri-apps/cli-win32-x64-msvc" "1.5.6" + + "@tauri-apps/tauri-forage@^1.0.0-beta.2": + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/@tauri-apps/tauri-forage/-/tauri-forage-1.0.0-beta.2.tgz#c11b438ba32731dc7b4c8689d9fda4130baadc07" + integrity sha512-aGObWlY8sgEfImt8+Cv4D+hqWhWB4KwPLVRQTv2uPtHSrXpXrvkJ8vTjy+QsT7tGPyVhcLPBchbyGu0JReErSQ== + dependencies: + localforage "^1.7.3" + ramda "^0.26.1" + tweetnacl "^1.0.1" + tweetnacl-util "^0.15.0" + + "@testing-library/dom@^8.0.0", "@testing-library/dom@^8.3.0": + version "8.20.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f" + integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^5.0.1" + aria-query "5.1.3" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.5.0" + pretty-format "^27.0.2" + + "@testing-library/jest-dom@^5.14.1": + version "5.17.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz#5e97c8f9a15ccf4656da00fecab505728de81e0c" + integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== + dependencies: + "@adobe/css-tools" "^4.0.1" + "@babel/runtime" "^7.9.2" + "@types/testing-library__jest-dom" "^5.9.1" + aria-query "^5.0.0" + chalk "^3.0.0" + css.escape "^1.5.1" + dom-accessibility-api "^0.5.6" + lodash "^4.17.15" + redent "^3.0.0" + + "@testing-library/react@^12.0.0": + version "12.1.5" + resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b" + integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg== + dependencies: + "@babel/runtime" "^7.12.5" + "@testing-library/dom" "^8.0.0" + "@types/react-dom" "<18.0.0" + + "@testing-library/user-event@^13.2.1": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + + "@tootallnate/once@1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" + integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== + + "@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== + + "@trysound/sax@0.2.0": + version "0.2.0" + resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" + integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== + + "@tsconfig/node10@^1.0.7": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" + integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== + + "@tsconfig/node12@^1.0.7": + version "1.0.11" + resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" + integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== + + "@tsconfig/node14@^1.0.0": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" + integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== + + "@tsconfig/node16@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" + integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== + + "@tufjs/canonical-json@1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" + integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== + + "@tufjs/models@1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" + integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== + dependencies: + "@tufjs/canonical-json" "1.0.0" + minimatch "^9.0.0" + + "@types/acorn@^4.0.0": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" + integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== + dependencies: + "@types/estree" "*" + + "@types/aria-query@^5.0.1": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.3.tgz#07570ebd25f9b516c910a91f7244052c9b58eabc" + integrity sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA== + + "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" + integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== + dependencies: + "@babel/parser" "^7.20.7" + "@babel/types" "^7.20.7" + "@types/babel__generator" "*" + "@types/babel__template" "*" + "@types/babel__traverse" "*" + + "@types/babel__generator@*": + version "7.6.6" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" + integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== + dependencies: + "@babel/types" "^7.0.0" + + "@types/babel__template@*": + version "7.4.3" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" + integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== + dependencies: + "@babel/parser" "^7.1.0" + "@babel/types" "^7.0.0" + + "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": + version "7.20.3" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" + integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== + dependencies: + "@babel/types" "^7.20.7" + + "@types/big.js@^6.1.6": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.1.tgz#0e5eda9b8ffe33e2cc4540fad6e91a4c7255ca88" + integrity sha512-dKzZVT10m3ELZgYIShPJ+3Os/E1s3aDQS+wr1ne7VCLU/8hc/R+z/+gkm9WabxSkV9E8wJhTl5wC+0fD9nitsw== + + "@types/body-parser@*": + version "1.19.4" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462" + integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA== + dependencies: + "@types/connect" "*" + "@types/node" "*" + + "@types/bonjour@^3.5.9": + version "3.5.12" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8" + integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg== + dependencies: + "@types/node" "*" + + "@types/bs58@^4.0.1": + version "4.0.3" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.3.tgz#0ccc90341c886acb7abeb42c6f848403a6a021af" + integrity sha512-yVMwEsD7S5YU372eUWAmFRmTqF6EUSqs1Tj2X1kD0hiA4YlE33BhC3tELKLVYpZQEc5gLIQX2BAXmJdXaBARXA== + dependencies: + "@types/node" "*" + base-x "^3.0.6" + + "@types/connect-history-api-fallback@^1.3.5": + version "1.5.2" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc" + integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + + "@types/connect@*": + version "3.4.37" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5" + integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q== + dependencies: + "@types/node" "*" + + "@types/d3-array@^3.0.3": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.0.tgz#603b85d0072962bdecaf8391f60eea465c8dc282" + integrity sha512-tjU8juPSfhMnu6mJZPOCVVGba4rZoE0tjHDPb81PYwA8CzbaFscGjgkUM7juUJu6iWA1cCVWNEVwxZ5HN9Jj8Q== + + "@types/d3-color@*": + version "3.1.2" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.2.tgz#7939eed011a908287cd1bcfd11580c17b2ac7f8a" + integrity sha512-At+Ski7dL8Bs58E8g8vPcFJc8tGcaC12Z4m07+p41+DRqnZQcAlp3NfYjLrhNYv+zEyQitU1CUxXNjqUyf+c0g== + + "@types/d3-color@^1": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.4.tgz#d8a270d6fd864977ea339899a0dfb35974da93a4" + integrity sha512-KsjVf5gjylqqZIsRxYPiFQIY8NvmJEmA9nMrJT0yCcpABhvYzhjoCCPCjaYMANp96GBdS4VXRfhHWnCTudDdJg== + + "@types/d3-dsv@*": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.5.tgz#c12df56be81d0b457d167842fa87276d0d6eb880" + integrity sha512-73WZR3QFOaSRVz9iOrebTbTnbo7xjcgS/i0Cq5zy0jMXPO3v/JbkTD3Zqii1eYE6v4EJ78g5VP407rm+p8fdlA== + + "@types/d3-ease@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.1.tgz#ef386d2f28602dba82206888047f97f7f7f7558a" + integrity sha512-VZofjpEt8HWv3nxUAosj5o/+4JflnJ7Bbv07k17VO3T2WRuzGdZeookfaF60iVh5RdhVG49LE5w6LIshVUC6rg== + + "@types/d3-fetch@^3.0.1": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.5.tgz#0bec3763a04d199ad8bce2756b6f6818ee188b32" + integrity sha512-Rc8pb6H0RRLpAV2hEXduykUgcDUOhjSLTLmCIeo6ejzgs4SaITh/EteMb3p5Env3Hqjsqw0fCksyqopHHzMkMg== + dependencies: + "@types/d3-dsv" "*" + + "@types/d3-geo@^1": + version "1.12.6" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.6.tgz#127802904cd656e9a8c45489d3110a1f87fbacb7" + integrity sha512-ZUjOG+unedpNb2IGYau7WdQcoGQjrVnVrpAdJTcIE1g7wD4kR4rHQy7JYPu+5iZ2C8DOXQnbtsyimo2fP2AykA== + dependencies: + "@types/geojson" "*" + + "@types/d3-geo@^3.0.2": + version "3.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.6.tgz#138821c463c67551e1cc13729f0211986c5c3cce" + integrity sha512-wblAES3b+C3hvp4VakwECEKtHquT/xc6K4HOna95LM1j1fd7s7WmU4V+JMQZfKhNCMkV2vWD+ZUgY2Uj6gqfuA== + dependencies: + "@types/geojson" "*" + + "@types/d3-interpolate@^1": + version "1.4.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.4.tgz#cae4c7e7da8649a869cb4f25e62f289b43c86167" + integrity sha512-iZOtsYamYn0qP8f4U7EtQV4JqR/2z0Mp9AxUdPnuC+D8ovmnw/ZFvpoC0mVKJ9eZzrA/fscGr3/R9892F5RRxg== + dependencies: + "@types/d3-color" "^1" + + "@types/d3-interpolate@^3.0.1": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.3.tgz#e10c06c4bf11bd770ed56184a0d76cd516ff4ded" + integrity sha512-6OZ2EIB4lLj+8cUY7I/Cgn9Q+hLdA4DjJHYOQDiHL0SzqS1K9DL5xIOVBSIHgF+tiuO9MU1D36qvdIvRDRPh+Q== + dependencies: + "@types/d3-color" "*" + + "@types/d3-path@*": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.1.tgz#6171c9e388904014764661a37613e3c4ab8df22d" + integrity sha512-blRhp7ki7pVznM8k6lk5iUU9paDbVRVq+/xpf0RRgSJn5gr6SE7RcFtxooYGMBOc1RZiGyqRpVdu5AD0z0ooMA== + + "@types/d3-scale@^4.0.1", "@types/d3-scale@^4.0.2": + version "4.0.6" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.6.tgz#9d221949f37b90b52696ec99f9b1e972d55fe10d" + integrity sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ== + dependencies: + "@types/d3-time" "*" + + "@types/d3-selection@^1": + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.5.tgz#a0f436406ec3586f705fbe5d64cf1b5b28b25119" + integrity sha512-87ZWS/UZ+t1gJ0Ras1iWcyWOxOuzPhPfeEdTN19IyEHK28ssS3KI7orQZ3Eqyijhuvm7vxePh+U0cL79H9g41Q== + + "@types/d3-shape@^3.1.0": + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.4.tgz#748a256d5e499cdfb3e48beca9c557f3ea0ff15c" + integrity sha512-M2/xsWPsjaZc5ifMKp1EBp0gqJG0eO/zlldJNOC85Y/5DGsBQ49gDkRJ2h5GY7ZVD6KUumvZWsylSbvTaJTqKg== + dependencies: + "@types/d3-path" "*" + + "@types/d3-time@*", "@types/d3-time@^3.0.0": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.2.tgz#f4425b2ebcb04495a7b2390da03633ef1a8adbe5" + integrity sha512-kbdRXTmUgNfw5OTE3KZnFQn6XdIc4QGroN5UixgdrXATmYsdlPQS6pEut9tVlIojtzuFD4txs/L+Rq41AHtLpg== + + "@types/d3-timer@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.1.tgz#8dac23292df0e559a3aa459d8efca78a734c3fbe" + integrity sha512-GGTvzKccVEhxmRfJEB6zhY9ieT4UhGVUIQaBzFpUO9OXy2ycAlnPCSJLzmGGgqt3KVjqN3QCQB4g1rsZnHsWhg== + + "@types/d3-zoom@^1": + version "1.8.6" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.6.tgz#3c29d9549789419c55f98f2dccc52349838c5e15" + integrity sha512-MBQ34pRegwb+I59RexzTLTX09QqN1bJlXUd8oTbQjlUOWfuh0Fo0DV/D8Y6Lly+x3rfbVqIP61vdY/LhzQf6DA== + dependencies: + "@types/d3-interpolate" "^1" + "@types/d3-selection" "^1" + + "@types/debug@^4.0.0": + version "4.1.10" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.10.tgz#f23148a6eb771a34c466a4fc28379d8101e84494" + integrity sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA== + dependencies: + "@types/ms" "*" + + "@types/eslint-scope@^3.7.3": + version "3.7.6" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" + integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== + dependencies: + "@types/eslint" "*" + "@types/estree" "*" + + "@types/eslint@*": + version "8.44.6" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" + integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== + dependencies: + "@types/estree" "*" + "@types/json-schema" "*" + + "@types/estree-jsx@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.2.tgz#758bcb4f35f2a970362b2bd2b7021fe2ae6e8509" + integrity sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA== + dependencies: + "@types/estree" "*" + + "@types/estree@*", "@types/estree@^1.0.0": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" + integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== + + "@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + + "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": + version "4.17.39" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8" + integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + "@types/send" "*" + + "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": + version "4.17.20" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433" + integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.33" + "@types/qs" "*" + "@types/serve-static" "*" + + "@types/favicons@5.5.0": + version "5.5.0" + resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" + integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== + dependencies: + "@types/node" "*" + + "@types/flat@^5.0.2": + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.4.tgz#d8262918655d942cb0b79f09020240d5ff668557" + integrity sha512-Qy8SOE+x5F40jebCj4vPoA/Y6J2Zd6h9ihMPYP8U8//dDEOK4Yu0ShOTKqEmWPR+4AdV4sls/VCaR6azEFvKKg== + + "@types/geojson@*", "@types/geojson@^7946.0.8": + version "7946.0.12" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.12.tgz#0307536218d32e6b970bccd1d148b9c4e5b6f10d" + integrity sha512-uK2z1ZHJyC0nQRbuovXFt4mzXDwf27vQeUWNhfKGwRcWW429GOhP8HxUHlM6TLH4bzmlv/HlEjpvJh3JfmGsAA== + + "@types/glob@*": + version "8.1.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" + integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== + dependencies: + "@types/minimatch" "^5.1.2" + "@types/node" "*" + + "@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== + dependencies: + "@types/minimatch" "*" + "@types/node" "*" + + "@types/graceful-fs@^4.1.2": + version "4.1.8" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" + integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== + dependencies: + "@types/node" "*" + + "@types/hast@^2.0.0": + version "2.3.7" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.7.tgz#5e9bd7ab4452d5313aeec9d38fbc193a70f8d810" + integrity sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw== + dependencies: + "@types/unist" "^2" + + "@types/html-minifier-terser@^5.0.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" + integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== + + "@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + + "@types/http-errors@*": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62" + integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== + + "@types/http-proxy@^1.17.8": + version "1.17.13" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465" + integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw== + dependencies: + "@types/node" "*" + + "@types/is-function@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.2.tgz#1f29acd54f5473f0b4822548e27078eac4e450d2" + integrity sha512-Je5TaQzK7H06pt4e88WsjXwRC64EkmxsdqirUI+4GPVMjhs68Dmm8hr+yqf8tmpYlfR6zPlsJC5xs14dlVUehw== + + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" + integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== + + "@types/istanbul-lib-report@*": + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" + integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== + dependencies: + "@types/istanbul-lib-coverage" "*" + + "@types/istanbul-reports@^3.0.0": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" + integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== + dependencies: + "@types/istanbul-lib-report" "*" + + "@types/jest@*": + version "29.5.7" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036" + integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g== + dependencies: + expect "^29.0.0" + pretty-format "^29.0.0" + + "@types/jest@^27.0.1": + version "27.5.2" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" + integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== + dependencies: + jest-matcher-utils "^27.0.0" + pretty-format "^27.0.0" + + "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": + version "7.0.14" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" + integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + + "@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + + "@types/lodash@^4.14.167", "@types/lodash@^4.14.175": + version "4.14.200" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149" + integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q== + + "@types/long@^4.0.1": + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" + integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== + + "@types/luxon@^2.3.2": + version "2.4.0" + resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-2.4.0.tgz#897d3abc23b68d78b69d76a12c21e01eb5adab95" + integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== + + "@types/mdast@^3.0.0": + version "3.0.14" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.14.tgz#0735473a5b35be032b9f2685b7413cbab1b8a639" + integrity sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw== + dependencies: + "@types/unist" "^2" + + "@types/mdx@^2.0.0": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.9.tgz#80971e367bb884350ab5b2ce8fc06b34960170e7" + integrity sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg== + + "@types/mime@*": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91" + integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ== + + "@types/mime@^1": + version "1.3.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9" + integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw== + + "@types/minimatch@*", "@types/minimatch@^5.1.2": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" + integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== + + "@types/minimatch@^3.0.3": + version "3.0.5" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" + integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== + + "@types/minimist@^1.2.0": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.4.tgz#81f886786411c45bba3f33e781ab48bd56bfca2e" + integrity sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ== + + "@types/ms@*": + version "0.7.33" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" + integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== + + "@types/node-fetch@^2.5.7": + version "2.6.8" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.8.tgz#9a2993583975849c2e1f360b6ca2f11755b2c504" + integrity sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA== + dependencies: + "@types/node" "*" + form-data "^4.0.0" + + "@types/node-forge@^1.3.0": + version "1.3.8" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb" + integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg== + dependencies: + "@types/node" "*" + + "@types/node@*", "@types/node@>=13.7.0": + version "20.8.10" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" + integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== + dependencies: + undici-types "~5.26.4" + + "@types/node@10.12.18": + version "10.12.18" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" + integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== + + "@types/node@^13.7.0": + version "13.13.52" + resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" + integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== + + "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": + version "16.18.60" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.60.tgz#0b0f4316906f1bd0e03b640363f67bd4e86958bd" + integrity sha512-ZUGPWx5vKfN+G2/yN7pcSNLkIkXEvlwNaJEd4e0ppX7W2S8XAkdc/37hM4OUNJB9sa0p12AOvGvxL4JCPiz9DA== + + "@types/normalize-package-data@^2.4.0": + version "2.4.3" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" + integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== + + "@types/npmlog@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.5.tgz#41f1b95437f9c86cbb326bb07f0d5683f905bf4f" + integrity sha512-Fl3TEbwPoR7V1z6CMJ18whXOUkOYqF5eCkGKTir2VuevdLYUmcwj9mQdvXzuY0oagZBbsy0J7df41jn+ZcwGRA== + dependencies: + "@types/node" "*" + + "@types/parse-json@^4.0.0": + version "4.0.1" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" + integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== + + "@types/parse5@^5.0.0": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + + "@types/prettier@^2.1.5": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" + integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== + + "@types/pretty-hrtime@^1.0.0": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.2.tgz#9b6e102bc2e1eea1c1c7fadf144483ce2687f233" + integrity sha512-vyv9knII8XeW8TnXDcGH7HqG6FeR56ESN6ExM34d/U8Zvs3xuG34euV6CVyB7KEYI7Ts4lQM8b4NL72e7UadnA== + + "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.9": + version "15.7.9" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" + integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== + + "@types/qrcode.react@^1.0.2": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.4.tgz#4e6739769a21ee6072bceaab3ec0c866c6a79a17" + integrity sha512-O35T9AJk0wg7ffkgpSQ4Zr7I7eEfEsTCD5u7V2dsvYnZLfUpQz2rLg5ZG2FM/zLmOF4sEE0FY6mxT9WleUDb3Q== + dependencies: + "@types/react" "*" + + "@types/qs@*", "@types/qs@^6.9.5": + version "6.9.9" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" + integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== + + "@types/range-parser@*": + version "1.2.6" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a" + integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA== + + "@types/react-dom@<18.0.0": + version "17.0.22" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.22.tgz#34317e08be27b33fa9e7cdb56125b22538261bad" + integrity sha512-wHt4gkdSMb4jPp1vc30MLJxoWGsZs88URfmt3FRXoOEYrrqK3I8IuZLE/uFBb4UT6MRfI0wXFu4DS7LS0kUC7Q== + dependencies: + "@types/react" "^17" + + "@types/react-dom@^18.0.10": + version "18.2.14" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" + integrity sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ== + dependencies: + "@types/react" "*" + + "@types/react-simple-maps@^1.0.6": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/react-simple-maps/-/react-simple-maps-1.0.8.tgz#a21beb16cbeeadcb093a47de7888db64a2f103aa" + integrity sha512-gNXpQor+H0CCjp8GVNUeeTV+iDPdqFuCDIlYHH17KZ/tVHK1WaRIZl+s2ZnPCVQo27nEnRgU3GQxYbOYxXxgNQ== + dependencies: + "@types/d3-geo" "^1" + "@types/d3-zoom" "^1" + "@types/geojson" "*" + "@types/react" "*" + + "@types/react-tooltip@^4.2.4": + version "4.2.4" + resolved "https://registry.yarnpkg.com/@types/react-tooltip/-/react-tooltip-4.2.4.tgz#d0acad2a3061806e10aab91dd26a95a77fd35125" + integrity sha512-UzjzmgY/VH3Str6DcAGTLMA1mVVhGOyARNTANExrirtp+JgxhaIOVDxq4TIRmpSi4voLv+w4HA9CC5GvhhCA0A== + dependencies: + react-tooltip "*" + + "@types/react-transition-group@^4.4.8": + version "4.4.8" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" + integrity sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg== + dependencies: + "@types/react" "*" + + "@types/react@*", "@types/react@^18.0.26": + version "18.2.36" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.36.tgz#bc68ffb4408e5d0c419b0760b2eaeec70aeeedb3" + integrity sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + + "@types/react@^17": + version "17.0.69" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.69.tgz#245a0cf2f5b0fb1d645691d3083e3c7d4409b98f" + integrity sha512-klEeru//GhiQvXUBayz0Q4l3rKHWsBR/EUOhOeow6hK2jV7MlO44+8yEk6+OtPeOlRfnpUnrLXzGK+iGph5aeg== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + + "@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + + "@types/retry@0.12.0": + version "0.12.0" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" + integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== + + "@types/scheduler@*": + version "0.16.5" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" + integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== + + "@types/semver@^7.3.12", "@types/semver@^7.3.8": + version "7.5.4" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" + integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + + "@types/send@*": + version "0.17.3" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b" + integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + + "@types/serve-index@^1.9.1": + version "1.9.3" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9" + integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg== + dependencies: + "@types/express" "*" + + "@types/serve-static@*", "@types/serve-static@^1.13.10": + version "1.15.4" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2" + integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw== + dependencies: + "@types/http-errors" "*" + "@types/mime" "*" + "@types/node" "*" + + "@types/sockjs@^0.3.33": + version "0.3.35" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21" + integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw== + dependencies: + "@types/node" "*" + + "@types/source-list-map@*": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.4.tgz#a3d4e4791606f40a833ab1caf41f77463c8d72ff" + integrity sha512-Kdfm7Sk5VX8dFW7Vbp18+fmAatBewzBILa1raHYxrGEFXT0jNl9x3LWfuW7bTbjEKFNey9Dfkj/UzT6z/NvRlg== + + "@types/stack-utils@^2.0.0": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" + integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== + + "@types/tapable@^1", "@types/tapable@^1.0.5": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.10.tgz#5203aad08455c6988f7b2347715023e3935b1056" + integrity sha512-q8F20SdXG5fdVJQ5yxsVlH+f+oekP42QeHv4s5KlrxTMT0eopXn7ol1rhxMcksf8ph7XNv811iVDE2hOpUvEPg== + + "@types/testing-library__jest-dom@^5.9.1": + version "5.14.9" + resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466" + integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== + dependencies: + "@types/jest" "*" + + "@types/topojson-client@^3.1.0": + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.3.tgz#d710e90f0a4a25bbdbf4fc0c1863f9a6b5023e26" + integrity sha512-liC+dHCxoqQy5bbJMsF59Cx1WZZwbcT084v/5bdp3NWSFUuzQpsm4gbLQh+wlv58Mng4jCsO4p8hWelqGlb7rg== + dependencies: + "@types/geojson" "*" + "@types/topojson-specification" "*" + + "@types/topojson-specification@*": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.4.tgz#df2d2738a11bacda3b88f5b4630e3da80a12a609" + integrity sha512-LG/a8kJi4X6MsFhZKiBAIC/a+yCFtjkHsDMwuQqSoB1az8D2bR2xRKU3aczizfcqdt2lVqnS+aJBFMrO+rO5Aw== + dependencies: + "@types/geojson" "*" + + "@types/uglify-js@*": + version "3.17.3" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.3.tgz#784efb40320d248588e1748dd12e1f43733f1416" + integrity sha512-ToldSfJ6wxO21cakcz63oFD1GjqQbKzhZCD57eH7zWuYT5UEZvfUoqvrjX5d+jB9g4a/sFO0n6QSVzzn5sMsjg== + dependencies: + source-map "^0.6.1" + + "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.9" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.9.tgz#72e164381659a49557b0a078b28308f2c6a3e1ce" + integrity sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ== + + "@types/uuid@^8.3.4": + version "8.3.4" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" + integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== + + "@types/webpack-env@^1.16.0": + version "1.18.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f" + integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q== + + "@types/webpack-sources@*": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.2.tgz#6e6027cad8b54d2a4e5735df49af559bb4de2db0" + integrity sha512-acCzhuVe+UJy8abiSFQWXELhhNMZjQjQKpLNEi1pKGgKXZj0ul614ATcx4kkhunPost6Xw+aCq8y8cn1/WwAiA== + dependencies: + "@types/node" "*" + "@types/source-list-map" "*" + source-map "^0.7.3" + + "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": + version "4.41.35" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.35.tgz#32903809685caf87ea612e4e74577874359c3749" + integrity sha512-XRC6HLGHtNfN8/xWeu1YUQV1GSE+28q8lSqvcJ+0xt/zW9Wmn4j9pCSvaXPyRlCKrl5OuqECQNEJUy2vo8oWqg== + dependencies: + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + anymatch "^3.0.0" + source-map "^0.6.0" + + "@types/ws@^8.5.5": + version "8.5.8" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" + integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== + dependencies: + "@types/node" "*" + + "@types/yargs-parser@*": + version "21.0.2" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" + integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== + + "@types/yargs@^15.0.0": + version "15.0.17" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.17.tgz#bea870ba551b43831bfaa75de2e4a3849c39322b" + integrity sha512-cj53I8GUcWJIgWVTSVe2L7NJAB5XWGdsoMosVvUgv1jEnMbAcsbaCzt1coUcyi8Sda5PgTWAooG8jNyDTD+CWA== + dependencies: + "@types/yargs-parser" "*" + + "@types/yargs@^16.0.0": + version "16.0.7" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.7.tgz#b0d0502cb5f6c17994df72a600049f10bbf17203" + integrity sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg== + dependencies: + "@types/yargs-parser" "*" + + "@types/yargs@^17.0.8": + version "17.0.29" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" + integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== + dependencies: + "@types/yargs-parser" "*" + + "@types/zxcvbn@^4.4.1": + version "4.4.3" + resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.3.tgz#c323d8bf07673a782ef07950d4b6a878e56181fe" + integrity sha512-AxZBi8J3V3lm+f2Vgg06D8y0womXpLf3ZEDYeLPGGK0ydR724sQH83T5tYgN+CN6VTRnAlevFKJkWTecCnk8ug== + + "@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.7.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" + integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== + dependencies: + "@eslint-community/regexpp" "^4.4.0" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/type-utils" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + graphemer "^1.4.0" + ignore "^5.2.0" + natural-compare-lite "^1.4.0" + semver "^7.3.7" + tsutils "^3.21.0" + + "@typescript-eslint/experimental-utils@^5.3.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" + integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== + dependencies: + "@typescript-eslint/utils" "5.62.0" + + "@typescript-eslint/parser@^5.13.0", "@typescript-eslint/parser@^5.7.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" + integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== + dependencies: + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + debug "^4.3.4" + + "@typescript-eslint/scope-manager@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" + integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + + "@typescript-eslint/type-utils@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" + integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== + dependencies: + "@typescript-eslint/typescript-estree" "5.62.0" + "@typescript-eslint/utils" "5.62.0" + debug "^4.3.4" + tsutils "^3.21.0" + + "@typescript-eslint/types@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" + integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== + + "@typescript-eslint/typescript-estree@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" + integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== + dependencies: + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/visitor-keys" "5.62.0" + debug "^4.3.4" + globby "^11.1.0" + is-glob "^4.0.3" + semver "^7.3.7" + tsutils "^3.21.0" + + "@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" + integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@types/json-schema" "^7.0.9" + "@types/semver" "^7.3.12" + "@typescript-eslint/scope-manager" "5.62.0" + "@typescript-eslint/types" "5.62.0" + "@typescript-eslint/typescript-estree" "5.62.0" + eslint-scope "^5.1.1" + semver "^7.3.7" + + "@typescript-eslint/visitor-keys@5.62.0": + version "5.62.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" + integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== + dependencies: + "@typescript-eslint/types" "5.62.0" + eslint-visitor-keys "^3.3.0" + + "@ungap/structured-clone@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" + integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== + + "@vanilla-extract/css-utils@^0.1.3": + version "0.1.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css-utils/-/css-utils-0.1.3.tgz#cadeb6bc563547b20e9b903647d8b334d3a79ef8" + integrity sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw== + + "@vanilla-extract/css@^1.12.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.13.0.tgz#85f521d428f55b0e9599675033caba81194cc6c0" + integrity sha512-JFFBXhnJrPlGqHBabagXqo5ghXw9mtV270ycIGyLDZG8NAK5eRwAYkMowAxuzK7wZSm67GnETWYB7b0AUmyttg== + dependencies: + "@emotion/hash" "^0.9.0" + "@vanilla-extract/private" "^1.0.3" + ahocorasick "1.0.2" + chalk "^4.1.1" + css-what "^6.1.0" + cssesc "^3.0.0" + csstype "^3.0.7" + deep-object-diff "^1.1.9" + deepmerge "^4.2.2" + media-query-parser "^2.0.2" + outdent "^0.8.0" + + "@vanilla-extract/dynamic@^2.0.3": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.0.3.tgz#44b4e018cbdfb6af3d27e73c78b38617dfe419ad" + integrity sha512-Rglfw2gXAYiBzAQ4jgUG7rBgE2c88e/zcG27ZVoIqMHVq56wf2C1katGMm1yFMNBgzqM7oBNYzz4YOMzznydkg== + dependencies: + "@vanilla-extract/private" "^1.0.3" + + "@vanilla-extract/private@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" + integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== + + "@vanilla-extract/recipes@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.4.0.tgz#7bb2edb0757b6f40c244d72569da7f74d6afa427" + integrity sha512-gFgB7BofUYbtbxINHK6DhMv1JDFDXp/YI/Xm+cqKar+1I/2dfxPepeDxSexL6YB4ftfeaDw8Kn5zydMvHcGOEQ== + + "@walletconnect/core@2.10.4": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.4.tgz#da9396b56f63806c165389cbf98d2373d36854df" + integrity sha512-MGdw5a4dIlQFPxVHEw2neIpHPAw3gtrsJYyUqm6rI+1c1SfmZyOPCaYTr6zPU2cnoWQUjv2ePMLeO/JKy3Yh5g== + dependencies: + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-provider" "1.0.13" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/jsonrpc-ws-connection" "1.0.13" + "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/relay-auth" "^1.0.4" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/utils" "2.10.4" + events "^3.3.0" + lodash.isequal "4.5.0" + uint8arrays "^3.1.0" + + "@walletconnect/environment@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" + integrity sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg== + dependencies: + tslib "1.14.1" + + "@walletconnect/events@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" + integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== + dependencies: + keyvaluestorage-interface "^1.0.0" + tslib "1.14.1" + + "@walletconnect/heartbeat@1.2.1": + version "1.2.1" + resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" + integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" + + "@walletconnect/jsonrpc-provider@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" + integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.8" + "@walletconnect/safe-json" "^1.0.2" + tslib "1.14.1" + + "@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": + version "1.0.3" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" + integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== + dependencies: + keyvaluestorage-interface "^1.0.0" + tslib "1.14.1" + + "@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.8": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" + integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== + dependencies: + "@walletconnect/environment" "^1.0.1" + "@walletconnect/jsonrpc-types" "^1.0.3" + tslib "1.14.1" + + "@walletconnect/jsonrpc-ws-connection@1.0.13": + version "1.0.13" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.13.tgz#23b0cdd899801bfbb44a6556936ec2b93ef2adf4" + integrity sha512-mfOM7uFH4lGtQxG+XklYuFBj6dwVvseTt5/ahOkkmpcAEgz2umuzu7fTR+h5EmjQBdrmYyEBOWADbeaFNxdySg== + dependencies: + "@walletconnect/jsonrpc-utils" "^1.0.6" + "@walletconnect/safe-json" "^1.0.2" + events "^3.3.0" + tslib "1.14.1" + ws "^7.5.1" + + "@walletconnect/keyvaluestorage@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz#92f5ca0f54c1a88a093778842ce0c874d86369c8" + integrity sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ== + dependencies: + safe-json-utils "^1.1.1" + tslib "1.14.1" + + "@walletconnect/logger@^2.0.1": + version "2.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.0.1.tgz#7f489b96e9a1ff6bf3e58f0fbd6d69718bf844a8" + integrity sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ== + dependencies: + pino "7.11.0" + tslib "1.14.1" + + "@walletconnect/relay-api@^1.0.9": + version "1.0.9" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" + integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== + dependencies: + "@walletconnect/jsonrpc-types" "^1.0.2" + tslib "1.14.1" + + "@walletconnect/relay-auth@^1.0.4": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" + integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== + dependencies: + "@stablelib/ed25519" "^1.0.2" + "@stablelib/random" "^1.0.1" + "@walletconnect/safe-json" "^1.0.1" + "@walletconnect/time" "^1.0.2" + tslib "1.14.1" + uint8arrays "^3.0.0" + + "@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" + integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== + dependencies: + tslib "1.14.1" + + "@walletconnect/sign-client@^2.9.0": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.4.tgz#4e3b14ebe900472874f4cae5f53c74a6077c85da" + integrity sha512-C5VHkK59/DQNrJS91UXLn5OSr0drXHkKjajhl2a9hb3h6kxuSdlWbyC0yRPKT1sD0fQho8+EWZHBiV063yBePw== + dependencies: + "@walletconnect/core" "2.10.4" + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/utils" "2.10.4" + events "^3.3.0" + + "@walletconnect/time@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" + integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== + dependencies: + tslib "1.14.1" + + "@walletconnect/types@2.10.4": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.4.tgz#23f6e4bd785671812dc6ea96848a6bd7ea78f038" + integrity sha512-eQpOElyiwJp3tepuOS3TS9dXTl9jVVlrC3iVA8bytnbLagkAUxmiv/s7PyDFx+ndXwQVh8PFBkWg1oxGwgCSBA== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + + "@walletconnect/utils@2.10.4", "@walletconnect/utils@^2.9.0": + version "2.10.4" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.4.tgz#5f17938e7ea481541ec2dbae0df5cd494c72523f" + integrity sha512-XbrKgnQ0hC9DC9wjFb468MEYMoJxnCVmOj2gi01DA4FSr8fJi7wwNRUnlnZzLWrUWrHuaPReYe4PgBAgIv363g== + dependencies: + "@stablelib/chacha20poly1305" "1.0.1" + "@stablelib/hkdf" "1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/sha256" "1.0.1" + "@stablelib/x25519" "^1.0.3" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.10.4" + "@walletconnect/window-getters" "^1.0.1" + "@walletconnect/window-metadata" "^1.0.1" + detect-browser "5.3.0" + query-string "7.1.3" + uint8arrays "^3.1.0" + + "@walletconnect/window-getters@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" + integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== + dependencies: + tslib "1.14.1" + + "@walletconnect/window-metadata@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" + integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== + dependencies: + "@walletconnect/window-getters" "^1.0.1" + tslib "1.14.1" + + "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" + integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== + dependencies: + "@webassemblyjs/helper-numbers" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + + "@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + + "@webassemblyjs/floating-point-hex-parser@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" + integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== + + "@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + + "@webassemblyjs/helper-api-error@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" + integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== + + "@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + + "@webassemblyjs/helper-buffer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" + integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== + + "@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + + "@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + + "@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + + "@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + + "@webassemblyjs/helper-numbers@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" + integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== + dependencies: + "@webassemblyjs/floating-point-hex-parser" "1.11.6" + "@webassemblyjs/helper-api-error" "1.11.6" + "@xtuc/long" "4.2.2" + + "@webassemblyjs/helper-wasm-bytecode@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" + integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== + + "@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + + "@webassemblyjs/helper-wasm-section@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" + integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + + "@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + + "@webassemblyjs/ieee754@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" + integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + + "@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + + "@webassemblyjs/leb128@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" + integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== + dependencies: + "@xtuc/long" "4.2.2" + + "@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + + "@webassemblyjs/utf8@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" + integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== + + "@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + + "@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + + "@webassemblyjs/wasm-edit@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" + integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/helper-wasm-bytecode" "1.11.6" + "@webassemblyjs/helper-wasm-section" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-opt" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + "@webassemblyjs/wast-printer" "1.11.6" + + "@webassemblyjs/wasm-gen@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" + integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== + dependencies: + "@webassemblyjs/ast" "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/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + + "@webassemblyjs/wasm-opt@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" + integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@webassemblyjs/helper-buffer" "1.11.6" + "@webassemblyjs/wasm-gen" "1.11.6" + "@webassemblyjs/wasm-parser" "1.11.6" + + "@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + + "@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" + integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@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/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + + "@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + + "@webassemblyjs/wast-printer@1.11.6": + version "1.11.6" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" + integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== + dependencies: + "@webassemblyjs/ast" "1.11.6" + "@xtuc/long" "4.2.2" + + "@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + + "@webpack-cli/configtest@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" + integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== + + "@webpack-cli/info@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" + integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== + dependencies: + envinfo "^7.7.3" + + "@webpack-cli/serve@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" + integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== + + "@xtuc/ieee754@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" + integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== + + "@xtuc/long@4.2.2": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" + integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== + + "@yarnpkg/lockfile@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" + integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== + + "@yarnpkg/parsers@3.0.0-rc.46": + version "3.0.0-rc.46" + resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" + integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== + dependencies: + js-yaml "^3.10.0" + tslib "^2.4.0" + + "@zkochan/js-yaml@0.0.6": + version "0.0.6" + resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" + integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== + dependencies: + argparse "^2.0.1" + + JSONStream@^1.3.5: + version "1.3.5" + resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" + integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== + dependencies: + jsonparse "^1.2.0" + through ">=2.2.7 <3" + + abab@^2.0.3, abab@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" + integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== + + abbrev@1, abbrev@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== + + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + + acorn-globals@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" + integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== + dependencies: + acorn "^7.1.1" + acorn-walk "^7.1.1" + + acorn-import-assertions@^1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" + integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== + + acorn-jsx@^5.0.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" + integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== + + acorn-walk@^7.1.1, acorn-walk@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + + acorn-walk@^8.1.1: + version "8.3.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" + integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== + + acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + + acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + + acorn@^8.0.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + version "8.11.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" + integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== + + add-stream@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" + integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== + + address@^1.0.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" + integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== + + agent-base@6, agent-base@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" + integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== + dependencies: + debug "4" + + agentkeepalive@^4.2.1: + version "4.5.0" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" + integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== + dependencies: + humanize-ms "^1.2.1" + + aggregate-error@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" + integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== + dependencies: + clean-stack "^2.0.0" + indent-string "^4.0.0" + + ahocorasick@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/ahocorasick/-/ahocorasick-1.0.2.tgz#9eee93aef9d02bfb476d9b648d9b7a40ef2fd500" + integrity sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA== + + airbnb-js-shims@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" + integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + array.prototype.flatmap "^1.2.1" + es5-shim "^4.5.13" + es6-shim "^0.35.5" + function.prototype.name "^1.1.0" + globalthis "^1.0.0" + object.entries "^1.1.0" + object.fromentries "^2.0.0 || ^1.0.0" + object.getownpropertydescriptors "^2.0.3" + object.values "^1.1.0" + promise.allsettled "^1.0.0" + promise.prototype.finally "^3.1.0" + string.prototype.matchall "^4.0.0 || ^3.0.1" + string.prototype.padend "^3.0.0" + string.prototype.padstart "^3.0.0" + symbol.prototype.description "^1.0.0" + + ajv-errors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" + integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== + + ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== + dependencies: + ajv "^8.0.0" + + ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" + integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== + + ajv-keywords@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + + ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: + version "6.12.6" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" + 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" + + ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: + version "8.12.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" + 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" + + animejs@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.1.tgz#de9fe2e792f44a777a7fdf6ae160e26604b0cdda" + integrity sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A== + + ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" + + ansi-colors@4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" + integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== + + ansi-colors@^3.0.0: + version "3.2.4" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" + integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== + + ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + + ansi-escapes@^4.2.1: + version "4.3.2" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" + integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== + dependencies: + type-fest "^0.21.3" + + ansi-html-community@0.0.8, ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== + + ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== + + ansi-regex@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" + integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== + + ansi-regex@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" + integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== + + ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== + dependencies: + color-convert "^1.9.0" + + ansi-styles@^4.0.0, ansi-styles@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" + integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== + dependencies: + color-convert "^2.0.1" + + ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + + ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + + ansi-to-html@^0.6.11: + version "0.6.15" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" + integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== + dependencies: + entities "^2.0.0" + + anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + + anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: + version "3.1.3" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" + integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + + app-root-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" + integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== + + "aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + + aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + + are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + + are-we-there-yet@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" + integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + + arg@^4.1.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" + integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== + + argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + + argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + + aria-query@5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" + integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== + dependencies: + deep-equal "^2.0.5" + + aria-query@^5.0.0, aria-query@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" + integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== + dependencies: + dequal "^2.0.3" + + arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== + + arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== + + arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + + array-buffer-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" + integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== + dependencies: + call-bind "^1.0.2" + is-array-buffer "^3.0.1" + + array-differ@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" + integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== + + array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== + + array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== + + array-flatten@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" + integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== + + array-ify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" + integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== + + array-includes@^3.0.3, array-includes@^3.1.6, array-includes@^3.1.7: + version "3.1.7" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" + integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-string "^1.0.7" + + array-union@^1.0.1, array-union@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== + dependencies: + array-uniq "^1.0.1" + + array-union@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" + integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== + + array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== + + array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + + array.prototype.findlastindex@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" + integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + + array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" + integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + + array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" + integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + + array.prototype.map@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.6.tgz#6a3d23f7192b2066eb97666ccc34118cb8163950" + integrity sha512-nK1psgF2cXqP3wSyCSq0Hc7zwNq3sfljQqaG27r/7a7ooNUnn5nGq6yYWyks9jMO5EoFQ0ax80hSg6oXSRNXaw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + + array.prototype.reduce@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" + integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + + array.prototype.tosorted@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" + integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + es-shim-unscopables "^1.0.0" + get-intrinsic "^1.2.1" + + arraybuffer.prototype.slice@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" + integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + is-array-buffer "^3.0.2" + is-shared-array-buffer "^1.0.2" + + arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== + + arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + + asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + + assert@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76" + integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A== + dependencies: + object.assign "^4.1.4" + util "^0.10.4" + + assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + + ast-types-flow@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" + integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== + + ast-types@^0.14.2: + version "0.14.2" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" + integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== + dependencies: + tslib "^2.0.1" + + astral-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" + integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== + + astring@^1.8.0: + version "1.8.6" + resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.6.tgz#2c9c157cf1739d67561c56ba896e6948f6b93731" + integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== + + async-each@^1.0.1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" + integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== + + async@^3.2.3: + version "3.2.5" + resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" + integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== + + asynciterator.prototype@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" + integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== + dependencies: + has-symbols "^1.0.3" + + asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== + + at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + + atob@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" + integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== + + atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + + author-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" + integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g== + + autoprefixer@^9.8.6: + version "9.8.8" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" + integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== + dependencies: + browserslist "^4.12.0" + caniuse-lite "^1.0.30001109" + normalize-range "^0.1.2" + num2fraction "^1.2.2" + picocolors "^0.2.1" + postcss "^7.0.32" + postcss-value-parser "^4.1.0" + + available-typed-arrays@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" + integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== + + axe-core@=4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" + integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== + + axios@^0.21.1, axios@^0.21.2: + version "0.21.4" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" + integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== + dependencies: + follow-redirects "^1.14.0" + + axios@^1.0.0, axios@^1.3.3: + version "1.6.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" + integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + + axobject-query@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" + integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== + dependencies: + dequal "^2.0.3" + + b4a@^1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" + integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== + + babel-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" + integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== + dependencies: + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__core" "^7.1.14" + babel-plugin-istanbul "^6.1.1" + babel-preset-jest "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + slash "^3.0.0" + + babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" + integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== + dependencies: + find-cache-dir "^3.3.1" + loader-utils "^2.0.0" + make-dir "^3.1.0" + schema-utils "^2.6.5" + + babel-plugin-add-react-displayname@^0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz#339d4cddb7b65fd62d1df9db9fe04de134122bd5" + integrity sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw== + + babel-plugin-apply-mdx-type-prop@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" + integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + "@mdx-js/util" "1.6.22" + + babel-plugin-extract-import-names@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" + integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + + babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + + babel-plugin-jest-hoist@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" + integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== + dependencies: + "@babel/template" "^7.3.3" + "@babel/types" "^7.3.3" + "@types/babel__core" "^7.0.0" + "@types/babel__traverse" "^7.0.6" + + babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + + babel-plugin-named-exports-order@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" + integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== + + babel-plugin-polyfill-corejs2@^0.4.6: + version "0.4.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" + integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== + dependencies: + "@babel/compat-data" "^7.22.6" + "@babel/helper-define-polyfill-provider" "^0.4.3" + semver "^6.3.1" + + babel-plugin-polyfill-corejs3@^0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" + integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.1.5" + core-js-compat "^3.8.1" + + babel-plugin-polyfill-corejs3@^0.8.5: + version "0.8.6" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" + integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + core-js-compat "^3.33.1" + + babel-plugin-polyfill-regenerator@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" + integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.4.3" + + babel-plugin-react-docgen@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" + integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== + dependencies: + ast-types "^0.14.2" + lodash "^4.17.15" + react-docgen "^5.0.0" + + babel-plugin-root-import@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-5.1.0.tgz#80ea1cd5945b463a5e3f7e204a69478c573e328c" + integrity sha512-9VYUlnHtM7zjM9vM3kFClUDH7jjhqnvQwxWYGP18EciPsPZYZD9wGqVGwry6gQv0UdZS0+WmbPSlKSjKv1wZFw== + dependencies: + slash "^1.0.0" + + babel-plugin-root-import@^6.6.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-6.6.0.tgz#85940840f308a8c292f66ca0b5bdd314046273ed" + integrity sha512-SPzVOHd7nDh5loZwZBxtX/oOu1MXeKjTkz+1VnnzLWC0dk8sJIGC2IDQ2uWIBjE5mUtXlQ35MTHSqN0Xn7qHrg== + dependencies: + slash "^3.0.0" + + babel-preset-current-node-syntax@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" + integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== + dependencies: + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-bigint" "^7.8.3" + "@babel/plugin-syntax-class-properties" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.8.3" + "@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-top-level-await" "^7.8.3" + + babel-preset-jest@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" + integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== + dependencies: + babel-plugin-jest-hoist "^27.5.1" + babel-preset-current-node-syntax "^1.0.0" + + bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== + + bail@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" + integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== + + balanced-match@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" + integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== + + base-x@^3.0.2, base-x@^3.0.6: + version "3.0.9" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" + integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== + dependencies: + safe-buffer "^5.0.1" + + base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + + base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + + batch@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" + integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== + + bech32@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" + integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== + + before-after-hook@^2.2.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" + integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== + + better-opn@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== + dependencies: + open "^7.0.3" + + big-integer@^1.6.48, big-integer@^1.6.7: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + + big.js@^5.2.2: + version "5.2.2" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" + integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== + + big.js@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" + integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== + + bignumber.js@^9.1.1: + version "9.1.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" + integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== + + binary-extensions@^1.0.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" + integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== + + binary-extensions@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" + integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== + + bindings@^1.3.0, bindings@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" + integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== + dependencies: + file-uri-to-path "1.0.0" + + bip32@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" + integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== + dependencies: + "@types/node" "10.12.18" + bs58check "^2.1.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + tiny-secp256k1 "^1.1.3" + typeforce "^1.11.5" + wif "^2.0.6" + + bip39@^3.0.2, bip39@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" + integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== + dependencies: + "@noble/hashes" "^1.2.0" + + bl@^4.0.3, bl@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" + integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== + dependencies: + buffer "^5.5.0" + inherits "^2.0.4" + readable-stream "^3.4.0" + + bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + + bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.8, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + + bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + + body-parser@1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" + integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== + dependencies: + bytes "3.1.2" + content-type "~1.0.4" + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" + iconv-lite "0.4.24" + on-finished "2.4.1" + qs "6.11.0" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" + + bonjour-service@^1.0.11: + version "1.1.1" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" + integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== + dependencies: + array-flatten "^2.1.2" + dns-equal "^1.0.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.5" + + boolbase@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" + integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== + + bowser@2.11.0: + version "2.11.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" + integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== + + boxen@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + 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" + + bplist-parser@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" + integrity sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q== + dependencies: + big-integer "^1.6.7" + + brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + + brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + + braces@^2.3.1, braces@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + + braces@^3.0.2, braces@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" + integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== + dependencies: + fill-range "^7.0.1" + + brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + + browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== + + browser-process-hrtime@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" + integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== + + browser-stdout@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" + integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== + + browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + + browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + + browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + + browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + + browserify-sign@^4.0.0: + version "4.2.2" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" + integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== + dependencies: + bn.js "^5.2.1" + browserify-rsa "^4.1.0" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.4" + inherits "^2.0.4" + parse-asn1 "^5.1.6" + readable-stream "^3.6.2" + safe-buffer "^5.2.1" + + browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + + browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: + version "4.22.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" + integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== + dependencies: + caniuse-lite "^1.0.30001541" + electron-to-chromium "^1.4.535" + node-releases "^2.0.13" + update-browserslist-db "^1.0.13" + + bs-logger@0.x: + version "0.2.6" + resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" + integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== + dependencies: + fast-json-stable-stringify "2.x" + + bs58@^4.0.0, bs58@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== + dependencies: + base-x "^3.0.2" + + bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" + integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + safe-buffer "^5.1.2" + + bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + + buffer-from@^1.0.0, buffer-from@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" + integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== + + buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + + buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + + buffer@^5.5.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" + integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.1.13" + + buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + + builtin-modules@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" + integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== + + builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + + builtins@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" + integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== + + builtins@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" + + byte-size@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" + integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== + + bytes@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" + integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== + + bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== + + c8@^7.6.0: + version "7.14.0" + resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" + integrity sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw== + dependencies: + "@bcoe/v8-coverage" "^0.2.3" + "@istanbuljs/schema" "^0.1.3" + find-up "^5.0.0" + foreground-child "^2.0.0" + istanbul-lib-coverage "^3.2.0" + istanbul-lib-report "^3.0.0" + istanbul-reports "^3.1.4" + rimraf "^3.0.2" + test-exclude "^6.0.0" + v8-to-istanbul "^9.0.0" + yargs "^16.2.0" + yargs-parser "^20.2.9" + + cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + + cacache@^15.0.5: + version "15.3.0" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" + integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== + dependencies: + "@npmcli/fs" "^1.0.0" + "@npmcli/move-file" "^1.0.1" + chownr "^2.0.0" + fs-minipass "^2.0.0" + glob "^7.1.4" + infer-owner "^1.0.4" + lru-cache "^6.0.0" + minipass "^3.1.1" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.2" + mkdirp "^1.0.3" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^8.0.1" + tar "^6.0.2" + unique-filename "^1.1.1" + + cacache@^16.1.0: + version "16.1.3" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" + integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^2.0.0" + + cacache@^17.0.0: + version "17.1.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" + integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== + dependencies: + "@npmcli/fs" "^3.1.0" + fs-minipass "^3.0.0" + glob "^10.2.2" + lru-cache "^7.7.1" + minipass "^7.0.3" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + p-map "^4.0.0" + ssri "^10.0.0" + tar "^6.1.11" + unique-filename "^3.0.0" + + cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== + dependencies: + collection-visit "^1.0.0" + component-emitter "^1.2.1" + get-value "^2.0.6" + has-value "^1.0.0" + isobject "^3.0.1" + set-value "^2.0.0" + to-object-path "^0.3.0" + union-value "^1.0.0" + unset-value "^1.0.0" + + call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" + integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== + dependencies: + function-bind "^1.1.2" + get-intrinsic "^1.2.1" + set-function-length "^1.1.1" + + call-me-maybe@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" + integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== + + callsites@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" + integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== + + camel-case@^4.1.1, camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + + camelcase-css@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + + camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + + camelcase-keys@^6.2.2: + version "6.2.2" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" + integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== + dependencies: + camelcase "^5.3.1" + map-obj "^4.0.0" + quick-lru "^4.0.1" + + camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== + + camelcase@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" + integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== + + camelcase@^6.0.0, camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== + + caniuse-api@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" + integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== + dependencies: + browserslist "^4.0.0" + caniuse-lite "^1.0.0" + lodash.memoize "^4.1.2" + lodash.uniq "^4.5.0" + + caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: + version "1.0.30001561" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" + integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== + + capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + + case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== + + ccount@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" + integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== + + ccount@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" + integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== + + chain-registry@^1.19.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.20.0.tgz#1442a1d715a7ebf57781aeb185e3cbaa7b08196c" + integrity sha512-kBeQVdopECXasauhaA+HiJNSB0UpzNmxtv5AvIpJBAZc3nuM2wzPxaHAiPz1OG5ifYwMraOkvPNxwOnXd1nZzw== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.17.0" + + chalk@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" + integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + + chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + + chalk@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" + integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + + chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + + char-regex@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" + integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== + + character-entities-html4@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" + integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== + + character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + + character-entities-legacy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" + integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== + + character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + + character-entities@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" + integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== + + character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== + + character-reference-invalid@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" + integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== + + chardet@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" + integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== + + chokidar@3.5.3, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + + chokidar@^2.1.8: + version "2.1.8" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" + integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== + dependencies: + anymatch "^2.0.0" + async-each "^1.0.1" + braces "^2.3.2" + glob-parent "^3.1.0" + inherits "^2.0.3" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + normalize-path "^3.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.2.1" + upath "^1.1.1" + optionalDependencies: + fsevents "^1.2.7" + + chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + + chownr@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" + integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== + + chrome-trace-event@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" + integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== + + ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + + ci-info@^3.2.0, ci-info@^3.6.1: + version "3.9.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" + integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== + + cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + + cjs-module-lexer@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" + integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== + + class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + + classnames@^2.2.5, classnames@^2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" + integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== + + clean-css@^4.2.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" + integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== + dependencies: + source-map "~0.6.0" + + clean-css@^5.2.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" + integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== + dependencies: + source-map "~0.6.0" + + clean-stack@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" + integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== + + clean-webpack-plugin@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz#72947d4403d452f38ed61a9ff0ada8122aacd729" + integrity sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w== + dependencies: + del "^4.1.1" + + cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + + cli-cursor@3.1.0, cli-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" + integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== + dependencies: + restore-cursor "^3.1.0" + + cli-spinners@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" + integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== + + cli-spinners@^2.5.0: + version "2.9.1" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" + integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== + + cli-table3@^0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" + integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + + cli-width@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" + integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== + + client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + + clipboard-copy@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" + integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== + + cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + + cliui@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" + integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.1" + wrap-ansi "^7.0.0" + + clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== + + clone-deep@4.0.1, clone-deep@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" + integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== + dependencies: + is-plain-object "^2.0.4" + kind-of "^6.0.2" + shallow-clone "^3.0.0" + + clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== + + clone@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== + + clone@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" + integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== + + cloneable-readable@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" + integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + + clsx@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" + integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== + + clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1, clsx@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + + clsx@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" + integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + + cmd-shim@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" + integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== + + co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== + + collapse-white-space@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== + + collect-v8-coverage@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" + integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== + + collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + + color-convert@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" + integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== + dependencies: + color-name "1.1.3" + + color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + + color-name@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" + integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== + + color-name@^1.0.0, color-name@~1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" + integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== + + color-string@^1.9.0: + version "1.9.1" + resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" + integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== + dependencies: + color-name "^1.0.0" + simple-swizzle "^0.2.2" + + color-support@^1.1.2, color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + + color@^4.0.1, color@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" + integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== + dependencies: + color-convert "^2.0.1" + color-string "^1.9.0" + + colord@^2.9.1: + version "2.9.3" + resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" + integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== + + colorette@^1.2.2: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" + integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== + + colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.19: + version "2.0.20" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" + integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== + + colornames@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" + integrity sha512-/pyV40IrsdulWv+wFPmERh9k/mjsPZ64yUMDmWrtj/k1nmgrzzIENWKdaVKyBbvFdQWqkcaRxr+polCo3VMe7A== + + colors@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + + columnify@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" + integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== + dependencies: + strip-ansi "^6.0.1" + wcwidth "^1.0.0" + + combined-stream@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" + integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== + dependencies: + delayed-stream "~1.0.0" + + comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + + comma-separated-tokens@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" + integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== + + commander@2, commander@^2.19.0, commander@^2.20.0: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + + commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + + commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + + commander@^7.0.0, commander@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + + commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + + commander@^9.4.1: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + + common-path-prefix@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" + integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== + + commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + + compare-func@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" + integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== + dependencies: + array-ify "^1.0.0" + dot-prop "^5.1.0" + + component-emitter@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" + integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + + compressible@~2.0.16: + version "2.0.18" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" + integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== + dependencies: + mime-db ">= 1.43.0 < 2" + + compression@^1.7.4: + version "1.7.4" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" + integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== + dependencies: + accepts "~1.3.5" + bytes "3.0.0" + compressible "~2.0.16" + debug "2.6.9" + on-headers "~1.0.2" + safe-buffer "5.1.2" + vary "~1.1.2" + + concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== + + concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + + concat-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^3.0.2" + typedarray "^0.0.6" + + confusing-browser-globals@^1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" + integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== + + connect-history-api-fallback@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" + integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + + console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + + console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + + constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + + content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== + dependencies: + safe-buffer "5.2.1" + + content-type@~1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + + conventional-changelog-angular@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" + integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== + dependencies: + compare-func "^2.0.0" + + conventional-changelog-core@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz#3c331b155d5b9850f47b4760aeddfc983a92ad49" + integrity sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A== + dependencies: + add-stream "^1.0.0" + conventional-changelog-writer "^6.0.0" + conventional-commits-parser "^4.0.0" + dateformat "^3.0.3" + get-pkg-repo "^4.2.1" + git-raw-commits "^3.0.0" + git-remote-origin-url "^2.0.0" + git-semver-tags "^5.0.0" + normalize-package-data "^3.0.3" + read-pkg "^3.0.0" + read-pkg-up "^3.0.0" + + conventional-changelog-preset-loader@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz#14975ef759d22515d6eabae6396c2ae721d4c105" + integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA== + + conventional-changelog-writer@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz#d8d3bb5e1f6230caed969dcc762b1c368a8f7b01" + integrity sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ== + dependencies: + conventional-commits-filter "^3.0.0" + dateformat "^3.0.3" + handlebars "^4.7.7" + json-stringify-safe "^5.0.1" + meow "^8.1.2" + semver "^7.0.0" + split "^1.0.1" + + conventional-commits-filter@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz#bf1113266151dd64c49cd269e3eb7d71d7015ee2" + integrity sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q== + dependencies: + lodash.ismatch "^4.4.0" + modify-values "^1.0.1" + + conventional-commits-parser@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505" + integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg== + dependencies: + JSONStream "^1.3.5" + is-text-path "^1.0.1" + meow "^8.1.2" + split2 "^3.2.2" + + conventional-recommended-bump@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424" + integrity sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA== + dependencies: + concat-stream "^2.0.0" + conventional-changelog-preset-loader "^3.0.0" + conventional-commits-filter "^3.0.0" + conventional-commits-parser "^4.0.0" + git-raw-commits "^3.0.0" + git-semver-tags "^5.0.0" + meow "^8.1.2" + + convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" + integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== + + convert-source-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" + integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + + cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== + + cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + + copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + + copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== + + copy-to-clipboard@^3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" + integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== + dependencies: + toggle-selection "^1.0.6" + + core-js-compat@^3.31.0, core-js-compat@^3.33.1, core-js-compat@^3.8.1: + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" + integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw== + dependencies: + browserslist "^4.22.1" + + core-js-pure@^3.23.3: + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" + integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== + + core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: + version "3.33.2" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" + integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== + + core-util-is@~1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" + integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== + + cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + + cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" + integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== + 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" + + cosmiconfig@^8.2.0: + version "8.3.6" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" + integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== + dependencies: + import-fresh "^3.3.0" + js-yaml "^4.1.0" + parse-json "^5.2.0" + path-type "^4.0.0" + + cosmjs-types@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.4.1.tgz#3b2a53ba60d33159dd075596ce8267cfa7027063" + integrity sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog== + dependencies: + long "^4.0.0" + protobufjs "~6.11.2" + + cosmjs-types@^0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.5.2.tgz#2d42b354946f330dfb5c90a87fdc2a36f97b965d" + integrity sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg== + dependencies: + long "^4.0.0" + protobufjs "~6.11.2" + + cp-file@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" + integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== + dependencies: + graceful-fs "^4.1.2" + make-dir "^3.0.0" + nested-error-stacks "^2.0.0" + p-event "^4.1.0" + + cpy@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" + integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== + dependencies: + arrify "^2.0.1" + cp-file "^7.0.0" + globby "^9.2.0" + has-glob "^1.0.0" + junk "^3.1.0" + nested-error-stacks "^2.1.0" + p-all "^2.1.0" + p-filter "^2.1.0" + p-map "^3.0.0" + + create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + + create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + + create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + + create-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" + integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== + + cross-spawn@^6.0.0, cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== + dependencies: + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" + + crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + + crypto-js@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" + integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== + + css-declaration-sorter@^6.3.1: + version "6.4.1" + resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" + integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== + + css-loader@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + + css-loader@^5.0.1: + version "5.2.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" + postcss "^8.2.15" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" + semver "^7.3.5" + + css-loader@^6.7.3: + version "6.8.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" + integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== + dependencies: + icss-utils "^5.1.0" + postcss "^8.4.21" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.3" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.8" + + css-minimizer-webpack-plugin@^3.0.2: + version "3.4.1" + resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" + integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== + dependencies: + cssnano "^5.0.6" + jest-worker "^27.0.2" + postcss "^8.3.5" + schema-utils "^4.0.0" + serialize-javascript "^6.0.0" + source-map "^0.6.1" + + css-select@^4.1.3: + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + 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" + + css-tree@^1.1.2, css-tree@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" + integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== + dependencies: + mdn-data "2.0.14" + source-map "^0.6.1" + + css-vendor@^2.0.8: + version "2.0.8" + resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" + integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== + dependencies: + "@babel/runtime" "^7.8.3" + is-in-browser "^1.0.2" + + css-what@^6.0.1, css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== + + css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== + + cssesc@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" + integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== + + cssnano-preset-default@^5.2.14: + version "5.2.14" + resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" + 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" + + cssnano-utils@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" + integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== + + cssnano@^5.0.6: + version "5.1.15" + resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" + integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== + dependencies: + cssnano-preset-default "^5.2.14" + lilconfig "^2.0.3" + yaml "^1.10.2" + + csso@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" + integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== + dependencies: + css-tree "^1.1.2" + + cssom@^0.4.4: + version "0.4.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" + integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== + + cssom@~0.3.6: + version "0.3.8" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" + integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== + + cssstyle@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" + integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== + dependencies: + cssom "~0.3.6" + + csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" + integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== + + currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== + dependencies: + array-find-index "^1.0.1" + + cyclist@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" + integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== + + "d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: + version "3.2.4" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" + integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== + dependencies: + internmap "1 - 2" + + d3-array@^2.5.0: + version "2.12.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" + integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== + dependencies: + internmap "^1.0.0" + + "d3-color@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" + integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== + + "d3-color@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" + integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== + + "d3-dispatch@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz#8a18e16f76dd3fcaef42163c97b926aa9b55e7cf" + integrity sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA== + + d3-drag@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-2.0.0.tgz#9eaf046ce9ed1c25c88661911c1d5a4d8eb7ea6d" + integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== + dependencies: + d3-dispatch "1 - 2" + d3-selection "2" + + "d3-ease@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-2.0.0.tgz#fd1762bfca00dae4bacea504b1d628ff290ac563" + integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ== + + d3-ease@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" + integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== + + "d3-format@1 - 3": + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" + integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== + + d3-geo@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-2.0.2.tgz#c065c1b71fe8c5f1be657e5f43d9bdd010383c40" + integrity sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA== + dependencies: + d3-array "^2.5.0" + + "d3-interpolate@1 - 2": + version "2.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" + integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== + dependencies: + d3-color "1 - 2" + + "d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" + integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== + dependencies: + d3-color "1 - 3" + + d3-path@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" + integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== + + d3-scale@^4.0.0, d3-scale@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" + integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== + dependencies: + d3-array "2.10.0 - 3" + d3-format "1 - 3" + d3-interpolate "1.2.0 - 3" + d3-time "2.1.1 - 3" + d3-time-format "2 - 4" + + d3-selection@2, d3-selection@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-2.0.0.tgz#94a11638ea2141b7565f883780dabc7ef6a61066" + integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== + + d3-shape@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" + integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== + dependencies: + d3-path "^3.1.0" + + "d3-time-format@2 - 4": + version "4.1.0" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" + integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== + dependencies: + d3-time "1 - 3" + + "d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" + integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== + dependencies: + d3-array "2 - 3" + + "d3-timer@1 - 2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" + integrity sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA== + + d3-timer@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" + integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== + + d3-transition@2: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-2.0.0.tgz#366ef70c22ef88d1e34105f507516991a291c94c" + integrity sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog== + dependencies: + d3-color "1 - 2" + d3-dispatch "1 - 2" + d3-ease "1 - 2" + d3-interpolate "1 - 2" + d3-timer "1 - 2" + + d3-zoom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-2.0.0.tgz#f04d0afd05518becce879d04709c47ecd93fba54" + integrity sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw== + dependencies: + d3-dispatch "1 - 2" + d3-drag "2" + d3-interpolate "1 - 2" + d3-selection "2" + d3-transition "2" + + damerau-levenshtein@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" + integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== + + dargs@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" + integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== + + data-urls@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" + integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== + dependencies: + abab "^2.0.3" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.0.0" + + date-fns@^2.24.0, date-fns@^2.28.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" + integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== + dependencies: + "@babel/runtime" "^7.21.0" + + dateformat@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== + + debug@2.6.9, debug@^2.2.0, debug@^2.3.3: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== + dependencies: + ms "2.0.0" + + debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + + debug@^3.0.0, debug@^3.2.7: + version "3.2.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" + integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== + dependencies: + ms "^2.1.1" + + decamelize-keys@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" + integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== + dependencies: + decamelize "^1.1.0" + map-obj "^1.0.0" + + decamelize@^1.1.0, decamelize@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== + + decamelize@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" + integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== + + decimal.js-light@^2.4.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" + integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== + + decimal.js@^10.2.1: + version "10.4.3" + resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" + integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== + + decode-named-character-reference@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" + integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== + dependencies: + character-entities "^2.0.0" + + decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" + integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== + + decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + + dedent@0.7.0, dedent@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" + integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== + + deep-equal@^2.0.5: + version "2.2.2" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.2.tgz#9b2635da569a13ba8e1cc159c2f744071b115daa" + integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== + dependencies: + array-buffer-byte-length "^1.0.0" + call-bind "^1.0.2" + es-get-iterator "^1.1.3" + get-intrinsic "^1.2.1" + is-arguments "^1.1.1" + is-array-buffer "^3.0.2" + is-date-object "^1.0.5" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + isarray "^2.0.5" + object-is "^1.1.5" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.0" + side-channel "^1.0.4" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + + deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== + + deep-is@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + + deep-object-diff@^1.1.9: + version "1.1.9" + resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.9.tgz#6df7ef035ad6a0caa44479c536ed7b02570f4595" + integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== + + deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + + default-browser-id@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-1.0.4.tgz#e59d09a5d157b828b876c26816e61c3d2a2c203a" + integrity sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw== + dependencies: + bplist-parser "^0.1.0" + meow "^3.1.0" + untildify "^2.0.0" + + default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" + + defaults@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" + integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== + dependencies: + clone "^1.0.2" + + define-data-property@^1.0.1, define-data-property@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" + integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== + dependencies: + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + + define-lazy-prop@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" + integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== + + define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" + integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== + dependencies: + define-data-property "^1.0.1" + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + + define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== + dependencies: + is-descriptor "^0.1.0" + + define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== + dependencies: + is-descriptor "^1.0.0" + + define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + + del@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" + integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== + dependencies: + "@types/glob" "^7.1.1" + globby "^6.1.0" + is-path-cwd "^2.0.0" + is-path-in-cwd "^2.0.0" + p-map "^2.0.0" + pify "^4.0.1" + rimraf "^2.6.3" + + delay@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/delay/-/delay-4.4.1.tgz#6e02d02946a1b6ab98b39262ced965acba2ac4d1" + integrity sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ== + + delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== + + delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + + depd@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + + depd@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" + integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== + + deprecation@^2.0.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" + integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== + + dequal@^2.0.0, dequal@^2.0.2, dequal@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" + integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== + + des.js@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" + integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + + destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + + detab@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" + integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== + dependencies: + repeat-string "^1.5.4" + + detect-browser@5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" + integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== + + detect-indent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" + integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== + + detect-libc@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== + + detect-libc@^2.0.0, detect-libc@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" + integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== + + detect-newline@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" + integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== + + detect-node@^2.0.4: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" + integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== + + detect-package-manager@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" + integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== + dependencies: + execa "^5.1.1" + + detect-port@^1.3.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" + integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== + dependencies: + address "^1.0.1" + debug "4" + + diacritics@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1" + integrity sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA== + + diff-sequences@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" + integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== + + diff-sequences@^28.1.1: + version "28.1.1" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" + integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== + + diff-sequences@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" + integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== + + diff@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" + integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== + + diff@^3.1.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== + + diff@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" + integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== + + diff@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" + integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== + + diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + + dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + + dir-glob@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" + integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== + dependencies: + path-type "^4.0.0" + + dns-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" + integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== + + dns-packet@^5.2.2: + version "5.6.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" + integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== + dependencies: + "@leichtgewicht/ip-codec" "^2.0.1" + + doctrine@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" + integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== + dependencies: + esutils "^2.0.2" + + doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== + dependencies: + esutils "^2.0.2" + + dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: + version "0.5.16" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" + integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== + + dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" + + dom-helpers@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" + integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== + dependencies: + "@babel/runtime" "^7.1.2" + + dom-helpers@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" + integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^3.0.2" + + dom-serializer@^1.0.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" + integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.2.0" + entities "^2.0.0" + + dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + + domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + + domelementtype@^2.0.1, domelementtype@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + + domexception@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" + integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== + dependencies: + webidl-conversions "^5.0.0" + + domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + + domutils@^2.5.2, domutils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" + integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== + dependencies: + dom-serializer "^1.0.1" + domelementtype "^2.2.0" + domhandler "^4.2.0" + + dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + + dot-prop@^5.1.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" + integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== + dependencies: + is-obj "^2.0.0" + + dotenv-defaults@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-2.0.2.tgz#6b3ec2e4319aafb70940abda72d3856770ee77ac" + integrity sha512-iOIzovWfsUHU91L5i8bJce3NYK5JXeAwH50Jh6+ARUdLiiGlYWfGw6UkzsYqaXZH/hjE/eCd/PlfM/qqyK0AMg== + dependencies: + dotenv "^8.2.0" + + dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + + dotenv-expand@~10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + + dotenv-webpack@^7.0.3: + version "7.1.1" + resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-7.1.1.tgz#ee8a699e1d736fd8eb9363fbc7054cfff1bd9dbf" + integrity sha512-xw/19VqHDkXALtBOJAnnrSU/AZDIQRXczAmJyp0lZv6SH2aBLzUTl96W1MVryJZ7okZ+djZS4Gj4KlZ0xP7deA== + dependencies: + dotenv-defaults "^2.0.2" + + dotenv@^16.0.3, dotenv@~16.3.1: + version "16.3.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" + integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== + + dotenv@^8.0.0, dotenv@^8.2.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== + + duplexer@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + + duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + + duplexify@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + + eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + + ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== + + ejs@^3.1.7: + version "3.1.9" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" + integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== + dependencies: + jake "^10.8.5" + + electron-to-chromium@^1.4.535: + version "1.4.576" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" + integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== + + elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" + + emittery@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" + integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== + + emoji-regex@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" + integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== + + emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + + emojis-list@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" + integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== + + encodeurl@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" + integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== + + encoding@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" + integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== + dependencies: + iconv-lite "^0.6.2" + + end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: + version "1.4.4" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" + integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== + dependencies: + once "^1.4.0" + + endent@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" + integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== + dependencies: + dedent "^0.7.0" + fast-json-parse "^1.0.3" + objectorarray "^1.0.5" + + enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + + enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: + version "5.15.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" + integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + + enquirer@^2.3.5: + version "2.4.1" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" + integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== + dependencies: + ansi-colors "^4.1.1" + strip-ansi "^6.0.1" + + enquirer@~2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" + integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== + dependencies: + ansi-colors "^4.1.1" + + entities@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" + integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== + + entities@^4.4.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" + integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== + + env-paths@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" + integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== + + envinfo@7.8.1: + version "7.8.1" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" + integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== + + envinfo@^7.7.3: + version "7.11.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f" + integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg== + + err-code@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" + integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== + + errno@^0.1.3, errno@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" + integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== + dependencies: + prr "~1.0.1" + + error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== + dependencies: + is-arrayish "^0.2.1" + + error-stack-parser@^2.0.6: + version "2.1.4" + resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" + integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== + dependencies: + stackframe "^1.3.4" + + es-abstract@^1.22.1: + version "1.22.3" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" + integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== + dependencies: + array-buffer-byte-length "^1.0.0" + arraybuffer.prototype.slice "^1.0.2" + available-typed-arrays "^1.0.5" + call-bind "^1.0.5" + es-set-tostringtag "^2.0.1" + es-to-primitive "^1.2.1" + function.prototype.name "^1.1.6" + get-intrinsic "^1.2.2" + get-symbol-description "^1.0.0" + globalthis "^1.0.3" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + internal-slot "^1.0.5" + is-array-buffer "^3.0.2" + is-callable "^1.2.7" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-typed-array "^1.1.12" + is-weakref "^1.0.2" + object-inspect "^1.13.1" + object-keys "^1.1.1" + object.assign "^4.1.4" + regexp.prototype.flags "^1.5.1" + safe-array-concat "^1.0.1" + safe-regex-test "^1.0.0" + string.prototype.trim "^1.2.8" + string.prototype.trimend "^1.0.7" + string.prototype.trimstart "^1.0.7" + typed-array-buffer "^1.0.0" + typed-array-byte-length "^1.0.0" + typed-array-byte-offset "^1.0.0" + typed-array-length "^1.0.4" + unbox-primitive "^1.0.2" + which-typed-array "^1.1.13" + + es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + + es-get-iterator@^1.0.2, es-get-iterator@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" + integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + has-symbols "^1.0.3" + is-arguments "^1.1.1" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.7" + isarray "^2.0.5" + stop-iteration-iterator "^1.0.0" + + es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: + version "1.0.15" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" + integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== + dependencies: + asynciterator.prototype "^1.0.0" + call-bind "^1.0.2" + define-properties "^1.2.1" + es-abstract "^1.22.1" + es-set-tostringtag "^2.0.1" + function-bind "^1.1.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + has-property-descriptors "^1.0.0" + has-proto "^1.0.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + iterator.prototype "^1.1.2" + safe-array-concat "^1.0.1" + + es-module-lexer@^1.2.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" + integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== + + es-set-tostringtag@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" + integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== + dependencies: + get-intrinsic "^1.2.2" + has-tostringtag "^1.0.0" + hasown "^2.0.0" + + es-shim-unscopables@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" + integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== + dependencies: + hasown "^2.0.0" + + es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + + es5-shim@^4.5.13: + version "4.6.7" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" + integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== + + es6-shim@^0.35.5: + version "0.35.8" + resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.8.tgz#89216f6fbf8bacba3f897c8c0e814d2a41c05fb7" + integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== + + escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + + escape-html@^1.0.3, escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== + + escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" + integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== + + escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== + + escape-string-regexp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" + integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== + + escodegen@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" + integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionalDependencies: + source-map "~0.6.1" + + eslint-config-airbnb-base@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" + integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== + dependencies: + confusing-browser-globals "^1.0.10" + object.assign "^4.1.2" + object.entries "^1.1.5" + semver "^6.3.0" + + eslint-config-airbnb-typescript@^16.1.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.2.0.tgz#9193fafd62f1cbf444895f4495eae334baf3265b" + integrity sha512-OUaMPZpTOZGKd5tXOjJ9PRU4iYNW/Z5DoHIynjsVK/FpkWdiY5+nxQW6TiJAlLwVI1l53xUOrnlZWtVBVQzuWA== + dependencies: + eslint-config-airbnb-base "^15.0.0" + + eslint-config-airbnb@^19.0.2, eslint-config-airbnb@^19.0.4: + version "19.0.4" + resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" + integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== + dependencies: + eslint-config-airbnb-base "^15.0.0" + object.assign "^4.1.2" + object.entries "^1.1.5" + + eslint-config-prettier@^8.3.0, eslint-config-prettier@^8.5.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" + integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== + + eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.9: + version "0.3.9" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" + integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== + dependencies: + debug "^3.2.7" + is-core-module "^2.13.0" + resolve "^1.22.4" + + eslint-import-resolver-root-import@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-root-import/-/eslint-import-resolver-root-import-1.0.4.tgz#82991138d8014b5e2283b27622ad1ba21f535609" + integrity sha512-c8cUQcELRBe0mnblBZJKEfL+jIUGR8pctK5gdru5N7bBOIve2WZ0R3KoO5GOksXJ4WzZhtcBS2xPaTJYEe4IdQ== + dependencies: + eslint-import-resolver-node "^0.3.2" + json5 "^2.1.0" + + eslint-module-utils@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" + integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== + dependencies: + debug "^3.2.7" + + eslint-plugin-import@^2.25.4: + version "2.29.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" + integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== + dependencies: + array-includes "^3.1.7" + array.prototype.findlastindex "^1.2.3" + array.prototype.flat "^1.3.2" + array.prototype.flatmap "^1.3.2" + debug "^3.2.7" + doctrine "^2.1.0" + eslint-import-resolver-node "^0.3.9" + eslint-module-utils "^2.8.0" + hasown "^2.0.0" + is-core-module "^2.13.1" + is-glob "^4.0.3" + minimatch "^3.1.2" + object.fromentries "^2.0.7" + object.groupby "^1.0.1" + object.values "^1.1.7" + semver "^6.3.1" + tsconfig-paths "^3.14.2" + + eslint-plugin-jest@^26.1.1: + version "26.9.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz#7931c31000b1c19e57dbfb71bbf71b817d1bf949" + integrity sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng== + dependencies: + "@typescript-eslint/utils" "^5.10.0" + + eslint-plugin-jsx-a11y@^6.5.1: + version "6.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" + integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== + dependencies: + "@babel/runtime" "^7.23.2" + aria-query "^5.3.0" + array-includes "^3.1.7" + array.prototype.flatmap "^1.3.2" + ast-types-flow "^0.0.8" + axe-core "=4.7.0" + axobject-query "^3.2.1" + damerau-levenshtein "^1.0.8" + emoji-regex "^9.2.2" + es-iterator-helpers "^1.0.15" + hasown "^2.0.0" + jsx-ast-utils "^3.3.5" + language-tags "^1.0.9" + minimatch "^3.1.2" + object.entries "^1.1.7" + object.fromentries "^2.0.7" + + eslint-plugin-mocha@^10.0.3: + version "10.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz#15b05ce5be4b332bb0d76826ec1c5ebf67102ad6" + integrity sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ== + dependencies: + eslint-utils "^3.0.0" + rambda "^7.4.0" + + eslint-plugin-prettier@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" + integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== + dependencies: + prettier-linter-helpers "^1.0.0" + + eslint-plugin-react-hooks@^4.3.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" + integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== + + eslint-plugin-react@^7.29.2: + version "7.33.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" + integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== + dependencies: + array-includes "^3.1.6" + array.prototype.flatmap "^1.3.1" + array.prototype.tosorted "^1.1.1" + doctrine "^2.1.0" + es-iterator-helpers "^1.0.12" + estraverse "^5.3.0" + jsx-ast-utils "^2.4.1 || ^3.0.0" + minimatch "^3.1.2" + object.entries "^1.1.6" + object.fromentries "^2.0.6" + object.hasown "^1.1.2" + object.values "^1.1.6" + prop-types "^15.8.1" + resolve "^2.0.0-next.4" + semver "^6.3.1" + string.prototype.matchall "^4.0.8" + + eslint-plugin-storybook@^0.5.12: + version "0.5.13" + resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.5.13.tgz#dee4056eaa59c886a9ae78fb7b2ee0ed5fad4366" + integrity sha512-82x3FH1VAi68Awu1VEjn/hLkzFZsOP8ItcC5/uGF9WszIrj6n7Q3MZD57oE26k3aKwuPfFtAPnSjFnaBkBab+g== + dependencies: + "@storybook/csf" "^0.0.1" + "@typescript-eslint/experimental-utils" "^5.3.0" + requireindex "^1.1.0" + + eslint-scope@5.1.1, eslint-scope@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" + integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== + dependencies: + esrecurse "^4.3.0" + estraverse "^4.1.1" + + eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + + eslint-scope@^7.2.2: + version "7.2.2" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" + integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== + dependencies: + esrecurse "^4.3.0" + estraverse "^5.2.0" + + eslint-utils@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" + integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== + dependencies: + eslint-visitor-keys "^1.1.0" + + eslint-utils@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" + integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== + dependencies: + eslint-visitor-keys "^2.0.0" + + eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" + integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== + + eslint-visitor-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" + integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== + + eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: + version "3.4.3" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" + integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== + + eslint@^7.18.0: + version "7.32.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" + integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== + dependencies: + "@babel/code-frame" "7.12.11" + "@eslint/eslintrc" "^0.4.3" + "@humanwhocodes/config-array" "^0.5.0" + ajv "^6.10.0" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.0.1" + doctrine "^3.0.0" + enquirer "^2.3.5" + escape-string-regexp "^4.0.0" + eslint-scope "^5.1.1" + eslint-utils "^2.1.0" + eslint-visitor-keys "^2.0.0" + espree "^7.3.1" + esquery "^1.4.0" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + functional-red-black-tree "^1.0.1" + glob-parent "^5.1.2" + globals "^13.6.0" + ignore "^4.0.6" + import-fresh "^3.0.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + js-yaml "^3.13.1" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.0.4" + natural-compare "^1.4.0" + optionator "^0.9.1" + progress "^2.0.0" + regexpp "^3.1.0" + semver "^7.2.1" + strip-ansi "^6.0.0" + strip-json-comments "^3.1.0" + table "^6.0.9" + text-table "^0.2.0" + v8-compile-cache "^2.0.3" + + eslint@^8.10.0: + version "8.53.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" + integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== + dependencies: + "@eslint-community/eslint-utils" "^4.2.0" + "@eslint-community/regexpp" "^4.6.1" + "@eslint/eslintrc" "^2.1.3" + "@eslint/js" "8.53.0" + "@humanwhocodes/config-array" "^0.11.13" + "@humanwhocodes/module-importer" "^1.0.1" + "@nodelib/fs.walk" "^1.2.8" + "@ungap/structured-clone" "^1.2.0" + ajv "^6.12.4" + chalk "^4.0.0" + cross-spawn "^7.0.2" + debug "^4.3.2" + doctrine "^3.0.0" + escape-string-regexp "^4.0.0" + eslint-scope "^7.2.2" + eslint-visitor-keys "^3.4.3" + espree "^9.6.1" + esquery "^1.4.2" + esutils "^2.0.2" + fast-deep-equal "^3.1.3" + file-entry-cache "^6.0.1" + find-up "^5.0.0" + glob-parent "^6.0.2" + globals "^13.19.0" + graphemer "^1.4.0" + ignore "^5.2.0" + imurmurhash "^0.1.4" + is-glob "^4.0.0" + is-path-inside "^3.0.3" + js-yaml "^4.1.0" + json-stable-stringify-without-jsonify "^1.0.1" + levn "^0.4.1" + lodash.merge "^4.6.2" + minimatch "^3.1.2" + natural-compare "^1.4.0" + optionator "^0.9.3" + strip-ansi "^6.0.1" + text-table "^0.2.0" + + espree@^7.3.0, espree@^7.3.1: + version "7.3.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" + integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== + dependencies: + acorn "^7.4.0" + acorn-jsx "^5.3.1" + eslint-visitor-keys "^1.3.0" + + espree@^9.6.0, espree@^9.6.1: + version "9.6.1" + resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" + integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== + dependencies: + acorn "^8.9.0" + acorn-jsx "^5.3.2" + eslint-visitor-keys "^3.4.1" + + esprima@^4.0.0, esprima@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + + esquery@^1.4.0, esquery@^1.4.2: + version "1.5.0" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" + integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== + dependencies: + estraverse "^5.1.0" + + esrecurse@^4.1.0, esrecurse@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" + integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== + dependencies: + estraverse "^5.2.0" + + estraverse@^4.1.1: + version "4.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" + integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== + + estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" + integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== + + estree-to-babel@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" + integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== + dependencies: + "@babel/traverse" "^7.1.6" + "@babel/types" "^7.2.0" + c8 "^7.6.0" + + estree-util-attach-comments@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz#ee44f4ff6890ee7dfb3237ac7810154c94c63f84" + integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== + dependencies: + "@types/estree" "^1.0.0" + + estree-util-build-jsx@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz#32f8a239fb40dc3f3dca75bb5dcf77a831e4e47b" + integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== + dependencies: + "@types/estree-jsx" "^1.0.0" + estree-util-is-identifier-name "^2.0.0" + estree-walker "^3.0.0" + + estree-util-is-identifier-name@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz#fb70a432dcb19045e77b05c8e732f1364b4b49b2" + integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== + + estree-util-to-js@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz#0f80d42443e3b13bd32f7012fffa6f93603f4a36" + integrity sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA== + dependencies: + "@types/estree-jsx" "^1.0.0" + astring "^1.8.0" + source-map "^0.7.0" + + estree-util-visit@^1.0.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.2.1.tgz#8bc2bc09f25b00827294703835aabee1cc9ec69d" + integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/unist" "^2.0.0" + + estree-walker@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" + integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== + + estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + + estree-walker@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" + integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== + dependencies: + "@types/estree" "^1.0.0" + + esutils@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" + integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== + + etag@~1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" + integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== + + eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + + events@3.3.0, events@^3.0.0, events@^3.2.0, events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + + evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + + exec-sh@^0.3.2: + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== + + execa@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" + integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + + execa@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" + integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== + dependencies: + cross-spawn "^6.0.0" + get-stream "^4.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + + execa@^5.0.0, execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + + exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== + + expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + expand-template@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" + integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== + + expect@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" + integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== + dependencies: + "@jest/types" "^27.5.1" + jest-get-type "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + + expect@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" + integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== + dependencies: + "@jest/expect-utils" "^28.1.3" + jest-get-type "^28.0.2" + jest-matcher-utils "^28.1.3" + jest-message-util "^28.1.3" + jest-util "^28.1.3" + + expect@^29.0.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" + integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== + dependencies: + "@jest/expect-utils" "^29.7.0" + jest-get-type "^29.6.3" + jest-matcher-utils "^29.7.0" + jest-message-util "^29.7.0" + jest-util "^29.7.0" + + exponential-backoff@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" + integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== + + express@^4.17.1, express@^4.17.3, express@^4.18.2: + version "4.18.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" + integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + dependencies: + accepts "~1.3.8" + array-flatten "1.1.1" + body-parser "1.20.1" + content-disposition "0.5.4" + content-type "~1.0.4" + cookie "0.5.0" + cookie-signature "1.0.6" + debug "2.6.9" + depd "2.0.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + finalhandler "1.2.0" + fresh "0.5.2" + http-errors "2.0.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "2.4.1" + parseurl "~1.3.3" + path-to-regexp "0.1.7" + proxy-addr "~2.0.7" + qs "6.11.0" + range-parser "~1.2.1" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" + type-is "~1.6.18" + utils-merge "1.0.1" + vary "~1.1.2" + + extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== + dependencies: + is-extendable "^0.1.0" + + extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + + extend@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + + external-editor@^3.0.3: + version "3.1.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" + integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== + dependencies: + chardet "^0.7.0" + iconv-lite "^0.4.24" + tmp "^0.0.33" + + extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== + + fast-diff@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" + integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== + + fast-equals@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d" + integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== + + fast-fifo@^1.1.0, fast-fifo@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" + integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== + + fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + + fast-glob@^3.2.9: + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== + dependencies: + "@nodelib/fs.stat" "^2.0.2" + "@nodelib/fs.walk" "^1.2.3" + glob-parent "^5.1.2" + merge2 "^1.3.0" + micromatch "^4.0.4" + + fast-json-parse@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" + integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== + + fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" + integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== + + fast-levenshtein@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + + fast-redact@^3.0.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" + integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + + fastest-levenshtein@^1.0.12: + version "1.0.16" + resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" + integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== + + fastq@^1.6.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" + integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== + dependencies: + reusify "^1.0.4" + + favicons-webpack-plugin@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-5.0.2.tgz#0837a753ee4485785fa2cec1c3b83472f9ff60ce" + integrity sha512-D/A+Ze0x57+YZBU69hK/lR3NI636qQnKduWyQm0THGl1y3jt16whPHHsi8yjsuXvetv84Eh/I/yYJbAMC2iQxg== + dependencies: + "@types/favicons" "5.5.0" + find-root "^1.1.0" + parse-author "^2.0.0" + parse5 "^6.0.1" + optionalDependencies: + html-webpack-plugin ">=5.0.0" + + favicons@7.0.0-beta.1: + version "7.0.0-beta.1" + resolved "https://registry.yarnpkg.com/favicons/-/favicons-7.0.0-beta.1.tgz#57a7319d75bb004590b5bae8c2388858135535eb" + integrity sha512-68NaOyryvZpQlQw1w1K40AH6bl8KfhpL2Nb/EBedeBseYS7Rpz1d3t4eBaLIdOBRM2/353EKkZeKzBvQnp6LvA== + dependencies: + colors "^1.4.0" + escape-html "^1.0.3" + lodash.defaultsdeep "^4.6.1" + sharp "^0.29.1" + through2 "^4.0.2" + vinyl "^2.2.1" + xml2js "^0.4.23" + + favicons@^7.0.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/favicons/-/favicons-7.1.4.tgz#bc0ed1a8d752f94a36912294681925e272d25ff0" + integrity sha512-lnZpVgT7Fzz+DUjioKF1dMwLYlpqWCaB4gIksIfIKwtlhHO1Q7w23hERwHQjEsec+43iENwbTAPRDW3XvpLhbg== + dependencies: + escape-html "^1.0.3" + sharp "^0.32.4" + xml2js "^0.6.1" + + faye-websocket@^0.11.3: + version "0.11.4" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" + integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== + dependencies: + websocket-driver ">=0.5.1" + + fb-watchman@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" + integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== + dependencies: + bser "2.1.1" + + fetch-retry@^5.0.2: + version "5.0.6" + resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" + integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== + + figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + + figures@3.2.0, figures@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" + integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== + dependencies: + escape-string-regexp "^1.0.5" + + file-entry-cache@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" + integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== + dependencies: + flat-cache "^3.0.4" + + file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + + file-system-cache@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-2.3.0.tgz#201feaf4c8cd97b9d0d608e96861bb6005f46fe6" + integrity sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ== + dependencies: + fs-extra "11.1.1" + ramda "0.29.0" + + file-system-cache@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.1.0.tgz#984de17b976b75a77a27e08d6828137c1aa80fa1" + integrity sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw== + dependencies: + fs-extra "^10.1.0" + ramda "^0.28.0" + + file-uri-to-path@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" + integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== + + filelist@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" + integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== + dependencies: + minimatch "^5.0.1" + + fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + + fill-range@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" + integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== + dependencies: + to-regex-range "^5.0.1" + + filter-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" + integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== + + finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + + find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== + dependencies: + commondir "^1.0.1" + make-dir "^2.0.0" + pkg-dir "^3.0.0" + + find-cache-dir@^3.3.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" + integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== + dependencies: + commondir "^1.0.1" + make-dir "^3.0.2" + pkg-dir "^4.1.0" + + find-root@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" + integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== + + find-up@5.0.0, find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + + find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + + find-up@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== + dependencies: + locate-path "^2.0.0" + + find-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" + integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== + dependencies: + locate-path "^3.0.0" + + find-up@^4.0.0, find-up@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" + integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== + dependencies: + locate-path "^5.0.0" + path-exists "^4.0.0" + + flat-cache@^3.0.4: + version "3.1.1" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" + integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + dependencies: + flatted "^3.2.9" + keyv "^4.5.3" + rimraf "^3.0.2" + + flat@^5.0.2: + version "5.0.2" + resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" + integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== + + flatted@^3.2.9: + version "3.2.9" + resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" + integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== + + flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + + focus-lock@^0.8.0: + version "0.8.1" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" + integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== + dependencies: + tslib "^1.9.3" + + follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.0: + version "1.15.3" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" + integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== + + for-each@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" + integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== + dependencies: + is-callable "^1.1.3" + + for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== + + foreground-child@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" + integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^3.0.2" + + foreground-child@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" + integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + + fork-ts-checker-webpack-plugin@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== + dependencies: + "@babel/code-frame" "^7.5.5" + chalk "^2.4.1" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + + fork-ts-checker-webpack-plugin@^6.0.4: + version "6.5.3" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" + integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + + fork-ts-checker-webpack-plugin@^7.2.1: + version "7.3.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz#a9c984a018493962360d7c7e77a67b44a2d5f3aa" + integrity sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA== + dependencies: + "@babel/code-frame" "^7.16.7" + chalk "^4.1.2" + chokidar "^3.5.3" + cosmiconfig "^7.0.1" + deepmerge "^4.2.2" + fs-extra "^10.0.0" + memfs "^3.4.1" + minimatch "^3.0.4" + node-abort-controller "^3.0.1" + schema-utils "^3.1.1" + semver "^7.3.5" + tapable "^2.2.1" + + form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + + form-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" + integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + + forwarded@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" + integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== + + fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== + dependencies: + map-cache "^0.2.2" + + fresh@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" + integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== + + from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + + fs-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" + integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== + + fs-extra@11.1.1, fs-extra@^11.1.0, fs-extra@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" + integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + + fs-extra@^10.0.0, fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + + fs-extra@^9.0.0, fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + + fs-minipass@^2.0.0, fs-minipass@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" + integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== + dependencies: + minipass "^3.0.0" + + fs-minipass@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" + integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== + dependencies: + minipass "^7.0.3" + + fs-monkey@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" + integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== + + fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + + fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== + + fsevents@^1.2.7: + version "1.2.13" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" + integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== + dependencies: + bindings "^1.5.0" + nan "^2.12.1" + + fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + + function-bind@^1.1.1, function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + + function.prototype.name@^1.1.0, function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" + integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + functions-have-names "^1.2.3" + + functional-red-black-tree@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" + integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== + + functions-have-names@^1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + + gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + + gauge@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" + integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.3" + console-control-strings "^1.1.0" + has-unicode "^2.0.1" + signal-exit "^3.0.7" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.5" + + gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: + version "1.0.0-beta.2" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" + integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== + + get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" + integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== + dependencies: + function-bind "^1.1.2" + has-proto "^1.0.1" + has-symbols "^1.0.3" + hasown "^2.0.0" + + get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + + get-pkg-repo@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" + integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== + dependencies: + "@hutson/parse-repository-url" "^3.0.0" + hosted-git-info "^4.0.0" + through2 "^2.0.0" + yargs "^16.2.0" + + get-port@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== + + get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== + + get-stream@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" + integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== + + get-stream@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" + integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== + dependencies: + pump "^3.0.0" + + get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + + get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + + get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== + + git-raw-commits@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-3.0.0.tgz#5432f053a9744f67e8db03dbc48add81252cfdeb" + integrity sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw== + dependencies: + dargs "^7.0.0" + meow "^8.1.2" + split2 "^3.2.2" + + git-remote-origin-url@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" + integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== + dependencies: + gitconfiglocal "^1.0.0" + pify "^2.3.0" + + git-semver-tags@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-5.0.1.tgz#db748aa0e43d313bf38dcd68624d8443234e1c15" + integrity sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA== + dependencies: + meow "^8.1.2" + semver "^7.0.0" + + git-up@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" + integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== + dependencies: + is-ssh "^1.4.0" + parse-url "^8.1.0" + + git-url-parse@13.1.0: + version "13.1.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" + integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== + dependencies: + git-up "^7.0.0" + + gitconfiglocal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" + integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== + dependencies: + ini "^1.3.2" + + github-from-package@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" + integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== + + github-slugger@^1.0.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" + integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== + + glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" + integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== + dependencies: + is-glob "^4.0.1" + + glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + + glob-parent@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" + integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== + dependencies: + is-glob "^4.0.3" + + glob-promise@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== + dependencies: + "@types/glob" "*" + + glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== + + glob-to-regexp@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" + integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== + + glob@7.1.4: + version "7.1.4" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" + integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@^10.2.2: + version "10.3.10" + resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" + integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^2.3.5" + minimatch "^9.0.1" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + path-scurry "^1.10.1" + + glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + + glob@^8.0.1, glob@^8.0.3: + version "8.1.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" + integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + + glob@^9.2.0: + version "9.3.5" + resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" + integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== + dependencies: + fs.realpath "^1.0.0" + minimatch "^8.0.2" + minipass "^4.2.4" + path-scurry "^1.6.1" + + global@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + + globals@^11.1.0: + version "11.12.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" + integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== + + globals@^13.19.0, globals@^13.6.0, globals@^13.9.0: + version "13.23.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" + integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== + dependencies: + type-fest "^0.20.2" + + globalthis@^1.0.0, globalthis@^1.0.1, globalthis@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + + globby@11.1.0, globby@^11.0.2, globby@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== + dependencies: + array-union "^2.1.0" + dir-glob "^3.0.1" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" + slash "^3.0.0" + + globby@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" + integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== + dependencies: + array-union "^1.0.1" + glob "^7.0.3" + object-assign "^4.0.1" + pify "^2.0.0" + pinkie-promise "^2.0.0" + + globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== + dependencies: + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" + + gopd@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" + integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== + dependencies: + get-intrinsic "^1.1.3" + + graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" + integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== + + graphemer@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" + integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + + handle-thing@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" + integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== + + handlebars@^4.7.7: + version "4.7.8" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" + integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.2" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + + hard-rejection@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" + integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== + + has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + + has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== + + has-flag@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" + integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== + + has-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" + integrity sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g== + dependencies: + is-glob "^3.0.0" + + has-property-descriptors@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" + integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== + dependencies: + get-intrinsic "^1.2.2" + + has-proto@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" + integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== + + has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + + has-tostringtag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" + integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== + dependencies: + has-symbols "^1.0.2" + + has-unicode@2.0.1, has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + + has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + + has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + + has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== + + has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + + hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + + hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + + hasown@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" + integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== + dependencies: + function-bind "^1.1.2" + + hast-to-hyperscript@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" + integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== + 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" + + hast-util-from-parse5@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" + integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== + 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" + + hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== + + hast-util-raw@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" + 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" + + hast-util-to-estree@^2.0.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz#da60142ffe19a6296923ec222aba73339c8bf470" + integrity sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ== + dependencies: + "@types/estree" "^1.0.0" + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + estree-util-attach-comments "^2.0.0" + estree-util-is-identifier-name "^2.0.0" + hast-util-whitespace "^2.0.0" + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdxjs-esm "^1.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.4.1" + unist-util-position "^4.0.0" + zwitch "^2.0.0" + + hast-util-to-parse5@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" + integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== + 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" + + hast-util-whitespace@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557" + integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== + + hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== + 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" + + he@1.2.0, he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + + hex-rgb@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.3.0.tgz#af5e974e83bb2fefe44d55182b004ec818c07776" + integrity sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw== + + hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + + hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" + integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== + dependencies: + react-is "^16.7.0" + + hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + + hosted-git-info@^3.0.6: + version "3.0.8" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" + integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== + dependencies: + lru-cache "^6.0.0" + + hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" + integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== + dependencies: + lru-cache "^6.0.0" + + hosted-git-info@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" + integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== + dependencies: + lru-cache "^7.5.1" + + hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + + html-encoding-sniffer@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" + integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== + dependencies: + whatwg-encoding "^1.0.5" + + html-entities@^2.1.0, html-entities@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" + integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== + + html-escaper@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" + integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== + + html-minifier-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + + html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + 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" + + html-tags@^3.1.0: + version "3.3.1" + resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" + integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== + + html-void-elements@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== + + html-webpack-plugin@>=5.0.0, html-webpack-plugin@^5.0.0, html-webpack-plugin@^5.3.2: + version "5.5.3" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" + integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + + html-webpack-plugin@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" + integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.20" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + + htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + + http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" + integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== + + http-deceiver@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== + + http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== + dependencies: + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" + + http-errors@~1.6.2: + version "1.6.3" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" + integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== + dependencies: + depd "~1.1.2" + inherits "2.0.3" + setprototypeof "1.1.0" + statuses ">= 1.4.0 < 2" + + http-parser-js@>=0.5.1: + version "0.5.8" + resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" + integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== + + http-proxy-agent@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" + integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== + dependencies: + "@tootallnate/once" "1" + agent-base "6" + debug "4" + + http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== + dependencies: + "@tootallnate/once" "2" + agent-base "6" + debug "4" + + http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + + http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + + https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + + https-proxy-agent@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== + dependencies: + agent-base "6" + debug "4" + + human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + + humanize-ms@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" + integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== + dependencies: + ms "^2.0.0" + + hyphenate-style-name@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" + integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== + + i18n-iso-countries@^6.8.0: + version "6.8.0" + resolved "https://registry.yarnpkg.com/i18n-iso-countries/-/i18n-iso-countries-6.8.0.tgz#eebbc75594c6832aff86176c1bb38daa133d6dfd" + integrity sha512-jJs/+CA6+VUICFxqGcB0vFMERGfhfvyNk+8Vb9EagSZkl7kSpm/kT0VyhvzM/zixDWEV/+oN9L7v/GT9BwzoGg== + dependencies: + diacritics "1.3.0" + + iconv-lite@0.4.24, iconv-lite@^0.4.24: + version "0.4.24" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" + integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== + dependencies: + safer-buffer ">= 2.1.2 < 3" + + iconv-lite@^0.6.2: + version "0.6.3" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" + integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== + dependencies: + safer-buffer ">= 2.1.2 < 3.0.0" + + icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + + icss-utils@^5.0.0, icss-utils@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" + integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + + ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + + iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== + + ignore-by-default@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" + integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== + + ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== + dependencies: + minimatch "^5.0.1" + + ignore-walk@^6.0.0: + version "6.0.3" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb" + integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== + dependencies: + minimatch "^9.0.0" + + ignore@^4.0.3, ignore@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + + ignore@^5.0.4, ignore@^5.2.0: + version "5.2.4" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" + integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + + immediate@~3.0.5: + version "3.0.6" + resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" + integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== + + immer@^9.0.19: + version "9.0.21" + resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" + integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== + + import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" + integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== + dependencies: + parent-module "^1.0.0" + resolve-from "^4.0.0" + + import-local@3.1.0, import-local@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" + integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== + dependencies: + pkg-dir "^4.2.0" + resolve-cwd "^3.0.0" + + imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== + + indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== + dependencies: + repeating "^2.0.0" + + indent-string@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" + integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== + + infer-owner@^1.0.3, infer-owner@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" + integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== + + inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== + dependencies: + once "^1.3.0" + wrappy "1" + + inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + + inherits@2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== + + ini@^1.3.2, ini@^1.3.8, ini@~1.3.0: + version "1.3.8" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" + integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== + + init-package-json@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-5.0.0.tgz#030cf0ea9c84cfc1b0dc2e898b45d171393e4b40" + integrity sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw== + dependencies: + npm-package-arg "^10.0.0" + promzard "^1.0.0" + read "^2.0.0" + read-package-json "^6.0.0" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + validate-npm-package-name "^5.0.0" + + inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + + inquirer@^8.2.4: + version "8.2.6" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" + integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== + dependencies: + ansi-escapes "^4.2.1" + chalk "^4.1.1" + cli-cursor "^3.1.0" + cli-width "^3.0.0" + external-editor "^3.0.3" + figures "^3.0.0" + lodash "^4.17.21" + mute-stream "0.0.8" + ora "^5.4.1" + run-async "^2.4.0" + rxjs "^7.5.5" + string-width "^4.1.0" + strip-ansi "^6.0.0" + through "^2.3.6" + wrap-ansi "^6.0.1" + + internal-slot@^1.0.4, internal-slot@^1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" + integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== + dependencies: + get-intrinsic "^1.2.2" + hasown "^2.0.0" + side-channel "^1.0.4" + + "internmap@1 - 2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" + integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== + + internmap@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" + integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== + + interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== + + intl-messageformat@^10.1.0: + version "10.5.4" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.4.tgz#7b212b083f1b354d7e282518e78057e025134af9" + integrity sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w== + dependencies: + "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/fast-memoize" "2.2.0" + "@formatjs/icu-messageformat-parser" "2.7.0" + tslib "^2.4.0" + + ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + + ipaddr.js@1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" + integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== + + ipaddr.js@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" + integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + + is-absolute-url@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" + integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== + + is-accessor-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" + integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== + dependencies: + hasown "^2.0.0" + + is-alphabetical@1.0.4, is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + + is-alphabetical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" + integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== + + is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + + is-alphanumerical@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" + integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== + dependencies: + is-alphabetical "^2.0.0" + is-decimal "^2.0.0" + + is-arguments@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" + integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" + integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.0" + is-typed-array "^1.1.10" + + is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== + + is-arrayish@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" + integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== + + is-async-function@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" + integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== + dependencies: + has-tostringtag "^1.0.0" + + is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + + is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== + dependencies: + binary-extensions "^1.0.0" + + is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + + is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== + + is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + + is-builtin-module@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" + integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== + dependencies: + builtin-modules "^3.3.0" + + is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" + integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== + + is-ci@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" + integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== + dependencies: + ci-info "^3.2.0" + + is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + + is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: + version "2.13.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" + integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== + dependencies: + hasown "^2.0.0" + + is-data-descriptor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" + integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== + dependencies: + hasown "^2.0.0" + + is-date-object@^1.0.1, is-date-object@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" + integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== + dependencies: + has-tostringtag "^1.0.0" + + is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + + is-decimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" + integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== + + is-descriptor@^0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" + integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== + dependencies: + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" + + is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" + integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== + dependencies: + is-accessor-descriptor "^1.0.1" + is-data-descriptor "^1.0.1" + + is-docker@^2.0.0, is-docker@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" + integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== + + is-dom@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" + integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== + dependencies: + is-object "^1.0.1" + is-window "^1.0.2" + + is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== + + is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== + dependencies: + is-plain-object "^2.0.4" + + is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== + + is-finalizationregistry@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" + integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== + dependencies: + call-bind "^1.0.2" + + is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + + is-fullwidth-code-point@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" + integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== + + is-function@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + + is-generator-fn@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" + integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== + + is-generator-function@^1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" + integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== + dependencies: + has-tostringtag "^1.0.0" + + is-glob@^3.0.0, is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== + dependencies: + is-extglob "^2.1.0" + + is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: + version "4.0.3" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" + integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== + dependencies: + is-extglob "^2.1.1" + + is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + + is-hexadecimal@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" + integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== + + is-in-browser@^1.0.2, is-in-browser@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" + integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== + + is-interactive@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" + integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== + + is-lambda@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" + integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== + + is-map@^2.0.1, is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + + is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + + is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + + is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + + is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== + dependencies: + kind-of "^3.0.2" + + is-number@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" + integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== + + is-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" + integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== + + is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + + is-path-cwd@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" + integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== + + is-path-in-cwd@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" + integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== + dependencies: + is-path-inside "^2.1.0" + + is-path-inside@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" + integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== + dependencies: + path-is-inside "^1.0.2" + + is-path-inside@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" + integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== + + is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + + is-plain-obj@^2.0.0, is-plain-obj@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + + is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== + + is-plain-obj@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" + integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== + + is-plain-object@5.0.0, is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + + is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== + dependencies: + isobject "^3.0.1" + + is-potential-custom-element-name@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" + integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== + + is-reference@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + + is-reference@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.2.tgz#154747a01f45cd962404ee89d43837af2cba247c" + integrity sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg== + dependencies: + "@types/estree" "*" + + is-regex@^1.1.2, is-regex@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" + integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.0.0" + + is-set@^2.0.1, is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + + is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" + + is-ssh@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" + integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== + dependencies: + protocols "^2.0.1" + + is-stream@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" + integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== + + is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + + is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + + is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + + is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + + is-text-path@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" + integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== + dependencies: + text-extensions "^1.0.0" + + is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + version "1.1.12" + resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" + integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== + dependencies: + which-typed-array "^1.1.11" + + is-typedarray@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== + + is-unicode-supported@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" + integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== + + is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + + is-weakmap@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" + integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== + + is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + + is-weakset@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" + integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + + is-whitespace-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== + + is-window@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" + integrity sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg== + + is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== + + is-word-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== + + is-wsl@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== + + is-wsl@^2.1.1, is-wsl@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" + integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== + dependencies: + is-docker "^2.0.0" + + isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== + + isarray@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" + integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== + + isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== + + isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== + dependencies: + isarray "1.0.0" + + isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== + + isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + + isomorphic-unfetch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" + integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== + dependencies: + node-fetch "^2.6.1" + unfetch "^4.2.0" + + isomorphic-ws@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" + integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== + + istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.1.tgz#c680fd1544600460367af5811866c34c44c6f3b1" + integrity sha512-opCrKqbthmq3SKZ10mFMQG9dk3fTa3quaOLD35kJa5ejwZHd9xAr+kLuziiZz2cG32s4lMZxNdmdcEQnTDP4+g== + + istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" + integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== + dependencies: + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-coverage "^3.2.0" + semver "^6.3.0" + + istanbul-lib-report@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" + integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== + dependencies: + istanbul-lib-coverage "^3.0.0" + make-dir "^4.0.0" + supports-color "^7.1.0" + + istanbul-lib-source-maps@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" + integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== + dependencies: + debug "^4.1.1" + istanbul-lib-coverage "^3.0.0" + source-map "^0.6.1" + + istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: + version "3.1.6" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" + integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== + dependencies: + html-escaper "^2.0.0" + istanbul-lib-report "^3.0.0" + + iterate-iterator@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" + integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== + + iterate-value@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" + + iterator.prototype@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" + integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== + dependencies: + define-properties "^1.2.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + reflect.getprototypeof "^1.0.4" + set-function-name "^2.0.1" + + jackspeak@^2.3.5: + version "2.3.6" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" + integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== + dependencies: + "@isaacs/cliui" "^8.0.2" + optionalDependencies: + "@pkgjs/parseargs" "^0.11.0" + + jake@^10.8.5: + version "10.8.7" + resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" + integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== + dependencies: + async "^3.2.3" + chalk "^4.0.2" + filelist "^1.0.4" + minimatch "^3.1.2" + + javascript-stringify@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" + integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== + + jest-changed-files@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" + integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== + dependencies: + "@jest/types" "^27.5.1" + execa "^5.0.0" + throat "^6.0.1" + + jest-circus@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" + integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + dedent "^0.7.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + throat "^6.0.1" + + jest-cli@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" + integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== + dependencies: + "@jest/core" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + exit "^0.1.2" + graceful-fs "^4.2.9" + import-local "^3.0.2" + jest-config "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + prompts "^2.0.1" + yargs "^16.2.0" + + jest-config@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" + integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== + dependencies: + "@babel/core" "^7.8.0" + "@jest/test-sequencer" "^27.5.1" + "@jest/types" "^27.5.1" + babel-jest "^27.5.1" + chalk "^4.0.0" + ci-info "^3.2.0" + deepmerge "^4.2.2" + glob "^7.1.1" + graceful-fs "^4.2.9" + jest-circus "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-get-type "^27.5.1" + jest-jasmine2 "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runner "^27.5.1" + jest-util "^27.5.1" + jest-validate "^27.5.1" + micromatch "^4.0.4" + parse-json "^5.2.0" + pretty-format "^27.5.1" + slash "^3.0.0" + strip-json-comments "^3.1.1" + + "jest-diff@>=29.4.3 < 30", jest-diff@^29.4.1, jest-diff@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" + integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.6.3" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + + jest-diff@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" + integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== + dependencies: + chalk "^4.0.0" + diff-sequences "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + + jest-diff@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" + integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== + dependencies: + chalk "^4.0.0" + diff-sequences "^28.1.1" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + + jest-docblock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" + integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== + dependencies: + detect-newline "^3.0.0" + + jest-each@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" + integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + jest-get-type "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + + jest-environment-jsdom@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" + integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + jsdom "^16.6.0" + + jest-environment-node@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" + integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + jest-mock "^27.5.1" + jest-util "^27.5.1" + + jest-get-type@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" + integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== + + jest-get-type@^28.0.2: + version "28.0.2" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" + integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== + + jest-get-type@^29.6.3: + version "29.6.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" + integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== + + jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + + jest-haste-map@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" + integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== + dependencies: + "@jest/types" "^27.5.1" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.9" + jest-regex-util "^27.5.1" + jest-serializer "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + micromatch "^4.0.4" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.3.2" + + jest-jasmine2@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" + integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + co "^4.6.0" + expect "^27.5.1" + is-generator-fn "^2.0.0" + jest-each "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-runtime "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + pretty-format "^27.5.1" + throat "^6.0.1" + + jest-leak-detector@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" + integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== + dependencies: + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + + jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" + integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== + dependencies: + chalk "^4.0.0" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + pretty-format "^27.5.1" + + jest-matcher-utils@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" + integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== + dependencies: + chalk "^4.0.0" + jest-diff "^28.1.3" + jest-get-type "^28.0.2" + pretty-format "^28.1.3" + + jest-matcher-utils@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" + integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== + dependencies: + chalk "^4.0.0" + jest-diff "^29.7.0" + jest-get-type "^29.6.3" + pretty-format "^29.7.0" + + jest-message-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" + integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^27.5.1" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^27.5.1" + slash "^3.0.0" + stack-utils "^2.0.3" + + jest-message-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" + integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^28.1.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^28.1.3" + slash "^3.0.0" + stack-utils "^2.0.3" + + jest-message-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" + integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== + dependencies: + "@babel/code-frame" "^7.12.13" + "@jest/types" "^29.6.3" + "@types/stack-utils" "^2.0.0" + chalk "^4.0.0" + graceful-fs "^4.2.9" + micromatch "^4.0.4" + pretty-format "^29.7.0" + slash "^3.0.0" + stack-utils "^2.0.3" + + jest-mock@^27.0.6, jest-mock@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + + jest-pnp-resolver@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" + integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== + + jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + + jest-regex-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" + integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== + + jest-resolve-dependencies@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" + integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== + dependencies: + "@jest/types" "^27.5.1" + jest-regex-util "^27.5.1" + jest-snapshot "^27.5.1" + + jest-resolve@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" + integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== + dependencies: + "@jest/types" "^27.5.1" + chalk "^4.0.0" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-pnp-resolver "^1.2.2" + jest-util "^27.5.1" + jest-validate "^27.5.1" + resolve "^1.20.0" + resolve.exports "^1.1.0" + slash "^3.0.0" + + jest-runner@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" + integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== + dependencies: + "@jest/console" "^27.5.1" + "@jest/environment" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + emittery "^0.8.1" + graceful-fs "^4.2.9" + jest-docblock "^27.5.1" + jest-environment-jsdom "^27.5.1" + jest-environment-node "^27.5.1" + jest-haste-map "^27.5.1" + jest-leak-detector "^27.5.1" + jest-message-util "^27.5.1" + jest-resolve "^27.5.1" + jest-runtime "^27.5.1" + jest-util "^27.5.1" + jest-worker "^27.5.1" + source-map-support "^0.5.6" + throat "^6.0.1" + + jest-runtime@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" + integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== + dependencies: + "@jest/environment" "^27.5.1" + "@jest/fake-timers" "^27.5.1" + "@jest/globals" "^27.5.1" + "@jest/source-map" "^27.5.1" + "@jest/test-result" "^27.5.1" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + chalk "^4.0.0" + cjs-module-lexer "^1.0.0" + collect-v8-coverage "^1.0.0" + execa "^5.0.0" + glob "^7.1.3" + graceful-fs "^4.2.9" + jest-haste-map "^27.5.1" + jest-message-util "^27.5.1" + jest-mock "^27.5.1" + jest-regex-util "^27.5.1" + jest-resolve "^27.5.1" + jest-snapshot "^27.5.1" + jest-util "^27.5.1" + slash "^3.0.0" + strip-bom "^4.0.0" + + jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + + jest-serializer@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" + integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.9" + + jest-snapshot@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" + integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== + dependencies: + "@babel/core" "^7.7.2" + "@babel/generator" "^7.7.2" + "@babel/plugin-syntax-typescript" "^7.7.2" + "@babel/traverse" "^7.7.2" + "@babel/types" "^7.0.0" + "@jest/transform" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/babel__traverse" "^7.0.4" + "@types/prettier" "^2.1.5" + babel-preset-current-node-syntax "^1.0.0" + chalk "^4.0.0" + expect "^27.5.1" + graceful-fs "^4.2.9" + jest-diff "^27.5.1" + jest-get-type "^27.5.1" + jest-haste-map "^27.5.1" + jest-matcher-utils "^27.5.1" + jest-message-util "^27.5.1" + jest-util "^27.5.1" + natural-compare "^1.4.0" + pretty-format "^27.5.1" + semver "^7.3.2" + + jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + + jest-util@^27.0.0, jest-util@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" + integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + + jest-util@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" + integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== + dependencies: + "@jest/types" "^28.1.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + + jest-util@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" + integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== + dependencies: + "@jest/types" "^29.6.3" + "@types/node" "*" + chalk "^4.0.0" + ci-info "^3.2.0" + graceful-fs "^4.2.9" + picomatch "^2.2.3" + + jest-validate@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" + integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== + dependencies: + "@jest/types" "^27.5.1" + camelcase "^6.2.0" + chalk "^4.0.0" + jest-get-type "^27.5.1" + leven "^3.1.0" + pretty-format "^27.5.1" + + jest-watcher@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" + integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== + dependencies: + "@jest/test-result" "^27.5.1" + "@jest/types" "^27.5.1" + "@types/node" "*" + ansi-escapes "^4.2.1" + chalk "^4.0.0" + jest-util "^27.5.1" + string-length "^4.0.1" + + jest-worker@^26.5.0, jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + + jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + + jest@^27.1.0: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" + integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== + dependencies: + "@jest/core" "^27.5.1" + import-local "^3.0.2" + jest-cli "^27.5.1" + + js-sha3@0.8.0, js-sha3@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" + integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== + + js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== + + "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== + + js-yaml@4.1.0, js-yaml@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + + js-yaml@^3.10.0, js-yaml@^3.13.1: + version "3.14.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" + integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + + jsdom@^16.6.0: + version "16.7.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" + integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== + dependencies: + abab "^2.0.5" + acorn "^8.2.4" + acorn-globals "^6.0.0" + cssom "^0.4.4" + cssstyle "^2.3.0" + data-urls "^2.0.0" + decimal.js "^10.2.1" + domexception "^2.0.1" + escodegen "^2.0.0" + form-data "^3.0.0" + html-encoding-sniffer "^2.0.1" + http-proxy-agent "^4.0.1" + https-proxy-agent "^5.0.0" + is-potential-custom-element-name "^1.0.1" + nwsapi "^2.2.0" + parse5 "6.0.1" + saxes "^5.0.1" + symbol-tree "^3.2.4" + tough-cookie "^4.0.0" + w3c-hr-time "^1.0.2" + w3c-xmlserializer "^2.0.0" + webidl-conversions "^6.1.0" + whatwg-encoding "^1.0.5" + whatwg-mimetype "^2.3.0" + whatwg-url "^8.5.0" + ws "^7.4.6" + xml-name-validator "^3.0.0" + + jsesc@^2.5.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" + integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== + + jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== + + json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + + json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== + + json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" + integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== + + json-parse-even-better-errors@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" + integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + + json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== + + json-schema-traverse@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" + integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== + + json-stable-stringify-without-jsonify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" + integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== + + json-stringify-safe@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== + + json5@2.x, json5@^2.1.0, json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" + integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== + + json5@^1.0.1, json5@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" + integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== + dependencies: + minimist "^1.2.0" + + jsonc-parser@3.2.0, jsonc-parser@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" + integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== + + jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + + jsonparse@^1.2.0, jsonparse@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" + integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== + + jss-plugin-camel-case@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" + integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== + dependencies: + "@babel/runtime" "^7.3.1" + hyphenate-style-name "^1.0.3" + jss "10.10.0" + + jss-plugin-default-unit@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" + integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + + jss-plugin-global@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" + integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + + jss-plugin-nested@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" + integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + tiny-warning "^1.0.2" + + jss-plugin-props-sort@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" + integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + + jss-plugin-rule-value-function@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" + integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== + dependencies: + "@babel/runtime" "^7.3.1" + jss "10.10.0" + tiny-warning "^1.0.2" + + jss-plugin-vendor-prefixer@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" + integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== + dependencies: + "@babel/runtime" "^7.3.1" + css-vendor "^2.0.8" + jss "10.10.0" + + jss@10.10.0, jss@^10.10.0: + version "10.10.0" + resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" + integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== + dependencies: + "@babel/runtime" "^7.3.1" + csstype "^3.0.2" + is-in-browser "^1.1.3" + tiny-warning "^1.0.2" + + "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: + version "3.3.5" + resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" + integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== + dependencies: + array-includes "^3.1.6" + array.prototype.flat "^1.3.1" + object.assign "^4.1.4" + object.values "^1.1.6" + + junk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" + integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== + + keyv@^4.5.3: + version "4.5.4" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" + integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== + dependencies: + json-buffer "3.0.1" + + keyvaluestorage-interface@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" + integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== + + kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== + dependencies: + is-buffer "^1.1.5" + + kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== + dependencies: + is-buffer "^1.1.5" + + kind-of@^6.0.2, kind-of@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" + integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== + + kleur@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + + kleur@^4.0.3: + version "4.1.5" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + + klona@^2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" + integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== + + language-subtag-registry@^0.3.20: + version "0.3.22" + resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" + integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== + + language-tags@^1.0.9: + version "1.0.9" + resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" + integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== + dependencies: + language-subtag-registry "^0.3.20" + + launch-editor@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" + integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== + dependencies: + picocolors "^1.0.0" + shell-quote "^1.8.1" + + lazy-universal-dotenv@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" + integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== + dependencies: + "@babel/runtime" "^7.5.0" + app-root-dir "^1.0.2" + core-js "^3.0.4" + dotenv "^8.0.0" + dotenv-expand "^5.1.0" + + "legacy-swc-helpers@npm:@swc/helpers@=0.4.14": + version "0.4.14" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" + integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== + dependencies: + tslib "^2.4.0" + + lerna@^7.3.0: + version "7.4.2" + resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" + integrity sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA== + dependencies: + "@lerna/child-process" "7.4.2" + "@lerna/create" "7.4.2" + "@npmcli/run-script" "6.0.2" + "@nx/devkit" ">=16.5.1 < 17" + "@octokit/plugin-enterprise-rest" "6.0.1" + "@octokit/rest" "19.0.11" + byte-size "8.1.1" + chalk "4.1.0" + clone-deep "4.0.1" + cmd-shim "6.0.1" + columnify "1.6.0" + conventional-changelog-angular "7.0.0" + conventional-changelog-core "5.0.1" + conventional-recommended-bump "7.0.1" + cosmiconfig "^8.2.0" + dedent "0.7.0" + envinfo "7.8.1" + execa "5.0.0" + fs-extra "^11.1.1" + get-port "5.1.1" + get-stream "6.0.0" + git-url-parse "13.1.0" + glob-parent "5.1.2" + globby "11.1.0" + graceful-fs "4.2.11" + has-unicode "2.0.1" + import-local "3.1.0" + ini "^1.3.8" + init-package-json "5.0.0" + inquirer "^8.2.4" + is-ci "3.0.1" + is-stream "2.0.0" + jest-diff ">=29.4.3 < 30" + js-yaml "4.1.0" + libnpmaccess "7.0.2" + libnpmpublish "7.3.0" + load-json-file "6.2.0" + lodash "^4.17.21" + make-dir "4.0.0" + minimatch "3.0.5" + multimatch "5.0.0" + node-fetch "2.6.7" + npm-package-arg "8.1.1" + npm-packlist "5.1.1" + npm-registry-fetch "^14.0.5" + npmlog "^6.0.2" + nx ">=16.5.1 < 17" + p-map "4.0.0" + p-map-series "2.1.0" + p-pipe "3.1.0" + p-queue "6.6.2" + p-reduce "2.1.0" + p-waterfall "2.1.1" + pacote "^15.2.0" + pify "5.0.0" + read-cmd-shim "4.0.0" + read-package-json "6.0.4" + resolve-from "5.0.0" + rimraf "^4.4.1" + semver "^7.3.8" + signal-exit "3.0.7" + slash "3.0.0" + ssri "^9.0.1" + strong-log-transformer "2.1.0" + tar "6.1.11" + temp-dir "1.0.0" + typescript ">=3 < 6" + upath "2.0.1" + uuid "^9.0.0" + validate-npm-package-license "3.0.4" + validate-npm-package-name "5.0.0" + write-file-atomic "5.0.1" + write-pkg "4.0.0" + yargs "16.2.0" + yargs-parser "20.2.4" + + leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + + levn@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" + integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== + dependencies: + prelude-ls "^1.2.1" + type-check "~0.4.0" + + libnpmaccess@7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52" + integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw== + dependencies: + npm-package-arg "^10.1.0" + npm-registry-fetch "^14.0.3" + + libnpmpublish@7.3.0: + version "7.3.0" + resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.3.0.tgz#2ceb2b36866d75a6cd7b4aa748808169f4d17e37" + integrity sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg== + dependencies: + ci-info "^3.6.1" + normalize-package-data "^5.0.0" + npm-package-arg "^10.1.0" + npm-registry-fetch "^14.0.3" + proc-log "^3.0.0" + semver "^7.3.7" + sigstore "^1.4.0" + ssri "^10.0.1" + + libsodium-wrappers@^0.7.6: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" + integrity sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw== + dependencies: + libsodium "^0.7.13" + + libsodium@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.13.tgz#230712ec0b7447c57b39489c48a4af01985fb393" + integrity sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw== + + lie@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" + integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== + dependencies: + immediate "~3.0.5" + + lilconfig@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" + integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== + + lines-and-columns@^1.1.6: + version "1.2.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" + integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== + + lines-and-columns@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" + integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + + load-json-file@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" + integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== + dependencies: + graceful-fs "^4.1.15" + parse-json "^5.0.0" + strip-bom "^4.0.0" + type-fest "^0.6.0" + + load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + + load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + + loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + + loader-runner@^4.1.0, loader-runner@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" + integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== + + loader-utils@^1.2.3: + version "1.4.2" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" + integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^1.0.1" + + loader-utils@^2.0.0, loader-utils@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" + integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + + localforage@^1.7.3, localforage@^1.8.1: + version "1.10.0" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" + integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== + dependencies: + lie "3.1.1" + + locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + + locate-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" + integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== + dependencies: + p-locate "^3.0.0" + path-exists "^3.0.0" + + locate-path@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" + integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== + dependencies: + p-locate "^4.1.0" + + locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + + lodash-es@^4.17.21: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" + integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== + + lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + + lodash.defaultsdeep@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" + integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + + lodash.isequal@4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" + integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== + + lodash.ismatch@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" + integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== + + lodash.memoize@4.x, lodash.memoize@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== + + lodash.merge@^4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + + lodash.padend@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" + integrity sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw== + + lodash.trimstart@^4.5.1: + version "4.5.1" + resolved "https://registry.yarnpkg.com/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz#8ff4dec532d82486af59573c39445914e944a7f1" + integrity sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ== + + lodash.truncate@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" + integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== + + lodash.uniq@4.5.0, lodash.uniq@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== + + lodash.words@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-4.2.0.tgz#5ecfeaf8ecf8acaa8e0c8386295f1993c9cf4036" + integrity sha512-mXxqd8Yx9BGPij3lZKFSdOsjOTbL4krbCCp9slEozaN4EMppA2dFmK/f8HeohodprY6W0vOdiQ5WFgPaTI75xQ== + + lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + + log-symbols@4.1.0, log-symbols@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" + integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== + dependencies: + chalk "^4.1.0" + is-unicode-supported "^0.1.0" + + long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== + + longest-streak@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" + integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== + + loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + + loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + + lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + + lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" + + lru-cache@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" + integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== + dependencies: + yallist "^4.0.0" + + lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + + "lru-cache@^9.1.1 || ^10.0.0": + version "10.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" + integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== + + lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + + luxon@^2.3.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.5.2.tgz#17ed497f0277e72d58a4756d6a9abee4681457b6" + integrity sha512-Yg7/RDp4nedqmLgyH0LwgGRvMEKVzKbUdkBYyCosbHgJ+kaOUx0qzSiSatVc3DFygnirTPYnMM2P5dg2uH1WvA== + + lz-string@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" + integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== + + magic-string@^0.25.3: + version "0.25.9" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" + integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== + dependencies: + sourcemap-codec "^1.4.8" + + magic-string@^0.27.0: + version "0.27.0" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" + integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.13" + + magic-string@^0.30.2: + version "0.30.5" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" + integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== + dependencies: + "@jridgewell/sourcemap-codec" "^1.4.15" + + make-dir@4.0.0, make-dir@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" + integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== + dependencies: + semver "^7.5.3" + + make-dir@^2.0.0, make-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" + integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== + dependencies: + pify "^4.0.1" + semver "^5.6.0" + + make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" + integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== + dependencies: + semver "^6.0.0" + + make-error@1.x, make-error@^1.1.1: + version "1.3.6" + resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" + integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== + + make-fetch-happen@^10.0.3: + version "10.2.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" + integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + + make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: + version "11.1.1" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" + integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== + dependencies: + agentkeepalive "^4.2.1" + cacache "^17.0.0" + http-cache-semantics "^4.1.1" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^10.0.0" + + makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + + map-age-cleaner@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" + integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== + dependencies: + p-defer "^1.0.0" + + map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + + map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== + + map-obj@^4.0.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" + integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== + + map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== + + map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== + dependencies: + object-visit "^1.0.0" + + markdown-escapes@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== + + markdown-extensions@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" + integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== + + marked@^4.0.16: + version "4.3.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" + integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== + + md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + + mdast-squeeze-paragraphs@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" + integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== + dependencies: + unist-util-remove "^2.0.0" + + mdast-util-definitions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" + integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== + dependencies: + unist-util-visit "^2.0.0" + + mdast-util-definitions@^5.0.0: + version "5.1.2" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz#9910abb60ac5d7115d6819b57ae0bcef07a3f7a7" + integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + + mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0" + integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + decode-named-character-reference "^1.0.0" + mdast-util-to-string "^3.1.0" + micromark "^3.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-decode-string "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-stringify-position "^3.0.0" + uvu "^0.5.0" + + mdast-util-mdx-expression@^1.0.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz#d027789e67524d541d6de543f36d51ae2586f220" + integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + + mdast-util-mdx-jsx@^2.0.0: + version "2.1.4" + resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz#7c1f07f10751a78963cfabee38017cbc8b7786d1" + integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + ccount "^2.0.0" + mdast-util-from-markdown "^1.1.0" + mdast-util-to-markdown "^1.3.0" + parse-entities "^4.0.0" + stringify-entities "^4.0.0" + unist-util-remove-position "^4.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + + mdast-util-mdx@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz#49b6e70819b99bb615d7223c088d295e53bb810f" + integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw== + dependencies: + mdast-util-from-markdown "^1.0.0" + mdast-util-mdx-expression "^1.0.0" + mdast-util-mdx-jsx "^2.0.0" + mdast-util-mdxjs-esm "^1.0.0" + mdast-util-to-markdown "^1.0.0" + + mdast-util-mdxjs-esm@^1.0.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz#645d02cd607a227b49721d146fd81796b2e2d15b" + integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== + dependencies: + "@types/estree-jsx" "^1.0.0" + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + mdast-util-to-markdown "^1.0.0" + + mdast-util-phrasing@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz#c7c21d0d435d7fb90956038f02e8702781f95463" + integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== + dependencies: + "@types/mdast" "^3.0.0" + unist-util-is "^5.0.0" + + mdast-util-to-hast@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" + integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== + 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" + + mdast-util-to-hast@^12.1.0: + version "12.3.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz#045d2825fb04374e59970f5b3f279b5700f6fb49" + integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-definitions "^5.0.0" + micromark-util-sanitize-uri "^1.1.0" + trim-lines "^3.0.0" + unist-util-generated "^2.0.0" + unist-util-position "^4.0.0" + unist-util-visit "^4.0.0" + + mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz#c13343cb3fc98621911d33b5cd42e7d0731171c6" + integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + longest-streak "^3.0.0" + mdast-util-phrasing "^3.0.0" + mdast-util-to-string "^3.0.0" + micromark-util-decode-string "^1.0.0" + unist-util-visit "^4.0.0" + zwitch "^2.0.0" + + mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + + mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789" + integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== + dependencies: + "@types/mdast" "^3.0.0" + + mdn-data@2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" + integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== + + mdurl@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== + + media-query-parser@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" + integrity sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w== + dependencies: + "@babel/runtime" "^7.12.5" + + media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== + + mem@^8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/mem/-/mem-8.1.1.tgz#cf118b357c65ab7b7e0817bdf00c8062297c0122" + integrity sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA== + dependencies: + map-age-cleaner "^0.1.3" + mimic-fn "^3.1.0" + + memfs@^3.1.2, memfs@^3.2.2, memfs@^3.4.1, memfs@^3.4.3: + version "3.6.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" + integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== + dependencies: + fs-monkey "^1.0.4" + + memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== + dependencies: + map-or-similar "^1.5.0" + + memory-fs@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + + memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + + memorystream@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" + integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== + + meow@^3.1.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + + meow@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" + integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== + dependencies: + "@types/minimist" "^1.2.0" + camelcase-keys "^6.2.2" + decamelize-keys "^1.1.0" + hard-rejection "^2.1.0" + minimist-options "4.1.0" + normalize-package-data "^3.0.0" + read-pkg-up "^7.0.1" + redent "^3.0.0" + trim-newlines "^3.0.0" + type-fest "^0.18.0" + yargs-parser "^20.2.3" + + merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== + + merge-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" + integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== + + merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" + integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== + + methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== + + microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + + micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8" + integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-factory-destination "^1.0.0" + micromark-factory-label "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-factory-title "^1.0.0" + micromark-factory-whitespace "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-classify-character "^1.0.0" + micromark-util-html-tag-name "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + + micromark-extension-mdx-expression@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz#5bc1f5fd90388e8293b3ef4f7c6f06c24aff6314" + integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw== + dependencies: + "@types/estree" "^1.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + + micromark-extension-mdx-jsx@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz#e72d24b7754a30d20fb797ece11e2c4e2cae9e82" + integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + estree-util-is-identifier-name "^2.0.0" + micromark-factory-mdx-expression "^1.0.0" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + + micromark-extension-mdx-md@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz#595d4b2f692b134080dca92c12272ab5b74c6d1a" + integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA== + dependencies: + micromark-util-types "^1.0.0" + + micromark-extension-mdxjs-esm@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz#e4f8be9c14c324a80833d8d3a227419e2b25dec1" + integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w== + dependencies: + "@types/estree" "^1.0.0" + micromark-core-commonmark "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.1.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + + micromark-extension-mdxjs@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz#f78d4671678d16395efeda85170c520ee795ded8" + integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q== + dependencies: + acorn "^8.0.0" + acorn-jsx "^5.0.0" + micromark-extension-mdx-expression "^1.0.0" + micromark-extension-mdx-jsx "^1.0.0" + micromark-extension-mdx-md "^1.0.0" + micromark-extension-mdxjs-esm "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-factory-destination@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f" + integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-factory-label@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68" + integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + + micromark-factory-mdx-expression@^1.0.0: + version "1.0.9" + resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz#57ba4571b69a867a1530f34741011c71c73a4976" + integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA== + dependencies: + "@types/estree" "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-events-to-acorn "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + unist-util-position-from-estree "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + + micromark-factory-space@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" + integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-factory-title@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1" + integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-factory-whitespace@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705" + integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== + dependencies: + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-util-character@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" + integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== + dependencies: + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-util-chunked@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b" + integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== + dependencies: + micromark-util-symbol "^1.0.0" + + micromark-util-classify-character@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d" + integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-util-combine-extensions@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84" + integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-types "^1.0.0" + + micromark-util-decode-numeric-character-reference@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6" + integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== + dependencies: + micromark-util-symbol "^1.0.0" + + micromark-util-decode-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c" + integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== + dependencies: + decode-named-character-reference "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-symbol "^1.0.0" + + micromark-util-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5" + integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== + + micromark-util-events-to-acorn@^1.0.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz#a4ab157f57a380e646670e49ddee97a72b58b557" + integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w== + dependencies: + "@types/acorn" "^4.0.0" + "@types/estree" "^1.0.0" + "@types/unist" "^2.0.0" + estree-util-visit "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + vfile-message "^3.0.0" + + micromark-util-html-tag-name@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588" + integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== + + micromark-util-normalize-identifier@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7" + integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== + dependencies: + micromark-util-symbol "^1.0.0" + + micromark-util-resolve-all@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188" + integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== + dependencies: + micromark-util-types "^1.0.0" + + micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d" + integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== + dependencies: + micromark-util-character "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-symbol "^1.0.0" + + micromark-util-subtokenize@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1" + integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== + dependencies: + micromark-util-chunked "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.0" + uvu "^0.5.0" + + micromark-util-symbol@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" + integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== + + micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" + integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== + + micromark@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9" + integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== + dependencies: + "@types/debug" "^4.0.0" + debug "^4.0.0" + decode-named-character-reference "^1.0.0" + micromark-core-commonmark "^1.0.1" + micromark-factory-space "^1.0.0" + micromark-util-character "^1.0.0" + micromark-util-chunked "^1.0.0" + micromark-util-combine-extensions "^1.0.0" + micromark-util-decode-numeric-character-reference "^1.0.0" + micromark-util-encode "^1.0.0" + micromark-util-normalize-identifier "^1.0.0" + micromark-util-resolve-all "^1.0.0" + micromark-util-sanitize-uri "^1.0.0" + micromark-util-subtokenize "^1.0.0" + micromark-util-symbol "^1.0.0" + micromark-util-types "^1.0.1" + uvu "^0.5.0" + + micromatch@^3.1.10, micromatch@^3.1.4: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + + micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + + miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + + mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + + mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.30, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + + mime@1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" + integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== + + mime@^2.4.4: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + + mimic-fn@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" + integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== + + mimic-fn@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" + integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== + + mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + + min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== + dependencies: + dom-walk "^0.1.0" + + min-indent@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" + integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== + + mini-css-extract-plugin@^2.2.2: + version "2.7.6" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" + integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== + dependencies: + schema-utils "^4.0.0" + + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== + + minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + + minimatch@3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== + dependencies: + brace-expansion "^1.1.7" + + minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + + minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + + minimatch@^5.0.1, minimatch@^5.1.0: + version "5.1.6" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" + integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== + dependencies: + brace-expansion "^2.0.1" + + minimatch@^8.0.2: + version "8.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" + integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== + dependencies: + brace-expansion "^2.0.1" + + minimatch@^9.0.0, minimatch@^9.0.1: + version "9.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" + integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== + dependencies: + brace-expansion "^2.0.1" + + minimist-options@4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" + integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== + dependencies: + arrify "^1.0.1" + is-plain-obj "^1.1.0" + kind-of "^6.0.3" + + minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: + version "1.2.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" + integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== + + minipass-collect@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" + integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== + dependencies: + minipass "^3.0.0" + + minipass-fetch@^2.0.3: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" + integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + + minipass-fetch@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" + integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== + dependencies: + minipass "^7.0.3" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + + minipass-flush@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" + integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== + dependencies: + minipass "^3.0.0" + + minipass-json-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" + integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== + dependencies: + jsonparse "^1.3.1" + minipass "^3.0.0" + + minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" + integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== + dependencies: + minipass "^3.0.0" + + minipass-sized@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" + integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== + dependencies: + minipass "^3.0.0" + + minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: + version "3.3.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" + integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== + dependencies: + yallist "^4.0.0" + + minipass@^4.2.4: + version "4.2.8" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" + integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== + + minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + + "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: + version "7.0.4" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" + integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== + + minizlib@^2.1.1, minizlib@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" + integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== + dependencies: + minipass "^3.0.0" + yallist "^4.0.0" + + mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + + mixin-deep@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" + integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + + mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" + integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== + + mkdirp@^0.5.1, mkdirp@^0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + + mkdirp@^1.0.3, mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + + mobx@^6.1.7: + version "6.10.2" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.10.2.tgz#96e123deef140750360ca9a5b02a8b91fbffd4d9" + integrity sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ== + + mocha@^10.0.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" + integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== + dependencies: + ansi-colors "4.1.1" + browser-stdout "1.3.1" + chokidar "3.5.3" + debug "4.3.4" + diff "5.0.0" + escape-string-regexp "4.0.0" + find-up "5.0.0" + glob "7.2.0" + he "1.2.0" + js-yaml "4.1.0" + log-symbols "4.1.0" + minimatch "5.0.1" + ms "2.1.3" + nanoid "3.3.3" + serialize-javascript "6.0.0" + strip-json-comments "3.1.1" + supports-color "8.1.1" + workerpool "6.2.1" + yargs "16.2.0" + yargs-parser "20.2.4" + yargs-unparser "2.0.0" + + modify-values@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" + integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== + + moq.ts@^7.3.4: + version "7.4.1" + resolved "https://registry.yarnpkg.com/moq.ts/-/moq.ts-7.4.1.tgz#1bb7e808324dc5b0143fa8b1a94f539203d475cb" + integrity sha512-P97MjGUkkMKQrAHbNScyJvSv3S7pMxnuxd3HgaOrPuoC6okwPqru3ZX8W/mTdU7Ms74622MeeWHqoDaGyYKonw== + dependencies: + tslib "2.1.0" + + move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + + mri@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" + integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== + + ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== + + ms@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" + integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== + + ms@2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" + integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== + + ms@2.1.3, ms@^2.0.0, ms@^2.1.1: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + + multicast-dns@^7.2.5: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== + dependencies: + dns-packet "^5.2.2" + thunky "^1.0.2" + + multiformats@^9.4.2: + version "9.9.0" + resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" + integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== + + multimatch@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" + integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== + dependencies: + "@types/minimatch" "^3.0.3" + array-differ "^3.0.0" + array-union "^2.1.0" + arrify "^2.0.1" + minimatch "^3.0.4" + + mute-stream@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" + integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== + + mute-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" + integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== + + nan@^2.12.1, nan@^2.13.2: + version "2.18.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" + integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== + + nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== + + nanoid@3.3.3: + version "3.3.3" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" + integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== + + nanoid@^3.3.1, nanoid@^3.3.6: + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== + + nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + + napi-build-utils@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" + integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + + natural-compare-lite@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" + integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== + + natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== + + negotiator@0.6.3, negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + + neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" + integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== + + nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" + integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== + + nice-try@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" + integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== + + no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + + node-abi@^3.3.0: + version "3.51.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" + integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== + dependencies: + semver "^7.3.5" + + node-abort-controller@^3.0.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" + integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== + + node-addon-api@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" + integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== + + node-addon-api@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" + integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== + + node-addon-api@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" + integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + + node-dir@^0.1.10: + version "0.1.17" + resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" + integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== + dependencies: + minimatch "^3.0.2" + + node-fetch@2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + + node-fetch@^2.6.1, node-fetch@^2.6.7: + version "2.7.0" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" + integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== + dependencies: + whatwg-url "^5.0.0" + + node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== + + node-gyp-build@^4.3.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" + integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + + node-gyp@^9.0.0, node-gyp@^9.3.1: + version "9.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" + integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== + dependencies: + env-paths "^2.2.0" + exponential-backoff "^3.1.1" + glob "^7.1.4" + graceful-fs "^4.2.6" + make-fetch-happen "^10.0.3" + nopt "^6.0.0" + npmlog "^6.0.0" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.2" + which "^2.0.2" + + node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + + node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + + node-machine-id@1.1.12: + version "1.1.12" + resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" + integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== + + node-releases@^2.0.13: + version "2.0.13" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" + integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== + + nodemon@^2.0.21: + version "2.0.22" + resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" + integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== + dependencies: + chokidar "^3.5.2" + debug "^3.2.7" + ignore-by-default "^1.0.1" + minimatch "^3.1.2" + pstree.remy "^1.1.8" + semver "^5.7.1" + simple-update-notifier "^1.0.7" + supports-color "^5.5.0" + touch "^3.1.0" + undefsafe "^2.0.5" + + nopt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" + integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== + dependencies: + abbrev "^1.0.0" + + nopt@~1.0.10: + version "1.0.10" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" + integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== + dependencies: + abbrev "1" + + normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + + normalize-package-data@^3.0.0, normalize-package-data@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" + integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== + dependencies: + hosted-git-info "^4.0.1" + is-core-module "^2.5.0" + semver "^7.3.4" + validate-npm-package-license "^3.0.1" + + normalize-package-data@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" + integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== + dependencies: + hosted-git-info "^6.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + + normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== + dependencies: + remove-trailing-separator "^1.0.1" + + normalize-path@^3.0.0, normalize-path@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" + integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== + + normalize-range@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" + integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== + + normalize-url@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" + integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== + + notistack@^2.0.3: + version "2.0.8" + resolved "https://registry.yarnpkg.com/notistack/-/notistack-2.0.8.tgz#78cdf34c64e311bf1d1d71c2123396bcdea5e95b" + integrity sha512-/IY14wkFp5qjPgKNvAdfL5Jp6q90+MjgKTPh4c81r/lW70KeuX6b9pE/4f8L4FG31cNudbN9siiFS5ql1aSLRw== + dependencies: + clsx "^1.1.0" + hoist-non-react-statics "^3.3.0" + + npm-bundled@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" + integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== + dependencies: + npm-normalize-package-bin "^1.0.1" + + npm-bundled@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" + integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== + dependencies: + npm-normalize-package-bin "^3.0.0" + + npm-install-checks@^6.0.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" + integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== + dependencies: + semver "^7.1.1" + + npm-normalize-package-bin@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" + integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== + + npm-normalize-package-bin@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" + integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== + + npm-package-arg@8.1.1: + version "8.1.1" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" + integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== + dependencies: + hosted-git-info "^3.0.6" + semver "^7.0.0" + validate-npm-package-name "^3.0.0" + + npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" + integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== + dependencies: + hosted-git-info "^6.0.0" + proc-log "^3.0.0" + semver "^7.3.5" + validate-npm-package-name "^5.0.0" + + npm-packlist@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" + integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== + dependencies: + glob "^8.0.1" + ignore-walk "^5.0.1" + npm-bundled "^1.1.2" + npm-normalize-package-bin "^1.0.1" + + npm-packlist@^7.0.0: + version "7.0.4" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" + integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== + dependencies: + ignore-walk "^6.0.0" + + npm-pick-manifest@^8.0.0: + version "8.0.2" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" + integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== + dependencies: + npm-install-checks "^6.0.0" + npm-normalize-package-bin "^3.0.0" + npm-package-arg "^10.0.0" + semver "^7.3.5" + + npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: + version "14.0.5" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" + integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== + dependencies: + make-fetch-happen "^11.0.0" + minipass "^5.0.0" + minipass-fetch "^3.0.0" + minipass-json-stream "^1.0.1" + minizlib "^2.1.2" + npm-package-arg "^10.0.0" + proc-log "^3.0.0" + + npm-run-all@^4.1.5: + version "4.1.5" + resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" + integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== + dependencies: + ansi-styles "^3.2.1" + chalk "^2.4.1" + cross-spawn "^6.0.5" + memorystream "^0.3.1" + minimatch "^3.0.4" + pidtree "^0.3.0" + read-pkg "^3.0.0" + shell-quote "^1.6.1" + string.prototype.padend "^3.0.0" + + npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + + npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== + dependencies: + path-key "^3.0.0" + + npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + + npmlog@^6.0.0, npmlog@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" + integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.3" + set-blocking "^2.0.0" + + nth-check@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" + integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== + dependencies: + boolbase "^1.0.0" + + num2fraction@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" + integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== + + nwsapi@^2.2.0: + version "2.2.7" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" + integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== + + nx@16.10.0, "nx@>=16.5.1 < 17": + version "16.10.0" + resolved "https://registry.yarnpkg.com/nx/-/nx-16.10.0.tgz#b070461f7de0a3d7988bd78558ea84cda3543ace" + integrity sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg== + dependencies: + "@nrwl/tao" "16.10.0" + "@parcel/watcher" "2.0.4" + "@yarnpkg/lockfile" "^1.1.0" + "@yarnpkg/parsers" "3.0.0-rc.46" + "@zkochan/js-yaml" "0.0.6" + axios "^1.0.0" + chalk "^4.1.0" + cli-cursor "3.1.0" + cli-spinners "2.6.1" + cliui "^8.0.1" + dotenv "~16.3.1" + dotenv-expand "~10.0.0" + enquirer "~2.3.6" + figures "3.2.0" + flat "^5.0.2" + fs-extra "^11.1.0" + glob "7.1.4" + ignore "^5.0.4" + jest-diff "^29.4.1" + js-yaml "4.1.0" + jsonc-parser "3.2.0" + lines-and-columns "~2.0.3" + minimatch "3.0.5" + node-machine-id "1.1.12" + npm-run-path "^4.0.1" + open "^8.4.0" + semver "7.5.3" + string-width "^4.2.3" + strong-log-transformer "^2.1.0" + tar-stream "~2.2.0" + tmp "~0.2.1" + tsconfig-paths "^4.1.2" + tslib "^2.3.0" + v8-compile-cache "2.3.0" + yargs "^17.6.2" + yargs-parser "21.1.1" + optionalDependencies: + "@nx/nx-darwin-arm64" "16.10.0" + "@nx/nx-darwin-x64" "16.10.0" + "@nx/nx-freebsd-x64" "16.10.0" + "@nx/nx-linux-arm-gnueabihf" "16.10.0" + "@nx/nx-linux-arm64-gnu" "16.10.0" + "@nx/nx-linux-arm64-musl" "16.10.0" + "@nx/nx-linux-x64-gnu" "16.10.0" + "@nx/nx-linux-x64-musl" "16.10.0" + "@nx/nx-win32-arm64-msvc" "16.10.0" + "@nx/nx-win32-x64-msvc" "16.10.0" + + object-assign@^4.0.1, object-assign@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + + object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + + object-inspect@^1.13.1, object-inspect@^1.9.0: + version "1.13.1" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" + integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== + + object-is@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" + integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + + object-keys@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" + integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== + + object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== + dependencies: + isobject "^3.0.0" + + object.assign@^4.1.2, object.assign@^4.1.4: + version "4.1.4" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" + integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + has-symbols "^1.0.3" + object-keys "^1.1.1" + + object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.6, object.entries@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" + integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + "object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.6, object.fromentries@^2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" + integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: + version "2.1.7" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz#7a466a356cd7da4ba8b9e94ff6d35c3eeab5d56a" + integrity sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g== + dependencies: + array.prototype.reduce "^1.0.6" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + safe-array-concat "^1.0.0" + + object.groupby@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" + integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + + object.hasown@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" + integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== + dependencies: + define-properties "^1.2.0" + es-abstract "^1.22.1" + + object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== + dependencies: + isobject "^3.0.1" + + object.values@^1.1.0, object.values@^1.1.6, object.values@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" + integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + objectorarray@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" + integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== + + obuf@^1.0.0, obuf@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" + integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + + on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + + on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + + on-headers@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" + integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== + + once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== + dependencies: + wrappy "1" + + onetime@^5.1.0, onetime@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" + integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== + dependencies: + mimic-fn "^2.1.0" + + open@^7.0.3: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + + open@^8.0.9, open@^8.4.0: + version "8.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" + integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== + dependencies: + define-lazy-prop "^2.0.0" + is-docker "^2.1.1" + is-wsl "^2.2.0" + + optionator@^0.9.1, optionator@^0.9.3: + version "0.9.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" + integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== + dependencies: + "@aashutoshrathi/word-wrap" "^1.2.3" + deep-is "^0.1.3" + fast-levenshtein "^2.0.6" + levn "^0.4.1" + prelude-ls "^1.2.1" + type-check "^0.4.0" + + ora@^5.4.1: + version "5.4.1" + resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" + integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== + dependencies: + bl "^4.1.0" + chalk "^4.1.0" + cli-cursor "^3.1.0" + cli-spinners "^2.5.0" + is-interactive "^1.0.0" + is-unicode-supported "^0.1.0" + log-symbols "^4.1.0" + strip-ansi "^6.0.0" + wcwidth "^1.0.1" + + os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + + os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== + + os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== + + outdent@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.8.0.tgz#2ebc3e77bf49912543f1008100ff8e7f44428eb0" + integrity sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A== + + p-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" + integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== + dependencies: + p-map "^2.0.0" + + p-defer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" + integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== + + p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + + p-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" + integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== + dependencies: + p-map "^2.0.0" + + p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== + + p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== + dependencies: + p-try "^1.0.0" + + p-limit@^2.0.0, p-limit@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" + integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== + dependencies: + p-try "^2.0.0" + + p-limit@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== + dependencies: + yocto-queue "^0.1.0" + + p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== + dependencies: + p-limit "^1.1.0" + + p-locate@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" + integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== + dependencies: + p-limit "^2.0.0" + + p-locate@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" + integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== + dependencies: + p-limit "^2.2.0" + + p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + + p-map-series@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" + integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== + + p-map@4.0.0, p-map@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" + integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== + dependencies: + aggregate-error "^3.0.0" + + p-map@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" + integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== + + p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + + p-pipe@3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" + integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== + + p-queue@6.6.2: + version "6.6.2" + resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" + integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== + dependencies: + eventemitter3 "^4.0.4" + p-timeout "^3.2.0" + + p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" + integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== + + p-retry@^4.5.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" + integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== + dependencies: + "@types/retry" "0.12.0" + retry "^0.13.1" + + p-timeout@^3.1.0, p-timeout@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" + + p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== + + p-try@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" + integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== + + p-waterfall@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" + integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== + dependencies: + p-reduce "^2.0.0" + + pacote@^15.2.0: + version "15.2.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" + integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== + dependencies: + "@npmcli/git" "^4.0.0" + "@npmcli/installed-package-contents" "^2.0.1" + "@npmcli/promise-spawn" "^6.0.1" + "@npmcli/run-script" "^6.0.0" + cacache "^17.0.0" + fs-minipass "^3.0.0" + minipass "^5.0.0" + npm-package-arg "^10.0.0" + npm-packlist "^7.0.0" + npm-pick-manifest "^8.0.0" + npm-registry-fetch "^14.0.0" + proc-log "^3.0.0" + promise-retry "^2.0.1" + read-package-json "^6.0.0" + read-package-json-fast "^3.0.0" + sigstore "^1.3.0" + ssri "^10.0.0" + tar "^6.1.11" + + pako@^2.0.2: + version "2.1.0" + resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" + integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== + + pako@~1.0.5: + version "1.0.11" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" + integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== + + parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + + param-case@^3.0.3, param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + + parent-module@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" + integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== + dependencies: + callsites "^3.0.0" + + parse-asn1@^5.0.0, parse-asn1@^5.1.6: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + + parse-author@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" + integrity sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw== + dependencies: + author-regex "^1.0.0" + + parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + 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" + + parse-entities@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" + integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== + dependencies: + "@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" + + parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + + parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + + parse-json@^5.0.0, parse-json@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" + integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== + dependencies: + "@babel/code-frame" "^7.0.0" + error-ex "^1.3.1" + json-parse-even-better-errors "^2.3.0" + lines-and-columns "^1.1.6" + + parse-path@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.0.tgz#605a2d58d0a749c8594405d8cc3a2bf76d16099b" + integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== + dependencies: + protocols "^2.0.0" + + parse-url@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" + integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== + dependencies: + parse-path "^7.0.0" + + parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + + parseurl@~1.3.2, parseurl@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" + integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== + + pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + + pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + + path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + + path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + + path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + + path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" + + path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== + + path-exists@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" + integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== + + path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== + + path-is-inside@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" + integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== + + path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + + path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + + path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + + path-scurry@^1.10.1, path-scurry@^1.6.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" + integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== + dependencies: + lru-cache "^9.1.1 || ^10.0.0" + minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + + path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== + + path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + + path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + + path-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" + integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + + pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + + periscopic@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" + integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^3.0.0" + is-reference "^3.0.0" + + picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + + picocolors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" + integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== + + picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + + pidtree@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" + integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== + + pify@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== + + pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== + + pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + + pify@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" + integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== + + pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== + dependencies: + pinkie "^2.0.0" + + pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== + + pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" + + pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + + pino@7.11.0: + version "7.11.0" + resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" + integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.15.1" + + pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: + version "4.0.6" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" + integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== + + pkg-dir@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" + integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== + dependencies: + find-up "^3.0.0" + + pkg-dir@^4.1.0, pkg-dir@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" + integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== + dependencies: + find-up "^4.0.0" + + pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + + pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + + polished@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1" + integrity sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ== + dependencies: + "@babel/runtime" "^7.17.8" + + posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== + + postcss-calc@^8.2.3: + version "8.2.4" + resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" + integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== + dependencies: + postcss-selector-parser "^6.0.9" + postcss-value-parser "^4.2.0" + + postcss-colormin@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" + integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + colord "^2.9.1" + postcss-value-parser "^4.2.0" + + postcss-convert-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" + integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + + postcss-discard-comments@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" + integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== + + postcss-discard-duplicates@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" + integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== + + postcss-discard-empty@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" + integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== + + postcss-discard-overridden@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" + integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== + + postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== + dependencies: + postcss "^7.0.26" + + postcss-loader@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" + integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.4" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" + + postcss-merge-longhand@^5.1.7: + version "5.1.7" + resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" + integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== + dependencies: + postcss-value-parser "^4.2.0" + stylehacks "^5.1.1" + + postcss-merge-rules@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" + integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + cssnano-utils "^3.1.0" + postcss-selector-parser "^6.0.5" + + postcss-minify-font-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" + integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-minify-gradients@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" + integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== + dependencies: + colord "^2.9.1" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + + postcss-minify-params@^5.1.4: + version "5.1.4" + resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" + integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== + dependencies: + browserslist "^4.21.4" + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + + postcss-minify-selectors@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" + integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== + dependencies: + postcss-selector-parser "^6.0.5" + + postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== + dependencies: + postcss "^7.0.5" + + postcss-modules-extract-imports@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" + integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== + + postcss-modules-local-by-default@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + + postcss-modules-local-by-default@^4.0.0, postcss-modules-local-by-default@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" + integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== + dependencies: + icss-utils "^5.0.0" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + + postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + + postcss-modules-scope@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" + integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== + dependencies: + postcss-selector-parser "^6.0.4" + + postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + + postcss-modules-values@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" + integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== + dependencies: + icss-utils "^5.0.0" + + postcss-normalize-charset@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" + integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== + + postcss-normalize-display-values@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" + integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-normalize-positions@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" + integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-normalize-repeat-style@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" + integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-normalize-string@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" + integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-normalize-timing-functions@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" + integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-normalize-unicode@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" + integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== + dependencies: + browserslist "^4.21.4" + postcss-value-parser "^4.2.0" + + postcss-normalize-url@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" + integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== + dependencies: + normalize-url "^6.0.1" + postcss-value-parser "^4.2.0" + + postcss-normalize-whitespace@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" + integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-ordered-values@^5.1.3: + version "5.1.3" + resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" + integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== + dependencies: + cssnano-utils "^3.1.0" + postcss-value-parser "^4.2.0" + + postcss-reduce-initial@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" + integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== + dependencies: + browserslist "^4.21.4" + caniuse-api "^3.0.0" + + postcss-reduce-transforms@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" + integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== + dependencies: + postcss-value-parser "^4.2.0" + + postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: + version "6.0.13" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" + integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + + postcss-svgo@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" + integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== + dependencies: + postcss-value-parser "^4.2.0" + svgo "^2.7.0" + + postcss-unique-selectors@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" + integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== + dependencies: + postcss-selector-parser "^6.0.5" + + postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== + + postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== + dependencies: + picocolors "^0.2.1" + source-map "^0.6.1" + + postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.21: + version "8.4.31" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" + integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + dependencies: + nanoid "^3.3.6" + picocolors "^1.0.0" + source-map-js "^1.0.2" + + prebuild-install@^7.0.0, prebuild-install@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" + integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== + dependencies: + detect-libc "^2.0.0" + expand-template "^2.0.3" + github-from-package "0.0.0" + minimist "^1.2.3" + mkdirp-classic "^0.5.3" + napi-build-utils "^1.0.1" + node-abi "^3.3.0" + pump "^3.0.0" + rc "^1.2.7" + simple-get "^4.0.0" + tar-fs "^2.0.0" + tunnel-agent "^0.6.0" + + prelude-ls@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" + integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== + + prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + + "prettier@>=2.2.1 <=2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" + integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== + + prettier@^2.8.7: + version "2.8.8" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" + integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== + + pretty-bytes@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b" + integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ== + + pretty-error@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== + dependencies: + lodash "^4.17.20" + renderkid "^2.0.4" + + pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + + pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + + pretty-format@^28.1.3: + version "28.1.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" + integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== + dependencies: + "@jest/schemas" "^28.1.3" + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^18.0.0" + + pretty-format@^29.0.0, pretty-format@^29.7.0: + version "29.7.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" + integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== + dependencies: + "@jest/schemas" "^29.6.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + + pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + + proc-log@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" + integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== + + process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" + integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + + process-warning@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + + process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + + progress@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" + integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== + + promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== + + promise-retry@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" + integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== + dependencies: + err-code "^2.0.2" + retry "^0.12.0" + + promise.allsettled@^1.0.0: + version "1.0.7" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.7.tgz#b9dd51e9cffe496243f5271515652c468865f2d8" + integrity sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA== + dependencies: + array.prototype.map "^1.0.5" + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + iterate-value "^1.0.2" + + promise.prototype.finally@^3.1.0: + version "3.1.7" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.7.tgz#9d163f58edf3004d14878c988a22b1cb45e03407" + integrity sha512-iL9OcJRUZcCE5xn6IwhZxO+eMM0VEXjkETHy+Nk+d9q3s7kxVtPg+mBlMO+ZGxNKNMODyKmy/bOyt/yhxTnvEw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.1" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + set-function-name "^2.0.1" + + prompts@^2.0.1, prompts@^2.4.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + + promzard@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b" + integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig== + dependencies: + read "^2.0.0" + + prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + + property-expr@^2.0.4, property-expr@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" + integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== + + property-information@^5.0.0, property-information@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== + dependencies: + xtend "^4.0.0" + + property-information@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.4.0.tgz#6bc4c618b0c2d68b3bb8b552cbb97f8e300a0f82" + integrity sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ== + + protobufjs@^6.11.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: + version "6.11.4" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" + integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" ">=13.7.0" + long "^4.0.0" + + protobufjs@~6.10.2: + version "6.10.3" + resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef" + integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg== + dependencies: + "@protobufjs/aspromise" "^1.1.2" + "@protobufjs/base64" "^1.1.2" + "@protobufjs/codegen" "^2.0.4" + "@protobufjs/eventemitter" "^1.1.0" + "@protobufjs/fetch" "^1.1.0" + "@protobufjs/float" "^1.0.2" + "@protobufjs/inquire" "^1.1.0" + "@protobufjs/path" "^1.1.2" + "@protobufjs/pool" "^1.1.0" + "@protobufjs/utf8" "^1.1.0" + "@types/long" "^4.0.1" + "@types/node" "^13.7.0" + long "^4.0.0" + + protocols@^2.0.0, protocols@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" + integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== + + proxy-addr@~2.0.7: + version "2.0.7" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" + integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== + dependencies: + forwarded "0.2.0" + ipaddr.js "1.9.1" + + proxy-from-env@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" + integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== + + prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== + + psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + + pstree.remy@^1.1.8: + version "1.1.8" + resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" + integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== + + public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + + pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pump@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" + integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + + pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + + punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== + + punycode@^2.1.0, punycode@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" + integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== + + qr.js@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" + integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ== + + qrcode.react@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.1.tgz#2834bb50e5e275ffe5af6906eff15391fe9e38a5" + integrity sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg== + dependencies: + loose-envify "^1.4.0" + prop-types "^15.6.0" + qr.js "0.0.0" + + qs@6.11.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" + + qs@^6.10.0, qs@^6.11.2: + version "6.11.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" + integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== + dependencies: + side-channel "^1.0.4" + + query-string@7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" + integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== + dependencies: + decode-uri-component "^0.2.2" + filter-obj "^1.1.0" + split-on-first "^1.0.0" + strict-uri-encode "^2.0.0" + + querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + + querystringify@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" + integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== + + queue-microtask@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" + integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== + + queue-tick@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" + integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== + + quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + + quick-lru@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" + integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== + + rainbow-sprinkles@^0.17.0: + version "0.17.0" + resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.0.tgz#6ee06c6decc767b89bf01fc5fe87ecf859fd4c2f" + integrity sha512-ok3NrylQ0szvJtuBYaB/w09L9zOvvqcSQrvycT2A5XJxQNvwvkeADvTqQWGOQ3b6MkO8UmYccBPt8g8vVvxM9A== + + rambda@^7.4.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.5.0.tgz#1865044c59bc0b16f63026c6e5a97e4b1bbe98fe" + integrity sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA== + + ramda@0.29.0: + version "0.29.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.0.tgz#fbbb67a740a754c8a4cbb41e2a6e0eb8507f55fb" + integrity sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA== + + ramda@^0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" + integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== + + ramda@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" + integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== + + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" + integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== + dependencies: + safe-buffer "^5.1.0" + + randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + + range-parser@^1.2.1, range-parser@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" + integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== + + raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== + dependencies: + bytes "3.1.2" + http-errors "2.0.0" + iconv-lite "0.4.24" + unpipe "1.0.0" + + raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + + rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + + react-aria@^3.29.1: + version "3.29.1" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.29.1.tgz#4f6e968a15cfec69d8d8735b98d0fe8ac31b4be2" + integrity sha512-dDoaTh5fCaD3kO0kv49pqUUOsXRGuqFX7owQaly/RhWkBw/dlIYkHRVdOatllI/v4h1/Ne40QOXl15aAISozlA== + dependencies: + "@react-aria/breadcrumbs" "^3.5.7" + "@react-aria/button" "^3.8.4" + "@react-aria/calendar" "^3.5.2" + "@react-aria/checkbox" "^3.11.2" + "@react-aria/combobox" "^3.7.1" + "@react-aria/datepicker" "^3.8.1" + "@react-aria/dialog" "^3.5.7" + "@react-aria/dnd" "^3.4.3" + "@react-aria/focus" "^3.14.3" + "@react-aria/gridlist" "^3.7.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/link" "^3.6.1" + "@react-aria/listbox" "^3.11.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/meter" "^3.4.7" + "@react-aria/numberfield" "^3.9.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/progress" "^3.4.7" + "@react-aria/radio" "^3.8.2" + "@react-aria/searchfield" "^3.5.7" + "@react-aria/select" "^3.13.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/separator" "^3.3.7" + "@react-aria/slider" "^3.7.2" + "@react-aria/ssr" "^3.8.0" + "@react-aria/switch" "^3.5.6" + "@react-aria/table" "^3.13.1" + "@react-aria/tabs" "^3.8.1" + "@react-aria/tag" "^3.2.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/tooltip" "^3.6.4" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-types/shared" "^3.21.0" + + react-docgen-typescript@^2.1.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" + integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== + + react-docgen@^5.0.0: + version "5.4.3" + resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" + integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== + dependencies: + "@babel/core" "^7.7.5" + "@babel/generator" "^7.12.11" + "@babel/runtime" "^7.7.6" + ast-types "^0.14.2" + commander "^2.19.0" + doctrine "^3.0.0" + estree-to-babel "^3.1.0" + neo-async "^2.6.1" + node-dir "^0.1.10" + strip-indent "^3.0.0" + + react-dom@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" + integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== + dependencies: + loose-envify "^1.1.0" + scheduler "^0.23.0" + + react-element-to-jsx-string@^14.3.4: + version "14.3.4" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz#709125bc72f06800b68f9f4db485f2c7d31218a8" + integrity sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg== + dependencies: + "@base2/pretty-print-object" "1.0.1" + is-plain-object "5.0.0" + react-is "17.0.2" + + react-error-boundary@^3.1.3, react-error-boundary@^3.1.4: + version "3.1.4" + resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" + integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== + dependencies: + "@babel/runtime" "^7.12.5" + + react-google-charts@^3.0.15: + version "3.0.15" + resolved "https://registry.yarnpkg.com/react-google-charts/-/react-google-charts-3.0.15.tgz#30759a470f48336e744fd383d054122b039a1ff2" + integrity sha512-78s5xOQOJvL+jIewrWQZEHtlVk+5Yh4zZy+ODA1on1o1FaRjKWXxoo4n4JQl1XuqkF/A9NWque3KqM6pMggjzQ== + dependencies: + react-load-script "^0.0.6" + + react-hook-form@^7.14.2: + version "7.48.2" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" + integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== + + react-identicons@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/react-identicons/-/react-identicons-1.2.5.tgz#3502249e49d88f4e3500092694410a984bb102fa" + integrity sha512-x7prkDoc2pD7wSl2C1pGxS+XAoSdq1ABWJWTBUimVTDVJArKOLd0B4wRUJpDm4r+9y7pgf8ylyPGsmlWSV5n2g== + + react-inspector@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" + integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== + dependencies: + "@babel/runtime" "^7.0.0" + is-dom "^1.0.0" + prop-types "^15.0.0" + + react-is@17.0.2, react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + + react-is@^16.10.2, react-is@^16.13.1, react-is@^16.7.0: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + + react-is@^18.0.0, react-is@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" + integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== + + react-lifecycles-compat@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" + integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== + + react-load-script@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/react-load-script/-/react-load-script-0.0.6.tgz#db6851236aaa25bb622677a2eb51dad4f8d2c258" + integrity sha512-aRGxDGP9VoLxcsaYvKWIW+LRrMOzz2eEcubTS4NvQPPugjk2VvMhow0wWTkSl7RxookomD1MwcP4l5UStg5ShQ== + + react-markdown@^8.0.4: + version "8.0.7" + resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.7.tgz#c8dbd1b9ba5f1c5e7e5f2a44de465a3caafdf89b" + integrity sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== + dependencies: + "@types/hast" "^2.0.0" + "@types/prop-types" "^15.0.0" + "@types/unist" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-whitespace "^2.0.0" + prop-types "^15.0.0" + property-information "^6.0.0" + react-is "^18.0.0" + remark-parse "^10.0.0" + remark-rehype "^10.0.0" + space-separated-tokens "^2.0.0" + style-to-object "^0.4.0" + unified "^10.0.0" + unist-util-visit "^4.0.0" + vfile "^5.0.0" + + react-merge-refs@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" + integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== + + react-refresh-typescript@^2.0.2: + version "2.0.9" + resolved "https://registry.yarnpkg.com/react-refresh-typescript/-/react-refresh-typescript-2.0.9.tgz#f8a86efcb34f8d717100230564b9b57477d74b10" + integrity sha512-chAnOO4vpxm/3WkgOVmti+eN8yUtkJzeGkOigV6UA9eDFz12W34e/SsYe2H5+RwYJ3+sfSZkVbiXcG1chEBxlg== + + react-refresh@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3" + integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ== + + react-refresh@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" + integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== + + react-resize-detector@^8.0.4: + version "8.1.0" + resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-8.1.0.tgz#1c7817db8bc886e2dbd3fbe3b26ea8e56be0524a" + integrity sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w== + dependencies: + lodash "^4.17.21" + + react-router-dom@6, react-router-dom@^6.7.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.18.0.tgz#0a50c167209d6e7bd2ed9de200a6579ea4fb1dca" + integrity sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw== + dependencies: + "@remix-run/router" "1.11.0" + react-router "6.18.0" + + react-router@6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.18.0.tgz#32e2bedc318e095a48763b5ed7758e54034cd36a" + integrity sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg== + dependencies: + "@remix-run/router" "1.11.0" + + react-simple-maps@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/react-simple-maps/-/react-simple-maps-2.3.0.tgz#7fdb55120335a9b1ef5bf62e0dcb669511705f3e" + integrity sha512-IZVeiPSRZKwD6I/2NvXpQ2uENYGDGZp8DvZjkapcxuJ/LQHTfl+Byb+KNgY7s+iatRA2ad8LnZ3AgqcjziCCsw== + dependencies: + d3-geo "^2.0.1" + d3-selection "^2.0.0" + d3-zoom "^2.0.0" + topojson-client "^3.1.0" + + react-smooth@^2.0.4: + version "2.0.5" + resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" + integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== + dependencies: + fast-equals "^5.0.0" + react-transition-group "2.9.0" + + react-stately@^3.27.1: + version "3.27.1" + resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.27.1.tgz#b24992bd72da1b1632bf4f4232d87ce6913a19bd" + integrity sha512-qHhivqOpyATaWwoj3xl3IqqoEnib+dsl2vYlOz92CT5Ntm6lprF7KO+LkxdkS0SnUckdGewFM1NjCmbK7wPJgw== + dependencies: + "@react-stately/calendar" "^3.4.1" + "@react-stately/checkbox" "^3.5.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/combobox" "^3.7.1" + "@react-stately/data" "^3.10.3" + "@react-stately/datepicker" "^3.8.0" + "@react-stately/dnd" "^3.2.5" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/numberfield" "^3.6.2" + "@react-stately/overlays" "^3.6.3" + "@react-stately/radio" "^3.9.1" + "@react-stately/searchfield" "^3.4.6" + "@react-stately/select" "^3.5.5" + "@react-stately/selection" "^3.14.0" + "@react-stately/slider" "^3.4.4" + "@react-stately/table" "^3.11.2" + "@react-stately/tabs" "^3.6.1" + "@react-stately/toggle" "^3.6.3" + "@react-stately/tooltip" "^3.4.5" + "@react-stately/tree" "^3.7.3" + "@react-types/shared" "^3.21.0" + + react-tooltip@*: + version "5.22.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.22.0.tgz#3082065b1efbd207813f484b617b1b75325f15d5" + integrity sha512-xbJBRY1LyHYd7j00UeBOqZR9SH/1S47Pe+m8vM1a+ZXglkeSNnBt5YYoPttU/amjC/VZJAPQ8+2B9x8Fl8U1qA== + dependencies: + "@floating-ui/dom" "^1.0.0" + classnames "^2.3.0" + + react-tooltip@^4.2.21: + version "4.5.1" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-4.5.1.tgz#77eccccdf16adec804132e558ec20ca5783b866a" + integrity sha512-Zo+CSFUGXar1uV+bgXFFDe7VeS2iByeIp5rTgTcc2HqtuOS5D76QapejNNfx320MCY91TlhTQat36KGFTqgcvw== + dependencies: + prop-types "^15.8.1" + uuid "^7.0.3" + + react-transition-group@2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" + integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== + dependencies: + dom-helpers "^3.4.0" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react-lifecycles-compat "^3.0.4" + + react-transition-group@^4.4.5: + version "4.4.5" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" + integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + + react@^18.2.0: + version "18.2.0" + resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" + integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== + dependencies: + loose-envify "^1.1.0" + + read-cmd-shim@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" + integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== + + read-package-json-fast@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" + integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== + dependencies: + json-parse-even-better-errors "^3.0.0" + npm-normalize-package-bin "^3.0.0" + + read-package-json@6.0.4, read-package-json@^6.0.0: + version "6.0.4" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" + integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== + dependencies: + glob "^10.2.2" + json-parse-even-better-errors "^3.0.0" + normalize-package-data "^5.0.0" + npm-normalize-package-bin "^3.0.0" + + read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + + read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + + read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + + read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + + read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + + read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + + read@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/read/-/read-2.1.0.tgz#69409372c54fe3381092bc363a00650b6ac37218" + integrity sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ== + dependencies: + mute-stream "~1.0.0" + + "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" + integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + + readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + + readdirp@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" + integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== + dependencies: + graceful-fs "^4.1.11" + micromatch "^3.1.10" + readable-stream "^2.0.2" + + readdirp@~3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" + integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== + dependencies: + picomatch "^2.2.1" + + readonly-date@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" + integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== + + real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + + recharts-scale@^0.4.4: + version "0.4.5" + resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" + integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== + dependencies: + decimal.js-light "^2.4.1" + + recharts@^2.1.13: + version "2.9.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.2.tgz#a6a4e4c2887467ea57abde7e3af5c8021355a606" + integrity sha512-ig0zYgO5nUP/896GW16b9yy2sHIRW1AHB90x48hypFTSjjxQt/J9rPzlLJjgNupzJKEHPCwMi1VnvN/k20K45w== + dependencies: + classnames "^2.2.5" + eventemitter3 "^4.0.1" + lodash "^4.17.19" + react-is "^16.10.2" + react-resize-detector "^8.0.4" + react-smooth "^2.0.4" + recharts-scale "^0.4.4" + tiny-invariant "^1.3.1" + victory-vendor "^36.6.8" + + rechoir@^0.7.0: + version "0.7.1" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" + integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== + dependencies: + resolve "^1.9.0" + + redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + + redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + + reflect.getprototypeof@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" + integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + globalthis "^1.0.3" + which-builtin-type "^1.1.3" + + regenerate-unicode-properties@^10.1.0: + version "10.1.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" + integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== + dependencies: + regenerate "^1.4.2" + + regenerate@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" + integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== + + regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.7: + version "0.13.11" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" + integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== + + regenerator-runtime@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" + integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== + + regenerator-transform@^0.15.2: + version "0.15.2" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" + integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== + dependencies: + "@babel/runtime" "^7.8.4" + + regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + + regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" + integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + set-function-name "^2.0.0" + + regexpp@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" + integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== + + regexpu-core@^5.3.1: + version "5.3.2" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" + integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== + dependencies: + "@babel/regjsgen" "^0.8.0" + regenerate "^1.4.2" + regenerate-unicode-properties "^10.1.0" + regjsparser "^0.9.1" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + + regjsparser@^0.9.1: + version "0.9.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" + integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== + dependencies: + jsesc "~0.5.0" + + relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + + remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^4.0.0" + space-separated-tokens "^1.0.0" + unist-util-visit "^2.0.0" + + remark-footnotes@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" + integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== + + remark-mdx@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" + integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== + 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" + + remark-mdx@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-2.3.0.tgz#efe678025a8c2726681bde8bf111af4a93943db4" + integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g== + dependencies: + mdast-util-mdx "^2.0.0" + micromark-extension-mdxjs "^1.0.0" + + remark-parse@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" + 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" + + remark-parse@^10.0.0: + version "10.0.2" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.2.tgz#ca241fde8751c2158933f031a4e3efbaeb8bc262" + integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== + dependencies: + "@types/mdast" "^3.0.0" + mdast-util-from-markdown "^1.0.0" + unified "^10.0.0" + + remark-rehype@^10.0.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279" + integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== + dependencies: + "@types/hast" "^2.0.0" + "@types/mdast" "^3.0.0" + mdast-util-to-hast "^12.1.0" + unified "^10.0.0" + + remark-slug@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" + integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + + remark-squeeze-paragraphs@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" + integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== + dependencies: + mdast-squeeze-paragraphs "^4.0.0" + + remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + + renderkid@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" + integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^3.0.1" + + renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" + + repeat-element@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" + integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== + + repeat-string@^1.5.4, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== + + repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== + dependencies: + is-finite "^1.0.0" + + replace-ext@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" + integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== + + require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== + + require-from-string@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" + integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== + + requireindex@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" + integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== + + requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + + reselect@^4.1.6: + version "4.1.8" + resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" + integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== + + resolve-cwd@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" + integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== + dependencies: + resolve-from "^5.0.0" + + resolve-from@5.0.0, resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + + resolve-from@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" + integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== + + resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== + + resolve.exports@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" + integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== + + resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.3.2, resolve@^1.9.0: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + + resolve@^2.0.0-next.4: + version "2.0.0-next.5" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" + integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + + restore-cursor@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" + integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== + dependencies: + onetime "^5.1.0" + signal-exit "^3.0.2" + + ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== + + retry@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" + integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== + + retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + + reusify@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" + integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== + + rgb-hex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-3.0.0.tgz#eab0168cc1279563b18a14605315389142e2e487" + integrity sha512-8h7ZcwxCBDKvchSWbWngJuSCqJGQ6nDuLLg+QcRyQDbX9jMWt+PpPeXAhSla0GOooEomk3lCprUpGkMdsLjKyg== + + rimraf@^2.5.4, rimraf@^2.6.3: + version "2.7.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" + integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== + dependencies: + glob "^7.1.3" + + rimraf@^3.0.0, rimraf@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" + integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== + dependencies: + glob "^7.1.3" + + rimraf@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" + integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== + dependencies: + glob "^9.2.0" + + ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + + rollup-plugin-dts@^5.0.0, rollup-plugin-dts@^5.2.0: + version "5.3.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-5.3.1.tgz#c2841269a3a5cb986b7791b0328e6a178eba108f" + integrity sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg== + dependencies: + magic-string "^0.30.2" + optionalDependencies: + "@babel/code-frame" "^7.22.5" + + rollup-plugin-inject@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz#e4233855bfba6c0c12a312fd6649dff9a13ee9f4" + integrity sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== + dependencies: + estree-walker "^0.6.1" + magic-string "^0.25.3" + rollup-pluginutils "^2.8.1" + + rollup-plugin-node-polyfills@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz#53092a2744837164d5b8a28812ba5f3ff61109fd" + integrity sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== + dependencies: + rollup-plugin-inject "^3.0.0" + + rollup-pluginutils@^2.8.1: + version "2.8.2" + resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" + integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== + dependencies: + estree-walker "^0.6.1" + + rollup@^3.17.2, rollup@^3.2.1: + version "3.29.4" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" + integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== + optionalDependencies: + fsevents "~2.3.2" + + rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + + run-async@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" + integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== + + run-parallel@^1.1.9: + version "1.2.0" + resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" + integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== + dependencies: + queue-microtask "^1.2.2" + + run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== + dependencies: + aproba "^1.1.1" + + rxjs@^7.5.5: + version "7.8.1" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" + integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== + dependencies: + tslib "^2.1.0" + + sade@^1.7.3: + version "1.8.1" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" + integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== + dependencies: + mri "^1.1.0" + + safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" + integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + isarray "^2.0.5" + + safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== + + safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== + + safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + + safe-json-utils@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" + integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== + + safe-regex-test@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" + integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.3" + is-regex "^1.1.4" + + safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== + dependencies: + ret "~0.1.10" + + safe-stable-stringify@^2.1.0: + version "2.4.3" + resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + + "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== + + sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + + sax@>=0.6.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" + integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== + + saxes@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" + integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== + dependencies: + xmlchars "^2.2.0" + + scheduler@^0.23.0: + version "0.23.0" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" + integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== + dependencies: + loose-envify "^1.1.0" + + schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + + schema-utils@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" + integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== + dependencies: + ajv "^6.1.0" + ajv-errors "^1.0.0" + ajv-keywords "^3.1.0" + + schema-utils@^2.6.5, schema-utils@^2.7.0: + version "2.7.1" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" + integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== + dependencies: + "@types/json-schema" "^7.0.5" + ajv "^6.12.4" + ajv-keywords "^3.5.2" + + schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" + integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== + dependencies: + "@types/json-schema" "^7.0.8" + ajv "^6.12.5" + ajv-keywords "^3.5.2" + + schema-utils@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" + integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.9.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.1.0" + + select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== + + selfsigned@^2.1.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" + integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== + dependencies: + "@types/node-forge" "^1.3.0" + node-forge "^1" + + "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: + version "5.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" + integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== + + semver@7.5.3: + version "7.5.3" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" + integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== + dependencies: + lru-cache "^6.0.0" + + semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== + dependencies: + lru-cache "^6.0.0" + + semver@^6.0.0, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: + version "6.3.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" + integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== + + semver@~7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + + send@0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== + dependencies: + debug "2.6.9" + depd "2.0.0" + destroy "1.2.0" + encodeurl "~1.0.2" + escape-html "~1.0.3" + etag "~1.8.1" + fresh "0.5.2" + http-errors "2.0.0" + mime "1.6.0" + ms "2.1.3" + on-finished "2.4.1" + range-parser "~1.2.1" + statuses "2.0.1" + + serialize-javascript@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" + integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== + dependencies: + randombytes "^2.1.0" + + serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + + serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" + + serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" + integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== + dependencies: + randombytes "^2.1.0" + + serve-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA== + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + + serve-index@^1.9.1: + version "1.9.1" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" + integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== + dependencies: + accepts "~1.3.4" + batch "0.6.1" + debug "2.6.9" + escape-html "~1.0.3" + http-errors "~1.6.2" + mime-types "~2.1.17" + parseurl "~1.3.2" + + serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== + dependencies: + encodeurl "~1.0.2" + escape-html "~1.0.3" + parseurl "~1.3.3" + send "0.18.0" + + set-blocking@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== + + set-function-length@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" + integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== + dependencies: + define-data-property "^1.1.1" + get-intrinsic "^1.2.1" + gopd "^1.0.1" + has-property-descriptors "^1.0.0" + + set-function-name@^2.0.0, set-function-name@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" + integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== + dependencies: + define-data-property "^1.0.1" + functions-have-names "^1.2.3" + has-property-descriptors "^1.0.0" + + set-value@^2.0.0, set-value@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" + integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + + setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + + setprototypeof@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" + integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== + + setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + + sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + + shallow-clone@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" + integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== + dependencies: + kind-of "^6.0.2" + + sharp@^0.29.1: + version "0.29.3" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" + integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== + dependencies: + color "^4.0.1" + detect-libc "^1.0.3" + node-addon-api "^4.2.0" + prebuild-install "^7.0.0" + semver "^7.3.5" + simple-get "^4.0.0" + tar-fs "^2.1.1" + tunnel-agent "^0.6.0" + + sharp@^0.32.4: + version "0.32.6" + resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" + integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== + dependencies: + color "^4.2.3" + detect-libc "^2.0.2" + node-addon-api "^6.1.0" + prebuild-install "^7.1.1" + semver "^7.5.4" + simple-get "^4.0.1" + tar-fs "^3.0.4" + tunnel-agent "^0.6.0" + + shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + + shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + + shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + + shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + + shell-quote@^1.6.1, shell-quote@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" + integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== + + shiki@^0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14" + integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng== + dependencies: + jsonc-parser "^3.0.0" + vscode-oniguruma "^1.6.1" + vscode-textmate "5.2.0" + + side-channel@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" + integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== + dependencies: + call-bind "^1.0.0" + get-intrinsic "^1.0.2" + object-inspect "^1.9.0" + + signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + + signal-exit@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" + integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== + + sigstore@^1.3.0, sigstore@^1.4.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" + integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== + dependencies: + "@sigstore/bundle" "^1.1.0" + "@sigstore/protobuf-specs" "^0.2.0" + "@sigstore/sign" "^1.0.0" + "@sigstore/tuf" "^1.0.3" + make-fetch-happen "^11.0.1" + + simple-concat@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" + integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== + + simple-get@^4.0.0, simple-get@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" + integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== + dependencies: + decompress-response "^6.0.0" + once "^1.3.1" + simple-concat "^1.0.0" + + simple-swizzle@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" + integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== + dependencies: + is-arrayish "^0.3.1" + + simple-update-notifier@^1.0.7: + version "1.1.0" + resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" + integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== + dependencies: + semver "~7.0.0" + + sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + + slash@3.0.0, slash@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" + integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== + + slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== + + slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + + slice-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" + integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== + dependencies: + ansi-styles "^4.0.0" + astral-regex "^2.0.0" + is-fullwidth-code-point "^3.0.0" + + smart-buffer@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" + integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== + + snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + + snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== + dependencies: + kind-of "^3.2.0" + + snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + + sockjs@^0.3.24: + version "0.3.24" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" + integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== + dependencies: + faye-websocket "^0.11.3" + uuid "^8.3.2" + websocket-driver "^0.7.4" + + socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + + socks@^2.6.2: + version "2.7.1" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" + integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== + dependencies: + ip "^2.0.0" + smart-buffer "^4.2.0" + + sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" + + sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== + dependencies: + is-plain-obj "^1.0.0" + + source-list-map@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" + integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== + + source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== + + source-map-resolve@^0.5.0: + version "0.5.3" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" + integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== + dependencies: + atob "^2.1.2" + decode-uri-component "^0.2.0" + resolve-url "^0.2.1" + source-map-url "^0.4.0" + urix "^0.1.0" + + source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + + source-map-url@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" + integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== + + source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== + + source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== + + source-map@^0.7.0, source-map@^0.7.3, source-map@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" + integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== + + sourcemap-codec@^1.4.8: + version "1.4.8" + resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" + integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== + + space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + + space-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" + integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== + + spdx-correct@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" + integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + + spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + + spdx-expression-parse@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + + spdx-license-ids@^3.0.0: + version "3.0.16" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" + integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== + + spdy-transport@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" + integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== + dependencies: + debug "^4.1.0" + detect-node "^2.0.4" + hpack.js "^2.1.6" + obuf "^1.1.2" + readable-stream "^3.0.6" + wbuf "^1.7.3" + + spdy@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" + integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== + dependencies: + debug "^4.1.0" + handle-thing "^2.0.0" + http-deceiver "^1.2.7" + select-hose "^2.0.0" + spdy-transport "^3.0.0" + + split-on-first@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" + integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== + + split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== + dependencies: + extend-shallow "^3.0.0" + + split2@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" + integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== + dependencies: + readable-stream "^3.0.0" + + split2@^4.0.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + + split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + + sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== + + ssri@^10.0.0, ssri@^10.0.1: + version "10.0.5" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" + integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== + dependencies: + minipass "^7.0.3" + + ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== + dependencies: + figgy-pudding "^3.5.1" + + ssri@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" + integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== + dependencies: + minipass "^3.1.1" + + ssri@^9.0.0, ssri@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + + stable@^0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" + integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== + + stack-utils@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" + integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== + dependencies: + escape-string-regexp "^2.0.0" + + stackframe@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" + integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + + state-toggle@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== + + static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + + statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + + "statuses@>= 1.4.0 < 2": + version "1.5.0" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" + integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + + stop-iteration-iterator@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" + integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== + dependencies: + internal-slot "^1.0.4" + + store2@^2.12.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" + integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== + + stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + + stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + + stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + + stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + + streamx@^2.15.0: + version "2.15.2" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.2.tgz#680eacebdc9c43ede7362c2e6695b34dd413c741" + integrity sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg== + dependencies: + fast-fifo "^1.1.0" + queue-tick "^1.0.1" + + strict-uri-encode@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" + integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== + + string-length@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" + integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== + dependencies: + char-regex "^1.0.2" + strip-ansi "^6.0.0" + + string-to-color@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/string-to-color/-/string-to-color-2.2.2.tgz#46210bf7777dc9198dcdf997bd18ae6749cc9a73" + integrity sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA== + dependencies: + colornames "^1.1.1" + hex-rgb "^4.1.0" + lodash.padend "^4.6.1" + lodash.trimstart "^4.5.1" + lodash.words "^4.2.0" + rgb-hex "^3.0.0" + + "string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + 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" + + string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + + "string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.8: + version "4.0.10" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" + integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + get-intrinsic "^1.2.1" + has-symbols "^1.0.3" + internal-slot "^1.0.5" + regexp.prototype.flags "^1.5.0" + set-function-name "^2.0.0" + side-channel "^1.0.4" + + string.prototype.padend@^3.0.0: + version "3.1.5" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz#311ef3a4e3c557dd999cdf88fbdde223f2ac0f95" + integrity sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + string.prototype.padstart@^3.0.0: + version "3.1.5" + resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.5.tgz#ce435e145e4d68b701d1db51cb546ba100177d98" + integrity sha512-R57IsE3JIfModQWrVXYZ8ZHWMBNDpIoniDwhYCR1nx+iHwDkjjk26a8xM9BYgf7SAXJO7sdNPng5J+0ccr5LFQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + string.prototype.trim@^1.2.8: + version "1.2.8" + resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" + integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + string.prototype.trimend@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" + integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + string.prototype.trimstart@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" + integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.2.0" + es-abstract "^1.22.1" + + string_decoder@^1.0.0, string_decoder@^1.1.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + + string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== + dependencies: + safe-buffer "~5.1.0" + + stringify-entities@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" + integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== + dependencies: + character-entities-html4 "^2.0.0" + character-entities-legacy "^3.0.0" + + "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + + strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== + dependencies: + ansi-regex "^2.0.0" + + strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + + strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + + strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + + strip-bom@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" + integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== + + strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + + strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== + + strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== + dependencies: + get-stdin "^4.0.1" + + strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + + strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" + integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== + + strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== + + strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" + integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== + dependencies: + duplexer "^0.1.1" + minimist "^1.2.0" + through "^2.3.4" + + style-loader@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== + dependencies: + loader-utils "^2.0.0" + schema-utils "^2.7.0" + + style-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + + style-loader@^3.3.1: + version "3.3.3" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" + integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== + + style-to-object@0.3.0, style-to-object@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== + dependencies: + inline-style-parser "0.1.1" + + style-to-object@^0.4.0, style-to-object@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" + integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg== + dependencies: + inline-style-parser "0.1.1" + + stylehacks@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" + integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== + dependencies: + browserslist "^4.21.4" + postcss-selector-parser "^6.0.4" + + stylis@4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" + integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== + + supports-color@8.1.1, supports-color@^8.0.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" + integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== + dependencies: + has-flag "^4.0.0" + + supports-color@^5.3.0, supports-color@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" + integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== + dependencies: + has-flag "^3.0.0" + + supports-color@^7.0.0, supports-color@^7.1.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" + integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== + dependencies: + has-flag "^4.0.0" + + supports-hyperlinks@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" + integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== + dependencies: + has-flag "^4.0.0" + supports-color "^7.0.0" + + supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + + svg-parser@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" + integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== + + svgo@^2.7.0, svgo@^2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" + integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== + 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" + + symbol-observable@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" + integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== + + symbol-tree@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" + integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== + + symbol.prototype.description@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz#d30e01263b6020fbbd2d2884a6276ce4d49ab568" + integrity sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ== + dependencies: + call-bind "^1.0.2" + get-symbol-description "^1.0.0" + has-symbols "^1.0.2" + object.getownpropertydescriptors "^2.1.2" + + synchronous-promise@^2.0.15: + version "2.0.17" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" + integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== + + tabbable@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" + integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== + + table@^6.0.9: + version "6.8.1" + resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" + integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== + dependencies: + ajv "^8.0.1" + lodash.truncate "^4.4.2" + slice-ansi "^4.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + + tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + + tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" + integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== + + tar-fs@^2.0.0, tar-fs@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" + 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" + + tar-fs@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" + integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== + dependencies: + mkdirp-classic "^0.5.2" + pump "^3.0.0" + tar-stream "^3.1.5" + + tar-stream@^2.1.4, tar-stream@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" + 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" + + tar-stream@^3.1.5: + version "3.1.6" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" + integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== + dependencies: + b4a "^1.6.4" + fast-fifo "^1.2.0" + streamx "^2.15.0" + + tar@6.1.11: + version "6.1.11" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" + integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^3.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + + tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: + version "6.2.0" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" + integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + + telejson@^6.0.8: + version "6.0.8" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" + integrity sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg== + dependencies: + "@types/is-function" "^1.0.0" + global "^4.4.0" + is-function "^1.0.2" + is-regex "^1.1.2" + is-symbol "^1.0.3" + isobject "^4.0.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + + telejson@^7.2.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" + integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== + dependencies: + memoizerific "^1.11.3" + + temp-dir@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" + integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== + + terminal-link@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" + integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== + dependencies: + ansi-escapes "^4.2.1" + supports-hyperlinks "^2.0.0" + + terser-webpack-plugin@^1.4.3: + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" + source-map "^0.6.1" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + + terser-webpack-plugin@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.5.0" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + terser "^5.3.4" + webpack-sources "^1.4.3" + + terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.3.7: + version "5.3.9" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" + integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.17" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.1" + terser "^5.16.8" + + terser@^4.1.2, terser@^4.6.3: + version "4.8.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== + dependencies: + commander "^2.20.0" + source-map "~0.6.1" + source-map-support "~0.5.12" + + terser@^5.10.0, terser@^5.16.8, terser@^5.3.4: + version "5.24.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" + integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== + dependencies: + "@jridgewell/source-map" "^0.3.3" + acorn "^8.8.2" + commander "^2.20.0" + source-map-support "~0.5.20" + + test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + + text-extensions@^1.0.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" + integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== + + text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== + + thread-loader@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b" + integrity sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA== + dependencies: + json-parse-better-errors "^1.0.2" + loader-runner "^4.1.0" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + + thread-stream@^0.15.1: + version "0.15.2" + resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" + integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== + dependencies: + real-require "^0.1.0" + + throat@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" + integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== + + through2@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + + through2@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" + integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== + dependencies: + readable-stream "3" + + through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== + + thunky@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" + integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== + + timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + + tiny-case@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" + integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== + + tiny-invariant@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" + integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== + + tiny-secp256k1@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" + integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== + dependencies: + bindings "^1.3.0" + bn.js "^4.11.8" + create-hmac "^1.1.7" + elliptic "^6.4.0" + nan "^2.13.2" + + tiny-warning@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" + integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== + + tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== + dependencies: + os-tmpdir "~1.0.2" + + tmp@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" + integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== + dependencies: + rimraf "^3.0.0" + + tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + + to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== + + to-fast-properties@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" + integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== + + to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== + dependencies: + kind-of "^3.0.2" + + to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + + to-regex-range@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" + integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== + dependencies: + is-number "^7.0.0" + + to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + + toggle-selection@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" + integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== + + toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + + topojson-client@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" + integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== + dependencies: + commander "2" + + toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + + touch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" + integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== + dependencies: + nopt "~1.0.10" + + tough-cookie@^4.0.0: + version "4.1.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" + integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.2.0" + url-parse "^1.5.3" + + tr46@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" + integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== + dependencies: + punycode "^2.1.1" + + tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + + trim-lines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" + integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== + + trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== + + trim-newlines@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" + integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== + + trim-trailing-lines@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" + integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== + + trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== + + trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + + trough@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" + integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== + + ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + + ts-jest@^27.0.5: + version "27.1.5" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" + integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== + dependencies: + bs-logger "0.x" + fast-json-stable-stringify "2.x" + jest-util "^27.0.0" + json5 "2.x" + lodash.memoize "4.x" + make-error "1.x" + semver "7.x" + yargs-parser "20.x" + + ts-loader@^9.4.2: + version "9.5.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" + integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + source-map "^0.7.4" + + ts-mocha@^10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" + integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== + dependencies: + ts-node "7.0.1" + optionalDependencies: + tsconfig-paths "^3.5.0" + + ts-node@10: + version "10.9.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" + integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== + dependencies: + "@cspotcode/source-map-support" "^0.8.0" + "@tsconfig/node10" "^1.0.7" + "@tsconfig/node12" "^1.0.7" + "@tsconfig/node14" "^1.0.0" + "@tsconfig/node16" "^1.0.2" + acorn "^8.4.1" + acorn-walk "^8.1.1" + arg "^4.1.0" + create-require "^1.1.0" + diff "^4.0.1" + make-error "^1.1.1" + v8-compile-cache-lib "^3.0.1" + yn "3.1.1" + + ts-node@7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" + integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== + dependencies: + arrify "^1.0.0" + buffer-from "^1.1.0" + diff "^3.1.0" + make-error "^1.1.1" + minimist "^1.2.0" + mkdirp "^0.5.1" + source-map-support "^0.5.6" + yn "^2.0.0" + + ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== + + tsconfig-paths-webpack-plugin@^3.5.2: + version "3.5.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz#01aafff59130c04a8c4ebc96a3045c43c376449a" + integrity sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.7.0" + tsconfig-paths "^3.9.0" + + tsconfig-paths@^3.14.2, tsconfig-paths@^3.5.0, tsconfig-paths@^3.9.0: + version "3.14.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" + integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + + tsconfig-paths@^4.1.2: + version "4.2.0" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" + integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== + dependencies: + json5 "^2.2.2" + minimist "^1.2.6" + strip-bom "^3.0.0" + + tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.3: + version "1.14.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" + integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== + + tslib@2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" + integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== + + tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" + integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== + + tsutils@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" + integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== + dependencies: + tslib "^1.8.1" + + tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== + + tuf-js@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" + integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== + dependencies: + "@tufjs/models" "1.0.4" + debug "^4.3.4" + make-fetch-happen "^11.1.1" + + tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== + dependencies: + safe-buffer "^5.0.1" + + tweetnacl-util@^0.15.0: + version "0.15.1" + resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" + integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== + + tweetnacl@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" + integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== + + type-check@^0.4.0, type-check@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" + integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== + dependencies: + prelude-ls "^1.2.1" + + type-detect@4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" + integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== + + type-fest@^0.18.0: + version "0.18.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" + integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== + + type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + + type-fest@^0.21.3: + version "0.21.3" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" + integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== + + type-fest@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" + integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== + + type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + + type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + + type-fest@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" + integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== + + type-is@~1.6.18: + version "1.6.18" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" + integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== + dependencies: + media-typer "0.3.0" + mime-types "~2.1.24" + + typed-array-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" + integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.2.1" + is-typed-array "^1.1.10" + + typed-array-byte-length@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" + integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + + typed-array-byte-offset@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" + integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.2" + for-each "^0.3.3" + has-proto "^1.0.1" + is-typed-array "^1.1.10" + + typed-array-length@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" + integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== + dependencies: + call-bind "^1.0.2" + for-each "^0.3.3" + is-typed-array "^1.1.9" + + typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + + typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + + typedoc@^0.22.13: + version "0.22.18" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.18.tgz#1d000c33b66b88fd8cdfea14a26113a83b7e6591" + integrity sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA== + dependencies: + glob "^8.0.3" + lunr "^2.3.9" + marked "^4.0.16" + minimatch "^5.1.0" + shiki "^0.10.1" + + typeforce@^1.11.5: + version "1.18.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" + integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== + + "typescript@>=3 < 6": + version "5.2.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" + integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + + typescript@^4.6.2, typescript@^4.8.4: + version "4.9.5" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" + integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + + uglify-js@^3.1.4: + version "3.17.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" + integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== + + uint8arrays@^3.0.0, uint8arrays@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" + integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== + dependencies: + multiformats "^9.4.2" + + unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + + undefsafe@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" + integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== + + undici-types@~5.26.4: + version "5.26.5" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" + integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + + unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + + unherit@^1.0.4: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== + dependencies: + inherits "^2.0.0" + xtend "^4.0.0" + + unicode-canonical-property-names-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" + integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + + unicode-match-property-ecmascript@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" + integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== + dependencies: + unicode-canonical-property-names-ecmascript "^2.0.0" + unicode-property-aliases-ecmascript "^2.0.0" + + unicode-match-property-value-ecmascript@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" + integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + + unicode-property-aliases-ecmascript@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" + integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== + + unified@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" + integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== + 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" + + unified@^10.0.0: + version "10.1.2" + resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" + integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== + dependencies: + "@types/unist" "^2.0.0" + bail "^2.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^4.0.0" + trough "^2.0.0" + vfile "^5.0.0" + + union-value@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" + integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^2.0.1" + + unique-filename@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" + integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== + dependencies: + unique-slug "^2.0.0" + + unique-filename@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" + integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== + dependencies: + unique-slug "^3.0.0" + + unique-filename@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" + integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== + dependencies: + unique-slug "^4.0.0" + + unique-slug@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" + integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== + dependencies: + imurmurhash "^0.1.4" + + unique-slug@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" + integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== + dependencies: + imurmurhash "^0.1.4" + + unique-slug@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" + integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== + dependencies: + imurmurhash "^0.1.4" + + unist-builder@2.0.3, unist-builder@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== + + unist-util-generated@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" + integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== + + unist-util-generated@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.1.tgz#e37c50af35d3ed185ac6ceacb6ca0afb28a85cae" + integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== + + unist-util-is@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" + integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== + + unist-util-is@^5.0.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9" + integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== + dependencies: + "@types/unist" "^2.0.0" + + unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz#8ac2480027229de76512079e377afbcabcfcce22" + integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== + dependencies: + "@types/unist" "^2.0.0" + + unist-util-position@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== + + unist-util-position@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.4.tgz#93f6d8c7d6b373d9b825844645877c127455f037" + integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== + dependencies: + "@types/unist" "^2.0.0" + + unist-util-remove-position@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" + integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== + dependencies: + unist-util-visit "^2.0.0" + + unist-util-remove-position@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz#a89be6ea72e23b1a402350832b02a91f6a9afe51" + integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-visit "^4.0.0" + + unist-util-remove@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" + integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== + dependencies: + unist-util-is "^4.0.0" + + unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + + unist-util-stringify-position@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d" + integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== + dependencies: + "@types/unist" "^2.0.0" + + unist-util-visit-parents@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + + unist-util-visit-parents@^5.1.1: + version "5.1.3" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb" + integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + + unist-util-visit@2.0.3, unist-util-visit@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + + unist-util-visit@^4.0.0: + version "4.1.2" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2" + integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^5.0.0" + unist-util-visit-parents "^5.1.1" + + universal-user-agent@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" + integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== + + universalify@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" + integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== + + universalify@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" + integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== + + unpipe@1.0.0, unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== + + unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + + untildify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== + dependencies: + os-homedir "^1.0.0" + + upath@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" + integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== + + upath@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" + integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== + + update-browserslist-db@^1.0.13: + version "1.0.13" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" + integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + + uri-js@^4.2.2: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + + urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== + + url-loader@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" + + url-parse@^1.5.3: + version "1.5.10" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" + integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== + dependencies: + querystringify "^2.1.1" + requires-port "^1.0.0" + + url@^0.11.0: + version "0.11.3" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" + integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== + dependencies: + punycode "^1.4.1" + qs "^6.11.2" + + use-clipboard-copy@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/use-clipboard-copy/-/use-clipboard-copy-0.2.0.tgz#e1f31f2b21e369bc79b5d7b358e2c8aece6ef264" + integrity sha512-f0PMMwZ2/Hh9/54L12capx4s6ASdd6edNJxg2OcqWVNM8BPvtOSmNFIN1Dg/q//fPp8MpUZceHfr7cnWOS0RxA== + dependencies: + clipboard-copy "^3.0.0" + + use-sync-external-store@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" + integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== + + use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== + + util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + + util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + + util@^0.10.4: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== + dependencies: + inherits "2.0.3" + + util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + + utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + + utility-types@^3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" + integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== + + utils-merge@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" + integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== + + uuid-browser@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" + integrity sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg== + + uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + + uuid@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" + integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== + + uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + + uuid@^9.0.0, uuid@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" + integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== + + uvu@^0.5.0: + version "0.5.6" + resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" + integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== + dependencies: + dequal "^2.0.0" + diff "^5.0.0" + kleur "^4.0.3" + sade "^1.7.3" + + v8-compile-cache-lib@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" + integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== + + v8-compile-cache@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" + integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== + + v8-compile-cache@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" + integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== + + v8-to-istanbul@^8.1.0: + version "8.1.1" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" + integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + source-map "^0.7.3" + + v8-to-istanbul@^9.0.0: + version "9.1.3" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" + integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^2.0.0" + + validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + + validate-npm-package-name@5.0.0, validate-npm-package-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" + integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== + dependencies: + builtins "^5.0.0" + + validate-npm-package-name@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" + integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== + dependencies: + builtins "^1.0.3" + + vary@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" + integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== + + vfile-location@^3.0.0, vfile-location@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" + integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== + + vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + + vfile-message@^3.0.0: + version "3.1.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea" + integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^3.0.0" + + vfile@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" + integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + + vfile@^5.0.0: + version "5.3.7" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7" + integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^3.0.0" + vfile-message "^3.0.0" + + victory-vendor@^36.6.8: + version "36.6.12" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.12.tgz#17fa4d79d266a6e2bde0291c60c5002c55008164" + integrity sha512-pJrTkNHln+D83vDCCSUf0ZfxBvIaVrFHmrBOsnnLAbdqfudRACAj51He2zU94/IWq9464oTADcPVkmWAfNMwgA== + dependencies: + "@types/d3-array" "^3.0.3" + "@types/d3-ease" "^3.0.0" + "@types/d3-interpolate" "^3.0.1" + "@types/d3-scale" "^4.0.2" + "@types/d3-shape" "^3.1.0" + "@types/d3-time" "^3.0.0" + "@types/d3-timer" "^3.0.0" + d3-array "^3.1.6" + d3-ease "^3.0.1" + d3-interpolate "^3.0.1" + d3-scale "^4.0.2" + d3-shape "^3.1.0" + d3-time "^3.0.0" + d3-timer "^3.0.1" + + vinyl@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" + integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + + vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + + vscode-oniguruma@^1.6.1: + version "1.7.0" + resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" + integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== + + vscode-textmate@5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" + integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== + + w3c-hr-time@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" + integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== + dependencies: + browser-process-hrtime "^1.0.0" + + w3c-xmlserializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" + integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== + dependencies: + xml-name-validator "^3.0.0" + + walker@^1.0.7, walker@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + + watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + + watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + + watchpack@^2.2.0, watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + + wbuf@^1.1.0, wbuf@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" + integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== + dependencies: + minimalistic-assert "^1.0.0" + + wcwidth@^1.0.0, wcwidth@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" + integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== + dependencies: + defaults "^1.0.3" + + web-namespaces@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== + + webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + + webidl-conversions@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" + integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== + + webidl-conversions@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" + integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== + + webpack-cli@^4.8.0: + version "4.10.0" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" + integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== + dependencies: + "@discoveryjs/json-ext" "^0.5.0" + "@webpack-cli/configtest" "^1.2.0" + "@webpack-cli/info" "^1.5.0" + "@webpack-cli/serve" "^1.7.0" + colorette "^2.0.14" + commander "^7.0.0" + cross-spawn "^7.0.3" + fastest-levenshtein "^1.0.12" + import-local "^3.0.2" + interpret "^2.2.0" + rechoir "^0.7.0" + webpack-merge "^5.7.3" + + webpack-dev-middleware@^3.7.3: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== + dependencies: + memory-fs "^0.4.1" + mime "^2.4.4" + mkdirp "^0.5.1" + range-parser "^1.2.1" + webpack-log "^2.0.0" + + webpack-dev-middleware@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz#179cc40795882cae510b1aa7f3710cbe93c9333e" + integrity sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w== + dependencies: + colorette "^1.2.2" + mem "^8.1.1" + memfs "^3.2.2" + mime-types "^2.1.30" + range-parser "^1.2.1" + schema-utils "^3.0.0" + + webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + + webpack-dev-server@^4.5.0: + version "4.15.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" + integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/serve-static" "^1.13.10" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.5" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" + compression "^1.7.4" + connect-history-api-fallback "^2.0.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + launch-editor "^2.6.0" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.1.1" + serve-index "^1.9.1" + sockjs "^0.3.24" + spdy "^4.0.2" + webpack-dev-middleware "^5.3.1" + ws "^8.13.0" + + webpack-favicons@^1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/webpack-favicons/-/webpack-favicons-1.3.8.tgz#cc986bf8f4cd7629af44a726ca142e14c66e7be5" + integrity sha512-c40JTAUOorQSle2X1p5eRBpNl/zWw4rqR5EvCvLGZqMaXHUtJM/waCLgz0H4Pg1nXvvqV/LoYoqSvoAI0WiD0g== + dependencies: + favicons "7.0.0-beta.1" + + webpack-filter-warnings-plugin@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" + integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + + webpack-hot-middleware@^2.25.1: + version "2.25.4" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz#d8bc9e9cb664fc3105c8e83d2b9ed436bee4e193" + integrity sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w== + dependencies: + ansi-html-community "0.0.8" + html-entities "^2.1.0" + strip-ansi "^6.0.0" + + webpack-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" + integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== + dependencies: + ansi-colors "^3.0.0" + uuid "^3.3.2" + + webpack-merge@^5.7.3, webpack-merge@^5.8.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" + integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== + dependencies: + clone-deep "^4.0.1" + flat "^5.0.2" + wildcard "^2.0.0" + + webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" + integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + + webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== + + webpack-virtual-modules@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" + integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== + dependencies: + debug "^3.0.0" + + webpack-virtual-modules@^0.4.1: + version "0.4.6" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz#3e4008230731f1db078d9cb6f68baf8571182b45" + integrity sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA== + + webpack@4: + version "4.47.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" + integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + + "webpack@>=4.43.0 <6.0.0", webpack@^5.75.0, webpack@^5.9.0: + version "5.89.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" + integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^1.0.0" + "@webassemblyjs/ast" "^1.11.5" + "@webassemblyjs/wasm-edit" "^1.11.5" + "@webassemblyjs/wasm-parser" "^1.11.5" + acorn "^8.7.1" + acorn-import-assertions "^1.9.0" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.15.0" + es-module-lexer "^1.2.1" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.2.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.3.7" + watchpack "^2.4.0" + webpack-sources "^3.2.3" + + websocket-driver@>=0.5.1, websocket-driver@^0.7.4: + version "0.7.4" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" + integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== + dependencies: + http-parser-js ">=0.5.1" + safe-buffer ">=5.1.0" + websocket-extensions ">=0.1.1" + + websocket-extensions@>=0.1.1: + version "0.1.4" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" + integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== + + whatwg-encoding@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" + integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== + dependencies: + iconv-lite "0.4.24" + + whatwg-mimetype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" + integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== + + whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + + whatwg-url@^8.0.0, whatwg-url@^8.5.0: + version "8.7.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" + integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== + dependencies: + lodash "^4.7.0" + tr46 "^2.1.0" + webidl-conversions "^6.1.0" + + which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + + which-builtin-type@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" + integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== + dependencies: + function.prototype.name "^1.1.5" + has-tostringtag "^1.0.0" + is-async-function "^2.0.0" + is-date-object "^1.0.5" + is-finalizationregistry "^1.0.2" + is-generator-function "^1.0.10" + is-regex "^1.1.4" + is-weakref "^1.0.2" + isarray "^2.0.5" + which-boxed-primitive "^1.0.2" + which-collection "^1.0.1" + which-typed-array "^1.1.9" + + which-collection@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" + integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== + dependencies: + is-map "^2.0.1" + is-set "^2.0.1" + is-weakmap "^2.0.1" + is-weakset "^2.0.1" + + which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + version "1.1.13" + resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" + integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== + dependencies: + available-typed-arrays "^1.0.5" + call-bind "^1.0.4" + for-each "^0.3.3" + gopd "^1.0.1" + has-tostringtag "^1.0.0" + + which@^1.2.9: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + + which@^2.0.1, which@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" + integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== + dependencies: + isexe "^2.0.0" + + which@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" + integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== + dependencies: + isexe "^2.0.0" + + wide-align@^1.1.2, wide-align@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + + widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + + wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== + dependencies: + bs58check "<3.0.0" + + wildcard@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" + integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== + + wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + + worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + + worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + + workerpool@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" + integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== + + "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + + wrap-ansi@^6.0.1: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + + wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + + wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== + + write-file-atomic@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" + integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== + dependencies: + imurmurhash "^0.1.4" + signal-exit "^4.0.1" + + write-file-atomic@^2.4.2: + version "2.4.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" + integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + + write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== + dependencies: + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + + write-json-file@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" + integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== + dependencies: + detect-indent "^5.0.0" + graceful-fs "^4.1.15" + make-dir "^2.1.0" + pify "^4.0.1" + sort-keys "^2.0.0" + write-file-atomic "^2.4.2" + + write-pkg@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" + integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== + dependencies: + sort-keys "^2.0.0" + type-fest "^0.4.1" + write-json-file "^3.2.0" + + ws@^7, ws@^7.4.6, ws@^7.5.1: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + + ws@^8.13.0, ws@^8.2.3: + version "8.14.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" + integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== + + x-default-browser@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" + integrity sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw== + optionalDependencies: + default-browser-id "^1.0.4" + + xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== + + xml2js@^0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" + integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + + xml2js@^0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" + integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + + xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + + xmlchars@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" + integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== + + xstream@^11.14.0: + version "11.14.0" + resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" + integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== + dependencies: + globalthis "^1.0.1" + symbol-observable "^2.0.3" + + xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + + y18n@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" + integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== + + y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + + yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + + yallist@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" + integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== + + yaml-loader@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.8.0.tgz#c839325e3fdee082b3768b2a21fe34fde5d96f61" + integrity sha512-LjeKnTzVBKWiQBeE2L9ssl6WprqaUIxCSNs5tle8PaDydgu3wVFXTbMfsvF2MSErpy9TDVa092n4q6adYwJaWg== + dependencies: + javascript-stringify "^2.0.1" + loader-utils "^2.0.0" + yaml "^2.0.0" + + yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" + integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== + + yaml@^2.0.0: + version "2.3.4" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" + integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== + + yargs-parser@20.2.4: + version "20.2.4" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" + integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== + + yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + + yargs-parser@21.1.1, yargs-parser@^21.1.1: + version "21.1.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" + integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== + + yargs-unparser@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" + integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== + dependencies: + camelcase "^6.0.0" + decamelize "^4.0.0" + flat "^5.0.2" + is-plain-obj "^2.1.0" + + yargs@16.2.0, yargs@^16.2.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + + yargs@^17.6.2: + version "17.7.2" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" + integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + + yn@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" + integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + + yn@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" + integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== + + yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + + yup@^0.32.9: + version "0.32.11" + resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5" + integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg== + dependencies: + "@babel/runtime" "^7.15.4" + "@types/lodash" "^4.14.175" + lodash "^4.17.21" + lodash-es "^4.17.21" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2" + + yup@^1.2.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.2.tgz#afffc458f1513ed386e6aaf4bcaa4e67a9e270dc" + integrity sha512-6KCM971iQtJ+/KUaHdrhVr2LDkfhBtFPRnsG1P8F4q3uUVQ2RfEM9xekpha9aA4GXWJevjM10eDcPQ1FfWlmaQ== + dependencies: + property-expr "^2.0.5" + tiny-case "^1.0.3" + toposort "^2.0.2" + type-fest "^2.19.0" + + zustand@4.4.6: + version "4.4.6" + resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" + integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== + dependencies: + use-sync-external-store "1.2.0" + + zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== + + zwitch@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" + integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== + + zxcvbn@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30" + integrity sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ== diff --git a/yarn.lock b/yarn.lock index 577735f153..b0e24432af 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1190,7 +1190,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.22.6", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.23.2" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== @@ -1582,69 +1582,69 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== -"@cosmos-kit/core@^2.7.4": - version "2.7.4" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.4.tgz#8d028c3b99ab4d11aed47bf5d1c22d0157bca694" - integrity sha512-/G2ucBgEooSzKYBzwNC7/NksDVuXGorEgP8dPTR7iAxfFLSg0j/lDPFH4tezVJSV/NZxbw4Suptk+KyUGDEzNw== +"@cosmos-kit/core@^2.7.6": + version "2.7.6" + resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.6.tgz#391f64b92be667e932859ab22092e91a8b087a23" + integrity sha512-9ORAoY0RLB14ppwMO8I5kvjK9dZUCG/2tMUoMZKtHrLvGnW4vE+tC4FuQW9v23xBwV6MGkoFDxNn1b4j29a2IA== dependencies: "@chain-registry/types" "0.17.0" - "@walletconnect/types" "2.7.2" + "@walletconnect/types" "2.10.4" bowser "2.11.0" events "3.3.0" uuid "^9.0.1" -"@cosmos-kit/keplr-extension@^2.5.7": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.7.tgz#e8fef3c4f43d3402aa3d0320936cdaf03fb8a811" - integrity sha512-Bwh1nJz/1l9mGtcjh0qUcZtMRjkOoTNUkMRbUoV8PqQtwcVvgB5DefmiXAcFxH+sB7ObPjjSNp2bN0o7gpHE0g== +"@cosmos-kit/keplr-extension@^2.5.9": + version "2.5.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.9.tgz#398175e7d60ff11627825f1c27389f3342ba0935" + integrity sha512-9c2XAbKLtnMnWH+pNtSYXeqqSkIsWFW/zL9L7tf6jOov+Y9d6mLmHKfGOadbly3GX9l2RZfvYuZ1NZbCvC5u/w== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.4" + "@cosmos-kit/core" "^2.7.6" -"@cosmos-kit/keplr-mobile@^2.4.5": - version "2.4.5" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.5.tgz#407b8c31afd1ec49cb4e600e84dbfe8224f59ab2" - integrity sha512-4cF0MfcJEGvWqL31YVMoahP4WlSSe5Nyj2NMGCzuMsOdRWCSpdB06c9RJ+erI0JyVDXjam7tTA9WTlyT+dgAKg== +"@cosmos-kit/keplr-mobile@^2.4.8": + version "2.4.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.8.tgz#6692ed5290e0eb3be3c51ce7d2972252ce569ce4" + integrity sha512-KUkUuSC9kPyVAJIlLyewwwKmkoUV0otVSy4IyOAbhobf9N6Vun08zh5YVz8xfqM8jdzG6F8saoYDBRWqi4xPWA== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.4" - "@cosmos-kit/walletconnect" "^2.4.5" + "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/walletconnect" "^2.4.8" "@cosmos-kit/keplr@^2.4.7": - version "2.4.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.7.tgz#512ca3ca1ecf87b7219186be81127d0a021319f1" - integrity sha512-56HTflompCUZ3yg86cqgRl91Crpy1JInLJ1UbPgNbiHm7pVUR6/davfnMcZ6AN559MTxs5PCU9v0zW7mlEC0pg== + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.10.tgz#148e8d63c2ad5545da5ef54943a31ed1d37ae2d5" + integrity sha512-LBiAZkG9sQ9+efVuIb/afK8JvW0OgJigkkAGA2DIGcwqA7k+b2XbvHLNU6octTYLyR32JoiB7M3xkGeIxBfpNw== dependencies: - "@cosmos-kit/keplr-extension" "^2.5.7" - "@cosmos-kit/keplr-mobile" "^2.4.5" + "@cosmos-kit/keplr-extension" "^2.5.9" + "@cosmos-kit/keplr-mobile" "^2.4.8" -"@cosmos-kit/react-lite@^2.5.5": - version "2.5.5" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.5.tgz#905107aadcc87ae268ea7d8927ff74601b6df8f7" - integrity sha512-i1FTkMMLDOUkO+lPbUS3RRQoewgX79ux+gTctB/6wJqBhZkzoINCCn2XHYrKioXqhe2a1xn5n+EUWkBEPsZK8w== +"@cosmos-kit/react-lite@^2.5.7": + version "2.5.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.7.tgz#2a6c4e2c9a4712320e72307b7be4d87b012ffb96" + integrity sha512-CHpHw6G0Utf3LhSyONEJUkxuu5wDb9O/C2H+PdYZx50lAn/lBnNaeelQEGQUct0mVdi8XRcjsccjz5JbdjvkBQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.4" + "@cosmos-kit/core" "^2.7.6" "@cosmos-kit/react@^2.9.6": - version "2.9.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.6.tgz#8c6cba92ffb342c0c6555da64c87d9c421f6586d" - integrity sha512-bHBZ4SSlRWuQ3pd3run8N57AhKJ1Jime06njEmuFnNPeoC42abKAxpQAFckSeKpuN2hgxj8TAtzPgJMbhwNbnQ== + version "2.9.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.8.tgz#95d1515bd808b76526816dc8d606eca96d5751d5" + integrity sha512-DNmFwoW9TO2a+MvXeJiBfoh+03fFKKQ4jBN4nodKC6CvwTM8i+MnGm2/46gGB/q9iLu2qyVKRkg47uiGqTQZXQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.4" - "@cosmos-kit/react-lite" "^2.5.5" + "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/react-lite" "^2.5.7" "@interchain-ui/react" "^1.11.0" "@react-icons/all-files" "^4.1.0" -"@cosmos-kit/walletconnect@^2.4.5": - version "2.4.5" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.5.tgz#b9119ba09f88a18e229ccdb5a8907d0fa2bbbc64" - integrity sha512-ZTE8xh1yKJjqpQDI1wux2Sda1lMxr0Zx/iT4ZDaVuFr1pSzlIoM8SKqAySCr43JNCwF/Y9Uq1HAwLs1vq8lS6w== +"@cosmos-kit/walletconnect@^2.4.8": + version "2.4.8" + resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.8.tgz#62630f06999d1b59fbe4764ae4cb6912a50cf107" + integrity sha512-SUb21ZiK7UTJ6A8Y5GcD6MfS+iy+hrPUYIpTRLobEKt2uwbmMeRP9hIkhvKxN97iTqXK5ay6BPAtmoJunTpv9g== dependencies: - "@cosmos-kit/core" "^2.7.4" + "@cosmos-kit/core" "^2.7.6" "@walletconnect/sign-client" "^2.9.0" - "@walletconnect/types" "^2.9.0" + "@walletconnect/types" "2.10.4" "@walletconnect/utils" "^2.9.0" events "3.3.0" @@ -2067,30 +2067,30 @@ integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@interchain-ui/react@^1.11.0": - version "1.11.12" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.11.12.tgz#e5e8cf0faaa639410948ffe47b8fddc09e64891b" - integrity sha512-N2JCjuMax4J1kLFScpZbN3AyDgnetISUv4F0mwGuTWsRrNDdvBbu+EDhMICXoIGSNHeigVe0YjVVMLSpupunig== + version "1.13.0" + resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.13.0.tgz#b9430c6e9fd5d94a81c3f6ce574b0d0142c491d5" + integrity sha512-samY/4jYEeKLf88AUabxnDpGMFm8V3y+xQCDTjecEn2KkNu23J2fonKUQA8F2Rnj7vsTBHxdjZDeT2wLxlcJFA== dependencies: "@fastify/deepmerge" "^1.3.0" "@floating-ui/dom" "^1.5.2" "@floating-ui/react" "^0.26.0" "@formkit/auto-animate" "1.0.0-beta.6" - "@react-aria/i18n" "^3.8.4" - "@react-aria/numberfield" "^3.9.1" "@react-aria/utils" "^3.21.1" - "@react-stately/numberfield" "^3.6.2" "@vanilla-extract/css" "^1.12.0" "@vanilla-extract/css-utils" "^0.1.3" "@vanilla-extract/dynamic" "^2.0.3" "@vanilla-extract/recipes" "^0.4.0" animejs "^3.2.1" bignumber.js "^9.1.1" + client-only "^0.0.1" clsx "^1.2.1" copy-to-clipboard "^3.3.3" immer "^9.0.19" lodash "^4.17.21" rainbow-sprinkles "^0.17.0" - zustand "^4.3.8" + react-aria "^3.29.1" + react-stately "^3.27.1" + zustand "4.4.6" "@internationalized/date@^3.5.0": version "3.5.0" @@ -2680,23 +2680,23 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@mui/base@5.0.0-beta.22": - version "5.0.0-beta.22" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.22.tgz#9ea6be6c8bfc4d8f825660da36d228f5315d4706" - integrity sha512-l4asGID5tmyerx9emJfXOKLyXzaBtdXNIFE3M+IrSZaFtGFvaQKHhc3+nxxSxPf1+G44psjczM0ekRQCdXx9HA== +"@mui/base@5.0.0-beta.23": + version "5.0.0-beta.23" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.23.tgz#dd10dfc609d8937749521f940965f757fa3c0f2c" + integrity sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw== dependencies: "@babel/runtime" "^7.23.2" "@floating-ui/react-dom" "^2.0.2" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.16.tgz#03ceb422d69a33e6c1cbd7e943cf60816878be2a" - integrity sha512-97isBjzH2v1K7oB4UH2f4NOkBShOynY6dhnoR2XlUk/g6bb7ZBv2I3D1hvvqPtpEigKu93e7f/jAYr5d9LOc5w== +"@mui/core-downloads-tracker@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.17.tgz#68ec40ea00832fb685f09bd493648b1f68f5baf4" + integrity sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ== "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": version "5.14.16" @@ -2706,30 +2706,29 @@ "@babel/runtime" "^7.23.2" "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.151" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.151.tgz#4f0e904f0db8088c5c9a3c3da5bde676cb3ce7ca" - integrity sha512-EAIzoDZ0WATa31m71juG1LnURjsmdkUOjNqy2j5WUp4y80obdGYKTT1Yh1hdI5SKND6621vaBPiGoKITjCZJ8A== + version "5.0.0-alpha.152" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.152.tgz#22efc0dc0e19325759691c81db1ac32da1250481" + integrity sha512-P81QbS/FolrTAjm72N8ndTCYCdPufxJeftNcuc/L4ENHrAo8bV4wcweEyL2AcetfvTgpmGf3QaITrQv8Ts067A== dependencies: "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.22" - "@mui/system" "^5.14.16" + "@mui/base" "5.0.0-beta.23" + "@mui/system" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" - "@mui/x-tree-view" "6.0.0-alpha.1" + "@mui/utils" "^5.14.17" clsx "^2.0.0" prop-types "^15.8.1" "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.16.tgz#45cd62d312d10399d3813ee6dc43bd1f11179bf4" - integrity sha512-W4zZ4vnxgGk6/HqBwgsDHKU7x2l2NhX+r8gAwfg58Rhu3ikfY7NkIS6y8Gl3NkATc4GG1FNaGjjpQKfJx3U6Jw== + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.17.tgz#8e11098e52965be3e9ed117d6c107bbe511fac46" + integrity sha512-+y0VeOLWfEA4Z98We/UH6KCo8+f2HLZDK45FY+sJf8kSojLy3VntadKtC/u0itqnXXb1Pr4wKB2tSIBW02zY4Q== dependencies: "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.22" - "@mui/core-downloads-tracker" "^5.14.16" - "@mui/system" "^5.14.16" + "@mui/base" "5.0.0-beta.23" + "@mui/core-downloads-tracker" "^5.14.17" + "@mui/system" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" "@types/react-transition-group" "^4.4.8" clsx "^2.0.0" csstype "^3.1.2" @@ -2737,19 +2736,19 @@ react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.16.tgz#ffdc9a9d3deaa46af000f04c0a9cc3a982f73071" - integrity sha512-FNlL0pTSEBh8nXsVWreCHDSHk+jG8cBx1sxRbT8JVtL+PYbYPi802zfV4B00Kkf0LNRVRvAVQwojMWSR/MYGng== +"@mui/private-theming@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.17.tgz#2fdf9d7df54dcb27e8ae7e00f440eb8310376ec3" + integrity sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g== dependencies: "@babel/runtime" "^7.23.2" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" prop-types "^15.8.1" -"@mui/styled-engine@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.16.tgz#a4a78a9980f138c2e705d04d67d44051f5005f22" - integrity sha512-FfvYvTG/Zd+KXMMImbcMYEeQAbONGuX5Vx3gBmmtB6KyA7Mvm9Pma1ly3R0gc44yeoFd+2wBjn1feS8h42HW5w== +"@mui/styled-engine@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.17.tgz#7f79d863604076db5278bd38a2eeac44cd2ed336" + integrity sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw== dependencies: "@babel/runtime" "^7.23.2" "@emotion/cache" "^11.11.0" @@ -2757,15 +2756,15 @@ prop-types "^15.8.1" "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.16.tgz#663e5f2317c2b631d9d8bd873f23344ab0729815" - integrity sha512-pBA2eLBEfqLv/jmu9qGcErwml27upH2YBFRuRU2loZm5R57di5y/GjpM9EWc77+49axaTlHfO8LWbic4kPvxoQ== + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.17.tgz#441afdd9425b4aad3dea727b0067d367a41f4b58" + integrity sha512-CsftJtCxF3ABigNXikmBJEsI6XQDmeTQNmjaA6wbjYA+29xPMUEQD4Coe+VXGkcc2jrE6Vy8qZ3ytO8QaM9KAw== dependencies: "@babel/runtime" "^7.23.2" "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.16" + "@mui/private-theming" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" clsx "^2.0.0" csstype "^3.1.2" hoist-non-react-statics "^3.3.2" @@ -2779,16 +2778,16 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.16": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.16.tgz#5c30c5123767416358c3b73774eb985e189119a4" - integrity sha512-uKnPfsDqDs8bbN54TviAuoGWOmFiQLwNZ3Wvj+OBkJCzwA6QnLb/sSeCB7Pk3ilH4h4jQ0BHtbR+Xpjy9wlOuA== +"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.17": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.17.tgz#3e212d1e699d4c777bbe5c6584ae129b1ef7d8bc" + integrity sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg== dependencies: "@babel/runtime" "^7.23.2" - "@mui/private-theming" "^5.14.16" - "@mui/styled-engine" "^5.14.16" + "@mui/private-theming" "^5.14.17" + "@mui/styled-engine" "^5.14.17" "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.16" + "@mui/utils" "^5.14.17" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" @@ -2798,10 +2797,10 @@ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== -"@mui/utils@^5.10.3", "@mui/utils@^5.14.16", "@mui/utils@^5.14.3", "@mui/utils@^5.7.0": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.16.tgz#09a15fd45530cadc642c5c08eb6cc660ea230506" - integrity sha512-3xV31GposHkwRbQzwJJuooWpK2ybWdEdeUPtRjv/6vjomyi97F3+68l+QVj9tPTvmfSbr2sx5c/NuvDulrdRmA== +"@mui/utils@^5.10.3", "@mui/utils@^5.14.17", "@mui/utils@^5.7.0": + version "5.14.17" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.17.tgz#8e2e7ca58865119eec8c6bdb359f539c25aaf576" + integrity sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ== dependencies: "@babel/runtime" "^7.23.2" "@types/prop-types" "^15.7.9" @@ -2819,18 +2818,6 @@ prop-types "^15.8.1" reselect "^4.1.6" -"@mui/x-tree-view@6.0.0-alpha.1": - version "6.0.0-alpha.1" - resolved "https://registry.yarnpkg.com/@mui/x-tree-view/-/x-tree-view-6.0.0-alpha.1.tgz#fe499f8c43c01d28aca95cfb17491746ffcc3080" - integrity sha512-JUG3HmBrmGEALbCFg1b+i7h726e1dWYZs4db3syO1j+Q++E3nbvE4Lehp5yGTFm+8esH0Tny50tuJaa4WX6VSA== - dependencies: - "@babel/runtime" "^7.22.6" - "@mui/utils" "^5.14.3" - "@types/react-transition-group" "^4.4.6" - clsx "^2.0.0" - prop-types "^15.8.1" - react-transition-group "^4.4.5" - "@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0": version "1.3.2" resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" @@ -3242,6 +3229,136 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== +"@react-aria/breadcrumbs@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.7.tgz#1d7f5e01887c62516a3e705e59a92e96d315c6c6" + integrity sha512-z+L1gNyWrjZ4Fs0Vo4AkwJicPpEGIestww6r8CiTlt07eo0vCReNmB3oofI6nMJOSu51yef+qqBtFyr0tqBgiw== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/link" "^3.6.1" + "@react-aria/utils" "^3.21.1" + "@react-types/breadcrumbs" "^3.7.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/button@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.8.4.tgz#0f0afe45ad9dfc4f79b2755983a503e2de74f7f5" + integrity sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/calendar@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.2.tgz#a00b2337c0f6c8840aaa9bd5410e95452c5a5e2d" + integrity sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/calendar" "^3.4.1" + "@react-types/button" "^3.9.0" + "@react-types/calendar" "^3.4.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/checkbox@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.11.2.tgz#9e1045edf282298cb8337fd3fd1d953c6cf5f667" + integrity sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA== + dependencies: + "@react-aria/label" "^3.7.2" + "@react-aria/toggle" "^3.8.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/checkbox" "^3.5.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/combobox@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.7.1.tgz#8fc26008b54bd2d2c6eac6c126c1b2bba5a5e774" + integrity sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/listbox" "^3.11.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/combobox" "^3.7.1" + "@react-stately/layout" "^3.13.3" + "@react-types/button" "^3.9.0" + "@react-types/combobox" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/datepicker@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.8.1.tgz#7ad2ff17799b7601edfc2eef7d2f35086f182897" + integrity sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/number" "^3.3.0" + "@internationalized/string" "^3.1.1" + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/spinbutton" "^3.5.4" + "@react-aria/utils" "^3.21.1" + "@react-stately/datepicker" "^3.8.0" + "@react-types/button" "^3.9.0" + "@react-types/calendar" "^3.4.1" + "@react-types/datepicker" "^3.6.1" + "@react-types/dialog" "^3.5.6" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/dialog@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.7.tgz#e57eca98e95114d618d583f5cc5400bdcf1190b0" + integrity sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/overlays" "^3.18.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/overlays" "^3.6.3" + "@react-types/dialog" "^3.5.6" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/dnd@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.4.3.tgz#f13e438f6613f79988ffa5d6a79c5705c26428d4" + integrity sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA== + dependencies: + "@internationalized/string" "^3.1.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/dnd" "^3.2.5" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-aria/focus@^3.14.3": version "3.14.3" resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.14.3.tgz#5e66dbf47e1d92aebf67d52b3b08d1631591f5b6" @@ -3253,6 +3370,42 @@ "@swc/helpers" "^0.5.0" clsx "^1.1.1" +"@react-aria/grid@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.4.tgz#1f19df9b413e843c82a280a40cd863650e424dfd" + integrity sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/grid" "^3.8.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/checkbox" "^3.5.2" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/gridlist@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.1.tgz#0be67cd3f0d30a6fe76c0f73927f403ca416a555" + integrity sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/grid" "^3.8.4" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-aria/i18n@^3.8.4": version "3.8.4" resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.8.4.tgz#e7ecd3edcaa66ceaf9ebb1034395e021685163af" @@ -3287,6 +3440,34 @@ "@react-types/shared" "^3.21.0" "@swc/helpers" "^0.5.0" +"@react-aria/link@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.1.tgz#1e196dc2e25af24a713c3bb6d653aae37b67a1a2" + integrity sha512-uVkuNHabxE11Eqeo0d1RA86EckOlfJ2Ld8uN8HnTxiLetXLZYUMBwlZfBJvT3RdwPtTG7jC3OK3BvwiyIJrtZw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/link" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/listbox@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.1.tgz#2a2c88daf6a67e07ab17440f72a859913161e6e8" + integrity sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-types/listbox" "^3.4.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-aria/live-announcer@^3.3.1": version "3.3.1" resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz#bf864b8820fb02daaeefc1c972782a0174fd60b9" @@ -3294,6 +3475,35 @@ dependencies: "@swc/helpers" "^0.5.0" +"@react-aria/menu@^3.11.1": + version "3.11.1" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.1.tgz#fb31c5533d5106c41ed73c14516ecbf74742976a" + integrity sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/menu" "^3.5.6" + "@react-stately/tree" "^3.7.3" + "@react-types/button" "^3.9.0" + "@react-types/menu" "^3.9.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/meter@^3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.7.tgz#33a7b2d4a0be56d147949bb36f3f32bc545c3a87" + integrity sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA== + dependencies: + "@react-aria/progress" "^3.4.7" + "@react-types/meter" "^3.3.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-aria/numberfield@^3.9.1": version "3.9.1" resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.9.1.tgz#de8bbcfbd971c22311a85a3ab34165c53ff96519" @@ -3312,6 +3522,124 @@ "@react-types/textfield" "^3.8.1" "@swc/helpers" "^0.5.0" +"@react-aria/overlays@^3.18.1": + version "3.18.1" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.18.1.tgz#b53093b2e1004feff155c81730e0101179cd6c47" + integrity sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/ssr" "^3.8.0" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/overlays" "^3.6.3" + "@react-types/button" "^3.9.0" + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/progress@^3.4.7": + version "3.4.7" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.7.tgz#babee1f4775b7baa1b8e2250c861c98805e3d6ee" + integrity sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-types/progress" "^3.5.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/radio@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.8.2.tgz#318fb1bbdc67131181c03002a5d8458405239b85" + integrity sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/radio" "^3.9.1" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/searchfield@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.5.7.tgz#00f0be54375967f86e2b3365bd80ea602af021a3" + integrity sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/searchfield" "^3.4.6" + "@react-types/button" "^3.9.0" + "@react-types/searchfield" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/select@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.13.1.tgz#c6d7eda36b8f8887c9baf0f1dea06f30806d71fc" + integrity sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/listbox" "^3.11.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/select" "^3.5.5" + "@react-types/button" "^3.9.0" + "@react-types/select" "^3.8.4" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/selection@^3.17.1": + version "3.17.1" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.1.tgz#12df277b8806fd26093e16f6a2734bd1e6fbb3e2" + integrity sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/separator@^3.3.7": + version "3.3.7" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.7.tgz#258f52a64d9ec58d62d3257edac542007b54a142" + integrity sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/slider@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.2.tgz#e122bbf945c5ae0f72be1c8977ef9be957c4bdbf" + integrity sha512-io7yJm2jS0gK1ILE9kjClh9zylKsOLbRy748CyD66LDV0ZIjj2D/uZF6BtfKq7Zhc2OsMvDB9+e2IkrszKe8uw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/utils" "^3.21.1" + "@react-stately/radio" "^3.9.1" + "@react-stately/slider" "^3.4.4" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@react-types/slider" "^3.6.2" + "@swc/helpers" "^0.5.0" + "@react-aria/spinbutton@^3.5.4": version "3.5.4" resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz#d1c317838f4ae55d6a2e6c698581e4cf0f2b0c89" @@ -3331,6 +3659,71 @@ dependencies: "@swc/helpers" "^0.5.0" +"@react-aria/switch@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.6.tgz#2f3d4b4198f26848fac9876233981b232c151620" + integrity sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w== + dependencies: + "@react-aria/toggle" "^3.8.2" + "@react-stately/toggle" "^3.6.3" + "@react-types/switch" "^3.4.2" + "@swc/helpers" "^0.5.0" + +"@react-aria/table@^3.13.1": + version "3.13.1" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.1.tgz#843e377b62c695b6559dd0b6ef0d7bdb8f56c358" + integrity sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/grid" "^3.8.4" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/live-announcer" "^3.3.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-stately/collections" "^3.10.2" + "@react-stately/flags" "^3.0.0" + "@react-stately/table" "^3.11.2" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/checkbox" "^3.5.2" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/tabs@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.1.tgz#89229734a5afccbb9a8a03ac8098b1b3653a948f" + integrity sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-stately/tabs" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@react-types/tabs" "^3.3.3" + "@swc/helpers" "^0.5.0" + +"@react-aria/tag@^3.2.1": + version "3.2.1" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.2.1.tgz#1fcfece4fc574f066d32aca005fbfc133ef3c247" + integrity sha512-i7Mj3IhB91sGp3NS6iNBVh25W+LR2XXpTmtn3OS4R62q3Oalw/1PKqPWqFc73Lb5IWF5rj3eh2yTf+rerWf3dw== + dependencies: + "@react-aria/gridlist" "^3.7.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/selection" "^3.17.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/list" "^3.10.0" + "@react-types/button" "^3.9.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-aria/textfield@^3.12.2": version "3.12.2" resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.12.2.tgz#e1ae5abaf72ed9c800e6a8afface3b2fd58258ca" @@ -3343,6 +3736,33 @@ "@react-types/textfield" "^3.8.1" "@swc/helpers" "^0.5.0" +"@react-aria/toggle@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.8.2.tgz#4336f0d70e33347c7bcf43f3ec4e617ce449127b" + integrity sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/toggle" "^3.6.3" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@react-types/switch" "^3.4.2" + "@swc/helpers" "^0.5.0" + +"@react-aria/tooltip@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.4.tgz#1be90589f290b09c2a938907124cf72821fb277c" + integrity sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw== + dependencies: + "@react-aria/focus" "^3.14.3" + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-stately/tooltip" "^3.4.5" + "@react-types/shared" "^3.21.0" + "@react-types/tooltip" "^3.4.5" + "@swc/helpers" "^0.5.0" + "@react-aria/utils@^3.21.1": version "3.21.1" resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.21.1.tgz#35f5d545757ea38f05a0d2f5492f13217ebb03ce" @@ -3354,11 +3774,150 @@ "@swc/helpers" "^0.5.0" clsx "^1.1.1" +"@react-aria/visually-hidden@^3.8.6": + version "3.8.6" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.6.tgz#9b149851ac41e9c72c7819f8d4ad47ddfb45b863" + integrity sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + clsx "^1.1.1" + "@react-icons/all-files@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== +"@react-stately/calendar@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.1.tgz#8982ca015c81f35154a23fb26a514a08f9b041a5" + integrity sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-stately/utils" "^3.8.0" + "@react-types/calendar" "^3.4.1" + "@react-types/datepicker" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/checkbox@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.5.1.tgz#a6f6ad01852aded85f4baa7c3e97e44d2c47a607" + integrity sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw== + dependencies: + "@react-stately/toggle" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/collections@^3.10.2": + version "3.10.2" + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.2.tgz#c739d9d596ecb744be15fde6f064ad85dd6145db" + integrity sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q== + dependencies: + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/combobox@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.7.1.tgz#d101280d406469479ba954cabd872188634033c4" + integrity sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/select" "^3.5.5" + "@react-stately/utils" "^3.8.0" + "@react-types/combobox" "^3.8.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/data@^3.10.3": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.10.3.tgz#4cdbb0f29489e6f74d2ae7ae032930336695eaa0" + integrity sha512-cC9mxCZU4N9GbdOB4g2/J8+W+860GvBd874to0ObSc/XOR4VbuIsxAFIabW5UwmJV+XaqqK4TUBG0C6YScXeWQ== + dependencies: + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/datepicker@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.8.0.tgz#f87eefb4c5dec937b9d5eb101dd4407457ecd0e7" + integrity sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g== + dependencies: + "@internationalized/date" "^3.5.0" + "@internationalized/string" "^3.1.1" + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/datepicker" "^3.6.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/dnd@^3.2.5": + version "3.2.5" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.5.tgz#e18c9708133071df911792e85ef6edd2508b3a71" + integrity sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ== + dependencies: + "@react-stately/selection" "^3.14.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/flags@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-stately/flags/-/flags-3.0.0.tgz#c5a73965f8c90e8bf5981adddb4bdbb0ba2f5690" + integrity sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w== + dependencies: + "@swc/helpers" "^0.4.14" + +"@react-stately/grid@^3.8.2": + version "3.8.2" + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.2.tgz#b2bd8614489a46ad7d0de13551507afd68d95de2" + integrity sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/layout@^3.13.3": + version "3.13.3" + resolved "https://registry.yarnpkg.com/@react-stately/layout/-/layout-3.13.3.tgz#65ca0ad8a4653122017c68ec2dc3a3d592296d02" + integrity sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/table" "^3.11.2" + "@react-stately/virtualizer" "^3.6.4" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/list@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.0.tgz#6b2c66778b687d8c197809059f102029a9bb5079" + integrity sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/menu@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.6.tgz#21861b7cfba579d69272509aef8197d3fad7463a" + integrity sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA== + dependencies: + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/menu" "^3.9.5" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-stately/numberfield@^3.6.2": version "3.6.2" resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.6.2.tgz#2102d956239721fbf629891d2de46920416492fc" @@ -3370,6 +3929,128 @@ "@react-types/shared" "^3.21.0" "@swc/helpers" "^0.5.0" +"@react-stately/overlays@^3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.3.tgz#cdfe5edb1ed6ad84fc1022af931586489cb23552" + integrity sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/overlays" "^3.8.3" + "@swc/helpers" "^0.5.0" + +"@react-stately/radio@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.9.1.tgz#c43c88e2bff23d3059b0ea22191337a1d644fe0c" + integrity sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/radio" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/searchfield@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.4.6.tgz#8d2a394fc20fec559d669e5d63c0a4d7588cb4a0" + integrity sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/searchfield" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/select@^3.5.5": + version "3.5.5" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.5.5.tgz#e0b6dc9635bf46632efeba552e7ff3641c2f581f" + integrity sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/select" "^3.8.4" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/selection@^3.14.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.0.tgz#26a574bf2e35657db1988974df8bd2747b09f5c6" + integrity sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/slider@^3.4.4": + version "3.4.4" + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.4.tgz#36a3f171077fb0e5bd7af7accdc228f5fd2fbe32" + integrity sha512-tFexbtN50zSo6e1Gi8K9MBfqgOo1eemF/VvFbde3PP9nG+ODcxEIajaYDPlMUuFw5cemJuoKo3+G5NBBn2/AjQ== + dependencies: + "@react-aria/i18n" "^3.8.4" + "@react-aria/utils" "^3.21.1" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@react-types/slider" "^3.6.2" + "@swc/helpers" "^0.5.0" + +"@react-stately/table@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.2.tgz#df78442355f3dd086042ad4bf6473a2aaf31f6c1" + integrity sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/flags" "^3.0.0" + "@react-stately/grid" "^3.8.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + "@react-types/table" "^3.9.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/tabs@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.1.tgz#61c010c82ba0d6fde7804245742e0569d6b9eafd" + integrity sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag== + dependencies: + "@react-stately/list" "^3.10.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@react-types/tabs" "^3.3.3" + "@swc/helpers" "^0.5.0" + +"@react-stately/toggle@^3.6.3": + version "3.6.3" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.6.3.tgz#4de25fd458890e37f6c363d058b018e5f11a9882" + integrity sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q== + dependencies: + "@react-stately/utils" "^3.8.0" + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/tooltip@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.5.tgz#9ba147485d7d7123da91bb417d3722351e90394d" + integrity sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q== + dependencies: + "@react-stately/overlays" "^3.6.3" + "@react-stately/utils" "^3.8.0" + "@react-types/tooltip" "^3.4.5" + "@swc/helpers" "^0.5.0" + +"@react-stately/tree@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.3.tgz#d0b3da5db553e64e8f3def5bae45f765f62a3fd8" + integrity sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA== + dependencies: + "@react-stately/collections" "^3.10.2" + "@react-stately/selection" "^3.14.0" + "@react-stately/utils" "^3.8.0" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + "@react-stately/utils@^3.8.0": version "3.8.0" resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.8.0.tgz#88a45742c58bde804f6cbecb20ea3833915cfdf0" @@ -3377,6 +4058,23 @@ dependencies: "@swc/helpers" "^0.5.0" +"@react-stately/virtualizer@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.4.tgz#fab655aa14d30a7241ff5751a0eb80552ac5d751" + integrity sha512-lf3+FDRnyLyY1IhLfwA6GuE/9F3nIEc5p245NkUSN1ngKlXI5PvLHNatiVbONC3wt90abkpMK+WMhu2S/B+4lA== + dependencies: + "@react-aria/utils" "^3.21.1" + "@react-types/shared" "^3.21.0" + "@swc/helpers" "^0.5.0" + +"@react-types/breadcrumbs@^3.7.1": + version "3.7.1" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.1.tgz#ec89a2acbae7c9637d087ed0a5f17dda76219d76" + integrity sha512-WWC5pQdWkAzJ2hkx4w7f+waDLLvuD9vowKey+bdLoEmKvdaHNLLVUQPEyFm6SQ5+E3pNBWkNx9a+0S9iW6wa+Q== + dependencies: + "@react-types/link" "^3.5.1" + "@react-types/shared" "^3.21.0" + "@react-types/button@^3.9.0": version "3.9.0" resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.0.tgz#66df80cafaa98aaa34c331e927d21fdf4a0bdc4a" @@ -3384,6 +4082,53 @@ dependencies: "@react-types/shared" "^3.21.0" +"@react-types/calendar@^3.4.1": + version "3.4.1" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.1.tgz#fa12696b3aae5247b3b1dcf747cbc2c5d5d7c30c" + integrity sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/shared" "^3.21.0" + +"@react-types/checkbox@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.5.2.tgz#f463befdd37bc2c9e5c6febd62e53131e8983fa4" + integrity sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/combobox@^3.8.1": + version "3.8.1" + resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.8.1.tgz#ac9c7abcdde708b09fae78b0dd6d88993f6a8177" + integrity sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/datepicker@^3.6.1": + version "3.6.1" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.6.1.tgz#07debffdd611da13f6926266687c22b92624b7ab" + integrity sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/calendar" "^3.4.1" + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + +"@react-types/dialog@^3.5.6": + version "3.5.6" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.6.tgz#e874f0896d595e5a7f5924165b0db78e5f62fe9d" + integrity sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + +"@react-types/grid@^3.2.2": + version "3.2.2" + resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.2.tgz#9434d8ed0a80a64e38b2c95f8bbccfa794fd3888" + integrity sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg== + dependencies: + "@react-types/shared" "^3.21.0" + "@react-types/label@^3.8.1": version "3.8.1" resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.8.1.tgz#b076a0fb955051307bfa3fed7e18ce0dc76d8c7b" @@ -3391,6 +4136,37 @@ dependencies: "@react-types/shared" "^3.21.0" +"@react-types/link@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.1.tgz#042cd4f7e7929a53657a5432fd3497056c331b34" + integrity sha512-hX2KpjB7wSuJw5Pia63+WEgEql53VfVG1Vu2cTUJDxfrgUtawwHtxB8B0K3cs3jBanq69amgAInEx0FfqYY0uQ== + dependencies: + "@react-aria/interactions" "^3.19.1" + "@react-types/shared" "^3.21.0" + +"@react-types/listbox@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.5.tgz#c18fbfe38412f7ce42b381fd4aa7bf443dcb6a59" + integrity sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/menu@^3.9.5": + version "3.9.5" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.5.tgz#9f67aebda9f491f0e94e2de7a15898c6cabf0772" + integrity sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + +"@react-types/meter@^3.3.5": + version "3.3.5" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.5.tgz#274dc17b4de985063e74272d82c0052e13bb75e8" + integrity sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg== + dependencies: + "@react-types/progress" "^3.5.0" + "@react-types/shared" "^3.21.0" + "@react-types/numberfield@^3.6.1": version "3.6.1" resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.6.1.tgz#da13f9086181a64a7e2e39f500584bdca20097b3" @@ -3398,11 +4174,77 @@ dependencies: "@react-types/shared" "^3.21.0" +"@react-types/overlays@^3.8.3": + version "3.8.3" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.3.tgz#47132f08ae3a115273036d98b9441a51d4a4ab09" + integrity sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/progress@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.0.tgz#5fa64897bcf93308c8386a3d0444585cb869e313" + integrity sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/radio@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.5.2.tgz#399e220e2529b2e7c93aa117d39adcca6dc24d1f" + integrity sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/searchfield@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.1.tgz#9e8d9b4ff16749a821cbba20e0069f5d77a8b9f2" + integrity sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ== + dependencies: + "@react-types/shared" "^3.21.0" + "@react-types/textfield" "^3.8.1" + +"@react-types/select@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.8.4.tgz#564e6d89095d736ed580a733dd8baa7fadab05bc" + integrity sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ== + dependencies: + "@react-types/shared" "^3.21.0" + "@react-types/shared@^3.21.0": version "3.21.0" resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.21.0.tgz#1af41fdf7dfbdbd33bbc1210617c43ed0d4ef20c" integrity sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg== +"@react-types/slider@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.6.2.tgz#b401bbbd473b62edc394ac3c41ed6df329d111d4" + integrity sha512-LSvna1gpOvBxOBI5I/CYEtkAshWYwPlxE9F/jCaxCa9Q7E9xZp1hFFGY87iQ1A3vQM5SCa5PFStwOvXO7rA55w== + dependencies: + "@react-types/shared" "^3.21.0" + +"@react-types/switch@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.4.2.tgz#8c0a8f8dfcaae29ccd9409a2beaac0d31a131027" + integrity sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A== + dependencies: + "@react-types/checkbox" "^3.5.2" + "@react-types/shared" "^3.21.0" + +"@react-types/table@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.0.tgz#0053ce5b78f2214afaf7e38cdd96a57eecbd2ff9" + integrity sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg== + dependencies: + "@react-types/grid" "^3.2.2" + "@react-types/shared" "^3.21.0" + +"@react-types/tabs@^3.3.3": + version "3.3.3" + resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.3.tgz#8601d9cd03c6aa4cca1227df667ae8cedb58839c" + integrity sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw== + dependencies: + "@react-types/shared" "^3.21.0" + "@react-types/textfield@^3.8.1": version "3.8.1" resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.8.1.tgz#433c82d8f696ed77b1d5e71aadc40cbe378b536c" @@ -3410,6 +4252,14 @@ dependencies: "@react-types/shared" "^3.21.0" +"@react-types/tooltip@^3.4.5": + version "3.4.5" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.5.tgz#f1edf9940bc3cde89ae9d49fda815e16f253dfd5" + integrity sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q== + dependencies: + "@react-types/overlays" "^3.8.3" + "@react-types/shared" "^3.21.0" + "@remix-run/router@1.11.0": version "1.11.0" resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.11.0.tgz#e0e45ac3fff9d8a126916f166809825537e9f955" @@ -4128,13 +4978,13 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channels@7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.2.tgz#f5ea597a799e13b7307fe79067faede5e13e6619" - integrity sha512-3SgqWq9NS0XX1QxK3riuaOLrReHWwVhI63u6q1ryDD3SttpmAezZETibOAtzDuk2FKgsyHTmAlmcGQf4ZxhOJA== +"@storybook/channels@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" + integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== dependencies: - "@storybook/client-logger" "7.5.2" - "@storybook/core-events" "7.5.2" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -4174,10 +5024,10 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/client-logger@7.5.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.2.tgz#ffe6fd3cb336fc7dac6670412c4c8bf70e89c1d1" - integrity sha512-7YgLItlmiYDzWYexTaRNuHhtFarh9krsI+8l7Yjn9ryoHSTJUcTWx+yPJm1II+PQR8v/x5UgsxzultjgEurfRQ== +"@storybook/client-logger@7.5.3", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" + integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== dependencies: "@storybook/global" "^5.0.0" @@ -4284,10 +5134,10 @@ dependencies: core-js "^3.8.2" -"@storybook/core-events@7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.2.tgz#e5185e39fdcb7ab93510f6174798d5f242e1041b" - integrity sha512-DV8bFEFVKDEvaH87KYPXDE0YEV+Y9yjFv2xxmC9pF8l+MWCtVW72RBLhB+gU5NM1bkHrRDNb0lOJfVGKlhxOog== +"@storybook/core-events@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" + integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== dependencies: ts-dedent "^2.0.0" @@ -4421,15 +5271,15 @@ global "^4.4.0" "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.2.tgz#1a88c0e4e30d4b8d79c0aeaf106048e3ac9ecfa0" - integrity sha512-1l36cc7GaVeTiknhToZcaqI6RsIOfcBgdnvgJ0tiL1naN1GkneCMr+1oLWnlHVrWIOXgh6vNyD792kE3uTLkFg== + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.3.tgz#de875ba10db3b5a06a1acbc27a8b1f8fb1d875ff" + integrity sha512-p6b+/6ohTCKxWn00bXT8KBqVjXUOxeILnJtLlG83USLQCpI+XVkpmK57HYuydqEwy/1XjG+4S4ntPk9VVz3u7w== dependencies: - "@storybook/channels" "7.5.2" - "@storybook/client-logger" "7.5.2" - "@storybook/core-events" "7.5.2" + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.5.2" + "@storybook/preview-api" "7.5.3" "@storybook/manager-webpack4@6.5.16": version "6.5.16" @@ -4545,17 +5395,17 @@ dependencies: core-js "^3.8.2" -"@storybook/preview-api@7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.2.tgz#72512c11369975904894c6f50036f10d3c329e59" - integrity sha512-rpmHR/09UBSnorDBTcE7JgHUQjZLO146NCI+vbI7Pqfb4QX/8lhwkFr4cuHRAR16mv6DAJbDVoPETO0Z/CH9aw== +"@storybook/preview-api@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" + integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== dependencies: - "@storybook/channels" "7.5.2" - "@storybook/client-logger" "7.5.2" - "@storybook/core-events" "7.5.2" + "@storybook/channels" "7.5.3" + "@storybook/client-logger" "7.5.3" + "@storybook/core-events" "7.5.3" "@storybook/csf" "^0.1.0" "@storybook/global" "^5.0.0" - "@storybook/types" "7.5.2" + "@storybook/types" "7.5.3" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -4736,12 +5586,12 @@ memoizerific "^1.11.3" regenerator-runtime "^0.13.7" -"@storybook/types@7.5.2": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.2.tgz#38f2e4a4cb0bb402b840d9e7f7762c0d113dc63b" - integrity sha512-RDKHo6WUES+4nt7uZMfankjxdpYX2EI2GpJ2n2RPcnhzmb/ub1huNTjbzDEYMqY24SppljZeIN57m3Ar6L6f9A== +"@storybook/types@7.5.3": + version "7.5.3" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" + integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== dependencies: - "@storybook/channels" "7.5.2" + "@storybook/channels" "7.5.3" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -4872,6 +5722,14 @@ "@svgr/plugin-jsx" "^6.5.1" "@svgr/plugin-svgo" "^6.5.1" +"@swc/helpers@^0.4.14": + version "0.4.36" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.36.tgz#fcfff76ed52c214f357e8e9d3f37b568908072d9" + integrity sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q== + dependencies: + legacy-swc-helpers "npm:@swc/helpers@=0.4.14" + tslib "^2.4.0" + "@swc/helpers@^0.5.0": version "0.5.3" resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" @@ -4879,7 +5737,7 @@ dependencies: tslib "^2.4.0" -"@tauri-apps/api@^1.2.0": +"@tauri-apps/api@^1.2.0", "@tauri-apps/api@^1.5.1": version "1.5.1" resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.1.tgz#9074476c4323f71351db624e9711c99277cdfb99" integrity sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA== @@ -5601,7 +6459,7 @@ dependencies: react-tooltip "*" -"@types/react-transition-group@^4.4.6", "@types/react-transition-group@^4.4.8": +"@types/react-transition-group@^4.4.8": version "4.4.8" resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" integrity sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg== @@ -5609,9 +6467,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.34" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.34.tgz#aed20f19473721ba328feb99d1ec3307ebc1a8dd" - integrity sha512-U6eW/alrRk37FU/MS2RYMjx0Va2JGIVXELTODaTIYgvWGCV4Y4TfTUzG8DdmpDNIT0Xpj/R7GfyHOJJrDttcvg== + version "18.2.36" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.36.tgz#bc68ffb4408e5d0c419b0760b2eaeec70aeeedb3" + integrity sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -6078,7 +6936,7 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.10.4", "@walletconnect/types@^2.9.0": +"@walletconnect/types@2.10.4": version "2.10.4" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.4.tgz#23f6e4bd785671812dc6ea96848a6bd7ea78f038" integrity sha512-eQpOElyiwJp3tepuOS3TS9dXTl9jVVlrC3iVA8bytnbLagkAUxmiv/s7PyDFx+ndXwQVh8PFBkWg1oxGwgCSBA== @@ -6090,18 +6948,6 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" -"@walletconnect/types@2.7.2": - version "2.7.2" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.7.2.tgz#508d1755110864dee294f955e09b7da3f8ee0064" - integrity sha512-1O2UefakZpT0ErRfEAXY7Ls3qdUrKDky/DsK088xR6klyfkQOx+aSVH0fJYLhmnqPTuvp3lrqNbsDc0s6/6nvg== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "^1.0.2" - "@walletconnect/keyvaluestorage" "^1.0.2" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - "@walletconnect/utils@2.10.4", "@walletconnect/utils@^2.9.0": version "2.10.4" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.4.tgz#5f17938e7ea481541ec2dbae0df5cd494c72523f" @@ -7274,6 +8120,11 @@ base-x@^3.0.2, base-x@^3.0.6: dependencies: safe-buffer "^5.0.1" +base-x@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" + integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== + base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -7597,6 +8448,13 @@ bs58@^4.0.0, bs58@^4.0.1: dependencies: base-x "^3.0.2" +bs58@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" + integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== + dependencies: + base-x "^4.0.0" + bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" @@ -8141,6 +8999,11 @@ cli-width@^3.0.0: resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +client-only@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" + integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== + clipboard-copy@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" @@ -10664,9 +11527,9 @@ fast-glob@^2.2.6: micromatch "^3.1.10" fast-glob@^3.2.9: - version "3.3.1" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.1.tgz#784b4e897340f3dbbef17413b3f11acf03c874c4" - integrity sha512-kNFPyjhh5cKjrUltxs+wFx+ZkbRaxxmZ+X0ZU31SOsxCEtP9VPgtq2teZw1DebupL5GmDaNQ6yKMMVcM41iqDg== + version "3.3.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" + integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -12821,9 +13684,9 @@ isomorphic-ws@^4.0.1: integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" - integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== + version "3.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.1.tgz#c680fd1544600460367af5811866c34c44c6f3b1" + integrity sha512-opCrKqbthmq3SKZ10mFMQG9dk3fTa3quaOLD35kJa5ejwZHd9xAr+kLuziiZz2cG32s4lMZxNdmdcEQnTDP4+g== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" @@ -13780,6 +14643,13 @@ lazy-universal-dotenv@^3.0.1: dotenv "^8.0.0" dotenv-expand "^5.1.0" +"legacy-swc-helpers@npm:@swc/helpers@=0.4.14": + version "0.4.14" + resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" + integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== + dependencies: + tslib "^2.4.0" + lerna@^7.3.0: version "7.4.2" resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" @@ -15308,9 +16178,9 @@ nanoid@3.3.3: integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== nanoid@^3.3.1, nanoid@^3.3.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.6.tgz#443380c856d6e9f9824267d960b4236ad583ea4c" - integrity sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA== + version "3.3.7" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" + integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== nanomatch@^1.2.9: version "1.2.13" @@ -17324,6 +18194,48 @@ rc@^1.2.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +react-aria@^3.29.1: + version "3.29.1" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.29.1.tgz#4f6e968a15cfec69d8d8735b98d0fe8ac31b4be2" + integrity sha512-dDoaTh5fCaD3kO0kv49pqUUOsXRGuqFX7owQaly/RhWkBw/dlIYkHRVdOatllI/v4h1/Ne40QOXl15aAISozlA== + dependencies: + "@react-aria/breadcrumbs" "^3.5.7" + "@react-aria/button" "^3.8.4" + "@react-aria/calendar" "^3.5.2" + "@react-aria/checkbox" "^3.11.2" + "@react-aria/combobox" "^3.7.1" + "@react-aria/datepicker" "^3.8.1" + "@react-aria/dialog" "^3.5.7" + "@react-aria/dnd" "^3.4.3" + "@react-aria/focus" "^3.14.3" + "@react-aria/gridlist" "^3.7.1" + "@react-aria/i18n" "^3.8.4" + "@react-aria/interactions" "^3.19.1" + "@react-aria/label" "^3.7.2" + "@react-aria/link" "^3.6.1" + "@react-aria/listbox" "^3.11.1" + "@react-aria/menu" "^3.11.1" + "@react-aria/meter" "^3.4.7" + "@react-aria/numberfield" "^3.9.1" + "@react-aria/overlays" "^3.18.1" + "@react-aria/progress" "^3.4.7" + "@react-aria/radio" "^3.8.2" + "@react-aria/searchfield" "^3.5.7" + "@react-aria/select" "^3.13.1" + "@react-aria/selection" "^3.17.1" + "@react-aria/separator" "^3.3.7" + "@react-aria/slider" "^3.7.2" + "@react-aria/ssr" "^3.8.0" + "@react-aria/switch" "^3.5.6" + "@react-aria/table" "^3.13.1" + "@react-aria/tabs" "^3.8.1" + "@react-aria/tag" "^3.2.1" + "@react-aria/textfield" "^3.12.2" + "@react-aria/tooltip" "^3.6.4" + "@react-aria/utils" "^3.21.1" + "@react-aria/visually-hidden" "^3.8.6" + "@react-types/shared" "^3.21.0" + react-docgen-typescript@^2.1.1: version "2.2.2" resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" @@ -17501,6 +18413,34 @@ react-smooth@^2.0.4: fast-equals "^5.0.0" react-transition-group "2.9.0" +react-stately@^3.27.1: + version "3.27.1" + resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.27.1.tgz#b24992bd72da1b1632bf4f4232d87ce6913a19bd" + integrity sha512-qHhivqOpyATaWwoj3xl3IqqoEnib+dsl2vYlOz92CT5Ntm6lprF7KO+LkxdkS0SnUckdGewFM1NjCmbK7wPJgw== + dependencies: + "@react-stately/calendar" "^3.4.1" + "@react-stately/checkbox" "^3.5.1" + "@react-stately/collections" "^3.10.2" + "@react-stately/combobox" "^3.7.1" + "@react-stately/data" "^3.10.3" + "@react-stately/datepicker" "^3.8.0" + "@react-stately/dnd" "^3.2.5" + "@react-stately/list" "^3.10.0" + "@react-stately/menu" "^3.5.6" + "@react-stately/numberfield" "^3.6.2" + "@react-stately/overlays" "^3.6.3" + "@react-stately/radio" "^3.9.1" + "@react-stately/searchfield" "^3.4.6" + "@react-stately/select" "^3.5.5" + "@react-stately/selection" "^3.14.0" + "@react-stately/slider" "^3.4.4" + "@react-stately/table" "^3.11.2" + "@react-stately/tabs" "^3.6.1" + "@react-stately/toggle" "^3.6.3" + "@react-stately/tooltip" "^3.4.5" + "@react-stately/tree" "^3.7.3" + "@react-types/shared" "^3.21.0" + react-tooltip@*: version "5.22.0" resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.22.0.tgz#3082065b1efbd207813f484b617b1b75325f15d5" @@ -21355,7 +22295,7 @@ yup@^1.2.0: toposort "^2.0.2" type-fest "^2.19.0" -zustand@^4.3.8: +zustand@4.4.6: version "4.4.6" resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== From 081fec72e52dce54f08e06ceb8d34e68f33f40a1 Mon Sep 17 00:00:00 2001 From: Yana Date: Tue, 7 Nov 2023 13:02:00 +0000 Subject: [PATCH 123/394] Connect delegate modal to keplr balance WIP WIP WIP WIP --- .../src/components/ConnectKeplrWallet.tsx | 19 +- .../Delegations/components/ConfirmTX.tsx | 48 +++ .../{ => components}/ConfirmationModal.tsx | 0 .../{ => components}/DelegateModal.tsx | 184 +++++---- .../{ => components}/ErrorModal.tsx | 2 +- .../Delegations/components/FeeWarning.tsx | 35 ++ .../Delegations/components/ModalDivider.tsx | 6 + .../Delegations/components/ModalFee.tsx | 35 ++ .../{ => components}/ModalListItem.tsx | 2 +- .../{ => components}/SimpleModal.tsx | 2 +- .../Delegations/components/styles.ts | 21 + explorer/src/components/Delegations/config.ts | 4 + .../Delegations/context/accounts.tsx | 170 ++++++++ .../components/Delegations/context/buy.tsx | 59 +++ .../components/Delegations/context/index.tsx | 3 + .../components/Delegations/context/main.tsx | 366 ++++++++++++++++++ .../Delegations/hooks/useCheckOwnership.ts | 59 +++ .../Delegations/hooks/useGetBalance.ts | 147 +++++++ .../components/Delegations/hooks/useGetFee.ts | 49 +++ .../Delegations/hooks/useKeyPress.ts | 29 ++ .../Delegations/requests/account.ts | 67 ++++ .../Delegations/requests/actions.ts | 54 +++ .../components/Delegations/requests/app.ts | 14 + .../Delegations/requests/contract.ts | 7 + .../Delegations/requests/delegation.ts | 33 ++ .../components/Delegations/requests/index.ts | 14 + .../Delegations/requests/logging.ts | 3 + .../Delegations/requests/network.ts | 16 + .../Delegations/requests/pendingEvents.ts | 4 + .../Delegations/requests/queries.ts | 63 +++ .../Delegations/requests/rewards.ts | 14 + .../Delegations/requests/signature.ts | 9 + .../Delegations/requests/simulate.ts | 87 +++++ .../components/Delegations/requests/utils.ts | 11 + .../Delegations/requests/vesting.ts | 125 ++++++ .../Delegations/requests/wrapper.ts | 20 + .../components/Delegations/types/global.ts | 97 +++++ .../src/components/Delegations/types/index.ts | 7 + .../Delegations/types/rust/AppEnv.ts | 5 + .../Delegations/types/rust/AppVersion.ts | 7 + .../Delegations/types/rust/Epoch.ts | 8 + .../Delegations/types/rust/Interval.ts | 8 + .../Delegations/types/rust/Network.ts | 3 + .../Delegations/types/rust/StateParams.ts | 8 + .../Delegations/types/rust/ValidatorUrl.ts | 6 + .../Delegations/types/rust/ValidatorUrls.ts | 6 + .../components/Delegations/typings/FC.d.ts | 1 + .../components/Delegations/typings/jpeg.d.ts | 9 + .../components/Delegations/typings/json.d.ts | 4 + .../components/Delegations/typings/png.d.ts | 4 + .../components/Delegations/typings/svg.d.ts | 4 + .../components/Delegations/utils/common.ts | 255 ++++++++++++ .../components/Delegations/utils/console.ts | 10 + .../Delegations/utils/fireRequests.ts | 22 ++ .../src/components/Delegations/utils/index.ts | 4 + .../src/components/Delegations/utils/sleep.ts | 3 + explorer/src/components/TableToolbar.tsx | 67 +++- 57 files changed, 2202 insertions(+), 117 deletions(-) create mode 100644 explorer/src/components/Delegations/components/ConfirmTX.tsx rename explorer/src/components/Delegations/{ => components}/ConfirmationModal.tsx (100%) rename explorer/src/components/Delegations/{ => components}/DelegateModal.tsx (61%) rename explorer/src/components/Delegations/{ => components}/ErrorModal.tsx (91%) create mode 100644 explorer/src/components/Delegations/components/FeeWarning.tsx create mode 100644 explorer/src/components/Delegations/components/ModalDivider.tsx create mode 100644 explorer/src/components/Delegations/components/ModalFee.tsx rename explorer/src/components/Delegations/{ => components}/ModalListItem.tsx (91%) rename explorer/src/components/Delegations/{ => components}/SimpleModal.tsx (97%) create mode 100644 explorer/src/components/Delegations/components/styles.ts create mode 100644 explorer/src/components/Delegations/config.ts create mode 100644 explorer/src/components/Delegations/context/accounts.tsx create mode 100644 explorer/src/components/Delegations/context/buy.tsx create mode 100644 explorer/src/components/Delegations/context/index.tsx create mode 100644 explorer/src/components/Delegations/context/main.tsx create mode 100644 explorer/src/components/Delegations/hooks/useCheckOwnership.ts create mode 100644 explorer/src/components/Delegations/hooks/useGetBalance.ts create mode 100644 explorer/src/components/Delegations/hooks/useGetFee.ts create mode 100644 explorer/src/components/Delegations/hooks/useKeyPress.ts create mode 100644 explorer/src/components/Delegations/requests/account.ts create mode 100644 explorer/src/components/Delegations/requests/actions.ts create mode 100644 explorer/src/components/Delegations/requests/app.ts create mode 100644 explorer/src/components/Delegations/requests/contract.ts create mode 100644 explorer/src/components/Delegations/requests/delegation.ts create mode 100644 explorer/src/components/Delegations/requests/index.ts create mode 100644 explorer/src/components/Delegations/requests/logging.ts create mode 100644 explorer/src/components/Delegations/requests/network.ts create mode 100644 explorer/src/components/Delegations/requests/pendingEvents.ts create mode 100644 explorer/src/components/Delegations/requests/queries.ts create mode 100644 explorer/src/components/Delegations/requests/rewards.ts create mode 100644 explorer/src/components/Delegations/requests/signature.ts create mode 100644 explorer/src/components/Delegations/requests/simulate.ts create mode 100644 explorer/src/components/Delegations/requests/utils.ts create mode 100644 explorer/src/components/Delegations/requests/vesting.ts create mode 100644 explorer/src/components/Delegations/requests/wrapper.ts create mode 100644 explorer/src/components/Delegations/types/global.ts create mode 100644 explorer/src/components/Delegations/types/index.ts create mode 100644 explorer/src/components/Delegations/types/rust/AppEnv.ts create mode 100644 explorer/src/components/Delegations/types/rust/AppVersion.ts create mode 100644 explorer/src/components/Delegations/types/rust/Epoch.ts create mode 100644 explorer/src/components/Delegations/types/rust/Interval.ts create mode 100644 explorer/src/components/Delegations/types/rust/Network.ts create mode 100644 explorer/src/components/Delegations/types/rust/StateParams.ts create mode 100644 explorer/src/components/Delegations/types/rust/ValidatorUrl.ts create mode 100644 explorer/src/components/Delegations/types/rust/ValidatorUrls.ts create mode 100644 explorer/src/components/Delegations/typings/FC.d.ts create mode 100644 explorer/src/components/Delegations/typings/jpeg.d.ts create mode 100644 explorer/src/components/Delegations/typings/json.d.ts create mode 100644 explorer/src/components/Delegations/typings/png.d.ts create mode 100644 explorer/src/components/Delegations/typings/svg.d.ts create mode 100644 explorer/src/components/Delegations/utils/common.ts create mode 100644 explorer/src/components/Delegations/utils/console.ts create mode 100644 explorer/src/components/Delegations/utils/fireRequests.ts create mode 100644 explorer/src/components/Delegations/utils/index.ts create mode 100644 explorer/src/components/Delegations/utils/sleep.ts diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx index 4fab8b8712..766f96059a 100644 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -39,8 +39,17 @@ export const trimAddress = (address = '', trimBy = 6) => { }; export default function ConnectKeplrWallet() { - const { username, connect, disconnect, wallet, openView, address, getCosmWasmClient, isWalletConnected } = - useChain('nyx'); + const { + username, + connect, + disconnect, + wallet, + openView, + address, + getCosmWasmClient, + isWalletConnected, + isWalletConnecting, + } = useChain('nyx'); const isClient = useIsClient(); const theme = useTheme(); @@ -70,9 +79,9 @@ export default function ConnectKeplrWallet() { if (!isClient) return null; const getGlobalbutton = () => { - // if (globalStatus === 'Connecting') { - // return ; - // } + if (isWalletConnecting) { + return ; + } if (isWalletConnected) { return ( diff --git a/explorer/src/components/Delegations/components/ConfirmTX.tsx b/explorer/src/components/Delegations/components/ConfirmTX.tsx new file mode 100644 index 0000000000..e62a86a23c --- /dev/null +++ b/explorer/src/components/Delegations/components/ConfirmTX.tsx @@ -0,0 +1,48 @@ +import React from 'react'; +import { FeeDetails } from '@nymproject/types'; +import { Box } from '@mui/material'; +import { useTheme, Theme } from '@mui/material/styles'; +import { SimpleModal } from './SimpleModal'; +import { ModalFee } from './ModalFee'; +import { ModalDivider } from './ModalDivider'; +import { backDropStyles, modalStyles } from './styles'; + +const storybookStyles = (theme: Theme, isStorybook?: boolean, backdropProps?: object) => + isStorybook + ? { + backdropProps: { ...backDropStyles(theme), ...backdropProps }, + sx: modalStyles(theme), + } + : {}; + +export const ConfirmTx: FCWithChildren<{ + open: boolean; + header: string; + subheader?: string; + fee: FeeDetails; + onConfirm: () => Promise; + onClose?: () => void; + onPrev: () => void; + isStorybook?: boolean; + children?: React.ReactNode; +}> = ({ open, fee, onConfirm, onClose, header, subheader, onPrev, children, isStorybook }) => { + const theme = useTheme(); + return ( + + + {children} + + + + + ); +}; diff --git a/explorer/src/components/Delegations/ConfirmationModal.tsx b/explorer/src/components/Delegations/components/ConfirmationModal.tsx similarity index 100% rename from explorer/src/components/Delegations/ConfirmationModal.tsx rename to explorer/src/components/Delegations/components/ConfirmationModal.tsx diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx similarity index 61% rename from explorer/src/components/Delegations/DelegateModal.tsx rename to explorer/src/components/Delegations/components/DelegateModal.tsx index 50b7276aa5..8f36deda0e 100644 --- a/explorer/src/components/Delegations/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -1,24 +1,22 @@ -import React, { useCallback, useContext, useState } from 'react'; +import React, { useCallback, useContext, useState, useEffect } from 'react'; import { Box, Typography, SxProps } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types'; -// import { Console } from 'src/utils/console'; -// import { useGetFee } from 'src/hooks/useGetFee'; -// import { simulateDelegateToMixnode, simulateVestingDelegateToMixnode, tryConvertIdentityToMixId } from 'src/requests'; +import { Console } from '../utils/console'; +import { useGetFee } from '../hooks/useGetFee'; import { debounce } from 'lodash'; import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; -// import { AppContext } from 'src/context'; -// import { SimpleModal } from '../Modals/SimpleModal'; -// import { ModalListItem } from '../Modals/ModalListItem'; -// import { checkTokenBalance, validateAmount, validateKey } from '../../utils'; -// import { TokenPoolSelector, TPoolOption } from '../TokenPoolSelector'; -// import { ConfirmTx } from '../ConfirmTX'; -// import { getMixnodeStakeSaturation } from '../../requests'; -// import { ErrorModal } from '../Modals/ErrorModal'; -// import { BalanceWarning } from '../FeeWarning'; +import { TPoolOption, checkTokenBalance, validateAmount, validateKey } from '../utils'; + +import { useChain } from '@cosmos-kit/react'; +import { uNYMtoNYM } from '../utils'; +import { ErrorModal } from './ErrorModal'; +import { ConfirmTx } from './ConfirmTX'; +import { BalanceWarning } from './FeeWarning'; +import { getMixnodeStakeSaturation, simulateDelegateToMixnode, tryConvertIdentityToMixId } from '../requests'; const MIN_AMOUNT_TO_DELEGATE = 10; @@ -29,8 +27,8 @@ export const DelegateModal: FCWithChildren<{ mixId: number, identityKey: string, amount: DecCoin, - // tokenPool: TPoolOption, - // fee?: FeeDetails, + tokenPool: TPoolOption, + fee?: FeeDetails, ) => Promise; identityKey?: string; onIdentityKeyChanged?: (identityKey: string) => void; @@ -38,7 +36,7 @@ export const DelegateModal: FCWithChildren<{ header?: string; buttonText?: string; rewardInterval: string; - accountBalance?: string; + // accountBalance?: string; estimatedReward?: number; profitMarginPercentage?: string | null; nodeUptimePercentage?: number | null; @@ -57,7 +55,7 @@ export const DelegateModal: FCWithChildren<{ buttonText, identityKey: initialIdentityKey, rewardInterval, - accountBalance, + // accountBalance, estimatedReward, denom, profitMarginPercentage, @@ -76,47 +74,45 @@ export const DelegateModal: FCWithChildren<{ const [errorIdentityKey, setErrorIdentityKey] = useState(); const [mixIdError, setMixIdError] = useState(); - // const { fee, getFee, resetFeeState, feeError } = useGetFee(); - // const { userBalance } = useContext(AppContext); + const { fee, getFee, resetFeeState, feeError } = useGetFee(); - // const handleCheckStakeSaturation = async (newMixId: number) => { - // try { - // const newSaturation = decimalToFloatApproximation( - // (await getMixnodeStakeSaturation(newMixId)).uncapped_saturation, - // ); - // if (newSaturation && newSaturation > 1) { - // const saturationPercentage = Math.round(newSaturation * 100); - // return { isOverSaturated: true, saturationPercentage }; - // } - // return { isOverSaturated: false, saturationPercentage: undefined }; - // } catch (e) { - // Console.error('Error fetching the saturation, error:', e); - // return { isOverSaturated: false, saturationPercentage: undefined }; - // } - // }; + const { username, connect, disconnect, wallet, openView, address, getCosmWasmClient, isWalletConnected } = + useChain('nyx'); + const [balance, setBalance] = useState<{ + status: 'loading' | 'success'; + data?: string; + }>({ status: 'loading', data: undefined }); + + useEffect(() => { + const getBalance = async (walletAddress: string) => { + setBalance({ status: 'loading', data: undefined }); + + const account = await getCosmWasmClient(); + const uNYMBalance = await account.getBalance(walletAddress, 'unym'); + const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); + + setBalance({ status: 'success', data: NYMBalance }); + }; + + if (address) { + getBalance(address); + } + }, [address, getCosmWasmClient]); const validate = async () => { let newValidatedValue = true; let errorAmountMessage; let errorIdentityKeyMessage; - // if (!identityKey || !validateKey(identityKey, 32)) { - // newValidatedValue = false; - // errorIdentityKeyMessage = undefined; - // } + if (!identityKey) { + newValidatedValue = false; + errorIdentityKeyMessage = 'Please enter a valid identity key'; + } - // if (identityKey && mixId && validateKey(identityKey, 32)) { - // const { isOverSaturated, saturationPercentage } = await handleCheckStakeSaturation(mixId); - // if (isOverSaturated) { - // newValidatedValue = false; - // errorIdentityKeyMessage = `This node is over saturated (${saturationPercentage}%), please select another node`; - // } - // } - - // if (amount && !(await validateAmount(amount, '0'))) { - // newValidatedValue = false; - // errorAmountMessage = 'Please enter a valid amount'; - // } + if (amount && !(await validateAmount(amount, '0'))) { + newValidatedValue = false; + errorAmountMessage = 'Please enter a valid amount'; + } if (amount && Number(amount) < MIN_AMOUNT_TO_DELEGATE) { errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`; @@ -127,9 +123,9 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; } - if (!mixId) { - newValidatedValue = false; - } + // if (!mixId) { + // newValidatedValue = false; + // } setErrorIdentityKey(errorIdentityKeyMessage); if (mixIdError && !errorIdentityKeyMessage) { @@ -141,21 +137,22 @@ export const DelegateModal: FCWithChildren<{ const handleOk = async () => { if (onOk && amount && identityKey && mixId) { - onOk(mixId, identityKey, { amount, denom }); //tokenPool, fee); + onOk(mixId, identityKey, { amount, denom }, 'balance', fee); } }; const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { - const hasEnoughTokens = true; // await checkTokenBalance(tokenPool, value.amount); + const tokenPool = 'balance'; + const hasEnoughTokens = checkTokenBalance(tokenPool, value.amount, balance.data || '0'); if (!hasEnoughTokens) { setErrorAmount('Not enough funds'); return; } - // if (tokenPool === 'balance') { - // getFee(simulateDelegateToMixnode, { mixId: id, amount: value }); - // } + if (tokenPool === 'balance') { + getFee(simulateDelegateToMixnode, { mixId: id, amount: value }); + } // if (tokenPool === 'locked') { // getFee(simulateVestingDelegateToMixnode, { mixId: id, amount: value }); @@ -184,15 +181,14 @@ export const DelegateModal: FCWithChildren<{ const resolveMixId = useCallback( debounce(async (idKey) => { - if (!idKey) { - //|| !validateKey(idKey, 32)) + if (!idKey || !validateKey(idKey, 32)) { return; } let res; try { - // res = await tryConvertIdentityToMixId(idKey); + res = await tryConvertIdentityToMixId(idKey); } catch (e) { - // Console.warn(`failed to resolve mix_id for "${idKey}": ${e}`); + Console.warn(`failed to resolve mix_id for "${idKey}": ${e}`); return; } if (res) { @@ -209,38 +205,38 @@ export const DelegateModal: FCWithChildren<{ resolveMixId(identityKey); }, [identityKey]); - // if (fee) { - // return ( - // - // {userBalance.balance?.amount.amount && fee?.amount?.amount && ( - // - // - // - // )} - // - // - // - // ); - // } + if (fee) { + return ( + + {balance.data && fee?.amount?.amount && ( + + + + )} + + + + ); + } - // if (feeError) { - // return ( - // - // ); - // } + if (feeError) { + return ( + + ); + } return ( - + diff --git a/explorer/src/components/Delegations/ErrorModal.tsx b/explorer/src/components/Delegations/components/ErrorModal.tsx similarity index 91% rename from explorer/src/components/Delegations/ErrorModal.tsx rename to explorer/src/components/Delegations/components/ErrorModal.tsx index 299760edcc..5a5df420da 100644 --- a/explorer/src/components/Delegations/ErrorModal.tsx +++ b/explorer/src/components/Delegations/components/ErrorModal.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Box, Button, Modal, SxProps, Typography } from '@mui/material'; -import { modalStyle } from '../../../../nym-wallet/src/components/Modals/styles'; +import { modalStyle } from '../../../../../nym-wallet/src/components/Modals/styles'; export const ErrorModal: FCWithChildren<{ open: boolean; diff --git a/explorer/src/components/Delegations/components/FeeWarning.tsx b/explorer/src/components/Delegations/components/FeeWarning.tsx new file mode 100644 index 0000000000..3dfaba39d1 --- /dev/null +++ b/explorer/src/components/Delegations/components/FeeWarning.tsx @@ -0,0 +1,35 @@ +import React, { useContext } from 'react'; +import { Warning } from '@mui/icons-material'; +import { FeeDetails } from '@nymproject/types'; +import { Alert, AlertTitle, Box } from '@mui/material'; +import { isBalanceEnough } from '../utils'; +import { AppContext } from '../context'; + +export const FeeWarning = ({ fee, amount }: { fee: FeeDetails; amount: number }) => { + if (fee.amount && +fee.amount.amount > amount) { + return ( + }> + Warning: Fees are greater than the reward + The fees for redeeming rewards will cost more than the rewards. Are you sure you want to continue? + + ); + } + return null; +}; + +export const BalanceWarning = ({ tx, fee }: { fee: string; tx?: string }) => { + const { userBalance } = useContext(AppContext); + + const hasEnoughBalanace = isBalanceEnough(fee, tx, userBalance.balance?.amount.amount); + + if (hasEnoughBalanace) return null; + + return ( + }> + Warning: Transaction amount is greater than your balance + The transaction amount (inc fees) is greater than your current balance, which could cause this transaction to + fail. + Do you want to continue? + + ); +}; diff --git a/explorer/src/components/Delegations/components/ModalDivider.tsx b/explorer/src/components/Delegations/components/ModalDivider.tsx new file mode 100644 index 0000000000..6258e0bfac --- /dev/null +++ b/explorer/src/components/Delegations/components/ModalDivider.tsx @@ -0,0 +1,6 @@ +import React from 'react'; +import { Box, SxProps } from '@mui/material'; + +export const ModalDivider: FCWithChildren<{ + sx?: SxProps; +}> = ({ sx }) => ; diff --git a/explorer/src/components/Delegations/components/ModalFee.tsx b/explorer/src/components/Delegations/components/ModalFee.tsx new file mode 100644 index 0000000000..835b73e689 --- /dev/null +++ b/explorer/src/components/Delegations/components/ModalFee.tsx @@ -0,0 +1,35 @@ +import React from 'react'; +import { FeeDetails } from '@nymproject/types'; +import { CircularProgress } from '@mui/material'; +import { ModalListItem } from './ModalListItem'; +import { ModalDivider } from './ModalDivider'; + +type TFeeProps = { fee?: FeeDetails; isLoading: boolean; error?: string; divider?: boolean }; +type TTotalAmountProps = { fee?: FeeDetails; amount?: string; isLoading: boolean; error?: string; divider?: boolean }; + +const getValue = ({ fee, amount, isLoading, error }: TTotalAmountProps) => { + if (isLoading) return ; + if (error && !isLoading) return 'n/a'; + if (fee) { + const numericFee = Number(fee.amount?.amount); + const numericAmountToTransfer = Number(amount); + return amount + ? `${numericFee + numericAmountToTransfer} ${fee.amount?.denom.toUpperCase()}` + : `${fee.amount?.amount} ${fee.amount?.denom.toUpperCase()}`; + } + return '-'; +}; + +export const ModalFee = ({ fee, isLoading, error, divider }: TFeeProps) => ( + <> + + {divider && } + +); + +export const ModalTotalAmount = ({ fee, amount, isLoading, error, divider }: TTotalAmountProps) => ( + <> + + {divider && } + +); diff --git a/explorer/src/components/Delegations/ModalListItem.tsx b/explorer/src/components/Delegations/components/ModalListItem.tsx similarity index 91% rename from explorer/src/components/Delegations/ModalListItem.tsx rename to explorer/src/components/Delegations/components/ModalListItem.tsx index c1fcc4bf4c..c545358cf5 100644 --- a/explorer/src/components/Delegations/ModalListItem.tsx +++ b/explorer/src/components/Delegations/components/ModalListItem.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Box, Stack, SxProps, Typography, TypographyProps } from '@mui/material'; -import { ModalDivider } from '../../../../nym-wallet/src/components/Modals/ModalDivider'; +import { ModalDivider } from '../../../../../nym-wallet/src/components/Modals/ModalDivider'; export const ModalListItem: FCWithChildren<{ label: string; diff --git a/explorer/src/components/Delegations/SimpleModal.tsx b/explorer/src/components/Delegations/components/SimpleModal.tsx similarity index 97% rename from explorer/src/components/Delegations/SimpleModal.tsx rename to explorer/src/components/Delegations/components/SimpleModal.tsx index 3db21c855f..add6329731 100644 --- a/explorer/src/components/Delegations/SimpleModal.tsx +++ b/explorer/src/components/Delegations/components/SimpleModal.tsx @@ -3,7 +3,7 @@ import { Box, Button, Modal, Stack, SxProps, Typography } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; import ErrorOutline from '@mui/icons-material/ErrorOutline'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; -import { modalStyle } from '../../../../nym-wallet/src/components/Modals/styles'; +import { modalStyle } from '../../../../../nym-wallet/src/components/Modals/styles'; import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; diff --git a/explorer/src/components/Delegations/components/styles.ts b/explorer/src/components/Delegations/components/styles.ts new file mode 100644 index 0000000000..9b26551767 --- /dev/null +++ b/explorer/src/components/Delegations/components/styles.ts @@ -0,0 +1,21 @@ +import { Theme } from '@mui/material/styles'; + +export const backDropStyles = (theme: Theme) => { + const { mode } = theme.palette; + return { + style: { + left: mode === 'light' ? '0' : '50%', + width: '50%', + }, + }; +}; + +export const modalStyles = (theme: Theme) => { + const { mode } = theme.palette; + return { left: mode === 'light' ? '25%' : '75%' }; +}; + +export const dialogStyles = (theme: Theme) => { + const { mode } = theme.palette; + return { left: mode === 'light' ? '-50%' : '50%' }; +}; diff --git a/explorer/src/components/Delegations/config.ts b/explorer/src/components/Delegations/config.ts new file mode 100644 index 0000000000..1b1f83ce1f --- /dev/null +++ b/explorer/src/components/Delegations/config.ts @@ -0,0 +1,4 @@ +export const config = { + IS_DEV_MODE: process.env.NODE_ENV === 'development', + LOG_TAURI_OPERATIONS: process.env.NODE_ENV === 'development', +}; diff --git a/explorer/src/components/Delegations/context/accounts.tsx b/explorer/src/components/Delegations/context/accounts.tsx new file mode 100644 index 0000000000..0ebf07cd09 --- /dev/null +++ b/explorer/src/components/Delegations/context/accounts.tsx @@ -0,0 +1,170 @@ +import React, { createContext, Dispatch, SetStateAction, useContext, useEffect, useMemo, useState } from 'react'; +import { AccountEntry } from '@nymproject/types'; +import { addAccount as addAccountRequest, renameAccount, showMnemonicForAccount } from '../requests'; +import { useSnackbar } from 'notistack'; +import { AppContext } from './main'; + +type TAccounts = { + accounts?: AccountEntry[]; + selectedAccount?: AccountEntry; + accountToEdit?: AccountEntry; + dialogToDisplay?: TAccountsDialog; + isLoading: boolean; + error?: string; + accountMnemonic: TAccountMnemonic; + setError: Dispatch>; + setAccountMnemonic: Dispatch>; + handleAddAccount: (data: { accountName: string; mnemonic: string; password: string }) => void; + setDialogToDisplay: (dialog?: TAccountsDialog) => void; + handleSelectAccount: (data: { accountName: string; password: string }) => Promise; + handleAccountToEdit: (accountId: string | undefined) => void; + handleEditAccount: ({ + account, + newAccountName, + password, + }: { + account: AccountEntry; + newAccountName: string; + password: string; + }) => Promise; + handleImportAccount: (account: AccountEntry) => void; + handleGetAccountMnemonic: (data: { password: string; accountName: string }) => void; +}; + +export type TAccountsDialog = 'Accounts' | 'Add' | 'Edit' | 'Import' | 'Mnemonic'; +export type TAccountMnemonic = { value?: string; accountName?: string }; + +export const AccountsContext = createContext({} as TAccounts); + +export const AccountsProvider: FCWithChildren = ({ children }) => { + const [accounts, setAccounts] = useState([]); + const [selectedAccount, setSelectedAccount] = useState(); + const [accountToEdit, setAccountToEdit] = useState(); + const [dialogToDisplay, setDialogToDisplay] = useState(); + const [accountMnemonic, setAccountMnemonic] = useState({ + value: undefined, + accountName: undefined, + }); + const [error, setError] = useState(); + const [isLoading, setIsLoading] = useState(false); + const { onAccountChange, storedAccounts } = useContext(AppContext); + const { enqueueSnackbar } = useSnackbar(); + + const handleAddAccount = async ({ + accountName, + mnemonic, + password, + }: { + accountName: string; + mnemonic: string; + password: string; + }) => { + setIsLoading(true); + try { + const newAccount = await addAccountRequest({ + accountName, + mnemonic, + password, + }); + setAccounts((accs) => [...accs, newAccount]); + enqueueSnackbar('New account created', { variant: 'success' }); + } catch (e) { + setError(`Error adding account: ${e}`); + throw new Error(); + } finally { + setIsLoading(false); + } + }; + const handleEditAccount = async ({ + account, + newAccountName, + password, + }: { + account: AccountEntry; + newAccountName: string; + password: string; + }) => { + setIsLoading(true); + try { + await renameAccount({ accountName: account.id, newAccountName, password }); + setAccounts((accs) => + accs?.map((acc) => (acc.address === account.address ? { ...acc, id: newAccountName } : acc)), + ); + if (selectedAccount?.id === account.id) { + setSelectedAccount({ ...selectedAccount, id: newAccountName }); + } + setDialogToDisplay('Accounts'); + } catch (e) { + throw new Error(`Error editing account: ${e}`); + } finally { + setIsLoading(false); + } + }; + + const handleImportAccount = (account: AccountEntry) => setAccounts((accs) => [...(accs ? [...accs] : []), account]); + + const handleAccountToEdit = (accountName: string | undefined) => + setAccountToEdit(accounts?.find((acc) => acc.id === accountName)); + + const handleSelectAccount = async ({ accountName, password }: { accountName: string; password: string }) => { + try { + await onAccountChange({ accountId: accountName, password }); + const match = accounts?.find((acc) => acc.id === accountName); + setSelectedAccount(match); + return true; + } catch (e) { + setError('Error switching account. Please check your password'); + return false; + } + }; + + const handleGetAccountMnemonic = async ({ password, accountName }: { password: string; accountName: string }) => { + try { + setIsLoading(true); + const mnemonic = await showMnemonicForAccount({ password, accountName }); + setAccountMnemonic({ value: mnemonic, accountName }); + } catch (e) { + setError(e as string); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + if (storedAccounts) { + setAccounts(storedAccounts); + } + + if (storedAccounts && !selectedAccount) { + setSelectedAccount(storedAccounts[0]); + } + }, [storedAccounts]); + + return ( + ({ + error, + setError, + accounts, + selectedAccount, + accountToEdit, + dialogToDisplay, + accountMnemonic, + setDialogToDisplay, + setAccountMnemonic, + isLoading, + handleAddAccount, + handleEditAccount, + handleAccountToEdit, + handleSelectAccount, + handleImportAccount, + handleGetAccountMnemonic, + }), + [accounts, selectedAccount, accountToEdit, dialogToDisplay, isLoading, error, accountMnemonic], + )} + > + {children} + + ); +}; diff --git a/explorer/src/components/Delegations/context/buy.tsx b/explorer/src/components/Delegations/context/buy.tsx new file mode 100644 index 0000000000..96e6893731 --- /dev/null +++ b/explorer/src/components/Delegations/context/buy.tsx @@ -0,0 +1,59 @@ +import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; +import { sign } from '../requests'; +import { Console } from '../utils/console'; +// import { AppContext } from './main'; + +export type TBuyContext = { + loading: boolean; + error?: string; + signMessage: (message: string) => Promise; + refresh: () => Promise; +}; + +export const BuyContext = createContext({ + loading: false, + signMessage: async () => '', + refresh: async () => undefined, +}); + +export const BuyContextProvider: FCWithChildren = ({ children }): JSX.Element => { + const [loading, setLoading] = useState(false); + const [error, setError] = useState(); + + const refresh = useCallback(async () => { + setError(undefined); + }, []); + + useEffect(() => { + refresh(); + }, [refresh]); + + const signMessage = async (message: string) => { + let signature; + setLoading(true); + try { + signature = await sign(message); + } catch (e: any) { + Console.log(`Sign message operation failed: ${e}`); + console.log('`Sign message operation failed: ${e}` :>> ', `Sign message operation failed: ${e}`); + setError(`Sign message operation failed: ${e}`); + } finally { + setLoading(false); + } + return signature; + }; + + const memoizedValue = useMemo( + () => ({ + loading, + error, + refresh, + signMessage, + }), + [loading, error], + ); + + return {children}; +}; + +export const useBuyContext = () => useContext(BuyContext); diff --git a/explorer/src/components/Delegations/context/index.tsx b/explorer/src/components/Delegations/context/index.tsx new file mode 100644 index 0000000000..9983022728 --- /dev/null +++ b/explorer/src/components/Delegations/context/index.tsx @@ -0,0 +1,3 @@ +export * from './main'; +export * from './accounts'; +export * from './buy'; diff --git a/explorer/src/components/Delegations/context/main.tsx b/explorer/src/components/Delegations/context/main.tsx new file mode 100644 index 0000000000..8653234cbb --- /dev/null +++ b/explorer/src/components/Delegations/context/main.tsx @@ -0,0 +1,366 @@ +import React, { createContext, useEffect, useMemo, useState } from 'react'; +import { forage } from '@tauri-apps/tauri-forage'; +import { useNavigate } from 'react-router-dom'; +import { useSnackbar } from 'notistack'; +import { Account, AccountEntry, MixNodeDetails } from '@nymproject/types'; +import { getVersion } from '@tauri-apps/api/app'; +import { AppEnv, Network } from '../types'; +import { TUseuserBalance, useGetBalance } from '../hooks/useGetBalance'; +import { + getEnv, + getMixnodeBondDetails, + listAccounts, + selectNetwork, + signInWithMnemonic, + signInWithPassword, + signOut, + switchAccount, +} from '../requests'; +import Big from 'big.js'; + +import { Console } from '../utils/console'; +import { createSignInWindow, getReactState, setReactState } from '../requests/app'; +// import { toDisplay } from '../utils'; + +const toDisplay = (val: string | number | Big, dp = 4) => { + let displayValue; + try { + displayValue = Big(val).toFixed(dp); + } catch (e: any) { + Console.warn(`${displayValue} not a valid decimal number: ${e}`); + } + return displayValue; +}; + +export const urls = (networkName?: Network) => + networkName === 'MAINNET' + ? { + mixnetExplorer: 'https://mixnet.explorers.guru/', + blockExplorer: 'https://blocks.nymtech.net', + networkExplorer: 'https://explorer.nymtech.net', + } + : { + blockExplorer: `https://${networkName}-blocks.nymtech.net`, + networkExplorer: `https://${networkName}-explorer.nymtech.net`, + }; + +type TLoginType = 'mnemonic' | 'password'; + +export type TAppContext = { + mode: 'light' | 'dark'; + appEnv?: AppEnv; + appVersion?: string; + clientDetails?: Account; + storedAccounts?: AccountEntry[]; + mixnodeDetails?: MixNodeDetails | null; + userBalance: TUseuserBalance; + showAdmin: boolean; + showTerminal: boolean; + network?: Network; + isLoading: boolean; + isAdminAddress: boolean; + error?: string; + loginType?: TLoginType; + showSendModal: boolean; + showReceiveModal: boolean; + onAccountChange: ({ accountId, password }: { accountId: string; password: string }) => void; + handleSwitchMode: () => void; + handleShowSendModal: () => void; + handleShowReceiveModal: () => void; + setIsLoading: (isLoading: boolean) => void; + setError: (value?: string) => void; + switchNetwork: (network: Network) => void; + getBondDetails: () => Promise; + handleShowAdmin: () => void; + logIn: (opts: { type: TLoginType; value: string }) => void; + handleShowTerminal: () => void; + signInWithPassword: (password: string) => void; + logOut: () => void; + keepState: () => Promise; + printBalance: string; + printVestedBalance?: string; // spendable vested token +}; + +interface RustState { + network?: Network; + loginType?: 'mnemonic' | 'password'; +} + +export const AppContext = createContext({} as TAppContext); + +export const AppProvider: FCWithChildren = ({ children }) => { + const [clientDetails, setClientDetails] = useState(); + const [storedAccounts, setStoredAccounts] = useState(); + const [mixnodeDetails, setMixnodeDetails] = useState(null); + const [network, setNetwork] = useState(); + const [appEnv, setAppEnv] = useState(); + const [showAdmin, setShowAdmin] = useState(false); + const [showTerminal, setShowTerminal] = useState(false); + const [mode, setMode] = useState<'light' | 'dark'>('light'); + const [loginType, setLoginType] = useState<'mnemonic' | 'password'>(); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(); + const [appVersion, setAppVersion] = useState(); + const [isAdminAddress, setIsAdminAddress] = useState(false); + const [showSendModal, setShowSendModal] = useState(false); + const [showReceiveModal, setShowReceiveModal] = useState(false); + const [printBalance, setPrintBalance] = useState('-'); + const [printVestedBalance, setPrintVestedBalance] = useState(); + + const userBalance = useGetBalance(clientDetails); + const navigate = useNavigate(); + const { enqueueSnackbar } = useSnackbar(); + + const initFromRustState = async () => { + const stateJson = await getReactState(); + if (stateJson) { + const state: RustState = JSON.parse(stateJson); + setNetwork(state.network); + setLoginType(state.loginType); + } + }; + + useEffect(() => { + initFromRustState(); + }, []); + + const keepState = async () => { + // add any state from this context to store in the Rust process + const state: RustState = { + network, + loginType, + }; + setReactState(JSON.stringify(state)); + }; + + const clearState = () => { + userBalance.clearAll(); + setStoredAccounts(undefined); + setNetwork(undefined); + setError(undefined); + setIsLoading(false); + setMixnodeDetails(null); + }; + + const loadAccount = async (n: Network) => { + try { + const client = await selectNetwork(n); + setClientDetails(client); + } catch (e) { + enqueueSnackbar('Error loading account', { variant: 'error' }); + Console.error(e as string); + } + }; + + const loadStoredAccounts = async () => { + const accounts = await listAccounts(); + setStoredAccounts(accounts); + }; + + const getBondDetails = async () => { + setMixnodeDetails(null); + try { + const mixnode = await getMixnodeBondDetails(); + setMixnodeDetails(mixnode); + } catch (e) { + Console.error(e as string); + } + }; + + const refreshAccount = async (_network: Network) => { + await loadAccount(_network); + if (loginType === 'password') { + await loadStoredAccounts(); + } + }; + + const getModeFromStorage = async () => { + try { + const modeFromStorage = await forage.getItem({ key: 'nym-wallet-mode' })(); + if (modeFromStorage) setMode(modeFromStorage); + } catch (e) { + Console.error(e); + } + }; + + const setModeInStorage = async (newMode: 'light' | 'dark') => { + await forage.setItem({ + key: 'nym-wallet-mode', + value: newMode, + })(); + }; + + useEffect(() => { + getVersion().then(setAppVersion); + getModeFromStorage(); + }, []); + + useEffect(() => { + if (!clientDetails) { + clearState(); + navigate('/'); + } + }, [clientDetails]); + + useEffect(() => { + if (network) { + refreshAccount(network); + getEnv().then(setAppEnv); + } + }, [network]); + + useEffect(() => { + const currency = clientDetails?.display_mix_denom.toUpperCase() || 'NYM'; + if (userBalance.originalVesting) { + setPrintVestedBalance(`${toDisplay(userBalance.tokenAllocation?.spendableVestedCoins || 0)} ${currency}`); + } + if (userBalance?.balance?.amount) { + setPrintBalance(`${toDisplay(userBalance.balance.amount.amount)} ${currency}`); + } else { + setPrintBalance(`${toDisplay(0)} ${currency}`); + } + }, [userBalance, clientDetails]); + + useEffect(() => { + let newValue = false; + if (network && appEnv?.ADMIN_ADDRESS && clientDetails?.client_address) { + try { + const adminAddressMap = JSON.parse(appEnv.ADMIN_ADDRESS); + const adminAddresses = adminAddressMap[network] || []; + if (adminAddresses.length) { + newValue = adminAddresses.includes(clientDetails?.client_address); + if (newValue) { + Console.log('Wallet is in admin mode: ', { + network, + adminAddress: adminAddressMap[network], + clientAddress: clientDetails?.client_address, + }); + } + } + } catch (e) { + Console.error('Failed to check admin addresses', e); + } + } + setIsAdminAddress(newValue); + }, [appEnv, network, clientDetails?.client_address]); + + const logIn = async ({ type, value }: { type: TLoginType; value: string }) => { + if (value.length === 0) { + setError(`A ${type} must be provided`); + return; + } + try { + setIsLoading(true); + if (type === 'mnemonic') { + await signInWithMnemonic(value); + setLoginType('mnemonic'); + } else { + await signInWithPassword(value); + setLoginType('password'); + } + setNetwork('MAINNET'); + navigate('/balance'); + } catch (e) { + setError(e as string); + } finally { + setIsLoading(false); + } + }; + + const logOut = async () => { + setIsLoading(true); + try { + await signOut(); + await setReactState(undefined); + setClientDetails(undefined); + enqueueSnackbar('Successfully logged out', { variant: 'success' }); + await createSignInWindow(); + } finally { + setIsLoading(false); + } + }; + + const onAccountChange = async ({ accountId, password }: { accountId: string; password: string }) => { + if (network) { + setIsLoading(true); + try { + await switchAccount({ accountId, password }); + await loadAccount(network); + enqueueSnackbar('Account switch success', { variant: 'success', preventDuplicate: true }); + } catch (e) { + throw new Error(`Error swtiching account: ${e}`); + } finally { + setIsLoading(false); + } + } + }; + + const handleShowAdmin = () => setShowAdmin((show) => !show); + const handleShowTerminal = () => setShowTerminal((show) => !show); + const switchNetwork = (_network: Network) => setNetwork(_network); + const handleShowSendModal = () => setShowSendModal((show) => !show); + const handleShowReceiveModal = () => setShowReceiveModal((show) => !show); + const handleSwitchMode = () => + setMode((currentMode) => { + const newMode = currentMode === 'light' ? 'dark' : 'light'; + setModeInStorage(newMode); + return newMode; + }); + + const memoizedValue = useMemo( + () => ({ + mode, + appEnv, + appVersion, + isAdminAddress, + isLoading, + error, + clientDetails, + storedAccounts, + mixnodeDetails, + userBalance, + showAdmin, + showTerminal, + network, + loginType, + setIsLoading, + setError, + signInWithPassword, + switchNetwork, + getBondDetails, + handleShowAdmin, + handleShowTerminal, + logIn, + logOut, + keepState, + onAccountChange, + showSendModal, + showReceiveModal, + handleShowSendModal, + handleShowReceiveModal, + handleSwitchMode, + printBalance, + printVestedBalance, + }), + [ + appVersion, + loginType, + isAdminAddress, + mode, + appEnv, + isLoading, + error, + clientDetails, + mixnodeDetails, + userBalance, + showAdmin, + network, + storedAccounts, + showTerminal, + showSendModal, + showReceiveModal, + ], + ); + + return {children}; +}; diff --git a/explorer/src/components/Delegations/hooks/useCheckOwnership.ts b/explorer/src/components/Delegations/hooks/useCheckOwnership.ts new file mode 100644 index 0000000000..ef171c43e1 --- /dev/null +++ b/explorer/src/components/Delegations/hooks/useCheckOwnership.ts @@ -0,0 +1,59 @@ +import { useCallback, useContext, useEffect, useState } from 'react'; +import { Console } from '../utils/console'; +// eslint-disable-next-line import/no-cycle +import { AppContext } from '../context/main'; +import { checkGatewayOwnership, checkMixnodeOwnership, getVestingPledgeInfo } from '../requests'; +import { EnumNodeType, TNodeOwnership } from '../types'; + +const initial: TNodeOwnership = { + hasOwnership: false, + nodeType: undefined, + vestingPledge: undefined, +}; + +export const useCheckOwnership = () => { + const { clientDetails } = useContext(AppContext); + + const [ownership, setOwnership] = useState(initial); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(); + + const checkOwnership = useCallback(async () => { + const status = { ...initial }; + try { + const [ownsMixnode, ownsGateway] = await Promise.all([checkMixnodeOwnership(), checkGatewayOwnership()]); + + if (ownsMixnode) { + status.hasOwnership = true; + status.nodeType = EnumNodeType.mixnode; + status.vestingPledge = await getVestingPledgeInfo({ + address: clientDetails?.client_address!, + type: EnumNodeType.mixnode, + }); + } + + if (ownsGateway) { + status.hasOwnership = true; + status.nodeType = EnumNodeType.gateway; + status.vestingPledge = await getVestingPledgeInfo({ + address: clientDetails?.client_address!, + type: EnumNodeType.gateway, + }); + } + + setOwnership(status); + } catch (e) { + Console.error(e as string); + setError(e as string); + setOwnership(initial); + } finally { + setIsLoading(false); + } + }, [clientDetails]); + + useEffect(() => { + checkOwnership(); + }, [clientDetails]); + + return { isLoading, error, ownership, checkOwnership }; +}; diff --git a/explorer/src/components/Delegations/hooks/useGetBalance.ts b/explorer/src/components/Delegations/hooks/useGetBalance.ts new file mode 100644 index 0000000000..b23eaf1a34 --- /dev/null +++ b/explorer/src/components/Delegations/hooks/useGetBalance.ts @@ -0,0 +1,147 @@ +/* eslint-disable import/no-cycle */ +import { useCallback, useEffect, useState } from 'react'; +import { Account, Balance, DecCoin, OriginalVestingResponse, Period, VestingAccountInfo } from '@nymproject/types'; +import { + getVestingCoins, + getVestedCoins, + getLockedCoins, + getSpendableCoins, + getOriginalVesting, + getCurrentVestingPeriod, + getVestingAccountInfo, + getSpendableRewardCoins, + getSpendableVestedCoins, + userBalance, +} from '../requests'; +import { Console } from '../utils/console'; + +type TTokenAllocation = { + [key in + | 'vesting' + | 'vested' + | 'locked' + | 'spendable' + | 'spendableRewardCoins' + | 'spendableVestedCoins']: DecCoin['amount']; +}; + +export type TUseuserBalance = { + error?: string; + balance?: Balance; + tokenAllocation?: TTokenAllocation; + originalVesting?: OriginalVestingResponse; + currentVestingPeriod?: Period; + vestingAccountInfo?: VestingAccountInfo; + isLoading: boolean; + fetchBalance: () => Promise; + fetchTokenAllocation: () => Promise; + clearBalance: () => void; + clearAll: () => void; + refreshBalances: () => Promise; +}; + +export const useGetBalance = (clientDetails?: Account): TUseuserBalance => { + const [balance, setBalance] = useState(); + const [error, setError] = useState(); + const [tokenAllocation, setTokenAllocation] = useState(); + const [originalVesting, setOriginalVesting] = useState(); + const [currentVestingPeriod, setCurrentVestingPeriod] = useState(); + const [vestingAccountInfo, setVestingAccountInfo] = useState(); + const [isLoading, setIsLoading] = useState(false); + + const clearBalance = () => setBalance(undefined); + const clearTokenAllocation = () => setTokenAllocation(undefined); + const clearOriginalVesting = () => setOriginalVesting(undefined); + + const fetchTokenAllocation = async () => { + setIsLoading(true); + if (clientDetails?.client_address) { + try { + const [ + originalVestingValue, + vestingCoins, + vestedCoins, + lockedCoins, + spendableCoins, + spendableVestedCoins, + spendableRewardCoins, + currentPeriod, + vestingAccountDetail, + ] = await Promise.all([ + getOriginalVesting(clientDetails?.client_address), + getVestingCoins(clientDetails?.client_address), + getVestedCoins(clientDetails?.client_address), + getLockedCoins(), + getSpendableCoins(), + getSpendableVestedCoins(), + getSpendableRewardCoins(), + getCurrentVestingPeriod(clientDetails?.client_address), + getVestingAccountInfo(clientDetails?.client_address), + ]); + setOriginalVesting(originalVestingValue); + setCurrentVestingPeriod(currentPeriod); + setTokenAllocation({ + vesting: vestingCoins.amount, + vested: vestedCoins.amount, + locked: lockedCoins.amount, + spendable: spendableCoins.amount, + spendableVestedCoins: spendableVestedCoins.amount, + spendableRewardCoins: spendableRewardCoins.amount, + }); + setVestingAccountInfo(vestingAccountDetail); + } catch (e) { + clearTokenAllocation(); + clearOriginalVesting(); + Console.error(e as string); + } + } + setIsLoading(false); + }; + + const fetchBalance = useCallback(async () => { + setIsLoading(true); + setError(undefined); + try { + const bal = await userBalance(); + setBalance(bal); + } catch (err) { + setError(err as string); + } finally { + setIsLoading(false); + } + }, []); + + const clearAll = () => { + clearBalance(); + clearTokenAllocation(); + clearOriginalVesting(); + }; + + const refreshBalances = async () => { + if (clientDetails?.client_address) { + await fetchBalance(); + await fetchTokenAllocation(); + } else { + clearAll(); + } + }; + + useEffect(() => { + refreshBalances(); + }, [clientDetails]); + + return { + error, + isLoading, + balance, + tokenAllocation, + originalVesting, + currentVestingPeriod, + vestingAccountInfo, + fetchBalance, + clearBalance, + clearAll, + fetchTokenAllocation, + refreshBalances, + }; +}; diff --git a/explorer/src/components/Delegations/hooks/useGetFee.ts b/explorer/src/components/Delegations/hooks/useGetFee.ts new file mode 100644 index 0000000000..081493f4ca --- /dev/null +++ b/explorer/src/components/Delegations/hooks/useGetFee.ts @@ -0,0 +1,49 @@ +import { DecCoin, FeeDetails } from '@nymproject/types'; +import { useState } from 'react'; +import { Console } from '../utils/console'; +import { getCustomFees } from '../requests'; + +export function useGetFee() { + const [fee, setFee] = useState(); + const [isFeeLoading, setIsFeeLoading] = useState(false); + const [feeError, setFeeError] = useState(); + + async function getFee(operation: (args: T) => Promise, args: T) { + try { + setIsFeeLoading(true); + const simulatedFee = await operation(args); + setFee(simulatedFee); + } catch (e) { + // Console.error(e); + setFeeError(e as string); + } + setIsFeeLoading(false); + } + + async function setFeeManually(amount: DecCoin) { + try { + setIsFeeLoading(true); + const fees = await getCustomFees({ feesAmount: amount }); + setFee(fees); + } catch (e) { + Console.error(e); + setFeeError(e as string); + } + setIsFeeLoading(false); + } + + const resetFeeState = () => { + setFee(undefined); + setIsFeeLoading(false); + setFeeError(undefined); + }; + + return { + fee, + isFeeLoading, + feeError, + getFee, + setFeeManually, + resetFeeState, + }; +} diff --git a/explorer/src/components/Delegations/hooks/useKeyPress.ts b/explorer/src/components/Delegations/hooks/useKeyPress.ts new file mode 100644 index 0000000000..73eb81598e --- /dev/null +++ b/explorer/src/components/Delegations/hooks/useKeyPress.ts @@ -0,0 +1,29 @@ +import { useState, useEffect } from 'react'; + +export function useKeyPress(targetKey: string): boolean { + // State for keeping track of whether key is pressed + const [keyPressed, setKeyPressed] = useState(false); + // If pressed key is our target key then set to true + function downHandler({ key }: { key: string }): void { + if (key === targetKey) { + setKeyPressed(true); + } + } + // If released key is our target key then set to false + const upHandler = ({ key }: { key: string }): void => { + if (key === targetKey) { + setKeyPressed(false); + } + }; + // Add event listeners + useEffect(() => { + window.addEventListener('keydown', downHandler); + window.addEventListener('keyup', upHandler); + // Remove event listeners on cleanup + return () => { + window.removeEventListener('keydown', downHandler); + window.removeEventListener('keyup', upHandler); + }; + }, []); // Empty array ensures that effect is only run on mount and unmount + return keyPressed; +} diff --git a/explorer/src/components/Delegations/requests/account.ts b/explorer/src/components/Delegations/requests/account.ts new file mode 100644 index 0000000000..daf150afd1 --- /dev/null +++ b/explorer/src/components/Delegations/requests/account.ts @@ -0,0 +1,67 @@ +import { Account, Balance, AccountEntry } from '@nymproject/types'; +import { invokeWrapper } from './wrapper'; + +export const signInWithMnemonic = async (mnemonic: string): Promise => + invokeWrapper('connect_with_mnemonic', { mnemonic }); + +export const userBalance = async () => invokeWrapper('get_balance'); + +export const createMnemonic = async () => invokeWrapper('create_new_mnemonic'); + +export const validateMnemonic = async (mnemonic: string) => invokeWrapper('validate_mnemonic', { mnemonic }); + +export const signOut = async () => invokeWrapper('logout'); + +export const isPasswordCreated = async () => invokeWrapper('does_password_file_exist'); + +export const createPassword = async ({ mnemonic, password }: { mnemonic: string; password: string }) => + invokeWrapper('create_password', { mnemonic, password }); + +export const updatePassword = async ({ + currentPassword, + newPassword, +}: { + currentPassword: string; + newPassword: string; +}) => invokeWrapper('update_password', { currentPassword, newPassword }); + +export const signInWithPassword = async (password: string) => + invokeWrapper('sign_in_with_password', { password }); + +export const switchAccount = async ({ accountId, password }: { accountId: string; password: string }) => + invokeWrapper('sign_in_with_password_and_account_id', { accountId, password }); + +export const addAccount = async ({ + mnemonic, + password, + accountName, +}: { + mnemonic: string; + password: string; + accountName: string; +}) => invokeWrapper('add_account_for_password', { mnemonic, password, accountId: accountName }); + +export const removeAccount = async ({ password, accountName }: { password: string; accountName: string }) => + invokeWrapper('remove_account_for_password', { password, innerId: accountName }); + +export const listAccounts = async () => invokeWrapper('list_accounts'); + +export const archiveWalletFile = async () => invokeWrapper('archive_wallet_file'); + +export const showMnemonicForAccount = async ({ password, accountName }: { password: string; accountName: string }) => + invokeWrapper('show_mnemonic_for_account_in_password', { password, accountId: accountName }); + +export const renameAccount = async ({ + password, + accountName, + newAccountName, +}: { + password: string; + accountName: string; + newAccountName: string; +}) => + invokeWrapper('rename_account_for_password', { + password, + accountId: accountName, + newAccountId: newAccountName, + }); diff --git a/explorer/src/components/Delegations/requests/actions.ts b/explorer/src/components/Delegations/requests/actions.ts new file mode 100644 index 0000000000..cf09085d5f --- /dev/null +++ b/explorer/src/components/Delegations/requests/actions.ts @@ -0,0 +1,54 @@ +import { + Fee, + DecCoin, + SendTxResult, + TransactionExecuteResult, + MixNodeConfigUpdate, + MixNodeCostParams, + GatewayConfigUpdate, +} from '@nymproject/types'; +import { + EnumNodeType, + TBondGatewayArgs, + TBondGatewaySignatureArgs, + TBondMixNodeArgs, + TBondMixnodeSignatureArgs, + TUpdateBondArgs, +} from '../types'; +import { invokeWrapper } from './wrapper'; + +export const bondGateway = async (args: TBondGatewayArgs) => + invokeWrapper('bond_gateway', args); + +export const generateGatewayMsgPayload = async (args: Omit) => + invokeWrapper('generate_gateway_bonding_msg_payload', args); + +export const unbondGateway = async (fee?: Fee) => invokeWrapper('unbond_gateway', { fee }); + +export const bondMixNode = async (args: TBondMixNodeArgs) => + invokeWrapper('bond_mixnode', args); + +export const generateMixnodeMsgPayload = async (args: Omit) => + invokeWrapper('generate_mixnode_bonding_msg_payload', args); + +export const unbondMixNode = async (fee?: Fee) => invokeWrapper('unbond_mixnode', { fee }); + +export const updateMixnodeCostParams = async (newCosts: MixNodeCostParams, fee?: Fee) => + invokeWrapper('update_mixnode_cost_params', { newCosts, fee }); + +export const updateMixnodeConfig = async (update: MixNodeConfigUpdate, fee?: Fee) => + invokeWrapper('update_mixnode_config', { update, fee }); + +export const updateGatewayConfig = async (update: GatewayConfigUpdate, fee?: Fee) => + invokeWrapper('update_gateway_config', { update, fee }); + +export const send = async (args: { amount: DecCoin; address: string; memo: string; fee?: Fee }) => + invokeWrapper('send', args); + +export const unbond = async (type: EnumNodeType) => { + if (type === EnumNodeType.mixnode) return unbondMixNode(); + return unbondGateway(); +}; + +export const updateBond = async (args: TUpdateBondArgs) => + invokeWrapper('update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/app.ts b/explorer/src/components/Delegations/requests/app.ts new file mode 100644 index 0000000000..acecfa8f25 --- /dev/null +++ b/explorer/src/components/Delegations/requests/app.ts @@ -0,0 +1,14 @@ +import { invokeWrapper } from './wrapper'; +import { AppVersion } from '../types/rust/AppVersion'; + +export const checkVersion = async () => invokeWrapper('check_version'); + +export const createMainWindow = async (): Promise => invokeWrapper('create_main_window'); + +export const createSignInWindow = async (): Promise => invokeWrapper('create_auth_window'); + +export const setReactState = async (newState?: string): Promise => + invokeWrapper('set_react_state', { newState }); + +export const getReactState = async (): Promise => + invokeWrapper('get_react_state'); diff --git a/explorer/src/components/Delegations/requests/contract.ts b/explorer/src/components/Delegations/requests/contract.ts new file mode 100644 index 0000000000..eb5a863bcc --- /dev/null +++ b/explorer/src/components/Delegations/requests/contract.ts @@ -0,0 +1,7 @@ +import { TauriContractStateParams } from '../types'; +import { invokeWrapper } from './wrapper'; + +export const getContractParams = async () => invokeWrapper('get_contract_settings'); + +export const setContractParams = async (params: TauriContractStateParams) => + invokeWrapper('update_contract_settings', { params }); diff --git a/explorer/src/components/Delegations/requests/delegation.ts b/explorer/src/components/Delegations/requests/delegation.ts new file mode 100644 index 0000000000..d68d8a9084 --- /dev/null +++ b/explorer/src/components/Delegations/requests/delegation.ts @@ -0,0 +1,33 @@ +import { + DelegationWithEverything, + DelegationsSummaryResponse, + TransactionExecuteResult, + DecCoin, + FeeDetails, + Fee, +} from '@nymproject/types'; +import { invokeWrapper } from './wrapper'; + +export const getMixNodeDelegationsForCurrentAccount = async () => + invokeWrapper('get_all_mix_delegations'); + +export const getDelegationSummary = async () => invokeWrapper('get_delegation_summary'); + +export const undelegateFromMixnode = async (mixId: number, fee?: Fee) => + invokeWrapper('undelegate_from_mixnode', { mixId, fee }); + +export const undelegateAllFromMixnode = async ( + mixId: number, + usesVestingContractTokens: boolean, + fee_liquid?: FeeDetails, + fee_vesting?: FeeDetails, +) => + invokeWrapper('undelegate_all_from_mixnode', { + mixId, + usesVestingContractTokens, + fee_liquid, + fee_vesting, + }); + +export const delegateToMixnode = async (mixId: number, amount: DecCoin, fee?: Fee) => + invokeWrapper('delegate_to_mixnode', { mixId, amount, fee }); diff --git a/explorer/src/components/Delegations/requests/index.ts b/explorer/src/components/Delegations/requests/index.ts new file mode 100644 index 0000000000..e6fb5e482c --- /dev/null +++ b/explorer/src/components/Delegations/requests/index.ts @@ -0,0 +1,14 @@ +export * from './app'; +export * from './account'; +export * from './actions'; +export * from './contract'; +export * from './delegation'; +export * from './logging'; +export * from './network'; +export * from './queries'; +export * from './rewards'; +export * from './signature'; +export * from './simulate'; +export * from './utils'; +export * from './vesting'; +export * from './pendingEvents'; diff --git a/explorer/src/components/Delegations/requests/logging.ts b/explorer/src/components/Delegations/requests/logging.ts new file mode 100644 index 0000000000..307f65d672 --- /dev/null +++ b/explorer/src/components/Delegations/requests/logging.ts @@ -0,0 +1,3 @@ +import { invokeWrapper } from './wrapper'; + +export const helpLogToggleWindow = async () => invokeWrapper('help_log_toggle_window', {}); diff --git a/explorer/src/components/Delegations/requests/network.ts b/explorer/src/components/Delegations/requests/network.ts new file mode 100644 index 0000000000..248207e616 --- /dev/null +++ b/explorer/src/components/Delegations/requests/network.ts @@ -0,0 +1,16 @@ +import { Account } from '@nymproject/types'; +import { Network } from '../types'; +import { invokeWrapper } from './wrapper'; + +export const selectNetwork = async (network: Network) => invokeWrapper('switch_network', { network }); + +export const getSelectedValidatorUrl = async (network: Network) => + invokeWrapper('get_selected_nyxd_url', { network }); + +export const getDefaultValidatorUrl = async (network: Network) => + invokeWrapper('get_default_nyxd_url', { network }); + +export const setSelectedValidatorUrl = async (args: { network: Network; url: string }) => + invokeWrapper('select_nyxd_url', args); + +export const resetValidatorUrl = async (network: Network) => invokeWrapper('reset_nyxd_url', { network }); diff --git a/explorer/src/components/Delegations/requests/pendingEvents.ts b/explorer/src/components/Delegations/requests/pendingEvents.ts new file mode 100644 index 0000000000..c92954a237 --- /dev/null +++ b/explorer/src/components/Delegations/requests/pendingEvents.ts @@ -0,0 +1,4 @@ +import { PendingEpochEvent } from '@nymproject/types'; +import { invokeWrapper } from './wrapper'; + +export const getPendingEpochEvents = async () => invokeWrapper('get_pending_epoch_events'); diff --git a/explorer/src/components/Delegations/requests/queries.ts b/explorer/src/components/Delegations/requests/queries.ts new file mode 100644 index 0000000000..63004176ac --- /dev/null +++ b/explorer/src/components/Delegations/requests/queries.ts @@ -0,0 +1,63 @@ +import { + DecCoin, + GatewayBond, + InclusionProbabilityResponse, + MixNodeDetails, + MixnodeStatusResponse, + PendingIntervalEvent, + RewardEstimationResponse, + StakeSaturationResponse, + WrappedDelegationEvent, +} from '@nymproject/types'; +import { Interval, TGatewayReport, TNodeDescription } from '../types'; +import { invokeWrapper } from './wrapper'; + +export const getAllPendingDelegations = async () => + invokeWrapper('get_pending_delegation_events'); + +export const getMixnodeBondDetails = async () => invokeWrapper('mixnode_bond_details'); +export const getGatewayBondDetails = async () => invokeWrapper('gateway_bond_details'); +export const getMixnodeAvgUptime = async () => invokeWrapper('get_mixnode_avg_uptime'); + +export const getPendingOperatorRewards = async (address: string) => + invokeWrapper('get_pending_operator_rewards', { address }); + +export const getMixnodeStakeSaturation = async (mixId: number) => + invokeWrapper('mixnode_stake_saturation', { mixId }); + +export const getMixnodeRewardEstimation = async (mixId: number) => + invokeWrapper('mixnode_reward_estimation', { mixId }); + +export const getMixnodeStatus = async (mixId: number) => + invokeWrapper('mixnode_status', { mixId }); + +export const checkMixnodeOwnership = async () => invokeWrapper('owns_mixnode'); + +export const checkGatewayOwnership = async () => invokeWrapper('owns_gateway'); + +export const getInclusionProbability = async (mixId: number) => + invokeWrapper('mixnode_inclusion_probability', { mixId }); + +export const getCurrentInterval = async () => invokeWrapper('get_current_interval'); + +export const getNumberOfMixnodeDelegators = async (mixId: number) => + invokeWrapper('get_number_of_mixnode_delegators', { mixId }); + +export const getNodeDescription = async (host: string, port: number) => + invokeWrapper('get_mix_node_description', { host, port }); + +export const getPendingIntervalEvents = async () => + invokeWrapper('get_pending_interval_events'); + +export const getGatewayReport = async (identity: string) => + invokeWrapper('gateway_report', { identity }); + +export const computeMixnodeRewardEstimation = async (args: { + mixId: number; + performance: string; + pledgeAmount: number; + totalDelegation: number; + profitMarginPercent: string; + intervalOperatingCost: { denom: 'unym'; amount: string }; +}) => invokeWrapper('compute_mixnode_reward_estimation', args); +export const getMixnodeUptime = async (mixId: number) => invokeWrapper('get_mixnode_uptime', { mixId }); diff --git a/explorer/src/components/Delegations/requests/rewards.ts b/explorer/src/components/Delegations/requests/rewards.ts new file mode 100644 index 0000000000..36b90838e7 --- /dev/null +++ b/explorer/src/components/Delegations/requests/rewards.ts @@ -0,0 +1,14 @@ +import { Fee, FeeDetails, RewardingParams, TransactionExecuteResult } from '@nymproject/types'; +import { invokeWrapper } from './wrapper'; + +export const claimOperatorReward = async (fee?: Fee) => + invokeWrapper('claim_operator_reward', { fee }); + +export const claimDelegatorRewards = async (mixId: number, fee?: FeeDetails) => + invokeWrapper('claim_locked_and_unlocked_delegator_reward', { + mixId, + fee: fee?.fee, + }); + +export const getCurrentRewardingParameter = async () => + invokeWrapper('get_current_rewarding_parameters', {}); diff --git a/explorer/src/components/Delegations/requests/signature.ts b/explorer/src/components/Delegations/requests/signature.ts new file mode 100644 index 0000000000..cf36289088 --- /dev/null +++ b/explorer/src/components/Delegations/requests/signature.ts @@ -0,0 +1,9 @@ +import { invokeWrapper } from './wrapper'; + +export const sign = async (message: string): Promise => invokeWrapper('sign', { message }); + +export const verify = async ( + signatureAsHex: string, + message: string, + publicKeyAsJsonOrAccountAddress?: string | null, +): Promise => invokeWrapper('verify', { publicKeyAsJsonOrAccountAddress, signatureAsHex, message }); diff --git a/explorer/src/components/Delegations/requests/simulate.ts b/explorer/src/components/Delegations/requests/simulate.ts new file mode 100644 index 0000000000..d5dfdb3a43 --- /dev/null +++ b/explorer/src/components/Delegations/requests/simulate.ts @@ -0,0 +1,87 @@ +import { + FeeDetails, + DecCoin, + Gateway, + MixNodeCostParams, + MixNodeConfigUpdate, + GatewayConfigUpdate, +} from '@nymproject/types'; +import { TBondGatewayArgs, TBondMixNodeArgs, TSimulateUpdateBondArgs } from '../types'; +import { invokeWrapper } from './wrapper'; + +export const simulateBondGateway = async (args: TBondGatewayArgs) => + invokeWrapper('simulate_bond_gateway', args); + +export const simulateUnbondGateway = async (args: any) => invokeWrapper('simulate_unbond_gateway', args); + +export const simulateBondMixnode = async (args: TBondMixNodeArgs) => + invokeWrapper('simulate_bond_mixnode', args); + +export const simulateUnbondMixnode = async (args: any) => invokeWrapper('simulate_unbond_mixnode', args); + +export const simulateUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams) => + invokeWrapper('simulate_update_mixnode_cost_params', { newCosts }); + +export const simulateUpdateMixnodeConfig = async (update: MixNodeConfigUpdate) => + invokeWrapper('simulate_update_mixnode_config', { update }); + +export const simulateUpdateGatewayConfig = async (update: GatewayConfigUpdate) => + invokeWrapper('simulate_update_gateway_config', { update }); + +export const simulateDelegateToMixnode = async (args: { mixId: number; amount: DecCoin }) => + invokeWrapper('simulate_delegate_to_mixnode', args); + +export const simulateUndelegateFromMixnode = async (mixId: number) => + invokeWrapper('simulate_undelegate_from_mixnode', { mixId }); + +export const simulateClaimDelegatorReward = async (mixId: number) => + invokeWrapper('simulate_claim_delegator_reward', { mixId }); + +export const simulateVestingClaimDelegatorReward = async (mixId: number) => + invokeWrapper('simulate_vesting_claim_delegator_reward', { mixId }); + +export const simulateVestingUndelegateFromMixnode = async (args: any) => + invokeWrapper('simulate_vesting_undelegate_from_mixnode', args); + +export const simulateVestingBondGateway = async (args: { gateway: Gateway; pledge: DecCoin; msgSignature: string }) => + invokeWrapper('simulate_vesting_bond_gateway', args); + +export const simulateVestingUnbondGateway = async (args: any) => + invokeWrapper('simulate_vesting_unbond_gateway', args); + +export const simulateVestingDelegateToMixnode = async (args: { mixId: number }) => + invokeWrapper('simulate_vesting_delegate_to_mixnode', args); + +export const simulateVestingBondMixnode = async (args: TBondMixNodeArgs) => + invokeWrapper('simulate_vesting_bond_mixnode', args); + +export const simulateVestingUnbondMixnode = async () => invokeWrapper('simulate_vesting_unbond_mixnode'); + +export const simulateVestingUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams) => + invokeWrapper('simulate_vesting_update_mixnode_cost_params', { newCosts }); + +export const simulateVestingUpdateMixnodeConfig = async (update: MixNodeConfigUpdate) => + invokeWrapper('simulate_vesting_update_mixnode_config', { update }); + +export const simulateVestingUpdateGatewayConfig = async (update: GatewayConfigUpdate) => + invokeWrapper('simulate_vesting_update_gateway_config', { update }); + +export const simulateWithdrawVestedCoins = async (args: any) => + invokeWrapper('simulate_withdraw_vested_coins', args); + +export const simulateSend = async ({ address, amount }: { address: string; amount: DecCoin }) => + invokeWrapper('simulate_send', { address, amount }); + +export const getCustomFees = async ({ feesAmount }: { feesAmount: DecCoin }) => + invokeWrapper('get_custom_fees', { feesAmount }); + +export const simulateClaimOperatorReward = async () => invokeWrapper('simulate_claim_operator_reward'); + +export const simulateVestingClaimOperatorReward = async () => + invokeWrapper('simulate_vesting_claim_operator_reward'); + +export const simulateUpdateBond = async (args: TSimulateUpdateBondArgs) => + invokeWrapper('simulate_update_pledge', args); + +export const simulateVestingUpdateBond = async (args: TSimulateUpdateBondArgs) => + invokeWrapper('simulate_vesting_update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/utils.ts b/explorer/src/components/Delegations/requests/utils.ts new file mode 100644 index 0000000000..0e307d9dc6 --- /dev/null +++ b/explorer/src/components/Delegations/requests/utils.ts @@ -0,0 +1,11 @@ +import { MixNodeCostParams } from '@nymproject/types'; +import { AppEnv } from '../types'; +import { invokeWrapper } from './wrapper'; + +export const getEnv = async () => invokeWrapper('get_env'); + +export const tryConvertIdentityToMixId = async (mixIdentity: string) => + invokeWrapper('try_convert_pubkey_to_mix_id', { mixIdentity }); + +export const getDefaultMixnodeCostParams = async (profitMarginPercent: string) => + invokeWrapper('default_mixnode_cost_params', { profitMarginPercent }); diff --git a/explorer/src/components/Delegations/requests/vesting.ts b/explorer/src/components/Delegations/requests/vesting.ts new file mode 100644 index 0000000000..2d13cb4448 --- /dev/null +++ b/explorer/src/components/Delegations/requests/vesting.ts @@ -0,0 +1,125 @@ +import { + TNodeType, + Gateway, + DecCoin, + MixNode, + OriginalVestingResponse, + Period, + PledgeData, + TransactionExecuteResult, + VestingAccountInfo, + MixNodeCostParams, + MixNodeConfigUpdate, + GatewayConfigUpdate, +} from '@nymproject/types'; +import { Fee } from '@nymproject/types/dist/types/rust/Fee'; +import { invokeWrapper } from './wrapper'; +import { TBondGatewaySignatureArgs, TBondMixnodeSignatureArgs, TUpdateBondArgs } from '../types'; + +export const getLockedCoins = async (): Promise => invokeWrapper('locked_coins'); + +export const getSpendableCoins = async (): Promise => invokeWrapper('spendable_coins'); + +export const getSpendableVestedCoins = async (): Promise => invokeWrapper('spendable_vested_coins'); + +export const getSpendableRewardCoins = async (): Promise => invokeWrapper('spendable_reward_coins'); + +export const getVestingCoins = async (vestingAccountAddress: string): Promise => + invokeWrapper('vesting_coins', { vestingAccountAddress }); + +export const getVestedCoins = async (vestingAccountAddress: string): Promise => + invokeWrapper('vested_coins', { vestingAccountAddress }); + +export const getOriginalVesting = async (vestingAccountAddress: string): Promise => { + const res = await invokeWrapper('original_vesting', { vestingAccountAddress }); + return { ...res, amount: res.amount }; +}; + +export const getCurrentVestingPeriod = async (address: string) => + invokeWrapper('get_current_vesting_period', { address }); + +export const vestingBondGateway = async ({ + gateway, + pledge, + msgSignature, +}: { + gateway: Gateway; + pledge: DecCoin; + msgSignature: string; +}) => invokeWrapper('vesting_bond_gateway', { gateway, msgSignature, pledge }); + +export const vestingGenerateGatewayMsgPayload = async (args: Omit) => + invokeWrapper('vesting_generate_gateway_bonding_msg_payload', args); + +export const vestingUnbondGateway = async (fee?: Fee) => + invokeWrapper('vesting_unbond_gateway', { fee }); + +export const vestingBondMixNode = async ({ + mixnode, + costParams, + pledge, + msgSignature, +}: { + mixnode: MixNode; + costParams: MixNodeCostParams; + pledge: DecCoin; + msgSignature: string; +}) => invokeWrapper('vesting_bond_mixnode', { mixnode, costParams, msgSignature, pledge }); + +export const vestingGenerateMixnodeMsgPayload = async (args: Omit) => + invokeWrapper('vesting_generate_mixnode_bonding_msg_payload', args); + +export const vestingUnbondMixnode = async (fee?: Fee) => + invokeWrapper('vesting_unbond_mixnode', { fee }); + +export const withdrawVestedCoins = async (amount: DecCoin, fee?: Fee) => + invokeWrapper('withdraw_vested_coins', { amount, fee }); + +export const vestingUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams, fee?: Fee) => + invokeWrapper('vesting_update_mixnode_cost_params', { newCosts, fee }); + +export const vestingUpdateMixnodeConfig = async (update: MixNodeConfigUpdate, fee?: Fee) => + invokeWrapper('vesting_update_mixnode_config', { update, fee }); + +export const vestingUpdateGatewayConfig = async (update: GatewayConfigUpdate, fee?: Fee) => + invokeWrapper('vesting_update_gateway_config', { update, fee }); + +export const vestingDelegateToMixnode = async (mixId: number, amount: DecCoin, fee?: Fee) => + invokeWrapper('vesting_delegate_to_mixnode', { mixId, amount, fee }); + +export const vestingUndelegateFromMixnode = async (mixId: number) => + invokeWrapper('vesting_undelegate_from_mixnode', { mixId }); + +export const getVestingAccountInfo = async (address: string) => + invokeWrapper('get_account_info', { address }); + +export const getVestingPledgeInfo = async ({ + address, + type, +}: { + address?: string; + type: TNodeType; +}): Promise => { + try { + return await invokeWrapper(`vesting_get_${type}_pledge`, { address }); + } catch (e) { + return undefined; + } +}; + +export const vestingDelegatedFree = async (vestingAccountAddress: string) => + invokeWrapper('delegated_free', { vestingAccountAddress }); + +export const vestingUnbond = async (type: TNodeType) => { + if (type === 'mixnode') return vestingUnbondMixnode(); + return vestingUnbondGateway(); +}; + +export const vestingClaimOperatorReward = async (fee?: Fee) => + invokeWrapper('vesting_claim_operator_reward', { fee }); + +export const vestingClaimDelegatorRewards = async (mixId: number) => + invokeWrapper('vesting_claim_delegator_reward', { mixId }); + +export const vestingUpdateBond = async (args: TUpdateBondArgs) => + invokeWrapper('vesting_update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/wrapper.ts b/explorer/src/components/Delegations/requests/wrapper.ts new file mode 100644 index 0000000000..5c9cb97f3a --- /dev/null +++ b/explorer/src/components/Delegations/requests/wrapper.ts @@ -0,0 +1,20 @@ +import { invoke } from '@tauri-apps/api'; +import { config } from '../config'; +import { Console } from '../utils/console'; + +export async function invokeWrapper(operationName: string, args?: any): Promise { + const res = await invoke(operationName, args); + if (config.LOG_TAURI_OPERATIONS) { + const argsToLog: any = {}; + if (args) { + Object.keys(args).forEach((key) => { + // check if the key should be excluded from logs + if (!['mnemonic', 'password', 'currentPassword', 'newPassword'].includes(key)) { + argsToLog[key] = args[key]; + } + }); + } + Console.log({ operationName, argsToLog, res }); + } + return res; +} diff --git a/explorer/src/components/Delegations/types/global.ts b/explorer/src/components/Delegations/types/global.ts new file mode 100644 index 0000000000..aaf9d56b2e --- /dev/null +++ b/explorer/src/components/Delegations/types/global.ts @@ -0,0 +1,97 @@ +import { DecCoin, Gateway, MixNode, MixNodeCostParams, PledgeData } from '@nymproject/types'; +import { Fee } from '@nymproject/types/dist/types/rust/Fee'; +// eslint-disable-next-line import/no-cycle +// import { TBondedGateway, TBondedMixnode } from '../context'; + +export enum EnumNodeType { + mixnode = 'mixnode', + gateway = 'gateway', +} + +export type TNodeOwnership = { + hasOwnership: boolean; + nodeType?: EnumNodeType; + vestingPledge?: PledgeData; +}; + +export type TPendingDelegation = { + block_height: number; +}; + +export type TDelegation = { + owner: string; + node_identity: string; + amount: DecCoin; + block_height: number; + proxy: string; // proxy address used to delegate the funds on behalf of another address + pending?: TPendingDelegation; +}; + +export type TBondGatewayArgs = { + gateway: Gateway; + pledge: DecCoin; + msgSignature: string; + fee?: Fee; +}; + +export type TBondMixNodeArgs = { + mixnode: MixNode; + costParams: MixNodeCostParams; + pledge: DecCoin; + msgSignature: string; + fee?: Fee; +}; + +export type TBondMixnodeSignatureArgs = { + mixnode: MixNode; + costParams: MixNodeCostParams; + pledge: DecCoin; + tokenPool: 'balance' | 'locked'; +}; + +export type TBondGatewaySignatureArgs = { + gateway: Gateway; + pledge: DecCoin; + tokenPool: 'balance' | 'locked'; +}; + +export type TUpdateBondArgs = { + currentPledge: DecCoin; + newPledge: DecCoin; + fee?: Fee; +}; + +export type TSimulateUpdateBondArgs = Omit; + +export type TNodeDescription = { + name: string; + description: string; + link: string; + location: string; +}; + +export type TDelegateArgs = { + identity: string; + amount: DecCoin; +}; + +export type Period = 'Before' | { In: number } | 'After'; + +export type TAccount = { + name: string; + address: string; + mnemonic: string; +}; + +export type TGatewayReport = { + identity: string; + owner: string; + last_day: number; + last_hour: number; + most_recent: number; +}; + +// export const isMixnode = (node: TBondedMixnode | TBondedGateway): node is TBondedMixnode => +// (node as TBondedMixnode).profitMargin !== undefined; + +// export const isGateway = (node: TBondedMixnode | TBondedGateway): node is TBondedGateway => !isMixnode(node); diff --git a/explorer/src/components/Delegations/types/index.ts b/explorer/src/components/Delegations/types/index.ts new file mode 100644 index 0000000000..85747b1acd --- /dev/null +++ b/explorer/src/components/Delegations/types/index.ts @@ -0,0 +1,7 @@ +export * from './global'; +export * from './rust/AppEnv'; +export * from './rust/Interval'; +export * from './rust/Network'; +export * from './rust/StateParams'; +export * from './rust/ValidatorUrl'; +export * from './rust/ValidatorUrls'; diff --git a/explorer/src/components/Delegations/types/rust/AppEnv.ts b/explorer/src/components/Delegations/types/rust/AppEnv.ts new file mode 100644 index 0000000000..861ecd9ef5 --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/AppEnv.ts @@ -0,0 +1,5 @@ +export interface AppEnv { + ADMIN_ADDRESS: string | null; + SHOW_TERMINAL: string | null; + ENABLE_QA_MODE: string | null; +} diff --git a/explorer/src/components/Delegations/types/rust/AppVersion.ts b/explorer/src/components/Delegations/types/rust/AppVersion.ts new file mode 100644 index 0000000000..82b94c5596 --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/AppVersion.ts @@ -0,0 +1,7 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export interface AppVersion { + current_version: string; + latest_version: string; + is_update_available: boolean; +} diff --git a/explorer/src/components/Delegations/types/rust/Epoch.ts b/explorer/src/components/Delegations/types/rust/Epoch.ts new file mode 100644 index 0000000000..21ec4ac2df --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/Epoch.ts @@ -0,0 +1,8 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export interface Epoch { + id: number; + start: bigint; + end: bigint; + duration_seconds: bigint; +} diff --git a/explorer/src/components/Delegations/types/rust/Interval.ts b/explorer/src/components/Delegations/types/rust/Interval.ts new file mode 100644 index 0000000000..c1526be658 --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/Interval.ts @@ -0,0 +1,8 @@ +export interface Interval { + id: number; + epochs_in_interval: number; + current_epoch_start_unix: bigint; + current_epoch_id: number; + epoch_length_seconds: bigint; + total_elapsed_epochs: number; +} diff --git a/explorer/src/components/Delegations/types/rust/Network.ts b/explorer/src/components/Delegations/types/rust/Network.ts new file mode 100644 index 0000000000..d55f0bce67 --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/Network.ts @@ -0,0 +1,3 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export type Network = 'QA' | 'SANDBOX' | 'MAINNET'; diff --git a/explorer/src/components/Delegations/types/rust/StateParams.ts b/explorer/src/components/Delegations/types/rust/StateParams.ts new file mode 100644 index 0000000000..2119c59470 --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/StateParams.ts @@ -0,0 +1,8 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { DecCoin } from '@nymproject/types/src/types/rust/DecCoin'; + +export interface TauriContractStateParams { + minimum_mixnode_pledge: DecCoin; + minimum_gateway_pledge: DecCoin; + minimum_mixnode_delegation: DecCoin | null; +} diff --git a/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts b/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts new file mode 100644 index 0000000000..00291a57cd --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. + +export interface ValidatorUrl { + url: string; + name: string | null; +} diff --git a/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts b/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts new file mode 100644 index 0000000000..57118d6c3f --- /dev/null +++ b/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts @@ -0,0 +1,6 @@ +// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. +import type { ValidatorUrl } from './ValidatorUrl'; + +export interface ValidatorUrls { + urls: Array; +} diff --git a/explorer/src/components/Delegations/typings/FC.d.ts b/explorer/src/components/Delegations/typings/FC.d.ts new file mode 100644 index 0000000000..08ebdfa298 --- /dev/null +++ b/explorer/src/components/Delegations/typings/FC.d.ts @@ -0,0 +1 @@ +declare type FCWithChildren

= React.FC>; diff --git a/explorer/src/components/Delegations/typings/jpeg.d.ts b/explorer/src/components/Delegations/typings/jpeg.d.ts new file mode 100644 index 0000000000..af2ed72913 --- /dev/null +++ b/explorer/src/components/Delegations/typings/jpeg.d.ts @@ -0,0 +1,9 @@ +declare module '*.jpeg' { + const value: any; + export default value; +} + +declare module '*.jpg' { + const value: any; + export default value; +} diff --git a/explorer/src/components/Delegations/typings/json.d.ts b/explorer/src/components/Delegations/typings/json.d.ts new file mode 100644 index 0000000000..b72dd46ee5 --- /dev/null +++ b/explorer/src/components/Delegations/typings/json.d.ts @@ -0,0 +1,4 @@ +declare module '*.json' { + const content: any; + export default content; +} diff --git a/explorer/src/components/Delegations/typings/png.d.ts b/explorer/src/components/Delegations/typings/png.d.ts new file mode 100644 index 0000000000..dd84df40a4 --- /dev/null +++ b/explorer/src/components/Delegations/typings/png.d.ts @@ -0,0 +1,4 @@ +declare module '*.png' { + const content: any; + export default content; +} diff --git a/explorer/src/components/Delegations/typings/svg.d.ts b/explorer/src/components/Delegations/typings/svg.d.ts new file mode 100644 index 0000000000..091d25e210 --- /dev/null +++ b/explorer/src/components/Delegations/typings/svg.d.ts @@ -0,0 +1,4 @@ +declare module '*.svg' { + const content: any; + export default content; +} diff --git a/explorer/src/components/Delegations/utils/common.ts b/explorer/src/components/Delegations/utils/common.ts new file mode 100644 index 0000000000..c738df4d2a --- /dev/null +++ b/explorer/src/components/Delegations/utils/common.ts @@ -0,0 +1,255 @@ +import { appWindow } from '@tauri-apps/api/window'; +import bs58 from 'bs58'; +import Big from 'big.js'; +import { valid } from 'semver'; +import { add, format, fromUnixTime } from 'date-fns'; +import { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types'; +import { getCurrentInterval, getDefaultMixnodeCostParams, getLockedCoins, getSpendableCoins } from '../requests'; +import { Console } from './console'; + +export type TPoolOption = 'balance' | 'locked'; + +export const uNYMtoNYM = (unym: string, rounding = 6) => { + const nym = Big(unym).div(1000000).toFixed(rounding); + + return { + asString: () => nym, + asNumber: () => Number(nym), + }; +}; + +// export const checkHasEnoughFunds = async (balance: string, allocationValue: string): Promise => { +// try { +// // const walletValue = await userBalance(); + +// const remainingBalance = +balance - +allocationValue; +// return remainingBalance >= 0; +// } catch (e) { +// Console.log(e as string); +// return false; +// } +// }; + +export const checkHasEnoughLockedTokens = async (allocationValue: string) => { + try { + const lockedTokens = await getLockedCoins(); + const spendableTokens = await getSpendableCoins(); + const remainingBalance = +lockedTokens.amount + +spendableTokens.amount - +allocationValue; + return remainingBalance >= 0; + } catch (e) { + Console.error(e as string); + } + return false; +}; + +export const checkTokenBalance = (tokenPool: TPoolOption, amount: string, balance: string) => { + let hasEnoughFunds = false; + // if (tokenPool === 'locked') { + // hasEnoughFunds = await checkHasEnoughLockedTokens(amount); + // } + + if (tokenPool === 'balance') { + const remainingBalance = +balance - +amount; + hasEnoughFunds = remainingBalance >= 0; + } + + return hasEnoughFunds; +}; + +export const validateKey = (key: string, bytesLength: number): boolean => { + // it must be a valid base58 key + try { + const bytes = bs58.decode(key); + // of length 32 + return bytes.length === bytesLength; + } catch (e) { + Console.error(e as string); + return false; + } +}; + +export const validateAmount = async ( + majorAmountAsString: DecCoin['amount'], + minimumAmountAsString: DecCoin['amount'], +): Promise => { + // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc + if (!Number(majorAmountAsString)) { + return false; + } + + if (!isValidRawCoin(majorAmountAsString)) { + return false; + } + + const majorValueFloat = parseInt(majorAmountAsString, Number(10)); + + return majorValueFloat >= parseInt(minimumAmountAsString, Number(10)); + + // this conversion seems really iffy but I'm not sure how to better approach it +}; + +export const isValidHostname = (value: string) => { + // regex for ipv4 and ipv6 and hhostname- source http://jsfiddle.net/DanielD/8S4nq/ + const hostnameRegex = + /((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))|(^\s*((?=.{1,255}$)(?=.*[A-Za-z].*)[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?)*)\s*$)/; + + return hostnameRegex.test(value); +}; + +export const validateVersion = (version: string): boolean => { + try { + return valid(version) !== null; + } catch (e) { + return false; + } +}; + +export const validateLocation = (location: string): boolean => { + const locationRegex = /^[a-z]+$/i; + return locationRegex.test(location); +}; + +export const validateRawPort = (rawPort: number): boolean => !Number.isNaN(rawPort) && rawPort >= 1 && rawPort <= 65535; + +export const truncate = (text: string, trim: number) => `${text.substring(0, trim)}...`; + +export const isGreaterThan = (a: number, b: number) => a > b; + +export const isLessThan = (a: number, b: number) => a < b; + +export const randomNumberBetween = (min: number, max: number) => { + const minCeil = Math.ceil(min); + const maxFloor = Math.floor(max); + return Math.floor(Math.random() * (maxFloor - minCeil + 1) + minCeil); +}; + +export const splice = (size: number, address?: string): string => { + if (address) { + return `${address.slice(0, size)}...${address.slice(-size)}`; + } + return ''; +}; + +export const maximizeWindow = async () => { + await appWindow.maximize(); +}; + +export function removeObjectDuplicates(arr: T[], id: K) { + return arr.filter((v, i, a) => a.findIndex((v2) => v2[id] === v[id]) === i); +} + +export const isDecimal = (value: number) => value - Math.floor(value) !== 0; + +export const attachDefaultOperatingCost = async (profitMarginPercent: string): Promise => + getDefaultMixnodeCostParams(profitMarginPercent); + +/** + * Converts a stringified percentage integer (0-100) to a stringified float (0.0-1.0). + * + * @param value - the percentage to convert + * @returns A stringified float + */ +export const toPercentFloatString = (value: string) => (Number(value) / 100).toString(); + +/** + * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100). + * + * @param value - the percentage to convert + * @returns A stringified integer + */ +export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString(); + +/** + * Converts a decimal number to a pretty representation + * with fixed decimal places. + * + * @param val - a decimal number of string form + * @param dp - number of decimal places (4 by default ie. 0.0000) + * @returns A prettified decimal number + */ +export const toDisplay = (val: string | number | Big, dp = 4) => { + let displayValue; + try { + displayValue = Big(val).toFixed(dp); + } catch (e: any) { + Console.warn(`${displayValue} not a valid decimal number: ${e}`); + } + return displayValue; +}; + +/** + * Takes a DecCoin and prettify its amount to a representation + * with fixed decimal places. + * + * @param coin - a DecCoin + * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000) + * @returns A DecCoin with prettified amount + */ +export const decCoinToDisplay = (coin: DecCoin, dp = 4) => { + const displayCoin = { ...coin }; + try { + displayCoin.amount = Big(coin.amount).toFixed(dp); + } catch (e: any) { + Console.warn(`${coin.amount} not a valid decimal number: ${e}`); + } + return displayCoin; +}; + +/** + * Converts a decimal number of μNYM (micro NYM) to NYM. + * + * @param unym - string representation of a decimal number of μNYM + * @param dp - number of decimal places (4 by default ie. 0.0000) + * @returns The corresponding decimal number in NYM + */ +export const unymToNym = (unym: string | Big, dp = 4) => { + let nym; + try { + nym = Big(unym).div(1_000_000).toFixed(dp); + } catch (e: any) { + Console.warn(`${unym} not a valid decimal number: ${e}`); + } + return nym; +}; + +/** + * + * Checks if the user's balance is enough to pay the fee + * @param balance - The user's current balance + * @param fee - The fee for the tx + * @param tx - The amount of the tx + * @returns boolean + * + */ + +export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => { + console.log('balance', balance, fee, tx); + try { + return Big(balance).gte(Big(fee).plus(Big(tx))); + } catch (e) { + console.log(e); + return false; + } +}; + +export const getIntervalAsDate = async () => { + const interval = await getCurrentInterval(); + const secondsToNextInterval = + Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); + + const nextInterval = format( + add(new Date(), { + seconds: secondsToNextInterval, + }), + 'dd/MM/yyyy, HH:mm', + ); + + const nextEpoch = format( + add(fromUnixTime(Number(interval.current_epoch_start_unix)), { + seconds: Number(interval.epoch_length_seconds), + }), + 'HH:mm', + ); + + return { nextEpoch, nextInterval }; +}; diff --git a/explorer/src/components/Delegations/utils/console.ts b/explorer/src/components/Delegations/utils/console.ts new file mode 100644 index 0000000000..6506c76d2a --- /dev/null +++ b/explorer/src/components/Delegations/utils/console.ts @@ -0,0 +1,10 @@ +/* eslint-disable no-console */ +import { config } from '../config'; + +export const Console = { + log: (message?: any, ...optionalParams: any[]) => + config.IS_DEV_MODE ? console.log(message, ...optionalParams) : undefined, + warn: (message?: any, ...optionalParams: any[]) => + config.IS_DEV_MODE ? console.warn(message, ...optionalParams) : undefined, + error: (message?: any, ...optionalParams: any[]) => console.error(message, ...optionalParams), +}; diff --git a/explorer/src/components/Delegations/utils/fireRequests.ts b/explorer/src/components/Delegations/utils/fireRequests.ts new file mode 100644 index 0000000000..441f3289a8 --- /dev/null +++ b/explorer/src/components/Delegations/utils/fireRequests.ts @@ -0,0 +1,22 @@ +import { Console } from './console'; + +export type TauriReq Promise)> = { + name: Req['name']; + request: () => ReturnType; + onFulfilled: (value: Awaited>) => void; +}; + +async function fireRequests(requests: TauriReq[]) { + const promises = await Promise.allSettled(requests.map((r) => r.request())); + + promises.forEach((res, index) => { + if (res.status === 'rejected') { + Console.warn(`${requests[index].name} request fails`, res.reason); + } + if (res.status === 'fulfilled') { + requests[index].onFulfilled(res.value as any); + } + }); +} + +export default fireRequests; diff --git a/explorer/src/components/Delegations/utils/index.ts b/explorer/src/components/Delegations/utils/index.ts new file mode 100644 index 0000000000..b1a2ade95a --- /dev/null +++ b/explorer/src/components/Delegations/utils/index.ts @@ -0,0 +1,4 @@ +export * from './common'; +export * from './fireRequests'; +export * from './console'; +export { default as fireRequests } from './fireRequests'; diff --git a/explorer/src/components/Delegations/utils/sleep.ts b/explorer/src/components/Delegations/utils/sleep.ts new file mode 100644 index 0000000000..4f1d101103 --- /dev/null +++ b/explorer/src/components/Delegations/utils/sleep.ts @@ -0,0 +1,3 @@ +export const sleep = (delayMilliseconds: number) => + // eslint-disable-next-line no-promise-executor-return + new Promise((resolve) => setTimeout(resolve, delayMilliseconds)); diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index c2c0951b9f..51ab38e191 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -1,10 +1,12 @@ -import * as React from 'react'; +import React, { FC, useContext, useEffect, useState, useMemo } from 'react'; import { Box, TextField, MenuItem, FormControl, Button } from '@mui/material'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import { Filters } from './Filters/Filters'; import { useIsMobile } from '../hooks/useIsMobile'; -import { useState } from 'react'; -import { DelegateModal } from './Delegations/DelegateModal'; +import { DelegateModal } from './Delegations/components/DelegateModal'; +import { ChainProvider } from '@cosmos-kit/react'; +import { assets, chains } from 'chain-registry'; +import { wallets as keplr } from '@cosmos-kit/keplr'; const fieldsHeight = '42.25px'; @@ -28,6 +30,32 @@ export const TableToolbar: FCWithChildren = ({ withFilters, }) => { const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); + const assetsFixedUp = useMemo(() => { + const nyx = assets.find((a) => a.chain_name === 'nyx'); + if (nyx) { + const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); + if (nyxCoin) { + nyxCoin.coingecko_id = 'nyx'; + } + nyx.assets = nyx.assets.reverse(); + } + return assets; + }, [assets]); + + const chainsFixedUp = useMemo(() => { + const nyx = chains.find((c) => c.chain_id === 'nyx'); + if (nyx) { + if (!nyx.staking) { + nyx.staking = { + staking_tokens: [{ denom: 'unyx' }], + lock_duration: { + blocks: 10000, + }, + }; + } + } + return chains; + }, [chains]); const isMobile = useIsMobile(); return ( @@ -104,18 +132,27 @@ export const TableToolbar: FCWithChildren = ({ {showNewDelegationModal && ( - setShowNewDelegationModal(false)} - onOk={undefined} - header="Delegate" - buttonText="Delegate stake" - denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} - accountBalance={'balance?.printable_balance'} - rewardInterval="weekly" - hasVestingContract={true} - // {...storybookStyles(theme, isStorybook)} - /> + 'amino', + }} + > + setShowNewDelegationModal(false)} + onOk={undefined} + header="Delegate" + buttonText="Delegate stake" + denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} + // accountBalance={'balance?.printable_balance' || 'error reading balance'} + rewardInterval="weekly" + hasVestingContract={true} + // {...storybookStyles(theme, isStorybook)} + /> + )} ); From 42a53a1c4960af92c46a81ce6968521d6a4d55c4 Mon Sep 17 00:00:00 2001 From: Yana Date: Thu, 9 Nov 2023 16:52:14 +0000 Subject: [PATCH 124/394] Remove identity key, mixId and amount validation WIP --- .../Delegations/components/DelegateModal.tsx | 203 +++++++++--------- explorer/src/components/TableToolbar.tsx | 6 +- sdk/typescript/docs/components/mixnodes.tsx | 1 + 3 files changed, 102 insertions(+), 108 deletions(-) diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index 8f36deda0e..8a9e844017 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -1,5 +1,5 @@ -import React, { useCallback, useContext, useState, useEffect } from 'react'; -import { Box, Typography, SxProps } from '@mui/material'; +import React, { useCallback, useContext, useState, useEffect, ChangeEvent } from 'react'; +import { Box, Typography, SxProps, TextField } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types'; @@ -35,14 +35,14 @@ export const DelegateModal: FCWithChildren<{ onAmountChanged?: (amount: string) => void; header?: string; buttonText?: string; - rewardInterval: string; + rewardInterval?: string; // accountBalance?: string; estimatedReward?: number; profitMarginPercentage?: string | null; nodeUptimePercentage?: number | null; denom: CurrencyDenom; initialAmount?: string; - hasVestingContract: boolean; + hasVestingContract?: boolean; sx?: SxProps; backdropProps?: object; }> = ({ @@ -76,8 +76,18 @@ export const DelegateModal: FCWithChildren<{ const { fee, getFee, resetFeeState, feeError } = useGetFee(); - const { username, connect, disconnect, wallet, openView, address, getCosmWasmClient, isWalletConnected } = - useChain('nyx'); + const { + username, + connect, + disconnect, + wallet, + openView, + address, + getCosmWasmClient, + isWalletConnected, + getSigningCosmWasmClient, + } = useChain('nyx'); + const [balance, setBalance] = useState<{ status: 'loading' | 'success'; data?: string; @@ -85,8 +95,6 @@ export const DelegateModal: FCWithChildren<{ useEffect(() => { const getBalance = async (walletAddress: string) => { - setBalance({ status: 'loading', data: undefined }); - const account = await getCosmWasmClient(); const uNYMBalance = await account.getBalance(walletAddress, 'unym'); const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); @@ -123,9 +131,14 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; } - // if (!mixId) { - // newValidatedValue = false; - // } + if (!mixId) { + newValidatedValue = false; + } + + if (amount && balance.data && +balance.data - +amount <= 0) { + errorAmountMessage = 'Not enough funds'; + newValidatedValue = false; + } setErrorIdentityKey(errorIdentityKeyMessage); if (mixIdError && !errorIdentityKeyMessage) { @@ -141,22 +154,16 @@ export const DelegateModal: FCWithChildren<{ } }; - const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { - const tokenPool = 'balance'; - const hasEnoughTokens = checkTokenBalance(tokenPool, value.amount, balance.data || '0'); + // const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { + // const SCWClient = await getSigningCosmWasmClient(); - if (!hasEnoughTokens) { - setErrorAmount('Not enough funds'); - return; - } + // console.log('SCWClient :>> ', SCWClient); + // }; - if (tokenPool === 'balance') { - getFee(simulateDelegateToMixnode, { mixId: id, amount: value }); - } + const handleConfirm = async () => { + const SCWClient = await getSigningCosmWasmClient(); - // if (tokenPool === 'locked') { - // getFee(simulateVestingDelegateToMixnode, { mixId: id, amount: value }); - // } + console.log('SCWClient :>> ', SCWClient); }; const handleIdentityKeyChanged = (newIdentityKey: string) => { @@ -167,6 +174,11 @@ export const DelegateModal: FCWithChildren<{ } }; + const handleMixIDChanged = (event: ChangeEvent) => { + const newValue = event.target.value; + setMixId(Number(newValue)); + }; + const handleAmountChanged = (newAmount: DecCoin) => { setAmount(newAmount.amount); @@ -177,83 +189,58 @@ export const DelegateModal: FCWithChildren<{ React.useEffect(() => { validate(); - }, [amount, identityKey, mixIdError]); + }, [amount, identityKey, mixId]); - const resolveMixId = useCallback( - debounce(async (idKey) => { - if (!idKey || !validateKey(idKey, 32)) { - return; - } - let res; - try { - res = await tryConvertIdentityToMixId(idKey); - } catch (e) { - Console.warn(`failed to resolve mix_id for "${idKey}": ${e}`); - return; - } - if (res) { - setMixId(res); - setMixIdError(undefined); - } else { - setMixIdError('Mixnode with this identity does not seem to be currently bonded'); - } - }, 500), - [], - ); + // if (fee) { + // return ( + // + // {balance.data && fee?.amount?.amount && ( + // + // + // + // )} + // + // + // + // ); + // } - React.useEffect(() => { - resolveMixId(identityKey); - }, [identityKey]); - - if (fee) { - return ( - - {balance.data && fee?.amount?.amount && ( - - - - )} - - - - ); - } - - if (feeError) { - return ( - - ); - } + // if (feeError) { + // return ( + // + // ); + // } return ( { - if (mixId && amount) { - handleConfirm({ mixId, value: { amount, denom } }); - } - }} + // onOk={async () => { + // if (mixId && amount) { + // handleConfirm({ mixId, value: { amount, denom } }); + // } + // }} + onOk={async () => handleConfirm()} header={header || 'Delegate'} okLabel={buttonText || 'Delegate stake'} - okDisabled={!isValidated} + okDisabled={isValidated} sx={sx} backdropProps={backdropProps} > - + + + {errorIdentityKey} + + + + - - {errorIdentityKey} - - {/* {hasVestingContract && setTokenPool(pool)} />} */} - ); diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index 51ab38e191..f5aae9f38b 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -30,6 +30,7 @@ export const TableToolbar: FCWithChildren = ({ withFilters, }) => { const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); + const assetsFixedUp = useMemo(() => { const nyx = assets.find((a) => a.chain_name === 'nyx'); if (nyx) { @@ -143,14 +144,9 @@ export const TableToolbar: FCWithChildren = ({ setShowNewDelegationModal(false)} - onOk={undefined} header="Delegate" buttonText="Delegate stake" denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} - // accountBalance={'balance?.printable_balance' || 'error reading balance'} - rewardInterval="weekly" - hasVestingContract={true} - // {...storybookStyles(theme, isStorybook)} /> )} diff --git a/sdk/typescript/docs/components/mixnodes.tsx b/sdk/typescript/docs/components/mixnodes.tsx index 616c950a95..461568bdd2 100644 --- a/sdk/typescript/docs/components/mixnodes.tsx +++ b/sdk/typescript/docs/components/mixnodes.tsx @@ -25,6 +25,7 @@ export const Mixnodes = () => { setBusy(true); const client = await getClient(); const { nodes } = await client.getMixNodesDetailed({}); + setMixnodes(nodes); setBusy(false); }; From f4b5693bcbc1fb92e2b0355fac71770307d7d6c1 Mon Sep 17 00:00:00 2001 From: Yana Date: Fri, 10 Nov 2023 17:27:49 +0000 Subject: [PATCH 125/394] Add CosmWasmSigningClient WIP wip --- .../Delegations/components/DelegateModal.tsx | 109 +++++++++++------- explorer/src/components/TableToolbar.tsx | 62 +++++++++- 2 files changed, 127 insertions(+), 44 deletions(-) diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index 8a9e844017..d4069687b1 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -2,34 +2,28 @@ import React, { useCallback, useContext, useState, useEffect, ChangeEvent } from import { Box, Typography, SxProps, TextField } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation } from '@nymproject/types'; -import { Console } from '../utils/console'; -import { useGetFee } from '../hooks/useGetFee'; -import { debounce } from 'lodash'; +import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types'; + import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; -import { TPoolOption, checkTokenBalance, validateAmount, validateKey } from '../utils'; +import { TPoolOption, validateAmount } from '../utils'; import { useChain } from '@cosmos-kit/react'; +import { StdFee } from '@cosmjs/amino'; +import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; + import { uNYMtoNYM } from '../utils'; import { ErrorModal } from './ErrorModal'; -import { ConfirmTx } from './ConfirmTX'; -import { BalanceWarning } from './FeeWarning'; -import { getMixnodeStakeSaturation, simulateDelegateToMixnode, tryConvertIdentityToMixId } from '../requests'; const MIN_AMOUNT_TO_DELEGATE = 10; +const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; +const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav'; export const DelegateModal: FCWithChildren<{ open: boolean; onClose: () => void; - onOk?: ( - mixId: number, - identityKey: string, - amount: DecCoin, - tokenPool: TPoolOption, - fee?: FeeDetails, - ) => Promise; + onOk?: () => void; identityKey?: string; onIdentityKeyChanged?: (identityKey: string) => void; onAmountChanged?: (amount: string) => void; @@ -54,27 +48,21 @@ export const DelegateModal: FCWithChildren<{ header, buttonText, identityKey: initialIdentityKey, - rewardInterval, // accountBalance, - estimatedReward, denom, - profitMarginPercentage, - nodeUptimePercentage, - initialAmount, - hasVestingContract, sx, backdropProps, }) => { const [mixId, setMixId] = useState(); const [identityKey, setIdentityKey] = useState(initialIdentityKey); - const [amount, setAmount] = useState(initialAmount); + const [amount, setAmount] = useState(); const [isValidated, setValidated] = useState(false); const [errorAmount, setErrorAmount] = useState(); - // const [tokenPool, setTokenPool] = useState('balance'); const [errorIdentityKey, setErrorIdentityKey] = useState(); const [mixIdError, setMixIdError] = useState(); + const [cosmWasmSignerClient, setCosmWasmSignerClient] = useState(); - const { fee, getFee, resetFeeState, feeError } = useGetFee(); + // const { fee, getFee, resetFeeState, feeError } = useGetFee(); const { username, @@ -86,6 +74,7 @@ export const DelegateModal: FCWithChildren<{ getCosmWasmClient, isWalletConnected, getSigningCosmWasmClient, + estimateFee, } = useChain('nyx'); const [balance, setBalance] = useState<{ @@ -93,6 +82,19 @@ export const DelegateModal: FCWithChildren<{ data?: string; }>({ status: 'loading', data: undefined }); + useEffect(() => { + const getClient = async () => { + await getSigningCosmWasmClient() + .then((res) => { + setCosmWasmSignerClient(res); + console.log('res :>> ', res); + }) + .catch((e) => console.log('e :>> ', e)); + }; + + isWalletConnected && getClient(); + }, [isWalletConnected]); + useEffect(() => { const getBalance = async (walletAddress: string) => { const account = await getCosmWasmClient(); @@ -117,7 +119,7 @@ export const DelegateModal: FCWithChildren<{ errorIdentityKeyMessage = 'Please enter a valid identity key'; } - if (amount && !(await validateAmount(amount, '0'))) { + if (amount && !(await validateAmount(amount.amount, '0'))) { newValidatedValue = false; errorAmountMessage = 'Please enter a valid amount'; } @@ -127,7 +129,7 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; } - if (!amount?.length) { + if (!amount?.amount.length) { newValidatedValue = false; } @@ -148,22 +150,47 @@ export const DelegateModal: FCWithChildren<{ setValidated(newValidatedValue); }; - const handleOk = async () => { - if (onOk && amount && identityKey && mixId) { - onOk(mixId, identityKey, { amount, denom }, 'balance', fee); - } + const delegateToMixnode = async ( + { + mixId, + }: { + mixId: number; + }, + fee: number | StdFee | 'auto' = 'auto', + memo?: string, + funds?: DecCoin[], + ): Promise => { + console.log('cosmWasmSignerClient :>> ', cosmWasmSignerClient); + const amount = (Number(funds![0].amount) * 1000000).toString(); + const uNymFunds = [{ amount: amount, denom: 'unym' }]; + return await cosmWasmSignerClient.execute( + address, + MIXNET_CONTRACT_ADDRESS, + { + delegate_to_mixnode: { + mix_id: mixId, + }, + }, + fee, + memo, + uNymFunds, + ); }; - // const handleConfirm = async ({ mixId: id, value }: { mixId: number; value: DecCoin }) => { - // const SCWClient = await getSigningCosmWasmClient(); - - // console.log('SCWClient :>> ', SCWClient); - // }; - const handleConfirm = async () => { - const SCWClient = await getSigningCosmWasmClient(); + const memo: string = 'test delegation'; + const fee = { gas: '1000000', amount: [{ amount: '25000', denom: 'unym' }] }; - console.log('SCWClient :>> ', SCWClient); + if (mixId && amount && onOk && cosmWasmSignerClient) { + console.log('trying to delegate :>> '); + console.log('balance.data :>> ', balance.data); + onOk(); + console.log('amount :>> ', amount); + console.log('fee :>> ', fee); + await delegateToMixnode({ mixId }, fee, memo, [amount]) + .then((res) => console.log('res :>> ', res)) + .catch((err) => console.log('err :>> ', err)); + } }; const handleIdentityKeyChanged = (newIdentityKey: string) => { @@ -180,7 +207,7 @@ export const DelegateModal: FCWithChildren<{ }; const handleAmountChanged = (newAmount: DecCoin) => { - setAmount(newAmount.amount); + setAmount(newAmount); if (onAmountChanged) { onAmountChanged(newAmount.amount); @@ -236,7 +263,7 @@ export const DelegateModal: FCWithChildren<{ onOk={async () => handleConfirm()} header={header || 'Delegate'} okLabel={buttonText || 'Delegate stake'} - okDisabled={isValidated} + okDisabled={!isValidated} sx={sx} backdropProps={backdropProps} > @@ -278,7 +305,7 @@ export const DelegateModal: FCWithChildren<{ required fullWidth label="Amount" - initialValue={amount} + // initialValue={amount} autoFocus={Boolean(initialIdentityKey)} onChanged={handleAmountChanged} denom={denom} diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index f5aae9f38b..bdd179ac7c 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -7,6 +7,7 @@ import { DelegateModal } from './Delegations/components/DelegateModal'; import { ChainProvider } from '@cosmos-kit/react'; import { assets, chains } from 'chain-registry'; import { wallets as keplr } from '@cosmos-kit/keplr'; +import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types'; const fieldsHeight = '42.25px'; @@ -19,6 +20,17 @@ type TableToolBarProps = { childrenBefore?: React.ReactNode; childrenAfter?: React.ReactNode; }; +type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound'; + +type DelegationModalProps = { + status: 'loading' | 'success' | 'error'; + action: ActionType; + message?: string; + transactions?: { + url: string; + hash: string; + }[]; +}; export const TableToolbar: FCWithChildren = ({ searchTerm, @@ -30,11 +42,12 @@ export const TableToolbar: FCWithChildren = ({ withFilters, }) => { const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); + const [confirmationModalProps, setConfirmationModalProps] = useState(); const assetsFixedUp = useMemo(() => { - const nyx = assets.find((a) => a.chain_name === 'nyx'); + const nyx = assets.find((a) => a.chain_name === 'sandbox'); if (nyx) { - const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); + const nyxCoin = nyx.assets.find((a) => a.name === 'sandbox'); if (nyxCoin) { nyxCoin.coingecko_id = 'nyx'; } @@ -53,11 +66,50 @@ export const TableToolbar: FCWithChildren = ({ blocks: 10000, }, }; + if (nyx.apis) nyx.apis.rpc = [{ address: 'https://rpc.nymtech.net', provider: 'nym' }]; } } return chains; }, [chains]); + const handleNewDelegation = () => { + // setConfirmationModalProps({ + // status: 'loading', + // action: 'delegate', + // }); + setShowNewDelegationModal(false); + // setCurrentDelegationListActionItem(undefined); + // try { + // const tx = await addDelegation( + // { + // mix_id, + // amount, + // }, + // tokenPool, + // fee, + // ); + + // const balances = await getAllBalances(); + + // setConfirmationModalProps({ + // status: 'success', + // action: 'delegate', + // message: 'This operation can take up to one hour to process', + // ...balances, + // transactions: [ + // { url: `${urls(network).blockExplorer}/transaction/${tx.transaction_hash}`, hash: tx.transaction_hash }, + // ], + // }); + // } catch (e) { + // Console.error('Failed to addDelegation', e); + // setConfirmationModalProps({ + // status: 'error', + // action: 'delegate', + // message: (e as Error).message, + // }); + // } + }; + const isMobile = useIsMobile(); return ( = ({ }} > @@ -147,6 +200,9 @@ export const TableToolbar: FCWithChildren = ({ header="Delegate" buttonText="Delegate stake" denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} + onOk={handleNewDelegation} + // accountBalance={balance?.printable_balance} + {...confirmationModalProps} /> )} From b16349f2e95de441253931927151914af2030a05 Mon Sep 17 00:00:00 2001 From: Yana Date: Wed, 15 Nov 2023 15:53:37 +0000 Subject: [PATCH 126/394] Add confirmation models --- .../Delegations/components/DelegateModal.tsx | 129 ++++++------------ .../components/DelegationModal.tsx | 80 +++++++++++ .../Delegations/components/LoadingModal.tsx | 29 ++++ .../components/Delegations/utils/common.ts | 13 ++ explorer/src/components/TableToolbar.tsx | 58 +++----- 5 files changed, 183 insertions(+), 126 deletions(-) create mode 100644 explorer/src/components/Delegations/components/DelegationModal.tsx create mode 100644 explorer/src/components/Delegations/components/LoadingModal.tsx diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index d4069687b1..e28384ec00 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -1,29 +1,25 @@ -import React, { useCallback, useContext, useState, useEffect, ChangeEvent } from 'react'; +import React, { useState, useEffect, ChangeEvent } from 'react'; import { Box, Typography, SxProps, TextField } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; -import { CurrencyDenom, FeeDetails, DecCoin, decimalToFloatApproximation, Coin } from '@nymproject/types'; - +import { CurrencyDenom, DecCoin } from '@nymproject/types'; import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; - -import { TPoolOption, validateAmount } from '../utils'; - +import { Console, urls, validateAmount } from '../utils'; import { useChain } from '@cosmos-kit/react'; import { StdFee } from '@cosmjs/amino'; import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; - import { uNYMtoNYM } from '../utils'; -import { ErrorModal } from './ErrorModal'; +import { DelegationModalProps } from './DelegationModal'; const MIN_AMOUNT_TO_DELEGATE = 10; const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; -const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav'; +// const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav'; export const DelegateModal: FCWithChildren<{ open: boolean; onClose: () => void; - onOk?: () => void; + onOk?: (delegationModalProps: DelegationModalProps) => void; identityKey?: string; onIdentityKeyChanged?: (identityKey: string) => void; onAmountChanged?: (amount: string) => void; @@ -61,8 +57,10 @@ export const DelegateModal: FCWithChildren<{ const [errorIdentityKey, setErrorIdentityKey] = useState(); const [mixIdError, setMixIdError] = useState(); const [cosmWasmSignerClient, setCosmWasmSignerClient] = useState(); - - // const { fee, getFee, resetFeeState, feeError } = useGetFee(); + const [balance, setBalance] = useState<{ + status: 'loading' | 'success'; + data?: string; + }>({ status: 'loading', data: undefined }); const { username, @@ -77,11 +75,6 @@ export const DelegateModal: FCWithChildren<{ estimateFee, } = useChain('nyx'); - const [balance, setBalance] = useState<{ - status: 'loading' | 'success'; - data?: string; - }>({ status: 'loading', data: undefined }); - useEffect(() => { const getClient = async () => { await getSigningCosmWasmClient() @@ -95,15 +88,14 @@ export const DelegateModal: FCWithChildren<{ isWalletConnected && getClient(); }, [isWalletConnected]); + const getBalance = async (walletAddress: string) => { + const account = await getCosmWasmClient(); + const uNYMBalance = await account.getBalance(walletAddress, 'unym'); + const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); + + setBalance({ status: 'success', data: NYMBalance }); + }; useEffect(() => { - const getBalance = async (walletAddress: string) => { - const account = await getCosmWasmClient(); - const uNYMBalance = await account.getBalance(walletAddress, 'unym'); - const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); - - setBalance({ status: 'success', data: NYMBalance }); - }; - if (address) { getBalance(address); } @@ -182,14 +174,32 @@ export const DelegateModal: FCWithChildren<{ const fee = { gas: '1000000', amount: [{ amount: '25000', denom: 'unym' }] }; if (mixId && amount && onOk && cosmWasmSignerClient) { - console.log('trying to delegate :>> '); - console.log('balance.data :>> ', balance.data); - onOk(); - console.log('amount :>> ', amount); - console.log('fee :>> ', fee); - await delegateToMixnode({ mixId }, fee, memo, [amount]) - .then((res) => console.log('res :>> ', res)) - .catch((err) => console.log('err :>> ', err)); + onOk({ + status: 'loading', + action: 'delegate', + }); + try { + await delegateToMixnode({ mixId }, fee, memo, [amount]).then((res) => { + console.log('res :>> ', res); + }); + const tx = await delegateToMixnode({ mixId }, fee, memo, [amount]); + + onOk({ + status: 'success', + action: 'delegate', + message: 'This operation can take up to one hour to process', + transactions: [ + { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash }, + ], + }); + } catch (e) { + Console.error('Failed to addDelegation', e); + onOk({ + status: 'error', + action: 'delegate', + message: (e as Error).message, + }); + } } }; @@ -218,39 +228,6 @@ export const DelegateModal: FCWithChildren<{ validate(); }, [amount, identityKey, mixId]); - // if (fee) { - // return ( - // - // {balance.data && fee?.amount?.amount && ( - // - // - // - // )} - // - // - // - // ); - // } - - // if (feeError) { - // return ( - // - // ); - // } - return ( - {/*

{getGlobalbutton()}
- - ); -} + return {getGlobalbutton()}; +}; diff --git a/explorer/src/components/Delegations/components/ConfirmTX.tsx b/explorer/src/components/Delegations/components/ConfirmTX.tsx deleted file mode 100644 index e62a86a23c..0000000000 --- a/explorer/src/components/Delegations/components/ConfirmTX.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import React from 'react'; -import { FeeDetails } from '@nymproject/types'; -import { Box } from '@mui/material'; -import { useTheme, Theme } from '@mui/material/styles'; -import { SimpleModal } from './SimpleModal'; -import { ModalFee } from './ModalFee'; -import { ModalDivider } from './ModalDivider'; -import { backDropStyles, modalStyles } from './styles'; - -const storybookStyles = (theme: Theme, isStorybook?: boolean, backdropProps?: object) => - isStorybook - ? { - backdropProps: { ...backDropStyles(theme), ...backdropProps }, - sx: modalStyles(theme), - } - : {}; - -export const ConfirmTx: FCWithChildren<{ - open: boolean; - header: string; - subheader?: string; - fee: FeeDetails; - onConfirm: () => Promise; - onClose?: () => void; - onPrev: () => void; - isStorybook?: boolean; - children?: React.ReactNode; -}> = ({ open, fee, onConfirm, onClose, header, subheader, onPrev, children, isStorybook }) => { - const theme = useTheme(); - return ( - - - {children} - - - - - ); -}; diff --git a/explorer/src/components/Delegations/components/ConfirmationModal.tsx b/explorer/src/components/Delegations/components/ConfirmationModal.tsx index 7cc8cc62ca..8e859f5eba 100644 --- a/explorer/src/components/Delegations/components/ConfirmationModal.tsx +++ b/explorer/src/components/Delegations/components/ConfirmationModal.tsx @@ -45,7 +45,7 @@ export const ConfirmationModal = ({ {title} {subTitle && (typeof subTitle === 'string' ? ( - + {subTitle} ) : ( diff --git a/explorer/src/components/Delegations/components/DelegateIconButton.tsx b/explorer/src/components/Delegations/components/DelegateIconButton.tsx new file mode 100644 index 0000000000..b19a5587d0 --- /dev/null +++ b/explorer/src/components/Delegations/components/DelegateIconButton.tsx @@ -0,0 +1,23 @@ +import * as React from 'react'; +import { IconButton, Tooltip } from '@mui/material'; +import { SxProps } from '@mui/system'; +import { DelegateIcon } from '../../../icons/DelevateSVG'; + +export const DelegateIconButton: FCWithChildren<{ + disabled?: boolean; + tooltip?: React.ReactNode; + sx?: SxProps; + onDelegate: () => void; +}> = ({ tooltip, onDelegate, sx, disabled }) => { + const handleOnDelegate = (e: React.MouseEvent) => { + e.stopPropagation(); + onDelegate(); + }; + return ( + + + + + + ); +}; diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index bc4030c7f2..4a2e6a32d3 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -1,97 +1,47 @@ -import React, { useState, useEffect, ChangeEvent } from 'react'; -import { Box, Typography, SxProps, TextField } from '@mui/material'; +import React, { useState, useEffect } from 'react'; +import { Box, SxProps, TextField } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { CurrencyDenom, DecCoin } from '@nymproject/types'; +import { useChain } from '@cosmos-kit/react'; import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; -import { Console, urls, validateAmount } from '../utils'; -import { useChain } from '@cosmos-kit/react'; -import { StdFee } from '@cosmjs/amino'; -import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; -import { uNYMtoNYM } from '../utils'; import { DelegationModalProps } from './DelegationModal'; +import { unymToNym, validateAmount } from '../../../utils/currency'; +import { urls } from '../../../utils'; const MIN_AMOUNT_TO_DELEGATE = 10; const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; -// const sandboxContractAddress = 'n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav'; export const DelegateModal: FCWithChildren<{ - open: boolean; - onClose: () => void; - onOk?: (delegationModalProps: DelegationModalProps) => void; - identityKey?: string; - onIdentityKeyChanged?: (identityKey: string) => void; - onAmountChanged?: (amount: string) => void; + mixId: number; + identityKey: string; header?: string; buttonText?: string; rewardInterval?: string; - // accountBalance?: string; estimatedReward?: number; profitMarginPercentage?: string | null; nodeUptimePercentage?: number | null; denom: CurrencyDenom; - initialAmount?: string; - hasVestingContract?: boolean; sx?: SxProps; backdropProps?: object; -}> = ({ - open, - onIdentityKeyChanged, - onAmountChanged, - onClose, - onOk, - header, - buttonText, - identityKey: initialIdentityKey, - // accountBalance, - denom, - sx, - backdropProps, -}) => { - const [mixId, setMixId] = useState(); - const [identityKey, setIdentityKey] = useState(initialIdentityKey); - const [amount, setAmount] = useState(); + onClose: () => void; + onOk?: (delegationModalProps: DelegationModalProps) => void; +}> = ({ mixId, identityKey, onClose, onOk, denom, sx }) => { + const [amount, setAmount] = useState({ amount: '10', denom: 'nym' }); const [isValidated, setValidated] = useState(false); const [errorAmount, setErrorAmount] = useState(); - const [errorIdentityKey, setErrorIdentityKey] = useState(); - const [mixIdError, setMixIdError] = useState(); - const [cosmWasmSignerClient, setCosmWasmSignerClient] = useState(); const [balance, setBalance] = useState<{ status: 'loading' | 'success'; data?: string; }>({ status: 'loading', data: undefined }); - const { - username, - connect, - disconnect, - wallet, - openView, - address, - getCosmWasmClient, - isWalletConnected, - getSigningCosmWasmClient, - estimateFee, - } = useChain('nyx'); - - useEffect(() => { - const getClient = async () => { - await getSigningCosmWasmClient() - .then((res) => { - setCosmWasmSignerClient(res); - console.log('res :>> ', res); - }) - .catch((e) => console.log('e :>> ', e)); - }; - - isWalletConnected && getClient(); - }, [isWalletConnected]); + const { address, getCosmWasmClient, getSigningCosmWasmClient } = useChain('nyx'); const getBalance = async (walletAddress: string) => { const account = await getCosmWasmClient(); const uNYMBalance = await account.getBalance(walletAddress, 'unym'); - const NYMBalance = uNYMtoNYM(uNYMBalance.amount).asString(); + const NYMBalance = unymToNym(uNYMBalance.amount); setBalance({ status: 'success', data: NYMBalance }); }; @@ -99,24 +49,19 @@ export const DelegateModal: FCWithChildren<{ if (address) { getBalance(address); } - }, [address, getCosmWasmClient]); + }, [address]); const validate = async () => { let newValidatedValue = true; let errorAmountMessage; - let errorIdentityKeyMessage; - - if (!identityKey) { - newValidatedValue = false; - errorIdentityKeyMessage = 'Please enter a valid identity key'; - } if (amount && !(await validateAmount(amount.amount, '0'))) { newValidatedValue = false; errorAmountMessage = 'Please enter a valid amount'; } + console.log(amount, MIN_AMOUNT_TO_DELEGATE); - if (amount && Number(amount) < MIN_AMOUNT_TO_DELEGATE) { + if (amount && +amount.amount < MIN_AMOUNT_TO_DELEGATE) { errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`; newValidatedValue = false; } @@ -125,99 +70,73 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; } - if (!mixId) { - newValidatedValue = false; - } - - if (amount && balance.data && +balance.data - +amount <= 0) { + if (amount && balance.data && +balance.data - +amount.amount <= 0) { errorAmountMessage = 'Not enough funds'; newValidatedValue = false; } - setErrorIdentityKey(errorIdentityKeyMessage); - if (mixIdError && !errorIdentityKeyMessage) { - setErrorIdentityKey(mixIdError); - } setErrorAmount(errorAmountMessage); setValidated(newValidatedValue); }; - const delegateToMixnode = async ( - { - mixId, - }: { - mixId: number; - }, - fee: number | StdFee | 'auto' = 'auto', - memo?: string, - funds?: DecCoin[], - ): Promise => { - const amount = (Number(funds![0].amount) * 1000000).toString(); - const uNymFunds = [{ amount: amount, denom: 'unym' }]; - return await cosmWasmSignerClient.execute( - address, - MIXNET_CONTRACT_ADDRESS, - { - delegate_to_mixnode: { - mix_id: mixId, + const delegateToMixnode = async ({ mixId, address, amount }: { mixId: number; address: string; amount: string }) => { + const amountToDelegate = (Number(amount) * 1000000).toString(); + const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }]; + const memo: string = 'test delegation'; + const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] }; + + try { + const signerClient = await getSigningCosmWasmClient(); + const tx = await signerClient.execute( + address, + MIXNET_CONTRACT_ADDRESS, + { + delegate_to_mixnode: { + mix_id: mixId, + }, }, - }, - fee, - memo, - uNymFunds, - ); + fee, + memo, + uNymFunds, + ); + return tx; + } catch (e) { + console.error('Failed to delegateToMixnode', e); + throw e; + } }; const handleConfirm = async () => { - const memo: string = 'test delegation'; - const fee = { gas: '1000000', amount: [{ amount: '25000', denom: 'unym' }] }; - - if (mixId && amount && onOk && cosmWasmSignerClient) { + if (mixId && amount && onOk) { onOk({ status: 'loading', - action: 'delegate', }); try { - const tx = await delegateToMixnode({ mixId }, fee, memo, [amount]); + if (!address) { + throw new Error('Please connect your wallet'); + } + + const tx = await delegateToMixnode({ mixId, address, amount: amount.amount }); onOk({ status: 'success', - action: 'delegate', message: 'This operation can take up to one hour to process', transactions: [ { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash }, ], }); } catch (e) { - Console.error('Failed to addDelegation', e); + console.error('Failed to addDelegation', e); onOk({ status: 'error', - action: 'delegate', message: (e as Error).message, }); } } }; - const handleIdentityKeyChanged = (newIdentityKey: string) => { - setIdentityKey(newIdentityKey); - - if (onIdentityKeyChanged) { - onIdentityKeyChanged(newIdentityKey); - } - }; - - const handleMixIDChanged = (event: ChangeEvent) => { - const newValue = event.target.value; - setMixId(Number(newValue)); - }; - const handleAmountChanged = (newAmount: DecCoin) => { setAmount(newAmount); - - if (onAmountChanged) { - onAmountChanged(newAmount.amount); - } }; React.useEffect(() => { @@ -226,60 +145,33 @@ export const DelegateModal: FCWithChildren<{ return ( { - // if (mixId && amount) { - // handleConfirm({ mixId, value: { amount, denom } }); - // } - // }} - onOk={async () => handleConfirm()} - header={header || 'Delegate'} - okLabel={buttonText || 'Delegate stake'} + onOk={handleConfirm} + header="Delegate" + okLabel="Delegate" okDisabled={!isValidated} sx={sx} - backdropProps={backdropProps} > undefined} initialValue={identityKey} - readOnly={Boolean(initialIdentityKey)} - textFieldProps={{ - autoFocus: !initialIdentityKey, - }} + readOnly showTickOnValid={false} /> - - {errorIdentityKey} - - - - + - + ); }; diff --git a/explorer/src/components/Delegations/components/DelegationModal.tsx b/explorer/src/components/Delegations/components/DelegationModal.tsx index 54343ed539..4b2e486a6c 100644 --- a/explorer/src/components/Delegations/components/DelegationModal.tsx +++ b/explorer/src/components/Delegations/components/DelegationModal.tsx @@ -5,29 +5,8 @@ import { LoadingModal } from './LoadingModal'; import { ConfirmationModal } from './ConfirmationModal'; import { ErrorModal } from './ErrorModal'; -export type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound'; - -const actionToHeader = (action: ActionType): string => { - // eslint-disable-next-line default-case - switch (action) { - case 'redeem': - return 'Rewards redeemed successfully'; - case 'redeem-all': - return 'All rewards redeemed successfully'; - case 'delegate': - return 'Delegation successful'; - case 'undelegate': - return 'Undelegation successful'; - case 'compound': - return 'Rewards compounded successfully'; - default: - throw new Error('Unknown type'); - } -}; - export type DelegationModalProps = { status: 'loading' | 'success' | 'error'; - action: ActionType; message?: string; transactions?: { url: string; @@ -43,7 +22,7 @@ export const DelegationModal: FCWithChildren< backdropProps?: object; children?: React.ReactNode; } -> = ({ status, action, message, transactions, open, onClose, children, sx, backdropProps }) => { +> = ({ status, message, transactions, open, onClose, children, sx, backdropProps }) => { if (status === 'loading') return ; if (status === 'error') { @@ -55,12 +34,7 @@ export const DelegationModal: FCWithChildren< } return ( - {})} - title={actionToHeader(action)} - confirmButton="Done" - > + {})} title="Delegation successful" confirmButton="Done"> {message && {message}} {transactions?.length === 1 && ( diff --git a/explorer/src/components/Delegations/components/ErrorModal.tsx b/explorer/src/components/Delegations/components/ErrorModal.tsx index b1c573af85..9d375051e2 100644 --- a/explorer/src/components/Delegations/components/ErrorModal.tsx +++ b/explorer/src/components/Delegations/components/ErrorModal.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Box, Button, Modal, SxProps, Typography } from '@mui/material'; -import { modalStyle } from '../../../../../nym-wallet/src/components/Modals/styles'; +import { modalStyle } from './SimpleModal'; export const ErrorModal: FCWithChildren<{ open: boolean; @@ -12,7 +12,7 @@ export const ErrorModal: FCWithChildren<{ children?: React.ReactNode; }> = ({ children, open, title, message, sx, backdropProps, onClose }) => ( - `1px solid #fff`, ...modalStyle, ...sx }} textAlign="center"> + theme.palette.error.main} mb={1}> {title || 'Oh no! Something went wrong...'} diff --git a/explorer/src/components/Delegations/components/FeeWarning.tsx b/explorer/src/components/Delegations/components/FeeWarning.tsx deleted file mode 100644 index 3dfaba39d1..0000000000 --- a/explorer/src/components/Delegations/components/FeeWarning.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React, { useContext } from 'react'; -import { Warning } from '@mui/icons-material'; -import { FeeDetails } from '@nymproject/types'; -import { Alert, AlertTitle, Box } from '@mui/material'; -import { isBalanceEnough } from '../utils'; -import { AppContext } from '../context'; - -export const FeeWarning = ({ fee, amount }: { fee: FeeDetails; amount: number }) => { - if (fee.amount && +fee.amount.amount > amount) { - return ( - }> - Warning: Fees are greater than the reward - The fees for redeeming rewards will cost more than the rewards. Are you sure you want to continue? - - ); - } - return null; -}; - -export const BalanceWarning = ({ tx, fee }: { fee: string; tx?: string }) => { - const { userBalance } = useContext(AppContext); - - const hasEnoughBalanace = isBalanceEnough(fee, tx, userBalance.balance?.amount.amount); - - if (hasEnoughBalanace) return null; - - return ( - }> - Warning: Transaction amount is greater than your balance - The transaction amount (inc fees) is greater than your current balance, which could cause this transaction to - fail. - Do you want to continue? - - ); -}; diff --git a/explorer/src/components/Delegations/components/LoadingModal.tsx b/explorer/src/components/Delegations/components/LoadingModal.tsx index 07367d117f..c47574efe3 100644 --- a/explorer/src/components/Delegations/components/LoadingModal.tsx +++ b/explorer/src/components/Delegations/components/LoadingModal.tsx @@ -1,25 +1,14 @@ import React from 'react'; import { Box, CircularProgress, Modal, Stack, Typography, SxProps } from '@mui/material'; - -const modalStyle: SxProps = { - position: 'absolute', - top: '50%', - left: '50%', - transform: 'translate(-50%, -50%)', - width: 500, - bgcolor: 'background.paper', - boxShadow: 24, - borderRadius: '16px', - p: 4, -}; +import { modalStyle } from './SimpleModal'; export const LoadingModal: FCWithChildren<{ text?: string; sx?: SxProps; backdropProps?: object; -}> = ({ sx, backdropProps, text = 'Please wait...' }) => ( - - `1px solid grey`, ...modalStyle, ...sx }} textAlign="center"> +}> = ({ sx, text = 'Please wait...' }) => ( + + {text} diff --git a/explorer/src/components/Delegations/components/ModalFee.tsx b/explorer/src/components/Delegations/components/ModalFee.tsx deleted file mode 100644 index 835b73e689..0000000000 --- a/explorer/src/components/Delegations/components/ModalFee.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import React from 'react'; -import { FeeDetails } from '@nymproject/types'; -import { CircularProgress } from '@mui/material'; -import { ModalListItem } from './ModalListItem'; -import { ModalDivider } from './ModalDivider'; - -type TFeeProps = { fee?: FeeDetails; isLoading: boolean; error?: string; divider?: boolean }; -type TTotalAmountProps = { fee?: FeeDetails; amount?: string; isLoading: boolean; error?: string; divider?: boolean }; - -const getValue = ({ fee, amount, isLoading, error }: TTotalAmountProps) => { - if (isLoading) return ; - if (error && !isLoading) return 'n/a'; - if (fee) { - const numericFee = Number(fee.amount?.amount); - const numericAmountToTransfer = Number(amount); - return amount - ? `${numericFee + numericAmountToTransfer} ${fee.amount?.denom.toUpperCase()}` - : `${fee.amount?.amount} ${fee.amount?.denom.toUpperCase()}`; - } - return '-'; -}; - -export const ModalFee = ({ fee, isLoading, error, divider }: TFeeProps) => ( - <> - - {divider && } - -); - -export const ModalTotalAmount = ({ fee, amount, isLoading, error, divider }: TTotalAmountProps) => ( - <> - - {divider && } - -); diff --git a/explorer/src/components/Delegations/components/ModalListItem.tsx b/explorer/src/components/Delegations/components/ModalListItem.tsx index c545358cf5..830c25705e 100644 --- a/explorer/src/components/Delegations/components/ModalListItem.tsx +++ b/explorer/src/components/Delegations/components/ModalListItem.tsx @@ -1,6 +1,6 @@ import React from 'react'; import { Box, Stack, SxProps, Typography, TypographyProps } from '@mui/material'; -import { ModalDivider } from '../../../../../nym-wallet/src/components/Modals/ModalDivider'; +import { ModalDivider } from './ModalDivider'; export const ModalListItem: FCWithChildren<{ label: string; diff --git a/explorer/src/components/Delegations/components/SimpleModal.tsx b/explorer/src/components/Delegations/components/SimpleModal.tsx index add6329731..b69b3ce554 100644 --- a/explorer/src/components/Delegations/components/SimpleModal.tsx +++ b/explorer/src/components/Delegations/components/SimpleModal.tsx @@ -3,9 +3,19 @@ import { Box, Button, Modal, Stack, SxProps, Typography } from '@mui/material'; import CloseIcon from '@mui/icons-material/Close'; import ErrorOutline from '@mui/icons-material/ErrorOutline'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; -import { modalStyle } from '../../../../../nym-wallet/src/components/Modals/styles'; - import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; +import { useIsMobile } from '../../../hooks/useIsMobile'; + +export const modalStyle = { + position: 'absolute' as 'absolute', + top: '50%', + left: '50%', + transform: 'translate(-50%, -50%)', + bgcolor: 'background.paper', + boxShadow: 24, + borderRadius: '16px', + p: 4, +}; export const StyledBackButton = ({ onBack, @@ -41,7 +51,6 @@ export const SimpleModal: FCWithChildren<{ backButtonFullWidth?: boolean; okDisabled?: boolean; sx?: SxProps; - backdropProps?: object; children?: React.ReactNode; }> = ({ open, @@ -49,7 +58,6 @@ export const SimpleModal: FCWithChildren<{ displayErrorIcon, displayInfoIcon, headerStyles, - subHeaderStyles, buttonFullWidth, onClose, okDisabled, @@ -62,45 +70,41 @@ export const SimpleModal: FCWithChildren<{ backButtonFullWidth, sx, children, - backdropProps, -}) => ( - - `1px solid #fff`, ...modalStyle, ...sx }}> - {displayErrorIcon && } - {displayInfoIcon && } - - {typeof header === 'string' ? ( - - {header} - - ) : ( - header - )} - {!hideCloseIcon && } - - - theme.palette.text.secondary} - // sx={{ color: (theme) => theme.palette.nym.nymWallet.text.muted, ...subHeaderStyles }} - > - {subHeader} - - - {children} - - {(onOk || onBack) && ( - - {onBack && } - {onOk && ( - +}) => { + const isMobile = useIsMobile(); + return ( + + + {displayErrorIcon && } + {displayInfoIcon && } + + {typeof header === 'string' ? ( + + {header} + + ) : ( + header )} - - )} - - -); + {!hideCloseIcon && } + + + theme.palette.text.secondary}> + {subHeader} + + + {children} + + {(onOk || onBack) && ( + + {onBack && } + {onOk && ( + + )} + + )} + + + ); +}; diff --git a/explorer/src/components/Delegations/config.ts b/explorer/src/components/Delegations/config.ts deleted file mode 100644 index 1b1f83ce1f..0000000000 --- a/explorer/src/components/Delegations/config.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const config = { - IS_DEV_MODE: process.env.NODE_ENV === 'development', - LOG_TAURI_OPERATIONS: process.env.NODE_ENV === 'development', -}; diff --git a/explorer/src/components/Delegations/context/accounts.tsx b/explorer/src/components/Delegations/context/accounts.tsx deleted file mode 100644 index 0ebf07cd09..0000000000 --- a/explorer/src/components/Delegations/context/accounts.tsx +++ /dev/null @@ -1,170 +0,0 @@ -import React, { createContext, Dispatch, SetStateAction, useContext, useEffect, useMemo, useState } from 'react'; -import { AccountEntry } from '@nymproject/types'; -import { addAccount as addAccountRequest, renameAccount, showMnemonicForAccount } from '../requests'; -import { useSnackbar } from 'notistack'; -import { AppContext } from './main'; - -type TAccounts = { - accounts?: AccountEntry[]; - selectedAccount?: AccountEntry; - accountToEdit?: AccountEntry; - dialogToDisplay?: TAccountsDialog; - isLoading: boolean; - error?: string; - accountMnemonic: TAccountMnemonic; - setError: Dispatch>; - setAccountMnemonic: Dispatch>; - handleAddAccount: (data: { accountName: string; mnemonic: string; password: string }) => void; - setDialogToDisplay: (dialog?: TAccountsDialog) => void; - handleSelectAccount: (data: { accountName: string; password: string }) => Promise; - handleAccountToEdit: (accountId: string | undefined) => void; - handleEditAccount: ({ - account, - newAccountName, - password, - }: { - account: AccountEntry; - newAccountName: string; - password: string; - }) => Promise; - handleImportAccount: (account: AccountEntry) => void; - handleGetAccountMnemonic: (data: { password: string; accountName: string }) => void; -}; - -export type TAccountsDialog = 'Accounts' | 'Add' | 'Edit' | 'Import' | 'Mnemonic'; -export type TAccountMnemonic = { value?: string; accountName?: string }; - -export const AccountsContext = createContext({} as TAccounts); - -export const AccountsProvider: FCWithChildren = ({ children }) => { - const [accounts, setAccounts] = useState([]); - const [selectedAccount, setSelectedAccount] = useState(); - const [accountToEdit, setAccountToEdit] = useState(); - const [dialogToDisplay, setDialogToDisplay] = useState(); - const [accountMnemonic, setAccountMnemonic] = useState({ - value: undefined, - accountName: undefined, - }); - const [error, setError] = useState(); - const [isLoading, setIsLoading] = useState(false); - const { onAccountChange, storedAccounts } = useContext(AppContext); - const { enqueueSnackbar } = useSnackbar(); - - const handleAddAccount = async ({ - accountName, - mnemonic, - password, - }: { - accountName: string; - mnemonic: string; - password: string; - }) => { - setIsLoading(true); - try { - const newAccount = await addAccountRequest({ - accountName, - mnemonic, - password, - }); - setAccounts((accs) => [...accs, newAccount]); - enqueueSnackbar('New account created', { variant: 'success' }); - } catch (e) { - setError(`Error adding account: ${e}`); - throw new Error(); - } finally { - setIsLoading(false); - } - }; - const handleEditAccount = async ({ - account, - newAccountName, - password, - }: { - account: AccountEntry; - newAccountName: string; - password: string; - }) => { - setIsLoading(true); - try { - await renameAccount({ accountName: account.id, newAccountName, password }); - setAccounts((accs) => - accs?.map((acc) => (acc.address === account.address ? { ...acc, id: newAccountName } : acc)), - ); - if (selectedAccount?.id === account.id) { - setSelectedAccount({ ...selectedAccount, id: newAccountName }); - } - setDialogToDisplay('Accounts'); - } catch (e) { - throw new Error(`Error editing account: ${e}`); - } finally { - setIsLoading(false); - } - }; - - const handleImportAccount = (account: AccountEntry) => setAccounts((accs) => [...(accs ? [...accs] : []), account]); - - const handleAccountToEdit = (accountName: string | undefined) => - setAccountToEdit(accounts?.find((acc) => acc.id === accountName)); - - const handleSelectAccount = async ({ accountName, password }: { accountName: string; password: string }) => { - try { - await onAccountChange({ accountId: accountName, password }); - const match = accounts?.find((acc) => acc.id === accountName); - setSelectedAccount(match); - return true; - } catch (e) { - setError('Error switching account. Please check your password'); - return false; - } - }; - - const handleGetAccountMnemonic = async ({ password, accountName }: { password: string; accountName: string }) => { - try { - setIsLoading(true); - const mnemonic = await showMnemonicForAccount({ password, accountName }); - setAccountMnemonic({ value: mnemonic, accountName }); - } catch (e) { - setError(e as string); - } finally { - setIsLoading(false); - } - }; - - useEffect(() => { - if (storedAccounts) { - setAccounts(storedAccounts); - } - - if (storedAccounts && !selectedAccount) { - setSelectedAccount(storedAccounts[0]); - } - }, [storedAccounts]); - - return ( - ({ - error, - setError, - accounts, - selectedAccount, - accountToEdit, - dialogToDisplay, - accountMnemonic, - setDialogToDisplay, - setAccountMnemonic, - isLoading, - handleAddAccount, - handleEditAccount, - handleAccountToEdit, - handleSelectAccount, - handleImportAccount, - handleGetAccountMnemonic, - }), - [accounts, selectedAccount, accountToEdit, dialogToDisplay, isLoading, error, accountMnemonic], - )} - > - {children} - - ); -}; diff --git a/explorer/src/components/Delegations/context/buy.tsx b/explorer/src/components/Delegations/context/buy.tsx deleted file mode 100644 index 96e6893731..0000000000 --- a/explorer/src/components/Delegations/context/buy.tsx +++ /dev/null @@ -1,59 +0,0 @@ -import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react'; -import { sign } from '../requests'; -import { Console } from '../utils/console'; -// import { AppContext } from './main'; - -export type TBuyContext = { - loading: boolean; - error?: string; - signMessage: (message: string) => Promise; - refresh: () => Promise; -}; - -export const BuyContext = createContext({ - loading: false, - signMessage: async () => '', - refresh: async () => undefined, -}); - -export const BuyContextProvider: FCWithChildren = ({ children }): JSX.Element => { - const [loading, setLoading] = useState(false); - const [error, setError] = useState(); - - const refresh = useCallback(async () => { - setError(undefined); - }, []); - - useEffect(() => { - refresh(); - }, [refresh]); - - const signMessage = async (message: string) => { - let signature; - setLoading(true); - try { - signature = await sign(message); - } catch (e: any) { - Console.log(`Sign message operation failed: ${e}`); - console.log('`Sign message operation failed: ${e}` :>> ', `Sign message operation failed: ${e}`); - setError(`Sign message operation failed: ${e}`); - } finally { - setLoading(false); - } - return signature; - }; - - const memoizedValue = useMemo( - () => ({ - loading, - error, - refresh, - signMessage, - }), - [loading, error], - ); - - return {children}; -}; - -export const useBuyContext = () => useContext(BuyContext); diff --git a/explorer/src/components/Delegations/context/index.tsx b/explorer/src/components/Delegations/context/index.tsx deleted file mode 100644 index 9983022728..0000000000 --- a/explorer/src/components/Delegations/context/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export * from './main'; -export * from './accounts'; -export * from './buy'; diff --git a/explorer/src/components/Delegations/context/main.tsx b/explorer/src/components/Delegations/context/main.tsx deleted file mode 100644 index 8653234cbb..0000000000 --- a/explorer/src/components/Delegations/context/main.tsx +++ /dev/null @@ -1,366 +0,0 @@ -import React, { createContext, useEffect, useMemo, useState } from 'react'; -import { forage } from '@tauri-apps/tauri-forage'; -import { useNavigate } from 'react-router-dom'; -import { useSnackbar } from 'notistack'; -import { Account, AccountEntry, MixNodeDetails } from '@nymproject/types'; -import { getVersion } from '@tauri-apps/api/app'; -import { AppEnv, Network } from '../types'; -import { TUseuserBalance, useGetBalance } from '../hooks/useGetBalance'; -import { - getEnv, - getMixnodeBondDetails, - listAccounts, - selectNetwork, - signInWithMnemonic, - signInWithPassword, - signOut, - switchAccount, -} from '../requests'; -import Big from 'big.js'; - -import { Console } from '../utils/console'; -import { createSignInWindow, getReactState, setReactState } from '../requests/app'; -// import { toDisplay } from '../utils'; - -const toDisplay = (val: string | number | Big, dp = 4) => { - let displayValue; - try { - displayValue = Big(val).toFixed(dp); - } catch (e: any) { - Console.warn(`${displayValue} not a valid decimal number: ${e}`); - } - return displayValue; -}; - -export const urls = (networkName?: Network) => - networkName === 'MAINNET' - ? { - mixnetExplorer: 'https://mixnet.explorers.guru/', - blockExplorer: 'https://blocks.nymtech.net', - networkExplorer: 'https://explorer.nymtech.net', - } - : { - blockExplorer: `https://${networkName}-blocks.nymtech.net`, - networkExplorer: `https://${networkName}-explorer.nymtech.net`, - }; - -type TLoginType = 'mnemonic' | 'password'; - -export type TAppContext = { - mode: 'light' | 'dark'; - appEnv?: AppEnv; - appVersion?: string; - clientDetails?: Account; - storedAccounts?: AccountEntry[]; - mixnodeDetails?: MixNodeDetails | null; - userBalance: TUseuserBalance; - showAdmin: boolean; - showTerminal: boolean; - network?: Network; - isLoading: boolean; - isAdminAddress: boolean; - error?: string; - loginType?: TLoginType; - showSendModal: boolean; - showReceiveModal: boolean; - onAccountChange: ({ accountId, password }: { accountId: string; password: string }) => void; - handleSwitchMode: () => void; - handleShowSendModal: () => void; - handleShowReceiveModal: () => void; - setIsLoading: (isLoading: boolean) => void; - setError: (value?: string) => void; - switchNetwork: (network: Network) => void; - getBondDetails: () => Promise; - handleShowAdmin: () => void; - logIn: (opts: { type: TLoginType; value: string }) => void; - handleShowTerminal: () => void; - signInWithPassword: (password: string) => void; - logOut: () => void; - keepState: () => Promise; - printBalance: string; - printVestedBalance?: string; // spendable vested token -}; - -interface RustState { - network?: Network; - loginType?: 'mnemonic' | 'password'; -} - -export const AppContext = createContext({} as TAppContext); - -export const AppProvider: FCWithChildren = ({ children }) => { - const [clientDetails, setClientDetails] = useState(); - const [storedAccounts, setStoredAccounts] = useState(); - const [mixnodeDetails, setMixnodeDetails] = useState(null); - const [network, setNetwork] = useState(); - const [appEnv, setAppEnv] = useState(); - const [showAdmin, setShowAdmin] = useState(false); - const [showTerminal, setShowTerminal] = useState(false); - const [mode, setMode] = useState<'light' | 'dark'>('light'); - const [loginType, setLoginType] = useState<'mnemonic' | 'password'>(); - const [isLoading, setIsLoading] = useState(false); - const [error, setError] = useState(); - const [appVersion, setAppVersion] = useState(); - const [isAdminAddress, setIsAdminAddress] = useState(false); - const [showSendModal, setShowSendModal] = useState(false); - const [showReceiveModal, setShowReceiveModal] = useState(false); - const [printBalance, setPrintBalance] = useState('-'); - const [printVestedBalance, setPrintVestedBalance] = useState(); - - const userBalance = useGetBalance(clientDetails); - const navigate = useNavigate(); - const { enqueueSnackbar } = useSnackbar(); - - const initFromRustState = async () => { - const stateJson = await getReactState(); - if (stateJson) { - const state: RustState = JSON.parse(stateJson); - setNetwork(state.network); - setLoginType(state.loginType); - } - }; - - useEffect(() => { - initFromRustState(); - }, []); - - const keepState = async () => { - // add any state from this context to store in the Rust process - const state: RustState = { - network, - loginType, - }; - setReactState(JSON.stringify(state)); - }; - - const clearState = () => { - userBalance.clearAll(); - setStoredAccounts(undefined); - setNetwork(undefined); - setError(undefined); - setIsLoading(false); - setMixnodeDetails(null); - }; - - const loadAccount = async (n: Network) => { - try { - const client = await selectNetwork(n); - setClientDetails(client); - } catch (e) { - enqueueSnackbar('Error loading account', { variant: 'error' }); - Console.error(e as string); - } - }; - - const loadStoredAccounts = async () => { - const accounts = await listAccounts(); - setStoredAccounts(accounts); - }; - - const getBondDetails = async () => { - setMixnodeDetails(null); - try { - const mixnode = await getMixnodeBondDetails(); - setMixnodeDetails(mixnode); - } catch (e) { - Console.error(e as string); - } - }; - - const refreshAccount = async (_network: Network) => { - await loadAccount(_network); - if (loginType === 'password') { - await loadStoredAccounts(); - } - }; - - const getModeFromStorage = async () => { - try { - const modeFromStorage = await forage.getItem({ key: 'nym-wallet-mode' })(); - if (modeFromStorage) setMode(modeFromStorage); - } catch (e) { - Console.error(e); - } - }; - - const setModeInStorage = async (newMode: 'light' | 'dark') => { - await forage.setItem({ - key: 'nym-wallet-mode', - value: newMode, - })(); - }; - - useEffect(() => { - getVersion().then(setAppVersion); - getModeFromStorage(); - }, []); - - useEffect(() => { - if (!clientDetails) { - clearState(); - navigate('/'); - } - }, [clientDetails]); - - useEffect(() => { - if (network) { - refreshAccount(network); - getEnv().then(setAppEnv); - } - }, [network]); - - useEffect(() => { - const currency = clientDetails?.display_mix_denom.toUpperCase() || 'NYM'; - if (userBalance.originalVesting) { - setPrintVestedBalance(`${toDisplay(userBalance.tokenAllocation?.spendableVestedCoins || 0)} ${currency}`); - } - if (userBalance?.balance?.amount) { - setPrintBalance(`${toDisplay(userBalance.balance.amount.amount)} ${currency}`); - } else { - setPrintBalance(`${toDisplay(0)} ${currency}`); - } - }, [userBalance, clientDetails]); - - useEffect(() => { - let newValue = false; - if (network && appEnv?.ADMIN_ADDRESS && clientDetails?.client_address) { - try { - const adminAddressMap = JSON.parse(appEnv.ADMIN_ADDRESS); - const adminAddresses = adminAddressMap[network] || []; - if (adminAddresses.length) { - newValue = adminAddresses.includes(clientDetails?.client_address); - if (newValue) { - Console.log('Wallet is in admin mode: ', { - network, - adminAddress: adminAddressMap[network], - clientAddress: clientDetails?.client_address, - }); - } - } - } catch (e) { - Console.error('Failed to check admin addresses', e); - } - } - setIsAdminAddress(newValue); - }, [appEnv, network, clientDetails?.client_address]); - - const logIn = async ({ type, value }: { type: TLoginType; value: string }) => { - if (value.length === 0) { - setError(`A ${type} must be provided`); - return; - } - try { - setIsLoading(true); - if (type === 'mnemonic') { - await signInWithMnemonic(value); - setLoginType('mnemonic'); - } else { - await signInWithPassword(value); - setLoginType('password'); - } - setNetwork('MAINNET'); - navigate('/balance'); - } catch (e) { - setError(e as string); - } finally { - setIsLoading(false); - } - }; - - const logOut = async () => { - setIsLoading(true); - try { - await signOut(); - await setReactState(undefined); - setClientDetails(undefined); - enqueueSnackbar('Successfully logged out', { variant: 'success' }); - await createSignInWindow(); - } finally { - setIsLoading(false); - } - }; - - const onAccountChange = async ({ accountId, password }: { accountId: string; password: string }) => { - if (network) { - setIsLoading(true); - try { - await switchAccount({ accountId, password }); - await loadAccount(network); - enqueueSnackbar('Account switch success', { variant: 'success', preventDuplicate: true }); - } catch (e) { - throw new Error(`Error swtiching account: ${e}`); - } finally { - setIsLoading(false); - } - } - }; - - const handleShowAdmin = () => setShowAdmin((show) => !show); - const handleShowTerminal = () => setShowTerminal((show) => !show); - const switchNetwork = (_network: Network) => setNetwork(_network); - const handleShowSendModal = () => setShowSendModal((show) => !show); - const handleShowReceiveModal = () => setShowReceiveModal((show) => !show); - const handleSwitchMode = () => - setMode((currentMode) => { - const newMode = currentMode === 'light' ? 'dark' : 'light'; - setModeInStorage(newMode); - return newMode; - }); - - const memoizedValue = useMemo( - () => ({ - mode, - appEnv, - appVersion, - isAdminAddress, - isLoading, - error, - clientDetails, - storedAccounts, - mixnodeDetails, - userBalance, - showAdmin, - showTerminal, - network, - loginType, - setIsLoading, - setError, - signInWithPassword, - switchNetwork, - getBondDetails, - handleShowAdmin, - handleShowTerminal, - logIn, - logOut, - keepState, - onAccountChange, - showSendModal, - showReceiveModal, - handleShowSendModal, - handleShowReceiveModal, - handleSwitchMode, - printBalance, - printVestedBalance, - }), - [ - appVersion, - loginType, - isAdminAddress, - mode, - appEnv, - isLoading, - error, - clientDetails, - mixnodeDetails, - userBalance, - showAdmin, - network, - storedAccounts, - showTerminal, - showSendModal, - showReceiveModal, - ], - ); - - return {children}; -}; diff --git a/explorer/src/components/Delegations/hooks/useCheckOwnership.ts b/explorer/src/components/Delegations/hooks/useCheckOwnership.ts deleted file mode 100644 index ef171c43e1..0000000000 --- a/explorer/src/components/Delegations/hooks/useCheckOwnership.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { useCallback, useContext, useEffect, useState } from 'react'; -import { Console } from '../utils/console'; -// eslint-disable-next-line import/no-cycle -import { AppContext } from '../context/main'; -import { checkGatewayOwnership, checkMixnodeOwnership, getVestingPledgeInfo } from '../requests'; -import { EnumNodeType, TNodeOwnership } from '../types'; - -const initial: TNodeOwnership = { - hasOwnership: false, - nodeType: undefined, - vestingPledge: undefined, -}; - -export const useCheckOwnership = () => { - const { clientDetails } = useContext(AppContext); - - const [ownership, setOwnership] = useState(initial); - const [isLoading, setIsLoading] = useState(true); - const [error, setError] = useState(); - - const checkOwnership = useCallback(async () => { - const status = { ...initial }; - try { - const [ownsMixnode, ownsGateway] = await Promise.all([checkMixnodeOwnership(), checkGatewayOwnership()]); - - if (ownsMixnode) { - status.hasOwnership = true; - status.nodeType = EnumNodeType.mixnode; - status.vestingPledge = await getVestingPledgeInfo({ - address: clientDetails?.client_address!, - type: EnumNodeType.mixnode, - }); - } - - if (ownsGateway) { - status.hasOwnership = true; - status.nodeType = EnumNodeType.gateway; - status.vestingPledge = await getVestingPledgeInfo({ - address: clientDetails?.client_address!, - type: EnumNodeType.gateway, - }); - } - - setOwnership(status); - } catch (e) { - Console.error(e as string); - setError(e as string); - setOwnership(initial); - } finally { - setIsLoading(false); - } - }, [clientDetails]); - - useEffect(() => { - checkOwnership(); - }, [clientDetails]); - - return { isLoading, error, ownership, checkOwnership }; -}; diff --git a/explorer/src/components/Delegations/hooks/useGetBalance.ts b/explorer/src/components/Delegations/hooks/useGetBalance.ts deleted file mode 100644 index b23eaf1a34..0000000000 --- a/explorer/src/components/Delegations/hooks/useGetBalance.ts +++ /dev/null @@ -1,147 +0,0 @@ -/* eslint-disable import/no-cycle */ -import { useCallback, useEffect, useState } from 'react'; -import { Account, Balance, DecCoin, OriginalVestingResponse, Period, VestingAccountInfo } from '@nymproject/types'; -import { - getVestingCoins, - getVestedCoins, - getLockedCoins, - getSpendableCoins, - getOriginalVesting, - getCurrentVestingPeriod, - getVestingAccountInfo, - getSpendableRewardCoins, - getSpendableVestedCoins, - userBalance, -} from '../requests'; -import { Console } from '../utils/console'; - -type TTokenAllocation = { - [key in - | 'vesting' - | 'vested' - | 'locked' - | 'spendable' - | 'spendableRewardCoins' - | 'spendableVestedCoins']: DecCoin['amount']; -}; - -export type TUseuserBalance = { - error?: string; - balance?: Balance; - tokenAllocation?: TTokenAllocation; - originalVesting?: OriginalVestingResponse; - currentVestingPeriod?: Period; - vestingAccountInfo?: VestingAccountInfo; - isLoading: boolean; - fetchBalance: () => Promise; - fetchTokenAllocation: () => Promise; - clearBalance: () => void; - clearAll: () => void; - refreshBalances: () => Promise; -}; - -export const useGetBalance = (clientDetails?: Account): TUseuserBalance => { - const [balance, setBalance] = useState(); - const [error, setError] = useState(); - const [tokenAllocation, setTokenAllocation] = useState(); - const [originalVesting, setOriginalVesting] = useState(); - const [currentVestingPeriod, setCurrentVestingPeriod] = useState(); - const [vestingAccountInfo, setVestingAccountInfo] = useState(); - const [isLoading, setIsLoading] = useState(false); - - const clearBalance = () => setBalance(undefined); - const clearTokenAllocation = () => setTokenAllocation(undefined); - const clearOriginalVesting = () => setOriginalVesting(undefined); - - const fetchTokenAllocation = async () => { - setIsLoading(true); - if (clientDetails?.client_address) { - try { - const [ - originalVestingValue, - vestingCoins, - vestedCoins, - lockedCoins, - spendableCoins, - spendableVestedCoins, - spendableRewardCoins, - currentPeriod, - vestingAccountDetail, - ] = await Promise.all([ - getOriginalVesting(clientDetails?.client_address), - getVestingCoins(clientDetails?.client_address), - getVestedCoins(clientDetails?.client_address), - getLockedCoins(), - getSpendableCoins(), - getSpendableVestedCoins(), - getSpendableRewardCoins(), - getCurrentVestingPeriod(clientDetails?.client_address), - getVestingAccountInfo(clientDetails?.client_address), - ]); - setOriginalVesting(originalVestingValue); - setCurrentVestingPeriod(currentPeriod); - setTokenAllocation({ - vesting: vestingCoins.amount, - vested: vestedCoins.amount, - locked: lockedCoins.amount, - spendable: spendableCoins.amount, - spendableVestedCoins: spendableVestedCoins.amount, - spendableRewardCoins: spendableRewardCoins.amount, - }); - setVestingAccountInfo(vestingAccountDetail); - } catch (e) { - clearTokenAllocation(); - clearOriginalVesting(); - Console.error(e as string); - } - } - setIsLoading(false); - }; - - const fetchBalance = useCallback(async () => { - setIsLoading(true); - setError(undefined); - try { - const bal = await userBalance(); - setBalance(bal); - } catch (err) { - setError(err as string); - } finally { - setIsLoading(false); - } - }, []); - - const clearAll = () => { - clearBalance(); - clearTokenAllocation(); - clearOriginalVesting(); - }; - - const refreshBalances = async () => { - if (clientDetails?.client_address) { - await fetchBalance(); - await fetchTokenAllocation(); - } else { - clearAll(); - } - }; - - useEffect(() => { - refreshBalances(); - }, [clientDetails]); - - return { - error, - isLoading, - balance, - tokenAllocation, - originalVesting, - currentVestingPeriod, - vestingAccountInfo, - fetchBalance, - clearBalance, - clearAll, - fetchTokenAllocation, - refreshBalances, - }; -}; diff --git a/explorer/src/components/Delegations/hooks/useGetFee.ts b/explorer/src/components/Delegations/hooks/useGetFee.ts deleted file mode 100644 index 081493f4ca..0000000000 --- a/explorer/src/components/Delegations/hooks/useGetFee.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { DecCoin, FeeDetails } from '@nymproject/types'; -import { useState } from 'react'; -import { Console } from '../utils/console'; -import { getCustomFees } from '../requests'; - -export function useGetFee() { - const [fee, setFee] = useState(); - const [isFeeLoading, setIsFeeLoading] = useState(false); - const [feeError, setFeeError] = useState(); - - async function getFee(operation: (args: T) => Promise, args: T) { - try { - setIsFeeLoading(true); - const simulatedFee = await operation(args); - setFee(simulatedFee); - } catch (e) { - // Console.error(e); - setFeeError(e as string); - } - setIsFeeLoading(false); - } - - async function setFeeManually(amount: DecCoin) { - try { - setIsFeeLoading(true); - const fees = await getCustomFees({ feesAmount: amount }); - setFee(fees); - } catch (e) { - Console.error(e); - setFeeError(e as string); - } - setIsFeeLoading(false); - } - - const resetFeeState = () => { - setFee(undefined); - setIsFeeLoading(false); - setFeeError(undefined); - }; - - return { - fee, - isFeeLoading, - feeError, - getFee, - setFeeManually, - resetFeeState, - }; -} diff --git a/explorer/src/components/Delegations/hooks/useKeyPress.ts b/explorer/src/components/Delegations/hooks/useKeyPress.ts deleted file mode 100644 index 73eb81598e..0000000000 --- a/explorer/src/components/Delegations/hooks/useKeyPress.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useState, useEffect } from 'react'; - -export function useKeyPress(targetKey: string): boolean { - // State for keeping track of whether key is pressed - const [keyPressed, setKeyPressed] = useState(false); - // If pressed key is our target key then set to true - function downHandler({ key }: { key: string }): void { - if (key === targetKey) { - setKeyPressed(true); - } - } - // If released key is our target key then set to false - const upHandler = ({ key }: { key: string }): void => { - if (key === targetKey) { - setKeyPressed(false); - } - }; - // Add event listeners - useEffect(() => { - window.addEventListener('keydown', downHandler); - window.addEventListener('keyup', upHandler); - // Remove event listeners on cleanup - return () => { - window.removeEventListener('keydown', downHandler); - window.removeEventListener('keyup', upHandler); - }; - }, []); // Empty array ensures that effect is only run on mount and unmount - return keyPressed; -} diff --git a/explorer/src/components/Delegations/requests/account.ts b/explorer/src/components/Delegations/requests/account.ts deleted file mode 100644 index daf150afd1..0000000000 --- a/explorer/src/components/Delegations/requests/account.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { Account, Balance, AccountEntry } from '@nymproject/types'; -import { invokeWrapper } from './wrapper'; - -export const signInWithMnemonic = async (mnemonic: string): Promise => - invokeWrapper('connect_with_mnemonic', { mnemonic }); - -export const userBalance = async () => invokeWrapper('get_balance'); - -export const createMnemonic = async () => invokeWrapper('create_new_mnemonic'); - -export const validateMnemonic = async (mnemonic: string) => invokeWrapper('validate_mnemonic', { mnemonic }); - -export const signOut = async () => invokeWrapper('logout'); - -export const isPasswordCreated = async () => invokeWrapper('does_password_file_exist'); - -export const createPassword = async ({ mnemonic, password }: { mnemonic: string; password: string }) => - invokeWrapper('create_password', { mnemonic, password }); - -export const updatePassword = async ({ - currentPassword, - newPassword, -}: { - currentPassword: string; - newPassword: string; -}) => invokeWrapper('update_password', { currentPassword, newPassword }); - -export const signInWithPassword = async (password: string) => - invokeWrapper('sign_in_with_password', { password }); - -export const switchAccount = async ({ accountId, password }: { accountId: string; password: string }) => - invokeWrapper('sign_in_with_password_and_account_id', { accountId, password }); - -export const addAccount = async ({ - mnemonic, - password, - accountName, -}: { - mnemonic: string; - password: string; - accountName: string; -}) => invokeWrapper('add_account_for_password', { mnemonic, password, accountId: accountName }); - -export const removeAccount = async ({ password, accountName }: { password: string; accountName: string }) => - invokeWrapper('remove_account_for_password', { password, innerId: accountName }); - -export const listAccounts = async () => invokeWrapper('list_accounts'); - -export const archiveWalletFile = async () => invokeWrapper('archive_wallet_file'); - -export const showMnemonicForAccount = async ({ password, accountName }: { password: string; accountName: string }) => - invokeWrapper('show_mnemonic_for_account_in_password', { password, accountId: accountName }); - -export const renameAccount = async ({ - password, - accountName, - newAccountName, -}: { - password: string; - accountName: string; - newAccountName: string; -}) => - invokeWrapper('rename_account_for_password', { - password, - accountId: accountName, - newAccountId: newAccountName, - }); diff --git a/explorer/src/components/Delegations/requests/actions.ts b/explorer/src/components/Delegations/requests/actions.ts deleted file mode 100644 index cf09085d5f..0000000000 --- a/explorer/src/components/Delegations/requests/actions.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { - Fee, - DecCoin, - SendTxResult, - TransactionExecuteResult, - MixNodeConfigUpdate, - MixNodeCostParams, - GatewayConfigUpdate, -} from '@nymproject/types'; -import { - EnumNodeType, - TBondGatewayArgs, - TBondGatewaySignatureArgs, - TBondMixNodeArgs, - TBondMixnodeSignatureArgs, - TUpdateBondArgs, -} from '../types'; -import { invokeWrapper } from './wrapper'; - -export const bondGateway = async (args: TBondGatewayArgs) => - invokeWrapper('bond_gateway', args); - -export const generateGatewayMsgPayload = async (args: Omit) => - invokeWrapper('generate_gateway_bonding_msg_payload', args); - -export const unbondGateway = async (fee?: Fee) => invokeWrapper('unbond_gateway', { fee }); - -export const bondMixNode = async (args: TBondMixNodeArgs) => - invokeWrapper('bond_mixnode', args); - -export const generateMixnodeMsgPayload = async (args: Omit) => - invokeWrapper('generate_mixnode_bonding_msg_payload', args); - -export const unbondMixNode = async (fee?: Fee) => invokeWrapper('unbond_mixnode', { fee }); - -export const updateMixnodeCostParams = async (newCosts: MixNodeCostParams, fee?: Fee) => - invokeWrapper('update_mixnode_cost_params', { newCosts, fee }); - -export const updateMixnodeConfig = async (update: MixNodeConfigUpdate, fee?: Fee) => - invokeWrapper('update_mixnode_config', { update, fee }); - -export const updateGatewayConfig = async (update: GatewayConfigUpdate, fee?: Fee) => - invokeWrapper('update_gateway_config', { update, fee }); - -export const send = async (args: { amount: DecCoin; address: string; memo: string; fee?: Fee }) => - invokeWrapper('send', args); - -export const unbond = async (type: EnumNodeType) => { - if (type === EnumNodeType.mixnode) return unbondMixNode(); - return unbondGateway(); -}; - -export const updateBond = async (args: TUpdateBondArgs) => - invokeWrapper('update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/app.ts b/explorer/src/components/Delegations/requests/app.ts deleted file mode 100644 index acecfa8f25..0000000000 --- a/explorer/src/components/Delegations/requests/app.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { invokeWrapper } from './wrapper'; -import { AppVersion } from '../types/rust/AppVersion'; - -export const checkVersion = async () => invokeWrapper('check_version'); - -export const createMainWindow = async (): Promise => invokeWrapper('create_main_window'); - -export const createSignInWindow = async (): Promise => invokeWrapper('create_auth_window'); - -export const setReactState = async (newState?: string): Promise => - invokeWrapper('set_react_state', { newState }); - -export const getReactState = async (): Promise => - invokeWrapper('get_react_state'); diff --git a/explorer/src/components/Delegations/requests/contract.ts b/explorer/src/components/Delegations/requests/contract.ts deleted file mode 100644 index eb5a863bcc..0000000000 --- a/explorer/src/components/Delegations/requests/contract.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { TauriContractStateParams } from '../types'; -import { invokeWrapper } from './wrapper'; - -export const getContractParams = async () => invokeWrapper('get_contract_settings'); - -export const setContractParams = async (params: TauriContractStateParams) => - invokeWrapper('update_contract_settings', { params }); diff --git a/explorer/src/components/Delegations/requests/delegation.ts b/explorer/src/components/Delegations/requests/delegation.ts deleted file mode 100644 index d68d8a9084..0000000000 --- a/explorer/src/components/Delegations/requests/delegation.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { - DelegationWithEverything, - DelegationsSummaryResponse, - TransactionExecuteResult, - DecCoin, - FeeDetails, - Fee, -} from '@nymproject/types'; -import { invokeWrapper } from './wrapper'; - -export const getMixNodeDelegationsForCurrentAccount = async () => - invokeWrapper('get_all_mix_delegations'); - -export const getDelegationSummary = async () => invokeWrapper('get_delegation_summary'); - -export const undelegateFromMixnode = async (mixId: number, fee?: Fee) => - invokeWrapper('undelegate_from_mixnode', { mixId, fee }); - -export const undelegateAllFromMixnode = async ( - mixId: number, - usesVestingContractTokens: boolean, - fee_liquid?: FeeDetails, - fee_vesting?: FeeDetails, -) => - invokeWrapper('undelegate_all_from_mixnode', { - mixId, - usesVestingContractTokens, - fee_liquid, - fee_vesting, - }); - -export const delegateToMixnode = async (mixId: number, amount: DecCoin, fee?: Fee) => - invokeWrapper('delegate_to_mixnode', { mixId, amount, fee }); diff --git a/explorer/src/components/Delegations/requests/index.ts b/explorer/src/components/Delegations/requests/index.ts deleted file mode 100644 index e6fb5e482c..0000000000 --- a/explorer/src/components/Delegations/requests/index.ts +++ /dev/null @@ -1,14 +0,0 @@ -export * from './app'; -export * from './account'; -export * from './actions'; -export * from './contract'; -export * from './delegation'; -export * from './logging'; -export * from './network'; -export * from './queries'; -export * from './rewards'; -export * from './signature'; -export * from './simulate'; -export * from './utils'; -export * from './vesting'; -export * from './pendingEvents'; diff --git a/explorer/src/components/Delegations/requests/logging.ts b/explorer/src/components/Delegations/requests/logging.ts deleted file mode 100644 index 307f65d672..0000000000 --- a/explorer/src/components/Delegations/requests/logging.ts +++ /dev/null @@ -1,3 +0,0 @@ -import { invokeWrapper } from './wrapper'; - -export const helpLogToggleWindow = async () => invokeWrapper('help_log_toggle_window', {}); diff --git a/explorer/src/components/Delegations/requests/network.ts b/explorer/src/components/Delegations/requests/network.ts deleted file mode 100644 index 248207e616..0000000000 --- a/explorer/src/components/Delegations/requests/network.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Account } from '@nymproject/types'; -import { Network } from '../types'; -import { invokeWrapper } from './wrapper'; - -export const selectNetwork = async (network: Network) => invokeWrapper('switch_network', { network }); - -export const getSelectedValidatorUrl = async (network: Network) => - invokeWrapper('get_selected_nyxd_url', { network }); - -export const getDefaultValidatorUrl = async (network: Network) => - invokeWrapper('get_default_nyxd_url', { network }); - -export const setSelectedValidatorUrl = async (args: { network: Network; url: string }) => - invokeWrapper('select_nyxd_url', args); - -export const resetValidatorUrl = async (network: Network) => invokeWrapper('reset_nyxd_url', { network }); diff --git a/explorer/src/components/Delegations/requests/pendingEvents.ts b/explorer/src/components/Delegations/requests/pendingEvents.ts deleted file mode 100644 index c92954a237..0000000000 --- a/explorer/src/components/Delegations/requests/pendingEvents.ts +++ /dev/null @@ -1,4 +0,0 @@ -import { PendingEpochEvent } from '@nymproject/types'; -import { invokeWrapper } from './wrapper'; - -export const getPendingEpochEvents = async () => invokeWrapper('get_pending_epoch_events'); diff --git a/explorer/src/components/Delegations/requests/queries.ts b/explorer/src/components/Delegations/requests/queries.ts deleted file mode 100644 index 63004176ac..0000000000 --- a/explorer/src/components/Delegations/requests/queries.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { - DecCoin, - GatewayBond, - InclusionProbabilityResponse, - MixNodeDetails, - MixnodeStatusResponse, - PendingIntervalEvent, - RewardEstimationResponse, - StakeSaturationResponse, - WrappedDelegationEvent, -} from '@nymproject/types'; -import { Interval, TGatewayReport, TNodeDescription } from '../types'; -import { invokeWrapper } from './wrapper'; - -export const getAllPendingDelegations = async () => - invokeWrapper('get_pending_delegation_events'); - -export const getMixnodeBondDetails = async () => invokeWrapper('mixnode_bond_details'); -export const getGatewayBondDetails = async () => invokeWrapper('gateway_bond_details'); -export const getMixnodeAvgUptime = async () => invokeWrapper('get_mixnode_avg_uptime'); - -export const getPendingOperatorRewards = async (address: string) => - invokeWrapper('get_pending_operator_rewards', { address }); - -export const getMixnodeStakeSaturation = async (mixId: number) => - invokeWrapper('mixnode_stake_saturation', { mixId }); - -export const getMixnodeRewardEstimation = async (mixId: number) => - invokeWrapper('mixnode_reward_estimation', { mixId }); - -export const getMixnodeStatus = async (mixId: number) => - invokeWrapper('mixnode_status', { mixId }); - -export const checkMixnodeOwnership = async () => invokeWrapper('owns_mixnode'); - -export const checkGatewayOwnership = async () => invokeWrapper('owns_gateway'); - -export const getInclusionProbability = async (mixId: number) => - invokeWrapper('mixnode_inclusion_probability', { mixId }); - -export const getCurrentInterval = async () => invokeWrapper('get_current_interval'); - -export const getNumberOfMixnodeDelegators = async (mixId: number) => - invokeWrapper('get_number_of_mixnode_delegators', { mixId }); - -export const getNodeDescription = async (host: string, port: number) => - invokeWrapper('get_mix_node_description', { host, port }); - -export const getPendingIntervalEvents = async () => - invokeWrapper('get_pending_interval_events'); - -export const getGatewayReport = async (identity: string) => - invokeWrapper('gateway_report', { identity }); - -export const computeMixnodeRewardEstimation = async (args: { - mixId: number; - performance: string; - pledgeAmount: number; - totalDelegation: number; - profitMarginPercent: string; - intervalOperatingCost: { denom: 'unym'; amount: string }; -}) => invokeWrapper('compute_mixnode_reward_estimation', args); -export const getMixnodeUptime = async (mixId: number) => invokeWrapper('get_mixnode_uptime', { mixId }); diff --git a/explorer/src/components/Delegations/requests/rewards.ts b/explorer/src/components/Delegations/requests/rewards.ts deleted file mode 100644 index 36b90838e7..0000000000 --- a/explorer/src/components/Delegations/requests/rewards.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { Fee, FeeDetails, RewardingParams, TransactionExecuteResult } from '@nymproject/types'; -import { invokeWrapper } from './wrapper'; - -export const claimOperatorReward = async (fee?: Fee) => - invokeWrapper('claim_operator_reward', { fee }); - -export const claimDelegatorRewards = async (mixId: number, fee?: FeeDetails) => - invokeWrapper('claim_locked_and_unlocked_delegator_reward', { - mixId, - fee: fee?.fee, - }); - -export const getCurrentRewardingParameter = async () => - invokeWrapper('get_current_rewarding_parameters', {}); diff --git a/explorer/src/components/Delegations/requests/signature.ts b/explorer/src/components/Delegations/requests/signature.ts deleted file mode 100644 index cf36289088..0000000000 --- a/explorer/src/components/Delegations/requests/signature.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { invokeWrapper } from './wrapper'; - -export const sign = async (message: string): Promise => invokeWrapper('sign', { message }); - -export const verify = async ( - signatureAsHex: string, - message: string, - publicKeyAsJsonOrAccountAddress?: string | null, -): Promise => invokeWrapper('verify', { publicKeyAsJsonOrAccountAddress, signatureAsHex, message }); diff --git a/explorer/src/components/Delegations/requests/simulate.ts b/explorer/src/components/Delegations/requests/simulate.ts deleted file mode 100644 index d5dfdb3a43..0000000000 --- a/explorer/src/components/Delegations/requests/simulate.ts +++ /dev/null @@ -1,87 +0,0 @@ -import { - FeeDetails, - DecCoin, - Gateway, - MixNodeCostParams, - MixNodeConfigUpdate, - GatewayConfigUpdate, -} from '@nymproject/types'; -import { TBondGatewayArgs, TBondMixNodeArgs, TSimulateUpdateBondArgs } from '../types'; -import { invokeWrapper } from './wrapper'; - -export const simulateBondGateway = async (args: TBondGatewayArgs) => - invokeWrapper('simulate_bond_gateway', args); - -export const simulateUnbondGateway = async (args: any) => invokeWrapper('simulate_unbond_gateway', args); - -export const simulateBondMixnode = async (args: TBondMixNodeArgs) => - invokeWrapper('simulate_bond_mixnode', args); - -export const simulateUnbondMixnode = async (args: any) => invokeWrapper('simulate_unbond_mixnode', args); - -export const simulateUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams) => - invokeWrapper('simulate_update_mixnode_cost_params', { newCosts }); - -export const simulateUpdateMixnodeConfig = async (update: MixNodeConfigUpdate) => - invokeWrapper('simulate_update_mixnode_config', { update }); - -export const simulateUpdateGatewayConfig = async (update: GatewayConfigUpdate) => - invokeWrapper('simulate_update_gateway_config', { update }); - -export const simulateDelegateToMixnode = async (args: { mixId: number; amount: DecCoin }) => - invokeWrapper('simulate_delegate_to_mixnode', args); - -export const simulateUndelegateFromMixnode = async (mixId: number) => - invokeWrapper('simulate_undelegate_from_mixnode', { mixId }); - -export const simulateClaimDelegatorReward = async (mixId: number) => - invokeWrapper('simulate_claim_delegator_reward', { mixId }); - -export const simulateVestingClaimDelegatorReward = async (mixId: number) => - invokeWrapper('simulate_vesting_claim_delegator_reward', { mixId }); - -export const simulateVestingUndelegateFromMixnode = async (args: any) => - invokeWrapper('simulate_vesting_undelegate_from_mixnode', args); - -export const simulateVestingBondGateway = async (args: { gateway: Gateway; pledge: DecCoin; msgSignature: string }) => - invokeWrapper('simulate_vesting_bond_gateway', args); - -export const simulateVestingUnbondGateway = async (args: any) => - invokeWrapper('simulate_vesting_unbond_gateway', args); - -export const simulateVestingDelegateToMixnode = async (args: { mixId: number }) => - invokeWrapper('simulate_vesting_delegate_to_mixnode', args); - -export const simulateVestingBondMixnode = async (args: TBondMixNodeArgs) => - invokeWrapper('simulate_vesting_bond_mixnode', args); - -export const simulateVestingUnbondMixnode = async () => invokeWrapper('simulate_vesting_unbond_mixnode'); - -export const simulateVestingUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams) => - invokeWrapper('simulate_vesting_update_mixnode_cost_params', { newCosts }); - -export const simulateVestingUpdateMixnodeConfig = async (update: MixNodeConfigUpdate) => - invokeWrapper('simulate_vesting_update_mixnode_config', { update }); - -export const simulateVestingUpdateGatewayConfig = async (update: GatewayConfigUpdate) => - invokeWrapper('simulate_vesting_update_gateway_config', { update }); - -export const simulateWithdrawVestedCoins = async (args: any) => - invokeWrapper('simulate_withdraw_vested_coins', args); - -export const simulateSend = async ({ address, amount }: { address: string; amount: DecCoin }) => - invokeWrapper('simulate_send', { address, amount }); - -export const getCustomFees = async ({ feesAmount }: { feesAmount: DecCoin }) => - invokeWrapper('get_custom_fees', { feesAmount }); - -export const simulateClaimOperatorReward = async () => invokeWrapper('simulate_claim_operator_reward'); - -export const simulateVestingClaimOperatorReward = async () => - invokeWrapper('simulate_vesting_claim_operator_reward'); - -export const simulateUpdateBond = async (args: TSimulateUpdateBondArgs) => - invokeWrapper('simulate_update_pledge', args); - -export const simulateVestingUpdateBond = async (args: TSimulateUpdateBondArgs) => - invokeWrapper('simulate_vesting_update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/utils.ts b/explorer/src/components/Delegations/requests/utils.ts deleted file mode 100644 index 0e307d9dc6..0000000000 --- a/explorer/src/components/Delegations/requests/utils.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { MixNodeCostParams } from '@nymproject/types'; -import { AppEnv } from '../types'; -import { invokeWrapper } from './wrapper'; - -export const getEnv = async () => invokeWrapper('get_env'); - -export const tryConvertIdentityToMixId = async (mixIdentity: string) => - invokeWrapper('try_convert_pubkey_to_mix_id', { mixIdentity }); - -export const getDefaultMixnodeCostParams = async (profitMarginPercent: string) => - invokeWrapper('default_mixnode_cost_params', { profitMarginPercent }); diff --git a/explorer/src/components/Delegations/requests/vesting.ts b/explorer/src/components/Delegations/requests/vesting.ts deleted file mode 100644 index 2d13cb4448..0000000000 --- a/explorer/src/components/Delegations/requests/vesting.ts +++ /dev/null @@ -1,125 +0,0 @@ -import { - TNodeType, - Gateway, - DecCoin, - MixNode, - OriginalVestingResponse, - Period, - PledgeData, - TransactionExecuteResult, - VestingAccountInfo, - MixNodeCostParams, - MixNodeConfigUpdate, - GatewayConfigUpdate, -} from '@nymproject/types'; -import { Fee } from '@nymproject/types/dist/types/rust/Fee'; -import { invokeWrapper } from './wrapper'; -import { TBondGatewaySignatureArgs, TBondMixnodeSignatureArgs, TUpdateBondArgs } from '../types'; - -export const getLockedCoins = async (): Promise => invokeWrapper('locked_coins'); - -export const getSpendableCoins = async (): Promise => invokeWrapper('spendable_coins'); - -export const getSpendableVestedCoins = async (): Promise => invokeWrapper('spendable_vested_coins'); - -export const getSpendableRewardCoins = async (): Promise => invokeWrapper('spendable_reward_coins'); - -export const getVestingCoins = async (vestingAccountAddress: string): Promise => - invokeWrapper('vesting_coins', { vestingAccountAddress }); - -export const getVestedCoins = async (vestingAccountAddress: string): Promise => - invokeWrapper('vested_coins', { vestingAccountAddress }); - -export const getOriginalVesting = async (vestingAccountAddress: string): Promise => { - const res = await invokeWrapper('original_vesting', { vestingAccountAddress }); - return { ...res, amount: res.amount }; -}; - -export const getCurrentVestingPeriod = async (address: string) => - invokeWrapper('get_current_vesting_period', { address }); - -export const vestingBondGateway = async ({ - gateway, - pledge, - msgSignature, -}: { - gateway: Gateway; - pledge: DecCoin; - msgSignature: string; -}) => invokeWrapper('vesting_bond_gateway', { gateway, msgSignature, pledge }); - -export const vestingGenerateGatewayMsgPayload = async (args: Omit) => - invokeWrapper('vesting_generate_gateway_bonding_msg_payload', args); - -export const vestingUnbondGateway = async (fee?: Fee) => - invokeWrapper('vesting_unbond_gateway', { fee }); - -export const vestingBondMixNode = async ({ - mixnode, - costParams, - pledge, - msgSignature, -}: { - mixnode: MixNode; - costParams: MixNodeCostParams; - pledge: DecCoin; - msgSignature: string; -}) => invokeWrapper('vesting_bond_mixnode', { mixnode, costParams, msgSignature, pledge }); - -export const vestingGenerateMixnodeMsgPayload = async (args: Omit) => - invokeWrapper('vesting_generate_mixnode_bonding_msg_payload', args); - -export const vestingUnbondMixnode = async (fee?: Fee) => - invokeWrapper('vesting_unbond_mixnode', { fee }); - -export const withdrawVestedCoins = async (amount: DecCoin, fee?: Fee) => - invokeWrapper('withdraw_vested_coins', { amount, fee }); - -export const vestingUpdateMixnodeCostParams = async (newCosts: MixNodeCostParams, fee?: Fee) => - invokeWrapper('vesting_update_mixnode_cost_params', { newCosts, fee }); - -export const vestingUpdateMixnodeConfig = async (update: MixNodeConfigUpdate, fee?: Fee) => - invokeWrapper('vesting_update_mixnode_config', { update, fee }); - -export const vestingUpdateGatewayConfig = async (update: GatewayConfigUpdate, fee?: Fee) => - invokeWrapper('vesting_update_gateway_config', { update, fee }); - -export const vestingDelegateToMixnode = async (mixId: number, amount: DecCoin, fee?: Fee) => - invokeWrapper('vesting_delegate_to_mixnode', { mixId, amount, fee }); - -export const vestingUndelegateFromMixnode = async (mixId: number) => - invokeWrapper('vesting_undelegate_from_mixnode', { mixId }); - -export const getVestingAccountInfo = async (address: string) => - invokeWrapper('get_account_info', { address }); - -export const getVestingPledgeInfo = async ({ - address, - type, -}: { - address?: string; - type: TNodeType; -}): Promise => { - try { - return await invokeWrapper(`vesting_get_${type}_pledge`, { address }); - } catch (e) { - return undefined; - } -}; - -export const vestingDelegatedFree = async (vestingAccountAddress: string) => - invokeWrapper('delegated_free', { vestingAccountAddress }); - -export const vestingUnbond = async (type: TNodeType) => { - if (type === 'mixnode') return vestingUnbondMixnode(); - return vestingUnbondGateway(); -}; - -export const vestingClaimOperatorReward = async (fee?: Fee) => - invokeWrapper('vesting_claim_operator_reward', { fee }); - -export const vestingClaimDelegatorRewards = async (mixId: number) => - invokeWrapper('vesting_claim_delegator_reward', { mixId }); - -export const vestingUpdateBond = async (args: TUpdateBondArgs) => - invokeWrapper('vesting_update_pledge', args); diff --git a/explorer/src/components/Delegations/requests/wrapper.ts b/explorer/src/components/Delegations/requests/wrapper.ts deleted file mode 100644 index 5c9cb97f3a..0000000000 --- a/explorer/src/components/Delegations/requests/wrapper.ts +++ /dev/null @@ -1,20 +0,0 @@ -import { invoke } from '@tauri-apps/api'; -import { config } from '../config'; -import { Console } from '../utils/console'; - -export async function invokeWrapper(operationName: string, args?: any): Promise { - const res = await invoke(operationName, args); - if (config.LOG_TAURI_OPERATIONS) { - const argsToLog: any = {}; - if (args) { - Object.keys(args).forEach((key) => { - // check if the key should be excluded from logs - if (!['mnemonic', 'password', 'currentPassword', 'newPassword'].includes(key)) { - argsToLog[key] = args[key]; - } - }); - } - Console.log({ operationName, argsToLog, res }); - } - return res; -} diff --git a/explorer/src/components/Delegations/types/global.ts b/explorer/src/components/Delegations/types/global.ts deleted file mode 100644 index aaf9d56b2e..0000000000 --- a/explorer/src/components/Delegations/types/global.ts +++ /dev/null @@ -1,97 +0,0 @@ -import { DecCoin, Gateway, MixNode, MixNodeCostParams, PledgeData } from '@nymproject/types'; -import { Fee } from '@nymproject/types/dist/types/rust/Fee'; -// eslint-disable-next-line import/no-cycle -// import { TBondedGateway, TBondedMixnode } from '../context'; - -export enum EnumNodeType { - mixnode = 'mixnode', - gateway = 'gateway', -} - -export type TNodeOwnership = { - hasOwnership: boolean; - nodeType?: EnumNodeType; - vestingPledge?: PledgeData; -}; - -export type TPendingDelegation = { - block_height: number; -}; - -export type TDelegation = { - owner: string; - node_identity: string; - amount: DecCoin; - block_height: number; - proxy: string; // proxy address used to delegate the funds on behalf of another address - pending?: TPendingDelegation; -}; - -export type TBondGatewayArgs = { - gateway: Gateway; - pledge: DecCoin; - msgSignature: string; - fee?: Fee; -}; - -export type TBondMixNodeArgs = { - mixnode: MixNode; - costParams: MixNodeCostParams; - pledge: DecCoin; - msgSignature: string; - fee?: Fee; -}; - -export type TBondMixnodeSignatureArgs = { - mixnode: MixNode; - costParams: MixNodeCostParams; - pledge: DecCoin; - tokenPool: 'balance' | 'locked'; -}; - -export type TBondGatewaySignatureArgs = { - gateway: Gateway; - pledge: DecCoin; - tokenPool: 'balance' | 'locked'; -}; - -export type TUpdateBondArgs = { - currentPledge: DecCoin; - newPledge: DecCoin; - fee?: Fee; -}; - -export type TSimulateUpdateBondArgs = Omit; - -export type TNodeDescription = { - name: string; - description: string; - link: string; - location: string; -}; - -export type TDelegateArgs = { - identity: string; - amount: DecCoin; -}; - -export type Period = 'Before' | { In: number } | 'After'; - -export type TAccount = { - name: string; - address: string; - mnemonic: string; -}; - -export type TGatewayReport = { - identity: string; - owner: string; - last_day: number; - last_hour: number; - most_recent: number; -}; - -// export const isMixnode = (node: TBondedMixnode | TBondedGateway): node is TBondedMixnode => -// (node as TBondedMixnode).profitMargin !== undefined; - -// export const isGateway = (node: TBondedMixnode | TBondedGateway): node is TBondedGateway => !isMixnode(node); diff --git a/explorer/src/components/Delegations/types/index.ts b/explorer/src/components/Delegations/types/index.ts deleted file mode 100644 index 85747b1acd..0000000000 --- a/explorer/src/components/Delegations/types/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './global'; -export * from './rust/AppEnv'; -export * from './rust/Interval'; -export * from './rust/Network'; -export * from './rust/StateParams'; -export * from './rust/ValidatorUrl'; -export * from './rust/ValidatorUrls'; diff --git a/explorer/src/components/Delegations/types/rust/AppEnv.ts b/explorer/src/components/Delegations/types/rust/AppEnv.ts deleted file mode 100644 index 861ecd9ef5..0000000000 --- a/explorer/src/components/Delegations/types/rust/AppEnv.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface AppEnv { - ADMIN_ADDRESS: string | null; - SHOW_TERMINAL: string | null; - ENABLE_QA_MODE: string | null; -} diff --git a/explorer/src/components/Delegations/types/rust/AppVersion.ts b/explorer/src/components/Delegations/types/rust/AppVersion.ts deleted file mode 100644 index 82b94c5596..0000000000 --- a/explorer/src/components/Delegations/types/rust/AppVersion.ts +++ /dev/null @@ -1,7 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export interface AppVersion { - current_version: string; - latest_version: string; - is_update_available: boolean; -} diff --git a/explorer/src/components/Delegations/types/rust/Epoch.ts b/explorer/src/components/Delegations/types/rust/Epoch.ts deleted file mode 100644 index 21ec4ac2df..0000000000 --- a/explorer/src/components/Delegations/types/rust/Epoch.ts +++ /dev/null @@ -1,8 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export interface Epoch { - id: number; - start: bigint; - end: bigint; - duration_seconds: bigint; -} diff --git a/explorer/src/components/Delegations/types/rust/Interval.ts b/explorer/src/components/Delegations/types/rust/Interval.ts deleted file mode 100644 index c1526be658..0000000000 --- a/explorer/src/components/Delegations/types/rust/Interval.ts +++ /dev/null @@ -1,8 +0,0 @@ -export interface Interval { - id: number; - epochs_in_interval: number; - current_epoch_start_unix: bigint; - current_epoch_id: number; - epoch_length_seconds: bigint; - total_elapsed_epochs: number; -} diff --git a/explorer/src/components/Delegations/types/rust/Network.ts b/explorer/src/components/Delegations/types/rust/Network.ts deleted file mode 100644 index d55f0bce67..0000000000 --- a/explorer/src/components/Delegations/types/rust/Network.ts +++ /dev/null @@ -1,3 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export type Network = 'QA' | 'SANDBOX' | 'MAINNET'; diff --git a/explorer/src/components/Delegations/types/rust/StateParams.ts b/explorer/src/components/Delegations/types/rust/StateParams.ts deleted file mode 100644 index 2119c59470..0000000000 --- a/explorer/src/components/Delegations/types/rust/StateParams.ts +++ /dev/null @@ -1,8 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { DecCoin } from '@nymproject/types/src/types/rust/DecCoin'; - -export interface TauriContractStateParams { - minimum_mixnode_pledge: DecCoin; - minimum_gateway_pledge: DecCoin; - minimum_mixnode_delegation: DecCoin | null; -} diff --git a/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts b/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts deleted file mode 100644 index 00291a57cd..0000000000 --- a/explorer/src/components/Delegations/types/rust/ValidatorUrl.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. - -export interface ValidatorUrl { - url: string; - name: string | null; -} diff --git a/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts b/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts deleted file mode 100644 index 57118d6c3f..0000000000 --- a/explorer/src/components/Delegations/types/rust/ValidatorUrls.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This file was generated by [ts-rs](https://github.com/Aleph-Alpha/ts-rs). Do not edit this file manually. -import type { ValidatorUrl } from './ValidatorUrl'; - -export interface ValidatorUrls { - urls: Array; -} diff --git a/explorer/src/components/Delegations/typings/FC.d.ts b/explorer/src/components/Delegations/typings/FC.d.ts deleted file mode 100644 index 08ebdfa298..0000000000 --- a/explorer/src/components/Delegations/typings/FC.d.ts +++ /dev/null @@ -1 +0,0 @@ -declare type FCWithChildren

= React.FC>; diff --git a/explorer/src/components/Delegations/typings/jpeg.d.ts b/explorer/src/components/Delegations/typings/jpeg.d.ts deleted file mode 100644 index af2ed72913..0000000000 --- a/explorer/src/components/Delegations/typings/jpeg.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -declare module '*.jpeg' { - const value: any; - export default value; -} - -declare module '*.jpg' { - const value: any; - export default value; -} diff --git a/explorer/src/components/Delegations/typings/json.d.ts b/explorer/src/components/Delegations/typings/json.d.ts deleted file mode 100644 index b72dd46ee5..0000000000 --- a/explorer/src/components/Delegations/typings/json.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.json' { - const content: any; - export default content; -} diff --git a/explorer/src/components/Delegations/typings/png.d.ts b/explorer/src/components/Delegations/typings/png.d.ts deleted file mode 100644 index dd84df40a4..0000000000 --- a/explorer/src/components/Delegations/typings/png.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.png' { - const content: any; - export default content; -} diff --git a/explorer/src/components/Delegations/typings/svg.d.ts b/explorer/src/components/Delegations/typings/svg.d.ts deleted file mode 100644 index 091d25e210..0000000000 --- a/explorer/src/components/Delegations/typings/svg.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -declare module '*.svg' { - const content: any; - export default content; -} diff --git a/explorer/src/components/Delegations/utils/common.ts b/explorer/src/components/Delegations/utils/common.ts deleted file mode 100644 index b07c21e724..0000000000 --- a/explorer/src/components/Delegations/utils/common.ts +++ /dev/null @@ -1,268 +0,0 @@ -import { appWindow } from '@tauri-apps/api/window'; -import bs58 from 'bs58'; -import Big from 'big.js'; -import { valid } from 'semver'; -import { add, format, fromUnixTime } from 'date-fns'; -import { DecCoin, isValidRawCoin, MixNodeCostParams } from '@nymproject/types'; -import { getCurrentInterval, getDefaultMixnodeCostParams, getLockedCoins, getSpendableCoins } from '../requests'; -import { Console } from './console'; -import { Network } from '../types'; - -export type TPoolOption = 'balance' | 'locked'; - -export const uNYMtoNYM = (unym: string, rounding = 6) => { - const nym = Big(unym).div(1000000).toFixed(rounding); - - return { - asString: () => nym, - asNumber: () => Number(nym), - }; -}; - -// export const checkHasEnoughFunds = async (balance: string, allocationValue: string): Promise => { -// try { -// // const walletValue = await userBalance(); - -// const remainingBalance = +balance - +allocationValue; -// return remainingBalance >= 0; -// } catch (e) { -// Console.log(e as string); -// return false; -// } -// }; - -export const checkHasEnoughLockedTokens = async (allocationValue: string) => { - try { - const lockedTokens = await getLockedCoins(); - const spendableTokens = await getSpendableCoins(); - const remainingBalance = +lockedTokens.amount + +spendableTokens.amount - +allocationValue; - return remainingBalance >= 0; - } catch (e) { - Console.error(e as string); - } - return false; -}; - -export const checkTokenBalance = (tokenPool: TPoolOption, amount: string, balance: string) => { - let hasEnoughFunds = false; - // if (tokenPool === 'locked') { - // hasEnoughFunds = await checkHasEnoughLockedTokens(amount); - // } - - if (tokenPool === 'balance') { - const remainingBalance = +balance - +amount; - hasEnoughFunds = remainingBalance >= 0; - } - - return hasEnoughFunds; -}; - -export const validateKey = (key: string, bytesLength: number): boolean => { - // it must be a valid base58 key - try { - const bytes = bs58.decode(key); - // of length 32 - return bytes.length === bytesLength; - } catch (e) { - Console.error(e as string); - return false; - } -}; - -export const validateAmount = async ( - majorAmountAsString: DecCoin['amount'], - minimumAmountAsString: DecCoin['amount'], -): Promise => { - // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc - if (!Number(majorAmountAsString)) { - return false; - } - - if (!isValidRawCoin(majorAmountAsString)) { - return false; - } - - const majorValueFloat = parseInt(majorAmountAsString, Number(10)); - - return majorValueFloat >= parseInt(minimumAmountAsString, Number(10)); - - // this conversion seems really iffy but I'm not sure how to better approach it -}; - -export const isValidHostname = (value: string) => { - // regex for ipv4 and ipv6 and hhostname- source http://jsfiddle.net/DanielD/8S4nq/ - const hostnameRegex = - /((^((([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]))\s*$)|(^\s*((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?\s*$))|(^\s*((?=.{1,255}$)(?=.*[A-Za-z].*)[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?(?:\.[0-9A-Za-z](?:(?:[0-9A-Za-z]|\b-){0,61}[0-9A-Za-z])?)*)\s*$)/; - - return hostnameRegex.test(value); -}; - -export const validateVersion = (version: string): boolean => { - try { - return valid(version) !== null; - } catch (e) { - return false; - } -}; - -export const validateLocation = (location: string): boolean => { - const locationRegex = /^[a-z]+$/i; - return locationRegex.test(location); -}; - -export const validateRawPort = (rawPort: number): boolean => !Number.isNaN(rawPort) && rawPort >= 1 && rawPort <= 65535; - -export const truncate = (text: string, trim: number) => `${text.substring(0, trim)}...`; - -export const isGreaterThan = (a: number, b: number) => a > b; - -export const isLessThan = (a: number, b: number) => a < b; - -export const randomNumberBetween = (min: number, max: number) => { - const minCeil = Math.ceil(min); - const maxFloor = Math.floor(max); - return Math.floor(Math.random() * (maxFloor - minCeil + 1) + minCeil); -}; - -export const splice = (size: number, address?: string): string => { - if (address) { - return `${address.slice(0, size)}...${address.slice(-size)}`; - } - return ''; -}; - -export const maximizeWindow = async () => { - await appWindow.maximize(); -}; - -export function removeObjectDuplicates(arr: T[], id: K) { - return arr.filter((v, i, a) => a.findIndex((v2) => v2[id] === v[id]) === i); -} - -export const isDecimal = (value: number) => value - Math.floor(value) !== 0; - -export const attachDefaultOperatingCost = async (profitMarginPercent: string): Promise => - getDefaultMixnodeCostParams(profitMarginPercent); - -/** - * Converts a stringified percentage integer (0-100) to a stringified float (0.0-1.0). - * - * @param value - the percentage to convert - * @returns A stringified float - */ -export const toPercentFloatString = (value: string) => (Number(value) / 100).toString(); - -/** - * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100). - * - * @param value - the percentage to convert - * @returns A stringified integer - */ -export const toPercentIntegerString = (value: string) => Math.round(Number(value) * 100).toString(); - -/** - * Converts a decimal number to a pretty representation - * with fixed decimal places. - * - * @param val - a decimal number of string form - * @param dp - number of decimal places (4 by default ie. 0.0000) - * @returns A prettified decimal number - */ -export const toDisplay = (val: string | number | Big, dp = 4) => { - let displayValue; - try { - displayValue = Big(val).toFixed(dp); - } catch (e: any) { - Console.warn(`${displayValue} not a valid decimal number: ${e}`); - } - return displayValue; -}; - -/** - * Takes a DecCoin and prettify its amount to a representation - * with fixed decimal places. - * - * @param coin - a DecCoin - * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000) - * @returns A DecCoin with prettified amount - */ -export const decCoinToDisplay = (coin: DecCoin, dp = 4) => { - const displayCoin = { ...coin }; - try { - displayCoin.amount = Big(coin.amount).toFixed(dp); - } catch (e: any) { - Console.warn(`${coin.amount} not a valid decimal number: ${e}`); - } - return displayCoin; -}; - -/** - * Converts a decimal number of μNYM (micro NYM) to NYM. - * - * @param unym - string representation of a decimal number of μNYM - * @param dp - number of decimal places (4 by default ie. 0.0000) - * @returns The corresponding decimal number in NYM - */ -export const unymToNym = (unym: string | Big, dp = 4) => { - let nym; - try { - nym = Big(unym).div(1_000_000).toFixed(dp); - } catch (e: any) { - Console.warn(`${unym} not a valid decimal number: ${e}`); - } - return nym; -}; - -/** - * - * Checks if the user's balance is enough to pay the fee - * @param balance - The user's current balance - * @param fee - The fee for the tx - * @param tx - The amount of the tx - * @returns boolean - * - */ - -export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => { - console.log('balance', balance, fee, tx); - try { - return Big(balance).gte(Big(fee).plus(Big(tx))); - } catch (e) { - console.log(e); - return false; - } -}; - -export const getIntervalAsDate = async () => { - const interval = await getCurrentInterval(); - const secondsToNextInterval = - Number(interval.epochs_in_interval - interval.current_epoch_id) * Number(interval.epoch_length_seconds); - - const nextInterval = format( - add(new Date(), { - seconds: secondsToNextInterval, - }), - 'dd/MM/yyyy, HH:mm', - ); - - const nextEpoch = format( - add(fromUnixTime(Number(interval.current_epoch_start_unix)), { - seconds: Number(interval.epoch_length_seconds), - }), - 'HH:mm', - ); - - return { nextEpoch, nextInterval }; -}; - -export const urls = (networkName?: Network) => - networkName === 'MAINNET' - ? { - mixnetExplorer: 'https://mixnet.explorers.guru/', - blockExplorer: 'https://blocks.nymtech.net', - networkExplorer: 'https://explorer.nymtech.net', - } - : { - blockExplorer: `https://${networkName}-blocks.nymtech.net`, - networkExplorer: `https://${networkName}-explorer.nymtech.net`, - }; diff --git a/explorer/src/components/Delegations/utils/console.ts b/explorer/src/components/Delegations/utils/console.ts deleted file mode 100644 index 6506c76d2a..0000000000 --- a/explorer/src/components/Delegations/utils/console.ts +++ /dev/null @@ -1,10 +0,0 @@ -/* eslint-disable no-console */ -import { config } from '../config'; - -export const Console = { - log: (message?: any, ...optionalParams: any[]) => - config.IS_DEV_MODE ? console.log(message, ...optionalParams) : undefined, - warn: (message?: any, ...optionalParams: any[]) => - config.IS_DEV_MODE ? console.warn(message, ...optionalParams) : undefined, - error: (message?: any, ...optionalParams: any[]) => console.error(message, ...optionalParams), -}; diff --git a/explorer/src/components/Delegations/utils/fireRequests.ts b/explorer/src/components/Delegations/utils/fireRequests.ts deleted file mode 100644 index 441f3289a8..0000000000 --- a/explorer/src/components/Delegations/utils/fireRequests.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { Console } from './console'; - -export type TauriReq Promise)> = { - name: Req['name']; - request: () => ReturnType; - onFulfilled: (value: Awaited>) => void; -}; - -async function fireRequests(requests: TauriReq[]) { - const promises = await Promise.allSettled(requests.map((r) => r.request())); - - promises.forEach((res, index) => { - if (res.status === 'rejected') { - Console.warn(`${requests[index].name} request fails`, res.reason); - } - if (res.status === 'fulfilled') { - requests[index].onFulfilled(res.value as any); - } - }); -} - -export default fireRequests; diff --git a/explorer/src/components/Delegations/utils/index.ts b/explorer/src/components/Delegations/utils/index.ts deleted file mode 100644 index b1a2ade95a..0000000000 --- a/explorer/src/components/Delegations/utils/index.ts +++ /dev/null @@ -1,4 +0,0 @@ -export * from './common'; -export * from './fireRequests'; -export * from './console'; -export { default as fireRequests } from './fireRequests'; diff --git a/explorer/src/components/Delegations/utils/sleep.ts b/explorer/src/components/Delegations/utils/sleep.ts deleted file mode 100644 index 4f1d101103..0000000000 --- a/explorer/src/components/Delegations/utils/sleep.ts +++ /dev/null @@ -1,3 +0,0 @@ -export const sleep = (delayMilliseconds: number) => - // eslint-disable-next-line no-promise-executor-return - new Promise((resolve) => setTimeout(resolve, delayMilliseconds)); diff --git a/explorer/src/components/Footer.tsx b/explorer/src/components/Footer.tsx index 2902cbd799..375b5c9b1a 100644 --- a/explorer/src/components/Footer.tsx +++ b/explorer/src/components/Footer.tsx @@ -23,23 +23,22 @@ export const Footer: FCWithChildren = () => { pb: 3, }} > - {isMobile && ( - - - - - - - )} + + + + + + + = ({ mixNo const palette = [theme.palette.text.primary]; const isMobile = useIsMobile(); const statusText = React.useMemo(() => getMixNodeStatusText(mixNodeRow.status), [mixNodeRow.status]); + console.log('mixNodeRow :>> ', mixNodeRow); return ( diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx index 9a0ac5f3d4..4564533875 100644 --- a/explorer/src/components/Nav.tsx +++ b/explorer/src/components/Nav.tsx @@ -20,18 +20,11 @@ import { MaintenanceBanner } from '@nymproject/react/banners/MaintenanceBanner'; import { NYM_WEBSITE } from '../api/constants'; import { useMainContext } from '../context/main'; import { MobileDrawerClose } from '../icons/MobileDrawerClose'; -import { Socials } from './Socials'; import { Footer } from './Footer'; import { NymVpnIcon } from '../icons/NymVpn'; import { DarkLightSwitchDesktop } from './Switch'; import { NavOptionType } from '../context/nav'; -import ConnectKeplrWallet from './ConnectKeplrWallet'; -import { assets, chains } from 'chain-registry'; -import { ChainProvider } from '@cosmos-kit/react'; -import { wallets as keplr } from '@cosmos-kit/keplr'; -import { useMemo } from 'react'; - -import '@interchain-ui/react/styles'; +import { ConnectKeplrWallet } from './ConnectKeplrWallet'; const drawerWidth = 255; const bannerHeight = 80; @@ -280,33 +273,6 @@ export const Nav: FCWithChildren = ({ children }) => { } }; - const assetsFixedUp = useMemo(() => { - const nyx = assets.find((a) => a.chain_name === 'nyx'); - if (nyx) { - const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); - if (nyxCoin) { - nyxCoin.coingecko_id = 'nyx'; - } - nyx.assets = nyx.assets.reverse(); - } - return assets; - }, [assets]); - - const chainsFixedUp = useMemo(() => { - const nyx = chains.find((c) => c.chain_id === 'nyx'); - if (nyx) { - if (!nyx.staking) { - nyx.staking = { - staking_tokens: [{ denom: 'unyx' }], - lock_duration: { - blocks: 10000, - }, - }; - } - } - return chains; - }, [chains]); - return ( { alignItems: 'center', }} > - - - - + diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index b79cc864c8..456eaccab8 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -3,11 +3,6 @@ import { Box, TextField, MenuItem, FormControl, Button } from '@mui/material'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import { Filters } from './Filters/Filters'; import { useIsMobile } from '../hooks/useIsMobile'; -import { DelegateModal } from './Delegations/components/DelegateModal'; -import { ChainProvider } from '@cosmos-kit/react'; -import { assets, chains } from 'chain-registry'; -import { wallets as keplr } from '@cosmos-kit/keplr'; -import { DelegationModal } from './Delegations/components/DelegationModal'; const fieldsHeight = '42.25px'; @@ -20,17 +15,6 @@ type TableToolBarProps = { childrenBefore?: React.ReactNode; childrenAfter?: React.ReactNode; }; -type ActionType = 'delegate' | 'undelegate' | 'redeem' | 'redeem-all' | 'compound'; - -type DelegationModalProps = { - status: 'loading' | 'success' | 'error'; - action: ActionType; - message?: string; - transactions?: { - url: string; - hash: string; - }[]; -}; export const TableToolbar: FCWithChildren = ({ searchTerm, @@ -41,42 +25,6 @@ export const TableToolbar: FCWithChildren = ({ childrenAfter, withFilters, }) => { - const [showNewDelegationModal, setShowNewDelegationModal] = useState(false); - const [confirmationModalProps, setConfirmationModalProps] = useState(); - - const assetsFixedUp = useMemo(() => { - const nyx = assets.find((a) => a.chain_name === 'nyx'); - if (nyx) { - const nyxCoin = nyx.assets.find((a) => a.name === 'nyx'); - if (nyxCoin) { - nyxCoin.coingecko_id = 'nyx'; - } - nyx.assets = nyx.assets.reverse(); - } - return assets; - }, [assets]); - - const chainsFixedUp = useMemo(() => { - const nyx = chains.find((c) => c.chain_id === 'nyx'); - if (nyx) { - if (!nyx.staking) { - nyx.staking = { - staking_tokens: [{ denom: 'unyx' }], - lock_duration: { - blocks: 10000, - }, - }; - if (nyx.apis) nyx.apis.rpc = [{ address: 'https://rpc.nymtech.net', provider: 'nym' }]; - } - } - return chains; - }, [chains]); - - const handleNewDelegation = (delegationModalProps: DelegationModalProps) => { - setShowNewDelegationModal(false); - setConfirmationModalProps(delegationModalProps); - }; - const isMobile = useIsMobile(); return ( = ({ marginTop: isMobile ? 2 : 0, }} > - {withFilters && } {childrenAfter} - - {showNewDelegationModal && ( - 'amino', - }} - > - setShowNewDelegationModal(false)} - header="Delegate" - buttonText="Delegate stake" - denom={'nym'} // clientDetails?.display_mix_denom || 'nym'} - onOk={(delegationModalProps: DelegationModalProps) => handleNewDelegation(delegationModalProps)} - // accountBalance={balance?.printable_balance} - /> - - )} - - {confirmationModalProps && ( - { - setConfirmationModalProps(undefined); - // await fetchBalance(); - }} - /> - )} ); }; diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx new file mode 100644 index 0000000000..6a14f556cf --- /dev/null +++ b/explorer/src/context/cosmos-kit.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { ChainProvider } from '@cosmos-kit/react'; +import { wallets as keplr } from '@cosmos-kit/keplr'; +import { assets, chains } from 'chain-registry'; + +const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( + + {children} + +); + +export default CosmosKitProvider; diff --git a/explorer/src/icons/DelevateSVG.tsx b/explorer/src/icons/DelevateSVG.tsx new file mode 100644 index 0000000000..56180d1b8a --- /dev/null +++ b/explorer/src/icons/DelevateSVG.tsx @@ -0,0 +1,12 @@ +import React from 'react'; +import { SvgIcon, SvgIconProps } from '@mui/material'; + +export const DelegateIcon = (props: SvgIconProps) => ( + + + + + + + +); diff --git a/explorer/src/icons/ElipsSVG.tsx b/explorer/src/icons/ElipsSVG.tsx index 05fdc6282c..6ced45169f 100644 --- a/explorer/src/icons/ElipsSVG.tsx +++ b/explorer/src/icons/ElipsSVG.tsx @@ -1,26 +1,20 @@ import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; -export const ElipsSVG: FCWithChildren = () => { - const theme = useTheme(); - const color = theme.palette.text.primary; - - return ( - - - - - - - - - - ); -}; +export const ElipsSVG: FCWithChildren = () => ( + + + + + + + + + +); diff --git a/explorer/src/icons/TokenSVG.tsx b/explorer/src/icons/TokenSVG.tsx index 00c74d8a44..76c2765369 100644 --- a/explorer/src/icons/TokenSVG.tsx +++ b/explorer/src/icons/TokenSVG.tsx @@ -7,7 +7,7 @@ export const TokenSVG: FCWithChildren = () => { return ( - + - - - - - + + + + + + + , ); diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 9ab833896c..d9980f6790 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -6,6 +6,7 @@ import { SelectChangeEvent } from '@mui/material/Select'; import { SxProps } from '@mui/system'; import { Theme, useTheme } from '@mui/material/styles'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; +import { useWallet } from '@cosmos-kit/react'; import { useMainContext } from '../../context/main'; import { MixnodeRowType, mixnodeToGridRow } from '../../components/MixNodes'; import { TableToolbar } from '../../components/TableToolbar'; @@ -19,6 +20,9 @@ import { splice } from '../../utils'; import { getMixNodeStatusColor } from '../../components/MixNodes/Status'; import { MixNodeStatusDropdown } from '../../components/MixNodes/StatusDropdown'; import { Tooltip } from '../../components/Tooltip'; +import { DelegateIconButton } from '../../components/Delegations/components/DelegateIconButton'; +import { DelegationModal, DelegationModalProps } from '../../components/Delegations/components/DelegationModal'; +import { DelegateModal } from '../../components/Delegations/components/DelegateModal'; const getCellFontStyle = (theme: Theme, row: MixnodeRowType, textColor?: string) => { const color = textColor || getMixNodeStatusColor(theme, row.status); @@ -40,9 +44,21 @@ export const PageMixnodes: FCWithChildren = () => { const [filteredMixnodes, setFilteredMixnodes] = React.useState([]); const [pageSize, setPageSize] = React.useState('10'); const [searchTerm, setSearchTerm] = React.useState(''); - const theme = useTheme(); + const [itemSelectedForDelegation, setItemSelectedForDelegation] = React.useState<{ + mixId: number; + identityKey: string; + }>(); + const [confirmationModalProps, setConfirmationModalProps] = React.useState(); const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>(); + + const theme = useTheme(); const navigate = useNavigate(); + const wallet = useWallet(); + + const handleNewDelegation = (delegationModalProps: DelegationModalProps) => { + setItemSelectedForDelegation(undefined); + setConfirmationModalProps(delegationModalProps); + }; const handleSearch = (str: string) => { setSearchTerm(str.toLowerCase()); @@ -82,13 +98,31 @@ export const PageMixnodes: FCWithChildren = () => { }; const columns: GridColDef[] = [ + { + field: 'delegate', + headerName: 'Delegate', + disableColumnMenu: true, + disableReorder: true, + align: 'center', + renderHeader: () => , + headerClassName: 'MuiDataGrid-header-override', + width: 80, + headerAlign: 'center', + renderCell: (params: GridRenderCellParams) => ( + { + setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); + }} + /> + ), + }, { field: 'mix_id', headerName: 'Mix ID', disableColumnMenu: true, renderHeader: () => , headerClassName: 'MuiDataGrid-header-override', - width: 100, + width: 70, headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( { disableColumnMenu: true, renderHeader: () => , headerClassName: 'MuiDataGrid-header-override', - width: 170, + width: 190, headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( <> @@ -363,6 +397,29 @@ export const PageMixnodes: FCWithChildren = () => { + + {itemSelectedForDelegation && ( + setItemSelectedForDelegation(undefined)} + header="Delegate" + buttonText="Delegate stake" + denom="nym" + onOk={(delegationModalProps: DelegationModalProps) => handleNewDelegation(delegationModalProps)} + identityKey={itemSelectedForDelegation.identityKey} + mixId={itemSelectedForDelegation.mixId} + /> + )} + + {confirmationModalProps && ( + { + setConfirmationModalProps(undefined); + // await fetchBalance(); + }} + /> + )} ); }; diff --git a/explorer/src/typeDefs/network.ts b/explorer/src/typeDefs/network.ts new file mode 100644 index 0000000000..f8615cd992 --- /dev/null +++ b/explorer/src/typeDefs/network.ts @@ -0,0 +1 @@ +export type Network = 'QA' | 'SANDBOX' | 'MAINNET'; diff --git a/explorer/src/utils/currency.ts b/explorer/src/utils/currency.ts index 85a9bf59e4..ad6ed1f165 100644 --- a/explorer/src/utils/currency.ts +++ b/explorer/src/utils/currency.ts @@ -1,5 +1,6 @@ import { printableCoin } from '@nymproject/nym-validator-client'; import Big from 'big.js'; +import { DecCoin, isValidRawCoin } from '@nymproject/types'; const DENOM = process.env.CURRENCY_DENOM || 'unym'; const DENOM_STAKING = process.env.CURRENCY_STAKING_DENOM || 'unyx'; @@ -61,3 +62,39 @@ export const unymToNym = (unym: string | number | Big, dp = 4) => { } return nym; }; + +export const validateAmount = async ( + majorAmountAsString: DecCoin['amount'], + minimumAmountAsString: DecCoin['amount'], +): Promise => { + // tests basic coin value requirements, like no more than 6 decimal places, value lower than total supply, etc + if (!Number(majorAmountAsString)) { + return false; + } + + if (!isValidRawCoin(majorAmountAsString)) { + return false; + } + + const majorValueFloat = parseInt(majorAmountAsString, Number(10)); + + return majorValueFloat >= parseInt(minimumAmountAsString, Number(10)); +}; + +/** + * Takes a DecCoin and prettify its amount to a representation + * with fixed decimal places. + * + * @param coin - a DecCoin + * @param dp - number of decimal places to apply to amount (4 by default ie. 0.0000) + * @returns A DecCoin with prettified amount + */ +export const decCoinToDisplay = (coin: DecCoin, dp = 4) => { + const displayCoin = { ...coin }; + try { + displayCoin.amount = Big(coin.amount).toFixed(dp); + } catch (e: any) { + console.warn(`${coin.amount} not a valid decimal number: ${e}`); + } + return displayCoin; +}; diff --git a/explorer/src/utils/index.ts b/explorer/src/utils/index.ts index 4994d73dbb..5375377b5a 100644 --- a/explorer/src/utils/index.ts +++ b/explorer/src/utils/index.ts @@ -2,8 +2,10 @@ import { MutableRefObject } from 'react'; import { Theme } from '@mui/material/styles'; import { registerLocale, getName } from 'i18n-iso-countries'; +import Big from 'big.js'; import { CountryData } from '../typeDefs/explorer-api'; import { EconomicsRowsType } from '../components/MixNodes/Economics/types'; +import { Network } from '../typeDefs/network'; registerLocale(require('i18n-iso-countries/langs/en.json')); @@ -48,6 +50,8 @@ export const splice = (start: number, deleteCount: number, address?: string): st return ''; }; +export const trimAddress = (address = '', trimBy = 6) => `${address.slice(0, trimBy)}...${address.slice(-trimBy)}`; + /** * Converts a stringified percentage float (0.0-1.0) to a stringified integer (0-100). * @@ -82,3 +86,39 @@ export const textColour = (value: EconomicsRowsType, field: string, theme: Theme } return theme.palette.nym.wallet.fee; }; + +export const isGreaterThan = (a: number, b: number) => a > b; + +export const isLessThan = (a: number, b: number) => a < b; + +/** + * + * Checks if the user's balance is enough to pay the fee + * @param balance - The user's current balance + * @param fee - The fee for the tx + * @param tx - The amount of the tx + * @returns boolean + * + */ + +export const isBalanceEnough = (fee: string, tx: string = '0', balance: string = '0') => { + console.log('balance', balance, fee, tx); + try { + return Big(balance).gte(Big(fee).plus(Big(tx))); + } catch (e) { + console.log(e); + return false; + } +}; + +export const urls = (networkName?: Network) => + networkName === 'MAINNET' + ? { + mixnetExplorer: 'https://mixnet.explorers.guru/', + blockExplorer: 'https://blocks.nymtech.net', + networkExplorer: 'https://explorer.nymtech.net', + } + : { + blockExplorer: `https://${networkName}-blocks.nymtech.net`, + networkExplorer: `https://${networkName}-explorer.nymtech.net`, + }; diff --git a/explorer/yarn-error.log b/explorer/yarn-error.log index 2c269e3be9..e2e77eb633 100644 --- a/explorer/yarn-error.log +++ b/explorer/yarn-error.log @@ -1,29 +1,29 @@ Arguments: - /Users/ianamatrosova/.nvm/versions/node/v18.18.2/bin/node /Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/bin/yarn.js add @nymproject/types + /home/fmtabbara/.nvm/versions/node/v18.12.1/bin/node /home/fmtabbara/.nvm/versions/node/v18.12.1/bin/yarn add @nymproject/types PATH: - /Users/ianamatrosova/.nvm/versions/node/v18.18.2/bin:/Users/ianamatrosova/.nvm/versions/node/v16.16.0/bin:/usr/local/bin:/System/Cryptexes/App/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/local/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/bin:/var/run/com.apple.security.cryptexd/codex.system/bootstrap/usr/appleinternal/bin:/Library/Apple/usr/bin:/usr/local/go/bin:/Users/ianamatrosova/.nvm/versions/node/v16.16.0/bin:/Users/ianamatrosova/.cargo/bin:/Users/ianamatrosova/bash_course/scripts:~/dev/flutter/bin:/Users/ianamatrosova/bash_course/scripts:~/dev/flutter/bin + /home/fmtabbara/.bun/bin:/home/fmtabbara/.deno/bin:/home/fmtabbara/.bun/bin:/home/fmtabbara/.deno/bin:/home/fmtabbara/.nvm/versions/node/v18.12.1/bin:/home/fmtabbara/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin:/home/fmtabbara/go/bin:/home/fmtabbara/.yarn/bin:/home/fmtabbara/.yarn/bin Yarn version: 1.22.19 Node version: - 18.18.2 + 18.12.1 Platform: - darwin arm64 + linux x64 Trace: Error: https://registry.yarnpkg.com/@nymproject%2ftypes: Not found - at params.callback [as _callback] (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:66145:18) - at self.callback (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:140890:22) - at Request.emit (node:events:517:28) - at Request. (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:141862:10) - at Request.emit (node:events:517:28) - at IncomingMessage. (/Users/ianamatrosova/.cache/node/corepack/yarn/1.22.19/lib/cli.js:141784:12) - at Object.onceWrapper (node:events:631:28) - at IncomingMessage.emit (node:events:529:35) - at endReadableNT (node:internal/streams/readable:1368:12) + at params.callback [as _callback] (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:66145:18) + at self.callback (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:140890:22) + at Request.emit (node:events:513:28) + at Request. (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:141862:10) + at Request.emit (node:events:513:28) + at IncomingMessage. (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:141784:12) + at Object.onceWrapper (node:events:627:28) + at IncomingMessage.emit (node:events:525:35) + at endReadableNT (node:internal/streams/readable:1359:12) at process.processTicksAndRejections (node:internal/process/task_queues:82:21) npm manifest: @@ -47,21 +47,29 @@ npm manifest: "storybook:build": "build-storybook" }, "dependencies": { + "@cosmjs/cosmwasm-stargate": "^0.32.0", + "@cosmjs/crypto": "^0.32.0", + "@cosmjs/encoding": "^0.32.0", "@cosmjs/math": "^0.26.2", + "@cosmjs/stargate": "^0.32.0", "@cosmos-kit/keplr": "^2.4.7", "@cosmos-kit/react": "^2.9.6", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", + "@interchain-ui/react": "^1.14.2", "@mui/icons-material": "^5.0.0", "@mui/material": "^5.0.1", "@mui/styles": "^5.0.1", "@mui/system": "^5.0.1", "@mui/x-data-grid": "^5.0.0-beta.5", "@nymproject/mui-theme": "^1.0.0", + "@nymproject/node-tester": "^1.0.0", "@nymproject/nym-validator-client": "^0.18.0", "@nymproject/react": "^1.0.0", + "@nymproject/types": "^1.0.0", "@tauri-apps/api": "^1.5.1", "big.js": "^6.2.1", + "bs58": "^5.0.0", "buffer": "^6.0.3", "chain-registry": "^1.19.0", "d3-scale": "^4.0.0", @@ -172,9 +180,9 @@ Lockfile: integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== "@adobe/css-tools@^4.0.1": - version "4.3.1" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.1.tgz#abfccb8ca78075a2b6187345c26243c1a0842f28" - integrity sha512-/62yikz7NLScCGAAST5SHdnjaDJQBDq0M2muyRTpf2VQhw6StBg2ALiu73zSJQ4fMVLA+0uBhBHAle7Wg+2kSg== + version "4.3.2" + resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" + integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== "@ampproject/remapping@^2.2.0": version "2.2.1" @@ -191,18 +199,18 @@ Lockfile: dependencies: "@babel/highlight" "^7.10.4" - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== + "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@babel/highlight" "^7.22.13" + "@babel/highlight" "^7.23.4" chalk "^2.4.2" - "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" - integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== + "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@7.12.9": version "7.12.9" @@ -227,32 +235,32 @@ Lockfile: source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.17.5", "@babel/core@^7.19.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" - integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" + integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.2" - "@babel/parser" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.5" + "@babel/parser" "^7.23.5" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" - "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.0", "@babel/generator@^7.7.2": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== + "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.5", "@babel/generator@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" + integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== dependencies: - "@babel/types" "^7.23.0" + "@babel/types" "^7.23.5" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" @@ -264,14 +272,14 @@ Lockfile: dependencies: "@babel/types" "^7.22.5" - "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": + "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== dependencies: "@babel/types" "^7.22.15" - "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": + "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== @@ -282,22 +290,22 @@ Lockfile: lru-cache "^5.1.1" semver "^6.3.1" - "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" - integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== + "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz#2a8792357008ae9ce8c0f2b78b9f646ac96b314b" + integrity sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" - "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== @@ -331,7 +339,7 @@ Lockfile: lodash.debounce "^4.0.8" resolve "^1.14.2" - "@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": + "@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== @@ -351,24 +359,24 @@ Lockfile: dependencies: "@babel/types" "^7.22.5" - "@babel/helper-member-expression-to-functions@^7.22.15": + "@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== dependencies: "@babel/types" "^7.23.0" - "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": + "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== dependencies: "@babel/types" "^7.22.15" - "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" - integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== + "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== dependencies: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-module-imports" "^7.22.15" @@ -393,7 +401,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - "@babel/helper-remap-async-to-generator@^7.22.20", "@babel/helper-remap-async-to-generator@^7.22.5": + "@babel/helper-remap-async-to-generator@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== @@ -402,7 +410,7 @@ Lockfile: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-wrap-function" "^7.22.20" - "@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": + "@babel/helper-replace-supers@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== @@ -432,20 +440,20 @@ Lockfile: dependencies: "@babel/types" "^7.22.5" - "@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== + "@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - "@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== + "@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== "@babel/helper-wrap-function@^7.22.20": version "7.22.20" @@ -456,44 +464,52 @@ Lockfile: "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" - "@babel/helpers@^7.12.5", "@babel/helpers@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" - integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== + "@babel/helpers@^7.12.5", "@babel/helpers@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" + integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" - "@babel/highlight@^7.10.4", "@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== + "@babel/highlight@^7.10.4", "@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" - "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== + "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" + integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" - integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" - integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.15" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz#20c60d4639d18f7da8602548512e9d3a4c8d7098" + integrity sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-proposal-class-properties@^7.12.1": version "7.18.6" @@ -504,23 +520,23 @@ Lockfile: "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-decorators@^7.12.12": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.2.tgz#0b345a5754f48309fa50b7cd99075ef0295b12c8" - integrity sha512-eR0gJQc830fJVGz37oKLvt9W9uUIQSAovUl0e9sJ3YeO09dlcoBVYD3CLrjCj4qHdXmfiyTyFt8yeQYSN5fxLg== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz#eeaa49d0dc9229aec4d23378653738cdc5a3ea0a" + integrity sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-create-class-features-plugin" "^7.23.5" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/plugin-syntax-decorators" "^7.22.10" + "@babel/plugin-syntax-decorators" "^7.23.3" "@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.17.tgz#91b60cd338f501cccdf549af2308768911ec5fbb" - integrity sha512-cop/3quQBVvdz6X5SJC6AhUv3C9DrVTM06LUEXimEdWAhCSyOJIr9NiZDU9leHZ0/aiG0Sh7Zmvaku5TWYNgbA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz#6f511a676c540ccc8d17a8553dbba9230b0ddac0" + integrity sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-default-from" "^7.22.5" + "@babel/plugin-syntax-export-default-from" "^7.23.3" "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": version "7.18.6" @@ -610,10 +626,10 @@ Lockfile: dependencies: "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-decorators@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz#7d83ea04d893c442b78ebf4c3cbac59a7211deff" - integrity sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ== + "@babel/plugin-syntax-decorators@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz#a1d351d6c25bfdcf2e16f99b039101bc0ffcb0ca" + integrity sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -624,10 +640,10 @@ Lockfile: dependencies: "@babel/helper-plugin-utils" "^7.8.0" - "@babel/plugin-syntax-export-default-from@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.22.5.tgz#ac3a24b362a04415a017ab96b9b4483d0e2a6e44" - integrity sha512-ODAqWWXB/yReh/jVQDag/3/tl6lgBueQkk/TcfW/59Oykm4c8a55XloX0CTk2k2VJiFWMgHby9xNX29IbCv9dQ== + "@babel/plugin-syntax-export-default-from@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz#7e6d4bf595d5724230200fb2b7401d4734b15335" + integrity sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -638,24 +654,24 @@ Lockfile: dependencies: "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-flow@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" - integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== + "@babel/plugin-syntax-flow@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" + integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-import-assertions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" - integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== + "@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-import-attributes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" - integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== + "@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -680,10 +696,10 @@ Lockfile: dependencies: "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-jsx@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== + "@babel/plugin-syntax-jsx@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -743,10 +759,10 @@ Lockfile: dependencies: "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== + "@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -758,219 +774,219 @@ Lockfile: "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" - integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== + "@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-async-generator-functions@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" - integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ== + "@babel/plugin-transform-async-generator-functions@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" + integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== dependencies: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.20" "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" - integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== + "@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== dependencies: - "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" - "@babel/plugin-transform-block-scoped-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" - integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== + "@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" - integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== + "@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-class-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" - integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== + "@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-class-static-block@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" - integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== + "@babel/plugin-transform-class-static-block@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" - integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== + "@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz#e7a75f815e0c534cc4c9a39c56636c84fc0d64f2" + integrity sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" - "@babel/plugin-transform-computed-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" - integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== + "@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.5" + "@babel/template" "^7.22.15" - "@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" - integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== + "@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-dotall-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" - integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== + "@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-duplicate-keys@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" - integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== + "@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-dynamic-import@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" - integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== + "@babel/plugin-transform-dynamic-import@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-exponentiation-operator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" - integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== + "@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-export-namespace-from@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" - integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== + "@babel/plugin-transform-export-namespace-from@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-transform-flow-strip-types@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" - integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== + "@babel/plugin-transform-flow-strip-types@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" + integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-flow" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.23.3" - "@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" - integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== + "@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz#afe115ff0fbce735e02868d41489093c63e15559" + integrity sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" - integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== + "@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== dependencies: - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-json-strings@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" - integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== + "@babel/plugin-transform-json-strings@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-transform-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" - integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== + "@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" - integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== + "@babel/plugin-transform-logical-assignment-operators@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-transform-member-expression-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" - integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== + "@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-modules-amd@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" - integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== + "@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== dependencies: - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-modules-commonjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" - integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== + "@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== dependencies: - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" - "@babel/plugin-transform-modules-systemjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" - integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== + "@babel/plugin-transform-modules-systemjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" + integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== dependencies: "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-identifier" "^7.22.20" - "@babel/plugin-transform-modules-umd@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" - integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== + "@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== dependencies: - "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": @@ -981,108 +997,108 @@ Lockfile: "@babel/helper-create-regexp-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-new-target@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" - integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== + "@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" - integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== + "@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-transform-numeric-separator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" - integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== + "@babel/plugin-transform-numeric-separator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-transform-object-rest-spread@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" - integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== + "@babel/plugin-transform-object-rest-spread@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" + integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== dependencies: - "@babel/compat-data" "^7.22.9" + "@babel/compat-data" "^7.23.3" "@babel/helper-compilation-targets" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.22.15" + "@babel/plugin-transform-parameters" "^7.23.3" - "@babel/plugin-transform-object-super@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" - integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== + "@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" - "@babel/plugin-transform-optional-catch-binding@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" - integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== + "@babel/plugin-transform-optional-catch-binding@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" - integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== + "@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" - integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== + "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-private-methods@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" - integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== + "@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-private-property-in-object@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" - integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== + "@babel/plugin-transform-private-property-in-object@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-transform-property-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" - integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== + "@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-constant-elements@^7.18.12": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz#6dfa7c1c37f7d7279e417ceddf5a04abb8bb9c29" - integrity sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz#5efc001d07ef0f7da0d73c3a86c132f73d28e43c" + integrity sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-react-display-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" - integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== + "@babel/plugin-transform-react-display-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -1094,135 +1110,136 @@ Lockfile: "@babel/plugin-transform-react-jsx" "^7.22.5" "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6" - integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA== + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-module-imports" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/types" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" - "@babel/plugin-transform-react-pure-annotations@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" - integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== + "@babel/plugin-transform-react-pure-annotations@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c" + integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-regenerator@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" - integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== + "@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" regenerator-transform "^0.15.2" - "@babel/plugin-transform-reserved-words@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" - integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== + "@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" - integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== + "@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" - integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== + "@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-sticky-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" - integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== + "@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" - integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== + "@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-typeof-symbol@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" - integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== + "@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-typescript@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" - integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== + "@babel/plugin-transform-typescript@^7.23.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz#83da13ef62a1ebddf2872487527094b31c9adb84" + integrity sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-create-class-features-plugin" "^7.23.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" - "@babel/plugin-transform-unicode-escapes@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" - integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== + "@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-unicode-property-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" - integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== + "@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-unicode-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" - integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== + "@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" - integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== + "@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.19.4": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" - integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.5.tgz#350a3aedfa9f119ad045b068886457e895ba0ca1" + integrity sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A== dependencies: - "@babel/compat-data" "^7.23.2" + "@babel/compat-data" "^7.23.5" "@babel/helper-compilation-targets" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.3" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@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.22.5" - "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" "@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" @@ -1234,56 +1251,55 @@ Lockfile: "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.23.2" - "@babel/plugin-transform-async-to-generator" "^7.22.5" - "@babel/plugin-transform-block-scoped-functions" "^7.22.5" - "@babel/plugin-transform-block-scoping" "^7.23.0" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.11" - "@babel/plugin-transform-classes" "^7.22.15" - "@babel/plugin-transform-computed-properties" "^7.22.5" - "@babel/plugin-transform-destructuring" "^7.23.0" - "@babel/plugin-transform-dotall-regex" "^7.22.5" - "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.11" - "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.11" - "@babel/plugin-transform-for-of" "^7.22.15" - "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.11" - "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" - "@babel/plugin-transform-member-expression-literals" "^7.22.5" - "@babel/plugin-transform-modules-amd" "^7.23.0" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-modules-systemjs" "^7.23.0" - "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.4" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.4" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.4" + "@babel/plugin-transform-classes" "^7.23.5" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.4" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.4" + "@babel/plugin-transform-for-of" "^7.23.3" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.4" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.3" + "@babel/plugin-transform-modules-umd" "^7.23.3" "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-numeric-separator" "^7.22.11" - "@babel/plugin-transform-object-rest-spread" "^7.22.15" - "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.23.0" - "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-property-literals" "^7.22.5" - "@babel/plugin-transform-regenerator" "^7.22.10" - "@babel/plugin-transform-reserved-words" "^7.22.5" - "@babel/plugin-transform-shorthand-properties" "^7.22.5" - "@babel/plugin-transform-spread" "^7.22.5" - "@babel/plugin-transform-sticky-regex" "^7.22.5" - "@babel/plugin-transform-template-literals" "^7.22.5" - "@babel/plugin-transform-typeof-symbol" "^7.22.5" - "@babel/plugin-transform-unicode-escapes" "^7.22.10" - "@babel/plugin-transform-unicode-property-regex" "^7.22.5" - "@babel/plugin-transform-unicode-regex" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" + "@babel/plugin-transform-numeric-separator" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.4" + "@babel/plugin-transform-optional-chaining" "^7.23.4" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.4" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.23.0" babel-plugin-polyfill-corejs2 "^0.4.6" babel-plugin-polyfill-corejs3 "^0.8.5" babel-plugin-polyfill-regenerator "^0.5.3" @@ -1291,13 +1307,13 @@ Lockfile: semver "^6.3.1" "@babel/preset-flow@^7.12.1": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.15.tgz#30318deb9b3ebd9f5738e96da03a531e0cd3165d" - integrity sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1" + integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-flow-strip-types" "^7.22.5" + "@babel/plugin-transform-flow-strip-types" "^7.23.3" "@babel/preset-modules@0.1.6-no-external-plugins": version "0.1.6-no-external-plugins" @@ -1309,27 +1325,27 @@ Lockfile: esutils "^2.0.2" "@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.18.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc" - integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709" + integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-display-name" "^7.23.3" "@babel/plugin-transform-react-jsx" "^7.22.15" "@babel/plugin-transform-react-jsx-development" "^7.22.5" - "@babel/plugin-transform-react-pure-annotations" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.23.3" "@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.18.6": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz#c8de488130b7081f7e1482936ad3de5b018beef4" - integrity sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-typescript" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" "@babel/register@^7.12.1": version "7.22.15" @@ -1354,10 +1370,10 @@ Lockfile: dependencies: regenerator-runtime "^0.13.2" - "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== + "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" + integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== dependencies: regenerator-runtime "^0.14.0" @@ -1368,7 +1384,7 @@ Lockfile: dependencies: regenerator-runtime "^0.13.2" - "@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3": + "@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== @@ -1377,28 +1393,28 @@ Lockfile: "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" - "@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.2", "@babel/traverse@^7.7.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== + "@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.5", "@babel/traverse@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" + integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" + "@babel/parser" "^7.23.5" + "@babel/types" "^7.23.5" debug "^4.1.0" globals "^11.1.0" - "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== + "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" + integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== dependencies: - "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-string-parser" "^7.23.4" "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" @@ -1471,6 +1487,16 @@ Lockfile: "@cosmjs/math" "^0.29.5" "@cosmjs/utils" "^0.29.5" + "@cosmjs/amino@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.0.tgz#1121b73f7d7c5287a599fde1194c8f78af0c0cb5" + integrity sha512-i1ehEZLQo8HUGY78eum+1ZrDQ48QSkHKy0zOTBOMqce6TiwACIC5kOjRSOWdRQDILcPFzPVrbS2dIgtrdd0ykg== + dependencies: + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + "@cosmjs/cosmwasm-launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.6.tgz#b03a96c8d5b5b4742ec4c56b4a01b1f4f33f7f57" @@ -1501,21 +1527,20 @@ Lockfile: pako "^2.0.2" protobufjs "~6.10.2" - "@cosmjs/cosmwasm-stargate@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" - integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== + "@cosmjs/cosmwasm-stargate@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.0.tgz#b35bd57edf9aac9008990b366bfad9ece35d71b1" + integrity sha512-XcCedSMNV5/choH3JCXAiwytBq0uqGI2k5tzifjUifnwd4v58hVA4NUIxUaXk4nWJ5Izd8iylCSmR2owH77Eqw== dependencies: - "@cosmjs/amino" "^0.29.5" - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/proto-signing" "^0.29.5" - "@cosmjs/stargate" "^0.29.5" - "@cosmjs/tendermint-rpc" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" - long "^4.0.0" + "@cosmjs/amino" "^0.32.0" + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/proto-signing" "^0.32.0" + "@cosmjs/stargate" "^0.32.0" + "@cosmjs/tendermint-rpc" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" pako "^2.0.2" "@cosmjs/crypto@^0.25.6": @@ -1547,6 +1572,19 @@ Lockfile: elliptic "^6.5.4" libsodium-wrappers "^0.7.6" + "@cosmjs/crypto@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.0.tgz#61de86e158932321aa4f7a49ff09d726a57c33af" + integrity sha512-h8Fuff9QtHeHAZXB8Mjpk8sYQSqOd484GtD1NAJRCqfXifanNUeZOaXAQkcHbA0eg/IYa+ev7+gOPxm9HkSshQ== + dependencies: + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + "@cosmjs/encoding@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" @@ -1565,6 +1603,15 @@ Lockfile: bech32 "^1.1.4" readonly-date "^1.0.0" + "@cosmjs/encoding@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.0.tgz#1b6f5b7e3f4c8c01c7863202e7eb0de9ad91a252" + integrity sha512-dlurY3BOnv/5JTz3ziGPxvJAsfaXHcOpYP+Fqwo2OHGoWxpQJgJub4QG5V530ZQHliX+6Wqp97lFEwstpISedg== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + "@cosmjs/json-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.25.6.tgz#4f888630e84ee114b164758ec5b48f134068656c" @@ -1581,6 +1628,14 @@ Lockfile: "@cosmjs/stream" "^0.29.5" xstream "^11.14.0" + "@cosmjs/json-rpc@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.0.tgz#733548f54db7cdc581d56e7e0e3d6a0b6ff42163" + integrity sha512-BhnPvgbNPjQZnpzstn6+uLGsP2E4IwREbP7L95yTid+IdTrdnFcF8Ol6xXBWsUtVHtUibX+rbK3wSSgEAV0OBA== + dependencies: + "@cosmjs/stream" "^0.32.0" + xstream "^11.14.0" + "@cosmjs/launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.25.6.tgz#c75f5d21be57af55fcb892f929520fa97f2d5bcc" @@ -1615,6 +1670,13 @@ Lockfile: dependencies: bn.js "^5.2.0" + "@cosmjs/math@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.0.tgz#71f960d59813e49d9736674c5ce40b7b63ee0cf4" + integrity sha512-3h12ENHm1B2TuzZY0JrjGyShIkdUAJDmb/xnSPBBJYZH6ZWL4DFLkq2gISq8XSVCBhuNVv4R+cSCdXs8/vSUTw== + dependencies: + bn.js "^5.2.0" + "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" @@ -1637,6 +1699,18 @@ Lockfile: cosmjs-types "^0.5.2" long "^4.0.0" + "@cosmjs/proto-signing@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.0.tgz#3f182552257b68d040d945913356c399281df0ce" + integrity sha512-9401CI0U5rvKMmYrEN4DAl7wvRd5PwfOTPgxoee+O0d3LzK4FUbTjnNIM7DeUi0zaQw/qU3vSbA3ZcMqPifSbQ== + dependencies: + "@cosmjs/amino" "^0.32.0" + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" + "@cosmjs/socket@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.25.6.tgz#7876bc24e1f16315fbb9e97bd63dea65ba90647d" @@ -1657,6 +1731,16 @@ Lockfile: ws "^7" xstream "^11.14.0" + "@cosmjs/socket@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.0.tgz#45bfaa45ae89347e5134cf115fdf2dc680559207" + integrity sha512-fzb9pBJ6RNYdMIpjCv6NHdQ7C9xSJvP0tF/Tfmmq0yexxl/xDkqSghaDub/os7QzN23RHjTreWjrz9Gov4Z5Vg== + dependencies: + "@cosmjs/stream" "^0.32.0" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + "@cosmjs/stargate@^0.25.5", "@cosmjs/stargate@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.25.6.tgz#ed7428aafd8fe1c12dc4b86f7967deb88117f61a" @@ -1691,6 +1775,22 @@ Lockfile: protobufjs "~6.11.3" xstream "^11.14.0" + "@cosmjs/stargate@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.0.tgz#2f1e1af50ad3156747e377a350b39673c664d324" + integrity sha512-Yo3l+A4vdy3ql30cIanY/j2uD3zxRXTQPrn2YUc67qCxacFkf7Fn3N9GdI7D/B2LQlguf/B5OwheizzWucapkw== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/proto-signing" "^0.32.0" + "@cosmjs/stream" "^0.32.0" + "@cosmjs/tendermint-rpc" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" + xstream "^11.14.0" + "@cosmjs/stream@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.25.6.tgz#1bf7536ed919be3fd7fbffa477c98ef5a93eac70" @@ -1705,6 +1805,13 @@ Lockfile: dependencies: xstream "^11.14.0" + "@cosmjs/stream@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.0.tgz#4fba49708172dffc41a37bbf63f69c8c3186330a" + integrity sha512-df3Svup2QwVr6EqmOzv3KTL0sOxN2sKvz4XJItUeDDxXbcEtTB0+kypmsRQihpXCCmetNArdnvbvkPWxsKCq0w== + dependencies: + xstream "^11.14.0" + "@cosmjs/tendermint-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" @@ -1736,6 +1843,22 @@ Lockfile: readonly-date "^1.0.0" xstream "^11.14.0" + "@cosmjs/tendermint-rpc@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.0.tgz#9acf9030ae20631679dfbaa0611ba618ffe3d192" + integrity sha512-bGH3C0CymIzkROltbqw1iXOEkXJkpjdngJu3hdCdB7bD9xbCWOqB9mT+aLpjNAkzSEAHR4nrWv1JF+3PU2Eggg== + dependencies: + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/json-rpc" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/socket" "^0.32.0" + "@cosmjs/stream" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + axios "^1.6.0" + readonly-date "^1.0.0" + xstream "^11.14.0" + "@cosmjs/utils@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" @@ -1746,10 +1869,15 @@ Lockfile: resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== - "@cosmos-kit/core@^2.7.6": - version "2.7.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.6.tgz#391f64b92be667e932859ab22092e91a8b087a23" - integrity sha512-9ORAoY0RLB14ppwMO8I5kvjK9dZUCG/2tMUoMZKtHrLvGnW4vE+tC4FuQW9v23xBwV6MGkoFDxNn1b4j29a2IA== + "@cosmjs/utils@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.0.tgz#128c0d672a289c99239502d06f045e7cdb60f45e" + integrity sha512-9EWhdTtpaNBSDf2i8nwkWWHfgXGumTVAQe4KuC/R0p3A842MiZhpMAU1WxaZkEO0fcvTbfnM/svAIMVcilDtkw== + + "@cosmos-kit/core@^2.7.7": + version "2.7.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.7.tgz#150876ddde226fd236e71a8725a6182ff4722f84" + integrity sha512-i/L66ieq3G8lB1eKXqzEYqFVQp0crsR2IuwqDXxytmy02WAydCZInAGiPXKklCBWecWGR6z305NJUynaWmYjmQ== dependencies: "@chain-registry/types" "0.17.0" "@walletconnect/types" "2.10.4" @@ -1757,56 +1885,55 @@ Lockfile: events "3.3.0" uuid "^9.0.1" - "@cosmos-kit/keplr-extension@^2.5.9": - version "2.5.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.9.tgz#398175e7d60ff11627825f1c27389f3342ba0935" - integrity sha512-9c2XAbKLtnMnWH+pNtSYXeqqSkIsWFW/zL9L7tf6jOov+Y9d6mLmHKfGOadbly3GX9l2RZfvYuZ1NZbCvC5u/w== + "@cosmos-kit/keplr-extension@^2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.10.tgz#4e27d351c3f49adc9eae6167c013dd64672bab28" + integrity sha512-Y9c8NQEoHkUNn3ziurMn7dI7JSkR6JVe8Ji/lnFSVqDqc+dOuGEpVqhn9wSJlZc6xuFm88vj9ry+83XbHuxMDA== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" - "@cosmos-kit/keplr-mobile@^2.4.8": - version "2.4.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.8.tgz#6692ed5290e0eb3be3c51ce7d2972252ce569ce4" - integrity sha512-KUkUuSC9kPyVAJIlLyewwwKmkoUV0otVSy4IyOAbhobf9N6Vun08zh5YVz8xfqM8jdzG6F8saoYDBRWqi4xPWA== + "@cosmos-kit/keplr-mobile@^2.4.10": + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.10.tgz#2444448a3ca77da6b8274ed6a0b1be3c0e325d25" + integrity sha512-+AM7q9bDGMu8aKjU126sACVtvOMQ8+Ex0s1GL5Icybqn/6WDDpmOo801k+nvznx7mwaQP7l0n6OUnwAjU3eAjg== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.6" - "@cosmos-kit/walletconnect" "^2.4.8" + "@cosmos-kit/core" "^2.7.7" + "@cosmos-kit/walletconnect" "^2.4.10" "@cosmos-kit/keplr@^2.4.7": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.10.tgz#148e8d63c2ad5545da5ef54943a31ed1d37ae2d5" - integrity sha512-LBiAZkG9sQ9+efVuIb/afK8JvW0OgJigkkAGA2DIGcwqA7k+b2XbvHLNU6octTYLyR32JoiB7M3xkGeIxBfpNw== + version "2.4.12" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.12.tgz#9e063ede4878fa2c87df94cf09787b5e48738ef5" + integrity sha512-bx5YiWN6BiTQjRTIlWxHgWCeWp0fdT0kRxayj6yMkfGWWmBE9kO6mAWmWjB6+zvKyvRRyddT5ry4WW7Gi7gnGw== dependencies: - "@cosmos-kit/keplr-extension" "^2.5.9" - "@cosmos-kit/keplr-mobile" "^2.4.8" + "@cosmos-kit/keplr-extension" "^2.5.10" + "@cosmos-kit/keplr-mobile" "^2.4.10" - "@cosmos-kit/react-lite@^2.5.7": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.7.tgz#2a6c4e2c9a4712320e72307b7be4d87b012ffb96" - integrity sha512-CHpHw6G0Utf3LhSyONEJUkxuu5wDb9O/C2H+PdYZx50lAn/lBnNaeelQEGQUct0mVdi8XRcjsccjz5JbdjvkBQ== + "@cosmos-kit/react-lite@^2.5.9": + version "2.5.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.9.tgz#1ee73d8db7e7b298c876ac12ff2133fb1bcbe847" + integrity sha512-2RWvR47RCFSyJKtit5g5TjRG504BXDj3mruo5Ukyt5p0n6O+kIDUyz0o1HlVUD4wfxRIr4jgYWU52EDYeYGavQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" "@cosmos-kit/react@^2.9.6": - version "2.9.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.8.tgz#95d1515bd808b76526816dc8d606eca96d5751d5" - integrity sha512-DNmFwoW9TO2a+MvXeJiBfoh+03fFKKQ4jBN4nodKC6CvwTM8i+MnGm2/46gGB/q9iLu2qyVKRkg47uiGqTQZXQ== + version "2.9.11" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.11.tgz#87484a62f46a442d8af7706ccf3ad38fb112b422" + integrity sha512-jlKQ76i0Cb5BxVX7hOX+MwgMQxSxGzg4maORuswD3hh4S4Qi4L2MkDPUIq294Oeaqn8IlTXVjyfVpIcpIwaAtQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.6" - "@cosmos-kit/react-lite" "^2.5.7" - "@interchain-ui/react" "^1.11.0" + "@cosmos-kit/core" "^2.7.7" + "@cosmos-kit/react-lite" "^2.5.9" "@react-icons/all-files" "^4.1.0" - "@cosmos-kit/walletconnect@^2.4.8": - version "2.4.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.8.tgz#62630f06999d1b59fbe4764ae4cb6912a50cf107" - integrity sha512-SUb21ZiK7UTJ6A8Y5GcD6MfS+iy+hrPUYIpTRLobEKt2uwbmMeRP9hIkhvKxN97iTqXK5ay6BPAtmoJunTpv9g== + "@cosmos-kit/walletconnect@^2.4.10": + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.10.tgz#8de2af854a094a2000c9647f9de6d2a7f279bd8e" + integrity sha512-i/vuZPQ8XhLfh0Llv1Ri7FXjqdvh60mfroKnTlqxO2LchxNcIw3MRZkZKuhalgZNQCPRe1ME2bOxwYmat55/Jg== dependencies: - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" "@walletconnect/sign-client" "^2.9.0" "@walletconnect/types" "2.10.4" "@walletconnect/utils" "^2.9.0" @@ -2019,10 +2146,10 @@ Lockfile: minimatch "^3.1.2" strip-json-comments "^3.1.1" - "@eslint/js@8.53.0": - version "8.53.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" - integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== + "@eslint/js@8.54.0": + version "8.54.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" + integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== "@ethersproject/address@^5.6.0": version "5.7.0" @@ -2105,19 +2232,19 @@ Lockfile: "@floating-ui/core" "^1.4.2" "@floating-ui/utils" "^0.1.3" - "@floating-ui/react-dom@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" - integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== + "@floating-ui/react-dom@^2.0.3", "@floating-ui/react-dom@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec" + integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ== dependencies: "@floating-ui/dom" "^1.5.1" "@floating-ui/react@^0.26.0": - version "0.26.1" - resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.1.tgz#a790bd3cff5f334d9e87d3ec132a3dc39d937800" - integrity sha512-5gyJIJ2tZOPMgmZ/vEcVhdmQiy75b7LPO71sYIiDsxGcZ4hxLuygQWCuT0YXHqppt//Eese+L6t5KnX/gZ3tVA== + version "0.26.3" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.3.tgz#1ec435f35e37d5e34577ee89c7abb1eedb3a0c5d" + integrity sha512-iKH8WRR0L/nLiM6qavFZxkyegIZRMxGnM9aKEc71M4wRlUNkgTamjPsOQXy11oZbDOH37MiTbk/nAPn9M2+shA== dependencies: - "@floating-ui/react-dom" "^2.0.2" + "@floating-ui/react-dom" "^2.0.3" "@floating-ui/utils" "^0.1.5" tabbable "^6.0.1" @@ -2126,12 +2253,12 @@ Lockfile: resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== - "@formatjs/ecma402-abstract@1.17.2": - version "1.17.2" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz#d197c6e26b9fd96ff7ba3b3a0cc2f25f1f2dcac3" - integrity sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg== + "@formatjs/ecma402-abstract@1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.0.tgz#e2120e7101020140661b58430a7ff4262705a2f2" + integrity sha512-PEVLoa3zBevWSCZzPIM/lvPCi8P5l4G+NXQMc/CjEiaCWgyHieUoo0nM7Bs0n/NbuQ6JpXEolivQ9pKSBHaDlA== dependencies: - "@formatjs/intl-localematcher" "0.4.2" + "@formatjs/intl-localematcher" "0.5.2" tslib "^2.4.0" "@formatjs/fast-memoize@2.2.0": @@ -2141,40 +2268,52 @@ Lockfile: dependencies: tslib "^2.4.0" - "@formatjs/icu-messageformat-parser@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz#9b13f2710a3b4efddfeb544480f684f27a53483b" - integrity sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q== + "@formatjs/icu-messageformat-parser@2.7.3": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.3.tgz#c8c95e7c9f8141bdb93bea0e92e4fcace19d3c9f" + integrity sha512-X/jy10V9S/vW+qlplqhMUxR8wErQ0mmIYSq4mrjpjDl9mbuGcCILcI1SUYkL5nlM4PJqpc0KOS0bFkkJNPxYRw== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" - "@formatjs/icu-skeleton-parser" "1.6.2" + "@formatjs/ecma402-abstract" "1.18.0" + "@formatjs/icu-skeleton-parser" "1.7.0" tslib "^2.4.0" - "@formatjs/icu-skeleton-parser@1.6.2": - version "1.6.2" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz#00303034dc08583973c8aa67b96534c49c0bad8d" - integrity sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA== + "@formatjs/icu-skeleton-parser@1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.7.0.tgz#796938d6d0ba8fc75bb9edee038d1350bfee32cb" + integrity sha512-Cfdo/fgbZzpN/jlN/ptQVe0lRHora+8ezrEeg2RfrNjyp+YStwBy7cqDY8k5/z2LzXg6O0AdzAV91XS0zIWv+A== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/ecma402-abstract" "1.18.0" tslib "^2.4.0" - "@formatjs/intl-localematcher@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz#7e6e596dbaf2f0c5a7c22da5a01d5c55f4c37e9a" - integrity sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA== + "@formatjs/intl-localematcher@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz#5fcf029fd218905575e5080fa33facdcb623d532" + integrity sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw== dependencies: tslib "^2.4.0" - "@formkit/auto-animate@1.0.0-beta.6": - version "1.0.0-beta.6" - resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz#ed7f8bc47d774a7764756646e9e3432e8be51cb3" - integrity sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w== + "@formkit/auto-animate@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-0.8.1.tgz#bcaba2969609ca3a7453eacd42b383a2739dfa35" + integrity sha512-0/Z2cuNXWVVIG/l0SpcHAWFhGdvLJ8DRvEfRWvmojtmRWfEy+LWNwgDazbZqY0qQYtkHcoEK3jBLkhiZaB/4Ig== "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + "@hapi/hoek@^9.0.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" + integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== + + "@hapi/topo@^5.0.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" + integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hookform/resolvers@^2.8.0": version "2.9.11" resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.11.tgz#9ce96e7746625a89239f68ca57c4f654264c17ef" @@ -2218,20 +2357,19 @@ Lockfile: resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== - "@interchain-ui/react@^1.11.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.13.0.tgz#b9430c6e9fd5d94a81c3f6ce574b0d0142c491d5" - integrity sha512-samY/4jYEeKLf88AUabxnDpGMFm8V3y+xQCDTjecEn2KkNu23J2fonKUQA8F2Rnj7vsTBHxdjZDeT2wLxlcJFA== + "@interchain-ui/react@^1.14.2": + version "1.14.2" + resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.14.2.tgz#2881eff57ce5988abecc4b7205bc2fad121d9c24" + integrity sha512-YA3Dkq4FOUOcKHoH8iTqozowo5VisaT4iPffkGnxkkShlMY/NwC5V4q5WbdkNaefKmlIoUJDKle/Pyx9UL4iyw== dependencies: "@fastify/deepmerge" "^1.3.0" "@floating-ui/dom" "^1.5.2" "@floating-ui/react" "^0.26.0" - "@formkit/auto-animate" "1.0.0-beta.6" + "@formkit/auto-animate" "^0.8.1" "@react-aria/utils" "^3.21.1" - "@vanilla-extract/css" "^1.12.0" - "@vanilla-extract/css-utils" "^0.1.3" - "@vanilla-extract/dynamic" "^2.0.3" - "@vanilla-extract/recipes" "^0.4.0" + "@vanilla-extract/css" "^1.14.0" + "@vanilla-extract/dynamic" "^2.1.0" + "@vanilla-extract/recipes" "^0.5.1" animejs "^3.2.1" bignumber.js "^9.1.1" client-only "^0.0.1" @@ -2259,10 +2397,10 @@ Lockfile: "@swc/helpers" "^0.5.0" intl-messageformat "^10.1.0" - "@internationalized/number@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.3.0.tgz#92233d130a0591085f93be86a9e6356cfa0e2de2" - integrity sha512-PuxgnKE5NJMOGKUcX1QROo8jq7sW7UWLrL5B6Rfe8BdWgU/be04cVvLyCeALD46vvbAv3d1mUvyHav/Q9a237g== + "@internationalized/number@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.4.0.tgz#1c3ebf6ac40ce649d3d97bb835ff0559957f2e1f" + integrity sha512-8TvotW3qVDHC4uv/BVoN6Qx0Dm8clHY1/vpH+dh+XRiPW/9NVpKn1P8d1A+WLphWrMwyqyWXI7uWehJPviaeIw== dependencies: "@swc/helpers" "^0.5.0" @@ -2273,6 +2411,11 @@ Lockfile: dependencies: "@swc/helpers" "^0.5.0" + "@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -2832,91 +2975,91 @@ Lockfile: call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" - "@mui/base@5.0.0-beta.23": - version "5.0.0-beta.23" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.23.tgz#dd10dfc609d8937749521f940965f757fa3c0f2c" - integrity sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw== + "@mui/base@5.0.0-beta.25": + version "5.0.0-beta.25" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.25.tgz#e1bc39f7a2daa9851fa8d0774ae6d89f0453bdc3" + integrity sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg== dependencies: - "@babel/runtime" "^7.23.2" - "@floating-ui/react-dom" "^2.0.2" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@floating-ui/react-dom" "^2.0.4" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" - "@mui/core-downloads-tracker@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.17.tgz#68ec40ea00832fb685f09bd493648b1f68f5baf4" - integrity sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ== + "@mui/core-downloads-tracker@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.19.tgz#9c04ad047c378d857d529ef9c535b60a10b9a47c" + integrity sha512-y4JseIen5pmZs1n9hHy95HKKioKco8f6N2lford2AmjJigVJOv0KsU0qryiCpyuEUZmi/xCduVilHsK9DSkPcA== "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.16.tgz#bd394183b0cfb068d4fa48292cd8d329be8d6b16" - integrity sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.19.tgz#6e0f4e9d89f99517d3c0ee65dee7ac97753755af" + integrity sha512-yjP8nluXxZGe3Y7pS+yxBV+hWZSsSBampCxkZwaw+1l+feL+rfP74vbEFbMrX/Kil9I/Y1tWfy5bs/eNvwNpWw== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.152" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.152.tgz#22efc0dc0e19325759691c81db1ac32da1250481" - integrity sha512-P81QbS/FolrTAjm72N8ndTCYCdPufxJeftNcuc/L4ENHrAo8bV4wcweEyL2AcetfvTgpmGf3QaITrQv8Ts067A== + version "5.0.0-alpha.154" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.154.tgz#c352e164e9f0313317dd8dc1bfd17236fbefbbc8" + integrity sha512-Rrhu8eUknjV6hhPMqq52e/p4/c6rvnu/k0AhysuljsHDZcHThYEZNe1mHFLveQ1RIje2VnJSsgmcNfcZKeOOAg== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.23" - "@mui/system" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/base" "5.0.0-beta.25" + "@mui/system" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" prop-types "^15.8.1" "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.17.tgz#8e11098e52965be3e9ed117d6c107bbe511fac46" - integrity sha512-+y0VeOLWfEA4Z98We/UH6KCo8+f2HLZDK45FY+sJf8kSojLy3VntadKtC/u0itqnXXb1Pr4wKB2tSIBW02zY4Q== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.19.tgz#6b81f6248da04ee73f935a79d81e7819c7115089" + integrity sha512-jSPLXst/YPgDGolhiu4rbethKjLVrI1IkoK8YrFUv8ygxDuhQdsE6+ZqjSSRXk3ytTMf6ghPnQ88OFRk4XjpNw== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.23" - "@mui/core-downloads-tracker" "^5.14.17" - "@mui/system" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" - "@types/react-transition-group" "^4.4.8" + "@babel/runtime" "^7.23.4" + "@mui/base" "5.0.0-beta.25" + "@mui/core-downloads-tracker" "^5.14.19" + "@mui/system" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" + "@types/react-transition-group" "^4.4.9" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" - "@mui/private-theming@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.17.tgz#2fdf9d7df54dcb27e8ae7e00f440eb8310376ec3" - integrity sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g== + "@mui/private-theming@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.19.tgz#f3bae7377f987dc5f40d0c43163ae1ed1f892961" + integrity sha512-U9w39VpXLGVM8wZlUU/47YGTsBSk60ZQRRxQZtdqPfN1N7OVllQeN4cEKZKR8PjqqR3aYRcSciQ4dc6CttRoXQ== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/utils" "^5.14.19" prop-types "^15.8.1" - "@mui/styled-engine@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.17.tgz#7f79d863604076db5278bd38a2eeac44cd2ed336" - integrity sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw== + "@mui/styled-engine@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.19.tgz#dee1d16044a5ef3a783b742381ea4348c159b013" + integrity sha512-jtj/Pyn/bS8PM7NXdFNTHWZfE3p+vItO4/HoQbUeAv3u+cnWXcTBGHHY/xdIn446lYGFDczTh1YyX8G4Ts0Rtg== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@emotion/cache" "^11.11.0" csstype "^3.1.2" prop-types "^15.8.1" "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.17.tgz#441afdd9425b4aad3dea727b0067d367a41f4b58" - integrity sha512-CsftJtCxF3ABigNXikmBJEsI6XQDmeTQNmjaA6wbjYA+29xPMUEQD4Coe+VXGkcc2jrE6Vy8qZ3ytO8QaM9KAw== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.19.tgz#713f66a4515f2a52f965485a081d64690241c879" + integrity sha512-5yARLEJ8zPzY6zpebupK3PqDo6jQBz1s78qXnBju10toP9HT4WEydpYdm+orDAlUUxP8eVlcpK0fVwza9NwbjA== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@mui/private-theming" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" csstype "^3.1.2" hoist-non-react-statics "^3.3.2" @@ -2930,32 +3073,32 @@ Lockfile: jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" - "@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.17.tgz#3e212d1e699d4c777bbe5c6584ae129b1ef7d8bc" - integrity sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg== + "@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.19.tgz#f13387c60af129e4d61dfbf168fcee348ebe952a" + integrity sha512-4e3Q+2nx+vgEsd0h5ftxlZGB7XtkkPos/zWqCqnxUs1l/T70s0lF2YNrWHHdSQ7LgtBu0eQ0qweZG2pR7KwkAw== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/private-theming" "^5.14.17" - "@mui/styled-engine" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/private-theming" "^5.14.19" + "@mui/styled-engine" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" - "@mui/types@^7.2.8": - version "7.2.8" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" - integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== + "@mui/types@^7.2.10": + version "7.2.10" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.10.tgz#13e3e9aa07ee6d593cfacd538e02e8e896d7a12f" + integrity sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ== - "@mui/utils@^5.10.3", "@mui/utils@^5.14.17", "@mui/utils@^5.7.0": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.17.tgz#8e2e7ca58865119eec8c6bdb359f539c25aaf576" - integrity sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ== + "@mui/utils@^5.10.3", "@mui/utils@^5.14.19", "@mui/utils@^5.7.0": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.19.tgz#39a5846a74ba199f1a2b067ea197dc6b9c8f442f" + integrity sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ== dependencies: - "@babel/runtime" "^7.23.2" - "@types/prop-types" "^15.7.9" + "@babel/runtime" "^7.23.4" + "@types/prop-types" "^15.7.11" prop-types "^15.8.1" react-is "^18.2.0" @@ -3163,10 +3306,10 @@ Lockfile: resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== - "@nymproject/node-tester@^1.0.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.2.tgz#7854fb7048b1fd2cf7665dad2b4a08ef0a2fcd39" - integrity sha512-Epn48utGII5QAE9bG7AaNuIE3YA2gsTNNvs11AyYB1B4cXk7RLGORcrZ6QBLUn4S+vxqbiPlX4D5G1CdZZVISQ== + "@nymproject/node-tester@^1.0.0", "@nymproject/node-tester@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" + integrity sha512-VDFdH2ddIcXXamwkMbeHA88Xa/S2iPWh9QxkFggppvHS1d6gmnNHAZxXm3Uuhx7pCpzKldA0OT7qohMg9GW9xg== "@nymproject/nym-validator-client@^0.18.0": version "0.18.0" @@ -3295,6 +3438,75 @@ Lockfile: dependencies: "@octokit/openapi-types" "^18.0.0" + "@parcel/watcher-android-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" + integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== + + "@parcel/watcher-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" + integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== + + "@parcel/watcher-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" + integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== + + "@parcel/watcher-freebsd-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" + integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== + + "@parcel/watcher-linux-arm-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" + integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== + + "@parcel/watcher-linux-arm64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" + integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== + + "@parcel/watcher-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" + integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== + + "@parcel/watcher-linux-x64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" + integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== + + "@parcel/watcher-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" + integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== + + "@parcel/watcher-wasm@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz#73b66c6fbd2a3326ae86a1ec77eab7139d0dd725" + integrity sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA== + dependencies: + is-glob "^4.0.3" + micromatch "^4.0.5" + napi-wasm "^1.1.0" + + "@parcel/watcher-win32-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" + integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== + + "@parcel/watcher-win32-ia32@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" + integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== + + "@parcel/watcher-win32-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" + integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== + "@parcel/watcher@2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" @@ -3303,6 +3515,29 @@ Lockfile: node-addon-api "^3.2.1" node-gyp-build "^4.3.0" + "@parcel/watcher@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" + integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== + dependencies: + detect-libc "^1.0.3" + is-glob "^4.0.3" + micromatch "^4.0.5" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.3.0" + "@parcel/watcher-darwin-arm64" "2.3.0" + "@parcel/watcher-darwin-x64" "2.3.0" + "@parcel/watcher-freebsd-x64" "2.3.0" + "@parcel/watcher-linux-arm-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-musl" "2.3.0" + "@parcel/watcher-linux-x64-glibc" "2.3.0" + "@parcel/watcher-linux-x64-musl" "2.3.0" + "@parcel/watcher-win32-arm64" "2.3.0" + "@parcel/watcher-win32-ia32" "2.3.0" + "@parcel/watcher-win32-x64" "2.3.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -3381,243 +3616,251 @@ Lockfile: resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - "@react-aria/breadcrumbs@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.7.tgz#1d7f5e01887c62516a3e705e59a92e96d315c6c6" - integrity sha512-z+L1gNyWrjZ4Fs0Vo4AkwJicPpEGIestww6r8CiTlt07eo0vCReNmB3oofI6nMJOSu51yef+qqBtFyr0tqBgiw== + "@react-aria/breadcrumbs@^3.5.8": + version "3.5.8" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.8.tgz#243a25621066443e42f2a6a1cb82fe3c558f6dea" + integrity sha512-jeek23igeqXct7S3ShW2jtFUc5g3fS9ZEBZkF64FWBrwfCiaZwb8TcKkK/xFw36/q5mxEt+seNiqnNzvsICJuQ== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/link" "^3.6.1" - "@react-aria/utils" "^3.21.1" - "@react-types/breadcrumbs" "^3.7.1" - "@react-types/shared" "^3.21.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/link" "^3.6.2" + "@react-aria/utils" "^3.22.0" + "@react-types/breadcrumbs" "^3.7.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/button@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.8.4.tgz#0f0afe45ad9dfc4f79b2755983a503e2de74f7f5" - integrity sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg== + "@react-aria/button@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.9.0.tgz#df59e0628917b320c4d1655e23547eb41a9a0f08" + integrity sha512-Jri4OCN+4YmpJDPNQvk1DJoskKD9sdTxZaWWWJdAwoSIunZk3IEBXVvRfKzsEAVtI+UJN25zC2kyjXbVPS2XAA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/calendar@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.2.tgz#a00b2337c0f6c8840aaa9bd5410e95452c5a5e2d" - integrity sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw== + "@react-aria/calendar@^3.5.3": + version "3.5.3" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.3.tgz#225014e7ef3124bdbc915b7283f7c5d378e1a2a9" + integrity sha512-jW48jk0TIe0HAJS+z8zqd8M86FEuqrk1qEIjMWnf8rFnA7hPPpjdjUrY9vSIeC95NcbyZbFnr1bHzQjAIzosQw== dependencies: "@internationalized/date" "^3.5.0" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/calendar" "^3.4.1" - "@react-types/button" "^3.9.0" - "@react-types/calendar" "^3.4.1" - "@react-types/shared" "^3.21.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/calendar" "^3.4.2" + "@react-types/button" "^3.9.1" + "@react-types/calendar" "^3.4.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/checkbox@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.11.2.tgz#9e1045edf282298cb8337fd3fd1d953c6cf5f667" - integrity sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA== + "@react-aria/checkbox@^3.12.0": + version "3.12.0" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.12.0.tgz#a965e975975404ecf1ff867284511e4490a69c21" + integrity sha512-CyFZoI+z9hhyB3wb7IBsZxE30vXfYO2vSyET16zlkJ4qiFMqMiVLE4ekq034MHltCdpAczgP5yfKgNnJOmj7vQ== dependencies: - "@react-aria/label" "^3.7.2" - "@react-aria/toggle" "^3.8.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/checkbox" "^3.5.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-aria/form" "^3.0.0" + "@react-aria/label" "^3.7.3" + "@react-aria/toggle" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/checkbox" "^3.6.0" + "@react-stately/form" "^3.0.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/checkbox" "^3.6.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/combobox@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.7.1.tgz#8fc26008b54bd2d2c6eac6c126c1b2bba5a5e774" - integrity sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ== + "@react-aria/combobox@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.8.0.tgz#1806cd5ea6c11c90802d7c0a0807d93271265c1c" + integrity sha512-lInzzZrH4vFlxmvDpXgQRkkREm7YIx258IRpQqll8Bny2vKMmZoF06zWMbcHP0CjFqYxExQeTjSYx0OTRRxkCQ== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/listbox" "^3.11.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/listbox" "^3.11.2" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/combobox" "^3.7.1" - "@react-stately/layout" "^3.13.3" - "@react-types/button" "^3.9.0" - "@react-types/combobox" "^3.8.1" - "@react-types/shared" "^3.21.0" + "@react-aria/menu" "^3.11.2" + "@react-aria/overlays" "^3.19.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/combobox" "^3.8.0" + "@react-stately/form" "^3.0.0" + "@react-types/button" "^3.9.1" + "@react-types/combobox" "^3.9.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/datepicker@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.8.1.tgz#7ad2ff17799b7601edfc2eef7d2f35086f182897" - integrity sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ== + "@react-aria/datepicker@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.9.0.tgz#281d351b36a3cd186e39f587437d9a3ce9d8986d" + integrity sha512-FIpiJxwBNOM8a6hLOqQJ4JrvRiGL6Zr44E1mHtAWStp2kBEJ6+O2JRm4PQ5Pzvdw6xnCpOBdfESdNdlXN7lVqQ== dependencies: "@internationalized/date" "^3.5.0" - "@internationalized/number" "^3.3.0" + "@internationalized/number" "^3.4.0" "@internationalized/string" "^3.1.1" - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/spinbutton" "^3.5.4" - "@react-aria/utils" "^3.21.1" - "@react-stately/datepicker" "^3.8.0" - "@react-types/button" "^3.9.0" - "@react-types/calendar" "^3.4.1" - "@react-types/datepicker" "^3.6.1" - "@react-types/dialog" "^3.5.6" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/spinbutton" "^3.6.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/datepicker" "^3.9.0" + "@react-stately/form" "^3.0.0" + "@react-types/button" "^3.9.1" + "@react-types/calendar" "^3.4.2" + "@react-types/datepicker" "^3.7.0" + "@react-types/dialog" "^3.5.7" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/dialog@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.7.tgz#e57eca98e95114d618d583f5cc5400bdcf1190b0" - integrity sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q== + "@react-aria/dialog@^3.5.8": + version "3.5.8" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.8.tgz#3b52ff145b16e0f47b04364239bd91d39968e3c2" + integrity sha512-KIc1FORdHhZ3bWom4qHO0hmlL4e5Hup6N25EY8HP5I7Ftv9EBBGaO5grtxZ2fX8kiCJNI4y+k67ZZ71wKJvMiA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/overlays" "^3.18.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/overlays" "^3.6.3" - "@react-types/dialog" "^3.5.6" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/utils" "^3.22.0" + "@react-types/dialog" "^3.5.7" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/dnd@^3.4.3": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.4.3.tgz#f13e438f6613f79988ffa5d6a79c5705c26428d4" - integrity sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA== + "@react-aria/dnd@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.5.0.tgz#de803fa390e73205b600933c7fe45ac888a62f3c" + integrity sha512-6IuqmXwnfgRfeXDbfsPZzScapCmtRIkphTBPoLT575uEbZC7ROLgRJ/4NIKxvtTA6IIBqUGcvaqU9Mpg8j4U5Q== dependencies: "@internationalized/string" "^3.1.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/dnd" "^3.2.5" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/dnd" "^3.2.6" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/focus@^3.14.3": - version "3.14.3" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.14.3.tgz#5e66dbf47e1d92aebf67d52b3b08d1631591f5b6" - integrity sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA== + "@react-aria/focus@^3.15.0": + version "3.15.0" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.15.0.tgz#acca3cfe94e0ba0c00276e74c6cca06975f75f87" + integrity sha512-nnxRyfqHuAjRwdQ4BpQyZPtGFKZmRU6cnaIb3pqWFCqEyJQensV7MA3TJ4Jhadq67cy1Ji5SYSlr1duBwjoYvw== dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" clsx "^1.1.1" - "@react-aria/grid@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.4.tgz#1f19df9b413e843c82a280a40cd863650e424dfd" - integrity sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA== + "@react-aria/form@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.0.0.tgz#d4e892687331a9cba1cfc48be5754100ab736dec" + integrity sha512-APeGph9oTO8nro4ZObuy1hk+0hpF/ji9O3odPGhLkzP/HvW2J7NI9pjKJOINfgtYr2yvVUZf/MbTMxPwtAxhaQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/grid@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.5.tgz#92682b36b230920d507e3ed4fb7e9564f96c9f02" + integrity sha512-0p+Bbs9rpQeOy8b75DamlzVPKylBoe/z0XwkeeTChHP2TK3TwPXh6J5EmisQx6K8zsb3iZULQRcP4QibvnMbrg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/grid" "^3.8.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/checkbox" "^3.5.2" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/grid" "^3.8.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/virtualizer" "^3.6.5" + "@react-types/checkbox" "^3.6.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/gridlist@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.1.tgz#0be67cd3f0d30a6fe76c0f73927f403ca416a555" - integrity sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg== + "@react-aria/gridlist@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.2.tgz#80a1399eba438df9d8d8e721eb98b3bf1acdbe52" + integrity sha512-9keGYZz0yILVqAnFzF6hGRtHm1vfSD1mNnH8oyn7mKjyr7qOln7s5f8Nl85ueMolfrV3H2rCZgM2itNQ+Ezzgg== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/grid" "^3.8.4" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/grid" "^3.8.5" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/list" "^3.10.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/i18n@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.8.4.tgz#e7ecd3edcaa66ceaf9ebb1034395e021685163af" - integrity sha512-YlTJn7YJlUxds/T5dNtme551qc118NoDQhK+IgGpzcmPQ3xSnwBAQP4Zwc7wCpAU+xEwnNcsGw+L1wJd49He/A== + "@react-aria/i18n@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.9.0.tgz#7aa74e02e74e348de3a34b7599e71ff6920b73ee" + integrity sha512-ebGP/sVG0ZtNF4RNFzs/W01tl7waYpBManh1kKWgA4roDPFt/odkgkDBzKGl+ggBb7TQRHsfUFHuqKsrsMy9TA== dependencies: "@internationalized/date" "^3.5.0" "@internationalized/message" "^3.1.1" - "@internationalized/number" "^3.3.0" + "@internationalized/number" "^3.4.0" "@internationalized/string" "^3.1.1" - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/interactions@^3.19.1": - version "3.19.1" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.19.1.tgz#b17b1f9dc84624d4222c7fa0a4fa6b4c14fe125a" - integrity sha512-2QFOvq/rJfMGEezmtYcGcJmfaD16kHKcSTLFrZ8aeBK6hYFddGVZJZk+dXf+G7iNaffa8rMt6uwzVe/malJPBA== + "@react-aria/interactions@^3.20.0": + version "3.20.0" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.20.0.tgz#8db350541004f50c0479cc52b82597d8248ac5db" + integrity sha512-JCCEyK2Nb4mEHucrgmqhTHTNAEqhsiM07jJmmY22eikxnCQnsEfdwXyg9cgZLG79D5V7jyqVRqOp2OsG7Qx7kQ== dependencies: - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/label@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.2.tgz#6563495cad2af9262e722514e88406baede48852" - integrity sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew== + "@react-aria/label@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.3.tgz#37cb12d2a9495534205b6266aa5174c2fd861368" + integrity sha512-v1zuqbpYyYaPjrBWpceGjMpwP4ne6fLoOXdoIZoKLux2jkAcyIF2kIJFiyYoPQYQJWGRNo7q1oSwamxmng4xJw== dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/label" "^3.8.1" - "@react-types/shared" "^3.21.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/link@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.1.tgz#1e196dc2e25af24a713c3bb6d653aae37b67a1a2" - integrity sha512-uVkuNHabxE11Eqeo0d1RA86EckOlfJ2Ld8uN8HnTxiLetXLZYUMBwlZfBJvT3RdwPtTG7jC3OK3BvwiyIJrtZw== + "@react-aria/link@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.2.tgz#4d7fb00000219aa3ff4bd02f59d5d3bd08be0da8" + integrity sha512-v9gXgQ3Gev0JOlg2MAXcubDMgX+0BlJ+hTyFYFMuN/4jVBlAe426WKbjg+6MMzxwukWg9C3Q08JzqdFTi4cBng== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/link" "^3.5.1" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/link" "^3.5.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/listbox@^3.11.1": - version "3.11.1" - resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.1.tgz#2a2c88daf6a67e07ab17440f72a859913161e6e8" - integrity sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg== + "@react-aria/listbox@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.2.tgz#5d1d841987c1fbe300fa5d4bf5071f660b2a625b" + integrity sha512-FXdoqYLUTJn16OxodyS518PIcwzFkCfW5bxQepoy88NDMGtqp6u8fvEPpAoZbomvw/pV9MuEaMAw9qLyfkD4DA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-types/listbox" "^3.4.5" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/list" "^3.10.1" + "@react-types/listbox" "^3.4.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" "@react-aria/live-announcer@^3.3.1": @@ -3627,394 +3870,389 @@ Lockfile: dependencies: "@swc/helpers" "^0.5.0" - "@react-aria/menu@^3.11.1": - version "3.11.1" - resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.1.tgz#fb31c5533d5106c41ed73c14516ecbf74742976a" - integrity sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q== + "@react-aria/menu@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.2.tgz#bf6dbf751acc09ace12d35bb034a3790f9006720" + integrity sha512-I4R5FOvRtwIQW+0naXav5giZBp935X2tXB2xBg/cSAYDXgfLmFPLHkyPbO77hR6FwazfFfJoKdn0pVcRox3lrQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/menu" "^3.5.6" - "@react-stately/tree" "^3.7.3" - "@react-types/button" "^3.9.0" - "@react-types/menu" "^3.9.5" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/menu" "^3.5.7" + "@react-stately/tree" "^3.7.4" + "@react-types/button" "^3.9.1" + "@react-types/menu" "^3.9.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/meter@^3.4.7": - version "3.4.7" - resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.7.tgz#33a7b2d4a0be56d147949bb36f3f32bc545c3a87" - integrity sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA== + "@react-aria/meter@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.8.tgz#af30df03a4c35b13a873ca0847cfa705902b918d" + integrity sha512-u/pNisFs8UottonYlwqaS2i/NhHIw9LcApHo55XP7XMFCnaHPlq3mJzpSsr0zuCTvat2djoKelj41jT6Fhuw+A== dependencies: - "@react-aria/progress" "^3.4.7" - "@react-types/meter" "^3.3.5" - "@react-types/shared" "^3.21.0" + "@react-aria/progress" "^3.4.8" + "@react-types/meter" "^3.3.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/numberfield@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.9.1.tgz#de8bbcfbd971c22311a85a3ab34165c53ff96519" - integrity sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA== + "@react-aria/numberfield@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.10.0.tgz#07d9be63346a0b8e9177a4ca9e4363e03f04afa9" + integrity sha512-ixkvkPTn18RNPnbaT726CHA+Wpr/qTYWboq8hSaJK0LiAtiEWCKg0pmVtJ4lFntAQ5GNp02xudTwhQdLN5WRig== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/spinbutton" "^3.6.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-stately/numberfield" "^3.7.0" + "@react-types/button" "^3.9.1" + "@react-types/numberfield" "^3.7.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/overlays@^3.19.0": + version "3.19.0" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.19.0.tgz#0568d808c61e923174e896fc342a1529538da545" + integrity sha512-VN5GkB8+uZ2cfXljBtkqmrsAhBdGoj4un/agH0Qyihi2dazsMeafczSNnqzbpVgB4Zt2UHPJUkKwihgzXRxJJA== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/overlays" "^3.6.4" + "@react-types/button" "^3.9.1" + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/progress@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.8.tgz#3776ebeecc27c5b03db7a260ab39a92dbf722a21" + integrity sha512-Nah3aj5BNRa0+urQZimzb0vuKQK7lsc8BrUwJuHTwGRBSWUjCADExrJYdhDIR/nLUV2TCmAQl+GJtTgbEEj0DQ== + dependencies: + "@react-aria/i18n" "^3.9.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-types/progress" "^3.5.1" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/radio@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.9.0.tgz#529b796ed3c5731c808af0a3da29e5535fa553b2" + integrity sha512-kr3+OQ1YU/3mURZfCsYaQmJ/c15qOm8uScaDRC39qz97bLNASakQqMImIaS+GluPKx1PEW3y2ErAgLplH28zZw== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/radio" "^3.10.0" + "@react-types/radio" "^3.6.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/searchfield@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.6.0.tgz#dc40310c875ba4edd288392ada7223186c5fd1eb" + integrity sha512-mHaN+sx2SLqluvF0/YIBQ9WA5LakSWl79FgC0sOWEaOZhDswAbJ9tESdi/M/ahtOnVwblE0cpHRlUKV0Oz4gOw== + dependencies: + "@react-aria/i18n" "^3.9.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/searchfield" "^3.5.0" + "@react-types/button" "^3.9.1" + "@react-types/searchfield" "^3.5.2" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/select@^3.14.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.14.0.tgz#81c7a3db9fec6d55f4b2820913207afc39b1600d" + integrity sha512-ulVFH8K1yr8CxQE7pzhlM3aWBltWfSbWdJV3FXDqM0kA+GHqqPwZVJcqPuegtaiju1z6nRk4q789kJa4o+4M9g== + dependencies: + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/listbox" "^3.11.2" + "@react-aria/menu" "^3.11.2" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/select" "^3.6.0" + "@react-types/button" "^3.9.1" + "@react-types/select" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/selection@^3.17.2": + version "3.17.2" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.2.tgz#74b798344df1eb90e3fdae9bc880c0488468ae3b" + integrity sha512-AXXY3eOIWnITabMn6c0bpLPXkSX7040LOZU+7pQgtZJwDdZorLuKw4i7WS5i71LcV71ywG4mtqc9mOb/GfhUbg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/selection" "^3.14.1" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/separator@^3.3.8": + version "3.3.8" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.8.tgz#de209f8158c4dd5d4d66f0a57525bbfdb5b00b15" + integrity sha512-u15HgH2IVKN/mx7Hp9dfNiFpPU/mq2EA7l0e2fsVSjA77nhSctUFBAqaR7FAI/y86RUhq3zplIz4BJek1/3Dvw== + dependencies: + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/slider@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.3.tgz#799b47e8559acf63d9c1195fac88bd4d5ca7cad0" + integrity sha512-AbrTD9UzMn0CwxFjOhJHz2ms2zdJlBL3XnbvqkpsmpXUl0u8WT1QAEaMnS5+792gnSGZs/ARDmse53o+IO8wTA== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/slider" "^3.4.5" + "@react-types/shared" "^3.22.0" + "@react-types/slider" "^3.7.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/spinbutton@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.0.tgz#b881ffd6780f90972879334268634740297197c9" + integrity sha512-I7f1gfwVRcjguEXZijk0z5g8njZ2YWnQzVzcwGf8ocLPxfw1CnSivNCzwVj2ChXPX10uXewXVMLWVCz+BRC9uQ== + dependencies: + "@react-aria/i18n" "^3.9.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/spinbutton" "^3.5.4" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/numberfield" "^3.6.2" - "@react-types/button" "^3.9.0" - "@react-types/numberfield" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" + "@react-aria/utils" "^3.22.0" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/overlays@^3.18.1": - version "3.18.1" - resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.18.1.tgz#b53093b2e1004feff155c81730e0101179cd6c47" - integrity sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw== + "@react-aria/ssr@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.0.tgz#457310129e1447b09d2f4aa2fdd62ab0e668d88c" + integrity sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/overlays" "^3.6.3" - "@react-types/button" "^3.9.0" - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" "@swc/helpers" "^0.5.0" - "@react-aria/progress@^3.4.7": - version "3.4.7" - resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.7.tgz#babee1f4775b7baa1b8e2250c861c98805e3d6ee" - integrity sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g== - dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-types/progress" "^3.5.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/radio@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.8.2.tgz#318fb1bbdc67131181c03002a5d8458405239b85" - integrity sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/radio" "^3.9.1" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/searchfield@^3.5.7": + "@react-aria/switch@^3.5.7": version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.5.7.tgz#00f0be54375967f86e2b3365bd80ea602af021a3" - integrity sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A== + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.7.tgz#b543ac69b5d5dca70c75fc6c80b9c2c9d8191403" + integrity sha512-zBEsB071zzhQ82RwAA42pFLXHgrpya0OoRAsTO6jHZwiaYMsyqJI2eiXd7F6rqklpgyO6k7jOQklGUuoSJW4pA== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/searchfield" "^3.4.6" - "@react-types/button" "^3.9.0" - "@react-types/searchfield" "^3.5.1" - "@react-types/shared" "^3.21.0" + "@react-aria/toggle" "^3.9.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/switch" "^3.5.0" "@swc/helpers" "^0.5.0" - "@react-aria/select@^3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.13.1.tgz#c6d7eda36b8f8887c9baf0f1dea06f30806d71fc" - integrity sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ== + "@react-aria/table@^3.13.2": + version "3.13.2" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.2.tgz#ef73709facdd005d7d0f6051dc9bedb85eb4e58a" + integrity sha512-bJgMx2SZ8SFmTosbv6k1lZ1a0Yw3f8tzWhpIQodCaMHhtI7izA6YqDNx47NeBNYpVm9DFfAoWbb79HFJ+OKIJA== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/listbox" "^3.11.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/select" "^3.5.5" - "@react-types/button" "^3.9.0" - "@react-types/select" "^3.8.4" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/selection@^3.17.1": - version "3.17.1" - resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.1.tgz#12df277b8806fd26093e16f6a2734bd1e6fbb3e2" - integrity sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/separator@^3.3.7": - version "3.3.7" - resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.7.tgz#258f52a64d9ec58d62d3257edac542007b54a142" - integrity sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw== - dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/slider@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.2.tgz#e122bbf945c5ae0f72be1c8977ef9be957c4bdbf" - integrity sha512-io7yJm2jS0gK1ILE9kjClh9zylKsOLbRy748CyD66LDV0ZIjj2D/uZF6BtfKq7Zhc2OsMvDB9+e2IkrszKe8uw== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/radio" "^3.9.1" - "@react-stately/slider" "^3.4.4" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@react-types/slider" "^3.6.2" - "@swc/helpers" "^0.5.0" - - "@react-aria/spinbutton@^3.5.4": - version "3.5.4" - resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz#d1c317838f4ae55d6a2e6c698581e4cf0f2b0c89" - integrity sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg== - dependencies: - "@react-aria/i18n" "^3.8.4" + "@react-aria/focus" "^3.15.0" + "@react-aria/grid" "^3.8.5" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.21.1" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/ssr@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.8.0.tgz#e7f467ac42f72504682724304ce221f785d70d49" - integrity sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A== - dependencies: - "@swc/helpers" "^0.5.0" - - "@react-aria/switch@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.6.tgz#2f3d4b4198f26848fac9876233981b232c151620" - integrity sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w== - dependencies: - "@react-aria/toggle" "^3.8.2" - "@react-stately/toggle" "^3.6.3" - "@react-types/switch" "^3.4.2" - "@swc/helpers" "^0.5.0" - - "@react-aria/table@^3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.1.tgz#843e377b62c695b6559dd0b6ef0d7bdb8f56c358" - integrity sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/grid" "^3.8.4" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/collections" "^3.10.2" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/collections" "^3.10.3" "@react-stately/flags" "^3.0.0" - "@react-stately/table" "^3.11.2" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/checkbox" "^3.5.2" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" + "@react-stately/table" "^3.11.3" + "@react-stately/virtualizer" "^3.6.5" + "@react-types/checkbox" "^3.6.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@react-types/table" "^3.9.1" "@swc/helpers" "^0.5.0" - "@react-aria/tabs@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.1.tgz#89229734a5afccbb9a8a03ac8098b1b3653a948f" - integrity sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-stately/tabs" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@react-types/tabs" "^3.3.3" - "@swc/helpers" "^0.5.0" - - "@react-aria/tag@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.2.1.tgz#1fcfece4fc574f066d32aca005fbfc133ef3c247" - integrity sha512-i7Mj3IhB91sGp3NS6iNBVh25W+LR2XXpTmtn3OS4R62q3Oalw/1PKqPWqFc73Lb5IWF5rj3eh2yTf+rerWf3dw== - dependencies: - "@react-aria/gridlist" "^3.7.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/textfield@^3.12.2": - version "3.12.2" - resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.12.2.tgz#e1ae5abaf72ed9c800e6a8afface3b2fd58258ca" - integrity sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" - "@swc/helpers" "^0.5.0" - - "@react-aria/toggle@^3.8.2": + "@react-aria/tabs@^3.8.2": version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.8.2.tgz#4336f0d70e33347c7bcf43f3ec4e617ce449127b" - integrity sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA== + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.2.tgz#ab11e77e6e9afaebb7549983c0aa0d66ae5d96bf" + integrity sha512-zDfeEEyJmcnH9TFvJECWIrJpxX4SmREFV1/P8hN6ZUJPYoeiGMXYYFvjcRb1r3LN8XKlbwR37AQ3Cn1/yhrUwQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@react-types/switch" "^3.4.2" + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/tabs" "^3.6.2" + "@react-types/shared" "^3.22.0" + "@react-types/tabs" "^3.3.4" "@swc/helpers" "^0.5.0" - "@react-aria/tooltip@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.4.tgz#1be90589f290b09c2a938907124cf72821fb277c" - integrity sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw== + "@react-aria/tag@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.3.0.tgz#ba7b5e2fc3c65f9a37c4737cb96897313174b9f2" + integrity sha512-mANJTcPyut98O4D3cAKaNEV6QFfoljZCDAgC+uJkV/Zn8cU4JOFeNLAyNoLRlPvYw+msqr6wUyPkWNERuO+1Uw== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/tooltip" "^3.4.5" - "@react-types/shared" "^3.21.0" - "@react-types/tooltip" "^3.4.5" + "@react-aria/gridlist" "^3.7.2" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/list" "^3.10.1" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-aria/utils@^3.21.1": - version "3.21.1" - resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.21.1.tgz#35f5d545757ea38f05a0d2f5492f13217ebb03ce" - integrity sha512-tySfyWHXOhd/b6JSrSOl7krngEXN3N6pi1hCAXObRu3+MZlaZOMDf/j18aoteaIF2Jpv8HMWUJUJtQKGmBJGRA== + "@react-aria/textfield@^3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.13.0.tgz#bc8a027f93598a1ebd5013d027549a03d7b8dd04" + integrity sha512-sUlinDE+k/WhbskyqVOkuffuhiQpjgvp+iGRoralStVgb8Tcb+POxgAlw5jS4tNjdivCb3IjVJemUNJM7xsxxA== dependencies: - "@react-aria/ssr" "^3.8.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@react-types/textfield" "^3.9.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/toggle@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.9.0.tgz#c1b253d2fc05f2a673abd9fe4d62bc01a8781a92" + integrity sha512-2YMWYQUEmcoAXtrAE86QXBS9XlmJyV6IFRlMTBNaeLTdH3AmACExgsyU66Tt0sKl6LMDMI376ItMFqAz27BBdQ== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/checkbox" "^3.6.0" + "@swc/helpers" "^0.5.0" + + "@react-aria/tooltip@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.5.tgz#aeb4c71db46f2c9ad0ff0b6810002bdacc07fea1" + integrity sha512-hXw4Z8nYLOWz3QOQ807wWZdvDwR3gofsmZhAehg2HPRwdRfCQK+1cjVKeUd9cKCAxs0Cay7dV0oUdilLbCQ2Gg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/tooltip" "^3.4.6" + "@react-types/shared" "^3.22.0" + "@react-types/tooltip" "^3.4.6" + "@swc/helpers" "^0.5.0" + + "@react-aria/utils@^3.21.1", "@react-aria/utils@^3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.22.0.tgz#962a45ae95fdc21de7f22dda68253b0fb2470d06" + integrity sha512-Qi/m65GFFljXA/ayj1m5g3KZdgbZY3jacSSqD5vNUOEGiKsn4OQcsw8RfC2c0SgtLV1hLzsfvFI1OiryPlGCcw== + dependencies: + "@react-aria/ssr" "^3.9.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" clsx "^1.1.1" - "@react-aria/visually-hidden@^3.8.6": - version "3.8.6" - resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.6.tgz#9b149851ac41e9c72c7819f8d4ad47ddfb45b863" - integrity sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w== + "@react-aria/visually-hidden@^3.8.7": + version "3.8.7" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.7.tgz#059699c70cc354ccb3699151b09071b3fc43fa82" + integrity sha512-OuIGMVQIt7GC43h4x35BgkZid8lhoPu7Xz4TQRP8nvOJWb1lH7ehrRRuGdUsK3y90nwpxTdNdg4DILblg+VaLw== dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - clsx "^1.1.1" "@react-icons/all-files@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== - "@react-stately/calendar@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.1.tgz#8982ca015c81f35154a23fb26a514a08f9b041a5" - integrity sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw== + "@react-stately/calendar@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.2.tgz#7dd55cd2f0689bd0a5825326507dcb6b3d7f3d05" + integrity sha512-RfH40rVa2EhUnQgqH3HTZL+YhL+6tZ8T9GbN1K3AbIM5BBEtkb3P8qGhcaI7WpwNy1rlRFFFXGcqFAMUncDg2Q== dependencies: "@internationalized/date" "^3.5.0" - "@react-stately/utils" "^3.8.0" - "@react-types/calendar" "^3.4.1" - "@react-types/datepicker" "^3.6.1" - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/calendar" "^3.4.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-stately/checkbox@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.5.1.tgz#a6f6ad01852aded85f4baa7c3e97e44d2c47a607" - integrity sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw== + "@react-stately/checkbox@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.6.0.tgz#448da0b07710a120959985fb081ad3855232fdc9" + integrity sha512-e1ChMwGovcOEDcdizqXDT6eDZixIMiPQOzNV5wPQ91SlGaIry9b0lQnK18tHg3yv2iiS6Ipj96cGBUKLJqQ+cQ== dependencies: - "@react-stately/toggle" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/checkbox" "^3.6.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-stately/collections@^3.10.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.2.tgz#c739d9d596ecb744be15fde6f064ad85dd6145db" - integrity sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q== - dependencies: - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/combobox@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.7.1.tgz#d101280d406469479ba954cabd872188634033c4" - integrity sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/select" "^3.5.5" - "@react-stately/utils" "^3.8.0" - "@react-types/combobox" "^3.8.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/data@^3.10.3": + "@react-stately/collections@^3.10.3": version "3.10.3" - resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.10.3.tgz#4cdbb0f29489e6f74d2ae7ae032930336695eaa0" - integrity sha512-cC9mxCZU4N9GbdOB4g2/J8+W+860GvBd874to0ObSc/XOR4VbuIsxAFIabW5UwmJV+XaqqK4TUBG0C6YScXeWQ== + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.3.tgz#c80bd30df3bf5d2a9c6fdf25f6313c5187d0154d" + integrity sha512-fA28HIApAIz9sNGeOVXZJPgV5Kig6M72KI1t9sUbnRUr9Xq9OMJTR6ElDMXNe0iTeZffRFDOPYyqnX9zkxof6Q== dependencies: - "@react-types/shared" "^3.21.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-stately/datepicker@^3.8.0": + "@react-stately/combobox@^3.8.0": version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.8.0.tgz#f87eefb4c5dec937b9d5eb101dd4407457ecd0e7" - integrity sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g== + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.8.0.tgz#6bd9b23ade552f04e8ebc0eeb80e077efed17d6d" + integrity sha512-F74Avf7+8ruRqEB+3Lh6/C5jXc3ESJbRf9ovUxhmNAzBGeFKesPn5HpEpo87C+3OukGb+/Buvi3Rhib9+HVBKA== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-stately/select" "^3.6.0" + "@react-stately/utils" "^3.9.0" + "@react-types/combobox" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/data@^3.11.0": + version "3.11.0" + resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.11.0.tgz#d744d868ee810126aef4a0a827ab394e3059d33a" + integrity sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q== + dependencies: + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/datepicker@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.9.0.tgz#0771c66df937806f812392f8a512a2e72bebbaf0" + integrity sha512-p6BuxPbDxjIgBZmskdv2dR6XIdPEftCjS7kYe/+iLZxfz1vYiDqpJVb3ascLyBjl84bDDyr4z2vWcKhdDwyhEA== dependencies: "@internationalized/date" "^3.5.0" "@internationalized/string" "^3.1.1" - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/datepicker" "^3.6.1" - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/overlays" "^3.6.4" + "@react-stately/utils" "^3.9.0" + "@react-types/datepicker" "^3.7.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-stately/dnd@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.5.tgz#e18c9708133071df911792e85ef6edd2508b3a71" - integrity sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ== + "@react-stately/dnd@^3.2.6": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.6.tgz#683649dce4183890528d8bea08c30f2b11c812f0" + integrity sha512-ex3Pjn+9uIoqsBb9F4ZFJb3fB0YadN8uYBOEiBb9N4UXWyANibGUYJ2FvIbvq1nFDU7On7MW1J9e3vkGglX4FQ== dependencies: - "@react-stately/selection" "^3.14.0" - "@react-types/shared" "^3.21.0" + "@react-stately/selection" "^3.14.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" "@react-stately/flags@^3.0.0": @@ -4024,398 +4262,375 @@ Lockfile: dependencies: "@swc/helpers" "^0.4.14" - "@react-stately/grid@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.2.tgz#b2bd8614489a46ad7d0de13551507afd68d95de2" - integrity sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A== + "@react-stately/form@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-stately/form/-/form-3.0.0.tgz#584af339a128045c357c1b8ca440c87460a41b0f" + integrity sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ== dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - "@react-stately/layout@^3.13.3": - version "3.13.3" - resolved "https://registry.yarnpkg.com/@react-stately/layout/-/layout-3.13.3.tgz#65ca0ad8a4653122017c68ec2dc3a3d592296d02" - integrity sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/table" "^3.11.2" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/list@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.0.tgz#6b2c66778b687d8c197809059f102029a9bb5079" - integrity sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/menu@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.6.tgz#21861b7cfba579d69272509aef8197d3fad7463a" - integrity sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA== - dependencies: - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/menu" "^3.9.5" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/numberfield@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.6.2.tgz#2102d956239721fbf629891d2de46920416492fc" - integrity sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ== - dependencies: - "@internationalized/number" "^3.3.0" - "@react-stately/utils" "^3.8.0" - "@react-types/numberfield" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/overlays@^3.6.3": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.3.tgz#cdfe5edb1ed6ad84fc1022af931586489cb23552" - integrity sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/overlays" "^3.8.3" - "@swc/helpers" "^0.5.0" - - "@react-stately/radio@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.9.1.tgz#c43c88e2bff23d3059b0ea22191337a1d644fe0c" - integrity sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/searchfield@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.4.6.tgz#8d2a394fc20fec559d669e5d63c0a4d7588cb4a0" - integrity sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/searchfield" "^3.5.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/select@^3.5.5": - version "3.5.5" - resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.5.5.tgz#e0b6dc9635bf46632efeba552e7ff3641c2f581f" - integrity sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/select" "^3.8.4" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/selection@^3.14.0": - version "3.14.0" - resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.0.tgz#26a574bf2e35657db1988974df8bd2747b09f5c6" - integrity sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/slider@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.4.tgz#36a3f171077fb0e5bd7af7accdc228f5fd2fbe32" - integrity sha512-tFexbtN50zSo6e1Gi8K9MBfqgOo1eemF/VvFbde3PP9nG+ODcxEIajaYDPlMUuFw5cemJuoKo3+G5NBBn2/AjQ== - dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/utils" "^3.21.1" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@react-types/slider" "^3.6.2" - "@swc/helpers" "^0.5.0" - - "@react-stately/table@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.2.tgz#df78442355f3dd086042ad4bf6473a2aaf31f6c1" - integrity sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/flags" "^3.0.0" - "@react-stately/grid" "^3.8.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/tabs@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.1.tgz#61c010c82ba0d6fde7804245742e0569d6b9eafd" - integrity sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag== - dependencies: - "@react-stately/list" "^3.10.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@react-types/tabs" "^3.3.3" - "@swc/helpers" "^0.5.0" - - "@react-stately/toggle@^3.6.3": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.6.3.tgz#4de25fd458890e37f6c363d058b018e5f11a9882" - integrity sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/tooltip@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.5.tgz#9ba147485d7d7123da91bb417d3722351e90394d" - integrity sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q== - dependencies: - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/tooltip" "^3.4.5" - "@swc/helpers" "^0.5.0" - - "@react-stately/tree@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.3.tgz#d0b3da5db553e64e8f3def5bae45f765f62a3fd8" - integrity sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/utils@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.8.0.tgz#88a45742c58bde804f6cbecb20ea3833915cfdf0" - integrity sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg== - dependencies: - "@swc/helpers" "^0.5.0" - - "@react-stately/virtualizer@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.4.tgz#fab655aa14d30a7241ff5751a0eb80552ac5d751" - integrity sha512-lf3+FDRnyLyY1IhLfwA6GuE/9F3nIEc5p245NkUSN1ngKlXI5PvLHNatiVbONC3wt90abkpMK+WMhu2S/B+4lA== - dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - - "@react-types/breadcrumbs@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.1.tgz#ec89a2acbae7c9637d087ed0a5f17dda76219d76" - integrity sha512-WWC5pQdWkAzJ2hkx4w7f+waDLLvuD9vowKey+bdLoEmKvdaHNLLVUQPEyFm6SQ5+E3pNBWkNx9a+0S9iW6wa+Q== - dependencies: - "@react-types/link" "^3.5.1" - "@react-types/shared" "^3.21.0" - - "@react-types/button@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.0.tgz#66df80cafaa98aaa34c331e927d21fdf4a0bdc4a" - integrity sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/calendar@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.1.tgz#fa12696b3aae5247b3b1dcf747cbc2c5d5d7c30c" - integrity sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/shared" "^3.21.0" - - "@react-types/checkbox@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.5.2.tgz#f463befdd37bc2c9e5c6febd62e53131e8983fa4" - integrity sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/combobox@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.8.1.tgz#ac9c7abcdde708b09fae78b0dd6d88993f6a8177" - integrity sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/datepicker@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.6.1.tgz#07debffdd611da13f6926266687c22b92624b7ab" - integrity sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/calendar" "^3.4.1" - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - - "@react-types/dialog@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.6.tgz#e874f0896d595e5a7f5924165b0db78e5f62fe9d" - integrity sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg== - dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - - "@react-types/grid@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.2.tgz#9434d8ed0a80a64e38b2c95f8bbccfa794fd3888" - integrity sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/label@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.8.1.tgz#b076a0fb955051307bfa3fed7e18ce0dc76d8c7b" - integrity sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/link@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.1.tgz#042cd4f7e7929a53657a5432fd3497056c331b34" - integrity sha512-hX2KpjB7wSuJw5Pia63+WEgEql53VfVG1Vu2cTUJDxfrgUtawwHtxB8B0K3cs3jBanq69amgAInEx0FfqYY0uQ== - dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-types/shared" "^3.21.0" - - "@react-types/listbox@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.5.tgz#c18fbfe38412f7ce42b381fd4aa7bf443dcb6a59" - integrity sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/menu@^3.9.5": - version "3.9.5" - resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.5.tgz#9f67aebda9f491f0e94e2de7a15898c6cabf0772" - integrity sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ== - dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - - "@react-types/meter@^3.3.5": - version "3.3.5" - resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.5.tgz#274dc17b4de985063e74272d82c0052e13bb75e8" - integrity sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg== - dependencies: - "@react-types/progress" "^3.5.0" - "@react-types/shared" "^3.21.0" - - "@react-types/numberfield@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.6.1.tgz#da13f9086181a64a7e2e39f500584bdca20097b3" - integrity sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/overlays@^3.8.3": + "@react-stately/grid@^3.8.3": version "3.8.3" - resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.3.tgz#47132f08ae3a115273036d98b9441a51d4a4ab09" - integrity sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw== + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.3.tgz#42420724084a023c74e50d9c82efd8074179680d" + integrity sha512-JceGSJcuO6Zv+Aq5s2NZvmbMjdPjTtGNQR9kTgXKC/pOfM6FJ58bJiOmEllyN6oawqh4Ey8Xdqk9NuW4l2ctuw== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" - "@react-types/progress@^3.5.0": + "@react-stately/list@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.1.tgz#1d926d4aef5764096ec357da8081ef09081fe5cc" + integrity sha512-iVarLMd7FmMT0H20dRWsFOHHX5+c4gK51AXP2BSr1VtDSfbL4dgaGgu7IaAMVc/rO0au1e1tPM2hutiIFvPcnA== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/menu@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.7.tgz#3232598399b4baebfc577d5f56b4bd5570f400c2" + integrity sha512-bzTmAqzcMNatvyruWlvOdZSmMhz3+mkdxtqaZzYHq+DpR6ka57lIRj8dBnZWQGwV3RypMZfz+X6aIX4kruGVbw== + dependencies: + "@react-stately/overlays" "^3.6.4" + "@react-types/menu" "^3.9.6" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/numberfield@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.7.0.tgz#a0fd05da980dbe510d1d99ea7cf21ce4f9bac1bb" + integrity sha512-DOz4jL7T30KGUXpGh/z80aHf+DEOQfvCHVDfll+IU7p3sd+bbM5uj7JdwXpZgIYUK8KTf2N49sL6lq5uCoxh8w== + dependencies: + "@internationalized/number" "^3.4.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/numberfield" "^3.7.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/overlays@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.4.tgz#1d0d974413fa3f13d97eec2cac5b48c49978d1a0" + integrity sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA== + dependencies: + "@react-stately/utils" "^3.9.0" + "@react-types/overlays" "^3.8.4" + "@swc/helpers" "^0.5.0" + + "@react-stately/radio@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.10.0.tgz#01750b861bfdbb048c6e1bbfb6a97a4f42c29c25" + integrity sha512-d8IgZtUq/4vhE7YhyBVg1QdVoFS0caIcvPumXqtp/5vlDgpUsVy9jSeWtbk0H4FyUcmJlQhRcTylKB9THXY1YQ== + dependencies: + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/radio" "^3.6.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/searchfield@^3.5.0": version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.0.tgz#5fa64897bcf93308c8386a3d0444585cb869e313" - integrity sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ== + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.0.tgz#8493eefd684bc85117b42c7c714f6541afe54816" + integrity sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/searchfield" "^3.5.2" + "@swc/helpers" "^0.5.0" - "@react-types/radio@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.5.2.tgz#399e220e2529b2e7c93aa117d39adcca6dc24d1f" - integrity sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg== + "@react-stately/select@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.6.0.tgz#e77464f3e0367d652866806c1ab61c132c31c49a" + integrity sha512-GvSE4DXmcvdRNUc+ciPU7gedt7LfRO8FFFIzhB/bCQhUlK6/xihUPrGXayzqxLeTQKttMH323LuYFKfwpJRhsA== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-types/select" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" - "@react-types/searchfield@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.1.tgz#9e8d9b4ff16749a821cbba20e0069f5d77a8b9f2" - integrity sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ== + "@react-stately/selection@^3.14.1": + version "3.14.1" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.1.tgz#798b4fbfda940778ae1dc1f2d2390cee97cce2c6" + integrity sha512-96/CerrB6yH4Ad9FkzBzyVerSPjcIj1NBTWTFHo1N+oHECvyGsDxZl7Y4LQR++teFK66FhX5KjCJQGae4IZd6A== dependencies: - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" + "@react-stately/collections" "^3.10.3" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" - "@react-types/select@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.8.4.tgz#564e6d89095d736ed580a733dd8baa7fadab05bc" - integrity sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/shared@^3.21.0": - version "3.21.0" - resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.21.0.tgz#1af41fdf7dfbdbd33bbc1210617c43ed0d4ef20c" - integrity sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg== - - "@react-types/slider@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.6.2.tgz#b401bbbd473b62edc394ac3c41ed6df329d111d4" - integrity sha512-LSvna1gpOvBxOBI5I/CYEtkAshWYwPlxE9F/jCaxCa9Q7E9xZp1hFFGY87iQ1A3vQM5SCa5PFStwOvXO7rA55w== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/switch@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.4.2.tgz#8c0a8f8dfcaae29ccd9409a2beaac0d31a131027" - integrity sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A== - dependencies: - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - - "@react-types/table@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.0.tgz#0053ce5b78f2214afaf7e38cdd96a57eecbd2ff9" - integrity sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg== - dependencies: - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - - "@react-types/tabs@^3.3.3": - version "3.3.3" - resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.3.tgz#8601d9cd03c6aa4cca1227df667ae8cedb58839c" - integrity sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/textfield@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.8.1.tgz#433c82d8f696ed77b1d5e71aadc40cbe378b536c" - integrity sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg== - dependencies: - "@react-types/shared" "^3.21.0" - - "@react-types/tooltip@^3.4.5": + "@react-stately/slider@^3.4.5": version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.5.tgz#f1edf9940bc3cde89ae9d49fda815e16f253dfd5" - integrity sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q== + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.5.tgz#46d4a7e0a1644894e91b12003fa1ba8e0787f4ca" + integrity sha512-lJPZC8seYbnZDqAlZm3/QC95I5iluG8ouwkPMmvtWCz1baayV/jJtfxA/74zR7Vcob9Fe7O57g8Edhz/hv9xOQ== dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@react-types/slider" "^3.7.0" + "@swc/helpers" "^0.5.0" - "@remix-run/router@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.11.0.tgz#e0e45ac3fff9d8a126916f166809825537e9f955" - integrity sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ== + "@react-stately/table@^3.11.3": + version "3.11.3" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.3.tgz#0d9e547fc2e30df174ac4ba3728402f62fb2fc0a" + integrity sha512-r0rzSKbtMG4tjFpCGtXb8p6hOuek03c6rheJE88z4I/ujZ5EmEO6Ps8q0JMNEDCY2qigvKM+ODisMBeZCEkIJg== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/flags" "^3.0.0" + "@react-stately/grid" "^3.8.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@react-types/table" "^3.9.1" + "@swc/helpers" "^0.5.0" + + "@react-stately/tabs@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.2.tgz#a9825d560af58c4f876e7b619c7e8cb29b071887" + integrity sha512-f+U4D1FAVfVVcNRbtKIv4GrO37CLFClYQlXx9zIuSXjHsviapVD2IQSyAmpKo/CbgXhYRMdGwENZdOsmF/Ns7g== + dependencies: + "@react-stately/list" "^3.10.1" + "@react-types/shared" "^3.22.0" + "@react-types/tabs" "^3.3.4" + "@swc/helpers" "^0.5.0" + + "@react-stately/toggle@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.7.0.tgz#abe2f08f37a0f41e6513d4fde3d46f49500bb5cc" + integrity sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g== + dependencies: + "@react-stately/utils" "^3.9.0" + "@react-types/checkbox" "^3.6.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/tooltip@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.6.tgz#e240184dedc35018f7b1e2d46eaca20a90d919bb" + integrity sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA== + dependencies: + "@react-stately/overlays" "^3.6.4" + "@react-types/tooltip" "^3.4.6" + "@swc/helpers" "^0.5.0" + + "@react-stately/tree@^3.7.4": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.4.tgz#57cc57863837092f13b7a3887e1b5c56330b5cac" + integrity sha512-0yvVODBS8WnSivLFX5ccEjCl2NA/8lbEt1E48wVcY1xcXgISNpw5MSGK5jC6YrtJPIqVolQIkNSbMreXGBktIg== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-stately/utils@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.9.0.tgz#9cb2c8eea5dd1b58256ecb436b963c01526bae37" + integrity sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw== + dependencies: + "@swc/helpers" "^0.5.0" + + "@react-stately/virtualizer@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.5.tgz#45891ac24b6aed0aa168e26c61a39d235d204a70" + integrity sha512-v0cZeNCGPMeo3LP4UrGuDo3Xpq7ufNaZyGObgSvdrIW49qK5F02kczcKy6NKg+QfOgC/+Nc9Tof/2S8dcxDrCA== + dependencies: + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + + "@react-types/breadcrumbs@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.2.tgz#3dc0c8ccebf75844efc56ac8e53dc072df083d5f" + integrity sha512-esl6RucDW2CNMsApJxNYfMtDaUcfLlwKMPH/loYsOBbKxGl2HsgVLMcdpjEkTRs2HCTNCbBXWpeU8AY77t+bsw== + dependencies: + "@react-types/link" "^3.5.2" + "@react-types/shared" "^3.22.0" + + "@react-types/button@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.1.tgz#eb54745133bdaad345d8d589021b67ef2882e1c5" + integrity sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/calendar@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.2.tgz#a184851c2c891e8baa06e3d11173bb4bf101a48b" + integrity sha512-tCZ21un/8OAhpNtmSXDkOVvS5Pzp+y/JwNr6VGFi8HBC5F/c8SzuwV0jKN8ymsZSWbDQ68xXGNWxFaG43Bw8Pg== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/shared" "^3.22.0" + + "@react-types/checkbox@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.6.0.tgz#ba702be25555c1520f78be39c8260354638792b6" + integrity sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/combobox@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.9.0.tgz#f671da0357cfe3a06a24a239fcfacc5b3e5125d0" + integrity sha512-VAQWM2jrIWROgcTKxj4k37WWpK/1zRjj1HfGeuenAQyOQwImqDwCHx5YxQR1GiUEFne4v1yXe2khT0T5Kt2vDg== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/datepicker@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.7.0.tgz#f44632994a0cdd20f350b40910f61a7c89091810" + integrity sha512-Uh+p6pZpMFc5ZBOns5TXCBbUvJp1KVROLBn2gk5dMEFVq78Qs1VFuAt4lwr9gQBOJrX5I/l65pRTwwWwAKxYtQ== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/calendar" "^3.4.2" + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + + "@react-types/dialog@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.7.tgz#3fd93875ff317d6014e814b6e1a2abb87272a1ef" + integrity sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + + "@react-types/grid@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.3.tgz#20b19b73315343630145ff9e43138e7f2855d946" + integrity sha512-GQM4RDmYhstcYZ0Odjq+xUwh1fhLmRebG6qMM8OXHTPQ77nhl3wc1UTGRhZm6mzEionplSRx4GCpEMEHMJIU0w== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/link@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.2.tgz#b363abca3365adc64b49c47163ce00235c01c667" + integrity sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/listbox@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.6.tgz#da0887dbb89a868d53b87486111bf0a51042da7b" + integrity sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/menu@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.6.tgz#1b36842cbdb4590dfff78437316aec4a3f47b1f6" + integrity sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + + "@react-types/meter@^3.3.6": + version "3.3.6" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.6.tgz#ae5960b27012f52ca33970f2ff416af71dad274d" + integrity sha512-1XYp1fA9UU0lO6kjf3TwVE8mppOJa64mBKAcLWtTyq1e/cYIAbx5o6CsuUx0YDpXKF6gdtvIWvfmxeWsmqJ1jQ== + dependencies: + "@react-types/progress" "^3.5.1" + + "@react-types/numberfield@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.7.0.tgz#a029bf2a8a07049c96ea5ffe1f7533ab2305bcf4" + integrity sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/overlays@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.4.tgz#a538f6f2fb9826f1da78d3b4f0f6326a709ce37d" + integrity sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/progress@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.1.tgz#b988cd2d2ff194c7652d74f714b230f26ab73c6c" + integrity sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/radio@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.6.0.tgz#519e4aa40dbb2a13852a5a6f36299a84639376a5" + integrity sha512-VOZzegxxZS55gHRVyWu278Q4y/rEQGiAVQCUqi25GmpbMe4MlHrzg16c76RiZMUK9PPoyv+XNUgAaPmxebkn7g== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/searchfield@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.2.tgz#e663899f42344243ea7b4cd6f0ab0bfe6020151e" + integrity sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA== + dependencies: + "@react-types/shared" "^3.22.0" + "@react-types/textfield" "^3.9.0" + + "@react-types/select@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.9.0.tgz#ddc1238194776ef161260547d25038409885ced8" + integrity sha512-0nalGmcoma4jreICLSJae/uKAuMiVyWgqWjGrGiUGGcdDchH4limKVEqNDaBwLvxVT6NB5LLsaipCTCAEEl4Rg== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/shared@^3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.22.0.tgz#70f85aad46cd225f7fcb29f1c2b5213163605074" + integrity sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA== + + "@react-types/slider@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.7.0.tgz#d9e4dbe1b2109c7accfcc0e2e330ff10cd3a837c" + integrity sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/switch@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.5.0.tgz#8ebf07c60aef22b181eb4ab884cf3d2abddd66c6" + integrity sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/table@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.1.tgz#5d1304d412bc7e637e832e86fcb8724e61c20735" + integrity sha512-3e+Oouw9jGqNDg+JRg7v7fgPqDZd6DtST9S/UPp81f32ntnQ8Wsu7S/J4eyLHu5CVQDqcHkf4xPeeXBgPx4qmw== + dependencies: + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + + "@react-types/tabs@^3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.4.tgz#43fa93a4a67dcc53031afc56a8ad3bf5f44473a8" + integrity sha512-4mCTtFrwMRypyGTZCvNYVT9CkknexO/UYvqwDm2jMYb8JgjRvxnomu776Yh7uyiYKWyql2upm20jqasEOm620w== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/textfield@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.9.0.tgz#ad29f0a70421f9d2cd6cf2795df10a7712954e69" + integrity sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA== + dependencies: + "@react-types/shared" "^3.22.0" + + "@react-types/tooltip@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.6.tgz#1f1eb22873a5d5ad355e0de1be46f48759b55f6f" + integrity sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + + "@remix-run/router@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065" + integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -4457,9 +4672,9 @@ Lockfile: resolve "^1.22.1" "@rollup/pluginutils@^5.0.1": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz#bbb4c175e19ebfeeb8c132c2eea0ecb89941a66c" - integrity sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -4470,75 +4685,92 @@ Lockfile: resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== - "@sentry-internal/tracing@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.77.0.tgz#f3d82486f8934a955b3dd2aa54c8d29586e42a37" - integrity sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw== + "@sentry-internal/tracing@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.84.0.tgz#430da253ee5b075be4ef57f20ea842c0208bc6b0" + integrity sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ== dependencies: - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" - "@sentry/browser@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.77.0.tgz#155440f1a0d3a1bbd5d564c28d6b0c9853a51d72" - integrity sha512-nJ2KDZD90H8jcPx9BysQLiQW+w7k7kISCWeRjrEMJzjtge32dmHA8G4stlUTRIQugy5F+73cOayWShceFP7QJQ== + "@sentry/browser@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.84.0.tgz#7c82470f0afbb6178f26127894e40e9ce2b1e6d6" + integrity sha512-X50TlTKY9WzAnHsYc4FYrCWgm+CdVo0h02ggmodVBUpRLUBjj+cs5Q1plov/v/XeorSwmorNEMUu/n+XZNSsrA== dependencies: - "@sentry-internal/tracing" "7.77.0" - "@sentry/core" "7.77.0" - "@sentry/replay" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry-internal/tracing" "7.84.0" + "@sentry/core" "7.84.0" + "@sentry/replay" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" - "@sentry/core@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.77.0.tgz#21100843132beeeff42296c8370cdcc7aa1d8510" - integrity sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg== + "@sentry/core@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.84.0.tgz#01d33fc452044ffd8ea57b20f60304b9cfa2b9e1" + integrity sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA== dependencies: - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" "@sentry/integrations@^7.54.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.77.0.tgz#f2717e05cb7c69363316ccd34096b2ea07ae4c59" - integrity sha512-P055qXgBHeZNKnnVEs5eZYLdy6P49Zr77A1aWJuNih/EenzMy922GOeGy2mF6XYrn1YJSjEwsNMNsQkcvMTK8Q== + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.84.0.tgz#3b016903e08f0dade74bbc152ea5605e231e39cd" + integrity sha512-aUu95BhnHSf/W/F4BvsFnf4x+piHiah5a180YTMqWcHMkJr7MnCWNIad9RJuHlcINSfyHtUr5+Z4Bajzqg60lw== dependencies: - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" localforage "^1.8.1" "@sentry/react@^7.54.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.77.0.tgz#9da14e4b21eae4b5a6306d39bb7c42ef0827d2c2" - integrity sha512-Q+htKzib5em0MdaQZMmPomaswaU3xhcVqmLi2CxqQypSjbYgBPPd+DuhrXKoWYLDDkkbY2uyfe4Lp3yLRWeXYw== + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.84.0.tgz#2cb3192f7fb67b7696e8ece08d67229b193ddaa4" + integrity sha512-VQZrEHwPKCYTSbRYXD2ohXcQg99G1Hgs8eevRUuRpdChmA2e3z/RvT00NlaSNNZrS86wPyKpAK6kickB/eSYrw== dependencies: - "@sentry/browser" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/browser" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" hoist-non-react-statics "^3.3.2" - "@sentry/replay@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.77.0.tgz#21d242c9cd70a7235237216174873fd140b6eb80" - integrity sha512-M9Ik2J5ekl+C1Och3wzLRZVaRGK33BlnBwfwf3qKjgLDwfKW+1YkwDfTHbc2b74RowkJbOVNcp4m8ptlehlSaQ== + "@sentry/replay@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.84.0.tgz#7e17876d9a1802ee33800e2b2cbda4e026c0a2af" + integrity sha512-c4PxT0ZpvkR9zXNfmAk3ojkm6eZ9+NlDze09RFBOCNo69QwIN90hnvbjXFC1+vRIJsfgo78Zr0ya/Wzb3Rog7Q== dependencies: - "@sentry-internal/tracing" "7.77.0" - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry-internal/tracing" "7.84.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" - "@sentry/types@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144" - integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA== + "@sentry/types@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.84.0.tgz#e8db86c36c61659c3b2558f0aa8b6a073a756117" + integrity sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA== - "@sentry/utils@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.77.0.tgz#1f88501f0b8777de31b371cf859d13c82ebe1379" - integrity sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g== + "@sentry/utils@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.84.0.tgz#32861d922fa31e86dd2863a1d9dfc5a369e98952" + integrity sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ== dependencies: - "@sentry/types" "7.77.0" + "@sentry/types" "7.84.0" + + "@sideway/address@^4.1.3": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" + integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== + dependencies: + "@hapi/hoek" "^9.0.0" + + "@sideway/formula@^3.0.1": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" + integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== + + "@sideway/pinpoint@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" + integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== "@sigstore/bundle@^1.1.0": version "1.1.0" @@ -5113,13 +5345,13 @@ Lockfile: ts-dedent "^2.0.0" util-deprecate "^1.0.2" - "@storybook/channels@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" - integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== + "@storybook/channels@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.2.tgz#77bb8ea5bda33fc00fea30954c15f2bdc4f74a5d" + integrity sha512-pSVpnMAfMsImPyAorYPcfkZmBY34+eHmcj8Zab0m/36/M0AQrUq7VSxA+7KD3rhoZaJjioeouxqigjiznNAbZw== dependencies: - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -5159,10 +5391,10 @@ Lockfile: core-js "^3.8.2" global "^4.4.0" - "@storybook/client-logger@7.5.3", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" - integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== + "@storybook/client-logger@7.6.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.2.tgz#4362d53e24464945fc711dcf0dcfb9b4b1c53586" + integrity sha512-9hlDm7q6jZPVBoqW8V7DTMNMsjMaL2t45h+I8veQhnC2ZW6g+lARXQQDHZpL6MKVkJn6mEA9F0nJBIknbQpqBQ== dependencies: "@storybook/global" "^5.0.0" @@ -5269,10 +5501,10 @@ Lockfile: dependencies: core-js "^3.8.2" - "@storybook/core-events@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" - integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== + "@storybook/core-events@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.2.tgz#13198c8020601fd74ec4eb53852f20e7f0bd68b5" + integrity sha512-JciGNDclg3hx+WkXsAzcCBYWk0xsyIbyCAwqN7XVHUpGndR/dl97Qum5MkO9kPb8r5toKpeBOQo5Kxo2GiE0dg== dependencies: ts-dedent "^2.0.0" @@ -5369,10 +5601,10 @@ Lockfile: dependencies: lodash "^4.17.15" - "@storybook/csf@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.1.tgz#abccc8c3e49aed0a6a7e87beb0d1c262b1921c06" - integrity sha512-4hE3AlNVxR60Wc5KSC68ASYzUobjPqtSKyhV6G+ge0FIXU55N5nTY7dXGRZHQGDBPq+XqchMkIdlkHPRs8nTHg== + "@storybook/csf@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.2.tgz#8e7452f0097507f5841b5ade3f5da1525bc9afb2" + integrity sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA== dependencies: type-fest "^2.19.0" @@ -5406,15 +5638,17 @@ Lockfile: global "^4.4.0" "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.3.tgz#de875ba10db3b5a06a1acbc27a8b1f8fb1d875ff" - integrity sha512-p6b+/6ohTCKxWn00bXT8KBqVjXUOxeILnJtLlG83USLQCpI+XVkpmK57HYuydqEwy/1XjG+4S4ntPk9VVz3u7w== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.6.2.tgz#1db5415ec268e49773cd44573baea6011b0e8c23" + integrity sha512-IQQh0troFy0naXJUc47UtqJ1Bcs4SaBBxxCMlUeJLML1w0EjBSNCB6kewTU/DfjlkFm8a7YnEwxPTEh1dZiq8w== dependencies: - "@storybook/channels" "7.5.3" - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" + "@storybook/channels" "7.6.2" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.5.3" + "@storybook/preview-api" "7.6.2" + "@vitest/utils" "^0.34.6" + util "^0.12.4" "@storybook/manager-webpack4@6.5.16": version "6.5.16" @@ -5530,17 +5764,17 @@ Lockfile: dependencies: core-js "^3.8.2" - "@storybook/preview-api@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" - integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== + "@storybook/preview-api@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.2.tgz#2b0158341510cfa87babaa13d8077a0741e2664d" + integrity sha512-5scmFblrBKBLQSZVlwNUCXhos8GJ8alzMSs0msAbguytjWEuNQ2EKoO7EoO3wvaYf7K3mkOg082RU9nH8SM6mg== dependencies: - "@storybook/channels" "7.5.3" - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" - "@storybook/csf" "^0.1.0" + "@storybook/channels" "7.6.2" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" + "@storybook/csf" "^0.1.2" "@storybook/global" "^5.0.0" - "@storybook/types" "7.5.3" + "@storybook/types" "7.6.2" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -5721,12 +5955,12 @@ Lockfile: memoizerific "^1.11.3" regenerator-runtime "^0.13.7" - "@storybook/types@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" - integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== + "@storybook/types@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.2.tgz#4db470df5cba3da244d979fbdaafafa45b0e0f4d" + integrity sha512-GlEkG4D/BFuPrLGpTkrfmeLM/fEki0FTnMs1SgNQL10wl6Y98EDJWvCItPVPBoGBERpShxEmkSi2HmcySWZgsA== dependencies: - "@storybook/channels" "7.5.3" + "@storybook/channels" "7.6.2" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -6054,14 +6288,14 @@ Lockfile: "@types/estree" "*" "@types/aria-query@^5.0.1": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.3.tgz#07570ebd25f9b516c910a91f7244052c9b58eabc" - integrity sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA== + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" - integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -6070,206 +6304,206 @@ Lockfile: "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.6" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" - integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== + version "7.6.7" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" + integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" - integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" - integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== + version "7.20.4" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== dependencies: "@babel/types" "^7.20.7" "@types/big.js@^6.1.6": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.1.tgz#0e5eda9b8ffe33e2cc4540fad6e91a4c7255ca88" - integrity sha512-dKzZVT10m3ELZgYIShPJ+3Os/E1s3aDQS+wr1ne7VCLU/8hc/R+z/+gkm9WabxSkV9E8wJhTl5wC+0fD9nitsw== + version "6.2.2" + resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.2.tgz#69422ec9ef59df1330ccfde2106d9e1159a083c3" + integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== "@types/body-parser@*": - version "1.19.4" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462" - integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA== + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" "@types/bonjour@^3.5.9": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8" - integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg== + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" "@types/bs58@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.3.tgz#0ccc90341c886acb7abeb42c6f848403a6a021af" - integrity sha512-yVMwEsD7S5YU372eUWAmFRmTqF6EUSqs1Tj2X1kD0hiA4YlE33BhC3tELKLVYpZQEc5gLIQX2BAXmJdXaBARXA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.4.tgz#49fbcb0c7db5f7cea26f0e0f61dc4a41a2445aab" + integrity sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g== dependencies: "@types/node" "*" base-x "^3.0.6" "@types/connect-history-api-fallback@^1.3.5": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc" - integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" "@types/connect@*": - version "3.4.37" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5" - integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q== + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/d3-array@^3.0.3": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.0.tgz#603b85d0072962bdecaf8391f60eea465c8dc282" - integrity sha512-tjU8juPSfhMnu6mJZPOCVVGba4rZoE0tjHDPb81PYwA8CzbaFscGjgkUM7juUJu6iWA1cCVWNEVwxZ5HN9Jj8Q== + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== "@types/d3-color@*": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.2.tgz#7939eed011a908287cd1bcfd11580c17b2ac7f8a" - integrity sha512-At+Ski7dL8Bs58E8g8vPcFJc8tGcaC12Z4m07+p41+DRqnZQcAlp3NfYjLrhNYv+zEyQitU1CUxXNjqUyf+c0g== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== "@types/d3-color@^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.4.tgz#d8a270d6fd864977ea339899a0dfb35974da93a4" - integrity sha512-KsjVf5gjylqqZIsRxYPiFQIY8NvmJEmA9nMrJT0yCcpABhvYzhjoCCPCjaYMANp96GBdS4VXRfhHWnCTudDdJg== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.5.tgz#23bb1afda325549c6314ab60aa2aa28c4c6b1c37" + integrity sha512-5sNP3DmtSnSozxcjqmzQKsDOuVJXZkceo1KJScDc1982kk/TS9mTPc6lpli1gTu1MIBF1YWutpHpjucNWcIj5g== "@types/d3-dsv@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.5.tgz#c12df56be81d0b457d167842fa87276d0d6eb880" - integrity sha512-73WZR3QFOaSRVz9iOrebTbTnbo7xjcgS/i0Cq5zy0jMXPO3v/JbkTD3Zqii1eYE6v4EJ78g5VP407rm+p8fdlA== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== "@types/d3-ease@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.1.tgz#ef386d2f28602dba82206888047f97f7f7f7558a" - integrity sha512-VZofjpEt8HWv3nxUAosj5o/+4JflnJ7Bbv07k17VO3T2WRuzGdZeookfaF60iVh5RdhVG49LE5w6LIshVUC6rg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== "@types/d3-fetch@^3.0.1": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.5.tgz#0bec3763a04d199ad8bce2756b6f6818ee188b32" - integrity sha512-Rc8pb6H0RRLpAV2hEXduykUgcDUOhjSLTLmCIeo6ejzgs4SaITh/EteMb3p5Env3Hqjsqw0fCksyqopHHzMkMg== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== dependencies: "@types/d3-dsv" "*" "@types/d3-geo@^1": - version "1.12.6" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.6.tgz#127802904cd656e9a8c45489d3110a1f87fbacb7" - integrity sha512-ZUjOG+unedpNb2IGYau7WdQcoGQjrVnVrpAdJTcIE1g7wD4kR4rHQy7JYPu+5iZ2C8DOXQnbtsyimo2fP2AykA== + version "1.12.7" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.7.tgz#595680bf9b9525031cef956ed80baf38b8f3b4be" + integrity sha512-QetZrWWjuMfCe0BHLjD+dOThlgk7YGZ2gj+yhFAbDN5TularNBEQiBs5/CIgX0+IBDjt7/fbkDd5V70J1LjjKA== dependencies: "@types/geojson" "*" "@types/d3-geo@^3.0.2": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.6.tgz#138821c463c67551e1cc13729f0211986c5c3cce" - integrity sha512-wblAES3b+C3hvp4VakwECEKtHquT/xc6K4HOna95LM1j1fd7s7WmU4V+JMQZfKhNCMkV2vWD+ZUgY2Uj6gqfuA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== dependencies: "@types/geojson" "*" "@types/d3-interpolate@^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.4.tgz#cae4c7e7da8649a869cb4f25e62f289b43c86167" - integrity sha512-iZOtsYamYn0qP8f4U7EtQV4JqR/2z0Mp9AxUdPnuC+D8ovmnw/ZFvpoC0mVKJ9eZzrA/fscGr3/R9892F5RRxg== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.5.tgz#7964699575ec9c594a9a7aaea411a812ce6cd674" + integrity sha512-k9L18hXXv7OvK4PqW1kSFYIzasGOvfhPUWmHFkoZ8/ci99EAmY4HoF6zMefrHl0SGV7XYc7Qq2MNh8dK3edg5A== dependencies: "@types/d3-color" "^1" "@types/d3-interpolate@^3.0.1": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.3.tgz#e10c06c4bf11bd770ed56184a0d76cd516ff4ded" - integrity sha512-6OZ2EIB4lLj+8cUY7I/Cgn9Q+hLdA4DjJHYOQDiHL0SzqS1K9DL5xIOVBSIHgF+tiuO9MU1D36qvdIvRDRPh+Q== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== dependencies: "@types/d3-color" "*" "@types/d3-path@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.1.tgz#6171c9e388904014764661a37613e3c4ab8df22d" - integrity sha512-blRhp7ki7pVznM8k6lk5iUU9paDbVRVq+/xpf0RRgSJn5gr6SE7RcFtxooYGMBOc1RZiGyqRpVdu5AD0z0ooMA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.2.tgz#4327f4a05d475cf9be46a93fc2e0f8d23380805a" + integrity sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA== "@types/d3-scale@^4.0.1", "@types/d3-scale@^4.0.2": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.6.tgz#9d221949f37b90b52696ec99f9b1e972d55fe10d" - integrity sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ== + version "4.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb" + integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== dependencies: "@types/d3-time" "*" "@types/d3-selection@^1": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.5.tgz#a0f436406ec3586f705fbe5d64cf1b5b28b25119" - integrity sha512-87ZWS/UZ+t1gJ0Ras1iWcyWOxOuzPhPfeEdTN19IyEHK28ssS3KI7orQZ3Eqyijhuvm7vxePh+U0cL79H9g41Q== + version "1.4.6" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.6.tgz#3e6056117b19d8bb6c729c872ca7234622099fb6" + integrity sha512-0MhJ/LzJe6/vQVxiYJnvNq5CD/MF6Qy0dLp4BEQ6Dz8oOaB0EMXfx1GGeBFSW+3VzgjaUrxK6uECDQj9VLa/Mg== "@types/d3-shape@^3.1.0": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.4.tgz#748a256d5e499cdfb3e48beca9c557f3ea0ff15c" - integrity sha512-M2/xsWPsjaZc5ifMKp1EBp0gqJG0eO/zlldJNOC85Y/5DGsBQ49gDkRJ2h5GY7ZVD6KUumvZWsylSbvTaJTqKg== + version "3.1.6" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72" + integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== dependencies: "@types/d3-path" "*" "@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.2.tgz#f4425b2ebcb04495a7b2390da03633ef1a8adbe5" - integrity sha512-kbdRXTmUgNfw5OTE3KZnFQn6XdIc4QGroN5UixgdrXATmYsdlPQS6pEut9tVlIojtzuFD4txs/L+Rq41AHtLpg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be" + integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== "@types/d3-timer@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.1.tgz#8dac23292df0e559a3aa459d8efca78a734c3fbe" - integrity sha512-GGTvzKccVEhxmRfJEB6zhY9ieT4UhGVUIQaBzFpUO9OXy2ycAlnPCSJLzmGGgqt3KVjqN3QCQB4g1rsZnHsWhg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== "@types/d3-zoom@^1": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.6.tgz#3c29d9549789419c55f98f2dccc52349838c5e15" - integrity sha512-MBQ34pRegwb+I59RexzTLTX09QqN1bJlXUd8oTbQjlUOWfuh0Fo0DV/D8Y6Lly+x3rfbVqIP61vdY/LhzQf6DA== + version "1.8.7" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.7.tgz#0afdcf771e6ea518f3a4b634bbb4c8e8979c65b1" + integrity sha512-HJWci3jXwFIuFKDqGn5PmuwrhZvuFdrnUmtSKCLXFAWyf2lAIUKMKh1/lHOkWBl/f4KVupGricJiqkQy+cVTog== dependencies: "@types/d3-interpolate" "^1" "@types/d3-selection" "^1" "@types/debug@^4.0.0": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.10.tgz#f23148a6eb771a34c466a4fc28379d8101e84494" - integrity sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA== + version "4.1.12" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== dependencies: "@types/ms" "*" "@types/eslint-scope@^3.7.3": - version "3.7.6" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" - integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.44.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" - integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== + version "8.44.8" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.8.tgz#f4fe1dab9b3d3dd98082d4b9f80e59ab40f1261c" + integrity sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw== dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree-jsx@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.2.tgz#758bcb4f35f2a970362b2bd2b7021fe2ae6e8509" - integrity sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.3.tgz#f8aa833ec986d82b8271a294a92ed1565bf2c66a" + integrity sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w== dependencies: "@types/estree" "*" "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" - integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/estree@^0.0.51": version "0.0.51" @@ -6277,9 +6511,9 @@ Lockfile: integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.39" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8" - integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ== + version "4.17.41" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== dependencies: "@types/node" "*" "@types/qs" "*" @@ -6287,9 +6521,9 @@ Lockfile: "@types/send" "*" "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": - version "4.17.20" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433" - integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw== + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -6304,14 +6538,14 @@ Lockfile: "@types/node" "*" "@types/flat@^5.0.2": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.4.tgz#d8262918655d942cb0b79f09020240d5ff668557" - integrity sha512-Qy8SOE+x5F40jebCj4vPoA/Y6J2Zd6h9ihMPYP8U8//dDEOK4Yu0ShOTKqEmWPR+4AdV4sls/VCaR6azEFvKKg== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.5.tgz#2304df0b2b1e6dde50d81f029593e0a1bc2474d3" + integrity sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q== "@types/geojson@*", "@types/geojson@^7946.0.8": - version "7946.0.12" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.12.tgz#0307536218d32e6b970bccd1d148b9c4e5b6f10d" - integrity sha512-uK2z1ZHJyC0nQRbuovXFt4mzXDwf27vQeUWNhfKGwRcWW429GOhP8HxUHlM6TLH4bzmlv/HlEjpvJh3JfmGsAA== + version "7946.0.13" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.13.tgz#e6e77ea9ecf36564980a861e24e62a095988775e" + integrity sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ== "@types/glob@*": version "8.1.0" @@ -6330,16 +6564,16 @@ Lockfile: "@types/node" "*" "@types/graceful-fs@^4.1.2": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" - integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" "@types/hast@^2.0.0": - version "2.3.7" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.7.tgz#5e9bd7ab4452d5313aeec9d38fbc193a70f8d810" - integrity sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.8.tgz#4ac5caf38b262b7bd5ca3202dda71f0271635660" + integrity sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ== dependencies: "@types/unist" "^2" @@ -6354,45 +6588,45 @@ Lockfile: integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-errors@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62" - integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/http-proxy@^1.17.8": - version "1.17.13" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465" - integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw== + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== dependencies: "@types/node" "*" "@types/is-function@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.2.tgz#1f29acd54f5473f0b4822548e27078eac4e450d2" - integrity sha512-Je5TaQzK7H06pt4e88WsjXwRC64EkmxsdqirUI+4GPVMjhs68Dmm8hr+yqf8tmpYlfR6zPlsJC5xs14dlVUehw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.3.tgz#548f851db5d30a12abeea2569ba75890dbf89425" + integrity sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" - integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" - integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" - integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@*": - version "29.5.7" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036" - integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g== + version "29.5.10" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.10.tgz#a10fc5bab9e426081c12b2ef73d24d4f0c9b7f50" + integrity sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -6406,9 +6640,9 @@ Lockfile: pretty-format "^27.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -6416,9 +6650,9 @@ Lockfile: integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.167", "@types/lodash@^4.14.175": - version "4.14.200" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149" - integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q== + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== "@types/long@^4.0.1": version "4.0.2" @@ -6431,26 +6665,26 @@ Lockfile: integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== "@types/mdast@^3.0.0": - version "3.0.14" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.14.tgz#0735473a5b35be032b9f2685b7413cbab1b8a639" - integrity sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw== + version "3.0.15" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" + integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== dependencies: "@types/unist" "^2" "@types/mdx@^2.0.0": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.9.tgz#80971e367bb884350ab5b2ce8fc06b34960170e7" - integrity sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg== + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.10.tgz#0d7b57fb1d83e27656156e4ee0dfba96532930e4" + integrity sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg== "@types/mime@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91" - integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/mime@^1": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9" - integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@*", "@types/minimatch@^5.1.2": version "5.1.2" @@ -6463,34 +6697,34 @@ Lockfile: integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.4.tgz#81f886786411c45bba3f33e781ab48bd56bfca2e" - integrity sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/ms@*": - version "0.7.33" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" - integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== + version "0.7.34" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node-fetch@^2.5.7": - version "2.6.8" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.8.tgz#9a2993583975849c2e1f360b6ca2f11755b2c504" - integrity sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA== + version "2.6.9" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" + integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== dependencies: "@types/node" "*" form-data "^4.0.0" "@types/node-forge@^1.3.0": - version "1.3.8" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb" - integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg== + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" + integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== dependencies: "@types/node" "*" "@types/node@*", "@types/node@>=13.7.0": - version "20.8.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" - integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== + version "20.10.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.1.tgz#d2c96f356c3125fedc983d74c424910c3767141c" + integrity sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg== dependencies: undici-types "~5.26.4" @@ -6505,26 +6739,26 @@ Lockfile: integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.60.tgz#0b0f4316906f1bd0e03b640363f67bd4e86958bd" - integrity sha512-ZUGPWx5vKfN+G2/yN7pcSNLkIkXEvlwNaJEd4e0ppX7W2S8XAkdc/37hM4OUNJB9sa0p12AOvGvxL4JCPiz9DA== + version "16.18.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.66.tgz#f59cc2ff96cc47f972a11a458a9b29bf0a209c34" + integrity sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw== "@types/normalize-package-data@^2.4.0": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" - integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/npmlog@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.5.tgz#41f1b95437f9c86cbb326bb07f0d5683f905bf4f" - integrity sha512-Fl3TEbwPoR7V1z6CMJ18whXOUkOYqF5eCkGKTir2VuevdLYUmcwj9mQdvXzuY0oagZBbsy0J7df41jn+ZcwGRA== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.6.tgz#792341665000209ee76997df8a16300fda6d77cb" + integrity sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ== dependencies: "@types/node" "*" "@types/parse-json@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" - integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/parse5@^5.0.0": version "5.0.3" @@ -6537,43 +6771,43 @@ Lockfile: integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/pretty-hrtime@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.2.tgz#9b6e102bc2e1eea1c1c7fadf144483ce2687f233" - integrity sha512-vyv9knII8XeW8TnXDcGH7HqG6FeR56ESN6ExM34d/U8Zvs3xuG34euV6CVyB7KEYI7Ts4lQM8b4NL72e7UadnA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" + integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== - "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.9": - version "15.7.9" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" - integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== + "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.11": + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== "@types/qrcode.react@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.4.tgz#4e6739769a21ee6072bceaab3ec0c866c6a79a17" - integrity sha512-O35T9AJk0wg7ffkgpSQ4Zr7I7eEfEsTCD5u7V2dsvYnZLfUpQz2rLg5ZG2FM/zLmOF4sEE0FY6mxT9WleUDb3Q== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.5.tgz#d4ddcacee8f34d22a663029a230c5f0ab908cfb7" + integrity sha512-BghPtnlwvrvq8QkGa1H25YnN+5OIgCKFuQruncGWLGJYOzeSKiix/4+B9BtfKF2wf5ja8yfyWYA3OXju995G8w== dependencies: "@types/react" "*" "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.9" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" - integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== "@types/range-parser@*": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a" - integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/react-dom@<18.0.0": - version "17.0.22" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.22.tgz#34317e08be27b33fa9e7cdb56125b22538261bad" - integrity sha512-wHt4gkdSMb4jPp1vc30MLJxoWGsZs88URfmt3FRXoOEYrrqK3I8IuZLE/uFBb4UT6MRfI0wXFu4DS7LS0kUC7Q== + version "17.0.25" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" + integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA== dependencies: "@types/react" "^17" "@types/react-dom@^18.0.10": - version "18.2.14" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" - integrity sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ== + version "18.2.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== dependencies: "@types/react" "*" @@ -6594,26 +6828,26 @@ Lockfile: dependencies: react-tooltip "*" - "@types/react-transition-group@^4.4.8": - version "4.4.8" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" - integrity sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg== + "@types/react-transition-group@^4.4.9": + version "4.4.9" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.9.tgz#12a1a1b5b8791067198149867b0823fbace31579" + integrity sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg== dependencies: "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.36" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.36.tgz#bc68ffb4408e5d0c419b0760b2eaeec70aeeedb3" - integrity sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw== + version "18.2.39" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.39.tgz#744bee99e053ad61fe74eb8b897f3ab5b19a7e25" + integrity sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/react@^17": - version "17.0.69" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.69.tgz#245a0cf2f5b0fb1d645691d3083e3c7d4409b98f" - integrity sha512-klEeru//GhiQvXUBayz0Q4l3rKHWsBR/EUOhOeow6hK2jV7MlO44+8yEk6+OtPeOlRfnpUnrLXzGK+iGph5aeg== + version "17.0.71" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.71.tgz#3673d446ad482b1564e44bf853b3ab5bcbc942c4" + integrity sha512-lfqOu9mp16nmaGRrS8deS2Taqhd5Ih0o92Te5Ws6I1py4ytHBcXLqh0YIqVsViqwVI5f+haiFM6hju814BzcmA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -6630,60 +6864,60 @@ Lockfile: integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/scheduler@*": - version "0.16.5" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" - integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== "@types/semver@^7.3.12", "@types/semver@^7.3.8": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== "@types/send@*": - version "0.17.3" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b" - integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug== + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: "@types/mime" "^1" "@types/node" "*" "@types/serve-index@^1.9.1": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9" - integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg== + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.4" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2" - integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw== + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== dependencies: "@types/http-errors" "*" "@types/mime" "*" "@types/node" "*" "@types/sockjs@^0.3.33": - version "0.3.35" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21" - integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw== + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" "@types/source-list-map@*": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.4.tgz#a3d4e4791606f40a833ab1caf41f77463c8d72ff" - integrity sha512-Kdfm7Sk5VX8dFW7Vbp18+fmAatBewzBILa1raHYxrGEFXT0jNl9x3LWfuW7bTbjEKFNey9Dfkj/UzT6z/NvRlg== + version "0.1.6" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454" + integrity sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g== "@types/stack-utils@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" - integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.10.tgz#5203aad08455c6988f7b2347715023e3935b1056" - integrity sha512-q8F20SdXG5fdVJQ5yxsVlH+f+oekP42QeHv4s5KlrxTMT0eopXn7ol1rhxMcksf8ph7XNv811iVDE2hOpUvEPg== + version "1.0.12" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.12.tgz#bc2cab12e87978eee89fb21576b670350d6d86ab" + integrity sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q== "@types/testing-library__jest-dom@^5.9.1": version "5.14.9" @@ -6693,31 +6927,31 @@ Lockfile: "@types/jest" "*" "@types/topojson-client@^3.1.0": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.3.tgz#d710e90f0a4a25bbdbf4fc0c1863f9a6b5023e26" - integrity sha512-liC+dHCxoqQy5bbJMsF59Cx1WZZwbcT084v/5bdp3NWSFUuzQpsm4gbLQh+wlv58Mng4jCsO4p8hWelqGlb7rg== + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.4.tgz#81b83f9ecd6542dc5c3df21967f992e3fe192c33" + integrity sha512-Ntf3ZSetMYy7z3PrVCvcqmdRoVhgKA9UKN0ZuuZf8Ts2kcyL4qK34IXBs6qO5fem62EK4k03PtkJPVoroVu4/w== dependencies: "@types/geojson" "*" "@types/topojson-specification" "*" "@types/topojson-specification@*": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.4.tgz#df2d2738a11bacda3b88f5b4630e3da80a12a609" - integrity sha512-LG/a8kJi4X6MsFhZKiBAIC/a+yCFtjkHsDMwuQqSoB1az8D2bR2xRKU3aczizfcqdt2lVqnS+aJBFMrO+rO5Aw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.5.tgz#bf0009b2e0debb2d97237b124c00b9ea92570375" + integrity sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ== dependencies: "@types/geojson" "*" "@types/uglify-js@*": - version "3.17.3" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.3.tgz#784efb40320d248588e1748dd12e1f43733f1416" - integrity sha512-ToldSfJ6wxO21cakcz63oFD1GjqQbKzhZCD57eH7zWuYT5UEZvfUoqvrjX5d+jB9g4a/sFO0n6QSVzzn5sMsjg== + version "3.17.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.4.tgz#3c70021f08023e5a760ce133d22966f200e1d31c" + integrity sha512-Hm/T0kV3ywpJyMGNbsItdivRhYNCQQf1IIsYsXnoVPES4t+FMLyDe0/K+Ea7ahWtMtSNb22ZdY7MIyoD9rqARg== dependencies: source-map "^0.6.1" "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.9.tgz#72e164381659a49557b0a078b28308f2c6a3e1ce" - integrity sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ== + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== "@types/uuid@^8.3.4": version "8.3.4" @@ -6725,23 +6959,23 @@ Lockfile: integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== "@types/webpack-env@^1.16.0": - version "1.18.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f" - integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q== + version "1.18.4" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032" + integrity sha512-I6e+9+HtWADAWeeJWDFQtdk4EVSAbj6Rtz4q8fJ7mSr1M0jzlFcs8/HZ+Xb5SHzVm1dxH7aUiI+A8kA8Gcrm0A== "@types/webpack-sources@*": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.2.tgz#6e6027cad8b54d2a4e5735df49af559bb4de2db0" - integrity sha512-acCzhuVe+UJy8abiSFQWXELhhNMZjQjQKpLNEi1pKGgKXZj0ul614ATcx4kkhunPost6Xw+aCq8y8cn1/WwAiA== + version "3.2.3" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.3.tgz#b667bd13e9fa15a9c26603dce502c7985418c3d8" + integrity sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw== dependencies: "@types/node" "*" "@types/source-list-map" "*" source-map "^0.7.3" "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.35" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.35.tgz#32903809685caf87ea612e4e74577874359c3749" - integrity sha512-XRC6HLGHtNfN8/xWeu1YUQV1GSE+28q8lSqvcJ+0xt/zW9Wmn4j9pCSvaXPyRlCKrl5OuqECQNEJUy2vo8oWqg== + version "4.41.38" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.38.tgz#5a40ac81bdd052bf405e8bdcf3e1236f6db6dc26" + integrity sha512-oOW7E931XJU1mVfCnxCVgv8GLFL768pDO5u2Gzk82i8yTIgX6i7cntyZOkZYb/JtYM8252SN9bQp9tgkVDSsRw== dependencies: "@types/node" "*" "@types/tapable" "^1" @@ -6751,42 +6985,42 @@ Lockfile: source-map "^0.6.0" "@types/ws@^8.5.5": - version "8.5.8" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" - integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: "@types/node" "*" "@types/yargs-parser@*": - version "21.0.2" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" - integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^15.0.0": - version "15.0.17" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.17.tgz#bea870ba551b43831bfaa75de2e4a3849c39322b" - integrity sha512-cj53I8GUcWJIgWVTSVe2L7NJAB5XWGdsoMosVvUgv1jEnMbAcsbaCzt1coUcyi8Sda5PgTWAooG8jNyDTD+CWA== + version "15.0.19" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" + integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.7" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.7.tgz#b0d0502cb5f6c17994df72a600049f10bbf17203" - integrity sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg== + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.29" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" - integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== dependencies: "@types/yargs-parser" "*" "@types/zxcvbn@^4.4.1": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.3.tgz#c323d8bf07673a782ef07950d4b6a878e56181fe" - integrity sha512-AxZBi8J3V3lm+f2Vgg06D8y0womXpLf3ZEDYeLPGGK0ydR724sQH83T5tYgN+CN6VTRnAlevFKJkWTecCnk8ug== + version "4.4.4" + resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.4.tgz#987f5fcd87e957097433c476c3a1c91a54f53131" + integrity sha512-Tuk4q7q0DnpzyJDI4aMeghGuFu2iS1QAdKpabn8JfbtfGmVDUgvZv1I7mEjP61Bvnp3ljKCC8BE6YYSTNxmvRQ== "@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.7.0": version "5.62.0" @@ -6884,19 +7118,13 @@ Lockfile: resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - "@vanilla-extract/css-utils@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css-utils/-/css-utils-0.1.3.tgz#cadeb6bc563547b20e9b903647d8b334d3a79ef8" - integrity sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw== - - "@vanilla-extract/css@^1.12.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.13.0.tgz#85f521d428f55b0e9599675033caba81194cc6c0" - integrity sha512-JFFBXhnJrPlGqHBabagXqo5ghXw9mtV270ycIGyLDZG8NAK5eRwAYkMowAxuzK7wZSm67GnETWYB7b0AUmyttg== + "@vanilla-extract/css@^1.14.0": + version "1.14.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.14.0.tgz#45fab9c04d893e3e363cf2cde7559d21233b7f63" + integrity sha512-rYfm7JciWZ8PFzBM/HDiE2GLnKI3xJ6/vdmVJ5BSgcCZ5CxRlM9Cjqclni9lGzF3eMOijnUhCd/KV8TOzyzbMA== dependencies: "@emotion/hash" "^0.9.0" "@vanilla-extract/private" "^1.0.3" - ahocorasick "1.0.2" chalk "^4.1.1" css-what "^6.1.0" cssesc "^3.0.0" @@ -6904,12 +7132,13 @@ Lockfile: deep-object-diff "^1.1.9" deepmerge "^4.2.2" media-query-parser "^2.0.2" + modern-ahocorasick "^1.0.0" outdent "^0.8.0" - "@vanilla-extract/dynamic@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.0.3.tgz#44b4e018cbdfb6af3d27e73c78b38617dfe419ad" - integrity sha512-Rglfw2gXAYiBzAQ4jgUG7rBgE2c88e/zcG27ZVoIqMHVq56wf2C1katGMm1yFMNBgzqM7oBNYzz4YOMzznydkg== + "@vanilla-extract/dynamic@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.1.0.tgz#316d3bd4adfd5f5c9fb080445c41d55abe3b463c" + integrity sha512-8zl0IgBYRtgD1h+56Zu13wHTiMTJSVEa4F7RWX9vTB/5Xe2KtjoiqApy/szHPVFA56c+ex6A4GpCQjT1bKXbYw== dependencies: "@vanilla-extract/private" "^1.0.3" @@ -6918,29 +7147,38 @@ Lockfile: resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== - "@vanilla-extract/recipes@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.4.0.tgz#7bb2edb0757b6f40c244d72569da7f74d6afa427" - integrity sha512-gFgB7BofUYbtbxINHK6DhMv1JDFDXp/YI/Xm+cqKar+1I/2dfxPepeDxSexL6YB4ftfeaDw8Kn5zydMvHcGOEQ== + "@vanilla-extract/recipes@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.5.1.tgz#617d1a0375af60835341770397810317d2f61998" + integrity sha512-7dCuBgPQQ/89siQ0w2lkfjgkmToPUUDzFlHf5DRmt9ykiiycfA52tmPJ2RI/mr7jXi7U/vEN2aGP9QJSXEpGlA== - "@walletconnect/core@2.10.4": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.4.tgz#da9396b56f63806c165389cbf98d2373d36854df" - integrity sha512-MGdw5a4dIlQFPxVHEw2neIpHPAw3gtrsJYyUqm6rI+1c1SfmZyOPCaYTr6zPU2cnoWQUjv2ePMLeO/JKy3Yh5g== + "@vitest/utils@^0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968" + integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A== + dependencies: + diff-sequences "^29.4.3" + loupe "^2.3.6" + pretty-format "^29.5.0" + + "@walletconnect/core@2.10.6": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.6.tgz#786b0d2e2045c210c917e29bfa0498bbc210be20" + integrity sha512-Z4vh4ZdfcoQjgPEOxeuF9HUZCVLtV3MgRbS/awLIj/omDrFnOwlBhxi5Syr4Y8muVGC0ocRetQYHae0/gX5crQ== dependencies: "@walletconnect/heartbeat" "1.2.1" "@walletconnect/jsonrpc-provider" "1.0.13" "@walletconnect/jsonrpc-types" "1.0.3" "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/jsonrpc-ws-connection" "1.0.13" - "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/keyvaluestorage" "^1.1.1" "@walletconnect/logger" "^2.0.1" "@walletconnect/relay-api" "^1.0.9" "@walletconnect/relay-auth" "^1.0.4" "@walletconnect/safe-json" "^1.0.2" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" - "@walletconnect/utils" "2.10.4" + "@walletconnect/types" "2.10.6" + "@walletconnect/utils" "2.10.6" events "^3.3.0" lodash.isequal "4.5.0" uint8arrays "^3.1.0" @@ -6995,24 +7233,24 @@ Lockfile: "@walletconnect/jsonrpc-types" "^1.0.3" tslib "1.14.1" - "@walletconnect/jsonrpc-ws-connection@1.0.13": - version "1.0.13" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.13.tgz#23b0cdd899801bfbb44a6556936ec2b93ef2adf4" - integrity sha512-mfOM7uFH4lGtQxG+XklYuFBj6dwVvseTt5/ahOkkmpcAEgz2umuzu7fTR+h5EmjQBdrmYyEBOWADbeaFNxdySg== + "@walletconnect/jsonrpc-ws-connection@1.0.14": + version "1.0.14" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" + integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== dependencies: "@walletconnect/jsonrpc-utils" "^1.0.6" "@walletconnect/safe-json" "^1.0.2" events "^3.3.0" - tslib "1.14.1" ws "^7.5.1" - "@walletconnect/keyvaluestorage@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz#92f5ca0f54c1a88a093778842ce0c874d86369c8" - integrity sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ== + "@walletconnect/keyvaluestorage@^1.0.2", "@walletconnect/keyvaluestorage@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" + integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== dependencies: - safe-json-utils "^1.1.1" - tslib "1.14.1" + "@walletconnect/safe-json" "^1.0.1" + idb-keyval "^6.2.1" + unstorage "^1.9.0" "@walletconnect/logger@^2.0.1": version "2.0.1" @@ -7050,18 +7288,18 @@ Lockfile: tslib "1.14.1" "@walletconnect/sign-client@^2.9.0": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.4.tgz#4e3b14ebe900472874f4cae5f53c74a6077c85da" - integrity sha512-C5VHkK59/DQNrJS91UXLn5OSr0drXHkKjajhl2a9hb3h6kxuSdlWbyC0yRPKT1sD0fQho8+EWZHBiV063yBePw== + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.6.tgz#722d2c2844565e2826dce6a6d3a36c9b3ca1ea91" + integrity sha512-EvUWjaZBQu2yKnH5/5F2qzbuiIuUN9ZgrNKgvXkw5z1Dq5RJCks0S9/MFlKH/ZSGqXnLl7uAzBXtoX4sMgbCMA== dependencies: - "@walletconnect/core" "2.10.4" + "@walletconnect/core" "2.10.6" "@walletconnect/events" "^1.0.1" "@walletconnect/heartbeat" "1.2.1" "@walletconnect/jsonrpc-utils" "1.0.8" "@walletconnect/logger" "^2.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" - "@walletconnect/utils" "2.10.4" + "@walletconnect/types" "2.10.6" + "@walletconnect/utils" "2.10.6" events "^3.3.0" "@walletconnect/time@^1.0.2": @@ -7083,10 +7321,22 @@ Lockfile: "@walletconnect/logger" "^2.0.1" events "^3.3.0" - "@walletconnect/utils@2.10.4", "@walletconnect/utils@^2.9.0": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.4.tgz#5f17938e7ea481541ec2dbae0df5cd494c72523f" - integrity sha512-XbrKgnQ0hC9DC9wjFb468MEYMoJxnCVmOj2gi01DA4FSr8fJi7wwNRUnlnZzLWrUWrHuaPReYe4PgBAgIv363g== + "@walletconnect/types@2.10.6": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.6.tgz#d9920ed4fd0113e0addbda8e7e73a5176a3163fd" + integrity sha512-WgHfiTG1yakmxheaBRiXhUdEmgxwrvsAdOIWaMf/spvrzVKYh6sHI3oyEEky5qj5jjiMiyQBeB57QamzCotbcQ== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + + "@walletconnect/utils@2.10.6", "@walletconnect/utils@^2.9.0": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.6.tgz#749b37d14e291e346862e7027ec7548463350226" + integrity sha512-oRsWWhN2+hi3aiDXrQEOfysz6FHQJGXLsNQPVt+WIBJplO6Szmdau9dbleD88u1iiT4GKPqE0R9FOYvvPm1H/w== dependencies: "@stablelib/chacha20poly1305" "1.0.1" "@stablelib/hkdf" "1.0.1" @@ -7096,7 +7346,7 @@ Lockfile: "@walletconnect/relay-api" "^1.0.9" "@walletconnect/safe-json" "^1.0.2" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" + "@walletconnect/types" "2.10.6" "@walletconnect/window-getters" "^1.0.1" "@walletconnect/window-metadata" "^1.0.1" detect-browser "5.3.0" @@ -7495,7 +7745,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - acorn@^8.0.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: + acorn@^8.0.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== @@ -7532,11 +7782,6 @@ Lockfile: clean-stack "^2.0.0" indent-string "^4.0.0" - ahocorasick@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ahocorasick/-/ahocorasick-1.0.2.tgz#9eee93aef9d02bfb476d9b648d9b7a40ef2fd500" - integrity sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA== - airbnb-js-shims@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" @@ -7605,9 +7850,9 @@ Lockfile: uri-js "^4.2.2" animejs@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.1.tgz#de9fe2e792f44a777a7fdf6ae160e26604b0cdda" - integrity sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A== + version "3.2.2" + resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.2.tgz#59be98c58834339d5847f4a70ddba74ac75b6afc" + integrity sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ== ansi-align@^3.0.0: version "3.0.1" @@ -7697,7 +7942,7 @@ Lockfile: micromatch "^3.1.4" normalize-path "^2.1.1" - anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: + anymatch@^3.0.0, anymatch@^3.0.3, anymatch@^3.1.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -7720,6 +7965,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== + arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -8052,10 +8302,10 @@ Lockfile: dependencies: follow-redirects "^1.14.0" - axios@^1.0.0, axios@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" - integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== + axios@^1.0.0, axios@^1.3.3, axios@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" @@ -8255,6 +8505,11 @@ Lockfile: dependencies: safe-buffer "^5.0.1" + base-x@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" + integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== + base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" @@ -8296,9 +8551,9 @@ Lockfile: open "^7.0.3" big-integer@^1.6.48, big-integer@^1.6.7: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== big.js@^5.2.2: version "5.2.2" @@ -8578,6 +8833,13 @@ Lockfile: dependencies: base-x "^3.0.2" + bs58@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" + integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== + dependencies: + base-x "^4.0.0" + bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" @@ -8861,9 +9123,9 @@ Lockfile: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001561" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" - integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== + version "1.0.30001565" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz#a528b253c8a2d95d2b415e11d8b9942acc100c4f" + integrity sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w== capture-exit@^2.0.0: version "2.0.0" @@ -9040,6 +9302,13 @@ Lockfile: inherits "^2.0.1" safe-buffer "^5.0.1" + citty@^0.1.3, citty@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.5.tgz#fe37ceae5dc764af75eb2fece99d2bf527ea4e50" + integrity sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ== + dependencies: + consola "^3.2.3" + cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -9055,7 +9324,7 @@ Lockfile: isobject "^3.0.0" static-extend "^0.1.1" - classnames@^2.2.5, classnames@^2.3.0: + classnames@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== @@ -9068,9 +9337,9 @@ Lockfile: source-map "~0.6.0" clean-css@^5.2.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" - integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== dependencies: source-map "~0.6.0" @@ -9104,9 +9373,9 @@ Lockfile: integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.5.0: - version "2.9.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" - integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.1: version "0.6.3" @@ -9132,6 +9401,15 @@ Lockfile: resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== + clipboardy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" + integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== + dependencies: + arch "^2.2.0" + execa "^5.1.1" + is-wsl "^2.2.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -9203,6 +9481,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== + cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + cmd-shim@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" @@ -9375,9 +9658,9 @@ Lockfile: dot-prop "^5.1.0" component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== compressible@~2.0.16: version "2.0.18" @@ -9434,6 +9717,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== + consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -9544,6 +9832,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== + cookie-es@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.0.0.tgz#4759684af168dfc54365b2c2dda0a8d7ee1e4865" + integrity sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -9579,21 +9872,21 @@ Lockfile: toggle-selection "^1.0.6" core-js-compat@^3.31.0, core-js-compat@^3.33.1, core-js-compat@^3.8.1: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" - integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.3.tgz#ec678b772c5a2d8a7c60a91c3a81869aa704ae01" + integrity sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow== dependencies: browserslist "^4.22.1" core-js-pure@^3.23.3: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" - integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.3.tgz#cbf9180ac4c4653823d784862bfb5c77eac0bf98" + integrity sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ== core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" - integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.3.tgz#3c644a323f0f533a0d360e9191e37f7fc059088d" + integrity sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw== core-util-is@~1.0.0: version "1.0.3" @@ -9648,6 +9941,11 @@ Lockfile: long "^4.0.0" protobufjs "~6.11.2" + cosmjs-types@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.9.0.tgz#c3bc482d28c7dfa25d1445093fdb2d9da1f6cfcc" + integrity sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ== + cp-file@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" @@ -10201,14 +10499,14 @@ Lockfile: integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-equal@^2.0.5: - version "2.2.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.2.tgz#9b2635da569a13ba8e1cc159c2f744071b115daa" - integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== dependencies: array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" + call-bind "^1.0.5" es-get-iterator "^1.1.3" - get-intrinsic "^1.2.1" + get-intrinsic "^1.2.2" is-arguments "^1.1.1" is-array-buffer "^3.0.2" is-date-object "^1.0.5" @@ -10218,11 +10516,11 @@ Lockfile: object-is "^1.1.5" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" + regexp.prototype.flags "^1.5.1" side-channel "^1.0.4" which-boxed-primitive "^1.0.2" which-collection "^1.0.1" - which-typed-array "^1.1.9" + which-typed-array "^1.1.13" deep-extend@^0.6.0: version "0.6.0" @@ -10281,7 +10579,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: + define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -10312,6 +10610,11 @@ Lockfile: is-descriptor "^1.0.2" isobject "^3.0.1" + defu@^6.1.2, defu@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" + integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== + del@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -10340,6 +10643,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -10368,6 +10676,11 @@ Lockfile: inherits "^2.0.1" minimalistic-assert "^1.0.0" + destr@^2.0.1, destr@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.2.tgz#8d3c0ee4ec0a76df54bc8b819bca215592a8c218" + integrity sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -10440,7 +10753,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== - diff-sequences@^29.6.3: + diff-sequences@^29.4.3, diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== @@ -10680,9 +10993,9 @@ Lockfile: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.576" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" - integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== + version "1.4.598" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.598.tgz#aaf1f64286001915b59210158d21b6284e96acbc" + integrity sha512-0JnipX0scPUlwsptQVCZggoCpREv+IrVD3h0ZG+sldmK9L27tSV3QjV8+QdaA4qQTzDf3PluNS45YYJky1oASw== elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -10914,9 +11227,9 @@ Lockfile: safe-array-concat "^1.0.1" es-module-lexer@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" - integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== + version "1.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" + integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== es-set-tostringtag@^2.0.1: version "2.0.2" @@ -11247,14 +11560,14 @@ Lockfile: v8-compile-cache "^2.0.3" eslint@^8.10.0: - version "8.53.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" - integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== + version "8.54.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" + integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.53.0" + "@eslint/js" "8.54.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -11897,9 +12210,9 @@ Lockfile: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" @@ -12061,7 +12374,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - fs-extra@11.1.1, fs-extra@^11.1.0, fs-extra@^11.1.1: + fs-extra@11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== @@ -12079,6 +12392,15 @@ Lockfile: jsonfile "^6.0.1" universalify "^2.0.0" + fs-extra@^11.1.0, fs-extra@^11.1.1: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -12200,6 +12522,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-func-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" @@ -12225,6 +12552,11 @@ Lockfile: through2 "^2.0.0" yargs "^16.2.0" + get-port-please@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.1.tgz#2556623cddb4801d823c0a6a15eec038abb483be" + integrity sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA== + get-port@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" @@ -12510,6 +12842,20 @@ Lockfile: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== + h3@^1.8.1, h3@^1.8.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.9.0.tgz#c5f512a93026df9837db6f30c9ef51135dd46752" + integrity sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA== + dependencies: + cookie-es "^1.0.0" + defu "^6.1.3" + destr "^2.0.2" + iron-webcrypto "^1.0.0" + radix3 "^1.1.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unenv "^1.7.4" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -12957,6 +13303,11 @@ Lockfile: follow-redirects "^1.0.0" requires-port "^1.0.0" + http-shutdown@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f" + integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw== + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -13020,6 +13371,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== + idb-keyval@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -13043,9 +13399,9 @@ Lockfile: minimatch "^5.0.1" ignore-walk@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb" - integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== + version "6.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" + integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== dependencies: minimatch "^9.0.0" @@ -13055,9 +13411,9 @@ Lockfile: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.4, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== immediate@~3.0.5: version "3.0.6" @@ -13194,15 +13550,30 @@ Lockfile: integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== intl-messageformat@^10.1.0: - version "10.5.4" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.4.tgz#7b212b083f1b354d7e282518e78057e025134af9" - integrity sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w== + version "10.5.8" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.8.tgz#7184da425f360a53a5483a6194e16d666b011fc0" + integrity sha512-NRf0jpBWV0vd671G5b06wNofAN8tp7WWDogMZyaU8GUAsmbouyvgwmFJI7zLjfAMpm3zK+vSwRP3jzaoIcMbaA== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/ecma402-abstract" "1.18.0" "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.7.0" + "@formatjs/icu-messageformat-parser" "2.7.3" tslib "^2.4.0" + ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" @@ -13218,6 +13589,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== + iron-webcrypto@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.0.0.tgz#e3b689c0c61b434a0a4cb82d0aeabbc8b672a867" + integrity sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg== + is-absolute-url@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" @@ -13256,7 +13632,7 @@ Lockfile: is-alphabetical "^2.0.0" is-decimal "^2.0.0" - is-arguments@^1.1.1: + is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -13459,7 +13835,7 @@ Lockfile: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - is-generator-function@^1.0.10: + is-generator-function@^1.0.10, is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== @@ -13687,7 +14063,7 @@ Lockfile: dependencies: text-extensions "^1.0.0" - is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: + is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -13807,9 +14183,9 @@ Lockfile: integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.1.tgz#c680fd1544600460367af5811866c34c44c6f3b1" - integrity sha512-opCrKqbthmq3SKZ10mFMQG9dk3fTa3quaOLD35kJa5ejwZHd9xAr+kLuziiZz2cG32s4lMZxNdmdcEQnTDP4+g== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" @@ -14460,6 +14836,22 @@ Lockfile: import-local "^3.0.2" jest-cli "^27.5.1" + jiti@^1.20.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== + + joi@^17.11.0: + version "17.11.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" + integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -14549,9 +14941,9 @@ Lockfile: integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" - integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" + integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== json-schema-traverse@^0.4.1: version "0.4.1" @@ -14585,7 +14977,7 @@ Lockfile: dependencies: minimist "^1.2.0" - jsonc-parser@3.2.0, jsonc-parser@^3.0.0: + jsonc-parser@3.2.0, jsonc-parser@^3.0.0, jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== @@ -14889,6 +15281,18 @@ Lockfile: sigstore "^1.4.0" ssri "^10.0.1" + libsodium-sumo@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz#533b97d2be44b1277e59c1f9f60805978ac5542d" + integrity sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ== + + libsodium-wrappers-sumo@^0.7.11: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz#a33aea845a0bb56db067548f04feba28c730ab8e" + integrity sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ== + dependencies: + libsodium-sumo "^0.7.13" + libsodium-wrappers@^0.7.6: version "0.7.13" resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" @@ -14919,9 +15323,32 @@ Lockfile: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== + + listhen@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/listhen/-/listhen-1.5.5.tgz#58915512af70f770aa3e9fb19367adf479bb58c4" + integrity sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA== + dependencies: + "@parcel/watcher" "^2.3.0" + "@parcel/watcher-wasm" "2.3.0" + citty "^0.1.4" + clipboardy "^3.0.0" + consola "^3.2.3" + defu "^6.1.2" + get-port-please "^3.1.1" + h3 "^1.8.1" + http-shutdown "^1.2.2" + jiti "^1.20.0" + mlly "^1.4.2" + node-forge "^1.3.1" + pathe "^1.1.1" + std-env "^3.4.3" + ufo "^1.3.0" + untun "^0.1.2" + uqr "^0.1.2" load-json-file@6.2.0: version "6.2.0" @@ -15029,11 +15456,21 @@ Lockfile: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== + lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + lodash.defaultsdeep@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== + lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + lodash.isequal@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -15117,6 +15554,13 @@ Lockfile: currently-unhandled "^0.4.1" signal-exit "^3.0.0" + loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -15124,6 +15568,11 @@ Lockfile: dependencies: tslib "^2.0.3" + lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -15143,11 +15592,6 @@ Lockfile: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - "lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -15903,7 +16347,7 @@ Lockfile: snapdragon "^0.8.1" to-regex "^3.0.2" - micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: + micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -15941,6 +16385,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -16170,10 +16619,20 @@ Lockfile: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + mlly@^1.2.0, mlly@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" + integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== + dependencies: + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" + mobx@^6.1.7: - version "6.10.2" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.10.2.tgz#96e123deef140750360ca9a5b02a8b91fbffd4d9" - integrity sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ== + version "6.12.0" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.0.tgz#72b2685ca5af031aaa49e77a4d76ed67fcbf9135" + integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ== mocha@^10.0.0: version "10.2.0" @@ -16202,6 +16661,11 @@ Lockfile: yargs-parser "20.2.4" yargs-unparser "2.0.0" + modern-ahocorasick@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz#dec373444f51b5458ac05216a8ec376e126dd283" + integrity sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA== + modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -16226,7 +16690,7 @@ Lockfile: rimraf "^2.5.4" run-queue "^1.0.3" - mri@^1.1.0: + mri@^1.1.0, mri@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== @@ -16327,6 +16791,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== + napi-wasm@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.0.tgz#bbe617823765ae9c1bc12ff5942370eae7b2ba4e" + integrity sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg== + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -16392,6 +16861,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== + node-addon-api@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" + integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== + node-dir@^0.1.10: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -16399,6 +16873,11 @@ Lockfile: dependencies: minimatch "^3.0.2" + node-fetch-native@^1.4.0, node-fetch-native@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.1.tgz#5a336e55b4e1b1e72b9927da09fecd2b374c9be5" + integrity sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w== + node-fetch@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -16413,15 +16892,15 @@ Lockfile: dependencies: whatwg-url "^5.0.0" - node-forge@^1: + node-forge@^1, node-forge@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp-build@^4.3.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" - integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + version "4.7.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== node-gyp@^9.0.0, node-gyp@^9.3.1: version "9.4.1" @@ -16823,12 +17302,12 @@ Lockfile: isobject "^3.0.0" object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + 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" @@ -16905,6 +17384,15 @@ Lockfile: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== + ofetch@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.3.tgz#588cb806a28e5c66c2c47dd8994f9059a036d8c0" + integrity sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg== + dependencies: + destr "^2.0.1" + node-fetch-native "^1.4.0" + ufo "^1.3.0" + on-exit-leak-free@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" @@ -17409,6 +17897,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== + pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== + pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -17537,6 +18030,15 @@ Lockfile: dependencies: find-up "^5.0.0" + pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + dependencies: + jsonc-parser "^3.2.0" + mlly "^1.2.0" + pathe "^1.1.0" + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -17942,7 +18444,7 @@ Lockfile: ansi-styles "^5.0.0" react-is "^18.0.0" - pretty-format@^29.0.0, pretty-format@^29.7.0: + pretty-format@^29.0.0, pretty-format@^29.5.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== @@ -18244,6 +18746,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== + radix3@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" + integrity sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A== + rainbow-sprinkles@^0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.0.tgz#6ee06c6decc767b89bf01fc5fe87ecf859fd4c2f" @@ -18318,46 +18825,46 @@ Lockfile: strip-json-comments "~2.0.1" react-aria@^3.29.1: - version "3.29.1" - resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.29.1.tgz#4f6e968a15cfec69d8d8735b98d0fe8ac31b4be2" - integrity sha512-dDoaTh5fCaD3kO0kv49pqUUOsXRGuqFX7owQaly/RhWkBw/dlIYkHRVdOatllI/v4h1/Ne40QOXl15aAISozlA== + version "3.30.0" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.30.0.tgz#dd53d2103050e7279ec8f3faacce5ae8521f61ce" + integrity sha512-ULMlmH68/jXzkDaMjuM9O8dKCxnAYviW4E5sywfLX4J6mC6eGsQzoqtwWeQgr1M9SJqLfgKaVoDP1dLvb4XzEA== dependencies: - "@react-aria/breadcrumbs" "^3.5.7" - "@react-aria/button" "^3.8.4" - "@react-aria/calendar" "^3.5.2" - "@react-aria/checkbox" "^3.11.2" - "@react-aria/combobox" "^3.7.1" - "@react-aria/datepicker" "^3.8.1" - "@react-aria/dialog" "^3.5.7" - "@react-aria/dnd" "^3.4.3" - "@react-aria/focus" "^3.14.3" - "@react-aria/gridlist" "^3.7.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/link" "^3.6.1" - "@react-aria/listbox" "^3.11.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/meter" "^3.4.7" - "@react-aria/numberfield" "^3.9.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/progress" "^3.4.7" - "@react-aria/radio" "^3.8.2" - "@react-aria/searchfield" "^3.5.7" - "@react-aria/select" "^3.13.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/separator" "^3.3.7" - "@react-aria/slider" "^3.7.2" - "@react-aria/ssr" "^3.8.0" - "@react-aria/switch" "^3.5.6" - "@react-aria/table" "^3.13.1" - "@react-aria/tabs" "^3.8.1" - "@react-aria/tag" "^3.2.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/tooltip" "^3.6.4" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-types/shared" "^3.21.0" + "@react-aria/breadcrumbs" "^3.5.8" + "@react-aria/button" "^3.9.0" + "@react-aria/calendar" "^3.5.3" + "@react-aria/checkbox" "^3.12.0" + "@react-aria/combobox" "^3.8.0" + "@react-aria/datepicker" "^3.9.0" + "@react-aria/dialog" "^3.5.8" + "@react-aria/dnd" "^3.5.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/gridlist" "^3.7.2" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/link" "^3.6.2" + "@react-aria/listbox" "^3.11.2" + "@react-aria/menu" "^3.11.2" + "@react-aria/meter" "^3.4.8" + "@react-aria/numberfield" "^3.10.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/progress" "^3.4.8" + "@react-aria/radio" "^3.9.0" + "@react-aria/searchfield" "^3.6.0" + "@react-aria/select" "^3.14.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/separator" "^3.3.8" + "@react-aria/slider" "^3.7.3" + "@react-aria/ssr" "^3.9.0" + "@react-aria/switch" "^3.5.7" + "@react-aria/table" "^3.13.2" + "@react-aria/tabs" "^3.8.2" + "@react-aria/tag" "^3.3.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/tooltip" "^3.6.5" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-types/shared" "^3.22.0" react-docgen-typescript@^2.1.1: version "2.2.2" @@ -18496,27 +19003,20 @@ Lockfile: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== - react-resize-detector@^8.0.4: - version "8.1.0" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-8.1.0.tgz#1c7817db8bc886e2dbd3fbe3b26ea8e56be0524a" - integrity sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w== - dependencies: - lodash "^4.17.21" - react-router-dom@6, react-router-dom@^6.7.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.18.0.tgz#0a50c167209d6e7bd2ed9de200a6579ea4fb1dca" - integrity sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw== + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b" + integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ== dependencies: - "@remix-run/router" "1.11.0" - react-router "6.18.0" + "@remix-run/router" "1.13.0" + react-router "6.20.0" - react-router@6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.18.0.tgz#32e2bedc318e095a48763b5ed7758e54034cd36a" - integrity sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg== + react-router@6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539" + integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w== dependencies: - "@remix-run/router" "1.11.0" + "@remix-run/router" "1.13.0" react-simple-maps@^2.3.0: version "2.3.0" @@ -18528,7 +19028,7 @@ Lockfile: d3-zoom "^2.0.0" topojson-client "^3.1.0" - react-smooth@^2.0.4: + react-smooth@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== @@ -18537,37 +19037,38 @@ Lockfile: react-transition-group "2.9.0" react-stately@^3.27.1: - version "3.27.1" - resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.27.1.tgz#b24992bd72da1b1632bf4f4232d87ce6913a19bd" - integrity sha512-qHhivqOpyATaWwoj3xl3IqqoEnib+dsl2vYlOz92CT5Ntm6lprF7KO+LkxdkS0SnUckdGewFM1NjCmbK7wPJgw== + version "3.28.0" + resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.28.0.tgz#f2831e50b70b0dcec7e3d7e3787f9dc1df42d9c3" + integrity sha512-owEHRGS1zRMwtiR/jeXUjUWyqk8oe53wNtedMvg9+8+NNhDKL4/DXHcIp2A13q08v09xYWgVPtnu8fsF53x2PQ== dependencies: - "@react-stately/calendar" "^3.4.1" - "@react-stately/checkbox" "^3.5.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/combobox" "^3.7.1" - "@react-stately/data" "^3.10.3" - "@react-stately/datepicker" "^3.8.0" - "@react-stately/dnd" "^3.2.5" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/numberfield" "^3.6.2" - "@react-stately/overlays" "^3.6.3" - "@react-stately/radio" "^3.9.1" - "@react-stately/searchfield" "^3.4.6" - "@react-stately/select" "^3.5.5" - "@react-stately/selection" "^3.14.0" - "@react-stately/slider" "^3.4.4" - "@react-stately/table" "^3.11.2" - "@react-stately/tabs" "^3.6.1" - "@react-stately/toggle" "^3.6.3" - "@react-stately/tooltip" "^3.4.5" - "@react-stately/tree" "^3.7.3" - "@react-types/shared" "^3.21.0" + "@react-stately/calendar" "^3.4.2" + "@react-stately/checkbox" "^3.6.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/combobox" "^3.8.0" + "@react-stately/data" "^3.11.0" + "@react-stately/datepicker" "^3.9.0" + "@react-stately/dnd" "^3.2.6" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-stately/numberfield" "^3.7.0" + "@react-stately/overlays" "^3.6.4" + "@react-stately/radio" "^3.10.0" + "@react-stately/searchfield" "^3.5.0" + "@react-stately/select" "^3.6.0" + "@react-stately/selection" "^3.14.1" + "@react-stately/slider" "^3.4.5" + "@react-stately/table" "^3.11.3" + "@react-stately/tabs" "^3.6.2" + "@react-stately/toggle" "^3.7.0" + "@react-stately/tooltip" "^3.4.6" + "@react-stately/tree" "^3.7.4" + "@react-types/shared" "^3.22.0" react-tooltip@*: - version "5.22.0" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.22.0.tgz#3082065b1efbd207813f484b617b1b75325f15d5" - integrity sha512-xbJBRY1LyHYd7j00UeBOqZR9SH/1S47Pe+m8vM1a+ZXglkeSNnBt5YYoPttU/amjC/VZJAPQ8+2B9x8Fl8U1qA== + version "5.24.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.24.0.tgz#c134e4c00d49a111986711696bcd9abf672caff6" + integrity sha512-HjstgpOrUwP4eN6mHU4EThpbxVuKO5SvqumRt1aAcPq0ya+pIVVxlwltndtdIIMBJ7w3jnN05vNfcfh2sxE2mQ== dependencies: "@floating-ui/dom" "^1.0.0" classnames "^2.3.0" @@ -18746,16 +19247,15 @@ Lockfile: decimal.js-light "^2.4.1" recharts@^2.1.13: - version "2.9.2" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.2.tgz#a6a4e4c2887467ea57abde7e3af5c8021355a606" - integrity sha512-ig0zYgO5nUP/896GW16b9yy2sHIRW1AHB90x48hypFTSjjxQt/J9rPzlLJjgNupzJKEHPCwMi1VnvN/k20K45w== + version "2.10.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.2.tgz#919e9ccba463c7face91438c807340f300435e55" + integrity sha512-goasBqGqpH8SLty+a24xG1KkZWowo793mgoNVrOkBRXZCG2xX+BUbCgaWrB/G+DGIpN2AX/arCttLuHdg/A6LQ== dependencies: - classnames "^2.2.5" + clsx "^2.0.0" eventemitter3 "^4.0.1" lodash "^4.17.19" react-is "^16.10.2" - react-resize-detector "^8.0.4" - react-smooth "^2.0.4" + react-smooth "^2.0.5" recharts-scale "^0.4.4" tiny-invariant "^1.3.1" victory-vendor "^36.6.8" @@ -18783,6 +19283,18 @@ Lockfile: indent-string "^4.0.0" strip-indent "^3.0.0" + redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + + redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + reflect.getprototypeof@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" @@ -19248,11 +19760,6 @@ Lockfile: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-json-utils@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" - integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -19968,6 +20475,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== + standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -19991,6 +20503,11 @@ Lockfile: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== + std-env@^3.4.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" + integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" @@ -20036,9 +20553,9 @@ Lockfile: integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== streamx@^2.15.0: - version "2.15.2" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.2.tgz#680eacebdc9c43ede7362c2e6695b34dd413c741" - integrity sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg== + version "2.15.5" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.5.tgz#87bcef4dc7f0b883f9359671203344a4e004c7f1" + integrity sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg== dependencies: fast-fifo "^1.1.0" queue-tick "^1.0.1" @@ -20824,9 +21341,9 @@ Lockfile: yargs-parser "20.x" ts-loader@^9.4.2: - version "9.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" - integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== + version "9.5.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" + integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -21085,15 +21602,20 @@ Lockfile: integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== "typescript@>=3 < 6": - version "5.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + version "5.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" + integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== typescript@^4.6.2, typescript@^4.8.4: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== + ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" + integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA== + uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" @@ -21116,6 +21638,11 @@ Lockfile: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" + uncrypto@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" + integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -21126,6 +21653,17 @@ Lockfile: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== + unenv@^1.7.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c" + integrity sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg== + dependencies: + consola "^3.2.3" + defu "^6.1.3" + mime "^3.0.0" + node-fetch-native "^1.4.1" + pathe "^1.1.1" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -21383,6 +21921,23 @@ Lockfile: has-value "^0.3.1" isobject "^3.0.0" + unstorage@^1.9.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.10.1.tgz#bf8cc00a406e40a6293e893da9807057d95875b0" + integrity sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw== + dependencies: + anymatch "^3.1.3" + chokidar "^3.5.3" + destr "^2.0.2" + h3 "^1.8.2" + ioredis "^5.3.2" + listhen "^1.5.5" + lru-cache "^10.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.1" + ofetch "^1.3.3" + ufo "^1.3.1" + untildify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" @@ -21390,6 +21945,15 @@ Lockfile: dependencies: os-homedir "^1.0.0" + untun@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/untun/-/untun-0.1.2.tgz#fa42a62ae24c1c5c6f3209692a2b0e1f573f1353" + integrity sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q== + dependencies: + citty "^0.1.3" + consola "^3.2.3" + pathe "^1.1.1" + upath@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" @@ -21408,6 +21972,11 @@ Lockfile: escalade "^3.1.1" picocolors "^1.0.0" + uqr@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" + integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -21489,6 +22058,17 @@ Lockfile: dependencies: inherits "2.0.3" + util@^0.12.4: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -21564,9 +22144,9 @@ Lockfile: source-map "^0.7.3" v8-to-istanbul@^9.0.0: - version "9.1.3" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" - integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== + version "9.2.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -21641,9 +22221,9 @@ Lockfile: vfile-message "^3.0.0" victory-vendor@^36.6.8: - version "36.6.12" - resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.12.tgz#17fa4d79d266a6e2bde0291c60c5002c55008164" - integrity sha512-pJrTkNHln+D83vDCCSUf0ZfxBvIaVrFHmrBOsnnLAbdqfudRACAj51He2zU94/IWq9464oTADcPVkmWAfNMwgA== + version "36.7.0" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.7.0.tgz#e02af33e249e74e659fa65c6d5936042c42e7aa8" + integrity sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA== dependencies: "@types/d3-array" "^3.0.3" "@types/d3-ease" "^3.0.0" @@ -22060,7 +22640,7 @@ Lockfile: is-weakmap "^2.0.1" is-weakset "^2.0.1" - which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: + which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== diff --git a/sdk/typescript/packages/validator-client/package.json b/sdk/typescript/packages/validator-client/package.json index 062aee2bca..399db91ff0 100644 --- a/sdk/typescript/packages/validator-client/package.json +++ b/sdk/typescript/packages/validator-client/package.json @@ -27,12 +27,12 @@ "tsc": "tsc --noEmit" }, "devDependencies": { - "@cosmjs/cosmwasm-stargate": "^0.29.5", + "@cosmjs/cosmwasm-stargate": "^0.32.0", "@cosmjs/crypto": "^0.29.5", "@cosmjs/math": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.29.5", + "@cosmjs/tendermint-rpc": "^0.32.0", "@favware/rollup-type-bundler": "^2.0.0", "@nymproject/types": "^1.0.0", "@rollup/plugin-commonjs": "^24.0.1", @@ -65,4 +65,4 @@ }, "private": false, "types": "dist/index.d.ts" -} \ No newline at end of file +} diff --git a/yarn.lock b/yarn.lock index b0e24432af..c57a5db684 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27,18 +27,18 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.22.13" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.22.13.tgz#e3c1c099402598483b7a8c46a721d1038803755e" - integrity sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" + integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== dependencies: - "@babel/highlight" "^7.22.13" + "@babel/highlight" "^7.23.4" chalk "^2.4.2" -"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.2.tgz#6a12ced93455827037bfb5ed8492820d60fc32cc" - integrity sha512-0S9TQMmDHlqAZ2ITT95irXKfxN9bncq8ZCoJhun3nHL/lLUxd2NKBJYoNGWH7S0hz6fRQwWlAWn/ILM0C70KZQ== +"@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" + integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== "@babel/core@7.12.9": version "7.12.9" @@ -63,32 +63,32 @@ source-map "^0.5.0" "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.17.5", "@babel/core@^7.19.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.2.tgz#ed10df0d580fff67c5f3ee70fd22e2e4c90a9f94" - integrity sha512-n7s51eWdaWZ3vGT2tD4T7J6eJs3QoBXydv7vkUM06Bf1cbVD2Kc2UrkzhiQwobfV7NwOnQXYL7UBJ5VPU+RGoQ== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" + integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.0" - "@babel/helpers" "^7.23.2" - "@babel/parser" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" + "@babel/helpers" "^7.23.5" + "@babel/parser" "^7.23.5" "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.0", "@babel/generator@^7.7.2": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.0.tgz#df5c386e2218be505b34837acbcb874d7a983420" - integrity sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g== +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.5", "@babel/generator@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" + integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== dependencies: - "@babel/types" "^7.23.0" + "@babel/types" "^7.23.5" "@jridgewell/gen-mapping" "^0.3.2" "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" @@ -100,14 +100,14 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.5": +"@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== dependencies: "@babel/types" "^7.22.15" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.5", "@babel/helper-compilation-targets@^7.22.6": +"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== @@ -118,22 +118,22 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.11", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.22.15.tgz#97a61b385e57fe458496fad19f8e63b63c867de4" - integrity sha512-jKkwA59IXcvSaiK2UN45kKwSC9o+KuoXsBDvHvU/7BecYIp8GQ2UwrVvFgJASUT+hBnwJx6MhvMCuMzwZZ7jlg== +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz#2a8792357008ae9ce8c0f2b78b9f646ac96b314b" + integrity sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" - "@babel/helper-member-expression-to-functions" "^7.22.15" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" + "@babel/helper-member-expression-to-functions" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.5": +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== @@ -167,7 +167,7 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-environment-visitor@^7.22.20", "@babel/helper-environment-visitor@^7.22.5": +"@babel/helper-environment-visitor@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== @@ -187,24 +187,24 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-member-expression-to-functions@^7.22.15": +"@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": version "7.23.0" resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== dependencies: "@babel/types" "^7.23.0" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15", "@babel/helper-module-imports@^7.22.5": +"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== dependencies: "@babel/types" "^7.22.15" -"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.22.5", "@babel/helper-module-transforms@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.0.tgz#3ec246457f6c842c0aee62a01f60739906f7047e" - integrity sha512-WhDWw1tdrlT0gMgUJSlX0IQvoO1eN279zrAUbVB+KpV2c3Tylz8+GnKOLllCS6Z/iZQEyVYxhZVUdPTqs2YYPw== +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" + integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== dependencies: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-module-imports" "^7.22.15" @@ -229,7 +229,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== -"@babel/helper-remap-async-to-generator@^7.22.20", "@babel/helper-remap-async-to-generator@^7.22.5": +"@babel/helper-remap-async-to-generator@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== @@ -238,7 +238,7 @@ "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-wrap-function" "^7.22.20" -"@babel/helper-replace-supers@^7.22.20", "@babel/helper-replace-supers@^7.22.5", "@babel/helper-replace-supers@^7.22.9": +"@babel/helper-replace-supers@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== @@ -268,20 +268,20 @@ dependencies: "@babel/types" "^7.22.5" -"@babel/helper-string-parser@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz#533f36457a25814cf1df6488523ad547d784a99f" - integrity sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw== +"@babel/helper-string-parser@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" + integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== "@babel/helper-validator-identifier@^7.22.20": version "7.22.20" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== -"@babel/helper-validator-option@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.22.15.tgz#694c30dfa1d09a6534cdfcafbe56789d36aba040" - integrity sha512-bMn7RmyFjY/mdECUbgn9eoSY4vqvacUnS9i9vGAGttgFWesO6B4CYWA7XlpbWgBt71iv/hfbPlynohStqnu5hA== +"@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" + integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== "@babel/helper-wrap-function@^7.22.20": version "7.22.20" @@ -292,44 +292,52 @@ "@babel/template" "^7.22.15" "@babel/types" "^7.22.19" -"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.2.tgz#2832549a6e37d484286e15ba36a5330483cac767" - integrity sha512-lzchcp8SjTSVe/fPmLwtWVBFC7+Tbn8LGHDVfDp9JGxpAY5opSaEFgt8UQvrnECWOTdji2mOWMz1rOhkHscmGQ== +"@babel/helpers@^7.12.5", "@babel/helpers@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" + integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== dependencies: "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.2" - "@babel/types" "^7.23.0" + "@babel/traverse" "^7.23.5" + "@babel/types" "^7.23.5" -"@babel/highlight@^7.10.4", "@babel/highlight@^7.22.13": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.22.20.tgz#4ca92b71d80554b01427815e06f2df965b9c1f54" - integrity sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg== +"@babel/highlight@^7.10.4", "@babel/highlight@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" + integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== dependencies: "@babel/helper-validator-identifier" "^7.22.20" chalk "^2.4.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.0.tgz#da950e622420bf96ca0d0f2909cdddac3acd8719" - integrity sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw== +"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" + integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.22.15.tgz#02dc8a03f613ed5fdc29fb2f728397c78146c962" - integrity sha512-FB9iYlz7rURmRJyXRKEnalYPPdn87H5no108cyuQQyMwlpJ2SJtpIUBI27kdTin956pz+LPypkPVPUTlxOmrsg== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" + integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.22.15.tgz#2aeb91d337d4e1a1e7ce85b76a37f5301781200f" - integrity sha512-Hyph9LseGvAeeXzikV88bczhsrLrIZqDPxO+sSmAunMPaGrBGhfMWzCPYTtiW9t+HzSE2wtV8e5cc5P6r1xMDQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" + integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.22.15" + "@babel/plugin-transform-optional-chaining" "^7.23.3" + +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz#20c60d4639d18f7da8602548512e9d3a4c8d7098" + integrity sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w== + dependencies: + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-proposal-class-properties@^7.12.1": version "7.18.6" @@ -340,23 +348,23 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-proposal-decorators@^7.12.12": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.2.tgz#0b345a5754f48309fa50b7cd99075ef0295b12c8" - integrity sha512-eR0gJQc830fJVGz37oKLvt9W9uUIQSAovUl0e9sJ3YeO09dlcoBVYD3CLrjCj4qHdXmfiyTyFt8yeQYSN5fxLg== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz#eeaa49d0dc9229aec4d23378653738cdc5a3ea0a" + integrity sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-create-class-features-plugin" "^7.23.5" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/plugin-syntax-decorators" "^7.22.10" + "@babel/plugin-syntax-decorators" "^7.23.3" "@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.22.17" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.22.17.tgz#91b60cd338f501cccdf549af2308768911ec5fbb" - integrity sha512-cop/3quQBVvdz6X5SJC6AhUv3C9DrVTM06LUEXimEdWAhCSyOJIr9NiZDU9leHZ0/aiG0Sh7Zmvaku5TWYNgbA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz#6f511a676c540ccc8d17a8553dbba9230b0ddac0" + integrity sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-default-from" "^7.22.5" + "@babel/plugin-syntax-export-default-from" "^7.23.3" "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": version "7.18.6" @@ -446,10 +454,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-decorators@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.22.10.tgz#7d83ea04d893c442b78ebf4c3cbac59a7211deff" - integrity sha512-z1KTVemBjnz+kSEilAsI4lbkPOl5TvJH7YDSY1CTIzvLWJ+KHXp+mRe8VPmfnyvqOPqar1V2gid2PleKzRUstQ== +"@babel/plugin-syntax-decorators@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz#a1d351d6c25bfdcf2e16f99b039101bc0ffcb0ca" + integrity sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -460,10 +468,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.22.5.tgz#ac3a24b362a04415a017ab96b9b4483d0e2a6e44" - integrity sha512-ODAqWWXB/yReh/jVQDag/3/tl6lgBueQkk/TcfW/59Oykm4c8a55XloX0CTk2k2VJiFWMgHby9xNX29IbCv9dQ== +"@babel/plugin-syntax-export-default-from@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz#7e6d4bf595d5724230200fb2b7401d4734b15335" + integrity sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -474,24 +482,24 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-flow@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.22.5.tgz#163b820b9e7696ce134df3ee716d9c0c98035859" - integrity sha512-9RdCl0i+q0QExayk2nOS7853w08yLucnnPML6EN9S8fgMPVtdLDCdx/cOQ/i44Lb9UeQX9A35yaqBBOMMZxPxQ== +"@babel/plugin-syntax-flow@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" + integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-assertions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.22.5.tgz#07d252e2aa0bc6125567f742cd58619cb14dce98" - integrity sha512-rdV97N7KqsRzeNGoWUOK6yUsWarLjE5Su/Snk9IYPU9CwkWHs4t+rTGOvffTR8XGkJMTAdLfO0xVnXm8wugIJg== +"@babel/plugin-syntax-import-assertions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" + integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-syntax-import-attributes@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.22.5.tgz#ab840248d834410b829f569f5262b9e517555ecb" - integrity sha512-KwvoWDeNKPETmozyFE0P2rOLqh39EoQHNjqizrI5B8Vt0ZNS7M56s7dAiAqbYfiAYOuIzIh96z3iR2ktgu3tEg== +"@babel/plugin-syntax-import-attributes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" + integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -516,10 +524,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.22.5.tgz#a6b68e84fb76e759fc3b93e901876ffabbe1d918" - integrity sha512-gvyP4hZrgrs/wWMaocvxZ44Hw0b3W8Pe+cMxc8V1ULQ07oh8VNbIRaoD1LRZVTvD+0nieDKjfgKg89sD7rrKrg== +"@babel/plugin-syntax-jsx@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" + integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -579,10 +587,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.22.5", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.22.5.tgz#aac8d383b062c5072c647a31ef990c1d0af90272" - integrity sha512-1mS2o03i7t1c6VzH6fdQ3OA8tcEIxwG18zIPRp+UY1Ihv6W+XZzBCVxExF9upussPXJ0xE9XRHwMoNs1ep/nRQ== +"@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" + integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -594,219 +602,219 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.22.5.tgz#e5ba566d0c58a5b2ba2a8b795450641950b71958" - integrity sha512-26lTNXoVRdAnsaDXPpvCNUq+OVWEVC6bx7Vvz9rC53F2bagUWW4u4ii2+h8Fejfh7RYqPxn+libeFBBck9muEw== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" + integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-async-generator-functions@^7.23.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.2.tgz#054afe290d64c6f576f371ccc321772c8ea87ebb" - integrity sha512-BBYVGxbDVHfoeXbOwcagAkOQAm9NxoTdMGfTqghu1GrvadSaw6iW3Je6IcL5PNOw8VwjxqBECXy50/iCQSY/lQ== +"@babel/plugin-transform-async-generator-functions@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" + integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== dependencies: "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-remap-async-to-generator" "^7.22.20" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.22.5.tgz#c7a85f44e46f8952f6d27fe57c2ed3cc084c3775" - integrity sha512-b1A8D8ZzE/VhNDoV1MSJTnpKkCG5bJo+19R4o4oy03zM7ws8yEMK755j61Dc3EyvdysbqH5BOOTquJ7ZX9C6vQ== +"@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" + integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== dependencies: - "@babel/helper-module-imports" "^7.22.5" + "@babel/helper-module-imports" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.5" + "@babel/helper-remap-async-to-generator" "^7.22.20" -"@babel/plugin-transform-block-scoped-functions@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.22.5.tgz#27978075bfaeb9fa586d3cb63a3d30c1de580024" - integrity sha512-tdXZ2UdknEKQWKJP1KMNmuF5Lx3MymtMN/pvA+p/VEkhK8jVcQ1fzSy8KM9qRYhAf2/lV33hoMPKI/xaI9sADA== +"@babel/plugin-transform-block-scoped-functions@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" + integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.0.tgz#8744d02c6c264d82e1a4bc5d2d501fd8aff6f022" - integrity sha512-cOsrbmIOXmf+5YbL99/S49Y3j46k/T16b9ml8bm9lP6N9US5iQ2yBK7gpui1pg0V/WMcXdkfKbTb7HXq9u+v4g== +"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" + integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-class-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.22.5.tgz#97a56e31ad8c9dc06a0b3710ce7803d5a48cca77" - integrity sha512-nDkQ0NfkOhPTq8YCLiWNxp1+f9fCobEjCb0n8WdbNUBc4IB5V7P1QnX9IjpSoquKrXF5SKojHleVNs2vGeHCHQ== +"@babel/plugin-transform-class-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" + integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-class-static-block@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.22.11.tgz#dc8cc6e498f55692ac6b4b89e56d87cec766c974" - integrity sha512-GMM8gGmqI7guS/llMFk1bJDkKfn3v3C4KHK9Yg1ey5qcHcOlKb0QvcMrgzvxo+T03/4szNh5lghY+fEC98Kq9g== +"@babel/plugin-transform-class-static-block@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" + integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.22.15.tgz#aaf4753aee262a232bbc95451b4bdf9599c65a0b" - integrity sha512-VbbC3PGjBdE0wAWDdHM9G8Gm977pnYI0XpqMd6LrKISj8/DJXEsWqgRuTYaNE9Bv0JGhTZUzHDlMk18IpOuoqw== +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.23.5": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz#e7a75f815e0c534cc4c9a39c56636c84fc0d64f2" + integrity sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/helper-environment-visitor" "^7.22.20" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-optimise-call-expression" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.9" + "@babel/helper-replace-supers" "^7.22.20" "@babel/helper-split-export-declaration" "^7.22.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.22.5.tgz#cd1e994bf9f316bd1c2dafcd02063ec261bb3869" - integrity sha512-4GHWBgRf0krxPX+AaPtgBAlTgTeZmqDynokHOX7aqqAB4tHs3U2Y02zH6ETFdLZGcg9UQSD1WCmkVrE9ErHeOg== +"@babel/plugin-transform-computed-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" + integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.5" + "@babel/template" "^7.22.15" -"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.0.tgz#6447aa686be48b32eaf65a73e0e2c0bd010a266c" - integrity sha512-vaMdgNXFkYrB+8lbgniSYWHsgqK5gjaMNcc84bMIOMRLH0L9AqYq3hwMdvnyqj1OPqea8UtjPEuS/DCenah1wg== +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" + integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dotall-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.22.5.tgz#dbb4f0e45766eb544e193fb00e65a1dd3b2a4165" - integrity sha512-5/Yk9QxCQCl+sOIB1WelKnVRxTJDSAIxtJLL2/pqL14ZVlbH0fUQUZa/T5/UnQtBNgghR7mfB8ERBKyKPCi7Vw== +"@babel/plugin-transform-dotall-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" + integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-duplicate-keys@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.22.5.tgz#b6e6428d9416f5f0bba19c70d1e6e7e0b88ab285" - integrity sha512-dEnYD+9BBgld5VBXHnF/DbYGp3fqGMsyxKbtD1mDyIA7AkTSpKXFhCVuj/oQVOoALfBs77DudA0BE4d5mcpmqw== +"@babel/plugin-transform-duplicate-keys@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" + integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-dynamic-import@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.22.11.tgz#2c7722d2a5c01839eaf31518c6ff96d408e447aa" - integrity sha512-g/21plo58sfteWjaO0ZNVb+uEOkJNjAaHhbejrnBmu011l/eNDScmkbjCC3l4FKb10ViaGU4aOkFznSu2zRHgA== +"@babel/plugin-transform-dynamic-import@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" + integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.22.5.tgz#402432ad544a1f9a480da865fda26be653e48f6a" - integrity sha512-vIpJFNM/FjZ4rh1myqIya9jXwrwwgFRHPjT3DkUA9ZLHuzox8jiXkOLvwm1H+PQIP3CqfC++WPKeuDi0Sjdj1g== +"@babel/plugin-transform-exponentiation-operator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" + integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.5" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-export-namespace-from@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.22.11.tgz#b3c84c8f19880b6c7440108f8929caf6056db26c" - integrity sha512-xa7aad7q7OiT8oNZ1mU7NrISjlSkVdMbNxn9IuLZyL9AJEhs1Apba3I+u5riX1dIkdptP5EKDG5XDPByWxtehw== +"@babel/plugin-transform-export-namespace-from@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" + integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-flow-strip-types@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.22.5.tgz#0bb17110c7bf5b35a60754b2f00c58302381dee2" - integrity sha512-tujNbZdxdG0/54g/oua8ISToaXTFBf8EnSb5PgQSciIXWOWKX3S4+JR7ZE9ol8FZwf9kxitzkGQ+QWeov/mCiA== +"@babel/plugin-transform-flow-strip-types@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" + integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-flow" "^7.22.5" + "@babel/plugin-syntax-flow" "^7.23.3" -"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.22.15.tgz#f64b4ccc3a4f131a996388fae7680b472b306b29" - integrity sha512-me6VGeHsx30+xh9fbDLLPi0J1HzmeIIyenoOQHuw2D4m2SAU3NrspX5XxJLBpqn5yrLzrlw2Iy3RA//Bx27iOA== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz#afe115ff0fbce735e02868d41489093c63e15559" + integrity sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-function-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.22.5.tgz#935189af68b01898e0d6d99658db6b164205c143" - integrity sha512-UIzQNMS0p0HHiQm3oelztj+ECwFnj+ZRV4KnguvlsD2of1whUeM6o7wGNj6oLwcDoAXQ8gEqfgC24D+VdIcevg== +"@babel/plugin-transform-function-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" + integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== dependencies: - "@babel/helper-compilation-targets" "^7.22.5" - "@babel/helper-function-name" "^7.22.5" + "@babel/helper-compilation-targets" "^7.22.15" + "@babel/helper-function-name" "^7.23.0" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-json-strings@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.22.11.tgz#689a34e1eed1928a40954e37f74509f48af67835" - integrity sha512-CxT5tCqpA9/jXFlme9xIBCc5RPtdDq3JpkkhgHQqtDdiTnTI0jtZ0QzXhr5DILeYifDPp2wvY2ad+7+hLMW5Pw== +"@babel/plugin-transform-json-strings@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" + integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.22.5.tgz#e9341f4b5a167952576e23db8d435849b1dd7920" - integrity sha512-fTLj4D79M+mepcw3dgFBTIDYpbcB9Sm0bpm4ppXPaO+U+PKFFyV9MGRvS0gvGw62sd10kT5lRMKXAADb9pWy8g== +"@babel/plugin-transform-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" + integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-logical-assignment-operators@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.22.11.tgz#24c522a61688bde045b7d9bc3c2597a4d948fc9c" - integrity sha512-qQwRTP4+6xFCDV5k7gZBF3C31K34ut0tbEcTKxlX/0KXxm9GLcO14p570aWxFvVzx6QAfPgq7gaeIHXJC8LswQ== +"@babel/plugin-transform-logical-assignment-operators@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" + integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.22.5.tgz#4fcc9050eded981a468347dd374539ed3e058def" - integrity sha512-RZEdkNtzzYCFl9SE9ATaUMTj2hqMb4StarOJLrZRbqqU4HSBE7UlBw9WBWQiDzrJZJdUWiMTVDI6Gv/8DPvfew== +"@babel/plugin-transform-member-expression-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" + integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-amd@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.0.tgz#05b2bc43373faa6d30ca89214731f76f966f3b88" - integrity sha512-xWT5gefv2HGSm4QHtgc1sYPbseOyf+FFDo2JbpE25GWl5BqTGO9IMwTYJRoIdjsF85GE+VegHxSCUt5EvoYTAw== +"@babel/plugin-transform-modules-amd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" + integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== dependencies: - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-modules-commonjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.0.tgz#b3dba4757133b2762c00f4f94590cf6d52602481" - integrity sha512-32Xzss14/UVc7k9g775yMIvkVK8xwKE0DPdP5JTapr3+Z9w4tzeOuLNY6BXDQR6BdnzIlXnCGAzsk/ICHBLVWQ== +"@babel/plugin-transform-modules-commonjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" + integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== dependencies: - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-simple-access" "^7.22.5" -"@babel/plugin-transform-modules-systemjs@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.0.tgz#77591e126f3ff4132a40595a6cccd00a6b60d160" - integrity sha512-qBej6ctXZD2f+DhlOC9yO47yEYgUh5CZNz/aBoH4j/3NOlRfJXJbY7xDQCqQVf9KbrqGzIWER1f23doHGrIHFg== +"@babel/plugin-transform-modules-systemjs@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" + integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== dependencies: "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.0" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-identifier" "^7.22.20" -"@babel/plugin-transform-modules-umd@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.22.5.tgz#4694ae40a87b1745e3775b6a7fe96400315d4f98" - integrity sha512-+S6kzefN/E1vkSsKx8kmQuqeQsvCKCd1fraCM7zXm4SFoggI099Tr4G8U81+5gtMdUeMQ4ipdQffbKLX0/7dBQ== +"@babel/plugin-transform-modules-umd@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" + integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== dependencies: - "@babel/helper-module-transforms" "^7.22.5" + "@babel/helper-module-transforms" "^7.23.3" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": @@ -817,108 +825,108 @@ "@babel/helper-create-regexp-features-plugin" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-new-target@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.22.5.tgz#1b248acea54ce44ea06dfd37247ba089fcf9758d" - integrity sha512-AsF7K0Fx/cNKVyk3a+DW0JLo+Ua598/NxMRvxDnkpCIGFh43+h/v2xyhRUYf6oD8gE4QtL83C7zZVghMjHd+iw== +"@babel/plugin-transform-new-target@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" + integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-nullish-coalescing-operator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.22.11.tgz#debef6c8ba795f5ac67cd861a81b744c5d38d9fc" - integrity sha512-YZWOw4HxXrotb5xsjMJUDlLgcDXSfO9eCmdl1bgW4+/lAGdkjaEvOnQ4p5WKKdUgSzO39dgPl0pTnfxm0OAXcg== +"@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" + integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.22.11.tgz#498d77dc45a6c6db74bb829c02a01c1d719cbfbd" - integrity sha512-3dzU4QGPsILdJbASKhF/V2TVP+gJya1PsueQCxIPCEcerqF21oEcrob4mzjsp2Py/1nLfF5m+xYNMDpmA8vffg== +"@babel/plugin-transform-numeric-separator@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" + integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.22.15.tgz#21a95db166be59b91cde48775310c0df6e1da56f" - integrity sha512-fEB+I1+gAmfAyxZcX1+ZUwLeAuuf8VIg67CTznZE0MqVFumWkh8xWtn58I4dxdVf080wn7gzWoF8vndOViJe9Q== +"@babel/plugin-transform-object-rest-spread@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" + integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== dependencies: - "@babel/compat-data" "^7.22.9" + "@babel/compat-data" "^7.23.3" "@babel/helper-compilation-targets" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.22.15" + "@babel/plugin-transform-parameters" "^7.23.3" -"@babel/plugin-transform-object-super@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.22.5.tgz#794a8d2fcb5d0835af722173c1a9d704f44e218c" - integrity sha512-klXqyaT9trSjIUrcsYIfETAzmOEZL3cBYqOYLJxBHfMFFggmXOv+NYSX/Jbs9mzMVESw/WycLFPRx8ba/b2Ipw== +"@babel/plugin-transform-object-super@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" + integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.5" + "@babel/helper-replace-supers" "^7.22.20" -"@babel/plugin-transform-optional-catch-binding@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.22.11.tgz#461cc4f578a127bb055527b3e77404cad38c08e0" - integrity sha512-rli0WxesXUeCJnMYhzAglEjLWVDF6ahb45HuprcmQuLidBJFWjNnOzssk2kuc6e33FlLaiZhG/kUIzUMWdBKaQ== +"@babel/plugin-transform-optional-catch-binding@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" + integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.22.15", "@babel/plugin-transform-optional-chaining@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.0.tgz#73ff5fc1cf98f542f09f29c0631647d8ad0be158" - integrity sha512-sBBGXbLJjxTzLBF5rFWaikMnOGOk/BmK6vVByIdEggZ7Vn6CvWXZyRkkLFK6WE0IF8jSliyOkUN6SScFgzCM0g== +"@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" + integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.22.15.tgz#719ca82a01d177af358df64a514d64c2e3edb114" - integrity sha512-hjk7qKIqhyzhhUvRT683TYQOFa/4cQKwQy7ALvTpODswN40MljzNDa0YldevS6tGbxwaEKVn502JmY0dP7qEtQ== +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" + integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-private-methods@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.22.5.tgz#21c8af791f76674420a147ae62e9935d790f8722" - integrity sha512-PPjh4gyrQnGe97JTalgRGMuU4icsZFnWkzicB/fUtzlKUqvsWBKEpPPfr5a2JiyirZkHxnAqkQMO5Z5B2kK3fA== +"@babel/plugin-transform-private-methods@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" + integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.5" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-private-property-in-object@^7.22.11": - version "7.22.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.22.11.tgz#ad45c4fc440e9cb84c718ed0906d96cf40f9a4e1" - integrity sha512-sSCbqZDBKHetvjSwpyWzhuHkmW5RummxJBVbYLkGkaiTOWGxml7SXt0iWa03bzxFIx7wOj3g/ILRd0RcJKBeSQ== +"@babel/plugin-transform-private-property-in-object@^7.23.4": + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" + integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.11" + "@babel/helper-create-class-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.22.5.tgz#b5ddabd73a4f7f26cd0e20f5db48290b88732766" - integrity sha512-TiOArgddK3mK/x1Qwf5hay2pxI6wCZnvQqrFSqbtg1GLl2JcNMitVH/YnqjP+M31pLUeTfzY1HAXFDnUBV30rQ== +"@babel/plugin-transform-property-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" + integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/plugin-transform-react-constant-elements@^7.18.12": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.22.5.tgz#6dfa7c1c37f7d7279e417ceddf5a04abb8bb9c29" - integrity sha512-BF5SXoO+nX3h5OhlN78XbbDrBOffv+AxPP2ENaJOVqjWCgBDeOY3WcaUcddutGSfoap+5NEQ/q/4I3WZIvgkXA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz#5efc001d07ef0f7da0d73c3a86c132f73d28e43c" + integrity sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-react-display-name@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.22.5.tgz#3c4326f9fce31c7968d6cb9debcaf32d9e279a2b" - integrity sha512-PVk3WPYudRF5z4GKMEYUrLjPl38fJSKNaEOkFuoprioowGuWN6w2RKznuFNSlJx7pzzXXStPUnNSOEO0jL5EVw== +"@babel/plugin-transform-react-display-name@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" + integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== dependencies: "@babel/helper-plugin-utils" "^7.22.5" @@ -930,135 +938,136 @@ "@babel/plugin-transform-react-jsx" "^7.22.5" "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.22.15.tgz#7e6266d88705d7c49f11c98db8b9464531289cd6" - integrity sha512-oKckg2eZFa8771O/5vi7XeTvmM6+O9cxZu+kanTU7tD4sin5nO/G8jGJhq8Hvt2Z0kUoEDRayuZLaUlYl8QuGA== + version "7.23.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" + integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-module-imports" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/types" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/types" "^7.23.4" -"@babel/plugin-transform-react-pure-annotations@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.22.5.tgz#1f58363eef6626d6fa517b95ac66fe94685e32c0" - integrity sha512-gP4k85wx09q+brArVinTXhWiyzLl9UpmGva0+mWyKxk6JZequ05x3eUcIUE+FyttPKJFRRVtAvQaJ6YF9h1ZpA== +"@babel/plugin-transform-react-pure-annotations@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c" + integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-regenerator@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.22.10.tgz#8ceef3bd7375c4db7652878b0241b2be5d0c3cca" - integrity sha512-F28b1mDt8KcT5bUyJc/U9nwzw6cV+UmTeRlXYIl2TNqMMJif0Jeey9/RQ3C4NOd2zp0/TRsDns9ttj2L523rsw== +"@babel/plugin-transform-regenerator@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" + integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.22.5.tgz#832cd35b81c287c4bcd09ce03e22199641f964fb" - integrity sha512-DTtGKFRQUDm8svigJzZHzb/2xatPc6TzNvAIJ5GqOKDsGFYgAskjRulbR/vGsPKq3OPqtexnz327qYpP57RFyA== +"@babel/plugin-transform-reserved-words@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" + integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.22.5.tgz#6e277654be82b5559fc4b9f58088507c24f0c624" - integrity sha512-vM4fq9IXHscXVKzDv5itkO1X52SmdFBFcMIBZ2FRn2nqVYqw6dBexUgMvAjHW+KXpPPViD/Yo3GrDEBaRC0QYA== +"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" + integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.22.5.tgz#6487fd29f229c95e284ba6c98d65eafb893fea6b" - integrity sha512-5ZzDQIGyvN4w8+dMmpohL6MBo+l2G7tfC/O2Dg7/hjpgeWvUx8FzfeOKxGog9IimPa4YekaQ9PlDqTLOljkcxg== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" + integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" -"@babel/plugin-transform-sticky-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.22.5.tgz#295aba1595bfc8197abd02eae5fc288c0deb26aa" - integrity sha512-zf7LuNpHG0iEeiyCNwX4j3gDg1jgt1k3ZdXBKbZSoA3BbGQGvMiSvfbZRR3Dr3aeJe3ooWFZxOOG3IRStYp2Bw== +"@babel/plugin-transform-sticky-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" + integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.22.5.tgz#8f38cf291e5f7a8e60e9f733193f0bcc10909bff" - integrity sha512-5ciOehRNf+EyUeewo8NkbQiUs4d6ZxiHo6BcBcnFlgiJfu16q0bQUw9Jvo0b0gBKFG1SMhDSjeKXSYuJLeFSMA== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" + integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typeof-symbol@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.22.5.tgz#5e2ba478da4b603af8673ff7c54f75a97b716b34" - integrity sha512-bYkI5lMzL4kPii4HHEEChkD0rkc+nvnlR6+o/qdqR6zrm0Sv/nodmyLhlq2DO0YKLUNd2VePmPRjJXSBh9OIdA== +"@babel/plugin-transform-typeof-symbol@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" + integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-typescript@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.22.15.tgz#15adef906451d86349eb4b8764865c960eb54127" - integrity sha512-1uirS0TnijxvQLnlv5wQBwOX3E1wCFX7ITv+9pBV2wKEk4K+M5tqDaoNXnTH8tjEIYHLO98MwiTWO04Ggz4XuA== +"@babel/plugin-transform-typescript@^7.23.3": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz#83da13ef62a1ebddf2872487527094b31c9adb84" + integrity sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA== dependencies: "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" + "@babel/helper-create-class-features-plugin" "^7.23.5" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.22.5" + "@babel/plugin-syntax-typescript" "^7.23.3" -"@babel/plugin-transform-unicode-escapes@^7.22.10": - version "7.22.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.22.10.tgz#c723f380f40a2b2f57a62df24c9005834c8616d9" - integrity sha512-lRfaRKGZCBqDlRU3UIFovdp9c9mEvlylmpod0/OatICsSfuQ9YFthRo1tpTkGsklEefZdqlEFdY4A2dwTb6ohg== +"@babel/plugin-transform-unicode-escapes@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" + integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== dependencies: "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-property-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.22.5.tgz#098898f74d5c1e86660dc112057b2d11227f1c81" - integrity sha512-HCCIb+CbJIAE6sXn5CjFQXMwkCClcOfPCzTlilJ8cUatfzwHlWQkbtV0zD338u9dZskwvuOYTuuaMaA8J5EI5A== +"@babel/plugin-transform-unicode-property-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" + integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.22.5.tgz#ce7e7bb3ef208c4ff67e02a22816656256d7a183" - integrity sha512-028laaOKptN5vHJf9/Arr/HiJekMd41hOEZYvNsrsXqJ7YPYuX2bQxh31fkZzGmq3YqHRJzYFFAVYvKfMPKqyg== +"@babel/plugin-transform-unicode-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" + integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" -"@babel/plugin-transform-unicode-sets-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.22.5.tgz#77788060e511b708ffc7d42fdfbc5b37c3004e91" - integrity sha512-lhMfi4FC15j13eKrh3DnYHjpGj6UKQHtNKTbtc1igvAhRy4+kLhV07OpLcsN0VgDEw/MjAvJO4BdMJsHwMhzCg== +"@babel/plugin-transform-unicode-sets-regex@^7.23.3": + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" + integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" + "@babel/helper-create-regexp-features-plugin" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.19.4": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.2.tgz#1f22be0ff0e121113260337dbc3e58fafce8d059" - integrity sha512-BW3gsuDD+rvHL2VO2SjAUNTBe5YrjsTiDyqamPDWY723na3/yPQ65X5oQkFVJZ0o50/2d+svm1rkPoJeR1KxVQ== + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.5.tgz#350a3aedfa9f119ad045b068886457e895ba0ca1" + integrity sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A== dependencies: - "@babel/compat-data" "^7.23.2" + "@babel/compat-data" "^7.23.5" "@babel/helper-compilation-targets" "^7.22.15" "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.22.15" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.22.15" + "@babel/helper-validator-option" "^7.23.5" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.3" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@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.22.5" - "@babel/plugin-syntax-import-attributes" "^7.22.5" + "@babel/plugin-syntax-import-assertions" "^7.23.3" + "@babel/plugin-syntax-import-attributes" "^7.23.3" "@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" @@ -1070,56 +1079,55 @@ "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.22.5" - "@babel/plugin-transform-async-generator-functions" "^7.23.2" - "@babel/plugin-transform-async-to-generator" "^7.22.5" - "@babel/plugin-transform-block-scoped-functions" "^7.22.5" - "@babel/plugin-transform-block-scoping" "^7.23.0" - "@babel/plugin-transform-class-properties" "^7.22.5" - "@babel/plugin-transform-class-static-block" "^7.22.11" - "@babel/plugin-transform-classes" "^7.22.15" - "@babel/plugin-transform-computed-properties" "^7.22.5" - "@babel/plugin-transform-destructuring" "^7.23.0" - "@babel/plugin-transform-dotall-regex" "^7.22.5" - "@babel/plugin-transform-duplicate-keys" "^7.22.5" - "@babel/plugin-transform-dynamic-import" "^7.22.11" - "@babel/plugin-transform-exponentiation-operator" "^7.22.5" - "@babel/plugin-transform-export-namespace-from" "^7.22.11" - "@babel/plugin-transform-for-of" "^7.22.15" - "@babel/plugin-transform-function-name" "^7.22.5" - "@babel/plugin-transform-json-strings" "^7.22.11" - "@babel/plugin-transform-literals" "^7.22.5" - "@babel/plugin-transform-logical-assignment-operators" "^7.22.11" - "@babel/plugin-transform-member-expression-literals" "^7.22.5" - "@babel/plugin-transform-modules-amd" "^7.23.0" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-modules-systemjs" "^7.23.0" - "@babel/plugin-transform-modules-umd" "^7.22.5" + "@babel/plugin-transform-arrow-functions" "^7.23.3" + "@babel/plugin-transform-async-generator-functions" "^7.23.4" + "@babel/plugin-transform-async-to-generator" "^7.23.3" + "@babel/plugin-transform-block-scoped-functions" "^7.23.3" + "@babel/plugin-transform-block-scoping" "^7.23.4" + "@babel/plugin-transform-class-properties" "^7.23.3" + "@babel/plugin-transform-class-static-block" "^7.23.4" + "@babel/plugin-transform-classes" "^7.23.5" + "@babel/plugin-transform-computed-properties" "^7.23.3" + "@babel/plugin-transform-destructuring" "^7.23.3" + "@babel/plugin-transform-dotall-regex" "^7.23.3" + "@babel/plugin-transform-duplicate-keys" "^7.23.3" + "@babel/plugin-transform-dynamic-import" "^7.23.4" + "@babel/plugin-transform-exponentiation-operator" "^7.23.3" + "@babel/plugin-transform-export-namespace-from" "^7.23.4" + "@babel/plugin-transform-for-of" "^7.23.3" + "@babel/plugin-transform-function-name" "^7.23.3" + "@babel/plugin-transform-json-strings" "^7.23.4" + "@babel/plugin-transform-literals" "^7.23.3" + "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" + "@babel/plugin-transform-member-expression-literals" "^7.23.3" + "@babel/plugin-transform-modules-amd" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-modules-systemjs" "^7.23.3" + "@babel/plugin-transform-modules-umd" "^7.23.3" "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.22.5" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.22.11" - "@babel/plugin-transform-numeric-separator" "^7.22.11" - "@babel/plugin-transform-object-rest-spread" "^7.22.15" - "@babel/plugin-transform-object-super" "^7.22.5" - "@babel/plugin-transform-optional-catch-binding" "^7.22.11" - "@babel/plugin-transform-optional-chaining" "^7.23.0" - "@babel/plugin-transform-parameters" "^7.22.15" - "@babel/plugin-transform-private-methods" "^7.22.5" - "@babel/plugin-transform-private-property-in-object" "^7.22.11" - "@babel/plugin-transform-property-literals" "^7.22.5" - "@babel/plugin-transform-regenerator" "^7.22.10" - "@babel/plugin-transform-reserved-words" "^7.22.5" - "@babel/plugin-transform-shorthand-properties" "^7.22.5" - "@babel/plugin-transform-spread" "^7.22.5" - "@babel/plugin-transform-sticky-regex" "^7.22.5" - "@babel/plugin-transform-template-literals" "^7.22.5" - "@babel/plugin-transform-typeof-symbol" "^7.22.5" - "@babel/plugin-transform-unicode-escapes" "^7.22.10" - "@babel/plugin-transform-unicode-property-regex" "^7.22.5" - "@babel/plugin-transform-unicode-regex" "^7.22.5" - "@babel/plugin-transform-unicode-sets-regex" "^7.22.5" + "@babel/plugin-transform-new-target" "^7.23.3" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" + "@babel/plugin-transform-numeric-separator" "^7.23.4" + "@babel/plugin-transform-object-rest-spread" "^7.23.4" + "@babel/plugin-transform-object-super" "^7.23.3" + "@babel/plugin-transform-optional-catch-binding" "^7.23.4" + "@babel/plugin-transform-optional-chaining" "^7.23.4" + "@babel/plugin-transform-parameters" "^7.23.3" + "@babel/plugin-transform-private-methods" "^7.23.3" + "@babel/plugin-transform-private-property-in-object" "^7.23.4" + "@babel/plugin-transform-property-literals" "^7.23.3" + "@babel/plugin-transform-regenerator" "^7.23.3" + "@babel/plugin-transform-reserved-words" "^7.23.3" + "@babel/plugin-transform-shorthand-properties" "^7.23.3" + "@babel/plugin-transform-spread" "^7.23.3" + "@babel/plugin-transform-sticky-regex" "^7.23.3" + "@babel/plugin-transform-template-literals" "^7.23.3" + "@babel/plugin-transform-typeof-symbol" "^7.23.3" + "@babel/plugin-transform-unicode-escapes" "^7.23.3" + "@babel/plugin-transform-unicode-property-regex" "^7.23.3" + "@babel/plugin-transform-unicode-regex" "^7.23.3" + "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" "@babel/preset-modules" "0.1.6-no-external-plugins" - "@babel/types" "^7.23.0" babel-plugin-polyfill-corejs2 "^0.4.6" babel-plugin-polyfill-corejs3 "^0.8.5" babel-plugin-polyfill-regenerator "^0.5.3" @@ -1127,13 +1135,13 @@ semver "^6.3.1" "@babel/preset-flow@^7.12.1": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.22.15.tgz#30318deb9b3ebd9f5738e96da03a531e0cd3165d" - integrity sha512-dB5aIMqpkgbTfN5vDdTRPzjqtWiZcRESNR88QYnoPR+bmdYoluOzMX9tQerTv0XzSgZYctPfO1oc0N5zdog1ew== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1" + integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-flow-strip-types" "^7.22.5" + "@babel/plugin-transform-flow-strip-types" "^7.23.3" "@babel/preset-modules@0.1.6-no-external-plugins": version "0.1.6-no-external-plugins" @@ -1145,27 +1153,27 @@ esutils "^2.0.2" "@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.18.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.22.15.tgz#9a776892b648e13cc8ca2edf5ed1264eea6b6afc" - integrity sha512-Csy1IJ2uEh/PecCBXXoZGAZBeCATTuePzCSB7dLYWS0vOEj6CNpjxIhW4duWwZodBNueH7QO14WbGn8YyeuN9w== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709" + integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-react-display-name" "^7.22.5" + "@babel/plugin-transform-react-display-name" "^7.23.3" "@babel/plugin-transform-react-jsx" "^7.22.15" "@babel/plugin-transform-react-jsx-development" "^7.22.5" - "@babel/plugin-transform-react-pure-annotations" "^7.22.5" + "@babel/plugin-transform-react-pure-annotations" "^7.23.3" "@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.18.6": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.2.tgz#c8de488130b7081f7e1482936ad3de5b018beef4" - integrity sha512-u4UJc1XsS1GhIGteM8rnGiIvf9rJpiVgMEeCnwlLA7WJPC+jcXWJAGxYmeqs5hOZD8BbAfnV5ezBOxQbb4OUxA== + version "7.23.3" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" + integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== dependencies: "@babel/helper-plugin-utils" "^7.22.5" "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.22.5" - "@babel/plugin-transform-modules-commonjs" "^7.23.0" - "@babel/plugin-transform-typescript" "^7.22.15" + "@babel/plugin-syntax-jsx" "^7.23.3" + "@babel/plugin-transform-modules-commonjs" "^7.23.3" + "@babel/plugin-transform-typescript" "^7.23.3" "@babel/register@^7.12.1": version "7.22.15" @@ -1190,10 +1198,10 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.2.tgz#062b0ac103261d68a966c4c7baf2ae3e62ec3885" - integrity sha512-mM8eg4yl5D6i3lu2QKPuPH4FArvJ8KhTofbE7jwMUv9KX5mBvwPAqnV3MlyBNqdp9RyRKP6Yck8TrfYrPvX3bg== +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" + integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== dependencies: regenerator-runtime "^0.14.0" @@ -1204,7 +1212,7 @@ dependencies: regenerator-runtime "^0.13.2" -"@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.22.5", "@babel/template@^7.3.3": +"@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.3.3": version "7.22.15" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== @@ -1213,28 +1221,28 @@ "@babel/parser" "^7.22.15" "@babel/types" "^7.22.15" -"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.2", "@babel/traverse@^7.7.2": - version "7.23.2" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.2.tgz#329c7a06735e144a506bdb2cad0268b7f46f4ad8" - integrity sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw== +"@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.5", "@babel/traverse@^7.7.2": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" + integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/generator" "^7.23.0" + "@babel/code-frame" "^7.23.5" + "@babel/generator" "^7.23.5" "@babel/helper-environment-visitor" "^7.22.20" "@babel/helper-function-name" "^7.23.0" "@babel/helper-hoist-variables" "^7.22.5" "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.0" - "@babel/types" "^7.23.0" + "@babel/parser" "^7.23.5" + "@babel/types" "^7.23.5" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.0.tgz#8c1f020c9df0e737e4e247c0619f58c68458aaeb" - integrity sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg== +"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.23.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" + integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== dependencies: - "@babel/helper-string-parser" "^7.22.5" + "@babel/helper-string-parser" "^7.23.4" "@babel/helper-validator-identifier" "^7.22.20" to-fast-properties "^2.0.0" @@ -1307,6 +1315,16 @@ "@cosmjs/math" "^0.29.5" "@cosmjs/utils" "^0.29.5" +"@cosmjs/amino@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.0.tgz#1121b73f7d7c5287a599fde1194c8f78af0c0cb5" + integrity sha512-i1ehEZLQo8HUGY78eum+1ZrDQ48QSkHKy0zOTBOMqce6TiwACIC5kOjRSOWdRQDILcPFzPVrbS2dIgtrdd0ykg== + dependencies: + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + "@cosmjs/cosmwasm-launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.6.tgz#b03a96c8d5b5b4742ec4c56b4a01b1f4f33f7f57" @@ -1337,21 +1355,20 @@ pako "^2.0.2" protobufjs "~6.10.2" -"@cosmjs/cosmwasm-stargate@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" - integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== +"@cosmjs/cosmwasm-stargate@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.0.tgz#b35bd57edf9aac9008990b366bfad9ece35d71b1" + integrity sha512-XcCedSMNV5/choH3JCXAiwytBq0uqGI2k5tzifjUifnwd4v58hVA4NUIxUaXk4nWJ5Izd8iylCSmR2owH77Eqw== dependencies: - "@cosmjs/amino" "^0.29.5" - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/proto-signing" "^0.29.5" - "@cosmjs/stargate" "^0.29.5" - "@cosmjs/tendermint-rpc" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" - long "^4.0.0" + "@cosmjs/amino" "^0.32.0" + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/proto-signing" "^0.32.0" + "@cosmjs/stargate" "^0.32.0" + "@cosmjs/tendermint-rpc" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" pako "^2.0.2" "@cosmjs/crypto@^0.25.6": @@ -1383,6 +1400,19 @@ elliptic "^6.5.4" libsodium-wrappers "^0.7.6" +"@cosmjs/crypto@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.0.tgz#61de86e158932321aa4f7a49ff09d726a57c33af" + integrity sha512-h8Fuff9QtHeHAZXB8Mjpk8sYQSqOd484GtD1NAJRCqfXifanNUeZOaXAQkcHbA0eg/IYa+ev7+gOPxm9HkSshQ== + dependencies: + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + "@cosmjs/encoding@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" @@ -1401,6 +1431,15 @@ bech32 "^1.1.4" readonly-date "^1.0.0" +"@cosmjs/encoding@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.0.tgz#1b6f5b7e3f4c8c01c7863202e7eb0de9ad91a252" + integrity sha512-dlurY3BOnv/5JTz3ziGPxvJAsfaXHcOpYP+Fqwo2OHGoWxpQJgJub4QG5V530ZQHliX+6Wqp97lFEwstpISedg== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + "@cosmjs/json-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.25.6.tgz#4f888630e84ee114b164758ec5b48f134068656c" @@ -1417,6 +1456,14 @@ "@cosmjs/stream" "^0.29.5" xstream "^11.14.0" +"@cosmjs/json-rpc@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.0.tgz#733548f54db7cdc581d56e7e0e3d6a0b6ff42163" + integrity sha512-BhnPvgbNPjQZnpzstn6+uLGsP2E4IwREbP7L95yTid+IdTrdnFcF8Ol6xXBWsUtVHtUibX+rbK3wSSgEAV0OBA== + dependencies: + "@cosmjs/stream" "^0.32.0" + xstream "^11.14.0" + "@cosmjs/launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.25.6.tgz#c75f5d21be57af55fcb892f929520fa97f2d5bcc" @@ -1451,6 +1498,13 @@ dependencies: bn.js "^5.2.0" +"@cosmjs/math@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.0.tgz#71f960d59813e49d9736674c5ce40b7b63ee0cf4" + integrity sha512-3h12ENHm1B2TuzZY0JrjGyShIkdUAJDmb/xnSPBBJYZH6ZWL4DFLkq2gISq8XSVCBhuNVv4R+cSCdXs8/vSUTw== + dependencies: + bn.js "^5.2.0" + "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" @@ -1473,6 +1527,18 @@ cosmjs-types "^0.5.2" long "^4.0.0" +"@cosmjs/proto-signing@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.0.tgz#3f182552257b68d040d945913356c399281df0ce" + integrity sha512-9401CI0U5rvKMmYrEN4DAl7wvRd5PwfOTPgxoee+O0d3LzK4FUbTjnNIM7DeUi0zaQw/qU3vSbA3ZcMqPifSbQ== + dependencies: + "@cosmjs/amino" "^0.32.0" + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" + "@cosmjs/socket@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.25.6.tgz#7876bc24e1f16315fbb9e97bd63dea65ba90647d" @@ -1493,6 +1559,16 @@ ws "^7" xstream "^11.14.0" +"@cosmjs/socket@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.0.tgz#45bfaa45ae89347e5134cf115fdf2dc680559207" + integrity sha512-fzb9pBJ6RNYdMIpjCv6NHdQ7C9xSJvP0tF/Tfmmq0yexxl/xDkqSghaDub/os7QzN23RHjTreWjrz9Gov4Z5Vg== + dependencies: + "@cosmjs/stream" "^0.32.0" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + "@cosmjs/stargate@^0.25.5", "@cosmjs/stargate@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.25.6.tgz#ed7428aafd8fe1c12dc4b86f7967deb88117f61a" @@ -1527,6 +1603,22 @@ protobufjs "~6.11.3" xstream "^11.14.0" +"@cosmjs/stargate@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.0.tgz#2f1e1af50ad3156747e377a350b39673c664d324" + integrity sha512-Yo3l+A4vdy3ql30cIanY/j2uD3zxRXTQPrn2YUc67qCxacFkf7Fn3N9GdI7D/B2LQlguf/B5OwheizzWucapkw== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/proto-signing" "^0.32.0" + "@cosmjs/stream" "^0.32.0" + "@cosmjs/tendermint-rpc" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + cosmjs-types "^0.9.0" + xstream "^11.14.0" + "@cosmjs/stream@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.25.6.tgz#1bf7536ed919be3fd7fbffa477c98ef5a93eac70" @@ -1541,6 +1633,13 @@ dependencies: xstream "^11.14.0" +"@cosmjs/stream@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.0.tgz#4fba49708172dffc41a37bbf63f69c8c3186330a" + integrity sha512-df3Svup2QwVr6EqmOzv3KTL0sOxN2sKvz4XJItUeDDxXbcEtTB0+kypmsRQihpXCCmetNArdnvbvkPWxsKCq0w== + dependencies: + xstream "^11.14.0" + "@cosmjs/tendermint-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" @@ -1572,6 +1671,22 @@ readonly-date "^1.0.0" xstream "^11.14.0" +"@cosmjs/tendermint-rpc@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.0.tgz#9acf9030ae20631679dfbaa0611ba618ffe3d192" + integrity sha512-bGH3C0CymIzkROltbqw1iXOEkXJkpjdngJu3hdCdB7bD9xbCWOqB9mT+aLpjNAkzSEAHR4nrWv1JF+3PU2Eggg== + dependencies: + "@cosmjs/crypto" "^0.32.0" + "@cosmjs/encoding" "^0.32.0" + "@cosmjs/json-rpc" "^0.32.0" + "@cosmjs/math" "^0.32.0" + "@cosmjs/socket" "^0.32.0" + "@cosmjs/stream" "^0.32.0" + "@cosmjs/utils" "^0.32.0" + axios "^1.6.0" + readonly-date "^1.0.0" + xstream "^11.14.0" + "@cosmjs/utils@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" @@ -1582,10 +1697,15 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== -"@cosmos-kit/core@^2.7.6": - version "2.7.6" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.6.tgz#391f64b92be667e932859ab22092e91a8b087a23" - integrity sha512-9ORAoY0RLB14ppwMO8I5kvjK9dZUCG/2tMUoMZKtHrLvGnW4vE+tC4FuQW9v23xBwV6MGkoFDxNn1b4j29a2IA== +"@cosmjs/utils@^0.32.0": + version "0.32.0" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.0.tgz#128c0d672a289c99239502d06f045e7cdb60f45e" + integrity sha512-9EWhdTtpaNBSDf2i8nwkWWHfgXGumTVAQe4KuC/R0p3A842MiZhpMAU1WxaZkEO0fcvTbfnM/svAIMVcilDtkw== + +"@cosmos-kit/core@^2.7.7": + version "2.7.7" + resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.7.tgz#150876ddde226fd236e71a8725a6182ff4722f84" + integrity sha512-i/L66ieq3G8lB1eKXqzEYqFVQp0crsR2IuwqDXxytmy02WAydCZInAGiPXKklCBWecWGR6z305NJUynaWmYjmQ== dependencies: "@chain-registry/types" "0.17.0" "@walletconnect/types" "2.10.4" @@ -1593,56 +1713,55 @@ events "3.3.0" uuid "^9.0.1" -"@cosmos-kit/keplr-extension@^2.5.9": - version "2.5.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.9.tgz#398175e7d60ff11627825f1c27389f3342ba0935" - integrity sha512-9c2XAbKLtnMnWH+pNtSYXeqqSkIsWFW/zL9L7tf6jOov+Y9d6mLmHKfGOadbly3GX9l2RZfvYuZ1NZbCvC5u/w== +"@cosmos-kit/keplr-extension@^2.5.10": + version "2.5.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.10.tgz#4e27d351c3f49adc9eae6167c013dd64672bab28" + integrity sha512-Y9c8NQEoHkUNn3ziurMn7dI7JSkR6JVe8Ji/lnFSVqDqc+dOuGEpVqhn9wSJlZc6xuFm88vj9ry+83XbHuxMDA== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" -"@cosmos-kit/keplr-mobile@^2.4.8": - version "2.4.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.8.tgz#6692ed5290e0eb3be3c51ce7d2972252ce569ce4" - integrity sha512-KUkUuSC9kPyVAJIlLyewwwKmkoUV0otVSy4IyOAbhobf9N6Vun08zh5YVz8xfqM8jdzG6F8saoYDBRWqi4xPWA== +"@cosmos-kit/keplr-mobile@^2.4.10": + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.10.tgz#2444448a3ca77da6b8274ed6a0b1be3c0e325d25" + integrity sha512-+AM7q9bDGMu8aKjU126sACVtvOMQ8+Ex0s1GL5Icybqn/6WDDpmOo801k+nvznx7mwaQP7l0n6OUnwAjU3eAjg== dependencies: "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.6" - "@cosmos-kit/walletconnect" "^2.4.8" + "@cosmos-kit/core" "^2.7.7" + "@cosmos-kit/walletconnect" "^2.4.10" "@cosmos-kit/keplr@^2.4.7": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.10.tgz#148e8d63c2ad5545da5ef54943a31ed1d37ae2d5" - integrity sha512-LBiAZkG9sQ9+efVuIb/afK8JvW0OgJigkkAGA2DIGcwqA7k+b2XbvHLNU6octTYLyR32JoiB7M3xkGeIxBfpNw== + version "2.4.12" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.12.tgz#9e063ede4878fa2c87df94cf09787b5e48738ef5" + integrity sha512-bx5YiWN6BiTQjRTIlWxHgWCeWp0fdT0kRxayj6yMkfGWWmBE9kO6mAWmWjB6+zvKyvRRyddT5ry4WW7Gi7gnGw== dependencies: - "@cosmos-kit/keplr-extension" "^2.5.9" - "@cosmos-kit/keplr-mobile" "^2.4.8" + "@cosmos-kit/keplr-extension" "^2.5.10" + "@cosmos-kit/keplr-mobile" "^2.4.10" -"@cosmos-kit/react-lite@^2.5.7": - version "2.5.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.7.tgz#2a6c4e2c9a4712320e72307b7be4d87b012ffb96" - integrity sha512-CHpHw6G0Utf3LhSyONEJUkxuu5wDb9O/C2H+PdYZx50lAn/lBnNaeelQEGQUct0mVdi8XRcjsccjz5JbdjvkBQ== +"@cosmos-kit/react-lite@^2.5.9": + version "2.5.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.9.tgz#1ee73d8db7e7b298c876ac12ff2133fb1bcbe847" + integrity sha512-2RWvR47RCFSyJKtit5g5TjRG504BXDj3mruo5Ukyt5p0n6O+kIDUyz0o1HlVUD4wfxRIr4jgYWU52EDYeYGavQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" "@cosmos-kit/react@^2.9.6": - version "2.9.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.8.tgz#95d1515bd808b76526816dc8d606eca96d5751d5" - integrity sha512-DNmFwoW9TO2a+MvXeJiBfoh+03fFKKQ4jBN4nodKC6CvwTM8i+MnGm2/46gGB/q9iLu2qyVKRkg47uiGqTQZXQ== + version "2.9.11" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.11.tgz#87484a62f46a442d8af7706ccf3ad38fb112b422" + integrity sha512-jlKQ76i0Cb5BxVX7hOX+MwgMQxSxGzg4maORuswD3hh4S4Qi4L2MkDPUIq294Oeaqn8IlTXVjyfVpIcpIwaAtQ== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.6" - "@cosmos-kit/react-lite" "^2.5.7" - "@interchain-ui/react" "^1.11.0" + "@cosmos-kit/core" "^2.7.7" + "@cosmos-kit/react-lite" "^2.5.9" "@react-icons/all-files" "^4.1.0" -"@cosmos-kit/walletconnect@^2.4.8": - version "2.4.8" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.8.tgz#62630f06999d1b59fbe4764ae4cb6912a50cf107" - integrity sha512-SUb21ZiK7UTJ6A8Y5GcD6MfS+iy+hrPUYIpTRLobEKt2uwbmMeRP9hIkhvKxN97iTqXK5ay6BPAtmoJunTpv9g== +"@cosmos-kit/walletconnect@^2.4.10": + version "2.4.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.10.tgz#8de2af854a094a2000c9647f9de6d2a7f279bd8e" + integrity sha512-i/vuZPQ8XhLfh0Llv1Ri7FXjqdvh60mfroKnTlqxO2LchxNcIw3MRZkZKuhalgZNQCPRe1ME2bOxwYmat55/Jg== dependencies: - "@cosmos-kit/core" "^2.7.6" + "@cosmos-kit/core" "^2.7.7" "@walletconnect/sign-client" "^2.9.0" "@walletconnect/types" "2.10.4" "@walletconnect/utils" "^2.9.0" @@ -1855,10 +1974,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.53.0": - version "8.53.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.53.0.tgz#bea56f2ed2b5baea164348ff4d5a879f6f81f20d" - integrity sha512-Kn7K8dx/5U6+cT1yEhpX1w4PCSg0M+XyRILPgvwcEBjerFWCwQj5sbr3/VmxqV0JGHCBCzyd6LxypEuehypY1w== +"@eslint/js@8.54.0": + version "8.54.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" + integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== "@ethersproject/address@^5.6.0": version "5.7.0" @@ -1941,19 +2060,19 @@ "@floating-ui/core" "^1.4.2" "@floating-ui/utils" "^0.1.3" -"@floating-ui/react-dom@^2.0.2": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.2.tgz#fab244d64db08e6bed7be4b5fcce65315ef44d20" - integrity sha512-5qhlDvjaLmAst/rKb3VdlCinwTF4EYMiVxuuc/HVUjs46W0zgtbMmAZ1UTsDrRTxRmUEzl92mOtWbeeXL26lSQ== +"@floating-ui/react-dom@^2.0.3", "@floating-ui/react-dom@^2.0.4": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec" + integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ== dependencies: "@floating-ui/dom" "^1.5.1" "@floating-ui/react@^0.26.0": - version "0.26.1" - resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.1.tgz#a790bd3cff5f334d9e87d3ec132a3dc39d937800" - integrity sha512-5gyJIJ2tZOPMgmZ/vEcVhdmQiy75b7LPO71sYIiDsxGcZ4hxLuygQWCuT0YXHqppt//Eese+L6t5KnX/gZ3tVA== + version "0.26.3" + resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.3.tgz#1ec435f35e37d5e34577ee89c7abb1eedb3a0c5d" + integrity sha512-iKH8WRR0L/nLiM6qavFZxkyegIZRMxGnM9aKEc71M4wRlUNkgTamjPsOQXy11oZbDOH37MiTbk/nAPn9M2+shA== dependencies: - "@floating-ui/react-dom" "^2.0.2" + "@floating-ui/react-dom" "^2.0.3" "@floating-ui/utils" "^0.1.5" tabbable "^6.0.1" @@ -1962,12 +2081,12 @@ resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== -"@formatjs/ecma402-abstract@1.17.2": - version "1.17.2" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.17.2.tgz#d197c6e26b9fd96ff7ba3b3a0cc2f25f1f2dcac3" - integrity sha512-k2mTh0m+IV1HRdU0xXM617tSQTi53tVR2muvYOsBeYcUgEAyxV1FOC7Qj279th3fBVQ+Dj6muvNJZcHSPNdbKg== +"@formatjs/ecma402-abstract@1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.0.tgz#e2120e7101020140661b58430a7ff4262705a2f2" + integrity sha512-PEVLoa3zBevWSCZzPIM/lvPCi8P5l4G+NXQMc/CjEiaCWgyHieUoo0nM7Bs0n/NbuQ6JpXEolivQ9pKSBHaDlA== dependencies: - "@formatjs/intl-localematcher" "0.4.2" + "@formatjs/intl-localematcher" "0.5.2" tslib "^2.4.0" "@formatjs/fast-memoize@2.2.0": @@ -1977,34 +2096,34 @@ dependencies: tslib "^2.4.0" -"@formatjs/icu-messageformat-parser@2.7.0": - version "2.7.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.0.tgz#9b13f2710a3b4efddfeb544480f684f27a53483b" - integrity sha512-7uqC4C2RqOaBQtcjqXsSpGRYVn+ckjhNga5T/otFh6MgxRrCJQqvjfbrGLpX1Lcbxdm5WH3Z2WZqt1+Tm/cn/Q== +"@formatjs/icu-messageformat-parser@2.7.3": + version "2.7.3" + resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.3.tgz#c8c95e7c9f8141bdb93bea0e92e4fcace19d3c9f" + integrity sha512-X/jy10V9S/vW+qlplqhMUxR8wErQ0mmIYSq4mrjpjDl9mbuGcCILcI1SUYkL5nlM4PJqpc0KOS0bFkkJNPxYRw== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" - "@formatjs/icu-skeleton-parser" "1.6.2" + "@formatjs/ecma402-abstract" "1.18.0" + "@formatjs/icu-skeleton-parser" "1.7.0" tslib "^2.4.0" -"@formatjs/icu-skeleton-parser@1.6.2": - version "1.6.2" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.6.2.tgz#00303034dc08583973c8aa67b96534c49c0bad8d" - integrity sha512-VtB9Slo4ZL6QgtDFJ8Injvscf0xiDd4bIV93SOJTBjUF4xe2nAWOoSjLEtqIG+hlIs1sNrVKAaFo3nuTI4r5ZA== +"@formatjs/icu-skeleton-parser@1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.7.0.tgz#796938d6d0ba8fc75bb9edee038d1350bfee32cb" + integrity sha512-Cfdo/fgbZzpN/jlN/ptQVe0lRHora+8ezrEeg2RfrNjyp+YStwBy7cqDY8k5/z2LzXg6O0AdzAV91XS0zIWv+A== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/ecma402-abstract" "1.18.0" tslib "^2.4.0" -"@formatjs/intl-localematcher@0.4.2": - version "0.4.2" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.4.2.tgz#7e6e596dbaf2f0c5a7c22da5a01d5c55f4c37e9a" - integrity sha512-BGdtJFmaNJy5An/Zan4OId/yR9Ih1OojFjcduX/xOvq798OgWSyDtd6Qd5jqJXwJs1ipe4Fxu9+cshic5Ox2tA== +"@formatjs/intl-localematcher@0.5.2": + version "0.5.2" + resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz#5fcf029fd218905575e5080fa33facdcb623d532" + integrity sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw== dependencies: tslib "^2.4.0" -"@formkit/auto-animate@1.0.0-beta.6": - version "1.0.0-beta.6" - resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-1.0.0-beta.6.tgz#ed7f8bc47d774a7764756646e9e3432e8be51cb3" - integrity sha512-PVDhLAlr+B4Xb7e+1wozBUWmXa6BFU8xUPR/W/E+TsQhPS1qkAdAsJ25keEnFrcePSnXHrOsh3tiFbEToOzV9w== +"@formkit/auto-animate@^0.8.1": + version "0.8.1" + resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-0.8.1.tgz#bcaba2969609ca3a7453eacd42b383a2739dfa35" + integrity sha512-0/Z2cuNXWVVIG/l0SpcHAWFhGdvLJ8DRvEfRWvmojtmRWfEy+LWNwgDazbZqY0qQYtkHcoEK3jBLkhiZaB/4Ig== "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": version "1.1.3" @@ -2066,20 +2185,19 @@ resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== -"@interchain-ui/react@^1.11.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.13.0.tgz#b9430c6e9fd5d94a81c3f6ce574b0d0142c491d5" - integrity sha512-samY/4jYEeKLf88AUabxnDpGMFm8V3y+xQCDTjecEn2KkNu23J2fonKUQA8F2Rnj7vsTBHxdjZDeT2wLxlcJFA== +"@interchain-ui/react@^1.14.2": + version "1.14.2" + resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.14.2.tgz#2881eff57ce5988abecc4b7205bc2fad121d9c24" + integrity sha512-YA3Dkq4FOUOcKHoH8iTqozowo5VisaT4iPffkGnxkkShlMY/NwC5V4q5WbdkNaefKmlIoUJDKle/Pyx9UL4iyw== dependencies: "@fastify/deepmerge" "^1.3.0" "@floating-ui/dom" "^1.5.2" "@floating-ui/react" "^0.26.0" - "@formkit/auto-animate" "1.0.0-beta.6" + "@formkit/auto-animate" "^0.8.1" "@react-aria/utils" "^3.21.1" - "@vanilla-extract/css" "^1.12.0" - "@vanilla-extract/css-utils" "^0.1.3" - "@vanilla-extract/dynamic" "^2.0.3" - "@vanilla-extract/recipes" "^0.4.0" + "@vanilla-extract/css" "^1.14.0" + "@vanilla-extract/dynamic" "^2.1.0" + "@vanilla-extract/recipes" "^0.5.1" animejs "^3.2.1" bignumber.js "^9.1.1" client-only "^0.0.1" @@ -2107,10 +2225,10 @@ "@swc/helpers" "^0.5.0" intl-messageformat "^10.1.0" -"@internationalized/number@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.3.0.tgz#92233d130a0591085f93be86a9e6356cfa0e2de2" - integrity sha512-PuxgnKE5NJMOGKUcX1QROo8jq7sW7UWLrL5B6Rfe8BdWgU/be04cVvLyCeALD46vvbAv3d1mUvyHav/Q9a237g== +"@internationalized/number@^3.4.0": + version "3.4.0" + resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.4.0.tgz#1c3ebf6ac40ce649d3d97bb835ff0559957f2e1f" + integrity sha512-8TvotW3qVDHC4uv/BVoN6Qx0Dm8clHY1/vpH+dh+XRiPW/9NVpKn1P8d1A+WLphWrMwyqyWXI7uWehJPviaeIw== dependencies: "@swc/helpers" "^0.5.0" @@ -2121,6 +2239,11 @@ dependencies: "@swc/helpers" "^0.5.0" +"@ioredis/commands@^1.1.1": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" + integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== + "@isaacs/cliui@^8.0.2": version "8.0.2" resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" @@ -2680,91 +2803,91 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@mui/base@5.0.0-beta.23": - version "5.0.0-beta.23" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.23.tgz#dd10dfc609d8937749521f940965f757fa3c0f2c" - integrity sha512-9L8SQUGAWtd/Qi7Qem26+oSSgpY7f2iQTuvcz/rsGpyZjSomMMO6lwYeQSA0CpWM7+aN7eGoSY/WV6wxJiIxXw== +"@mui/base@5.0.0-beta.25": + version "5.0.0-beta.25" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.25.tgz#e1bc39f7a2daa9851fa8d0774ae6d89f0453bdc3" + integrity sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg== dependencies: - "@babel/runtime" "^7.23.2" - "@floating-ui/react-dom" "^2.0.2" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@floating-ui/react-dom" "^2.0.4" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.17.tgz#68ec40ea00832fb685f09bd493648b1f68f5baf4" - integrity sha512-eE0uxrpJAEL2ZXkeGLKg8HQDafsiXY+6eNpP4lcv3yIjFfGbU6Hj9/P7Adt8jpU+6JIhmxvILGj2r27pX+zdrQ== +"@mui/core-downloads-tracker@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.19.tgz#9c04ad047c378d857d529ef9c535b60a10b9a47c" + integrity sha512-y4JseIen5pmZs1n9hHy95HKKioKco8f6N2lford2AmjJigVJOv0KsU0qryiCpyuEUZmi/xCduVilHsK9DSkPcA== "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": - version "5.14.16" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.16.tgz#bd394183b0cfb068d4fa48292cd8d329be8d6b16" - integrity sha512-wmOgslMEGvbHZjFLru8uH5E+pif/ciXAvKNw16q6joK6EWVWU5rDYWFknDaZhCvz8ZE/K8ZnJQ+lMG6GgHzXbg== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.19.tgz#6e0f4e9d89f99517d3c0ee65dee7ac97753755af" + integrity sha512-yjP8nluXxZGe3Y7pS+yxBV+hWZSsSBampCxkZwaw+1l+feL+rfP74vbEFbMrX/Kil9I/Y1tWfy5bs/eNvwNpWw== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.152" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.152.tgz#22efc0dc0e19325759691c81db1ac32da1250481" - integrity sha512-P81QbS/FolrTAjm72N8ndTCYCdPufxJeftNcuc/L4ENHrAo8bV4wcweEyL2AcetfvTgpmGf3QaITrQv8Ts067A== + version "5.0.0-alpha.154" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.154.tgz#c352e164e9f0313317dd8dc1bfd17236fbefbbc8" + integrity sha512-Rrhu8eUknjV6hhPMqq52e/p4/c6rvnu/k0AhysuljsHDZcHThYEZNe1mHFLveQ1RIje2VnJSsgmcNfcZKeOOAg== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.23" - "@mui/system" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/base" "5.0.0-beta.25" + "@mui/system" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" prop-types "^15.8.1" "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.17.tgz#8e11098e52965be3e9ed117d6c107bbe511fac46" - integrity sha512-+y0VeOLWfEA4Z98We/UH6KCo8+f2HLZDK45FY+sJf8kSojLy3VntadKtC/u0itqnXXb1Pr4wKB2tSIBW02zY4Q== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.19.tgz#6b81f6248da04ee73f935a79d81e7819c7115089" + integrity sha512-jSPLXst/YPgDGolhiu4rbethKjLVrI1IkoK8YrFUv8ygxDuhQdsE6+ZqjSSRXk3ytTMf6ghPnQ88OFRk4XjpNw== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/base" "5.0.0-beta.23" - "@mui/core-downloads-tracker" "^5.14.17" - "@mui/system" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" - "@types/react-transition-group" "^4.4.8" + "@babel/runtime" "^7.23.4" + "@mui/base" "5.0.0-beta.25" + "@mui/core-downloads-tracker" "^5.14.19" + "@mui/system" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" + "@types/react-transition-group" "^4.4.9" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.17.tgz#2fdf9d7df54dcb27e8ae7e00f440eb8310376ec3" - integrity sha512-u4zxsCm9xmQrlhVPug+Ccrtsjv7o2+rehvrgHoh0siSguvVgVQq5O3Hh10+tp/KWQo2JR4/nCEwquSXgITS1+g== +"@mui/private-theming@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.19.tgz#f3bae7377f987dc5f40d0c43163ae1ed1f892961" + integrity sha512-U9w39VpXLGVM8wZlUU/47YGTsBSk60ZQRRxQZtdqPfN1N7OVllQeN4cEKZKR8PjqqR3aYRcSciQ4dc6CttRoXQ== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/utils" "^5.14.19" prop-types "^15.8.1" -"@mui/styled-engine@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.17.tgz#7f79d863604076db5278bd38a2eeac44cd2ed336" - integrity sha512-AqpVjBEA7wnBvKPW168bNlqB6EN7HxTjLOY7oi275AzD/b1C7V0wqELy6NWoJb2yya5sRf7ENf4iNi3+T5cOgw== +"@mui/styled-engine@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.19.tgz#dee1d16044a5ef3a783b742381ea4348c159b013" + integrity sha512-jtj/Pyn/bS8PM7NXdFNTHWZfE3p+vItO4/HoQbUeAv3u+cnWXcTBGHHY/xdIn446lYGFDczTh1YyX8G4Ts0Rtg== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@emotion/cache" "^11.11.0" csstype "^3.1.2" prop-types "^15.8.1" "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.17.tgz#441afdd9425b4aad3dea727b0067d367a41f4b58" - integrity sha512-CsftJtCxF3ABigNXikmBJEsI6XQDmeTQNmjaA6wbjYA+29xPMUEQD4Coe+VXGkcc2jrE6Vy8qZ3ytO8QaM9KAw== + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.19.tgz#713f66a4515f2a52f965485a081d64690241c879" + integrity sha512-5yARLEJ8zPzY6zpebupK3PqDo6jQBz1s78qXnBju10toP9HT4WEydpYdm+orDAlUUxP8eVlcpK0fVwza9NwbjA== dependencies: - "@babel/runtime" "^7.23.2" + "@babel/runtime" "^7.23.4" "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@mui/private-theming" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" csstype "^3.1.2" hoist-non-react-statics "^3.3.2" @@ -2778,32 +2901,32 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.17": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.17.tgz#3e212d1e699d4c777bbe5c6584ae129b1ef7d8bc" - integrity sha512-Ccz3XlbCqka6DnbHfpL3o3TfOeWQPR+ewvNAgm8gnS9M0yVMmzzmY6z0w/C1eebb+7ZP7IoLUj9vojg/GBaTPg== +"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.19": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.19.tgz#f13387c60af129e4d61dfbf168fcee348ebe952a" + integrity sha512-4e3Q+2nx+vgEsd0h5ftxlZGB7XtkkPos/zWqCqnxUs1l/T70s0lF2YNrWHHdSQ7LgtBu0eQ0qweZG2pR7KwkAw== dependencies: - "@babel/runtime" "^7.23.2" - "@mui/private-theming" "^5.14.17" - "@mui/styled-engine" "^5.14.17" - "@mui/types" "^7.2.8" - "@mui/utils" "^5.14.17" + "@babel/runtime" "^7.23.4" + "@mui/private-theming" "^5.14.19" + "@mui/styled-engine" "^5.14.19" + "@mui/types" "^7.2.10" + "@mui/utils" "^5.14.19" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" -"@mui/types@^7.2.8": - version "7.2.8" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.8.tgz#2ed4402f104d65fcd4f460ca358654c8935e2285" - integrity sha512-9u0ji+xspl96WPqvrYJF/iO+1tQ1L5GTaDOeG3vCR893yy7VcWwRNiVMmPdPNpMDqx0WV1wtEW9OMwK9acWJzQ== +"@mui/types@^7.2.10": + version "7.2.10" + resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.10.tgz#13e3e9aa07ee6d593cfacd538e02e8e896d7a12f" + integrity sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ== -"@mui/utils@^5.10.3", "@mui/utils@^5.14.17", "@mui/utils@^5.7.0": - version "5.14.17" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.17.tgz#8e2e7ca58865119eec8c6bdb359f539c25aaf576" - integrity sha512-yxnWgSS4J6DMFPw2Dof85yBkG02VTbEiqsikymMsnZnXDurtVGTIhlNuV24GTmFTuJMzEyTTU9UF+O7zaL8LEQ== +"@mui/utils@^5.10.3", "@mui/utils@^5.14.19", "@mui/utils@^5.7.0": + version "5.14.19" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.19.tgz#39a5846a74ba199f1a2b067ea197dc6b9c8f442f" + integrity sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ== dependencies: - "@babel/runtime" "^7.23.2" - "@types/prop-types" "^15.7.9" + "@babel/runtime" "^7.23.4" + "@types/prop-types" "^15.7.11" prop-types "^15.8.1" react-is "^18.2.0" @@ -3011,10 +3134,17 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== +<<<<<<< HEAD "@nymproject/node-tester@^1.0.0": version "1.2.2" resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.2.tgz#7854fb7048b1fd2cf7665dad2b4a08ef0a2fcd39" integrity sha512-Epn48utGII5QAE9bG7AaNuIE3YA2gsTNNvs11AyYB1B4cXk7RLGORcrZ6QBLUn4S+vxqbiPlX4D5G1CdZZVISQ== +======= +"@nymproject/node-tester@^1.0.0", "@nymproject/node-tester@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" + integrity sha512-VDFdH2ddIcXXamwkMbeHA88Xa/S2iPWh9QxkFggppvHS1d6gmnNHAZxXm3Uuhx7pCpzKldA0OT7qohMg9GW9xg== +>>>>>>> 1a01da17e (refactor) "@nymproject/nym-validator-client@^0.18.0": version "0.18.0" @@ -3143,6 +3273,75 @@ dependencies: "@octokit/openapi-types" "^18.0.0" +"@parcel/watcher-android-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" + integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== + +"@parcel/watcher-darwin-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" + integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== + +"@parcel/watcher-darwin-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" + integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== + +"@parcel/watcher-freebsd-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" + integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== + +"@parcel/watcher-linux-arm-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" + integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== + +"@parcel/watcher-linux-arm64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" + integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== + +"@parcel/watcher-linux-arm64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" + integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== + +"@parcel/watcher-linux-x64-glibc@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" + integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== + +"@parcel/watcher-linux-x64-musl@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" + integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== + +"@parcel/watcher-wasm@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz#73b66c6fbd2a3326ae86a1ec77eab7139d0dd725" + integrity sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA== + dependencies: + is-glob "^4.0.3" + micromatch "^4.0.5" + napi-wasm "^1.1.0" + +"@parcel/watcher-win32-arm64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" + integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== + +"@parcel/watcher-win32-ia32@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" + integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== + +"@parcel/watcher-win32-x64@2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" + integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== + "@parcel/watcher@2.0.4": version "2.0.4" resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" @@ -3151,6 +3350,29 @@ node-addon-api "^3.2.1" node-gyp-build "^4.3.0" +"@parcel/watcher@^2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" + integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== + dependencies: + detect-libc "^1.0.3" + is-glob "^4.0.3" + micromatch "^4.0.5" + node-addon-api "^7.0.0" + optionalDependencies: + "@parcel/watcher-android-arm64" "2.3.0" + "@parcel/watcher-darwin-arm64" "2.3.0" + "@parcel/watcher-darwin-x64" "2.3.0" + "@parcel/watcher-freebsd-x64" "2.3.0" + "@parcel/watcher-linux-arm-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-glibc" "2.3.0" + "@parcel/watcher-linux-arm64-musl" "2.3.0" + "@parcel/watcher-linux-x64-glibc" "2.3.0" + "@parcel/watcher-linux-x64-musl" "2.3.0" + "@parcel/watcher-win32-arm64" "2.3.0" + "@parcel/watcher-win32-ia32" "2.3.0" + "@parcel/watcher-win32-x64" "2.3.0" + "@pkgjs/parseargs@^0.11.0": version "0.11.0" resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" @@ -3229,243 +3451,251 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== -"@react-aria/breadcrumbs@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.7.tgz#1d7f5e01887c62516a3e705e59a92e96d315c6c6" - integrity sha512-z+L1gNyWrjZ4Fs0Vo4AkwJicPpEGIestww6r8CiTlt07eo0vCReNmB3oofI6nMJOSu51yef+qqBtFyr0tqBgiw== +"@react-aria/breadcrumbs@^3.5.8": + version "3.5.8" + resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.8.tgz#243a25621066443e42f2a6a1cb82fe3c558f6dea" + integrity sha512-jeek23igeqXct7S3ShW2jtFUc5g3fS9ZEBZkF64FWBrwfCiaZwb8TcKkK/xFw36/q5mxEt+seNiqnNzvsICJuQ== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/link" "^3.6.1" - "@react-aria/utils" "^3.21.1" - "@react-types/breadcrumbs" "^3.7.1" - "@react-types/shared" "^3.21.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/link" "^3.6.2" + "@react-aria/utils" "^3.22.0" + "@react-types/breadcrumbs" "^3.7.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/button@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.8.4.tgz#0f0afe45ad9dfc4f79b2755983a503e2de74f7f5" - integrity sha512-rTGZk5zu+lQNjfij2fwnw2PAgBgzNLi3zbMw1FL5/XwVx+lEH2toeqKLoqULtd7nSxskYuQz56VhmjUok6Qkmg== +"@react-aria/button@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.9.0.tgz#df59e0628917b320c4d1655e23547eb41a9a0f08" + integrity sha512-Jri4OCN+4YmpJDPNQvk1DJoskKD9sdTxZaWWWJdAwoSIunZk3IEBXVvRfKzsEAVtI+UJN25zC2kyjXbVPS2XAA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/calendar@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.2.tgz#a00b2337c0f6c8840aaa9bd5410e95452c5a5e2d" - integrity sha512-HiyUiY0C2aoHa2252Es/Rj1fh5/tewLf6/3gUr42zKl7lq4IqG9cyW7LVRwA47ow1VGLPZSSqTcVakB7jgr7Zw== +"@react-aria/calendar@^3.5.3": + version "3.5.3" + resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.3.tgz#225014e7ef3124bdbc915b7283f7c5d378e1a2a9" + integrity sha512-jW48jk0TIe0HAJS+z8zqd8M86FEuqrk1qEIjMWnf8rFnA7hPPpjdjUrY9vSIeC95NcbyZbFnr1bHzQjAIzosQw== dependencies: "@internationalized/date" "^3.5.0" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/calendar" "^3.4.1" - "@react-types/button" "^3.9.0" - "@react-types/calendar" "^3.4.1" - "@react-types/shared" "^3.21.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/calendar" "^3.4.2" + "@react-types/button" "^3.9.1" + "@react-types/calendar" "^3.4.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/checkbox@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.11.2.tgz#9e1045edf282298cb8337fd3fd1d953c6cf5f667" - integrity sha512-8cgXxpc7IMJ9buw+Rbhr1xc66zNp2ePuFpjw3uWyH7S3IJEd2f5kXUDNWLXQRADJso95UlajRlJQiG4QIObEnA== +"@react-aria/checkbox@^3.12.0": + version "3.12.0" + resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.12.0.tgz#a965e975975404ecf1ff867284511e4490a69c21" + integrity sha512-CyFZoI+z9hhyB3wb7IBsZxE30vXfYO2vSyET16zlkJ4qiFMqMiVLE4ekq034MHltCdpAczgP5yfKgNnJOmj7vQ== dependencies: - "@react-aria/label" "^3.7.2" - "@react-aria/toggle" "^3.8.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/checkbox" "^3.5.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-aria/form" "^3.0.0" + "@react-aria/label" "^3.7.3" + "@react-aria/toggle" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/checkbox" "^3.6.0" + "@react-stately/form" "^3.0.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/checkbox" "^3.6.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/combobox@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.7.1.tgz#8fc26008b54bd2d2c6eac6c126c1b2bba5a5e774" - integrity sha512-37no1b3sRI9mDh3MpMPWNt0Q8QdoRipnx12Vx5Uvtb0PA23hwOWDquICzs157SoJpXP49/+eH6LiA0uTsqwVuQ== +"@react-aria/combobox@^3.8.0": + version "3.8.0" + resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.8.0.tgz#1806cd5ea6c11c90802d7c0a0807d93271265c1c" + integrity sha512-lInzzZrH4vFlxmvDpXgQRkkREm7YIx258IRpQqll8Bny2vKMmZoF06zWMbcHP0CjFqYxExQeTjSYx0OTRRxkCQ== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/listbox" "^3.11.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/listbox" "^3.11.2" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/combobox" "^3.7.1" - "@react-stately/layout" "^3.13.3" - "@react-types/button" "^3.9.0" - "@react-types/combobox" "^3.8.1" - "@react-types/shared" "^3.21.0" + "@react-aria/menu" "^3.11.2" + "@react-aria/overlays" "^3.19.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/combobox" "^3.8.0" + "@react-stately/form" "^3.0.0" + "@react-types/button" "^3.9.1" + "@react-types/combobox" "^3.9.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/datepicker@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.8.1.tgz#7ad2ff17799b7601edfc2eef7d2f35086f182897" - integrity sha512-q2Z5DYDkic3RWzvg3oysrA2VEebuxtEfqj8PSlNFndZh/pNrA+Tvkaatdk/BoxlsZsfeLof+/tBq6yWeqTDguQ== +"@react-aria/datepicker@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.9.0.tgz#281d351b36a3cd186e39f587437d9a3ce9d8986d" + integrity sha512-FIpiJxwBNOM8a6hLOqQJ4JrvRiGL6Zr44E1mHtAWStp2kBEJ6+O2JRm4PQ5Pzvdw6xnCpOBdfESdNdlXN7lVqQ== dependencies: "@internationalized/date" "^3.5.0" - "@internationalized/number" "^3.3.0" + "@internationalized/number" "^3.4.0" "@internationalized/string" "^3.1.1" - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/spinbutton" "^3.5.4" - "@react-aria/utils" "^3.21.1" - "@react-stately/datepicker" "^3.8.0" - "@react-types/button" "^3.9.0" - "@react-types/calendar" "^3.4.1" - "@react-types/datepicker" "^3.6.1" - "@react-types/dialog" "^3.5.6" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/spinbutton" "^3.6.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/datepicker" "^3.9.0" + "@react-stately/form" "^3.0.0" + "@react-types/button" "^3.9.1" + "@react-types/calendar" "^3.4.2" + "@react-types/datepicker" "^3.7.0" + "@react-types/dialog" "^3.5.7" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/dialog@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.7.tgz#e57eca98e95114d618d583f5cc5400bdcf1190b0" - integrity sha512-IKeBaIQBl+WYkhytyE0eISW4ApOEvCJZuw9Xq7gjlKFBlF4X6ffo8souv12KpaznK6/fp1vtEXMmy1AfejiT8Q== +"@react-aria/dialog@^3.5.8": + version "3.5.8" + resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.8.tgz#3b52ff145b16e0f47b04364239bd91d39968e3c2" + integrity sha512-KIc1FORdHhZ3bWom4qHO0hmlL4e5Hup6N25EY8HP5I7Ftv9EBBGaO5grtxZ2fX8kiCJNI4y+k67ZZ71wKJvMiA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/overlays" "^3.18.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/overlays" "^3.6.3" - "@react-types/dialog" "^3.5.6" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/utils" "^3.22.0" + "@react-types/dialog" "^3.5.7" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/dnd@^3.4.3": - version "3.4.3" - resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.4.3.tgz#f13e438f6613f79988ffa5d6a79c5705c26428d4" - integrity sha512-9yiYTQvfT5EUmSsGY3vZlK1xs+xHOFDw5I+c+HyvwqiSu0AIZ4yXqpJVwbarKeZlTOQGCWtb/SOHEdMXfaXKgA== +"@react-aria/dnd@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.5.0.tgz#de803fa390e73205b600933c7fe45ac888a62f3c" + integrity sha512-6IuqmXwnfgRfeXDbfsPZzScapCmtRIkphTBPoLT575uEbZC7ROLgRJ/4NIKxvtTA6IIBqUGcvaqU9Mpg8j4U5Q== dependencies: "@internationalized/string" "^3.1.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/dnd" "^3.2.5" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/dnd" "^3.2.6" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/focus@^3.14.3": - version "3.14.3" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.14.3.tgz#5e66dbf47e1d92aebf67d52b3b08d1631591f5b6" - integrity sha512-gvO/frZ7SxyfyHJYC+kRsUXnXct8hGHKlG1TwbkzCCXim9XIPKDgRzfNGuFfj0i8ZpR9xmsjOBUkHZny0uekFA== +"@react-aria/focus@^3.15.0": + version "3.15.0" + resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.15.0.tgz#acca3cfe94e0ba0c00276e74c6cca06975f75f87" + integrity sha512-nnxRyfqHuAjRwdQ4BpQyZPtGFKZmRU6cnaIb3pqWFCqEyJQensV7MA3TJ4Jhadq67cy1Ji5SYSlr1duBwjoYvw== dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" clsx "^1.1.1" -"@react-aria/grid@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.4.tgz#1f19df9b413e843c82a280a40cd863650e424dfd" - integrity sha512-UxEz98Z6yxVAOq7QSZ9OmSsvMwxJDVl7dVRwUHeqWxNprk9o5GGCLjhMv948XBUEnOvLV2qgtI7UoGzSdliUJA== +"@react-aria/form@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.0.0.tgz#d4e892687331a9cba1cfc48be5754100ab736dec" + integrity sha512-APeGph9oTO8nro4ZObuy1hk+0hpF/ji9O3odPGhLkzP/HvW2J7NI9pjKJOINfgtYr2yvVUZf/MbTMxPwtAxhaQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/grid@^3.8.5": + version "3.8.5" + resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.5.tgz#92682b36b230920d507e3ed4fb7e9564f96c9f02" + integrity sha512-0p+Bbs9rpQeOy8b75DamlzVPKylBoe/z0XwkeeTChHP2TK3TwPXh6J5EmisQx6K8zsb3iZULQRcP4QibvnMbrg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/grid" "^3.8.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/checkbox" "^3.5.2" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/grid" "^3.8.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/virtualizer" "^3.6.5" + "@react-types/checkbox" "^3.6.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/gridlist@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.1.tgz#0be67cd3f0d30a6fe76c0f73927f403ca416a555" - integrity sha512-XnU8mTc/KrwHsGayQm0u5aoaDzdZ8DftKSSfyBEqLiCaibKFqMADb987SOY5+IVGEtYkxDRn1Reo52U0Fs4mxg== +"@react-aria/gridlist@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.2.tgz#80a1399eba438df9d8d8e721eb98b3bf1acdbe52" + integrity sha512-9keGYZz0yILVqAnFzF6hGRtHm1vfSD1mNnH8oyn7mKjyr7qOln7s5f8Nl85ueMolfrV3H2rCZgM2itNQ+Ezzgg== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/grid" "^3.8.4" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/grid" "^3.8.5" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/list" "^3.10.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/i18n@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.8.4.tgz#e7ecd3edcaa66ceaf9ebb1034395e021685163af" - integrity sha512-YlTJn7YJlUxds/T5dNtme551qc118NoDQhK+IgGpzcmPQ3xSnwBAQP4Zwc7wCpAU+xEwnNcsGw+L1wJd49He/A== +"@react-aria/i18n@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.9.0.tgz#7aa74e02e74e348de3a34b7599e71ff6920b73ee" + integrity sha512-ebGP/sVG0ZtNF4RNFzs/W01tl7waYpBManh1kKWgA4roDPFt/odkgkDBzKGl+ggBb7TQRHsfUFHuqKsrsMy9TA== dependencies: "@internationalized/date" "^3.5.0" "@internationalized/message" "^3.1.1" - "@internationalized/number" "^3.3.0" + "@internationalized/number" "^3.4.0" "@internationalized/string" "^3.1.1" - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/interactions@^3.19.1": - version "3.19.1" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.19.1.tgz#b17b1f9dc84624d4222c7fa0a4fa6b4c14fe125a" - integrity sha512-2QFOvq/rJfMGEezmtYcGcJmfaD16kHKcSTLFrZ8aeBK6hYFddGVZJZk+dXf+G7iNaffa8rMt6uwzVe/malJPBA== +"@react-aria/interactions@^3.20.0": + version "3.20.0" + resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.20.0.tgz#8db350541004f50c0479cc52b82597d8248ac5db" + integrity sha512-JCCEyK2Nb4mEHucrgmqhTHTNAEqhsiM07jJmmY22eikxnCQnsEfdwXyg9cgZLG79D5V7jyqVRqOp2OsG7Qx7kQ== dependencies: - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/label@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.2.tgz#6563495cad2af9262e722514e88406baede48852" - integrity sha512-rS0xQy+4RH1+JLESzLZd9H285McjNNf2kKwBhzU0CW3akjlu7gqaMKEJhX9MlpPDIVOUc2oEObGdU3UMmqa8ew== +"@react-aria/label@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.3.tgz#37cb12d2a9495534205b6266aa5174c2fd861368" + integrity sha512-v1zuqbpYyYaPjrBWpceGjMpwP4ne6fLoOXdoIZoKLux2jkAcyIF2kIJFiyYoPQYQJWGRNo7q1oSwamxmng4xJw== dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/label" "^3.8.1" - "@react-types/shared" "^3.21.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/link@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.1.tgz#1e196dc2e25af24a713c3bb6d653aae37b67a1a2" - integrity sha512-uVkuNHabxE11Eqeo0d1RA86EckOlfJ2Ld8uN8HnTxiLetXLZYUMBwlZfBJvT3RdwPtTG7jC3OK3BvwiyIJrtZw== +"@react-aria/link@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.2.tgz#4d7fb00000219aa3ff4bd02f59d5d3bd08be0da8" + integrity sha512-v9gXgQ3Gev0JOlg2MAXcubDMgX+0BlJ+hTyFYFMuN/4jVBlAe426WKbjg+6MMzxwukWg9C3Q08JzqdFTi4cBng== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/link" "^3.5.1" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/link" "^3.5.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/listbox@^3.11.1": - version "3.11.1" - resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.1.tgz#2a2c88daf6a67e07ab17440f72a859913161e6e8" - integrity sha512-AkguQaIkqpP5oe++EZqYHowD7FfeQs+yY0QZVSsVPpNExcBug8/GcXvhSclcOxdh6ekZg4Wwcq7K0zhuTSOPzg== +"@react-aria/listbox@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.2.tgz#5d1d841987c1fbe300fa5d4bf5071f660b2a625b" + integrity sha512-FXdoqYLUTJn16OxodyS518PIcwzFkCfW5bxQepoy88NDMGtqp6u8fvEPpAoZbomvw/pV9MuEaMAw9qLyfkD4DA== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-types/listbox" "^3.4.5" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/list" "^3.10.1" + "@react-types/listbox" "^3.4.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" "@react-aria/live-announcer@^3.3.1": @@ -3475,394 +3705,389 @@ dependencies: "@swc/helpers" "^0.5.0" -"@react-aria/menu@^3.11.1": - version "3.11.1" - resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.1.tgz#fb31c5533d5106c41ed73c14516ecbf74742976a" - integrity sha512-1eVVDrGnSExaL7e8IiaM9ndWTjT23rsnQGUK3p66R1Ojs8Q5rPBuJpP74rsmIpYiKOCr8WyZunjm5Fjv5KfA5Q== +"@react-aria/menu@^3.11.2": + version "3.11.2" + resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.2.tgz#bf6dbf751acc09ace12d35bb034a3790f9006720" + integrity sha512-I4R5FOvRtwIQW+0naXav5giZBp935X2tXB2xBg/cSAYDXgfLmFPLHkyPbO77hR6FwazfFfJoKdn0pVcRox3lrQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/menu" "^3.5.6" - "@react-stately/tree" "^3.7.3" - "@react-types/button" "^3.9.0" - "@react-types/menu" "^3.9.5" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/menu" "^3.5.7" + "@react-stately/tree" "^3.7.4" + "@react-types/button" "^3.9.1" + "@react-types/menu" "^3.9.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/meter@^3.4.7": - version "3.4.7" - resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.7.tgz#33a7b2d4a0be56d147949bb36f3f32bc545c3a87" - integrity sha512-Cp4d6Pd5K6iphXMS/VZ81YxlboUi0I4WPQ+EYb4fxFBJMXVwMK6N5dnn8kwG0vpIx9m0pkFVxSZhlbrwnvW9KA== +"@react-aria/meter@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.8.tgz#af30df03a4c35b13a873ca0847cfa705902b918d" + integrity sha512-u/pNisFs8UottonYlwqaS2i/NhHIw9LcApHo55XP7XMFCnaHPlq3mJzpSsr0zuCTvat2djoKelj41jT6Fhuw+A== dependencies: - "@react-aria/progress" "^3.4.7" - "@react-types/meter" "^3.3.5" - "@react-types/shared" "^3.21.0" + "@react-aria/progress" "^3.4.8" + "@react-types/meter" "^3.3.6" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/numberfield@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.9.1.tgz#de8bbcfbd971c22311a85a3ab34165c53ff96519" - integrity sha512-s9LM5YUzZpbOn5KldUS2JmkDNOA9obVmm8TofICH+z6RnReznp72NLPn0IwblRnocmMOIvGINT55Tz50BmbfNA== +"@react-aria/numberfield@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.10.0.tgz#07d9be63346a0b8e9177a4ca9e4363e03f04afa9" + integrity sha512-ixkvkPTn18RNPnbaT726CHA+Wpr/qTYWboq8hSaJK0LiAtiEWCKg0pmVtJ4lFntAQ5GNp02xudTwhQdLN5WRig== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/spinbutton" "^3.6.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-stately/numberfield" "^3.7.0" + "@react-types/button" "^3.9.1" + "@react-types/numberfield" "^3.7.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/overlays@^3.19.0": + version "3.19.0" + resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.19.0.tgz#0568d808c61e923174e896fc342a1529538da545" + integrity sha512-VN5GkB8+uZ2cfXljBtkqmrsAhBdGoj4un/agH0Qyihi2dazsMeafczSNnqzbpVgB4Zt2UHPJUkKwihgzXRxJJA== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/ssr" "^3.9.0" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/overlays" "^3.6.4" + "@react-types/button" "^3.9.1" + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/progress@^3.4.8": + version "3.4.8" + resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.8.tgz#3776ebeecc27c5b03db7a260ab39a92dbf722a21" + integrity sha512-Nah3aj5BNRa0+urQZimzb0vuKQK7lsc8BrUwJuHTwGRBSWUjCADExrJYdhDIR/nLUV2TCmAQl+GJtTgbEEj0DQ== + dependencies: + "@react-aria/i18n" "^3.9.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-types/progress" "^3.5.1" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/radio@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.9.0.tgz#529b796ed3c5731c808af0a3da29e5535fa553b2" + integrity sha512-kr3+OQ1YU/3mURZfCsYaQmJ/c15qOm8uScaDRC39qz97bLNASakQqMImIaS+GluPKx1PEW3y2ErAgLplH28zZw== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/radio" "^3.10.0" + "@react-types/radio" "^3.6.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/searchfield@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.6.0.tgz#dc40310c875ba4edd288392ada7223186c5fd1eb" + integrity sha512-mHaN+sx2SLqluvF0/YIBQ9WA5LakSWl79FgC0sOWEaOZhDswAbJ9tESdi/M/ahtOnVwblE0cpHRlUKV0Oz4gOw== + dependencies: + "@react-aria/i18n" "^3.9.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/searchfield" "^3.5.0" + "@react-types/button" "^3.9.1" + "@react-types/searchfield" "^3.5.2" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/select@^3.14.0": + version "3.14.0" + resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.14.0.tgz#81c7a3db9fec6d55f4b2820913207afc39b1600d" + integrity sha512-ulVFH8K1yr8CxQE7pzhlM3aWBltWfSbWdJV3FXDqM0kA+GHqqPwZVJcqPuegtaiju1z6nRk4q789kJa4o+4M9g== + dependencies: + "@react-aria/form" "^3.0.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/listbox" "^3.11.2" + "@react-aria/menu" "^3.11.2" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/select" "^3.6.0" + "@react-types/button" "^3.9.1" + "@react-types/select" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/selection@^3.17.2": + version "3.17.2" + resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.2.tgz#74b798344df1eb90e3fdae9bc880c0488468ae3b" + integrity sha512-AXXY3eOIWnITabMn6c0bpLPXkSX7040LOZU+7pQgtZJwDdZorLuKw4i7WS5i71LcV71ywG4mtqc9mOb/GfhUbg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/selection" "^3.14.1" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/separator@^3.3.8": + version "3.3.8" + resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.8.tgz#de209f8158c4dd5d4d66f0a57525bbfdb5b00b15" + integrity sha512-u15HgH2IVKN/mx7Hp9dfNiFpPU/mq2EA7l0e2fsVSjA77nhSctUFBAqaR7FAI/y86RUhq3zplIz4BJek1/3Dvw== + dependencies: + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/slider@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.3.tgz#799b47e8559acf63d9c1195fac88bd4d5ca7cad0" + integrity sha512-AbrTD9UzMn0CwxFjOhJHz2ms2zdJlBL3XnbvqkpsmpXUl0u8WT1QAEaMnS5+792gnSGZs/ARDmse53o+IO8wTA== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/slider" "^3.4.5" + "@react-types/shared" "^3.22.0" + "@react-types/slider" "^3.7.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/spinbutton@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.0.tgz#b881ffd6780f90972879334268634740297197c9" + integrity sha512-I7f1gfwVRcjguEXZijk0z5g8njZ2YWnQzVzcwGf8ocLPxfw1CnSivNCzwVj2ChXPX10uXewXVMLWVCz+BRC9uQ== + dependencies: + "@react-aria/i18n" "^3.9.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/spinbutton" "^3.5.4" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/numberfield" "^3.6.2" - "@react-types/button" "^3.9.0" - "@react-types/numberfield" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" + "@react-aria/utils" "^3.22.0" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/overlays@^3.18.1": - version "3.18.1" - resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.18.1.tgz#b53093b2e1004feff155c81730e0101179cd6c47" - integrity sha512-C74eZbTp3OA/gXy9/+4iPrZiz7g27Zy6Q1+plbg5QTLpsFLBt2Ypy9jTTANNRZfW7a5NW/Bnw9WIRjCdtTBRXw== +"@react-aria/ssr@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.0.tgz#457310129e1447b09d2f4aa2fdd62ab0e668d88c" + integrity sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/ssr" "^3.8.0" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/overlays" "^3.6.3" - "@react-types/button" "^3.9.0" - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" "@swc/helpers" "^0.5.0" -"@react-aria/progress@^3.4.7": - version "3.4.7" - resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.7.tgz#babee1f4775b7baa1b8e2250c861c98805e3d6ee" - integrity sha512-wQ+xnzt5bBdbyQ2Qx80HxaFrPZRFKge57tmJWg4qelo7tzmgb3a22tf0Ug4C3gEz/uAv0JQWOtqLKTxjsiVP7g== - dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-types/progress" "^3.5.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/radio@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.8.2.tgz#318fb1bbdc67131181c03002a5d8458405239b85" - integrity sha512-j8yyGjboTgoBEQWlnJbQVvegKiUeQEUvU/kZ7ZAdj+eAL3BqfO6FO7yt6WzK7ZIBzjGS9YbesaUa3hwIjDi3LA== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/radio" "^3.9.1" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/searchfield@^3.5.7": +"@react-aria/switch@^3.5.7": version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.5.7.tgz#00f0be54375967f86e2b3365bd80ea602af021a3" - integrity sha512-HYjB/QH3AR2E39N6eu+P/DmJMjGweg6LrO1QUbBbKJS+LDorHTN9YNKA4N89gnDDz2IPyycjxtr71hEv0I092A== + resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.7.tgz#b543ac69b5d5dca70c75fc6c80b9c2c9d8191403" + integrity sha512-zBEsB071zzhQ82RwAA42pFLXHgrpya0OoRAsTO6jHZwiaYMsyqJI2eiXd7F6rqklpgyO6k7jOQklGUuoSJW4pA== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/searchfield" "^3.4.6" - "@react-types/button" "^3.9.0" - "@react-types/searchfield" "^3.5.1" - "@react-types/shared" "^3.21.0" + "@react-aria/toggle" "^3.9.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/switch" "^3.5.0" "@swc/helpers" "^0.5.0" -"@react-aria/select@^3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.13.1.tgz#c6d7eda36b8f8887c9baf0f1dea06f30806d71fc" - integrity sha512-tWWOnMnrV1nlZzdO04Ntvf5GCJ6MPkg8Gwv6y0klDDjt12Qyc7J8INluW5A4eMUdtxCkWdaiEsXjyYBHT14ILQ== +"@react-aria/table@^3.13.2": + version "3.13.2" + resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.2.tgz#ef73709facdd005d7d0f6051dc9bedb85eb4e58a" + integrity sha512-bJgMx2SZ8SFmTosbv6k1lZ1a0Yw3f8tzWhpIQodCaMHhtI7izA6YqDNx47NeBNYpVm9DFfAoWbb79HFJ+OKIJA== dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/listbox" "^3.11.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/select" "^3.5.5" - "@react-types/button" "^3.9.0" - "@react-types/select" "^3.8.4" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/selection@^3.17.1": - version "3.17.1" - resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.1.tgz#12df277b8806fd26093e16f6a2734bd1e6fbb3e2" - integrity sha512-g5gkSc/M+zJiVgWbUpKN095ea0D4fxdluH9ZcXxN4AAvcrVfEJyAnMmWOIKRebN8xR0KPfNRnKB7E6jld2tbuQ== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/separator@^3.3.7": - version "3.3.7" - resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.7.tgz#258f52a64d9ec58d62d3257edac542007b54a142" - integrity sha512-5XjDhvGVmGHxxOrXLFCQhOs75v579nPTaSlrKhG/5BjTN3JrByAtuNAw8XZf3HbtiCRZnnL2bKdVbHBjmbuvDw== - dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/slider@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.2.tgz#e122bbf945c5ae0f72be1c8977ef9be957c4bdbf" - integrity sha512-io7yJm2jS0gK1ILE9kjClh9zylKsOLbRy748CyD66LDV0ZIjj2D/uZF6BtfKq7Zhc2OsMvDB9+e2IkrszKe8uw== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-stately/radio" "^3.9.1" - "@react-stately/slider" "^3.4.4" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@react-types/slider" "^3.6.2" - "@swc/helpers" "^0.5.0" - -"@react-aria/spinbutton@^3.5.4": - version "3.5.4" - resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.5.4.tgz#d1c317838f4ae55d6a2e6c698581e4cf0f2b0c89" - integrity sha512-W5dhUOjyBIgd8d4z526fW/HXQ+BdFceeGyvNAXoYBi/1gt3KqN/6CZgskG7OQEufxCOWc9e4A2eWNwvkQVJvWg== - dependencies: - "@react-aria/i18n" "^3.8.4" + "@react-aria/focus" "^3.15.0" + "@react-aria/grid" "^3.8.5" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.21.1" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/ssr@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.8.0.tgz#e7f467ac42f72504682724304ce221f785d70d49" - integrity sha512-Y54xs483rglN5DxbwfCPHxnkvZ+gZ0LbSYmR72LyWPGft8hN/lrl1VRS1EW2SMjnkEWlj+Km2mwvA3kEHDUA0A== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-aria/switch@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.6.tgz#2f3d4b4198f26848fac9876233981b232c151620" - integrity sha512-W6H/0TFa72MJY02AatUERt5HKgaDTF8lOaTjNNmS6U6U20+//uvrVCqcBof8OMe4M60mQpkp7Bd6756CJAMX1w== - dependencies: - "@react-aria/toggle" "^3.8.2" - "@react-stately/toggle" "^3.6.3" - "@react-types/switch" "^3.4.2" - "@swc/helpers" "^0.5.0" - -"@react-aria/table@^3.13.1": - version "3.13.1" - resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.1.tgz#843e377b62c695b6559dd0b6ef0d7bdb8f56c358" - integrity sha512-TBtCmJsKl3rJW/dCzA0ZxPGb8mN7ndbryLh3u+iV/+GVAVsytvAenOGrq9sLHHWXwQo5RJoO1bkUudvrZrJ5/g== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/grid" "^3.8.4" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-stately/collections" "^3.10.2" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-stately/collections" "^3.10.3" "@react-stately/flags" "^3.0.0" - "@react-stately/table" "^3.11.2" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/checkbox" "^3.5.2" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" + "@react-stately/table" "^3.11.3" + "@react-stately/virtualizer" "^3.6.5" + "@react-types/checkbox" "^3.6.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@react-types/table" "^3.9.1" "@swc/helpers" "^0.5.0" -"@react-aria/tabs@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.1.tgz#89229734a5afccbb9a8a03ac8098b1b3653a948f" - integrity sha512-3kRd5rYKclmW9lllcANq0oun2d1pZq7Onma95laYfrWtPBZ3YDVKOkujGSqdfSQAFVshWBjl2Q03yyvcRiwzbQ== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-stately/tabs" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@react-types/tabs" "^3.3.3" - "@swc/helpers" "^0.5.0" - -"@react-aria/tag@^3.2.1": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.2.1.tgz#1fcfece4fc574f066d32aca005fbfc133ef3c247" - integrity sha512-i7Mj3IhB91sGp3NS6iNBVh25W+LR2XXpTmtn3OS4R62q3Oalw/1PKqPWqFc73Lb5IWF5rj3eh2yTf+rerWf3dw== - dependencies: - "@react-aria/gridlist" "^3.7.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/selection" "^3.17.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/list" "^3.10.0" - "@react-types/button" "^3.9.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-aria/textfield@^3.12.2": - version "3.12.2" - resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.12.2.tgz#e1ae5abaf72ed9c800e6a8afface3b2fd58258ca" - integrity sha512-wRg8LJjZV6o4S/LRFqxs5waGDTiuIa/CRN+/X37Fu7GeZFeK0IBvWjKPlXLe7gMswaFqRmTKnQCU42mzUdDK1g== - dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/label" "^3.7.2" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" - "@swc/helpers" "^0.5.0" - -"@react-aria/toggle@^3.8.2": +"@react-aria/tabs@^3.8.2": version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.8.2.tgz#4336f0d70e33347c7bcf43f3ec4e617ce449127b" - integrity sha512-0+RmlOQtyRmU+Dd9qM9od4DPpITC7jqA+n3aZn732XtCsosz5gPGbhFuLbSdWRZ42FQgqo7pZQWaDRZpJPkipA== + resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.2.tgz#ab11e77e6e9afaebb7549983c0aa0d66ae5d96bf" + integrity sha512-zDfeEEyJmcnH9TFvJECWIrJpxX4SmREFV1/P8hN6ZUJPYoeiGMXYYFvjcRb1r3LN8XKlbwR37AQ3Cn1/yhrUwQ== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/toggle" "^3.6.3" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@react-types/switch" "^3.4.2" + "@react-aria/focus" "^3.15.0" + "@react-aria/i18n" "^3.9.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/tabs" "^3.6.2" + "@react-types/shared" "^3.22.0" + "@react-types/tabs" "^3.3.4" "@swc/helpers" "^0.5.0" -"@react-aria/tooltip@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.4.tgz#1be90589f290b09c2a938907124cf72821fb277c" - integrity sha512-5WCOiRSugzbfEOH+Bjpuf6EsNyynqq5S1uDh/P6J8qiYDjc0xLRJ5dyLdytX7c8MK9Y0pIHi6xb0xR9jDqJXTw== +"@react-aria/tag@^3.3.0": + version "3.3.0" + resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.3.0.tgz#ba7b5e2fc3c65f9a37c4737cb96897313174b9f2" + integrity sha512-mANJTcPyut98O4D3cAKaNEV6QFfoljZCDAgC+uJkV/Zn8cU4JOFeNLAyNoLRlPvYw+msqr6wUyPkWNERuO+1Uw== dependencies: - "@react-aria/focus" "^3.14.3" - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-stately/tooltip" "^3.4.5" - "@react-types/shared" "^3.21.0" - "@react-types/tooltip" "^3.4.5" + "@react-aria/gridlist" "^3.7.2" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/selection" "^3.17.2" + "@react-aria/utils" "^3.22.0" + "@react-stately/list" "^3.10.1" + "@react-types/button" "^3.9.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-aria/utils@^3.21.1": - version "3.21.1" - resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.21.1.tgz#35f5d545757ea38f05a0d2f5492f13217ebb03ce" - integrity sha512-tySfyWHXOhd/b6JSrSOl7krngEXN3N6pi1hCAXObRu3+MZlaZOMDf/j18aoteaIF2Jpv8HMWUJUJtQKGmBJGRA== +"@react-aria/textfield@^3.13.0": + version "3.13.0" + resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.13.0.tgz#bc8a027f93598a1ebd5013d027549a03d7b8dd04" + integrity sha512-sUlinDE+k/WhbskyqVOkuffuhiQpjgvp+iGRoralStVgb8Tcb+POxgAlw5jS4tNjdivCb3IjVJemUNJM7xsxxA== dependencies: - "@react-aria/ssr" "^3.8.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/form" "^3.0.0" + "@react-aria/label" "^3.7.3" + "@react-aria/utils" "^3.22.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@react-types/textfield" "^3.9.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/toggle@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.9.0.tgz#c1b253d2fc05f2a673abd9fe4d62bc01a8781a92" + integrity sha512-2YMWYQUEmcoAXtrAE86QXBS9XlmJyV6IFRlMTBNaeLTdH3AmACExgsyU66Tt0sKl6LMDMI376ItMFqAz27BBdQ== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/toggle" "^3.7.0" + "@react-types/checkbox" "^3.6.0" + "@swc/helpers" "^0.5.0" + +"@react-aria/tooltip@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.5.tgz#aeb4c71db46f2c9ad0ff0b6810002bdacc07fea1" + integrity sha512-hXw4Z8nYLOWz3QOQ807wWZdvDwR3gofsmZhAehg2HPRwdRfCQK+1cjVKeUd9cKCAxs0Cay7dV0oUdilLbCQ2Gg== + dependencies: + "@react-aria/focus" "^3.15.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-stately/tooltip" "^3.4.6" + "@react-types/shared" "^3.22.0" + "@react-types/tooltip" "^3.4.6" + "@swc/helpers" "^0.5.0" + +"@react-aria/utils@^3.21.1", "@react-aria/utils@^3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.22.0.tgz#962a45ae95fdc21de7f22dda68253b0fb2470d06" + integrity sha512-Qi/m65GFFljXA/ayj1m5g3KZdgbZY3jacSSqD5vNUOEGiKsn4OQcsw8RfC2c0SgtLV1hLzsfvFI1OiryPlGCcw== + dependencies: + "@react-aria/ssr" "^3.9.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" clsx "^1.1.1" -"@react-aria/visually-hidden@^3.8.6": - version "3.8.6" - resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.6.tgz#9b149851ac41e9c72c7819f8d4ad47ddfb45b863" - integrity sha512-6DmS/JLbK9KgU/ClK1WjwOyvpn8HtwYn+uisMLdP7HlCm692peYOkXDR1jqYbHL4GlyLCD0JLI+/xGdVh5aR/w== +"@react-aria/visually-hidden@^3.8.7": + version "3.8.7" + resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.7.tgz#059699c70cc354ccb3699151b09071b3fc43fa82" + integrity sha512-OuIGMVQIt7GC43h4x35BgkZid8lhoPu7Xz4TQRP8nvOJWb1lH7ehrRRuGdUsK3y90nwpxTdNdg4DILblg+VaLw== dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" - clsx "^1.1.1" "@react-icons/all-files@^4.1.0": version "4.1.0" resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== -"@react-stately/calendar@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.1.tgz#8982ca015c81f35154a23fb26a514a08f9b041a5" - integrity sha512-XKCdrXNA7/ukZ842EeDZfLqYUQDv/x5RoAVkzTbp++3U/MLM1XZXsqj+5xVlQfJiWpQzM9L6ySjxzzgepJDeuw== +"@react-stately/calendar@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.2.tgz#7dd55cd2f0689bd0a5825326507dcb6b3d7f3d05" + integrity sha512-RfH40rVa2EhUnQgqH3HTZL+YhL+6tZ8T9GbN1K3AbIM5BBEtkb3P8qGhcaI7WpwNy1rlRFFFXGcqFAMUncDg2Q== dependencies: "@internationalized/date" "^3.5.0" - "@react-stately/utils" "^3.8.0" - "@react-types/calendar" "^3.4.1" - "@react-types/datepicker" "^3.6.1" - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/calendar" "^3.4.2" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-stately/checkbox@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.5.1.tgz#a6f6ad01852aded85f4baa7c3e97e44d2c47a607" - integrity sha512-j+EbHpZgS8J2LbysbVDK3vQAJc7YZHOjHRX20auEzVmulAFKwkRpevo/R5gEL4EpOz4bRyu+BH/jbssHXG+Ezw== +"@react-stately/checkbox@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.6.0.tgz#448da0b07710a120959985fb081ad3855232fdc9" + integrity sha512-e1ChMwGovcOEDcdizqXDT6eDZixIMiPQOzNV5wPQ91SlGaIry9b0lQnK18tHg3yv2iiS6Ipj96cGBUKLJqQ+cQ== dependencies: - "@react-stately/toggle" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/checkbox" "^3.6.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-stately/collections@^3.10.2": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.2.tgz#c739d9d596ecb744be15fde6f064ad85dd6145db" - integrity sha512-h+LzCa1gWhVRWVH8uR+ZxsKmFSx7kW3RIlcjWjhfyc59BzXCuojsOJKTTAyPVFP/3kOdJeltw8g/reV1Cw/x6Q== - dependencies: - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/combobox@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.7.1.tgz#d101280d406469479ba954cabd872188634033c4" - integrity sha512-JMKsbhCgP8HpwRjHLBmJILzyU9WzWykjXyP4QF/ifmkzGRjC/s46+Ieq+WonjVaLNGCoi6XqhYn2x2RyACSbsQ== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/select" "^3.5.5" - "@react-stately/utils" "^3.8.0" - "@react-types/combobox" "^3.8.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/data@^3.10.3": +"@react-stately/collections@^3.10.3": version "3.10.3" - resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.10.3.tgz#4cdbb0f29489e6f74d2ae7ae032930336695eaa0" - integrity sha512-cC9mxCZU4N9GbdOB4g2/J8+W+860GvBd874to0ObSc/XOR4VbuIsxAFIabW5UwmJV+XaqqK4TUBG0C6YScXeWQ== + resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.3.tgz#c80bd30df3bf5d2a9c6fdf25f6313c5187d0154d" + integrity sha512-fA28HIApAIz9sNGeOVXZJPgV5Kig6M72KI1t9sUbnRUr9Xq9OMJTR6ElDMXNe0iTeZffRFDOPYyqnX9zkxof6Q== dependencies: - "@react-types/shared" "^3.21.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-stately/datepicker@^3.8.0": +"@react-stately/combobox@^3.8.0": version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.8.0.tgz#f87eefb4c5dec937b9d5eb101dd4407457ecd0e7" - integrity sha512-6YDSmkrRafYCWhRHks8Z2tZavM1rqSOy8GY8VYjYMCVTFpRuhPK9TQaFv2BdzZL/vJ6OGThxqoglcEwywZVq2g== + resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.8.0.tgz#6bd9b23ade552f04e8ebc0eeb80e077efed17d6d" + integrity sha512-F74Avf7+8ruRqEB+3Lh6/C5jXc3ESJbRf9ovUxhmNAzBGeFKesPn5HpEpo87C+3OukGb+/Buvi3Rhib9+HVBKA== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-stately/select" "^3.6.0" + "@react-stately/utils" "^3.9.0" + "@react-types/combobox" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/data@^3.11.0": + version "3.11.0" + resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.11.0.tgz#d744d868ee810126aef4a0a827ab394e3059d33a" + integrity sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q== + dependencies: + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/datepicker@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.9.0.tgz#0771c66df937806f812392f8a512a2e72bebbaf0" + integrity sha512-p6BuxPbDxjIgBZmskdv2dR6XIdPEftCjS7kYe/+iLZxfz1vYiDqpJVb3ascLyBjl84bDDyr4z2vWcKhdDwyhEA== dependencies: "@internationalized/date" "^3.5.0" "@internationalized/string" "^3.1.1" - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/datepicker" "^3.6.1" - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/overlays" "^3.6.4" + "@react-stately/utils" "^3.9.0" + "@react-types/datepicker" "^3.7.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-stately/dnd@^3.2.5": - version "3.2.5" - resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.5.tgz#e18c9708133071df911792e85ef6edd2508b3a71" - integrity sha512-f9S+ycjAMEaz9HqGxkx4jsqo/ZS8kh0o97rxSKpGFKPZ02UMFWCr9lJI1p3hVGukiMahrmsNtoQXAvMcFAZyQQ== +"@react-stately/dnd@^3.2.6": + version "3.2.6" + resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.6.tgz#683649dce4183890528d8bea08c30f2b11c812f0" + integrity sha512-ex3Pjn+9uIoqsBb9F4ZFJb3fB0YadN8uYBOEiBb9N4UXWyANibGUYJ2FvIbvq1nFDU7On7MW1J9e3vkGglX4FQ== dependencies: - "@react-stately/selection" "^3.14.0" - "@react-types/shared" "^3.21.0" + "@react-stately/selection" "^3.14.1" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" "@react-stately/flags@^3.0.0": @@ -3872,398 +4097,375 @@ dependencies: "@swc/helpers" "^0.4.14" -"@react-stately/grid@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.2.tgz#b2bd8614489a46ad7d0de13551507afd68d95de2" - integrity sha512-CB5QpYjXFatuXZodj3r0vIiqTysUe6DURZdJu6RKG2Elx19n2k49fKyx7P7CTKD2sPBOMSSX4edWuTzpL8Tl+A== +"@react-stately/form@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@react-stately/form/-/form-3.0.0.tgz#584af339a128045c357c1b8ca440c87460a41b0f" + integrity sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ== dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" + "@react-types/shared" "^3.22.0" "@swc/helpers" "^0.5.0" -"@react-stately/layout@^3.13.3": - version "3.13.3" - resolved "https://registry.yarnpkg.com/@react-stately/layout/-/layout-3.13.3.tgz#65ca0ad8a4653122017c68ec2dc3a3d592296d02" - integrity sha512-AZ2Sm7iSRcRsNATXg7bjbPpZIjV3z7bHAJtICWA1wHieVVSV1FFoyDyiXdDTIOxyuGeytNPaxtGfPpFZia9Wsg== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/table" "^3.11.2" - "@react-stately/virtualizer" "^3.6.4" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/list@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.0.tgz#6b2c66778b687d8c197809059f102029a9bb5079" - integrity sha512-Yspumiln2fvzoO8AND8jNAIfBu1XPaYioeeDmsB5Vrya2EvOkzEGsauQSNBJ6Vhee1fQqpnmzH1HB0jfIKUfzg== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/menu@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.6.tgz#21861b7cfba579d69272509aef8197d3fad7463a" - integrity sha512-Cm82SVda1qP71Fcz8ohIn3JYKmKCuSUIFr1WsEo/YwDPkX0x9+ev6rmphHTsxDdkCLcYHSTQL6e2KL0wAg50zA== - dependencies: - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/menu" "^3.9.5" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/numberfield@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.6.2.tgz#2102d956239721fbf629891d2de46920416492fc" - integrity sha512-li/SO3BU3RGySRNlXhPRKr161GJyNbQe6kjnj+0BFTS/ST9nxCgxFK4llHf+S+I/shNI6+0U2nAjE85QOv4emQ== - dependencies: - "@internationalized/number" "^3.3.0" - "@react-stately/utils" "^3.8.0" - "@react-types/numberfield" "^3.6.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/overlays@^3.6.3": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.3.tgz#cdfe5edb1ed6ad84fc1022af931586489cb23552" - integrity sha512-K3eIiYAdAGTepYqNf2pVb+lPqLoVudXwmxPhyOSZXzjgpynD6tR3E9QfWQtkMazBuU73PnNX7zkH4l87r2AmTg== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/overlays" "^3.8.3" - "@swc/helpers" "^0.5.0" - -"@react-stately/radio@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.9.1.tgz#c43c88e2bff23d3059b0ea22191337a1d644fe0c" - integrity sha512-DrQPHiP9pz1uQbBP/NDFdO8uOZigPbvuAWPUNK7Gq6kye5lW+RsS97IUnYJePNTSMvhiAVz/aleBt05Gr/PZmg== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/radio" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/searchfield@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.4.6.tgz#8d2a394fc20fec559d669e5d63c0a4d7588cb4a0" - integrity sha512-DeVacER0MD35gzQjrYpX/e3k8rjKF82W0OooTkRjeQ2U48femZkQpmp3O+j10foQx2LLaxqt9PSW7QS0Ww1bCA== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/searchfield" "^3.5.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/select@^3.5.5": - version "3.5.5" - resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.5.5.tgz#e0b6dc9635bf46632efeba552e7ff3641c2f581f" - integrity sha512-nDkvFeAZbN7dK/Ty+mk1h4LZYYaoPpkwrG49wa67DTHkCc8Zk2+UEjhKPwOK20th4vfJKHzKjVa0Dtq4DIj0rw== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/select" "^3.8.4" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/selection@^3.14.0": - version "3.14.0" - resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.0.tgz#26a574bf2e35657db1988974df8bd2747b09f5c6" - integrity sha512-E5rNH+gVGDJQDSnPO30ynu6jZ0Z0++VPUbM5Bu3P/bZ3+TgoTtDDvlONba3fspgSBDfdnHpsuG9eqYnDtEAyYA== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/slider@^3.4.4": - version "3.4.4" - resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.4.tgz#36a3f171077fb0e5bd7af7accdc228f5fd2fbe32" - integrity sha512-tFexbtN50zSo6e1Gi8K9MBfqgOo1eemF/VvFbde3PP9nG+ODcxEIajaYDPlMUuFw5cemJuoKo3+G5NBBn2/AjQ== - dependencies: - "@react-aria/i18n" "^3.8.4" - "@react-aria/utils" "^3.21.1" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@react-types/slider" "^3.6.2" - "@swc/helpers" "^0.5.0" - -"@react-stately/table@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.2.tgz#df78442355f3dd086042ad4bf6473a2aaf31f6c1" - integrity sha512-EVgksPAsnEoqeT+5ej4aGJdu9kAu3LCDqQfnmif2P/R1BP5eDU1Kv0N/mV/90Xp546g7kuZ1wS2if/hWDXEA5g== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/flags" "^3.0.0" - "@react-stately/grid" "^3.8.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - "@react-types/table" "^3.9.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/tabs@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.1.tgz#61c010c82ba0d6fde7804245742e0569d6b9eafd" - integrity sha512-akGmejEaXg2RMZuWbRZ0W1MLr515e0uV0iVZefKBlcHtD/mK9K9Bo2XxBScf0TIhaPJ6Qa2w2k2+V7RmT7r8Ag== - dependencies: - "@react-stately/list" "^3.10.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@react-types/tabs" "^3.3.3" - "@swc/helpers" "^0.5.0" - -"@react-stately/toggle@^3.6.3": - version "3.6.3" - resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.6.3.tgz#4de25fd458890e37f6c363d058b018e5f11a9882" - integrity sha512-4kIMTjRjtaapFk4NVmBoFDUYfkmyqDaYAmHpRyEIHTDpBYn0xpxZL/MHv9WuLYa4MjJLRp0MeicuWiZ4ai7f6Q== - dependencies: - "@react-stately/utils" "^3.8.0" - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/tooltip@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.5.tgz#9ba147485d7d7123da91bb417d3722351e90394d" - integrity sha512-VrwQcjnrNddSulh+Zql8P8cORRnWqSPkHPqQwD/Ly91Rva3gUIy+VwnYeThbGDxRzlUv1wfN+UQraEcrgwSZ/Q== - dependencies: - "@react-stately/overlays" "^3.6.3" - "@react-stately/utils" "^3.8.0" - "@react-types/tooltip" "^3.4.5" - "@swc/helpers" "^0.5.0" - -"@react-stately/tree@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.3.tgz#d0b3da5db553e64e8f3def5bae45f765f62a3fd8" - integrity sha512-wB/68qetgCYTe7OMqbTFmtWRrEqVdIH2VlACPCsMlECr3lW9TrrbrOwlHIJfLhkxWvY3kSCoKcOJ5KTiJC9LGA== - dependencies: - "@react-stately/collections" "^3.10.2" - "@react-stately/selection" "^3.14.0" - "@react-stately/utils" "^3.8.0" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-stately/utils@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.8.0.tgz#88a45742c58bde804f6cbecb20ea3833915cfdf0" - integrity sha512-wCIoFDbt/uwNkWIBF+xV+21k8Z8Sj5qGO3uptTcVmjYcZngOaGGyB4NkiuZhmhG70Pkv+yVrRwoC1+4oav9cCg== - dependencies: - "@swc/helpers" "^0.5.0" - -"@react-stately/virtualizer@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.4.tgz#fab655aa14d30a7241ff5751a0eb80552ac5d751" - integrity sha512-lf3+FDRnyLyY1IhLfwA6GuE/9F3nIEc5p245NkUSN1ngKlXI5PvLHNatiVbONC3wt90abkpMK+WMhu2S/B+4lA== - dependencies: - "@react-aria/utils" "^3.21.1" - "@react-types/shared" "^3.21.0" - "@swc/helpers" "^0.5.0" - -"@react-types/breadcrumbs@^3.7.1": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.1.tgz#ec89a2acbae7c9637d087ed0a5f17dda76219d76" - integrity sha512-WWC5pQdWkAzJ2hkx4w7f+waDLLvuD9vowKey+bdLoEmKvdaHNLLVUQPEyFm6SQ5+E3pNBWkNx9a+0S9iW6wa+Q== - dependencies: - "@react-types/link" "^3.5.1" - "@react-types/shared" "^3.21.0" - -"@react-types/button@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.0.tgz#66df80cafaa98aaa34c331e927d21fdf4a0bdc4a" - integrity sha512-YhbchUDB7yL88ZFA0Zqod6qOMdzCLD5yVRmhWymk0yNLvB7EB1XX4c5sRANalfZSFP0RpCTlkjB05Hzp4+xOYg== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/calendar@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.1.tgz#fa12696b3aae5247b3b1dcf747cbc2c5d5d7c30c" - integrity sha512-tiCkHi6IQtYcVoAESG79eUBWDXoo8NImo+Mj8WAWpo1lOA3SV1W2PpeXkoRNqtloilQ0aYcmsaJJUhciQG4ndg== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/shared" "^3.21.0" - -"@react-types/checkbox@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.5.2.tgz#f463befdd37bc2c9e5c6febd62e53131e8983fa4" - integrity sha512-iRQrbY8vRRya3bt3i7sHAifhP/ozfkly1/TItkRK5MNPRNPRDKns55D8ZFkRMj4NSyKQpjVt1zzlBXrnSOxWdQ== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/combobox@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.8.1.tgz#ac9c7abcdde708b09fae78b0dd6d88993f6a8177" - integrity sha512-F910tk8K5qE0TksJ9LRGcJIpaPzpsCnFxT6E9oJH3ssK4N8qZL8QfT9tIKo2XWhK9Uxb/tIZOGQwA8Cn7TyZrA== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/datepicker@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.6.1.tgz#07debffdd611da13f6926266687c22b92624b7ab" - integrity sha512-/M+0e9hL9w98f5k4EoxeH2UfPsUPoS6fvmFsmwUZJcDiw7wP510XngnDLy9GOHj9xgqagZ20S79cxcEuTq7U6g== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/calendar" "^3.4.1" - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - -"@react-types/dialog@^3.5.6": - version "3.5.6" - resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.6.tgz#e874f0896d595e5a7f5924165b0db78e5f62fe9d" - integrity sha512-lwwaAgoi4xe4eEJxBns+cBIRstIPTKWWddMkp51r7Teeh2uKs1Wki7N+Acb9CfT6JQTQDqtVJm6K76rcqNBVwg== - dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - -"@react-types/grid@^3.2.2": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.2.tgz#9434d8ed0a80a64e38b2c95f8bbccfa794fd3888" - integrity sha512-R4USOpn1xfsWVGwZsakRlIdsBA10XNCnAUcRXQTn2JmzLjDCtcln6uYo9IFob080lQuvjkSw3j4zkw7Yo4Qepg== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/label@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/label/-/label-3.8.1.tgz#b076a0fb955051307bfa3fed7e18ce0dc76d8c7b" - integrity sha512-fA6zMTF2TmfU7H8JBJi0pNd8t5Ak4gO+ZA3cZBysf8r3EmdAsgr3LLqFaGTnZzPH1Fux6c7ARI3qjVpyNiejZQ== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/link@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.1.tgz#042cd4f7e7929a53657a5432fd3497056c331b34" - integrity sha512-hX2KpjB7wSuJw5Pia63+WEgEql53VfVG1Vu2cTUJDxfrgUtawwHtxB8B0K3cs3jBanq69amgAInEx0FfqYY0uQ== - dependencies: - "@react-aria/interactions" "^3.19.1" - "@react-types/shared" "^3.21.0" - -"@react-types/listbox@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.5.tgz#c18fbfe38412f7ce42b381fd4aa7bf443dcb6a59" - integrity sha512-nuRY3l8h/rBYQWTXWdZz5YJdl6QDDmXpHrnPuX7PxTwbXcwjhoMK+ZkJ0arA8Uv3MPs1OUcT6K6CInsPnG2ARQ== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/menu@^3.9.5": - version "3.9.5" - resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.5.tgz#9f67aebda9f491f0e94e2de7a15898c6cabf0772" - integrity sha512-KB5lJM0p9PxwpVlHV9sRdpjh+sqINeHrJgGizy/cQI9bj26nupiEgamSD14dULNI6BFT9DkgKCsobBtE04DDKQ== - dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" - -"@react-types/meter@^3.3.5": - version "3.3.5" - resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.5.tgz#274dc17b4de985063e74272d82c0052e13bb75e8" - integrity sha512-7kSP/bqkt6ANHUJLJ4OsHOPNwg9ETvWHAKXDYoCqkLYzdhFh0H/8EAW9z4Bh/io0GvR7ePds9s+32iislfSwDg== - dependencies: - "@react-types/progress" "^3.5.0" - "@react-types/shared" "^3.21.0" - -"@react-types/numberfield@^3.6.1": - version "3.6.1" - resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.6.1.tgz#da13f9086181a64a7e2e39f500584bdca20097b3" - integrity sha512-jdMCN0mQ7eZkPrCKYkkG+jSjcG2VQ5P7mR9tTaCQeQK1wo+tF/8LWD+6n6dU7hH/qlU9sxVEg3U3kJ9sgNK+Hw== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/overlays@^3.8.3": +"@react-stately/grid@^3.8.3": version "3.8.3" - resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.3.tgz#47132f08ae3a115273036d98b9441a51d4a4ab09" - integrity sha512-TrCG2I2+V+TD0PGi3CqfnyU5jEzcelSGgYJQvVxsl5Vv3ri7naBLIsOjF9x66tPxhINLCPUtOze/WYRAexp8aw== + resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.3.tgz#42420724084a023c74e50d9c82efd8074179680d" + integrity sha512-JceGSJcuO6Zv+Aq5s2NZvmbMjdPjTtGNQR9kTgXKC/pOfM6FJ58bJiOmEllyN6oawqh4Ey8Xdqk9NuW4l2ctuw== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" -"@react-types/progress@^3.5.0": +"@react-stately/list@^3.10.1": + version "3.10.1" + resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.1.tgz#1d926d4aef5764096ec357da8081ef09081fe5cc" + integrity sha512-iVarLMd7FmMT0H20dRWsFOHHX5+c4gK51AXP2BSr1VtDSfbL4dgaGgu7IaAMVc/rO0au1e1tPM2hutiIFvPcnA== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/menu@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.7.tgz#3232598399b4baebfc577d5f56b4bd5570f400c2" + integrity sha512-bzTmAqzcMNatvyruWlvOdZSmMhz3+mkdxtqaZzYHq+DpR6ka57lIRj8dBnZWQGwV3RypMZfz+X6aIX4kruGVbw== + dependencies: + "@react-stately/overlays" "^3.6.4" + "@react-types/menu" "^3.9.6" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/numberfield@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.7.0.tgz#a0fd05da980dbe510d1d99ea7cf21ce4f9bac1bb" + integrity sha512-DOz4jL7T30KGUXpGh/z80aHf+DEOQfvCHVDfll+IU7p3sd+bbM5uj7JdwXpZgIYUK8KTf2N49sL6lq5uCoxh8w== + dependencies: + "@internationalized/number" "^3.4.0" + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/numberfield" "^3.7.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/overlays@^3.6.4": + version "3.6.4" + resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.4.tgz#1d0d974413fa3f13d97eec2cac5b48c49978d1a0" + integrity sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA== + dependencies: + "@react-stately/utils" "^3.9.0" + "@react-types/overlays" "^3.8.4" + "@swc/helpers" "^0.5.0" + +"@react-stately/radio@^3.10.0": + version "3.10.0" + resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.10.0.tgz#01750b861bfdbb048c6e1bbfb6a97a4f42c29c25" + integrity sha512-d8IgZtUq/4vhE7YhyBVg1QdVoFS0caIcvPumXqtp/5vlDgpUsVy9jSeWtbk0H4FyUcmJlQhRcTylKB9THXY1YQ== + dependencies: + "@react-stately/form" "^3.0.0" + "@react-stately/utils" "^3.9.0" + "@react-types/radio" "^3.6.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/searchfield@^3.5.0": version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.0.tgz#5fa64897bcf93308c8386a3d0444585cb869e313" - integrity sha512-c1KLQCfYjdUdkTcPy0ZW31dc2+D86ZiZRHPNOaSYFGJjk9ItbWWi8BQTwlrw6D2l/+0d/YDdUFGaZhHMrY9mBQ== + resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.0.tgz#8493eefd684bc85117b42c7c714f6541afe54816" + integrity sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/searchfield" "^3.5.2" + "@swc/helpers" "^0.5.0" -"@react-types/radio@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.5.2.tgz#399e220e2529b2e7c93aa117d39adcca6dc24d1f" - integrity sha512-crYQ+97abd5v0Iw9X+Tt+E7KWdm5ckr4g0+Iy8byV1g6MyiBOsNtq9QT99TOzyWJPqqD8T9qZfAOk49wK7KEDg== +"@react-stately/select@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.6.0.tgz#e77464f3e0367d652866806c1ab61c132c31c49a" + integrity sha512-GvSE4DXmcvdRNUc+ciPU7gedt7LfRO8FFFIzhB/bCQhUlK6/xihUPrGXayzqxLeTQKttMH323LuYFKfwpJRhsA== dependencies: - "@react-types/shared" "^3.21.0" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-types/select" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" -"@react-types/searchfield@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.1.tgz#9e8d9b4ff16749a821cbba20e0069f5d77a8b9f2" - integrity sha512-+v9fo50JrZOfFzbdgJsW39hyTFv1gVH458nx82aidYJzQocFJniiAEl0ZhhRzbE8RijyjLleKIAY+klPeFmEaQ== +"@react-stately/selection@^3.14.1": + version "3.14.1" + resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.1.tgz#798b4fbfda940778ae1dc1f2d2390cee97cce2c6" + integrity sha512-96/CerrB6yH4Ad9FkzBzyVerSPjcIj1NBTWTFHo1N+oHECvyGsDxZl7Y4LQR++teFK66FhX5KjCJQGae4IZd6A== dependencies: - "@react-types/shared" "^3.21.0" - "@react-types/textfield" "^3.8.1" + "@react-stately/collections" "^3.10.3" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" -"@react-types/select@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.8.4.tgz#564e6d89095d736ed580a733dd8baa7fadab05bc" - integrity sha512-jHBaLiAHTcYPz52kuJpypBbR0WAA+YCZHy2HH+W8711HuTqePZCEp6QAWHK9Fw0qwSZQ052jYaWvOsgEZZ6ojQ== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/shared@^3.21.0": - version "3.21.0" - resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.21.0.tgz#1af41fdf7dfbdbd33bbc1210617c43ed0d4ef20c" - integrity sha512-wJA2cUF8dP4LkuNUt9Vh2kkfiQb2NLnV2pPXxVnKJZ7d4x2/7VPccN+LYPnH8m0X3+rt50cxWuPKQmjxSsCFOg== - -"@react-types/slider@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.6.2.tgz#b401bbbd473b62edc394ac3c41ed6df329d111d4" - integrity sha512-LSvna1gpOvBxOBI5I/CYEtkAshWYwPlxE9F/jCaxCa9Q7E9xZp1hFFGY87iQ1A3vQM5SCa5PFStwOvXO7rA55w== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/switch@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.4.2.tgz#8c0a8f8dfcaae29ccd9409a2beaac0d31a131027" - integrity sha512-OQWpawikWhF+ET1/kE0/JeJVr6gHjkR72p/idTsT7RUJySBcehhAscbIA8iWzVWJvdFCVF2hG7uzBAJTeDMr9A== - dependencies: - "@react-types/checkbox" "^3.5.2" - "@react-types/shared" "^3.21.0" - -"@react-types/table@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.0.tgz#0053ce5b78f2214afaf7e38cdd96a57eecbd2ff9" - integrity sha512-WOLxZ3tzLA4gxRxvnsZhnnQDbh4Qe/johpHNk4coSOFOP5W8PbunPacXnbvdPkSx6rqrOIzCnYcZCtgk4gDQmg== - dependencies: - "@react-types/grid" "^3.2.2" - "@react-types/shared" "^3.21.0" - -"@react-types/tabs@^3.3.3": - version "3.3.3" - resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.3.tgz#8601d9cd03c6aa4cca1227df667ae8cedb58839c" - integrity sha512-Zc4g5TIwJpKS5fiT9m4dypbCr1xqtauL4wqM76fGERCAZy0FwXTH/yjzHJDYKyWFJrQNWtJ0KAhJR/ZqKDVnIw== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/textfield@^3.8.1": - version "3.8.1" - resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.8.1.tgz#433c82d8f696ed77b1d5e71aadc40cbe378b536c" - integrity sha512-p8Xmew9kzJd+tCM7h9LyebZHpv7SH1IE1Nu13hLCOV5cZ/tVVVCwjNGLMv4MtUpSn++H42YLJgAW9Uif+a+RHg== - dependencies: - "@react-types/shared" "^3.21.0" - -"@react-types/tooltip@^3.4.5": +"@react-stately/slider@^3.4.5": version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.5.tgz#f1edf9940bc3cde89ae9d49fda815e16f253dfd5" - integrity sha512-pv87Vlu+Pn1Titw199y5aiSuXF/GHX+fBCihi9BeePqtwYm505e/Si01BNh5ejCeXXOS4JIMuXwmGGzGVdGk6Q== + resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.5.tgz#46d4a7e0a1644894e91b12003fa1ba8e0787f4ca" + integrity sha512-lJPZC8seYbnZDqAlZm3/QC95I5iluG8ouwkPMmvtWCz1baayV/jJtfxA/74zR7Vcob9Fe7O57g8Edhz/hv9xOQ== dependencies: - "@react-types/overlays" "^3.8.3" - "@react-types/shared" "^3.21.0" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@react-types/slider" "^3.7.0" + "@swc/helpers" "^0.5.0" -"@remix-run/router@1.11.0": - version "1.11.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.11.0.tgz#e0e45ac3fff9d8a126916f166809825537e9f955" - integrity sha512-BHdhcWgeiudl91HvVa2wxqZjSHbheSgIiDvxrF1VjFzBzpTtuDPkOdOi3Iqvc08kXtFkLjhbS+ML9aM8mJS+wQ== +"@react-stately/table@^3.11.3": + version "3.11.3" + resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.3.tgz#0d9e547fc2e30df174ac4ba3728402f62fb2fc0a" + integrity sha512-r0rzSKbtMG4tjFpCGtXb8p6hOuek03c6rheJE88z4I/ujZ5EmEO6Ps8q0JMNEDCY2qigvKM+ODisMBeZCEkIJg== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/flags" "^3.0.0" + "@react-stately/grid" "^3.8.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + "@react-types/table" "^3.9.1" + "@swc/helpers" "^0.5.0" + +"@react-stately/tabs@^3.6.2": + version "3.6.2" + resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.2.tgz#a9825d560af58c4f876e7b619c7e8cb29b071887" + integrity sha512-f+U4D1FAVfVVcNRbtKIv4GrO37CLFClYQlXx9zIuSXjHsviapVD2IQSyAmpKo/CbgXhYRMdGwENZdOsmF/Ns7g== + dependencies: + "@react-stately/list" "^3.10.1" + "@react-types/shared" "^3.22.0" + "@react-types/tabs" "^3.3.4" + "@swc/helpers" "^0.5.0" + +"@react-stately/toggle@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.7.0.tgz#abe2f08f37a0f41e6513d4fde3d46f49500bb5cc" + integrity sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g== + dependencies: + "@react-stately/utils" "^3.9.0" + "@react-types/checkbox" "^3.6.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/tooltip@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.6.tgz#e240184dedc35018f7b1e2d46eaca20a90d919bb" + integrity sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA== + dependencies: + "@react-stately/overlays" "^3.6.4" + "@react-types/tooltip" "^3.4.6" + "@swc/helpers" "^0.5.0" + +"@react-stately/tree@^3.7.4": + version "3.7.4" + resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.4.tgz#57cc57863837092f13b7a3887e1b5c56330b5cac" + integrity sha512-0yvVODBS8WnSivLFX5ccEjCl2NA/8lbEt1E48wVcY1xcXgISNpw5MSGK5jC6YrtJPIqVolQIkNSbMreXGBktIg== + dependencies: + "@react-stately/collections" "^3.10.3" + "@react-stately/selection" "^3.14.1" + "@react-stately/utils" "^3.9.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-stately/utils@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.9.0.tgz#9cb2c8eea5dd1b58256ecb436b963c01526bae37" + integrity sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw== + dependencies: + "@swc/helpers" "^0.5.0" + +"@react-stately/virtualizer@^3.6.5": + version "3.6.5" + resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.5.tgz#45891ac24b6aed0aa168e26c61a39d235d204a70" + integrity sha512-v0cZeNCGPMeo3LP4UrGuDo3Xpq7ufNaZyGObgSvdrIW49qK5F02kczcKy6NKg+QfOgC/+Nc9Tof/2S8dcxDrCA== + dependencies: + "@react-aria/utils" "^3.22.0" + "@react-types/shared" "^3.22.0" + "@swc/helpers" "^0.5.0" + +"@react-types/breadcrumbs@^3.7.2": + version "3.7.2" + resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.2.tgz#3dc0c8ccebf75844efc56ac8e53dc072df083d5f" + integrity sha512-esl6RucDW2CNMsApJxNYfMtDaUcfLlwKMPH/loYsOBbKxGl2HsgVLMcdpjEkTRs2HCTNCbBXWpeU8AY77t+bsw== + dependencies: + "@react-types/link" "^3.5.2" + "@react-types/shared" "^3.22.0" + +"@react-types/button@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.1.tgz#eb54745133bdaad345d8d589021b67ef2882e1c5" + integrity sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/calendar@^3.4.2": + version "3.4.2" + resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.2.tgz#a184851c2c891e8baa06e3d11173bb4bf101a48b" + integrity sha512-tCZ21un/8OAhpNtmSXDkOVvS5Pzp+y/JwNr6VGFi8HBC5F/c8SzuwV0jKN8ymsZSWbDQ68xXGNWxFaG43Bw8Pg== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/shared" "^3.22.0" + +"@react-types/checkbox@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.6.0.tgz#ba702be25555c1520f78be39c8260354638792b6" + integrity sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/combobox@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.9.0.tgz#f671da0357cfe3a06a24a239fcfacc5b3e5125d0" + integrity sha512-VAQWM2jrIWROgcTKxj4k37WWpK/1zRjj1HfGeuenAQyOQwImqDwCHx5YxQR1GiUEFne4v1yXe2khT0T5Kt2vDg== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/datepicker@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.7.0.tgz#f44632994a0cdd20f350b40910f61a7c89091810" + integrity sha512-Uh+p6pZpMFc5ZBOns5TXCBbUvJp1KVROLBn2gk5dMEFVq78Qs1VFuAt4lwr9gQBOJrX5I/l65pRTwwWwAKxYtQ== + dependencies: + "@internationalized/date" "^3.5.0" + "@react-types/calendar" "^3.4.2" + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + +"@react-types/dialog@^3.5.7": + version "3.5.7" + resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.7.tgz#3fd93875ff317d6014e814b6e1a2abb87272a1ef" + integrity sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + +"@react-types/grid@^3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.3.tgz#20b19b73315343630145ff9e43138e7f2855d946" + integrity sha512-GQM4RDmYhstcYZ0Odjq+xUwh1fhLmRebG6qMM8OXHTPQ77nhl3wc1UTGRhZm6mzEionplSRx4GCpEMEHMJIU0w== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/link@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.2.tgz#b363abca3365adc64b49c47163ce00235c01c667" + integrity sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/listbox@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.6.tgz#da0887dbb89a868d53b87486111bf0a51042da7b" + integrity sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/menu@^3.9.6": + version "3.9.6" + resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.6.tgz#1b36842cbdb4590dfff78437316aec4a3f47b1f6" + integrity sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + +"@react-types/meter@^3.3.6": + version "3.3.6" + resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.6.tgz#ae5960b27012f52ca33970f2ff416af71dad274d" + integrity sha512-1XYp1fA9UU0lO6kjf3TwVE8mppOJa64mBKAcLWtTyq1e/cYIAbx5o6CsuUx0YDpXKF6gdtvIWvfmxeWsmqJ1jQ== + dependencies: + "@react-types/progress" "^3.5.1" + +"@react-types/numberfield@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.7.0.tgz#a029bf2a8a07049c96ea5ffe1f7533ab2305bcf4" + integrity sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/overlays@^3.8.4": + version "3.8.4" + resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.4.tgz#a538f6f2fb9826f1da78d3b4f0f6326a709ce37d" + integrity sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/progress@^3.5.1": + version "3.5.1" + resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.1.tgz#b988cd2d2ff194c7652d74f714b230f26ab73c6c" + integrity sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/radio@^3.6.0": + version "3.6.0" + resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.6.0.tgz#519e4aa40dbb2a13852a5a6f36299a84639376a5" + integrity sha512-VOZzegxxZS55gHRVyWu278Q4y/rEQGiAVQCUqi25GmpbMe4MlHrzg16c76RiZMUK9PPoyv+XNUgAaPmxebkn7g== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/searchfield@^3.5.2": + version "3.5.2" + resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.2.tgz#e663899f42344243ea7b4cd6f0ab0bfe6020151e" + integrity sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA== + dependencies: + "@react-types/shared" "^3.22.0" + "@react-types/textfield" "^3.9.0" + +"@react-types/select@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.9.0.tgz#ddc1238194776ef161260547d25038409885ced8" + integrity sha512-0nalGmcoma4jreICLSJae/uKAuMiVyWgqWjGrGiUGGcdDchH4limKVEqNDaBwLvxVT6NB5LLsaipCTCAEEl4Rg== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/shared@^3.22.0": + version "3.22.0" + resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.22.0.tgz#70f85aad46cd225f7fcb29f1c2b5213163605074" + integrity sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA== + +"@react-types/slider@^3.7.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.7.0.tgz#d9e4dbe1b2109c7accfcc0e2e330ff10cd3a837c" + integrity sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/switch@^3.5.0": + version "3.5.0" + resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.5.0.tgz#8ebf07c60aef22b181eb4ab884cf3d2abddd66c6" + integrity sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/table@^3.9.1": + version "3.9.1" + resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.1.tgz#5d1304d412bc7e637e832e86fcb8724e61c20735" + integrity sha512-3e+Oouw9jGqNDg+JRg7v7fgPqDZd6DtST9S/UPp81f32ntnQ8Wsu7S/J4eyLHu5CVQDqcHkf4xPeeXBgPx4qmw== + dependencies: + "@react-types/grid" "^3.2.3" + "@react-types/shared" "^3.22.0" + +"@react-types/tabs@^3.3.4": + version "3.3.4" + resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.4.tgz#43fa93a4a67dcc53031afc56a8ad3bf5f44473a8" + integrity sha512-4mCTtFrwMRypyGTZCvNYVT9CkknexO/UYvqwDm2jMYb8JgjRvxnomu776Yh7uyiYKWyql2upm20jqasEOm620w== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/textfield@^3.9.0": + version "3.9.0" + resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.9.0.tgz#ad29f0a70421f9d2cd6cf2795df10a7712954e69" + integrity sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA== + dependencies: + "@react-types/shared" "^3.22.0" + +"@react-types/tooltip@^3.4.6": + version "3.4.6" + resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.6.tgz#1f1eb22873a5d5ad355e0de1be46f48759b55f6f" + integrity sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw== + dependencies: + "@react-types/overlays" "^3.8.4" + "@react-types/shared" "^3.22.0" + +"@remix-run/router@1.13.0": + version "1.13.0" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065" + integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -4305,9 +4507,9 @@ resolve "^1.22.1" "@rollup/pluginutils@^5.0.1": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.5.tgz#bbb4c175e19ebfeeb8c132c2eea0ecb89941a66c" - integrity sha512-6aEYR910NyP73oHiJglti74iRyOwgFU4x3meH/H8OJx6Ry0j6cOVZ5X/wTvub7G7Ao6qaHBEaNsV3GLJkSsF+Q== + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== dependencies: "@types/estree" "^1.0.0" estree-walker "^2.0.2" @@ -4318,75 +4520,75 @@ resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== -"@sentry-internal/tracing@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.77.0.tgz#f3d82486f8934a955b3dd2aa54c8d29586e42a37" - integrity sha512-8HRF1rdqWwtINqGEdx8Iqs9UOP/n8E0vXUu3Nmbqj4p5sQPA7vvCfq+4Y4rTqZFc7sNdFpDsRION5iQEh8zfZw== +"@sentry-internal/tracing@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.84.0.tgz#430da253ee5b075be4ef57f20ea842c0208bc6b0" + integrity sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ== dependencies: - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" -"@sentry/browser@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.77.0.tgz#155440f1a0d3a1bbd5d564c28d6b0c9853a51d72" - integrity sha512-nJ2KDZD90H8jcPx9BysQLiQW+w7k7kISCWeRjrEMJzjtge32dmHA8G4stlUTRIQugy5F+73cOayWShceFP7QJQ== +"@sentry/browser@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.84.0.tgz#7c82470f0afbb6178f26127894e40e9ce2b1e6d6" + integrity sha512-X50TlTKY9WzAnHsYc4FYrCWgm+CdVo0h02ggmodVBUpRLUBjj+cs5Q1plov/v/XeorSwmorNEMUu/n+XZNSsrA== dependencies: - "@sentry-internal/tracing" "7.77.0" - "@sentry/core" "7.77.0" - "@sentry/replay" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry-internal/tracing" "7.84.0" + "@sentry/core" "7.84.0" + "@sentry/replay" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" -"@sentry/core@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.77.0.tgz#21100843132beeeff42296c8370cdcc7aa1d8510" - integrity sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg== +"@sentry/core@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.84.0.tgz#01d33fc452044ffd8ea57b20f60304b9cfa2b9e1" + integrity sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA== dependencies: - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" "@sentry/integrations@^7.54.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.77.0.tgz#f2717e05cb7c69363316ccd34096b2ea07ae4c59" - integrity sha512-P055qXgBHeZNKnnVEs5eZYLdy6P49Zr77A1aWJuNih/EenzMy922GOeGy2mF6XYrn1YJSjEwsNMNsQkcvMTK8Q== + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.84.0.tgz#3b016903e08f0dade74bbc152ea5605e231e39cd" + integrity sha512-aUu95BhnHSf/W/F4BvsFnf4x+piHiah5a180YTMqWcHMkJr7MnCWNIad9RJuHlcINSfyHtUr5+Z4Bajzqg60lw== dependencies: - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" localforage "^1.8.1" "@sentry/react@^7.54.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.77.0.tgz#9da14e4b21eae4b5a6306d39bb7c42ef0827d2c2" - integrity sha512-Q+htKzib5em0MdaQZMmPomaswaU3xhcVqmLi2CxqQypSjbYgBPPd+DuhrXKoWYLDDkkbY2uyfe4Lp3yLRWeXYw== + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.84.0.tgz#2cb3192f7fb67b7696e8ece08d67229b193ddaa4" + integrity sha512-VQZrEHwPKCYTSbRYXD2ohXcQg99G1Hgs8eevRUuRpdChmA2e3z/RvT00NlaSNNZrS86wPyKpAK6kickB/eSYrw== dependencies: - "@sentry/browser" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry/browser" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" hoist-non-react-statics "^3.3.2" -"@sentry/replay@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.77.0.tgz#21d242c9cd70a7235237216174873fd140b6eb80" - integrity sha512-M9Ik2J5ekl+C1Och3wzLRZVaRGK33BlnBwfwf3qKjgLDwfKW+1YkwDfTHbc2b74RowkJbOVNcp4m8ptlehlSaQ== +"@sentry/replay@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.84.0.tgz#7e17876d9a1802ee33800e2b2cbda4e026c0a2af" + integrity sha512-c4PxT0ZpvkR9zXNfmAk3ojkm6eZ9+NlDze09RFBOCNo69QwIN90hnvbjXFC1+vRIJsfgo78Zr0ya/Wzb3Rog7Q== dependencies: - "@sentry-internal/tracing" "7.77.0" - "@sentry/core" "7.77.0" - "@sentry/types" "7.77.0" - "@sentry/utils" "7.77.0" + "@sentry-internal/tracing" "7.84.0" + "@sentry/core" "7.84.0" + "@sentry/types" "7.84.0" + "@sentry/utils" "7.84.0" -"@sentry/types@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.77.0.tgz#c5d00fe547b89ccde59cdea59143bf145cee3144" - integrity sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA== +"@sentry/types@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.84.0.tgz#e8db86c36c61659c3b2558f0aa8b6a073a756117" + integrity sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA== -"@sentry/utils@7.77.0": - version "7.77.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.77.0.tgz#1f88501f0b8777de31b371cf859d13c82ebe1379" - integrity sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g== +"@sentry/utils@7.84.0": + version "7.84.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.84.0.tgz#32861d922fa31e86dd2863a1d9dfc5a369e98952" + integrity sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ== dependencies: - "@sentry/types" "7.77.0" + "@sentry/types" "7.84.0" "@sideway/address@^4.1.3": version "4.1.4" @@ -4978,13 +5180,13 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channels@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.5.3.tgz#cbd178b0778f3484b970d0fd0edd294db6969e0f" - integrity sha512-dhWuV2o2lmxH0RKuzND8jxYzvSQTSmpE13P0IT/k8+I1up/rSNYOBQJT6SalakcNWXFAMXguo/8E7ApmnKKcEw== +"@storybook/channels@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.2.tgz#77bb8ea5bda33fc00fea30954c15f2bdc4f74a5d" + integrity sha512-pSVpnMAfMsImPyAorYPcfkZmBY34+eHmcj8Zab0m/36/M0AQrUq7VSxA+7KD3rhoZaJjioeouxqigjiznNAbZw== dependencies: - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -5024,10 +5226,10 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/client-logger@7.5.3", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.5.3.tgz#5a33a8a1785dbe6beff60654bc8947724c0cd62e" - integrity sha512-vUFYALypjix5FoJ5M/XUP6KmyTnQJNW1poHdW7WXUVSg+lBM6E5eAtjTm0hdxNNDH8KSrdy24nCLra5h0X0BWg== +"@storybook/client-logger@7.6.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.2.tgz#4362d53e24464945fc711dcf0dcfb9b4b1c53586" + integrity sha512-9hlDm7q6jZPVBoqW8V7DTMNMsjMaL2t45h+I8veQhnC2ZW6g+lARXQQDHZpL6MKVkJn6mEA9F0nJBIknbQpqBQ== dependencies: "@storybook/global" "^5.0.0" @@ -5134,10 +5336,10 @@ dependencies: core-js "^3.8.2" -"@storybook/core-events@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.5.3.tgz#210089576844569a914cc0cd1e07119bac6eb0e4" - integrity sha512-DFOpyQ22JD5C1oeOFzL8wlqSWZzrqgDfDbUGP8xdO4wJu+FVTxnnWN6ZYLdTPB1u27DOhd7TzjQMfLDHLu7kbQ== +"@storybook/core-events@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.2.tgz#13198c8020601fd74ec4eb53852f20e7f0bd68b5" + integrity sha512-JciGNDclg3hx+WkXsAzcCBYWk0xsyIbyCAwqN7XVHUpGndR/dl97Qum5MkO9kPb8r5toKpeBOQo5Kxo2GiE0dg== dependencies: ts-dedent "^2.0.0" @@ -5234,10 +5436,10 @@ dependencies: lodash "^4.17.15" -"@storybook/csf@^0.1.0": - version "0.1.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.1.tgz#abccc8c3e49aed0a6a7e87beb0d1c262b1921c06" - integrity sha512-4hE3AlNVxR60Wc5KSC68ASYzUobjPqtSKyhV6G+ge0FIXU55N5nTY7dXGRZHQGDBPq+XqchMkIdlkHPRs8nTHg== +"@storybook/csf@^0.1.2": + version "0.1.2" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.2.tgz#8e7452f0097507f5841b5ade3f5da1525bc9afb2" + integrity sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA== dependencies: type-fest "^2.19.0" @@ -5271,15 +5473,17 @@ global "^4.4.0" "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.5.3.tgz#de875ba10db3b5a06a1acbc27a8b1f8fb1d875ff" - integrity sha512-p6b+/6ohTCKxWn00bXT8KBqVjXUOxeILnJtLlG83USLQCpI+XVkpmK57HYuydqEwy/1XjG+4S4ntPk9VVz3u7w== + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.6.2.tgz#1db5415ec268e49773cd44573baea6011b0e8c23" + integrity sha512-IQQh0troFy0naXJUc47UtqJ1Bcs4SaBBxxCMlUeJLML1w0EjBSNCB6kewTU/DfjlkFm8a7YnEwxPTEh1dZiq8w== dependencies: - "@storybook/channels" "7.5.3" - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" + "@storybook/channels" "7.6.2" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.5.3" + "@storybook/preview-api" "7.6.2" + "@vitest/utils" "^0.34.6" + util "^0.12.4" "@storybook/manager-webpack4@6.5.16": version "6.5.16" @@ -5395,17 +5599,17 @@ dependencies: core-js "^3.8.2" -"@storybook/preview-api@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.5.3.tgz#eaf70f9b6888d0dac42ce39a296afd6acacf6156" - integrity sha512-LNmEf7oBRnZ1wG3bQ+P+TO29+NN5pSDJiAA6FabZBrtIVm+psc2lxBCDQvFYyAFzQSlt60toGKNW8+RfFNdR5Q== +"@storybook/preview-api@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.2.tgz#2b0158341510cfa87babaa13d8077a0741e2664d" + integrity sha512-5scmFblrBKBLQSZVlwNUCXhos8GJ8alzMSs0msAbguytjWEuNQ2EKoO7EoO3wvaYf7K3mkOg082RU9nH8SM6mg== dependencies: - "@storybook/channels" "7.5.3" - "@storybook/client-logger" "7.5.3" - "@storybook/core-events" "7.5.3" - "@storybook/csf" "^0.1.0" + "@storybook/channels" "7.6.2" + "@storybook/client-logger" "7.6.2" + "@storybook/core-events" "7.6.2" + "@storybook/csf" "^0.1.2" "@storybook/global" "^5.0.0" - "@storybook/types" "7.5.3" + "@storybook/types" "7.6.2" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -5586,12 +5790,12 @@ memoizerific "^1.11.3" regenerator-runtime "^0.13.7" -"@storybook/types@7.5.3": - version "7.5.3" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.5.3.tgz#be956805dafc09fa9a7a3dd4e0e5097ef08e4fd4" - integrity sha512-iu5W0Kdd6nysN5CPkY4GRl+0BpxRTdSfBIJak7mb6xCIHSB5t1tw4BOuqMQ5EgpikRY3MWJ4gY647QkWBX3MNQ== +"@storybook/types@7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.2.tgz#4db470df5cba3da244d979fbdaafafa45b0e0f4d" + integrity sha512-GlEkG4D/BFuPrLGpTkrfmeLM/fEki0FTnMs1SgNQL10wl6Y98EDJWvCItPVPBoGBERpShxEmkSi2HmcySWZgsA== dependencies: - "@storybook/channels" "7.5.3" + "@storybook/channels" "7.6.2" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -5919,14 +6123,14 @@ "@types/estree" "*" "@types/aria-query@^5.0.1": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.3.tgz#07570ebd25f9b516c910a91f7244052c9b58eabc" - integrity sha512-0Z6Tr7wjKJIk4OUEjVUQMtyunLDy339vcMaj38Kpj6jM2OE1p3S4kXExKZ7a3uXQAPCoy3sbrP1wibDKaf39oA== + version "5.0.4" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" + integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.3.tgz#d5625a50b6f18244425a1359a858c73d70340778" - integrity sha512-54fjTSeSHwfan8AyHWrKbfBWiEUrNTZsUwPTDSNaaP1QDQIZbeNUg3a59E9D+375MzUw/x1vx2/0F5LBz+AeYA== + version "7.20.5" + resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" + integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== dependencies: "@babel/parser" "^7.20.7" "@babel/types" "^7.20.7" @@ -5935,206 +6139,206 @@ "@types/babel__traverse" "*" "@types/babel__generator@*": - version "7.6.6" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.6.tgz#676f89f67dc8ddaae923f70ebc5f1fa800c031a8" - integrity sha512-66BXMKb/sUWbMdBNdMvajU7i/44RkrA3z/Yt1c7R5xejt8qh84iU54yUWCtm0QwGJlDcf/gg4zd/x4mpLAlb/w== + version "7.6.7" + resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" + integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== dependencies: "@babel/types" "^7.0.0" "@types/babel__template@*": - version "7.4.3" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.3.tgz#db9ac539a2fe05cfe9e168b24f360701bde41f5f" - integrity sha512-ciwyCLeuRfxboZ4isgdNZi/tkt06m8Tw6uGbBSBgWrnnZGNXiEyM27xc/PjXGQLqlZ6ylbgHMnm7ccF9tCkOeQ== + version "7.4.4" + resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" + integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== dependencies: "@babel/parser" "^7.1.0" "@babel/types" "^7.0.0" "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.20.3" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.3.tgz#a971aa47441b28ef17884ff945d0551265a2d058" - integrity sha512-Lsh766rGEFbaxMIDH7Qa+Yha8cMVI3qAK6CHt3OR0YfxOIn5Z54iHiyDRycHrBqeIiqGa20Kpsv1cavfBKkRSw== + version "7.20.4" + resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" + integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== dependencies: "@babel/types" "^7.20.7" "@types/big.js@^6.1.6": - version "6.2.1" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.1.tgz#0e5eda9b8ffe33e2cc4540fad6e91a4c7255ca88" - integrity sha512-dKzZVT10m3ELZgYIShPJ+3Os/E1s3aDQS+wr1ne7VCLU/8hc/R+z/+gkm9WabxSkV9E8wJhTl5wC+0fD9nitsw== + version "6.2.2" + resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.2.tgz#69422ec9ef59df1330ccfde2106d9e1159a083c3" + integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== "@types/body-parser@*": - version "1.19.4" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.4.tgz#78ad68f1f79eb851aa3634db0c7f57f6f601b462" - integrity sha512-N7UDG0/xiPQa2D/XrVJXjkWbpqHCd2sBaB32ggRF2l83RhPfamgKGF8gwwqyksS95qUS5ZYF9aF+lLPRlwI2UA== + version "1.19.5" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" + integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== dependencies: "@types/connect" "*" "@types/node" "*" "@types/bonjour@^3.5.9": - version "3.5.12" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.12.tgz#49badafb988e6c433ca675a5fd769b93b7649fc8" - integrity sha512-ky0kWSqXVxSqgqJvPIkgFkcn4C8MnRog308Ou8xBBIVo39OmUFy+jqNe0nPwLCDFxUpmT9EvT91YzOJgkDRcFg== + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" + integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== dependencies: "@types/node" "*" "@types/bs58@^4.0.1": - version "4.0.3" - resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.3.tgz#0ccc90341c886acb7abeb42c6f848403a6a021af" - integrity sha512-yVMwEsD7S5YU372eUWAmFRmTqF6EUSqs1Tj2X1kD0hiA4YlE33BhC3tELKLVYpZQEc5gLIQX2BAXmJdXaBARXA== + version "4.0.4" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.4.tgz#49fbcb0c7db5f7cea26f0e0f61dc4a41a2445aab" + integrity sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g== dependencies: "@types/node" "*" base-x "^3.0.6" "@types/connect-history-api-fallback@^1.3.5": - version "1.5.2" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.2.tgz#acf51e088b3bb6507f7b093bd2b0de20940179cc" - integrity sha512-gX2j9x+NzSh4zOhnRPSdPPmTepS4DfxES0AvIFv3jGv5QyeAJf6u6dY5/BAoAJU9Qq1uTvwOku8SSC2GnCRl6Q== + version "1.5.4" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" + integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== dependencies: "@types/express-serve-static-core" "*" "@types/node" "*" "@types/connect@*": - version "3.4.37" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.37.tgz#c66a96689fd3127c8772eb3e9e5c6028ec1a9af5" - integrity sha512-zBUSRqkfZ59OcwXon4HVxhx5oWCJmc0OtBTK05M+p0dYjgN6iTwIL2T/WbsQZrEsdnwaF9cWQ+azOnpPvIqY3Q== + version "3.4.38" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" + integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== dependencies: "@types/node" "*" "@types/d3-array@^3.0.3": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.0.tgz#603b85d0072962bdecaf8391f60eea465c8dc282" - integrity sha512-tjU8juPSfhMnu6mJZPOCVVGba4rZoE0tjHDPb81PYwA8CzbaFscGjgkUM7juUJu6iWA1cCVWNEVwxZ5HN9Jj8Q== + version "3.2.1" + resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" + integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== "@types/d3-color@*": - version "3.1.2" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.2.tgz#7939eed011a908287cd1bcfd11580c17b2ac7f8a" - integrity sha512-At+Ski7dL8Bs58E8g8vPcFJc8tGcaC12Z4m07+p41+DRqnZQcAlp3NfYjLrhNYv+zEyQitU1CUxXNjqUyf+c0g== + version "3.1.3" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" + integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== "@types/d3-color@^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.4.tgz#d8a270d6fd864977ea339899a0dfb35974da93a4" - integrity sha512-KsjVf5gjylqqZIsRxYPiFQIY8NvmJEmA9nMrJT0yCcpABhvYzhjoCCPCjaYMANp96GBdS4VXRfhHWnCTudDdJg== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.5.tgz#23bb1afda325549c6314ab60aa2aa28c4c6b1c37" + integrity sha512-5sNP3DmtSnSozxcjqmzQKsDOuVJXZkceo1KJScDc1982kk/TS9mTPc6lpli1gTu1MIBF1YWutpHpjucNWcIj5g== "@types/d3-dsv@*": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.5.tgz#c12df56be81d0b457d167842fa87276d0d6eb880" - integrity sha512-73WZR3QFOaSRVz9iOrebTbTnbo7xjcgS/i0Cq5zy0jMXPO3v/JbkTD3Zqii1eYE6v4EJ78g5VP407rm+p8fdlA== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" + integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== "@types/d3-ease@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.1.tgz#ef386d2f28602dba82206888047f97f7f7f7558a" - integrity sha512-VZofjpEt8HWv3nxUAosj5o/+4JflnJ7Bbv07k17VO3T2WRuzGdZeookfaF60iVh5RdhVG49LE5w6LIshVUC6rg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" + integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== "@types/d3-fetch@^3.0.1": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.5.tgz#0bec3763a04d199ad8bce2756b6f6818ee188b32" - integrity sha512-Rc8pb6H0RRLpAV2hEXduykUgcDUOhjSLTLmCIeo6ejzgs4SaITh/EteMb3p5Env3Hqjsqw0fCksyqopHHzMkMg== + version "3.0.7" + resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" + integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== dependencies: "@types/d3-dsv" "*" "@types/d3-geo@^1": - version "1.12.6" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.6.tgz#127802904cd656e9a8c45489d3110a1f87fbacb7" - integrity sha512-ZUjOG+unedpNb2IGYau7WdQcoGQjrVnVrpAdJTcIE1g7wD4kR4rHQy7JYPu+5iZ2C8DOXQnbtsyimo2fP2AykA== + version "1.12.7" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.7.tgz#595680bf9b9525031cef956ed80baf38b8f3b4be" + integrity sha512-QetZrWWjuMfCe0BHLjD+dOThlgk7YGZ2gj+yhFAbDN5TularNBEQiBs5/CIgX0+IBDjt7/fbkDd5V70J1LjjKA== dependencies: "@types/geojson" "*" "@types/d3-geo@^3.0.2": - version "3.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.0.6.tgz#138821c463c67551e1cc13729f0211986c5c3cce" - integrity sha512-wblAES3b+C3hvp4VakwECEKtHquT/xc6K4HOna95LM1j1fd7s7WmU4V+JMQZfKhNCMkV2vWD+ZUgY2Uj6gqfuA== + version "3.1.0" + resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" + integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== dependencies: "@types/geojson" "*" "@types/d3-interpolate@^1": - version "1.4.4" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.4.tgz#cae4c7e7da8649a869cb4f25e62f289b43c86167" - integrity sha512-iZOtsYamYn0qP8f4U7EtQV4JqR/2z0Mp9AxUdPnuC+D8ovmnw/ZFvpoC0mVKJ9eZzrA/fscGr3/R9892F5RRxg== + version "1.4.5" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.5.tgz#7964699575ec9c594a9a7aaea411a812ce6cd674" + integrity sha512-k9L18hXXv7OvK4PqW1kSFYIzasGOvfhPUWmHFkoZ8/ci99EAmY4HoF6zMefrHl0SGV7XYc7Qq2MNh8dK3edg5A== dependencies: "@types/d3-color" "^1" "@types/d3-interpolate@^3.0.1": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.3.tgz#e10c06c4bf11bd770ed56184a0d76cd516ff4ded" - integrity sha512-6OZ2EIB4lLj+8cUY7I/Cgn9Q+hLdA4DjJHYOQDiHL0SzqS1K9DL5xIOVBSIHgF+tiuO9MU1D36qvdIvRDRPh+Q== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" + integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== dependencies: "@types/d3-color" "*" "@types/d3-path@*": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.1.tgz#6171c9e388904014764661a37613e3c4ab8df22d" - integrity sha512-blRhp7ki7pVznM8k6lk5iUU9paDbVRVq+/xpf0RRgSJn5gr6SE7RcFtxooYGMBOc1RZiGyqRpVdu5AD0z0ooMA== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.2.tgz#4327f4a05d475cf9be46a93fc2e0f8d23380805a" + integrity sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA== "@types/d3-scale@^4.0.1", "@types/d3-scale@^4.0.2": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.6.tgz#9d221949f37b90b52696ec99f9b1e972d55fe10d" - integrity sha512-lo3oMLSiqsQUovv8j15X4BNEDOsnHuGjeVg7GRbAuB2PUa1prK5BNSOu6xixgNf3nqxPl4I1BqJWrPvFGlQoGQ== + version "4.0.8" + resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb" + integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== dependencies: "@types/d3-time" "*" "@types/d3-selection@^1": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.5.tgz#a0f436406ec3586f705fbe5d64cf1b5b28b25119" - integrity sha512-87ZWS/UZ+t1gJ0Ras1iWcyWOxOuzPhPfeEdTN19IyEHK28ssS3KI7orQZ3Eqyijhuvm7vxePh+U0cL79H9g41Q== + version "1.4.6" + resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.6.tgz#3e6056117b19d8bb6c729c872ca7234622099fb6" + integrity sha512-0MhJ/LzJe6/vQVxiYJnvNq5CD/MF6Qy0dLp4BEQ6Dz8oOaB0EMXfx1GGeBFSW+3VzgjaUrxK6uECDQj9VLa/Mg== "@types/d3-shape@^3.1.0": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.4.tgz#748a256d5e499cdfb3e48beca9c557f3ea0ff15c" - integrity sha512-M2/xsWPsjaZc5ifMKp1EBp0gqJG0eO/zlldJNOC85Y/5DGsBQ49gDkRJ2h5GY7ZVD6KUumvZWsylSbvTaJTqKg== + version "3.1.6" + resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72" + integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== dependencies: "@types/d3-path" "*" "@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.2.tgz#f4425b2ebcb04495a7b2390da03633ef1a8adbe5" - integrity sha512-kbdRXTmUgNfw5OTE3KZnFQn6XdIc4QGroN5UixgdrXATmYsdlPQS6pEut9tVlIojtzuFD4txs/L+Rq41AHtLpg== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be" + integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== "@types/d3-timer@^3.0.0": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.1.tgz#8dac23292df0e559a3aa459d8efca78a734c3fbe" - integrity sha512-GGTvzKccVEhxmRfJEB6zhY9ieT4UhGVUIQaBzFpUO9OXy2ycAlnPCSJLzmGGgqt3KVjqN3QCQB4g1rsZnHsWhg== + version "3.0.2" + resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" + integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== "@types/d3-zoom@^1": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.6.tgz#3c29d9549789419c55f98f2dccc52349838c5e15" - integrity sha512-MBQ34pRegwb+I59RexzTLTX09QqN1bJlXUd8oTbQjlUOWfuh0Fo0DV/D8Y6Lly+x3rfbVqIP61vdY/LhzQf6DA== + version "1.8.7" + resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.7.tgz#0afdcf771e6ea518f3a4b634bbb4c8e8979c65b1" + integrity sha512-HJWci3jXwFIuFKDqGn5PmuwrhZvuFdrnUmtSKCLXFAWyf2lAIUKMKh1/lHOkWBl/f4KVupGricJiqkQy+cVTog== dependencies: "@types/d3-interpolate" "^1" "@types/d3-selection" "^1" "@types/debug@^4.0.0": - version "4.1.10" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.10.tgz#f23148a6eb771a34c466a4fc28379d8101e84494" - integrity sha512-tOSCru6s732pofZ+sMv9o4o3Zc+Sa8l3bxd/tweTQudFn06vAzb13ZX46Zi6m6EJ+RUbRTHvgQJ1gBtSgkaUYA== + version "4.1.12" + resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" + integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== dependencies: "@types/ms" "*" "@types/eslint-scope@^3.7.3": - version "3.7.6" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.6.tgz#585578b368ed170e67de8aae7b93f54a1b2fdc26" - integrity sha512-zfM4ipmxVKWdxtDaJ3MP3pBurDXOCoyjvlpE3u6Qzrmw4BPbfm4/ambIeTk/r/J0iq/+2/xp0Fmt+gFvXJY2PQ== + version "3.7.7" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" + integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== dependencies: "@types/eslint" "*" "@types/estree" "*" "@types/eslint@*": - version "8.44.6" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.6.tgz#60e564551966dd255f4c01c459f0b4fb87068603" - integrity sha512-P6bY56TVmX8y9J87jHNgQh43h6VVU+6H7oN7hgvivV81K2XY8qJZ5vqPy/HdUoVIelii2kChYVzQanlswPWVFw== + version "8.44.8" + resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.8.tgz#f4fe1dab9b3d3dd98082d4b9f80e59ab40f1261c" + integrity sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw== dependencies: "@types/estree" "*" "@types/json-schema" "*" "@types/estree-jsx@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.2.tgz#758bcb4f35f2a970362b2bd2b7021fe2ae6e8509" - integrity sha512-GNBWlGBMjiiiL5TSkvPtOteuXsiVitw5MYGY1UYlrAq0SKyczsls6sCD7TZ8fsjRsvCVxml7EbyjJezPb3DrSA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.3.tgz#f8aa833ec986d82b8271a294a92ed1565bf2c66a" + integrity sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w== dependencies: "@types/estree" "*" "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.4.tgz#d9748f5742171b26218516cf1828b8eafaf8a9fa" - integrity sha512-2JwWnHK9H+wUZNorf2Zr6ves96WHoWDJIftkcxPKsS7Djta6Zu519LarhRNljPXkpsZR2ZMwNCPeW7omW07BJw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" + integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== "@types/estree@^0.0.51": version "0.0.51" @@ -6142,9 +6346,9 @@ integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.39" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.39.tgz#2107afc0a4b035e6cb00accac3bdf2d76ae408c8" - integrity sha512-BiEUfAiGCOllomsRAZOiMFP7LAnrifHpt56pc4Z7l9K6ACyN06Ns1JLMBxwkfLOjJRlSf06NwWsT7yzfpaVpyQ== + version "4.17.41" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" + integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== dependencies: "@types/node" "*" "@types/qs" "*" @@ -6152,9 +6356,9 @@ "@types/send" "*" "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": - version "4.17.20" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.20.tgz#e7c9b40276d29e38a4e3564d7a3d65911e2aa433" - integrity sha512-rOaqlkgEvOW495xErXMsmyX3WKBInbhG5eqojXYi3cGUaLoRDlXa5d52fkfWZT963AZ3v2eZ4MbKE6WpDAGVsw== + version "4.17.21" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" + integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^4.17.33" @@ -6169,14 +6373,14 @@ "@types/node" "*" "@types/flat@^5.0.2": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.4.tgz#d8262918655d942cb0b79f09020240d5ff668557" - integrity sha512-Qy8SOE+x5F40jebCj4vPoA/Y6J2Zd6h9ihMPYP8U8//dDEOK4Yu0ShOTKqEmWPR+4AdV4sls/VCaR6azEFvKKg== + version "5.0.5" + resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.5.tgz#2304df0b2b1e6dde50d81f029593e0a1bc2474d3" + integrity sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q== "@types/geojson@*", "@types/geojson@^7946.0.8": - version "7946.0.12" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.12.tgz#0307536218d32e6b970bccd1d148b9c4e5b6f10d" - integrity sha512-uK2z1ZHJyC0nQRbuovXFt4mzXDwf27vQeUWNhfKGwRcWW429GOhP8HxUHlM6TLH4bzmlv/HlEjpvJh3JfmGsAA== + version "7946.0.13" + resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.13.tgz#e6e77ea9ecf36564980a861e24e62a095988775e" + integrity sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ== "@types/glob@*": version "8.1.0" @@ -6195,16 +6399,16 @@ "@types/node" "*" "@types/graceful-fs@^4.1.2": - version "4.1.8" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.8.tgz#417e461e4dc79d957dc3107f45fe4973b09c2915" - integrity sha512-NhRH7YzWq8WiNKVavKPBmtLYZHxNY19Hh+az28O/phfp68CF45pMFud+ZzJ8ewnxnC5smIdF3dqFeiSUQ5I+pw== + version "4.1.9" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" + integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== dependencies: "@types/node" "*" "@types/hast@^2.0.0": - version "2.3.7" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.7.tgz#5e9bd7ab4452d5313aeec9d38fbc193a70f8d810" - integrity sha512-EVLigw5zInURhzfXUM65eixfadfsHKomGKUakToXo84t8gGIJuTcD2xooM2See7GyQ7DRtYjhCHnSUQez8JaLw== + version "2.3.8" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.8.tgz#4ac5caf38b262b7bd5ca3202dda71f0271635660" + integrity sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ== dependencies: "@types/unist" "^2" @@ -6219,45 +6423,45 @@ integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== "@types/http-errors@*": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.3.tgz#c54e61f79b3947d040f150abd58f71efb422ff62" - integrity sha512-pP0P/9BnCj1OVvQR2lF41EkDG/lWWnDyA203b/4Fmi2eTyORnBtcDoKDwjWQthELrBvWkMOrvSOnZ8OVlW6tXA== + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" + integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== "@types/http-proxy@^1.17.8": - version "1.17.13" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.13.tgz#dd3a4da550580eb0557d4c7128a2ff1d1a38d465" - integrity sha512-GkhdWcMNiR5QSQRYnJ+/oXzu0+7JJEPC8vkWXK351BkhjraZF+1W13CUYARUvX9+NqIU2n6YHA4iwywsc/M6Sw== + version "1.17.14" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" + integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== dependencies: "@types/node" "*" "@types/is-function@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.2.tgz#1f29acd54f5473f0b4822548e27078eac4e450d2" - integrity sha512-Je5TaQzK7H06pt4e88WsjXwRC64EkmxsdqirUI+4GPVMjhs68Dmm8hr+yqf8tmpYlfR6zPlsJC5xs14dlVUehw== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.3.tgz#548f851db5d30a12abeea2569ba75890dbf89425" + integrity sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw== "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.5.tgz#fdfdd69fa16d530047d9963635bd77c71a08c068" - integrity sha512-zONci81DZYCZjiLe0r6equvZut0b+dBRPBN5kBDjsONnutYNtJMoWQ9uR2RkL1gLG9NMTzvf+29e5RFfPbeKhQ== + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" + integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== "@types/istanbul-lib-report@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.2.tgz#394798d5f727402eb5ec99eb9618ffcd2b7645a1" - integrity sha512-8toY6FgdltSdONav1XtUHl4LN1yTmLza+EuDazb/fEmRNCwjyqNVIQWs2IfC74IqjHkREs/nQ2FWq5kZU9IC0w== + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" + integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== dependencies: "@types/istanbul-lib-coverage" "*" "@types/istanbul-reports@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.3.tgz#0313e2608e6d6955d195f55361ddeebd4b74c6e7" - integrity sha512-1nESsePMBlf0RPRffLZi5ujYh7IH1BWL4y9pr+Bn3cJBdxz+RTP8bUFljLz9HvzhhOSWKdyBZ4DIivdL6rvgZg== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" + integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== dependencies: "@types/istanbul-lib-report" "*" "@types/jest@*": - version "29.5.7" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.7.tgz#2c0dafe2715dd958a455bc10e2ec3e1ec47b5036" - integrity sha512-HLyetab6KVPSiF+7pFcUyMeLsx25LDNDemw9mGsJBkai/oouwrjTycocSDYopMEwFhN2Y4s9oPyOCZNofgSt2g== + version "29.5.10" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.10.tgz#a10fc5bab9e426081c12b2ef73d24d4f0c9b7f50" + integrity sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ== dependencies: expect "^29.0.0" pretty-format "^29.0.0" @@ -6271,9 +6475,9 @@ pretty-format "^27.0.0" "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.14" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.14.tgz#74a97a5573980802f32c8e47b663530ab3b6b7d1" - integrity sha512-U3PUjAudAdJBeC2pgN8uTIKgxrb4nlDF3SF0++EldXQvQBGkpFZMSnwQiIoDU77tv45VgNkl/L4ouD+rEomujw== + version "7.0.15" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" + integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/json5@^0.0.29": version "0.0.29" @@ -6281,9 +6485,9 @@ integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== "@types/lodash@^4.14.167", "@types/lodash@^4.14.175": - version "4.14.200" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.200.tgz#435b6035c7eba9cdf1e039af8212c9e9281e7149" - integrity sha512-YI/M/4HRImtNf3pJgbF+W6FrXovqj+T+/HpENLTooK9PnkacBsDpeP3IpHab40CClUfhNmdM2WTNP2sa2dni5Q== + version "4.14.202" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" + integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== "@types/long@^4.0.1": version "4.0.2" @@ -6296,26 +6500,26 @@ integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== "@types/mdast@^3.0.0": - version "3.0.14" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.14.tgz#0735473a5b35be032b9f2685b7413cbab1b8a639" - integrity sha512-gVZ04PGgw1qLZKsnWnyFv4ORnaJ+DXLdHTVSFbU8yX6xZ34Bjg4Q32yPkmveUP1yItXReKfB0Aknlh/3zxTKAw== + version "3.0.15" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" + integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== dependencies: "@types/unist" "^2" "@types/mdx@^2.0.0": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.9.tgz#80971e367bb884350ab5b2ce8fc06b34960170e7" - integrity sha512-OKMdj17y8Cs+k1r0XFyp59ChSOwf8ODGtMQ4mnpfz5eFDk1aO41yN3pSKGuvVzmWAkFp37seubY1tzOVpwfWwg== + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.10.tgz#0d7b57fb1d83e27656156e4ee0dfba96532930e4" + integrity sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg== "@types/mime@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.3.tgz#886674659ce55fe7c6c06ec5ca7c0eb276a08f91" - integrity sha512-i8MBln35l856k5iOhKk2XJ4SeAWg75mLIpZB4v6imOagKL6twsukBZGDMNhdOVk7yRFTMPpfILocMos59Q1otQ== + version "3.0.4" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" + integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== "@types/mime@^1": - version "1.3.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.4.tgz#a4ed836e069491414bab92c31fdea9e557aca0d9" - integrity sha512-1Gjee59G25MrQGk8bsNvC6fxNiRgUlGn2wlhGf95a59DrprnnHk80FIMMFG9XHMdrfsuA119ht06QPDXA1Z7tw== + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" + integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== "@types/minimatch@*", "@types/minimatch@^5.1.2": version "5.1.2" @@ -6328,34 +6532,34 @@ integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== "@types/minimist@^1.2.0": - version "1.2.4" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.4.tgz#81f886786411c45bba3f33e781ab48bd56bfca2e" - integrity sha512-Kfe/D3hxHTusnPNRbycJE1N77WHDsdS4AjUYIzlDzhDrS47NrwuL3YW4VITxwR7KCVpzwgy4Rbj829KSSQmwXQ== + version "1.2.5" + resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" + integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/ms@*": - version "0.7.33" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.33.tgz#80bf1da64b15f21fd8c1dc387c31929317d99ee9" - integrity sha512-AuHIyzR5Hea7ij0P9q7vx7xu4z0C28ucwjAZC0ja7JhINyCnOw8/DnvAPQQ9TfOlCtZAmCERKQX9+o1mgQhuOQ== + version "0.7.34" + resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" + integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== "@types/node-fetch@^2.5.7": - version "2.6.8" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.8.tgz#9a2993583975849c2e1f360b6ca2f11755b2c504" - integrity sha512-nnH5lV9QCMPsbEVdTb5Y+F3GQxLSw1xQgIydrb2gSfEavRPs50FnMr+KUaa+LoPSqibm2N+ZZxH7lavZlAT4GA== + version "2.6.9" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" + integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== dependencies: "@types/node" "*" form-data "^4.0.0" "@types/node-forge@^1.3.0": - version "1.3.8" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.8.tgz#044ad98354ff309a031a55a40ad122f3be1ac2bb" - integrity sha512-vGXshY9vim9CJjrpcS5raqSjEfKlJcWy2HNdgUasR66fAnVEYarrf1ULV4nfvpC1nZq/moA9qyqBcu83x+Jlrg== + version "1.3.10" + resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" + integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== dependencies: "@types/node" "*" "@types/node@*", "@types/node@>=13.7.0": - version "20.8.10" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.8.10.tgz#a5448b895c753ae929c26ce85cab557c6d4a365e" - integrity sha512-TlgT8JntpcbmKUFzjhsyhGfP2fsiz1Mv56im6enJ905xG1DAYesxJaeSbGqQmAw8OWPdhyJGhGSQGKRNJ45u9w== + version "20.10.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.1.tgz#d2c96f356c3125fedc983d74c424910c3767141c" + integrity sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg== dependencies: undici-types "~5.26.4" @@ -6370,26 +6574,26 @@ integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.60" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.60.tgz#0b0f4316906f1bd0e03b640363f67bd4e86958bd" - integrity sha512-ZUGPWx5vKfN+G2/yN7pcSNLkIkXEvlwNaJEd4e0ppX7W2S8XAkdc/37hM4OUNJB9sa0p12AOvGvxL4JCPiz9DA== + version "16.18.66" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.66.tgz#f59cc2ff96cc47f972a11a458a9b29bf0a209c34" + integrity sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw== "@types/normalize-package-data@^2.4.0": - version "2.4.3" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.3.tgz#291c243e4b94dbfbc0c0ee26b7666f1d5c030e2c" - integrity sha512-ehPtgRgaULsFG8x0NeYJvmyH1hmlfsNLujHe9dQEia/7MAJYdzMSi19JtchUHjmBA6XC/75dK55mzZH+RyieSg== + version "2.4.4" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" + integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== "@types/npmlog@^4.1.2": - version "4.1.5" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.5.tgz#41f1b95437f9c86cbb326bb07f0d5683f905bf4f" - integrity sha512-Fl3TEbwPoR7V1z6CMJ18whXOUkOYqF5eCkGKTir2VuevdLYUmcwj9mQdvXzuY0oagZBbsy0J7df41jn+ZcwGRA== + version "4.1.6" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.6.tgz#792341665000209ee76997df8a16300fda6d77cb" + integrity sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ== dependencies: "@types/node" "*" "@types/parse-json@^4.0.0": - version "4.0.1" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.1.tgz#27f7559836ad796cea31acb63163b203756a5b4e" - integrity sha512-3YmXzzPAdOTVljVMkTMBdBEvlOLg2cDQaDhnnhT3nT9uDbnJzjWhKlzb+desT12Y7tGqaN6d+AbozcKzyL36Ng== + version "4.0.2" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" + integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== "@types/parse5@^5.0.0": version "5.0.3" @@ -6402,43 +6606,43 @@ integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== "@types/pretty-hrtime@^1.0.0": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.2.tgz#9b6e102bc2e1eea1c1c7fadf144483ce2687f233" - integrity sha512-vyv9knII8XeW8TnXDcGH7HqG6FeR56ESN6ExM34d/U8Zvs3xuG34euV6CVyB7KEYI7Ts4lQM8b4NL72e7UadnA== + version "1.0.3" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" + integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== -"@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.9": - version "15.7.9" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.9.tgz#b6f785caa7ea1fe4414d9df42ee0ab67f23d8a6d" - integrity sha512-n1yyPsugYNSmHgxDFjicaI2+gCNjsBck8UX9kuofAKlc0h1bL+20oSF72KeNaW2DUlesbEVCFgyV2dPGTiY42g== +"@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.11": + version "15.7.11" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" + integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== "@types/qrcode.react@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.4.tgz#4e6739769a21ee6072bceaab3ec0c866c6a79a17" - integrity sha512-O35T9AJk0wg7ffkgpSQ4Zr7I7eEfEsTCD5u7V2dsvYnZLfUpQz2rLg5ZG2FM/zLmOF4sEE0FY6mxT9WleUDb3Q== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.5.tgz#d4ddcacee8f34d22a663029a230c5f0ab908cfb7" + integrity sha512-BghPtnlwvrvq8QkGa1H25YnN+5OIgCKFuQruncGWLGJYOzeSKiix/4+B9BtfKF2wf5ja8yfyWYA3OXju995G8w== dependencies: "@types/react" "*" "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.9" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.9.tgz#66f7b26288f6799d279edf13da7ccd40d2fa9197" - integrity sha512-wYLxw35euwqGvTDx6zfY1vokBFnsK0HNrzc6xNHchxfO2hpuRg74GbkEW7e3sSmPvj0TjCDT1VCa6OtHXnubsg== + version "6.9.10" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" + integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== "@types/range-parser@*": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.6.tgz#7cb33992049fd7340d5b10c0098e104184dfcd2a" - integrity sha512-+0autS93xyXizIYiyL02FCY8N+KkKPhILhcUSA276HxzreZ16kl+cmwvV2qAM/PuCCwPXzOXOWhiPcw20uSFcA== + version "1.2.7" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" + integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== "@types/react-dom@<18.0.0": - version "17.0.22" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.22.tgz#34317e08be27b33fa9e7cdb56125b22538261bad" - integrity sha512-wHt4gkdSMb4jPp1vc30MLJxoWGsZs88URfmt3FRXoOEYrrqK3I8IuZLE/uFBb4UT6MRfI0wXFu4DS7LS0kUC7Q== + version "17.0.25" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" + integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA== dependencies: "@types/react" "^17" "@types/react-dom@^18.0.10": - version "18.2.14" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.14.tgz#c01ba40e5bb57fc1dc41569bb3ccdb19eab1c539" - integrity sha512-V835xgdSVmyQmI1KLV2BEIUgqEuinxp9O4G6g3FqO/SqLac049E53aysv0oEFD2kHfejeKU+ZqL2bcFWj9gLAQ== + version "18.2.17" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" + integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== dependencies: "@types/react" "*" @@ -6459,26 +6663,26 @@ dependencies: react-tooltip "*" -"@types/react-transition-group@^4.4.8": - version "4.4.8" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.8.tgz#46f87d80512959cac793ecc610a93d80ef241ccf" - integrity sha512-QmQ22q+Pb+HQSn04NL3HtrqHwYMf4h3QKArOy5F8U5nEVMaihBs3SR10WiOM1iwPz5jIo8x/u11al+iEGZZrvg== +"@types/react-transition-group@^4.4.9": + version "4.4.9" + resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.9.tgz#12a1a1b5b8791067198149867b0823fbace31579" + integrity sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg== dependencies: "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.36" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.36.tgz#bc68ffb4408e5d0c419b0760b2eaeec70aeeedb3" - integrity sha512-o9XFsHYLLZ4+sb9CWUYwHqFVoG61SesydF353vFMMsQziiyRu8np4n2OYMUSDZ8XuImxDr9c5tR7gidlH29Vnw== + version "18.2.39" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.39.tgz#744bee99e053ad61fe74eb8b897f3ab5b19a7e25" + integrity sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" csstype "^3.0.2" "@types/react@^17": - version "17.0.69" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.69.tgz#245a0cf2f5b0fb1d645691d3083e3c7d4409b98f" - integrity sha512-klEeru//GhiQvXUBayz0Q4l3rKHWsBR/EUOhOeow6hK2jV7MlO44+8yEk6+OtPeOlRfnpUnrLXzGK+iGph5aeg== + version "17.0.71" + resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.71.tgz#3673d446ad482b1564e44bf853b3ab5bcbc942c4" + integrity sha512-lfqOu9mp16nmaGRrS8deS2Taqhd5Ih0o92Te5Ws6I1py4ytHBcXLqh0YIqVsViqwVI5f+haiFM6hju814BzcmA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -6495,60 +6699,60 @@ integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== "@types/scheduler@*": - version "0.16.5" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.5.tgz#4751153abbf8d6199babb345a52e1eb4167d64af" - integrity sha512-s/FPdYRmZR8SjLWGMCuax7r3qCWQw9QKHzXVukAuuIJkXkDRwp+Pu5LMIVFi0Fxbav35WURicYr8u1QsoybnQw== + version "0.16.8" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" + integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== "@types/semver@^7.3.12", "@types/semver@^7.3.8": - version "7.5.4" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.4.tgz#0a41252ad431c473158b22f9bfb9a63df7541cff" - integrity sha512-MMzuxN3GdFwskAnb6fz0orFvhfqi752yjaXylr0Rp4oDg5H0Zn1IuyRhDVvYOwAXoJirx2xuS16I3WjxnAIHiQ== + version "7.5.6" + resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" + integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== "@types/send@*": - version "0.17.3" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.3.tgz#81b2ea5a3a18aad357405af2d643ccbe5a09020b" - integrity sha512-/7fKxvKUoETxjFUsuFlPB9YndePpxxRAOfGC/yJdc9kTjTeP5kRCTzfnE8kPUKCeyiyIZu0YQ76s50hCedI1ug== + version "0.17.4" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" + integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== dependencies: "@types/mime" "^1" "@types/node" "*" "@types/serve-index@^1.9.1": - version "1.9.3" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.3.tgz#af9403916eb6fbf7d6ec6f47b2a4c46eb3222cc9" - integrity sha512-4KG+yMEuvDPRrYq5fyVm/I2uqAJSAwZK9VSa+Zf+zUq9/oxSSvy3kkIqyL+jjStv6UCVi8/Aho0NHtB1Fwosrg== + version "1.9.4" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" + integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== dependencies: "@types/express" "*" "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.4" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.4.tgz#44b5895a68ca637f06c229119e1c774ca88f81b2" - integrity sha512-aqqNfs1XTF0HDrFdlY//+SGUxmdSUbjeRXb5iaZc3x0/vMbYmdw9qvOgHWOyyLFxSSRnUuP5+724zBgfw8/WAw== + version "1.15.5" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" + integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== dependencies: "@types/http-errors" "*" "@types/mime" "*" "@types/node" "*" "@types/sockjs@^0.3.33": - version "0.3.35" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.35.tgz#f4a568c73d2a8071944bd6ffdca0d4e66810cd21" - integrity sha512-tIF57KB+ZvOBpAQwSaACfEu7htponHXaFzP7RfKYgsOS0NoYnn+9+jzp7bbq4fWerizI3dTB4NfAZoyeQKWJLw== + version "0.3.36" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" + integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== dependencies: "@types/node" "*" "@types/source-list-map@*": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.4.tgz#a3d4e4791606f40a833ab1caf41f77463c8d72ff" - integrity sha512-Kdfm7Sk5VX8dFW7Vbp18+fmAatBewzBILa1raHYxrGEFXT0jNl9x3LWfuW7bTbjEKFNey9Dfkj/UzT6z/NvRlg== + version "0.1.6" + resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454" + integrity sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g== "@types/stack-utils@^2.0.0": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.2.tgz#01284dde9ef4e6d8cef6422798d9a3ad18a66f8b" - integrity sha512-g7CK9nHdwjK2n0ymT2CW698FuWJRIx+RP6embAzZ2Qi8/ilIrA1Imt2LVSeHUzKvpoi7BhmmQcXz95eS0f2JXw== + version "2.0.3" + resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" + integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== "@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.10" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.10.tgz#5203aad08455c6988f7b2347715023e3935b1056" - integrity sha512-q8F20SdXG5fdVJQ5yxsVlH+f+oekP42QeHv4s5KlrxTMT0eopXn7ol1rhxMcksf8ph7XNv811iVDE2hOpUvEPg== + version "1.0.12" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.12.tgz#bc2cab12e87978eee89fb21576b670350d6d86ab" + integrity sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q== "@types/testing-library__jest-dom@^5.9.1": version "5.14.9" @@ -6558,31 +6762,31 @@ "@types/jest" "*" "@types/topojson-client@^3.1.0": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.3.tgz#d710e90f0a4a25bbdbf4fc0c1863f9a6b5023e26" - integrity sha512-liC+dHCxoqQy5bbJMsF59Cx1WZZwbcT084v/5bdp3NWSFUuzQpsm4gbLQh+wlv58Mng4jCsO4p8hWelqGlb7rg== + version "3.1.4" + resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.4.tgz#81b83f9ecd6542dc5c3df21967f992e3fe192c33" + integrity sha512-Ntf3ZSetMYy7z3PrVCvcqmdRoVhgKA9UKN0ZuuZf8Ts2kcyL4qK34IXBs6qO5fem62EK4k03PtkJPVoroVu4/w== dependencies: "@types/geojson" "*" "@types/topojson-specification" "*" "@types/topojson-specification@*": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.4.tgz#df2d2738a11bacda3b88f5b4630e3da80a12a609" - integrity sha512-LG/a8kJi4X6MsFhZKiBAIC/a+yCFtjkHsDMwuQqSoB1az8D2bR2xRKU3aczizfcqdt2lVqnS+aJBFMrO+rO5Aw== + version "1.0.5" + resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.5.tgz#bf0009b2e0debb2d97237b124c00b9ea92570375" + integrity sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ== dependencies: "@types/geojson" "*" "@types/uglify-js@*": - version "3.17.3" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.3.tgz#784efb40320d248588e1748dd12e1f43733f1416" - integrity sha512-ToldSfJ6wxO21cakcz63oFD1GjqQbKzhZCD57eH7zWuYT5UEZvfUoqvrjX5d+jB9g4a/sFO0n6QSVzzn5sMsjg== + version "3.17.4" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.4.tgz#3c70021f08023e5a760ce133d22966f200e1d31c" + integrity sha512-Hm/T0kV3ywpJyMGNbsItdivRhYNCQQf1IIsYsXnoVPES4t+FMLyDe0/K+Ea7ahWtMtSNb22ZdY7MIyoD9rqARg== dependencies: source-map "^0.6.1" "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.9" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.9.tgz#72e164381659a49557b0a078b28308f2c6a3e1ce" - integrity sha512-zC0iXxAv1C1ERURduJueYzkzZ2zaGyc+P2c95hgkikHPr3z8EdUZOlgEQ5X0DRmwDZn+hekycQnoeiiRVrmilQ== + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" + integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== "@types/uuid@^8.3.4": version "8.3.4" @@ -6590,23 +6794,23 @@ integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== "@types/webpack-env@^1.16.0": - version "1.18.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.3.tgz#e81f769199a5609c751f34fcc6f6095ceac7831f" - integrity sha512-v4CH6FLBCftYGFAswDhzFLjKgucXsOkIf5Mzl8ZZhEtC6oye9whFInNPKszNB9AvX7JEZMtpXxWctih6addP+Q== + version "1.18.4" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032" + integrity sha512-I6e+9+HtWADAWeeJWDFQtdk4EVSAbj6Rtz4q8fJ7mSr1M0jzlFcs8/HZ+Xb5SHzVm1dxH7aUiI+A8kA8Gcrm0A== "@types/webpack-sources@*": - version "3.2.2" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.2.tgz#6e6027cad8b54d2a4e5735df49af559bb4de2db0" - integrity sha512-acCzhuVe+UJy8abiSFQWXELhhNMZjQjQKpLNEi1pKGgKXZj0ul614ATcx4kkhunPost6Xw+aCq8y8cn1/WwAiA== + version "3.2.3" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.3.tgz#b667bd13e9fa15a9c26603dce502c7985418c3d8" + integrity sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw== dependencies: "@types/node" "*" "@types/source-list-map" "*" source-map "^0.7.3" "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.35" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.35.tgz#32903809685caf87ea612e4e74577874359c3749" - integrity sha512-XRC6HLGHtNfN8/xWeu1YUQV1GSE+28q8lSqvcJ+0xt/zW9Wmn4j9pCSvaXPyRlCKrl5OuqECQNEJUy2vo8oWqg== + version "4.41.38" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.38.tgz#5a40ac81bdd052bf405e8bdcf3e1236f6db6dc26" + integrity sha512-oOW7E931XJU1mVfCnxCVgv8GLFL768pDO5u2Gzk82i8yTIgX6i7cntyZOkZYb/JtYM8252SN9bQp9tgkVDSsRw== dependencies: "@types/node" "*" "@types/tapable" "^1" @@ -6616,42 +6820,42 @@ source-map "^0.6.0" "@types/ws@^8.5.5": - version "8.5.8" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.8.tgz#13efec7bd439d0bdf2af93030804a94f163b1430" - integrity sha512-flUksGIQCnJd6sZ1l5dqCEG/ksaoAg/eUwiLAGTJQcfgvZJKF++Ta4bJA6A5aPSJmsr+xlseHn4KLgVlNnvPTg== + version "8.5.10" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" + integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== dependencies: "@types/node" "*" "@types/yargs-parser@*": - version "21.0.2" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.2.tgz#7bd04c5da378496ef1695a1008bf8f71847a8b8b" - integrity sha512-5qcvofLPbfjmBfKaLfj/+f+Sbd6pN4zl7w7VSVI5uz7m9QZTuB2aZAa2uo1wHFBNN2x6g/SoTkXmd8mQnQF2Cw== + version "21.0.3" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" + integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== "@types/yargs@^15.0.0": - version "15.0.17" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.17.tgz#bea870ba551b43831bfaa75de2e4a3849c39322b" - integrity sha512-cj53I8GUcWJIgWVTSVe2L7NJAB5XWGdsoMosVvUgv1jEnMbAcsbaCzt1coUcyi8Sda5PgTWAooG8jNyDTD+CWA== + version "15.0.19" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" + integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^16.0.0": - version "16.0.7" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.7.tgz#b0d0502cb5f6c17994df72a600049f10bbf17203" - integrity sha512-lQcYmxWuOfJq4IncK88/nwud9rwr1F04CFc5xzk0k4oKVyz/AI35TfsXmhjf6t8zp8mpCOi17BfvuNWx+zrYkg== + version "16.0.9" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" + integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== dependencies: "@types/yargs-parser" "*" "@types/yargs@^17.0.8": - version "17.0.29" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.29.tgz#06aabc72497b798c643c812a8b561537fea760cf" - integrity sha512-nacjqA3ee9zRF/++a3FUY1suHTFKZeHba2n8WeDw9cCVdmzmHpIxyzOJBcpHvvEmS8E9KqWlSnWHUkOrkhWcvA== + version "17.0.32" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" + integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== dependencies: "@types/yargs-parser" "*" "@types/zxcvbn@^4.4.1": - version "4.4.3" - resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.3.tgz#c323d8bf07673a782ef07950d4b6a878e56181fe" - integrity sha512-AxZBi8J3V3lm+f2Vgg06D8y0womXpLf3ZEDYeLPGGK0ydR724sQH83T5tYgN+CN6VTRnAlevFKJkWTecCnk8ug== + version "4.4.4" + resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.4.tgz#987f5fcd87e957097433c476c3a1c91a54f53131" + integrity sha512-Tuk4q7q0DnpzyJDI4aMeghGuFu2iS1QAdKpabn8JfbtfGmVDUgvZv1I7mEjP61Bvnp3ljKCC8BE6YYSTNxmvRQ== "@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.7.0": version "5.62.0" @@ -6749,19 +6953,13 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@vanilla-extract/css-utils@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css-utils/-/css-utils-0.1.3.tgz#cadeb6bc563547b20e9b903647d8b334d3a79ef8" - integrity sha512-PZAcHROlgtCUGI2y0JntdNwvPwCNyeVnkQu6KTYKdmxBbK3w72XJUmLFYapfaFfgami4I9CTLnrJTPdtmS3gpw== - -"@vanilla-extract/css@^1.12.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.13.0.tgz#85f521d428f55b0e9599675033caba81194cc6c0" - integrity sha512-JFFBXhnJrPlGqHBabagXqo5ghXw9mtV270ycIGyLDZG8NAK5eRwAYkMowAxuzK7wZSm67GnETWYB7b0AUmyttg== +"@vanilla-extract/css@^1.14.0": + version "1.14.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.14.0.tgz#45fab9c04d893e3e363cf2cde7559d21233b7f63" + integrity sha512-rYfm7JciWZ8PFzBM/HDiE2GLnKI3xJ6/vdmVJ5BSgcCZ5CxRlM9Cjqclni9lGzF3eMOijnUhCd/KV8TOzyzbMA== dependencies: "@emotion/hash" "^0.9.0" "@vanilla-extract/private" "^1.0.3" - ahocorasick "1.0.2" chalk "^4.1.1" css-what "^6.1.0" cssesc "^3.0.0" @@ -6769,12 +6967,13 @@ deep-object-diff "^1.1.9" deepmerge "^4.2.2" media-query-parser "^2.0.2" + modern-ahocorasick "^1.0.0" outdent "^0.8.0" -"@vanilla-extract/dynamic@^2.0.3": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.0.3.tgz#44b4e018cbdfb6af3d27e73c78b38617dfe419ad" - integrity sha512-Rglfw2gXAYiBzAQ4jgUG7rBgE2c88e/zcG27ZVoIqMHVq56wf2C1katGMm1yFMNBgzqM7oBNYzz4YOMzznydkg== +"@vanilla-extract/dynamic@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.1.0.tgz#316d3bd4adfd5f5c9fb080445c41d55abe3b463c" + integrity sha512-8zl0IgBYRtgD1h+56Zu13wHTiMTJSVEa4F7RWX9vTB/5Xe2KtjoiqApy/szHPVFA56c+ex6A4GpCQjT1bKXbYw== dependencies: "@vanilla-extract/private" "^1.0.3" @@ -6783,29 +6982,38 @@ resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== -"@vanilla-extract/recipes@^0.4.0": - version "0.4.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.4.0.tgz#7bb2edb0757b6f40c244d72569da7f74d6afa427" - integrity sha512-gFgB7BofUYbtbxINHK6DhMv1JDFDXp/YI/Xm+cqKar+1I/2dfxPepeDxSexL6YB4ftfeaDw8Kn5zydMvHcGOEQ== +"@vanilla-extract/recipes@^0.5.1": + version "0.5.1" + resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.5.1.tgz#617d1a0375af60835341770397810317d2f61998" + integrity sha512-7dCuBgPQQ/89siQ0w2lkfjgkmToPUUDzFlHf5DRmt9ykiiycfA52tmPJ2RI/mr7jXi7U/vEN2aGP9QJSXEpGlA== -"@walletconnect/core@2.10.4": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.4.tgz#da9396b56f63806c165389cbf98d2373d36854df" - integrity sha512-MGdw5a4dIlQFPxVHEw2neIpHPAw3gtrsJYyUqm6rI+1c1SfmZyOPCaYTr6zPU2cnoWQUjv2ePMLeO/JKy3Yh5g== +"@vitest/utils@^0.34.6": + version "0.34.6" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968" + integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A== + dependencies: + diff-sequences "^29.4.3" + loupe "^2.3.6" + pretty-format "^29.5.0" + +"@walletconnect/core@2.10.6": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.6.tgz#786b0d2e2045c210c917e29bfa0498bbc210be20" + integrity sha512-Z4vh4ZdfcoQjgPEOxeuF9HUZCVLtV3MgRbS/awLIj/omDrFnOwlBhxi5Syr4Y8muVGC0ocRetQYHae0/gX5crQ== dependencies: "@walletconnect/heartbeat" "1.2.1" "@walletconnect/jsonrpc-provider" "1.0.13" "@walletconnect/jsonrpc-types" "1.0.3" "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/jsonrpc-ws-connection" "1.0.13" - "@walletconnect/keyvaluestorage" "^1.0.2" + "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/keyvaluestorage" "^1.1.1" "@walletconnect/logger" "^2.0.1" "@walletconnect/relay-api" "^1.0.9" "@walletconnect/relay-auth" "^1.0.4" "@walletconnect/safe-json" "^1.0.2" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" - "@walletconnect/utils" "2.10.4" + "@walletconnect/types" "2.10.6" + "@walletconnect/utils" "2.10.6" events "^3.3.0" lodash.isequal "4.5.0" uint8arrays "^3.1.0" @@ -6860,24 +7068,24 @@ "@walletconnect/jsonrpc-types" "^1.0.3" tslib "1.14.1" -"@walletconnect/jsonrpc-ws-connection@1.0.13": - version "1.0.13" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.13.tgz#23b0cdd899801bfbb44a6556936ec2b93ef2adf4" - integrity sha512-mfOM7uFH4lGtQxG+XklYuFBj6dwVvseTt5/ahOkkmpcAEgz2umuzu7fTR+h5EmjQBdrmYyEBOWADbeaFNxdySg== +"@walletconnect/jsonrpc-ws-connection@1.0.14": + version "1.0.14" + resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" + integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== dependencies: "@walletconnect/jsonrpc-utils" "^1.0.6" "@walletconnect/safe-json" "^1.0.2" events "^3.3.0" - tslib "1.14.1" ws "^7.5.1" -"@walletconnect/keyvaluestorage@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.0.2.tgz#92f5ca0f54c1a88a093778842ce0c874d86369c8" - integrity sha512-U/nNG+VLWoPFdwwKx0oliT4ziKQCEoQ27L5Hhw8YOFGA2Po9A9pULUYNWhDgHkrb0gYDNt//X7wABcEWWBd3FQ== +"@walletconnect/keyvaluestorage@^1.0.2", "@walletconnect/keyvaluestorage@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" + integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== dependencies: - safe-json-utils "^1.1.1" - tslib "1.14.1" + "@walletconnect/safe-json" "^1.0.1" + idb-keyval "^6.2.1" + unstorage "^1.9.0" "@walletconnect/logger@^2.0.1": version "2.0.1" @@ -6915,18 +7123,18 @@ tslib "1.14.1" "@walletconnect/sign-client@^2.9.0": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.4.tgz#4e3b14ebe900472874f4cae5f53c74a6077c85da" - integrity sha512-C5VHkK59/DQNrJS91UXLn5OSr0drXHkKjajhl2a9hb3h6kxuSdlWbyC0yRPKT1sD0fQho8+EWZHBiV063yBePw== + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.6.tgz#722d2c2844565e2826dce6a6d3a36c9b3ca1ea91" + integrity sha512-EvUWjaZBQu2yKnH5/5F2qzbuiIuUN9ZgrNKgvXkw5z1Dq5RJCks0S9/MFlKH/ZSGqXnLl7uAzBXtoX4sMgbCMA== dependencies: - "@walletconnect/core" "2.10.4" + "@walletconnect/core" "2.10.6" "@walletconnect/events" "^1.0.1" "@walletconnect/heartbeat" "1.2.1" "@walletconnect/jsonrpc-utils" "1.0.8" "@walletconnect/logger" "^2.0.1" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" - "@walletconnect/utils" "2.10.4" + "@walletconnect/types" "2.10.6" + "@walletconnect/utils" "2.10.6" events "^3.3.0" "@walletconnect/time@^1.0.2": @@ -6948,10 +7156,22 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" -"@walletconnect/utils@2.10.4", "@walletconnect/utils@^2.9.0": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.4.tgz#5f17938e7ea481541ec2dbae0df5cd494c72523f" - integrity sha512-XbrKgnQ0hC9DC9wjFb468MEYMoJxnCVmOj2gi01DA4FSr8fJi7wwNRUnlnZzLWrUWrHuaPReYe4PgBAgIv363g== +"@walletconnect/types@2.10.6": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.6.tgz#d9920ed4fd0113e0addbda8e7e73a5176a3163fd" + integrity sha512-WgHfiTG1yakmxheaBRiXhUdEmgxwrvsAdOIWaMf/spvrzVKYh6sHI3oyEEky5qj5jjiMiyQBeB57QamzCotbcQ== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + +"@walletconnect/utils@2.10.6", "@walletconnect/utils@^2.9.0": + version "2.10.6" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.6.tgz#749b37d14e291e346862e7027ec7548463350226" + integrity sha512-oRsWWhN2+hi3aiDXrQEOfysz6FHQJGXLsNQPVt+WIBJplO6Szmdau9dbleD88u1iiT4GKPqE0R9FOYvvPm1H/w== dependencies: "@stablelib/chacha20poly1305" "1.0.1" "@stablelib/hkdf" "1.0.1" @@ -6961,7 +7181,7 @@ "@walletconnect/relay-api" "^1.0.9" "@walletconnect/safe-json" "^1.0.2" "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.4" + "@walletconnect/types" "2.10.6" "@walletconnect/window-getters" "^1.0.1" "@walletconnect/window-metadata" "^1.0.1" detect-browser "5.3.0" @@ -7360,7 +7580,7 @@ acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -acorn@^8.0.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.0.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: version "8.11.2" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== @@ -7397,11 +7617,6 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" -ahocorasick@1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/ahocorasick/-/ahocorasick-1.0.2.tgz#9eee93aef9d02bfb476d9b648d9b7a40ef2fd500" - integrity sha512-hCOfMzbFx5IDutmWLAt6MZwOUjIfSM9G9FyVxytmE4Rs/5YDPWQrD/+IR1w+FweD9H2oOZEnv36TmkjhNURBVA== - airbnb-js-shims@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" @@ -7470,9 +7685,9 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: uri-js "^4.2.2" animejs@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.1.tgz#de9fe2e792f44a777a7fdf6ae160e26604b0cdda" - integrity sha512-sWno3ugFryK5nhiDm/2BKeFCpZv7vzerWUcUPyAZLDhMek3+S/p418ldZJbJXo5ZUOpfm2kP2XRO4NJcULMy9A== + version "3.2.2" + resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.2.tgz#59be98c58834339d5847f4a70ddba74ac75b6afc" + integrity sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ== ansi-align@^3.0.0: version "3.0.1" @@ -7562,7 +7777,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@^3.1.3, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== @@ -7585,6 +7800,11 @@ aproba@^1.1.1: resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== +arch@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" + integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== + are-we-there-yet@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" @@ -7917,10 +8137,10 @@ axios@^0.21.1, axios@^0.21.2: dependencies: follow-redirects "^1.14.0" -axios@^1.0.0, axios@^1.3.3: - version "1.6.0" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.0.tgz#f1e5292f26b2fd5c2e66876adc5b06cdbd7d2102" - integrity sha512-EZ1DYihju9pwVB+jg67ogm+Tmqc6JmhamRN6I4Zt8DfZu5lbcQGw3ozH9lFejSJgs/ibaef3A9PMXPLeefFGJg== +axios@^1.0.0, axios@^1.3.3, axios@^1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" + integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== dependencies: follow-redirects "^1.15.0" form-data "^4.0.0" @@ -8166,9 +8386,9 @@ better-opn@^2.1.1: open "^7.0.3" big-integer@^1.6.48, big-integer@^1.6.7: - version "1.6.51" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" - integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + version "1.6.52" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" + integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== big.js@^5.2.2: version "5.2.2" @@ -8738,9 +8958,9 @@ caniuse-api@^3.0.0: lodash.uniq "^4.5.0" caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001561" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001561.tgz#752f21f56f96f1b1a52e97aae98c57c562d5d9da" - integrity sha512-NTt0DNoKe958Q0BE0j0c1V9jbUzhBxHIEJy7asmGrpE0yG63KTV7PLHPnK2E1O9RsQrQ081I3NLuXGS6zht3cw== + version "1.0.30001565" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz#a528b253c8a2d95d2b415e11d8b9942acc100c4f" + integrity sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w== capture-exit@^2.0.0: version "2.0.0" @@ -8917,6 +9137,13 @@ cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: inherits "^2.0.1" safe-buffer "^5.0.1" +citty@^0.1.3, citty@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.5.tgz#fe37ceae5dc764af75eb2fece99d2bf527ea4e50" + integrity sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ== + dependencies: + consola "^3.2.3" + cjs-module-lexer@^1.0.0: version "1.2.3" resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" @@ -8932,7 +9159,7 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" -classnames@^2.2.5, classnames@^2.3.0: +classnames@^2.3.0: version "2.3.2" resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== @@ -8945,9 +9172,9 @@ clean-css@^4.2.3: source-map "~0.6.0" clean-css@^5.2.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.2.tgz#70ecc7d4d4114921f5d298349ff86a31a9975224" - integrity sha512-JVJbM+f3d3Q704rF4bqQ5UUyTtuJ0JRKNbTKVEeujCCBoMdkEi+V+e8oktO9qGQNSvHrFTM6JZRXrUvGR1czww== + version "5.3.3" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" + integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== dependencies: source-map "~0.6.0" @@ -8981,9 +9208,9 @@ cli-spinners@2.6.1: integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== cli-spinners@^2.5.0: - version "2.9.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.1.tgz#9c0b9dad69a6d47cbb4333c14319b060ed395a35" - integrity sha512-jHgecW0pxkonBJdrKsqxgRX9AcG+u/5k0Q7WPDfi8AogLAdwxEkyYYNWwZ5GvVFoFx2uiY1eNcSK00fh+1+FyQ== + version "2.9.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" + integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== cli-table3@^0.6.1: version "0.6.3" @@ -9009,6 +9236,15 @@ clipboard-copy@^3.0.0: resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== +clipboardy@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" + integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== + dependencies: + arch "^2.2.0" + execa "^5.1.1" + is-wsl "^2.2.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -9080,6 +9316,11 @@ clsx@^2.0.0: resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== +cluster-key-slot@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" + integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== + cmd-shim@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" @@ -9252,9 +9493,9 @@ compare-func@^2.0.0: dot-prop "^5.1.0" component-emitter@^1.2.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.0.tgz#16e4070fba8ae29b679f2215853ee181ab2eabc0" - integrity sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg== + version "1.3.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" + integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== compressible@~2.0.16: version "2.0.18" @@ -9311,6 +9552,11 @@ connect-history-api-fallback@^2.0.0: resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== +consola@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" + integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" @@ -9421,6 +9667,11 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +cookie-es@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.0.0.tgz#4759684af168dfc54365b2c2dda0a8d7ee1e4865" + integrity sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ== + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" @@ -9456,21 +9707,21 @@ copy-to-clipboard@^3.3.3: toggle-selection "^1.0.6" core-js-compat@^3.31.0, core-js-compat@^3.33.1, core-js-compat@^3.8.1: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.2.tgz#3ea4563bfd015ad4e4b52442865b02c62aba5085" - integrity sha512-axfo+wxFVxnqf8RvxTzoAlzW4gRoacrHeoFlc9n0x50+7BEyZL/Rt3hicaED1/CEd7I6tPCPVUYcJwCMO5XUYw== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.3.tgz#ec678b772c5a2d8a7c60a91c3a81869aa704ae01" + integrity sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow== dependencies: browserslist "^4.22.1" core-js-pure@^3.23.3: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.2.tgz#644830db2507ef84d068a70980ccd99c275f5fa6" - integrity sha512-a8zeCdyVk7uF2elKIGz67AjcXOxjRbwOLz8SbklEso1V+2DoW4OkAMZN9S9GBgvZIaqQi/OemFX4OiSoQEmg1Q== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.3.tgz#cbf9180ac4c4653823d784862bfb5c77eac0bf98" + integrity sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ== core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.33.2" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.2.tgz#312bbf6996a3a517c04c99b9909cdd27138d1ceb" - integrity sha512-XeBzWI6QL3nJQiHmdzbAOiMYqjrb7hwU7A39Qhvd/POSa/t9E1AeZyEZx3fNvp/vtM8zXwhoL0FsiS0hD0pruQ== + version "3.33.3" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.3.tgz#3c644a323f0f533a0d360e9191e37f7fc059088d" + integrity sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw== core-util-is@~1.0.0: version "1.0.3" @@ -9525,6 +9776,11 @@ cosmjs-types@^0.5.2: long "^4.0.0" protobufjs "~6.11.2" +cosmjs-types@^0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.9.0.tgz#c3bc482d28c7dfa25d1445093fdb2d9da1f6cfcc" + integrity sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ== + cp-file@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" @@ -10078,14 +10334,14 @@ dedent@0.7.0, dedent@^0.7.0: integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== deep-equal@^2.0.5: - version "2.2.2" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.2.tgz#9b2635da569a13ba8e1cc159c2f744071b115daa" - integrity sha512-xjVyBf0w5vH0I42jdAZzOKVldmPgSulmiyPRywoyq7HXC9qdgo17kxJE+rdnif5Tz6+pIrpJI8dCpMNLIGkUiA== + version "2.2.3" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" + integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== dependencies: array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" + call-bind "^1.0.5" es-get-iterator "^1.1.3" - get-intrinsic "^1.2.1" + get-intrinsic "^1.2.2" is-arguments "^1.1.1" is-array-buffer "^3.0.2" is-date-object "^1.0.5" @@ -10095,11 +10351,11 @@ deep-equal@^2.0.5: object-is "^1.1.5" object-keys "^1.1.1" object.assign "^4.1.4" - regexp.prototype.flags "^1.5.0" + regexp.prototype.flags "^1.5.1" side-channel "^1.0.4" which-boxed-primitive "^1.0.2" which-collection "^1.0.1" - which-typed-array "^1.1.9" + which-typed-array "^1.1.13" deep-extend@^0.6.0: version "0.6.0" @@ -10158,7 +10414,7 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== -define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.1.4, define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -10189,6 +10445,11 @@ define-property@^2.0.2: is-descriptor "^1.0.2" isobject "^3.0.1" +defu@^6.1.2, defu@^6.1.3: + version "6.1.3" + resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" + integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== + del@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" @@ -10217,6 +10478,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== +denque@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" + integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== + depd@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" @@ -10245,6 +10511,11 @@ des.js@^1.0.0: inherits "^2.0.1" minimalistic-assert "^1.0.0" +destr@^2.0.1, destr@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.2.tgz#8d3c0ee4ec0a76df54bc8b819bca215592a8c218" + integrity sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg== + destroy@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" @@ -10317,7 +10588,7 @@ diff-sequences@^28.1.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== -diff-sequences@^29.6.3: +diff-sequences@^29.4.3, diff-sequences@^29.6.3: version "29.6.3" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== @@ -10557,9 +10828,9 @@ ejs@^3.1.7: jake "^10.8.5" electron-to-chromium@^1.4.535: - version "1.4.576" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.576.tgz#0c6940fdc0d60f7e34bd742b29d8fa847c9294d1" - integrity sha512-yXsZyXJfAqzWk1WKryr0Wl0MN2D47xodPvEEwlVePBnhU5E7raevLQR+E6b9JAD3GfL/7MbAL9ZtWQQPcLx7wA== + version "1.4.598" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.598.tgz#aaf1f64286001915b59210158d21b6284e96acbc" + integrity sha512-0JnipX0scPUlwsptQVCZggoCpREv+IrVD3h0ZG+sldmK9L27tSV3QjV8+QdaA4qQTzDf3PluNS45YYJky1oASw== elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -10791,9 +11062,9 @@ es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: safe-array-concat "^1.0.1" es-module-lexer@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.3.1.tgz#c1b0dd5ada807a3b3155315911f364dc4e909db1" - integrity sha512-JUFAyicQV9mXc3YRxPnDlrfBKpqt6hUYzz9/boprUJHs4e4KVr3XwOF70doO6gwXUor6EWZJAyWAfKki84t20Q== + version "1.4.1" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" + integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== es-set-tostringtag@^2.0.1: version "2.0.2" @@ -11124,14 +11395,14 @@ eslint@^7.18.0: v8-compile-cache "^2.0.3" eslint@^8.10.0: - version "8.53.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.53.0.tgz#14f2c8244298fcae1f46945459577413ba2697ce" - integrity sha512-N4VuiPjXDUa4xVeV/GC/RV3hQW9Nw+Y463lkWaKKXKYMvmRiRDAtfpuPFLN+E1/6ZhyR8J2ig+eVREnYgUsiag== + version "8.54.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" + integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.53.0" + "@eslint/js" "8.54.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -11774,9 +12045,9 @@ find-up@^4.0.0, find-up@^4.1.0: path-exists "^4.0.0" flat-cache@^3.0.4: - version "3.1.1" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.1.1.tgz#a02a15fdec25a8f844ff7cc658f03dd99eb4609b" - integrity sha512-/qM2b3LUIaIgviBQovTLvijfyOQXPtSRnRK26ksj2J7rzPIecePUIpJsZ4T02Qg+xiAEKIs5K8dsHEd+VaKa/Q== + version "3.2.0" + resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" + integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== dependencies: flatted "^3.2.9" keyv "^4.5.3" @@ -11938,7 +12209,7 @@ fs-constants@^1.0.0: resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== -fs-extra@11.1.1, fs-extra@^11.1.0, fs-extra@^11.1.1: +fs-extra@11.1.1: version "11.1.1" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== @@ -11956,6 +12227,15 @@ fs-extra@^10.0.0, fs-extra@^10.1.0: jsonfile "^6.0.1" universalify "^2.0.0" +fs-extra@^11.1.0, fs-extra@^11.1.1: + version "11.2.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" + integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-extra@^9.0.0, fs-extra@^9.0.1: version "9.1.0" resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" @@ -12077,6 +12357,11 @@ get-caller-file@^2.0.5: resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== +get-func-name@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" + integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" @@ -12102,6 +12387,11 @@ get-pkg-repo@^4.2.1: through2 "^2.0.0" yargs "^16.2.0" +get-port-please@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.1.tgz#2556623cddb4801d823c0a6a15eec038abb483be" + integrity sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA== + get-port@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" @@ -12387,6 +12677,20 @@ graphemer@^1.4.0: resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== +h3@^1.8.1, h3@^1.8.2: + version "1.9.0" + resolved "https://registry.yarnpkg.com/h3/-/h3-1.9.0.tgz#c5f512a93026df9837db6f30c9ef51135dd46752" + integrity sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA== + dependencies: + cookie-es "^1.0.0" + defu "^6.1.3" + destr "^2.0.2" + iron-webcrypto "^1.0.0" + radix3 "^1.1.0" + ufo "^1.3.2" + uncrypto "^0.1.3" + unenv "^1.7.4" + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" @@ -12834,6 +13138,11 @@ http-proxy@^1.18.1: follow-redirects "^1.0.0" requires-port "^1.0.0" +http-shutdown@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f" + integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw== + https-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" @@ -12897,6 +13206,11 @@ icss-utils@^5.0.0, icss-utils@^5.1.0: resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== +idb-keyval@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" @@ -12920,9 +13234,9 @@ ignore-walk@^5.0.1: minimatch "^5.0.1" ignore-walk@^6.0.0: - version "6.0.3" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.3.tgz#0fcdb6decaccda35e308a7b0948645dd9523b7bb" - integrity sha512-C7FfFoTA+bI10qfeydT8aZbvr91vAEU+2W5BZUlzPec47oNb07SsOfwYrtxuvOYdUApPP/Qlh4DtAO51Ekk2QA== + version "6.0.4" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" + integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== dependencies: minimatch "^9.0.0" @@ -12932,9 +13246,9 @@ ignore@^4.0.3, ignore@^4.0.6: integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== ignore@^5.0.4, ignore@^5.2.0: - version "5.2.4" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.4.tgz#a291c0c6178ff1b960befe47fcdec301674a6324" - integrity sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ== + version "5.3.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" + integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== immediate@~3.0.5: version "3.0.6" @@ -13071,15 +13385,30 @@ interpret@^2.2.0: integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== intl-messageformat@^10.1.0: - version "10.5.4" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.4.tgz#7b212b083f1b354d7e282518e78057e025134af9" - integrity sha512-z+hrFdiJ/heRYlzegrdFYqU1m/KOMOVMqNilIArj+PbsuU8TNE7v4TWdQgSoxlxbT4AcZH3Op3/Fu15QTp+W1w== + version "10.5.8" + resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.8.tgz#7184da425f360a53a5483a6194e16d666b011fc0" + integrity sha512-NRf0jpBWV0vd671G5b06wNofAN8tp7WWDogMZyaU8GUAsmbouyvgwmFJI7zLjfAMpm3zK+vSwRP3jzaoIcMbaA== dependencies: - "@formatjs/ecma402-abstract" "1.17.2" + "@formatjs/ecma402-abstract" "1.18.0" "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.7.0" + "@formatjs/icu-messageformat-parser" "2.7.3" tslib "^2.4.0" +ioredis@^5.3.2: + version "5.3.2" + resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" + integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== + dependencies: + "@ioredis/commands" "^1.1.1" + cluster-key-slot "^1.1.0" + debug "^4.3.4" + denque "^2.1.0" + lodash.defaults "^4.2.0" + lodash.isarguments "^3.1.0" + redis-errors "^1.2.0" + redis-parser "^3.0.0" + standard-as-callback "^2.1.0" + ip@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" @@ -13095,6 +13424,11 @@ ipaddr.js@^2.0.1: resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== +iron-webcrypto@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.0.0.tgz#e3b689c0c61b434a0a4cb82d0aeabbc8b672a867" + integrity sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg== + is-absolute-url@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" @@ -13133,7 +13467,7 @@ is-alphanumerical@^2.0.0: is-alphabetical "^2.0.0" is-decimal "^2.0.0" -is-arguments@^1.1.1: +is-arguments@^1.0.4, is-arguments@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -13336,7 +13670,7 @@ is-generator-fn@^2.0.0: resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== -is-generator-function@^1.0.10: +is-generator-function@^1.0.10, is-generator-function@^1.0.7: version "1.0.10" resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== @@ -13564,7 +13898,7 @@ is-text-path@^1.0.1: dependencies: text-extensions "^1.0.0" -is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.9: +is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: version "1.1.12" resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== @@ -13684,9 +14018,9 @@ isomorphic-ws@^4.0.1: integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.1.tgz#c680fd1544600460367af5811866c34c44c6f3b1" - integrity sha512-opCrKqbthmq3SKZ10mFMQG9dk3fTa3quaOLD35kJa5ejwZHd9xAr+kLuziiZz2cG32s4lMZxNdmdcEQnTDP4+g== + version "3.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" + integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: version "5.2.1" @@ -14337,6 +14671,25 @@ jest@^27.1.0: import-local "^3.0.2" jest-cli "^27.5.1" +<<<<<<< HEAD +======= +jiti@^1.20.0: + version "1.21.0" + resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" + integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== + +joi@^17.11.0: + version "17.11.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" + integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== + dependencies: + "@hapi/hoek" "^9.0.0" + "@hapi/topo" "^5.0.0" + "@sideway/address" "^4.1.3" + "@sideway/formula" "^3.0.1" + "@sideway/pinpoint" "^2.0.0" + +>>>>>>> 1a01da17e (refactor) js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -14426,9 +14779,9 @@ json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== json-parse-even-better-errors@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.0.tgz#2cb2ee33069a78870a0c7e3da560026b89669cf7" - integrity sha512-iZbGHafX/59r39gPwVPRBGw0QQKnA7tte5pSMrhWOW7swGsVvVTjmfyAV9pNqk8YGT7tRCdxRu8uzcgZwoDooA== + version "3.0.1" + resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" + integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== json-schema-traverse@^0.4.1: version "0.4.1" @@ -14462,7 +14815,7 @@ json5@^1.0.1, json5@^1.0.2: dependencies: minimist "^1.2.0" -jsonc-parser@3.2.0, jsonc-parser@^3.0.0: +jsonc-parser@3.2.0, jsonc-parser@^3.0.0, jsonc-parser@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== @@ -14766,6 +15119,18 @@ libnpmpublish@7.3.0: sigstore "^1.4.0" ssri "^10.0.1" +libsodium-sumo@^0.7.13: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz#533b97d2be44b1277e59c1f9f60805978ac5542d" + integrity sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ== + +libsodium-wrappers-sumo@^0.7.11: + version "0.7.13" + resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz#a33aea845a0bb56db067548f04feba28c730ab8e" + integrity sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ== + dependencies: + libsodium-sumo "^0.7.13" + libsodium-wrappers@^0.7.6: version "0.7.13" resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" @@ -14796,9 +15161,32 @@ lines-and-columns@^1.1.6: integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== lines-and-columns@~2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.3.tgz#b2f0badedb556b747020ab8ea7f0373e22efac1b" - integrity sha512-cNOjgCnLB+FnvWWtyRTzmB3POJ+cXxTA81LoW7u8JdmhfXzriropYwpjShnz1QLLWsQwY7nIxoDmcPTwphDK9w== + version "2.0.4" + resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" + integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== + +listhen@^1.5.5: + version "1.5.5" + resolved "https://registry.yarnpkg.com/listhen/-/listhen-1.5.5.tgz#58915512af70f770aa3e9fb19367adf479bb58c4" + integrity sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA== + dependencies: + "@parcel/watcher" "^2.3.0" + "@parcel/watcher-wasm" "2.3.0" + citty "^0.1.4" + clipboardy "^3.0.0" + consola "^3.2.3" + defu "^6.1.2" + get-port-please "^3.1.1" + h3 "^1.8.1" + http-shutdown "^1.2.2" + jiti "^1.20.0" + mlly "^1.4.2" + node-forge "^1.3.1" + pathe "^1.1.1" + std-env "^3.4.3" + ufo "^1.3.0" + untun "^0.1.2" + uqr "^0.1.2" load-json-file@6.2.0: version "6.2.0" @@ -14906,11 +15294,21 @@ lodash.debounce@^4.0.8: resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== +lodash.defaults@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" + integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== + lodash.defaultsdeep@^4.6.1: version "4.6.1" resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== +lodash.isarguments@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== + lodash.isequal@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -14994,6 +15392,13 @@ loud-rejection@^1.0.0: currently-unhandled "^0.4.1" signal-exit "^3.0.0" +loupe@^2.3.6: + version "2.3.7" + resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" + integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== + dependencies: + get-func-name "^2.0.1" + lower-case@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" @@ -15001,6 +15406,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": + version "10.1.0" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" + integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -15020,11 +15430,6 @@ lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== -"lru-cache@^9.1.1 || ^10.0.0": - version "10.0.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.0.1.tgz#0a3be479df549cca0e5d693ac402ff19537a6b7a" - integrity sha512-IJ4uwUTi2qCccrioU6g9g/5rvvVl13bsdczUUcqbciD9iLr095yj8DQKdObriEvuNSx325N1rV1O0sJFszx75g== - lunr@^2.3.9: version "2.3.9" resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" @@ -15780,7 +16185,7 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4: +micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== @@ -15818,6 +16223,11 @@ mime@^2.4.4: resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== +mime@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" @@ -16047,10 +16457,20 @@ mkdirp@^1.0.3, mkdirp@^1.0.4: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mlly@^1.2.0, mlly@^1.4.2: + version "1.4.2" + resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" + integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== + dependencies: + acorn "^8.10.0" + pathe "^1.1.1" + pkg-types "^1.0.3" + ufo "^1.3.0" + mobx@^6.1.7: - version "6.10.2" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.10.2.tgz#96e123deef140750360ca9a5b02a8b91fbffd4d9" - integrity sha512-B1UGC3ieK3boCjnMEcZSwxqRDMdzX65H/8zOHbuTY8ZhvrIjTUoLRR2TP2bPqIgYRfb3+dUigu8yMZufNjn0LQ== + version "6.12.0" + resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.0.tgz#72b2685ca5af031aaa49e77a4d76ed67fcbf9135" + integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ== mocha@^10.0.0: version "10.2.0" @@ -16079,6 +16499,11 @@ mocha@^10.0.0: yargs-parser "20.2.4" yargs-unparser "2.0.0" +modern-ahocorasick@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz#dec373444f51b5458ac05216a8ec376e126dd283" + integrity sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA== + modify-values@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" @@ -16103,7 +16528,7 @@ move-concurrently@^1.0.1: rimraf "^2.5.4" run-queue "^1.0.3" -mri@^1.1.0: +mri@^1.1.0, mri@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== @@ -16204,6 +16629,11 @@ napi-build-utils@^1.0.1: resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== +napi-wasm@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.0.tgz#bbe617823765ae9c1bc12ff5942370eae7b2ba4e" + integrity sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg== + natural-compare-lite@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" @@ -16269,6 +16699,11 @@ node-addon-api@^6.1.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== +node-addon-api@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" + integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== + node-dir@^0.1.10: version "0.1.17" resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" @@ -16276,6 +16711,11 @@ node-dir@^0.1.10: dependencies: minimatch "^3.0.2" +node-fetch-native@^1.4.0, node-fetch-native@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.1.tgz#5a336e55b4e1b1e72b9927da09fecd2b374c9be5" + integrity sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w== + node-fetch@2.6.7: version "2.6.7" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" @@ -16290,15 +16730,15 @@ node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" -node-forge@^1: +node-forge@^1, node-forge@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp-build@^4.3.0: - version "4.6.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.6.1.tgz#24b6d075e5e391b8d5539d98c7fc5c210cac8a3e" - integrity sha512-24vnklJmyRS8ViBNI8KbtK/r/DmXQMRiOMXTNz2nrTnAYUwjmEEbnnpB/+kt+yWRv73bPsSPRFddrcIbAxSiMQ== + version "4.7.1" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" + integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== node-gyp@^9.0.0, node-gyp@^9.3.1: version "9.4.1" @@ -16700,12 +17140,12 @@ object-visit@^1.0.0: isobject "^3.0.0" object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.4" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" - integrity sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ== + version "4.1.5" + resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" + 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" @@ -16782,6 +17222,15 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +ofetch@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.3.tgz#588cb806a28e5c66c2c47dd8994f9059a036d8c0" + integrity sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg== + dependencies: + destr "^2.0.1" + node-fetch-native "^1.4.0" + ufo "^1.3.0" + on-exit-leak-free@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" @@ -17286,6 +17735,11 @@ path-type@^4.0.0: resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pathe@^1.1.0, pathe@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" + integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== + pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -17414,6 +17868,15 @@ pkg-dir@^5.0.0: dependencies: find-up "^5.0.0" +pkg-types@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" + integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== + dependencies: + jsonc-parser "^3.2.0" + mlly "^1.2.0" + pathe "^1.1.0" + pnp-webpack-plugin@1.6.4: version "1.6.4" resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" @@ -17819,7 +18282,7 @@ pretty-format@^28.1.3: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.0.0, pretty-format@^29.7.0: +pretty-format@^29.0.0, pretty-format@^29.5.0, pretty-format@^29.7.0: version "29.7.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== @@ -18121,6 +18584,11 @@ quick-lru@^4.0.1: resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +radix3@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" + integrity sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A== + rainbow-sprinkles@^0.17.0: version "0.17.0" resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.0.tgz#6ee06c6decc767b89bf01fc5fe87ecf859fd4c2f" @@ -18195,46 +18663,46 @@ rc@^1.2.7: strip-json-comments "~2.0.1" react-aria@^3.29.1: - version "3.29.1" - resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.29.1.tgz#4f6e968a15cfec69d8d8735b98d0fe8ac31b4be2" - integrity sha512-dDoaTh5fCaD3kO0kv49pqUUOsXRGuqFX7owQaly/RhWkBw/dlIYkHRVdOatllI/v4h1/Ne40QOXl15aAISozlA== + version "3.30.0" + resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.30.0.tgz#dd53d2103050e7279ec8f3faacce5ae8521f61ce" + integrity sha512-ULMlmH68/jXzkDaMjuM9O8dKCxnAYviW4E5sywfLX4J6mC6eGsQzoqtwWeQgr1M9SJqLfgKaVoDP1dLvb4XzEA== dependencies: - "@react-aria/breadcrumbs" "^3.5.7" - "@react-aria/button" "^3.8.4" - "@react-aria/calendar" "^3.5.2" - "@react-aria/checkbox" "^3.11.2" - "@react-aria/combobox" "^3.7.1" - "@react-aria/datepicker" "^3.8.1" - "@react-aria/dialog" "^3.5.7" - "@react-aria/dnd" "^3.4.3" - "@react-aria/focus" "^3.14.3" - "@react-aria/gridlist" "^3.7.1" - "@react-aria/i18n" "^3.8.4" - "@react-aria/interactions" "^3.19.1" - "@react-aria/label" "^3.7.2" - "@react-aria/link" "^3.6.1" - "@react-aria/listbox" "^3.11.1" - "@react-aria/menu" "^3.11.1" - "@react-aria/meter" "^3.4.7" - "@react-aria/numberfield" "^3.9.1" - "@react-aria/overlays" "^3.18.1" - "@react-aria/progress" "^3.4.7" - "@react-aria/radio" "^3.8.2" - "@react-aria/searchfield" "^3.5.7" - "@react-aria/select" "^3.13.1" - "@react-aria/selection" "^3.17.1" - "@react-aria/separator" "^3.3.7" - "@react-aria/slider" "^3.7.2" - "@react-aria/ssr" "^3.8.0" - "@react-aria/switch" "^3.5.6" - "@react-aria/table" "^3.13.1" - "@react-aria/tabs" "^3.8.1" - "@react-aria/tag" "^3.2.1" - "@react-aria/textfield" "^3.12.2" - "@react-aria/tooltip" "^3.6.4" - "@react-aria/utils" "^3.21.1" - "@react-aria/visually-hidden" "^3.8.6" - "@react-types/shared" "^3.21.0" + "@react-aria/breadcrumbs" "^3.5.8" + "@react-aria/button" "^3.9.0" + "@react-aria/calendar" "^3.5.3" + "@react-aria/checkbox" "^3.12.0" + "@react-aria/combobox" "^3.8.0" + "@react-aria/datepicker" "^3.9.0" + "@react-aria/dialog" "^3.5.8" + "@react-aria/dnd" "^3.5.0" + "@react-aria/focus" "^3.15.0" + "@react-aria/gridlist" "^3.7.2" + "@react-aria/i18n" "^3.9.0" + "@react-aria/interactions" "^3.20.0" + "@react-aria/label" "^3.7.3" + "@react-aria/link" "^3.6.2" + "@react-aria/listbox" "^3.11.2" + "@react-aria/menu" "^3.11.2" + "@react-aria/meter" "^3.4.8" + "@react-aria/numberfield" "^3.10.0" + "@react-aria/overlays" "^3.19.0" + "@react-aria/progress" "^3.4.8" + "@react-aria/radio" "^3.9.0" + "@react-aria/searchfield" "^3.6.0" + "@react-aria/select" "^3.14.0" + "@react-aria/selection" "^3.17.2" + "@react-aria/separator" "^3.3.8" + "@react-aria/slider" "^3.7.3" + "@react-aria/ssr" "^3.9.0" + "@react-aria/switch" "^3.5.7" + "@react-aria/table" "^3.13.2" + "@react-aria/tabs" "^3.8.2" + "@react-aria/tag" "^3.3.0" + "@react-aria/textfield" "^3.13.0" + "@react-aria/tooltip" "^3.6.5" + "@react-aria/utils" "^3.22.0" + "@react-aria/visually-hidden" "^3.8.7" + "@react-types/shared" "^3.22.0" react-docgen-typescript@^2.1.1: version "2.2.2" @@ -18373,27 +18841,20 @@ react-refresh@^0.11.0: resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== -react-resize-detector@^8.0.4: - version "8.1.0" - resolved "https://registry.yarnpkg.com/react-resize-detector/-/react-resize-detector-8.1.0.tgz#1c7817db8bc886e2dbd3fbe3b26ea8e56be0524a" - integrity sha512-S7szxlaIuiy5UqLhLL1KY3aoyGHbZzsTpYal9eYMwCyKqoqoVLCmIgAgNyIM1FhnP2KyBygASJxdhejrzjMb+w== - dependencies: - lodash "^4.17.21" - react-router-dom@6, react-router-dom@^6.7.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.18.0.tgz#0a50c167209d6e7bd2ed9de200a6579ea4fb1dca" - integrity sha512-Ubrue4+Ercc/BoDkFQfc6og5zRQ4A8YxSO3Knsne+eRbZ+IepAsK249XBH/XaFuOYOYr3L3r13CXTLvYt5JDjw== + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b" + integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ== dependencies: - "@remix-run/router" "1.11.0" - react-router "6.18.0" + "@remix-run/router" "1.13.0" + react-router "6.20.0" -react-router@6.18.0: - version "6.18.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.18.0.tgz#32e2bedc318e095a48763b5ed7758e54034cd36a" - integrity sha512-vk2y7Dsy8wI02eRRaRmOs9g2o+aE72YCx5q9VasT1N9v+lrdB79tIqrjMfByHiY5+6aYkH2rUa5X839nwWGPDg== +react-router@6.20.0: + version "6.20.0" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539" + integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w== dependencies: - "@remix-run/router" "1.11.0" + "@remix-run/router" "1.13.0" react-simple-maps@^2.3.0: version "2.3.0" @@ -18405,7 +18866,7 @@ react-simple-maps@^2.3.0: d3-zoom "^2.0.0" topojson-client "^3.1.0" -react-smooth@^2.0.4: +react-smooth@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== @@ -18414,37 +18875,38 @@ react-smooth@^2.0.4: react-transition-group "2.9.0" react-stately@^3.27.1: - version "3.27.1" - resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.27.1.tgz#b24992bd72da1b1632bf4f4232d87ce6913a19bd" - integrity sha512-qHhivqOpyATaWwoj3xl3IqqoEnib+dsl2vYlOz92CT5Ntm6lprF7KO+LkxdkS0SnUckdGewFM1NjCmbK7wPJgw== + version "3.28.0" + resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.28.0.tgz#f2831e50b70b0dcec7e3d7e3787f9dc1df42d9c3" + integrity sha512-owEHRGS1zRMwtiR/jeXUjUWyqk8oe53wNtedMvg9+8+NNhDKL4/DXHcIp2A13q08v09xYWgVPtnu8fsF53x2PQ== dependencies: - "@react-stately/calendar" "^3.4.1" - "@react-stately/checkbox" "^3.5.1" - "@react-stately/collections" "^3.10.2" - "@react-stately/combobox" "^3.7.1" - "@react-stately/data" "^3.10.3" - "@react-stately/datepicker" "^3.8.0" - "@react-stately/dnd" "^3.2.5" - "@react-stately/list" "^3.10.0" - "@react-stately/menu" "^3.5.6" - "@react-stately/numberfield" "^3.6.2" - "@react-stately/overlays" "^3.6.3" - "@react-stately/radio" "^3.9.1" - "@react-stately/searchfield" "^3.4.6" - "@react-stately/select" "^3.5.5" - "@react-stately/selection" "^3.14.0" - "@react-stately/slider" "^3.4.4" - "@react-stately/table" "^3.11.2" - "@react-stately/tabs" "^3.6.1" - "@react-stately/toggle" "^3.6.3" - "@react-stately/tooltip" "^3.4.5" - "@react-stately/tree" "^3.7.3" - "@react-types/shared" "^3.21.0" + "@react-stately/calendar" "^3.4.2" + "@react-stately/checkbox" "^3.6.0" + "@react-stately/collections" "^3.10.3" + "@react-stately/combobox" "^3.8.0" + "@react-stately/data" "^3.11.0" + "@react-stately/datepicker" "^3.9.0" + "@react-stately/dnd" "^3.2.6" + "@react-stately/form" "^3.0.0" + "@react-stately/list" "^3.10.1" + "@react-stately/menu" "^3.5.7" + "@react-stately/numberfield" "^3.7.0" + "@react-stately/overlays" "^3.6.4" + "@react-stately/radio" "^3.10.0" + "@react-stately/searchfield" "^3.5.0" + "@react-stately/select" "^3.6.0" + "@react-stately/selection" "^3.14.1" + "@react-stately/slider" "^3.4.5" + "@react-stately/table" "^3.11.3" + "@react-stately/tabs" "^3.6.2" + "@react-stately/toggle" "^3.7.0" + "@react-stately/tooltip" "^3.4.6" + "@react-stately/tree" "^3.7.4" + "@react-types/shared" "^3.22.0" react-tooltip@*: - version "5.22.0" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.22.0.tgz#3082065b1efbd207813f484b617b1b75325f15d5" - integrity sha512-xbJBRY1LyHYd7j00UeBOqZR9SH/1S47Pe+m8vM1a+ZXglkeSNnBt5YYoPttU/amjC/VZJAPQ8+2B9x8Fl8U1qA== + version "5.24.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.24.0.tgz#c134e4c00d49a111986711696bcd9abf672caff6" + integrity sha512-HjstgpOrUwP4eN6mHU4EThpbxVuKO5SvqumRt1aAcPq0ya+pIVVxlwltndtdIIMBJ7w3jnN05vNfcfh2sxE2mQ== dependencies: "@floating-ui/dom" "^1.0.0" classnames "^2.3.0" @@ -18623,16 +19085,15 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.1.13: - version "2.9.2" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.9.2.tgz#a6a4e4c2887467ea57abde7e3af5c8021355a606" - integrity sha512-ig0zYgO5nUP/896GW16b9yy2sHIRW1AHB90x48hypFTSjjxQt/J9rPzlLJjgNupzJKEHPCwMi1VnvN/k20K45w== + version "2.10.2" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.2.tgz#919e9ccba463c7face91438c807340f300435e55" + integrity sha512-goasBqGqpH8SLty+a24xG1KkZWowo793mgoNVrOkBRXZCG2xX+BUbCgaWrB/G+DGIpN2AX/arCttLuHdg/A6LQ== dependencies: - classnames "^2.2.5" + clsx "^2.0.0" eventemitter3 "^4.0.1" lodash "^4.17.19" react-is "^16.10.2" - react-resize-detector "^8.0.4" - react-smooth "^2.0.4" + react-smooth "^2.0.5" recharts-scale "^0.4.4" tiny-invariant "^1.3.1" victory-vendor "^36.6.8" @@ -18660,6 +19121,18 @@ redent@^3.0.0: indent-string "^4.0.0" strip-indent "^3.0.0" +redis-errors@^1.0.0, redis-errors@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" + integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== + +redis-parser@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" + integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== + dependencies: + redis-errors "^1.0.0" + reflect.getprototypeof@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" @@ -19125,11 +19598,6 @@ safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-json-utils@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/safe-json-utils/-/safe-json-utils-1.1.1.tgz#0e883874467d95ab914c3f511096b89bfb3e63b1" - integrity sha512-SAJWGKDs50tAbiDXLf89PDwt9XYkWyANFWVzn4dTXl5QyI8t2o/bW5/OJl3lvc2WVU4MEpTo9Yz5NVFNsp+OJQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -19845,6 +20313,11 @@ stackframe@^1.3.4: resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== +standard-as-callback@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" + integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== + state-toggle@^1.0.0: version "1.0.3" resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" @@ -19868,6 +20341,11 @@ statuses@2.0.1: resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== +std-env@^3.4.3: + version "3.5.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" + integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" @@ -19913,9 +20391,9 @@ stream-shift@^1.0.0: integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== streamx@^2.15.0: - version "2.15.2" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.2.tgz#680eacebdc9c43ede7362c2e6695b34dd413c741" - integrity sha512-b62pAV/aeMjUoRN2C/9F0n+G8AfcJjNC0zw/ZmOHeFsIe4m4GzjVW9m6VHXVjk536NbdU9JRwKMJRfkc+zUFTg== + version "2.15.5" + resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.5.tgz#87bcef4dc7f0b883f9359671203344a4e004c7f1" + integrity sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg== dependencies: fast-fifo "^1.1.0" queue-tick "^1.0.1" @@ -20701,9 +21179,9 @@ ts-jest@^27.0.5: yargs-parser "20.x" ts-loader@^9.4.2: - version "9.5.0" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.0.tgz#f0a51dda37cc4d8e43e6cb14edebbc599b0c3aa2" - integrity sha512-LLlB/pkB4q9mW2yLdFMnK3dEHbrBjeZTYguaaIfusyojBgAGf5kF+O6KcWqiGzWqHk0LBsoolrp4VftEURhybg== + version "9.5.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" + integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" @@ -20969,15 +21447,20 @@ typeforce@^1.11.5: integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== "typescript@>=3 < 6": - version "5.2.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.2.2.tgz#5ebb5e5a5b75f085f22bc3f8460fba308310fa78" - integrity sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w== + version "5.3.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" + integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== typescript@^4.6.2, typescript@^4.8.4: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== +ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" + integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA== + uglify-js@^3.1.4: version "3.17.4" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" @@ -21000,6 +21483,11 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" +uncrypto@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" + integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== + undefsafe@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" @@ -21010,6 +21498,17 @@ undici-types@~5.26.4: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== +unenv@^1.7.4: + version "1.8.0" + resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c" + integrity sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg== + dependencies: + consola "^3.2.3" + defu "^6.1.3" + mime "^3.0.0" + node-fetch-native "^1.4.1" + pathe "^1.1.1" + unfetch@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" @@ -21267,6 +21766,23 @@ unset-value@^1.0.0: has-value "^0.3.1" isobject "^3.0.0" +unstorage@^1.9.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.10.1.tgz#bf8cc00a406e40a6293e893da9807057d95875b0" + integrity sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw== + dependencies: + anymatch "^3.1.3" + chokidar "^3.5.3" + destr "^2.0.2" + h3 "^1.8.2" + ioredis "^5.3.2" + listhen "^1.5.5" + lru-cache "^10.0.2" + mri "^1.2.0" + node-fetch-native "^1.4.1" + ofetch "^1.3.3" + ufo "^1.3.1" + untildify@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" @@ -21274,6 +21790,15 @@ untildify@^2.0.0: dependencies: os-homedir "^1.0.0" +untun@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/untun/-/untun-0.1.2.tgz#fa42a62ae24c1c5c6f3209692a2b0e1f573f1353" + integrity sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q== + dependencies: + citty "^0.1.3" + consola "^3.2.3" + pathe "^1.1.1" + upath@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" @@ -21292,6 +21817,11 @@ update-browserslist-db@^1.0.13: escalade "^3.1.1" picocolors "^1.0.0" +uqr@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" + integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -21373,6 +21903,17 @@ util@^0.11.0: dependencies: inherits "2.0.3" +util@^0.12.4: + version "0.12.5" + resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" + integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== + dependencies: + inherits "^2.0.3" + is-arguments "^1.0.4" + is-generator-function "^1.0.7" + is-typed-array "^1.1.3" + which-typed-array "^1.1.2" + utila@~0.4: version "0.4.0" resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" @@ -21448,9 +21989,9 @@ v8-to-istanbul@^8.1.0: source-map "^0.7.3" v8-to-istanbul@^9.0.0: - version "9.1.3" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.3.tgz#ea456604101cd18005ac2cae3cdd1aa058a6306b" - integrity sha512-9lDD+EVI2fjFsMWXc6dy5JJzBsVTcQ2fVkfBvncZ6xJWG9wtBhOldG+mHkSL0+V1K/xgZz0JDO5UT5hFwHUghg== + version "9.2.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" + integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== dependencies: "@jridgewell/trace-mapping" "^0.3.12" "@types/istanbul-lib-coverage" "^2.0.1" @@ -21525,9 +22066,9 @@ vfile@^5.0.0: vfile-message "^3.0.0" victory-vendor@^36.6.8: - version "36.6.12" - resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.6.12.tgz#17fa4d79d266a6e2bde0291c60c5002c55008164" - integrity sha512-pJrTkNHln+D83vDCCSUf0ZfxBvIaVrFHmrBOsnnLAbdqfudRACAj51He2zU94/IWq9464oTADcPVkmWAfNMwgA== + version "36.7.0" + resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.7.0.tgz#e02af33e249e74e659fa65c6d5936042c42e7aa8" + integrity sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA== dependencies: "@types/d3-array" "^3.0.3" "@types/d3-ease" "^3.0.0" @@ -21944,7 +22485,7 @@ which-collection@^1.0.1: is-weakmap "^2.0.1" is-weakset "^2.0.1" -which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.9: +which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2, which-typed-array@^1.1.9: version "1.1.13" resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== From cb9d730c166da58d98cc1f79574724d75220d4ac Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 1 Dec 2023 14:57:39 +0000 Subject: [PATCH 129/394] display user message when wallet is not connected fix linting --- .../Delegations/components/DelegateModal.tsx | 24 ++++++++++++++----- .../components/DelegationModal.tsx | 10 +++++++- explorer/src/components/Nav.tsx | 1 - explorer/src/components/TableToolbar.tsx | 4 ++-- explorer/src/icons/TokenSVG.tsx | 2 -- explorer/src/pages/Mixnodes/index.tsx | 9 ++++++- 6 files changed, 37 insertions(+), 13 deletions(-) diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/components/DelegateModal.tsx index 4a2e6a32d3..d0df90ab13 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/components/DelegateModal.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { Box, SxProps, TextField } from '@mui/material'; +import { Box, SxProps } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { CurrencyDenom, DecCoin } from '@nymproject/types'; @@ -79,8 +79,16 @@ export const DelegateModal: FCWithChildren<{ setValidated(newValidatedValue); }; - const delegateToMixnode = async ({ mixId, address, amount }: { mixId: number; address: string; amount: string }) => { - const amountToDelegate = (Number(amount) * 1000000).toString(); + const delegateToMixnode = async ({ + delegationMixId, + delgationAddress, + delegationAmount, + }: { + delegationMixId: number; + delgationAddress: string; + delegationAmount: string; + }) => { + const amountToDelegate = (Number(delegationAmount) * 1000000).toString(); const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }]; const memo: string = 'test delegation'; const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] }; @@ -88,11 +96,11 @@ export const DelegateModal: FCWithChildren<{ try { const signerClient = await getSigningCosmWasmClient(); const tx = await signerClient.execute( - address, + delgationAddress, MIXNET_CONTRACT_ADDRESS, { delegate_to_mixnode: { - mix_id: mixId, + mix_id: delegationMixId, }, }, fee, @@ -116,7 +124,11 @@ export const DelegateModal: FCWithChildren<{ throw new Error('Please connect your wallet'); } - const tx = await delegateToMixnode({ mixId, address, amount: amount.amount }); + const tx = await delegateToMixnode({ + delegationMixId: mixId, + delgationAddress: address, + delegationAmount: amount.amount, + }); onOk({ status: 'success', diff --git a/explorer/src/components/Delegations/components/DelegationModal.tsx b/explorer/src/components/Delegations/components/DelegationModal.tsx index 4b2e486a6c..6e00092eac 100644 --- a/explorer/src/components/Delegations/components/DelegationModal.tsx +++ b/explorer/src/components/Delegations/components/DelegationModal.tsx @@ -6,7 +6,7 @@ import { ConfirmationModal } from './ConfirmationModal'; import { ErrorModal } from './ErrorModal'; export type DelegationModalProps = { - status: 'loading' | 'success' | 'error'; + status: 'loading' | 'success' | 'error' | 'info'; message?: string; transactions?: { url: string; @@ -33,6 +33,14 @@ export const DelegationModal: FCWithChildren< ); } + if (status === 'info') { + return ( + + {message} + + ); + } + return ( {})} title="Delegation successful" confirmButton="Done"> diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx index 4564533875..fd4a80e916 100644 --- a/explorer/src/components/Nav.tsx +++ b/explorer/src/components/Nav.tsx @@ -21,7 +21,6 @@ import { NYM_WEBSITE } from '../api/constants'; import { useMainContext } from '../context/main'; import { MobileDrawerClose } from '../icons/MobileDrawerClose'; import { Footer } from './Footer'; -import { NymVpnIcon } from '../icons/NymVpn'; import { DarkLightSwitchDesktop } from './Switch'; import { NavOptionType } from '../context/nav'; import { ConnectKeplrWallet } from './ConnectKeplrWallet'; diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index 456eaccab8..22a25e67fd 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -1,5 +1,5 @@ -import React, { FC, useContext, useEffect, useState, useMemo } from 'react'; -import { Box, TextField, MenuItem, FormControl, Button } from '@mui/material'; +import React from 'react'; +import { Box, TextField, MenuItem, FormControl } from '@mui/material'; import Select, { SelectChangeEvent } from '@mui/material/Select'; import { Filters } from './Filters/Filters'; import { useIsMobile } from '../hooks/useIsMobile'; diff --git a/explorer/src/icons/TokenSVG.tsx b/explorer/src/icons/TokenSVG.tsx index 76c2765369..94ab1468c9 100644 --- a/explorer/src/icons/TokenSVG.tsx +++ b/explorer/src/icons/TokenSVG.tsx @@ -1,8 +1,6 @@ import * as React from 'react'; -import { useTheme } from '@mui/material/styles'; export const TokenSVG: FCWithChildren = () => { - const theme = useTheme(); const color = 'white'; return ( diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index d9980f6790..b325a25f81 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -111,7 +111,14 @@ export const PageMixnodes: FCWithChildren = () => { renderCell: (params: GridRenderCellParams) => ( { - setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); + if (wallet.status !== 'Connected') { + setConfirmationModalProps({ + status: 'info', + message: 'Please connect your wallet to delegate', + }); + } else { + setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); + } }} /> ), From 718de1f10232b972da1f6c2c332f8e4bd3e3af5d Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Fri, 1 Dec 2023 16:08:32 +0000 Subject: [PATCH 130/394] fix up mobile view fix deps issues --- explorer/package.json | 2 + .../Delegations/components/ErrorModal.tsx | 2 +- .../Delegations/components/LoadingModal.tsx | 2 +- .../Delegations/components/SimpleModal.tsx | 8 +- .../packages/validator-client/package.json | 4 +- yarn.lock | 763 +++++++++--------- 6 files changed, 406 insertions(+), 375 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index 1b940b52e2..adbc37edeb 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -23,6 +23,7 @@ "@cosmjs/encoding": "^0.32.0", "@cosmjs/math": "^0.26.2", "@cosmjs/stargate": "^0.32.0", + "@cosmjs/tendermint-rpc": "^0.32.0", "@cosmos-kit/keplr": "^2.4.7", "@cosmos-kit/react": "^2.9.6", "@emotion/react": "^11.4.1", @@ -43,6 +44,7 @@ "bs58": "^5.0.0", "buffer": "^6.0.3", "chain-registry": "^1.19.0", + "cosmjs-types": "^0.9.0", "d3-scale": "^4.0.0", "date-fns": "^2.24.0", "i18n-iso-countries": "^6.8.0", diff --git a/explorer/src/components/Delegations/components/ErrorModal.tsx b/explorer/src/components/Delegations/components/ErrorModal.tsx index 9d375051e2..b9218d1e1e 100644 --- a/explorer/src/components/Delegations/components/ErrorModal.tsx +++ b/explorer/src/components/Delegations/components/ErrorModal.tsx @@ -12,7 +12,7 @@ export const ErrorModal: FCWithChildren<{ children?: React.ReactNode; }> = ({ children, open, title, message, sx, backdropProps, onClose }) => ( - + theme.palette.error.main} mb={1}> {title || 'Oh no! Something went wrong...'} diff --git a/explorer/src/components/Delegations/components/LoadingModal.tsx b/explorer/src/components/Delegations/components/LoadingModal.tsx index c47574efe3..eda13938d4 100644 --- a/explorer/src/components/Delegations/components/LoadingModal.tsx +++ b/explorer/src/components/Delegations/components/LoadingModal.tsx @@ -8,7 +8,7 @@ export const LoadingModal: FCWithChildren<{ backdropProps?: object; }> = ({ sx, text = 'Please wait...' }) => ( - + {text} diff --git a/explorer/src/components/Delegations/components/SimpleModal.tsx b/explorer/src/components/Delegations/components/SimpleModal.tsx index b69b3ce554..76e3b1751d 100644 --- a/explorer/src/components/Delegations/components/SimpleModal.tsx +++ b/explorer/src/components/Delegations/components/SimpleModal.tsx @@ -6,16 +6,17 @@ import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; import { useIsMobile } from '../../../hooks/useIsMobile'; -export const modalStyle = { +export const modalStyle = (width: number | string = 600) => ({ position: 'absolute' as 'absolute', top: '50%', left: '50%', + width, transform: 'translate(-50%, -50%)', bgcolor: 'background.paper', boxShadow: 24, borderRadius: '16px', p: 4, -}; +}); export const StyledBackButton = ({ onBack, @@ -72,9 +73,10 @@ export const SimpleModal: FCWithChildren<{ children, }) => { const isMobile = useIsMobile(); + return ( - + {displayErrorIcon && } {displayInfoIcon && } diff --git a/sdk/typescript/packages/validator-client/package.json b/sdk/typescript/packages/validator-client/package.json index 399db91ff0..4a9ff69810 100644 --- a/sdk/typescript/packages/validator-client/package.json +++ b/sdk/typescript/packages/validator-client/package.json @@ -27,12 +27,12 @@ "tsc": "tsc --noEmit" }, "devDependencies": { - "@cosmjs/cosmwasm-stargate": "^0.32.0", + "@cosmjs/cosmwasm-stargate": "0.29.5", "@cosmjs/crypto": "^0.29.5", "@cosmjs/math": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "^0.32.0", + "@cosmjs/tendermint-rpc": "0.29.5", "@favware/rollup-type-bundler": "^2.0.0", "@nymproject/types": "^1.0.0", "@rollup/plugin-commonjs": "^24.0.1", diff --git a/yarn.lock b/yarn.lock index c57a5db684..8795713d04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1315,15 +1315,15 @@ "@cosmjs/math" "^0.29.5" "@cosmjs/utils" "^0.29.5" -"@cosmjs/amino@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.0.tgz#1121b73f7d7c5287a599fde1194c8f78af0c0cb5" - integrity sha512-i1ehEZLQo8HUGY78eum+1ZrDQ48QSkHKy0zOTBOMqce6TiwACIC5kOjRSOWdRQDILcPFzPVrbS2dIgtrdd0ykg== +"@cosmjs/amino@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.1.tgz#412ea151ee064757d8c8746f8a8975dc73ee175f" + integrity sha512-5l2xQ2XuAhV/B3kTIMPBcVZ/OQ+9Yyddzw/lIVs4qE5e/oBI0PVNWXw1oyR0wgfGHrMUxgKjsoOOqE2IbXVyCw== dependencies: - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/crypto" "^0.32.1" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/utils" "^0.32.1" "@cosmjs/cosmwasm-launchpad@^0.25.6": version "0.25.6" @@ -1337,6 +1337,23 @@ "@cosmjs/utils" "^0.25.6" pako "^2.0.2" +"@cosmjs/cosmwasm-stargate@0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" + integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== + dependencies: + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stargate" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + pako "^2.0.2" + "@cosmjs/cosmwasm-stargate@^0.25.5": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.25.6.tgz#26a788213833aaffc4bc1a87df650741e0b8fd63" @@ -1356,18 +1373,18 @@ protobufjs "~6.10.2" "@cosmjs/cosmwasm-stargate@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.0.tgz#b35bd57edf9aac9008990b366bfad9ece35d71b1" - integrity sha512-XcCedSMNV5/choH3JCXAiwytBq0uqGI2k5tzifjUifnwd4v58hVA4NUIxUaXk4nWJ5Izd8iylCSmR2owH77Eqw== + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.1.tgz#2210007320c3f68a73e8cf8b9344a9dc6d4729b7" + integrity sha512-OWSg63RBoSnqAkzmGuKrGGibjMd/aX3BkinZ8Zg8ngMIiYftEkrlsIXhaZ5xPcAWTDWc6PK8Qzvfn5yaA24rTA== dependencies: - "@cosmjs/amino" "^0.32.0" - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/proto-signing" "^0.32.0" - "@cosmjs/stargate" "^0.32.0" - "@cosmjs/tendermint-rpc" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/amino" "^0.32.1" + "@cosmjs/crypto" "^0.32.1" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/proto-signing" "^0.32.1" + "@cosmjs/stargate" "^0.32.1" + "@cosmjs/tendermint-rpc" "^0.32.1" + "@cosmjs/utils" "^0.32.1" cosmjs-types "^0.9.0" pako "^2.0.2" @@ -1400,14 +1417,14 @@ elliptic "^6.5.4" libsodium-wrappers "^0.7.6" -"@cosmjs/crypto@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.0.tgz#61de86e158932321aa4f7a49ff09d726a57c33af" - integrity sha512-h8Fuff9QtHeHAZXB8Mjpk8sYQSqOd484GtD1NAJRCqfXifanNUeZOaXAQkcHbA0eg/IYa+ev7+gOPxm9HkSshQ== +"@cosmjs/crypto@^0.32.0", "@cosmjs/crypto@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.1.tgz#81202a10cbd36394a390454d954d782482537a5b" + integrity sha512-AsKucEg5o8evU0wXF/lDwX+ZSwCKF4bbc57nFzraHywlp3sNu4dfPPURoMrT0r7kT7wQZAy4Pdnvmm9nnCCm/Q== dependencies: - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/utils" "^0.32.1" "@noble/hashes" "^1" bn.js "^5.2.0" elliptic "^6.5.4" @@ -1431,10 +1448,10 @@ bech32 "^1.1.4" readonly-date "^1.0.0" -"@cosmjs/encoding@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.0.tgz#1b6f5b7e3f4c8c01c7863202e7eb0de9ad91a252" - integrity sha512-dlurY3BOnv/5JTz3ziGPxvJAsfaXHcOpYP+Fqwo2OHGoWxpQJgJub4QG5V530ZQHliX+6Wqp97lFEwstpISedg== +"@cosmjs/encoding@^0.32.0", "@cosmjs/encoding@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.1.tgz#1755c96e063bebef07a3f2d32971e90fb9ea4e3a" + integrity sha512-x60Lfds+Eq42rVV29NaoIAson3kBhATBI3zPp7X3GJTryBc5HFHQ6L/976tE1WB2DrvkfUdWS3ayCMVOY/qm1g== dependencies: base64-js "^1.3.0" bech32 "^1.1.4" @@ -1456,12 +1473,12 @@ "@cosmjs/stream" "^0.29.5" xstream "^11.14.0" -"@cosmjs/json-rpc@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.0.tgz#733548f54db7cdc581d56e7e0e3d6a0b6ff42163" - integrity sha512-BhnPvgbNPjQZnpzstn6+uLGsP2E4IwREbP7L95yTid+IdTrdnFcF8Ol6xXBWsUtVHtUibX+rbK3wSSgEAV0OBA== +"@cosmjs/json-rpc@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.1.tgz#0f816943e36a8e8079587180ed099cacb361fd90" + integrity sha512-Hsj3Sg+m/JF8qfISp/G4TXQ0FAO01mzDKtNcgKufIHCrvJNDiE69xGyGgSm/qKwsXLBmzRTSxHWK0+yZef3LNQ== dependencies: - "@cosmjs/stream" "^0.32.0" + "@cosmjs/stream" "^0.32.1" xstream "^11.14.0" "@cosmjs/launchpad@^0.25.6": @@ -1498,10 +1515,10 @@ dependencies: bn.js "^5.2.0" -"@cosmjs/math@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.0.tgz#71f960d59813e49d9736674c5ce40b7b63ee0cf4" - integrity sha512-3h12ENHm1B2TuzZY0JrjGyShIkdUAJDmb/xnSPBBJYZH6ZWL4DFLkq2gISq8XSVCBhuNVv4R+cSCdXs8/vSUTw== +"@cosmjs/math@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.1.tgz#e748b1f8bb20a927f5fe8311615911ed63c7334e" + integrity sha512-sqJgDjPh49rxe06apzwKYLxAw4LLFKmEd4yQtHqH16BxVVUrvK5UH9TEBpUrRErdjqENowekecDCDBZspGXHNA== dependencies: bn.js "^5.2.0" @@ -1527,16 +1544,16 @@ cosmjs-types "^0.5.2" long "^4.0.0" -"@cosmjs/proto-signing@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.0.tgz#3f182552257b68d040d945913356c399281df0ce" - integrity sha512-9401CI0U5rvKMmYrEN4DAl7wvRd5PwfOTPgxoee+O0d3LzK4FUbTjnNIM7DeUi0zaQw/qU3vSbA3ZcMqPifSbQ== +"@cosmjs/proto-signing@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.1.tgz#39de3c1758b2e3ae862d77fe4cb80b1dd6bc229f" + integrity sha512-IHJMXQ8XnfzR5K1hWb8VV/jEfJof6BL2mgGIA7X4hSPegwoVfb9hnFKPEPgFjGCTTvGZ8SfnCdXxpsOjianVIA== dependencies: - "@cosmjs/amino" "^0.32.0" - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/amino" "^0.32.1" + "@cosmjs/crypto" "^0.32.1" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/utils" "^0.32.1" cosmjs-types "^0.9.0" "@cosmjs/socket@^0.25.6": @@ -1559,12 +1576,12 @@ ws "^7" xstream "^11.14.0" -"@cosmjs/socket@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.0.tgz#45bfaa45ae89347e5134cf115fdf2dc680559207" - integrity sha512-fzb9pBJ6RNYdMIpjCv6NHdQ7C9xSJvP0tF/Tfmmq0yexxl/xDkqSghaDub/os7QzN23RHjTreWjrz9Gov4Z5Vg== +"@cosmjs/socket@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.1.tgz#a8d45cde9944646f2da930d55e4269bc411b694e" + integrity sha512-thPCLCmnCuZvrsDW4YmsADI/MliOXWuMnflbzX+3OhoTuEav2I4/1aOXY0jdy0bbqL0l1opx+JfmwdWptMgKzg== dependencies: - "@cosmjs/stream" "^0.32.0" + "@cosmjs/stream" "^0.32.1" isomorphic-ws "^4.0.1" ws "^7" xstream "^11.14.0" @@ -1603,19 +1620,19 @@ protobufjs "~6.11.3" xstream "^11.14.0" -"@cosmjs/stargate@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.0.tgz#2f1e1af50ad3156747e377a350b39673c664d324" - integrity sha512-Yo3l+A4vdy3ql30cIanY/j2uD3zxRXTQPrn2YUc67qCxacFkf7Fn3N9GdI7D/B2LQlguf/B5OwheizzWucapkw== +"@cosmjs/stargate@^0.32.0", "@cosmjs/stargate@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.1.tgz#c4e3a4b6847ef45c26275e64f4668274cae01f9c" + integrity sha512-S0E1qKQ2CMJU79G8bQTquTyrbU03gFsvCkbo3RvK8v2OltVCByjFNh+0nGN5do+uDOzwwmDvnNLhR+SaIyNQoQ== dependencies: "@confio/ics23" "^0.6.8" - "@cosmjs/amino" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/proto-signing" "^0.32.0" - "@cosmjs/stream" "^0.32.0" - "@cosmjs/tendermint-rpc" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/amino" "^0.32.1" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/proto-signing" "^0.32.1" + "@cosmjs/stream" "^0.32.1" + "@cosmjs/tendermint-rpc" "^0.32.1" + "@cosmjs/utils" "^0.32.1" cosmjs-types "^0.9.0" xstream "^11.14.0" @@ -1633,13 +1650,29 @@ dependencies: xstream "^11.14.0" -"@cosmjs/stream@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.0.tgz#4fba49708172dffc41a37bbf63f69c8c3186330a" - integrity sha512-df3Svup2QwVr6EqmOzv3KTL0sOxN2sKvz4XJItUeDDxXbcEtTB0+kypmsRQihpXCCmetNArdnvbvkPWxsKCq0w== +"@cosmjs/stream@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.1.tgz#bab72498a0a146ba172fb155fb7c38fb9bc16c6f" + integrity sha512-6RwHaGxWbIG0y++aCYP/doa4ex/Up8Q8G+ehwDzAq3aKl3zbDe9L0FmycclnMuwPm/baPIkEZ6+IVmJoNLX79Q== dependencies: xstream "^11.14.0" +"@cosmjs/tendermint-rpc@0.29.5", "@cosmjs/tendermint-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" + integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/json-rpc" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/socket" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + axios "^0.21.2" + readonly-date "^1.0.0" + xstream "^11.14.0" + "@cosmjs/tendermint-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" @@ -1655,34 +1688,18 @@ readonly-date "^1.0.0" xstream "^11.14.0" -"@cosmjs/tendermint-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" - integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== +"@cosmjs/tendermint-rpc@^0.32.0", "@cosmjs/tendermint-rpc@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.1.tgz#f7f8929619648fb0520047c6d930dc65588345d2" + integrity sha512-4uGSxB2JejWhwBUgxca4GqcK/BGnCFMIP7ptwEledrC3AY/shPeIYcPXWEBwO7sfwCta8DhAOCLrc9zhVC+VAQ== dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/json-rpc" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/socket" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - axios "^0.21.2" - readonly-date "^1.0.0" - xstream "^11.14.0" - -"@cosmjs/tendermint-rpc@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.0.tgz#9acf9030ae20631679dfbaa0611ba618ffe3d192" - integrity sha512-bGH3C0CymIzkROltbqw1iXOEkXJkpjdngJu3hdCdB7bD9xbCWOqB9mT+aLpjNAkzSEAHR4nrWv1JF+3PU2Eggg== - dependencies: - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/json-rpc" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/socket" "^0.32.0" - "@cosmjs/stream" "^0.32.0" - "@cosmjs/utils" "^0.32.0" + "@cosmjs/crypto" "^0.32.1" + "@cosmjs/encoding" "^0.32.1" + "@cosmjs/json-rpc" "^0.32.1" + "@cosmjs/math" "^0.32.1" + "@cosmjs/socket" "^0.32.1" + "@cosmjs/stream" "^0.32.1" + "@cosmjs/utils" "^0.32.1" axios "^1.6.0" readonly-date "^1.0.0" xstream "^11.14.0" @@ -1697,10 +1714,10 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== -"@cosmjs/utils@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.0.tgz#128c0d672a289c99239502d06f045e7cdb60f45e" - integrity sha512-9EWhdTtpaNBSDf2i8nwkWWHfgXGumTVAQe4KuC/R0p3A842MiZhpMAU1WxaZkEO0fcvTbfnM/svAIMVcilDtkw== +"@cosmjs/utils@^0.32.1": + version "0.32.1" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.1.tgz#0f7f7cbbe38c4a7fd852e698bad4d811fba5f80a" + integrity sha512-PV9pa0cVPFCNgfQKEOc6RcNFHr5wMQLcDqWoo/ekIoj1AfzAaqnojdnL80u1C9Qf+vOfRGIXubqiU7Tl7QZuig== "@cosmos-kit/core@^2.7.7": version "2.7.7" @@ -1959,10 +1976,10 @@ minimatch "^3.0.4" strip-json-comments "^3.1.1" -"@eslint/eslintrc@^2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" - integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== +"@eslint/eslintrc@^2.1.4": + version "2.1.4" + resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.4.tgz#388a269f0f25c1b6adc317b5a2c55714894c70ad" + integrity sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ== dependencies: ajv "^6.12.4" debug "^4.3.2" @@ -1974,10 +1991,10 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.54.0": - version "8.54.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" - integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== +"@eslint/js@8.55.0": + version "8.55.0" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.55.0.tgz#b721d52060f369aa259cf97392403cb9ce892ec6" + integrity sha512-qQfo2mxH5yVom1kacMtZZJFVdW+E70mqHMJvVg6WTLo+VBuQJ4TojZlfWBjK0ve5BdEeNAVxOsl/nvNMpJOaJA== "@ethersproject/address@^5.6.0": version "5.7.0" @@ -2046,9 +2063,9 @@ typescript "^4.8.4" "@floating-ui/core@^1.4.2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" - integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== + version "1.5.1" + resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.1.tgz#62707d7ec585d0929f882321a1b1f4ea9c680da5" + integrity sha512-QgcKYwzcc8vvZ4n/5uklchy8KVdjJwcOeI+HnnTNclJjs2nYsy23DOCf+sSV1kBwD9yDAoVKCkv/gEPzgQU3Pw== dependencies: "@floating-ui/utils" "^0.1.3" @@ -2186,9 +2203,9 @@ integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== "@interchain-ui/react@^1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.14.2.tgz#2881eff57ce5988abecc4b7205bc2fad121d9c24" - integrity sha512-YA3Dkq4FOUOcKHoH8iTqozowo5VisaT4iPffkGnxkkShlMY/NwC5V4q5WbdkNaefKmlIoUJDKle/Pyx9UL4iyw== + version "1.14.3" + resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.14.3.tgz#f4765310b684853ad7c87b78ef84e49b3fcdf9dd" + integrity sha512-SPwxIVYQL86LW7gSibJIxU42fTnMyEdJo6LBzejwX4jMvyIPqk7s5G5nUKV7xcfP4NqPciCIAo+jxLJa1R62KA== dependencies: "@fastify/deepmerge" "^1.3.0" "@floating-ui/dom" "^1.5.2" @@ -2803,23 +2820,23 @@ call-me-maybe "^1.0.1" glob-to-regexp "^0.3.0" -"@mui/base@5.0.0-beta.25": - version "5.0.0-beta.25" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.25.tgz#e1bc39f7a2daa9851fa8d0774ae6d89f0453bdc3" - integrity sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg== +"@mui/base@5.0.0-beta.26": + version "5.0.0-beta.26" + resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.26.tgz#5fab6062238dc17dd840bf1a17ab759370452713" + integrity sha512-gPMRKC84VRw+tjqYoyBzyrBUqHQucMXdlBpYazHa5rCXrb91fYEQk5SqQ2U5kjxx9QxZxTBvWAmZ6DblIgaGhQ== dependencies: "@babel/runtime" "^7.23.4" "@floating-ui/react-dom" "^2.0.4" "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" "@popperjs/core" "^2.11.8" clsx "^2.0.0" prop-types "^15.8.1" -"@mui/core-downloads-tracker@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.19.tgz#9c04ad047c378d857d529ef9c535b60a10b9a47c" - integrity sha512-y4JseIen5pmZs1n9hHy95HKKioKco8f6N2lford2AmjJigVJOv0KsU0qryiCpyuEUZmi/xCduVilHsK9DSkPcA== +"@mui/core-downloads-tracker@^5.14.20": + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.20.tgz#c9ce5ccfcc7972d3bc1623440e041e0a01386626" + integrity sha512-fXoGe8VOrIYajqALysFuyal1q1YmBARqJ3tmnWYDVl0scu8f6h6tZQbS2K8BY28QwkWNGyv4WRfuUkzN5HR3Ow== "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": version "5.14.19" @@ -2829,29 +2846,29 @@ "@babel/runtime" "^7.23.4" "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.154" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.154.tgz#c352e164e9f0313317dd8dc1bfd17236fbefbbc8" - integrity sha512-Rrhu8eUknjV6hhPMqq52e/p4/c6rvnu/k0AhysuljsHDZcHThYEZNe1mHFLveQ1RIje2VnJSsgmcNfcZKeOOAg== + version "5.0.0-alpha.155" + resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.155.tgz#db9cd4815954f237541ba5aae7c7d61d92a4edae" + integrity sha512-9mE929QFToQnSghSwvcy3Yeg+Pkj2WnR6z9OP871JiqFDL80b6OaLg2qyUt4zTFhbiBwUyBTJQ9XFrkFIibLHw== dependencies: "@babel/runtime" "^7.23.4" - "@mui/base" "5.0.0-beta.25" - "@mui/system" "^5.14.19" + "@mui/base" "5.0.0-beta.26" + "@mui/system" "^5.14.20" "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" clsx "^2.0.0" prop-types "^15.8.1" "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.19.tgz#6b81f6248da04ee73f935a79d81e7819c7115089" - integrity sha512-jSPLXst/YPgDGolhiu4rbethKjLVrI1IkoK8YrFUv8ygxDuhQdsE6+ZqjSSRXk3ytTMf6ghPnQ88OFRk4XjpNw== + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.20.tgz#d9834187838011642779c57bbdd989275ef37b6d" + integrity sha512-SUcPZnN6e0h1AtrDktEl76Dsyo/7pyEUQ+SAVe9XhHg/iliA0b4Vo+Eg4HbNkELsMbpDsUF4WHp7rgflPG7qYQ== dependencies: "@babel/runtime" "^7.23.4" - "@mui/base" "5.0.0-beta.25" - "@mui/core-downloads-tracker" "^5.14.19" - "@mui/system" "^5.14.19" + "@mui/base" "5.0.0-beta.26" + "@mui/core-downloads-tracker" "^5.14.20" + "@mui/system" "^5.14.20" "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" "@types/react-transition-group" "^4.4.9" clsx "^2.0.0" csstype "^3.1.2" @@ -2859,19 +2876,19 @@ react-is "^18.2.0" react-transition-group "^4.4.5" -"@mui/private-theming@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.19.tgz#f3bae7377f987dc5f40d0c43163ae1ed1f892961" - integrity sha512-U9w39VpXLGVM8wZlUU/47YGTsBSk60ZQRRxQZtdqPfN1N7OVllQeN4cEKZKR8PjqqR3aYRcSciQ4dc6CttRoXQ== +"@mui/private-theming@^5.14.20": + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.20.tgz#ccb0ef60d854510585cb266780d6e37589693c40" + integrity sha512-WV560e1vhs2IHCh0pgUaWHznrcrVoW9+cDCahU1VTkuwPokWVvb71ccWQ1f8Y3tRBPPcNkU2dChkkRJChLmQlQ== dependencies: "@babel/runtime" "^7.23.4" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" prop-types "^15.8.1" "@mui/styled-engine@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.19.tgz#dee1d16044a5ef3a783b742381ea4348c159b013" - integrity sha512-jtj/Pyn/bS8PM7NXdFNTHWZfE3p+vItO4/HoQbUeAv3u+cnWXcTBGHHY/xdIn446lYGFDczTh1YyX8G4Ts0Rtg== + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.20.tgz#b0e80294c35d2b68548f6f655fe80127b3169d05" + integrity sha512-Vs4nGptd9wRslo9zeRkuWcZeIEp+oYbODy+fiZKqqr4CH1Gfi9fdP0Q1tGYk8OiJ2EPB/tZSAyOy62Hyp/iP7g== dependencies: "@babel/runtime" "^7.23.4" "@emotion/cache" "^11.11.0" @@ -2879,15 +2896,15 @@ prop-types "^15.8.1" "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.19.tgz#713f66a4515f2a52f965485a081d64690241c879" - integrity sha512-5yARLEJ8zPzY6zpebupK3PqDo6jQBz1s78qXnBju10toP9HT4WEydpYdm+orDAlUUxP8eVlcpK0fVwza9NwbjA== + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.20.tgz#198d9c74cf29cd2986415e0e56fefe515b27096c" + integrity sha512-6OErKSuqDTooheoyvcHY2sKSrDpYEYRR+2h9SCnhz2hU7tw0eLd+HUuK1d9YJnCaR1aMKRvmqd10gU3y0z4H1Q== dependencies: "@babel/runtime" "^7.23.4" "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.19" + "@mui/private-theming" "^5.14.20" "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" clsx "^2.0.0" csstype "^3.1.2" hoist-non-react-statics "^3.3.2" @@ -2901,16 +2918,16 @@ jss-plugin-vendor-prefixer "^10.10.0" prop-types "^15.8.1" -"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.19.tgz#f13387c60af129e4d61dfbf168fcee348ebe952a" - integrity sha512-4e3Q+2nx+vgEsd0h5ftxlZGB7XtkkPos/zWqCqnxUs1l/T70s0lF2YNrWHHdSQ7LgtBu0eQ0qweZG2pR7KwkAw== +"@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.20": + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.20.tgz#4973883279377024ca2b4c98d311ec364f01875b" + integrity sha512-jKOGtK4VfYZG5kdaryUHss4X6hzcfh0AihT8gmnkfqRtWP7xjY+vPaUhhuSeibE5sqA5wCtdY75z6ep9pxFnIg== dependencies: "@babel/runtime" "^7.23.4" - "@mui/private-theming" "^5.14.19" + "@mui/private-theming" "^5.14.20" "@mui/styled-engine" "^5.14.19" "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" + "@mui/utils" "^5.14.20" clsx "^2.0.0" csstype "^3.1.2" prop-types "^15.8.1" @@ -2920,10 +2937,10 @@ resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.10.tgz#13e3e9aa07ee6d593cfacd538e02e8e896d7a12f" integrity sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ== -"@mui/utils@^5.10.3", "@mui/utils@^5.14.19", "@mui/utils@^5.7.0": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.19.tgz#39a5846a74ba199f1a2b067ea197dc6b9c8f442f" - integrity sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ== +"@mui/utils@^5.10.3", "@mui/utils@^5.14.20", "@mui/utils@^5.7.0": + version "5.14.20" + resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.20.tgz#6d57b8ef02633fbeef51de8f74a2388cde7da8b9" + integrity sha512-Y6yL5MoFmtQml20DZnaaK1znrCEwG6/vRSzW8PKOTrzhyqKIql0FazZRUR7sA5EPASgiyKZfq0FPwISRXm5NdA== dependencies: "@babel/runtime" "^7.23.4" "@types/prop-types" "^15.7.11" @@ -4462,10 +4479,10 @@ "@react-types/overlays" "^3.8.4" "@react-types/shared" "^3.22.0" -"@remix-run/router@1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065" - integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA== +"@remix-run/router@1.13.1": + version "1.13.1" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.1.tgz#07e2a8006f23a3bc898b3f317e0a58cc8076b86e" + integrity sha512-so+DHzZKsoOcoXrILB4rqDkMDy7NLMErRdOxvzvOKb507YINKUP4Di+shbTZDhSE/pBZ+vr7XGIpcOO0VLSA+Q== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -4516,79 +4533,89 @@ picomatch "^2.3.1" "@sapphire/utilities@^3.11.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" - integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== + version "3.14.0" + resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.14.0.tgz#4181145cf3cad127009d758e1a6ceb27db3c4eca" + integrity sha512-eYlpYlaKLvxTNjD3ymxpsf4MaSHW3x6vf+DMsLdMsV235J7i66VboHb8uxNcogR/lJ7khmMhMTCtabqUhNX4bA== -"@sentry-internal/tracing@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.84.0.tgz#430da253ee5b075be4ef57f20ea842c0208bc6b0" - integrity sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ== +"@sentry-internal/feedback@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.85.0.tgz#94ef44d59a01f145895525a9bd737dc68f4c7d64" + integrity sha512-MlbIN+N8CWFJBjbqMmARe4+UPo9QRhRar0YoOfmNA2Xqk/EwXcjHWkealosHznXH7tqVbjB25QJpHtDystft/Q== dependencies: - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry/core" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" -"@sentry/browser@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.84.0.tgz#7c82470f0afbb6178f26127894e40e9ce2b1e6d6" - integrity sha512-X50TlTKY9WzAnHsYc4FYrCWgm+CdVo0h02ggmodVBUpRLUBjj+cs5Q1plov/v/XeorSwmorNEMUu/n+XZNSsrA== +"@sentry-internal/tracing@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.85.0.tgz#1b4781a61e1e43badeff826cf40abe33dd760f1d" + integrity sha512-p3YMUwkPCy2su9cm/3+7QYR4RiMI0+07DU1BZtht9NLTzY2O87/yvUbn1v2yHR3vJQTy/+7N0ud9/mPBFznRQQ== dependencies: - "@sentry-internal/tracing" "7.84.0" - "@sentry/core" "7.84.0" - "@sentry/replay" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry/core" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" -"@sentry/core@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.84.0.tgz#01d33fc452044ffd8ea57b20f60304b9cfa2b9e1" - integrity sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA== +"@sentry/browser@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.85.0.tgz#70cea7b53e22b4262f770d70e879ff1a621825de" + integrity sha512-x4sH7vTQnZQgy1U7NuN8XwhleAw7YMQitccHeC5m+kpIKGUO7w4Mdvu8rD3dnjmVmZvASpnwocAxy57/vCU6Ww== dependencies: - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry-internal/feedback" "7.85.0" + "@sentry-internal/tracing" "7.85.0" + "@sentry/core" "7.85.0" + "@sentry/replay" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" + +"@sentry/core@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.85.0.tgz#dd90d772a5f75ff674f931f59b22a3fc286d0983" + integrity sha512-DFDAc4tWmHN5IWhr7XbHCiyF1Xgb95jz8Uj/JTX9atlgodId1UIbER77qpEmH3eQGid/QBdqrlR98zCixgSbwg== + dependencies: + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" "@sentry/integrations@^7.54.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.84.0.tgz#3b016903e08f0dade74bbc152ea5605e231e39cd" - integrity sha512-aUu95BhnHSf/W/F4BvsFnf4x+piHiah5a180YTMqWcHMkJr7MnCWNIad9RJuHlcINSfyHtUr5+Z4Bajzqg60lw== + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.85.0.tgz#967b9e1718cb99d5ba324f3a854e44e46e24a1a5" + integrity sha512-c/uEhrFbAefK00cnm/SjqZ31rWVsruiQWAvV4dxU/rSQ2dBWDuJz1woXX7Wd03yCSMq14tXtiDy9aTC4xCZ71w== dependencies: - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry/core" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" localforage "^1.8.1" "@sentry/react@^7.54.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.84.0.tgz#2cb3192f7fb67b7696e8ece08d67229b193ddaa4" - integrity sha512-VQZrEHwPKCYTSbRYXD2ohXcQg99G1Hgs8eevRUuRpdChmA2e3z/RvT00NlaSNNZrS86wPyKpAK6kickB/eSYrw== + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.85.0.tgz#eb94bee7a72208081d5256d7a8001f91b7d07b7e" + integrity sha512-digw63l1A9n+74rW8uiG575Xh3qWTkmvwgTfNRFvDokDRMqRTP0iQEqZRBrBEzMZ5JUa6s+5NLc1/dbMh1QQgA== dependencies: - "@sentry/browser" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry/browser" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" hoist-non-react-statics "^3.3.2" -"@sentry/replay@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.84.0.tgz#7e17876d9a1802ee33800e2b2cbda4e026c0a2af" - integrity sha512-c4PxT0ZpvkR9zXNfmAk3ojkm6eZ9+NlDze09RFBOCNo69QwIN90hnvbjXFC1+vRIJsfgo78Zr0ya/Wzb3Rog7Q== +"@sentry/replay@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.85.0.tgz#81ad025bc85b343da71e1fb7bd7c5702690e48c8" + integrity sha512-zVtTKfO+lu5qTwHpETI/oGo8hU3rdKHr3CdI1vRLw+d60PcAa/pWVlXsQeLRTw8PFwE358gHcpFZezj/11afew== dependencies: - "@sentry-internal/tracing" "7.84.0" - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" + "@sentry-internal/tracing" "7.85.0" + "@sentry/core" "7.85.0" + "@sentry/types" "7.85.0" + "@sentry/utils" "7.85.0" -"@sentry/types@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.84.0.tgz#e8db86c36c61659c3b2558f0aa8b6a073a756117" - integrity sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA== +"@sentry/types@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.85.0.tgz#648488b90f958ca6a86922cc5d26004853410ba6" + integrity sha512-R5jR4XkK5tBU2jDiPdSVqzkmjYRr666bcGaFGUHB/xDQCjPsjk+pEmCCL+vpuWoaZmQJUE1hVU7rgnVX81w8zg== -"@sentry/utils@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.84.0.tgz#32861d922fa31e86dd2863a1d9dfc5a369e98952" - integrity sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ== +"@sentry/utils@7.85.0": + version "7.85.0" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.85.0.tgz#b84467fd07bc2ef09fdf382ddcdcdc3f5b0d78b0" + integrity sha512-JZ7seNOLvhjAQ8GeB3GYknPQJkuhF88xAYOaESZP3xPOWBMFUN+IO4RqjMqMLFDniOwsVQS7GB/MfP+hxufieg== dependencies: - "@sentry/types" "7.84.0" + "@sentry/types" "7.85.0" "@sideway/address@^4.1.3": version "4.1.4" @@ -5180,13 +5207,13 @@ ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channels@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.2.tgz#77bb8ea5bda33fc00fea30954c15f2bdc4f74a5d" - integrity sha512-pSVpnMAfMsImPyAorYPcfkZmBY34+eHmcj8Zab0m/36/M0AQrUq7VSxA+7KD3rhoZaJjioeouxqigjiznNAbZw== +"@storybook/channels@7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.3.tgz#b3e0a8d92dfd553ba582fdb5dd0c55272790d3f9" + integrity sha512-o9J0TBbFon16tUlU5V6kJgzAlsloJcS1cTHWqh3VWczohbRm+X1PLNUihJ7Q8kBWXAuuJkgBu7RQH7Ib46WyYg== dependencies: - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" + "@storybook/client-logger" "7.6.3" + "@storybook/core-events" "7.6.3" "@storybook/global" "^5.0.0" qs "^6.10.0" telejson "^7.2.0" @@ -5226,10 +5253,10 @@ core-js "^3.8.2" global "^4.4.0" -"@storybook/client-logger@7.6.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.2.tgz#4362d53e24464945fc711dcf0dcfb9b4b1c53586" - integrity sha512-9hlDm7q6jZPVBoqW8V7DTMNMsjMaL2t45h+I8veQhnC2ZW6g+lARXQQDHZpL6MKVkJn6mEA9F0nJBIknbQpqBQ== +"@storybook/client-logger@7.6.3", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.3.tgz#221d6617e6874025b94602bc7ba6bf09d154bf5f" + integrity sha512-BpsCnefrBFdxD6ukMjAblm1D6zB4U5HR1I85VWw6LOqZrfzA6l/1uBxItz0XG96HTjngbvAabWf5k7ZFCx5UCg== dependencies: "@storybook/global" "^5.0.0" @@ -5336,10 +5363,10 @@ dependencies: core-js "^3.8.2" -"@storybook/core-events@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.2.tgz#13198c8020601fd74ec4eb53852f20e7f0bd68b5" - integrity sha512-JciGNDclg3hx+WkXsAzcCBYWk0xsyIbyCAwqN7XVHUpGndR/dl97Qum5MkO9kPb8r5toKpeBOQo5Kxo2GiE0dg== +"@storybook/core-events@7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.3.tgz#55ea88f5355bd995daf9ed0287293536b3eb7091" + integrity sha512-Vu3JX1mjtR8AX84lyqWsi2s2lhD997jKRWVznI3wx+UpTk8t7TTMLFk2rGYJRjaornhrqwvLYpnmtxRSxW9BOQ== dependencies: ts-dedent "^2.0.0" @@ -5473,15 +5500,15 @@ global "^4.4.0" "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.6.2.tgz#1db5415ec268e49773cd44573baea6011b0e8c23" - integrity sha512-IQQh0troFy0naXJUc47UtqJ1Bcs4SaBBxxCMlUeJLML1w0EjBSNCB6kewTU/DfjlkFm8a7YnEwxPTEh1dZiq8w== + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.6.3.tgz#471a41ece5169879368cde79fba4e7bc66c900c9" + integrity sha512-U1cbF0tewMQtKeLinQqUM5Mpcz1z5tsKhV9xAJKguvYVxllWvCA6cVxDM5fc66ws2mXpwFDcb82Kx05lMdmEoA== dependencies: - "@storybook/channels" "7.6.2" - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" + "@storybook/channels" "7.6.3" + "@storybook/client-logger" "7.6.3" + "@storybook/core-events" "7.6.3" "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.6.2" + "@storybook/preview-api" "7.6.3" "@vitest/utils" "^0.34.6" util "^0.12.4" @@ -5599,17 +5626,17 @@ dependencies: core-js "^3.8.2" -"@storybook/preview-api@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.2.tgz#2b0158341510cfa87babaa13d8077a0741e2664d" - integrity sha512-5scmFblrBKBLQSZVlwNUCXhos8GJ8alzMSs0msAbguytjWEuNQ2EKoO7EoO3wvaYf7K3mkOg082RU9nH8SM6mg== +"@storybook/preview-api@7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.3.tgz#da8e30e5cbe1c0ca5e40af5dc01a4714c37d5af8" + integrity sha512-uPaK7yLE1P++F+IOb/1j9pgdCwfMYZrUPHogF/Mf9r4cfEjDCcIeKgGMcsbU1KnkzNQQGPh8JRzRr/iYnLjswg== dependencies: - "@storybook/channels" "7.6.2" - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" + "@storybook/channels" "7.6.3" + "@storybook/client-logger" "7.6.3" + "@storybook/core-events" "7.6.3" "@storybook/csf" "^0.1.2" "@storybook/global" "^5.0.0" - "@storybook/types" "7.6.2" + "@storybook/types" "7.6.3" "@types/qs" "^6.9.5" dequal "^2.0.2" lodash "^4.17.21" @@ -5790,12 +5817,12 @@ memoizerific "^1.11.3" regenerator-runtime "^0.13.7" -"@storybook/types@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.2.tgz#4db470df5cba3da244d979fbdaafafa45b0e0f4d" - integrity sha512-GlEkG4D/BFuPrLGpTkrfmeLM/fEki0FTnMs1SgNQL10wl6Y98EDJWvCItPVPBoGBERpShxEmkSi2HmcySWZgsA== +"@storybook/types@7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.3.tgz#cd37997cfcd349d3eb4d2c9da9eb7f334d2fb937" + integrity sha512-vj9Jzg5eR52l8O9512QywbQpNdo67Z6BQWR8QoZRcG+/Bhzt08YI8IZMPQLFMKzcmWDPK0blQ4GfyKDYplMjPA== dependencies: - "@storybook/channels" "7.6.2" + "@storybook/channels" "7.6.3" "@types/babel__core" "^7.0.0" "@types/express" "^4.7.0" file-system-cache "2.3.0" @@ -5946,71 +5973,71 @@ resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.1.tgz#9074476c4323f71351db624e9711c99277cdfb99" integrity sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA== -"@tauri-apps/cli-darwin-arm64@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.6.tgz#0d68eaf6fa1b35197a9d4991ac5377e6085a569a" - integrity sha512-NNvG3XLtciCMsBahbDNUEvq184VZmOveTGOuy0So2R33b/6FDkuWaSgWZsR1mISpOuP034htQYW0VITCLelfqg== +"@tauri-apps/cli-darwin-arm64@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.7.tgz#3435f1b6c4b431e0283f94c3a0bd486be66b24ee" + integrity sha512-eUpOUhs2IOpKaLa6RyGupP2owDLfd0q2FR/AILzryjtBtKJJRDQQvuotf+LcbEce2Nc2AHeYJIqYAsB4sw9K+g== -"@tauri-apps/cli-darwin-x64@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.6.tgz#a48e1f66b12c33cf6c9c216865f2e9a3ff18a923" - integrity sha512-nkiqmtUQw3N1j4WoVjv81q6zWuZFhBLya/RNGUL94oafORloOZoSY0uTZJAoeieb3Y1YK0rCHSDl02MyV2Fi4A== +"@tauri-apps/cli-darwin-x64@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.7.tgz#d3d646e790067158d14a1f631a50c67dc05e3360" + integrity sha512-zfumTv1xUuR+RB1pzhRy+51tB6cm8I76g0xUBaXOfEdOJ9FqW5GW2jdnEUbpNuU65qJ1lB8LVWHKGrSWWKazew== -"@tauri-apps/cli-linux-arm-gnueabihf@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.6.tgz#385cd8054be7722cc07acc2d6d86f8e20c6265ef" - integrity sha512-z6SPx+axZexmWXTIVPNs4Tg7FtvdJl9EKxYN6JPjOmDZcqA13iyqWBQal2DA/GMZ1Xqo3vyJf6EoEaKaliymPQ== +"@tauri-apps/cli-linux-arm-gnueabihf@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.7.tgz#049c12980cdfd67fe9e5163762bf77f3c85f6956" + integrity sha512-JngWNqS06bMND9PhiPWp0e+yknJJuSozsSbo+iMzHoJNRauBZCUx+HnUcygUR66Cy6qM4eJvLXtsRG7ApxvWmg== -"@tauri-apps/cli-linux-arm64-gnu@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.6.tgz#bd3f8f61637a1073909cb2d663aa0c6e8e036337" - integrity sha512-QuQjMQmpsCbzBrmtQiG4uhnfAbdFx3nzm+9LtqjuZlurc12+Mj5MTgqQ3AOwQedH3f7C+KlvbqD2AdXpwTg7VA== +"@tauri-apps/cli-linux-arm64-gnu@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.7.tgz#d1c143da15cba74eebfaaf1662f0734e30f97562" + integrity sha512-WyIYP9BskgBGq+kf4cLAyru8ArrxGH2eMYGBJvuNEuSaqBhbV0i1uUxvyWdazllZLAEz1WvSocUmSwLknr1+sQ== -"@tauri-apps/cli-linux-arm64-musl@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.6.tgz#77fb4a804b77447bffba725a4b8b62df45f9ff97" - integrity sha512-8j5dH3odweFeom7bRGlfzDApWVOT4jIq8/214Wl+JeiNVehouIBo9lZGeghZBH3XKFRwEvU23i7sRVjuh2s8mg== +"@tauri-apps/cli-linux-arm64-musl@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.7.tgz#f79a17f5360a8ab25b90f3a8e9e6327d5378072f" + integrity sha512-OrDpihQP2MB0JY1a/wP9wsl9dDjFDpVEZOQxt4hU+UVGRCZQok7ghPBg4+Xpd1CkNkcCCuIeY8VxRvwLXpnIzg== -"@tauri-apps/cli-linux-x64-gnu@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.6.tgz#e70a6c9dd243c2a3fa1fec69de9ebc9abf4dc795" - integrity sha512-gbFHYHfdEGW0ffk8SigDsoXks6USpilF6wR0nqB/JbWzbzFR/sBuLVNQlJl1RKNakyJHu+lsFxGy0fcTdoX8xA== +"@tauri-apps/cli-linux-x64-gnu@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.7.tgz#2cbd17998dcfc8a465d61f30ac9e99ae65e2c2e8" + integrity sha512-4T7FAYVk76rZi8VkuLpiKUAqaSxlva86C1fHm/RtmoTKwZEV+MI3vIMoVg+AwhyWIy9PS55C75nF7+OwbnFnvQ== -"@tauri-apps/cli-linux-x64-musl@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.6.tgz#f25dad778b2da6ab7b2b81f81c0805026d742c33" - integrity sha512-9v688ogoLkeFYQNgqiSErfhTreLUd8B3prIBSYUt+x4+5Kcw91zWvIh+VSxL1n3KCGGsM7cuXhkGPaxwlEh1ug== +"@tauri-apps/cli-linux-x64-musl@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.7.tgz#d5d4ddded945cc781568d72b7eba367121f28525" + integrity sha512-LL9aMK601BmQjAUDcKWtt5KvAM0xXi0iJpOjoUD3LPfr5dLvBMTflVHQDAEtuZexLQyqpU09+60781PrI/FCTw== -"@tauri-apps/cli-win32-arm64-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.6.tgz#47d0f359e04d93c1fd0b527e18a56606f3df9bed" - integrity sha512-DRNDXFNZb6y5IZrw+lhTTA9l4wbzO4TNRBAlHAiXUrH+pRFZ/ZJtv5WEuAj9ocVSahVw2NaK5Yaold4NPAxHog== +"@tauri-apps/cli-win32-arm64-msvc@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.7.tgz#05a1bd4e2bc692bad995edb9d07e616cc5682fd5" + integrity sha512-TmAdM6GVkfir3AUFsDV2gyc25kIbJeAnwT72OnmJGAECHs/t/GLP9IkFLLVcFKsiosRf8BXhVyQ84NYkSWo14w== -"@tauri-apps/cli-win32-ia32-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.6.tgz#54c7ec152065e8167068411b82748a25a483d948" - integrity sha512-oUYKNR/IZjF4fsOzRpw0xesl2lOjhsQEyWlgbpT25T83EU113Xgck9UjtI7xemNI/OPCv1tPiaM1e7/ABdg5iA== +"@tauri-apps/cli-win32-ia32-msvc@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.7.tgz#8c832f4dc88374255ef1cda4d2d6a6d61a921388" + integrity sha512-bqWfxwCfLmrfZy69sEU19KHm5TFEaMb8KIekd4aRq/kyOlrjKLdZxN1PyNRP8zpJA1lTiRHzfUDfhpmnZH/skg== -"@tauri-apps/cli-win32-x64-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.6.tgz#963280a4f7001c27d4e4745f302728297c007deb" - integrity sha512-RmEf1os9C8//uq2hbjXi7Vgz9ne7798ZxqemAZdUwo1pv3oLVZSz1/IvZmUHPdy2e6zSeySqWu1D0Y3QRNN+dg== +"@tauri-apps/cli-win32-x64-msvc@1.5.7": + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.7.tgz#adfcce46f796dd22ef69fb26ad8c6972a3263985" + integrity sha512-OxLHVBNdzyQ//xT3kwjQFnJTn/N5zta/9fofAkXfnL7vqmVn6s/RY1LDa3sxCHlRaKw0n3ShpygRbM9M8+sO9w== "@tauri-apps/cli@^1.0.5", "@tauri-apps/cli@^1.2.2": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.5.6.tgz#5011c9dd3a36dc89073fed7d4cb429d38b37862b" - integrity sha512-k4Y19oVCnt7WZb2TnDzLqfs7o98Jq0tUoVMv+JQSzuRDJqaVu2xMBZ8dYplEn+EccdR5SOMyzaLBJWu38TVK1A== + version "1.5.7" + resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.5.7.tgz#8f9a8bf577a39b7f7c0e5b125e7b5b3e149cfb5a" + integrity sha512-z7nXLpDAYfQqR5pYhQlWOr88DgPq1AfQyxHhGiakiVgWlaG0ikEfQxop2txrd52H0TRADG0JHR9vFrVFPv4hVQ== optionalDependencies: - "@tauri-apps/cli-darwin-arm64" "1.5.6" - "@tauri-apps/cli-darwin-x64" "1.5.6" - "@tauri-apps/cli-linux-arm-gnueabihf" "1.5.6" - "@tauri-apps/cli-linux-arm64-gnu" "1.5.6" - "@tauri-apps/cli-linux-arm64-musl" "1.5.6" - "@tauri-apps/cli-linux-x64-gnu" "1.5.6" - "@tauri-apps/cli-linux-x64-musl" "1.5.6" - "@tauri-apps/cli-win32-arm64-msvc" "1.5.6" - "@tauri-apps/cli-win32-ia32-msvc" "1.5.6" - "@tauri-apps/cli-win32-x64-msvc" "1.5.6" + "@tauri-apps/cli-darwin-arm64" "1.5.7" + "@tauri-apps/cli-darwin-x64" "1.5.7" + "@tauri-apps/cli-linux-arm-gnueabihf" "1.5.7" + "@tauri-apps/cli-linux-arm64-gnu" "1.5.7" + "@tauri-apps/cli-linux-arm64-musl" "1.5.7" + "@tauri-apps/cli-linux-x64-gnu" "1.5.7" + "@tauri-apps/cli-linux-x64-musl" "1.5.7" + "@tauri-apps/cli-win32-arm64-msvc" "1.5.7" + "@tauri-apps/cli-win32-ia32-msvc" "1.5.7" + "@tauri-apps/cli-win32-x64-msvc" "1.5.7" "@tauri-apps/tauri-forage@^1.0.0-beta.2": version "1.0.0-beta.2" @@ -6557,9 +6584,9 @@ "@types/node" "*" "@types/node@*", "@types/node@>=13.7.0": - version "20.10.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.1.tgz#d2c96f356c3125fedc983d74c424910c3767141c" - integrity sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg== + version "20.10.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.3.tgz#4900adcc7fc189d5af5bb41da8f543cea6962030" + integrity sha512-XJavIpZqiXID5Yxnxv3RUDKTN5b81ddNC3ecsA0SoFXz/QU8OGBwZGMomiq0zw+uuqbL/krztv/DINAQ/EV4gg== dependencies: undici-types "~5.26.4" @@ -6574,9 +6601,9 @@ integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.66.tgz#f59cc2ff96cc47f972a11a458a9b29bf0a209c34" - integrity sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw== + version "16.18.67" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.67.tgz#518feb681958dedf2d187b8b4d20bf3530afe1fb" + integrity sha512-gUa0tDO9oxyAYO9V9tqxDJguVMDpqUwH5I5Q9ASYBCso+8CUdJlKPKDYS1YSS9kyZWIduDafZvucGM0zGNKFjg== "@types/normalize-package-data@^2.4.0": version "2.4.4" @@ -6671,9 +6698,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.0.26": - version "18.2.39" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.39.tgz#744bee99e053ad61fe74eb8b897f3ab5b19a7e25" - integrity sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA== + version "18.2.42" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.42.tgz#6f6b11a904f6d96dda3c2920328a97011a00aba7" + integrity sha512-c1zEr96MjakLYus/wPnuWDo1/zErfdU9rNsIGmE+NV71nx88FG9Ttgo5dqorXTu/LImX2f63WBP986gJkMPNbA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -6988,9 +7015,9 @@ integrity sha512-7dCuBgPQQ/89siQ0w2lkfjgkmToPUUDzFlHf5DRmt9ykiiycfA52tmPJ2RI/mr7jXi7U/vEN2aGP9QJSXEpGlA== "@vitest/utils@^0.34.6": - version "0.34.6" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968" - integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A== + version "0.34.7" + resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.7.tgz#46d0d27cd0f6ca1894257d4e141c5c48d7f50295" + integrity sha512-ziAavQLpCYS9sLOorGrFFKmy2gnfiNU0ZJ15TsMz/K92NAPS/rp9K4z6AJQQk5Y8adCy4Iwpxy7pQumQ/psnRg== dependencies: diff-sequences "^29.4.3" loupe "^2.3.6" @@ -8645,13 +8672,13 @@ browserify-zlib@^0.2.0: pako "~1.0.5" browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== + version "4.22.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.2.tgz#704c4943072bd81ea18997f3bd2180e89c77874b" + integrity sha512-0UgcrvQmBDvZHFGdYUehrCNIazki7/lUP3kkoi/r3YB2amZbFM9J43ZRkJTXBUZK4gmx56+Sqk9+Vs9mwZx9+A== dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" + caniuse-lite "^1.0.30001565" + electron-to-chromium "^1.4.601" + node-releases "^2.0.14" update-browserslist-db "^1.0.13" bs-logger@0.x: @@ -8957,10 +8984,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001565" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz#a528b253c8a2d95d2b415e11d8b9942acc100c4f" - integrity sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001565: + version "1.0.30001566" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001566.tgz#61a8e17caf3752e3e426d4239c549ebbb37fef0d" + integrity sha512-ggIhCsTxmITBAMmK8yZjEhCO5/47jKXPu6Dha/wuCS4JePVL+3uiDEBuhu2aIoT+bqTOR8L76Ip1ARL9xYsEJA== capture-exit@^2.0.0: version "2.0.0" @@ -10827,10 +10854,10 @@ ejs@^3.1.7: dependencies: jake "^10.8.5" -electron-to-chromium@^1.4.535: - version "1.4.598" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.598.tgz#aaf1f64286001915b59210158d21b6284e96acbc" - integrity sha512-0JnipX0scPUlwsptQVCZggoCpREv+IrVD3h0ZG+sldmK9L27tSV3QjV8+QdaA4qQTzDf3PluNS45YYJky1oASw== +electron-to-chromium@^1.4.601: + version "1.4.603" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.603.tgz#446907c21d333b55d0beaba1cb5b48430775a8a7" + integrity sha512-Dvo5OGjnl7AZTU632dFJtWj0uJK835eeOVQIuRcmBmsFsTNn3cL05FqOyHAfGQDIoHfLhyJ1Tya3PJ0ceMz54g== elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: version "6.5.4" @@ -11395,14 +11422,14 @@ eslint@^7.18.0: v8-compile-cache "^2.0.3" eslint@^8.10.0: - version "8.54.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" - integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== + version "8.55.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.55.0.tgz#078cb7b847d66f2c254ea1794fa395bf8e7e03f8" + integrity sha512-iyUUAM0PCKj5QpwGfmCAG9XXbZCWsqP/eWAWrG/W0umvjuLRBECwSFdt+rCntju0xEH7teIABPwXpahftIaTdA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.54.0" + "@eslint/eslintrc" "^2.1.4" + "@eslint/js" "8.55.0" "@humanwhocodes/config-array" "^0.11.13" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" @@ -16602,7 +16629,7 @@ nanoid@3.3.3: resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== -nanoid@^3.3.1, nanoid@^3.3.6: +nanoid@^3.3.1, nanoid@^3.3.7: version "3.3.7" resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== @@ -16673,9 +16700,9 @@ no-case@^3.0.4: tslib "^2.0.3" node-abi@^3.3.0: - version "3.51.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" - integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== + version "3.52.0" + resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.52.0.tgz#ffba0a85f54e552547e5849015f40f9514d5ba7c" + integrity sha512-JJ98b02z16ILv7859irtXn4oUaFWADtvkzy2c0IAatNVX2Mc9Yoh8z6hZInn3QwvMEYhHuQloYi+TTQy67SIdQ== dependencies: semver "^7.3.5" @@ -16796,10 +16823,10 @@ node-machine-id@1.1.12: resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== -node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== +node-releases@^2.0.14: + version "2.0.14" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.14.tgz#2ffb053bceb8b2be8495ece1ab6ce600c4461b0b" + integrity sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw== nodemon@^2.0.21: version "2.0.22" @@ -18194,11 +18221,11 @@ postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0 source-map "^0.6.1" postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.21: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== + version "8.4.32" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.32.tgz#1dac6ac51ab19adb21b8b34fd2d93a86440ef6c9" + integrity sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw== dependencies: - nanoid "^3.3.6" + nanoid "^3.3.7" picocolors "^1.0.0" source-map-js "^1.0.2" @@ -18842,19 +18869,19 @@ react-refresh@^0.11.0: integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== react-router-dom@6, react-router-dom@^6.7.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b" - integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ== + version "6.20.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.1.tgz#e34f8075b9304221420de3609e072bb349824984" + integrity sha512-npzfPWcxfQN35psS7rJgi/EW0Gx6EsNjfdJSAk73U/HqMEJZ2k/8puxfwHFgDQhBGmS3+sjnGbMdMSV45axPQw== dependencies: - "@remix-run/router" "1.13.0" - react-router "6.20.0" + "@remix-run/router" "1.13.1" + react-router "6.20.1" -react-router@6.20.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539" - integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w== +react-router@6.20.1: + version "6.20.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.1.tgz#e8cc326031d235aaeec405bb234af77cf0fe75ef" + integrity sha512-ccvLrB4QeT5DlaxSFFYi/KR8UMQ4fcD8zBcR71Zp1kaYTC5oJKYAp1cbavzGrogwxca+ubjkd7XjFZKBW8CxPA== dependencies: - "@remix-run/router" "1.13.0" + "@remix-run/router" "1.13.1" react-simple-maps@^2.3.0: version "2.3.0" @@ -18904,9 +18931,9 @@ react-stately@^3.27.1: "@react-types/shared" "^3.22.0" react-tooltip@*: - version "5.24.0" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.24.0.tgz#c134e4c00d49a111986711696bcd9abf672caff6" - integrity sha512-HjstgpOrUwP4eN6mHU4EThpbxVuKO5SvqumRt1aAcPq0ya+pIVVxlwltndtdIIMBJ7w3jnN05vNfcfh2sxE2mQ== + version "5.25.0" + resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.25.0.tgz#09d259c041bca1908449ac27b39717162655e0e3" + integrity sha512-/eGhmlwbHlJrVoUe75fb58rJfAy9aZnTvQAK9ZUPM0n9mmBGpEk13vDPiQVCeUuax+fBej+7JPsUXlhzaySc7w== dependencies: "@floating-ui/dom" "^1.0.0" classnames "^2.3.0" @@ -19085,9 +19112,9 @@ recharts-scale@^0.4.4: decimal.js-light "^2.4.1" recharts@^2.1.13: - version "2.10.2" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.2.tgz#919e9ccba463c7face91438c807340f300435e55" - integrity sha512-goasBqGqpH8SLty+a24xG1KkZWowo793mgoNVrOkBRXZCG2xX+BUbCgaWrB/G+DGIpN2AX/arCttLuHdg/A6LQ== + version "2.10.3" + resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.3.tgz#a5dbe219354d744701e8bbd116fe42393af92f6b" + integrity sha512-G4J96fKTZdfFQd6aQnZjo2nVNdXhp+uuLb00+cBTGLo85pChvm1+E67K3wBOHDE/77spcYb2Cy9gYWVqiZvQCg== dependencies: clsx "^2.0.0" eventemitter3 "^4.0.1" @@ -20342,9 +20369,9 @@ statuses@2.0.1: integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== std-env@^3.4.3: - version "3.5.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" - integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== + version "3.6.0" + resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.6.0.tgz#94807562bddc68fa90f2e02c5fd5b6865bb4e98e" + integrity sha512-aFZ19IgVmhdB2uX599ve2kE6BIE3YMnQ6Gp6BURhW/oIzpXGKr878TQfAQZn1+i0Flcc/UKUy1gOlcfaUBCryg== stop-iteration-iterator@^1.0.0: version "1.0.0" @@ -20903,9 +20930,9 @@ terser@^4.1.2, terser@^4.6.3: source-map-support "~0.5.12" terser@^5.10.0, terser@^5.16.8, terser@^5.3.4: - version "5.24.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" - integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== + version "5.25.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.25.0.tgz#6579b4cca45b08bf0fdaa1a04605fd5860dfb2ac" + integrity sha512-we0I9SIsfvNUMP77zC9HG+MylwYYsGFSBG8qm+13oud2Yh+O104y614FRbyjpxys16jZwot72Fpi827YvGzuqg== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" From 96a42fa03dc6739b38d2e1d0ee5fcec2d543fc79 Mon Sep 17 00:00:00 2001 From: fmtabbara Date: Tue, 5 Dec 2023 15:52:11 +0000 Subject: [PATCH 131/394] Fix table layouts tidy up exports --- .../src/components/ConnectKeplrWallet.tsx | 6 +- .../{components => }/ConfirmationModal.tsx | 0 .../{components => }/DelegateIconButton.tsx | 9 +- .../{components => }/DelegateModal.tsx | 4 +- .../{components => }/DelegationModal.tsx | 0 .../{components => }/ErrorModal.tsx | 0 .../{components => }/LoadingModal.tsx | 0 .../{components => }/ModalDivider.tsx | 0 .../{components => }/ModalListItem.tsx | 0 .../{components => }/SimpleModal.tsx | 2 +- explorer/src/components/Delegations/index.ts | 10 ++ .../Delegations/{components => }/styles.ts | 0 explorer/src/components/Filters/Filters.tsx | 12 +- .../src/components/Filters/FiltersButton.tsx | 34 +++++ .../src/components/MixNodes/DetailSection.tsx | 4 +- explorer/src/components/MixNodes/index.ts | 3 + .../MixNodes/{index.tsx => mappings.ts} | 0 .../src/components/Universal-DataGrid.tsx | 4 +- explorer/src/components/index.ts | 9 ++ explorer/src/hooks/index.ts | 3 + .../src/hooks/useGetMixnodeStatusColor.ts | 17 +++ explorer/src/pages/Mixnodes/index.tsx | 116 ++++++++---------- explorer/tsconfig.json | 16 ++- .../clipboard/CopyToClipboard.stories.tsx | 7 ++ .../components/clipboard/CopyToClipboard.tsx | 5 +- 25 files changed, 161 insertions(+), 100 deletions(-) rename explorer/src/components/Delegations/{components => }/ConfirmationModal.tsx (100%) rename explorer/src/components/Delegations/{components => }/DelegateIconButton.tsx (63%) rename explorer/src/components/Delegations/{components => }/DelegateModal.tsx (98%) rename explorer/src/components/Delegations/{components => }/DelegationModal.tsx (100%) rename explorer/src/components/Delegations/{components => }/ErrorModal.tsx (100%) rename explorer/src/components/Delegations/{components => }/LoadingModal.tsx (100%) rename explorer/src/components/Delegations/{components => }/ModalDivider.tsx (100%) rename explorer/src/components/Delegations/{components => }/ModalListItem.tsx (100%) rename explorer/src/components/Delegations/{components => }/SimpleModal.tsx (98%) create mode 100644 explorer/src/components/Delegations/index.ts rename explorer/src/components/Delegations/{components => }/styles.ts (100%) create mode 100644 explorer/src/components/Filters/FiltersButton.tsx create mode 100644 explorer/src/components/MixNodes/index.ts rename explorer/src/components/MixNodes/{index.tsx => mappings.ts} (100%) create mode 100644 explorer/src/components/index.ts create mode 100644 explorer/src/hooks/index.ts create mode 100644 explorer/src/hooks/useGetMixnodeStatusColor.ts diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx index 3093463c7a..66f8cc1598 100644 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -67,7 +67,11 @@ export const ConnectKeplrWallet = () => { ); } - return ; + return ( + + ); }; return {getGlobalbutton()}; diff --git a/explorer/src/components/Delegations/components/ConfirmationModal.tsx b/explorer/src/components/Delegations/ConfirmationModal.tsx similarity index 100% rename from explorer/src/components/Delegations/components/ConfirmationModal.tsx rename to explorer/src/components/Delegations/ConfirmationModal.tsx diff --git a/explorer/src/components/Delegations/components/DelegateIconButton.tsx b/explorer/src/components/Delegations/DelegateIconButton.tsx similarity index 63% rename from explorer/src/components/Delegations/components/DelegateIconButton.tsx rename to explorer/src/components/Delegations/DelegateIconButton.tsx index b19a5587d0..80ae730c75 100644 --- a/explorer/src/components/Delegations/components/DelegateIconButton.tsx +++ b/explorer/src/components/Delegations/DelegateIconButton.tsx @@ -1,22 +1,23 @@ import * as React from 'react'; import { IconButton, Tooltip } from '@mui/material'; import { SxProps } from '@mui/system'; -import { DelegateIcon } from '../../../icons/DelevateSVG'; +import { DelegateIcon } from '../../icons/DelevateSVG'; export const DelegateIconButton: FCWithChildren<{ + size?: 'small' | 'medium'; disabled?: boolean; tooltip?: React.ReactNode; sx?: SxProps; onDelegate: () => void; -}> = ({ tooltip, onDelegate, sx, disabled }) => { +}> = ({ tooltip, onDelegate, sx, disabled, size = 'medium' }) => { const handleOnDelegate = (e: React.MouseEvent) => { e.stopPropagation(); onDelegate(); }; return ( - - + + ); diff --git a/explorer/src/components/Delegations/components/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx similarity index 98% rename from explorer/src/components/Delegations/components/DelegateModal.tsx rename to explorer/src/components/Delegations/DelegateModal.tsx index d0df90ab13..c2b0da2e0a 100644 --- a/explorer/src/components/Delegations/components/DelegateModal.tsx +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -7,8 +7,8 @@ import { useChain } from '@cosmos-kit/react'; import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; import { DelegationModalProps } from './DelegationModal'; -import { unymToNym, validateAmount } from '../../../utils/currency'; -import { urls } from '../../../utils'; +import { unymToNym, validateAmount } from '../../utils/currency'; +import { urls } from '../../utils'; const MIN_AMOUNT_TO_DELEGATE = 10; const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; diff --git a/explorer/src/components/Delegations/components/DelegationModal.tsx b/explorer/src/components/Delegations/DelegationModal.tsx similarity index 100% rename from explorer/src/components/Delegations/components/DelegationModal.tsx rename to explorer/src/components/Delegations/DelegationModal.tsx diff --git a/explorer/src/components/Delegations/components/ErrorModal.tsx b/explorer/src/components/Delegations/ErrorModal.tsx similarity index 100% rename from explorer/src/components/Delegations/components/ErrorModal.tsx rename to explorer/src/components/Delegations/ErrorModal.tsx diff --git a/explorer/src/components/Delegations/components/LoadingModal.tsx b/explorer/src/components/Delegations/LoadingModal.tsx similarity index 100% rename from explorer/src/components/Delegations/components/LoadingModal.tsx rename to explorer/src/components/Delegations/LoadingModal.tsx diff --git a/explorer/src/components/Delegations/components/ModalDivider.tsx b/explorer/src/components/Delegations/ModalDivider.tsx similarity index 100% rename from explorer/src/components/Delegations/components/ModalDivider.tsx rename to explorer/src/components/Delegations/ModalDivider.tsx diff --git a/explorer/src/components/Delegations/components/ModalListItem.tsx b/explorer/src/components/Delegations/ModalListItem.tsx similarity index 100% rename from explorer/src/components/Delegations/components/ModalListItem.tsx rename to explorer/src/components/Delegations/ModalListItem.tsx diff --git a/explorer/src/components/Delegations/components/SimpleModal.tsx b/explorer/src/components/Delegations/SimpleModal.tsx similarity index 98% rename from explorer/src/components/Delegations/components/SimpleModal.tsx rename to explorer/src/components/Delegations/SimpleModal.tsx index 76e3b1751d..88dff4d9d7 100644 --- a/explorer/src/components/Delegations/components/SimpleModal.tsx +++ b/explorer/src/components/Delegations/SimpleModal.tsx @@ -4,7 +4,7 @@ import CloseIcon from '@mui/icons-material/Close'; import ErrorOutline from '@mui/icons-material/ErrorOutline'; import InfoOutlinedIcon from '@mui/icons-material/InfoOutlined'; import ArrowBackIosNewIcon from '@mui/icons-material/ArrowBackIosNew'; -import { useIsMobile } from '../../../hooks/useIsMobile'; +import { useIsMobile } from '../../hooks/useIsMobile'; export const modalStyle = (width: number | string = 600) => ({ position: 'absolute' as 'absolute', diff --git a/explorer/src/components/Delegations/index.ts b/explorer/src/components/Delegations/index.ts new file mode 100644 index 0000000000..da51de9bd9 --- /dev/null +++ b/explorer/src/components/Delegations/index.ts @@ -0,0 +1,10 @@ +export * from './ConfirmationModal'; +export * from './DelegateIconButton'; +export * from './DelegationModal'; +export * from './DelegateModal'; +export * from './ErrorModal'; +export * from './LoadingModal'; +export * from './ModalDivider'; +export * from './ModalListItem'; +export * from './SimpleModal'; +export * from './styles'; diff --git a/explorer/src/components/Delegations/components/styles.ts b/explorer/src/components/Delegations/styles.ts similarity index 100% rename from explorer/src/components/Delegations/components/styles.ts rename to explorer/src/components/Delegations/styles.ts diff --git a/explorer/src/components/Filters/Filters.tsx b/explorer/src/components/Filters/Filters.tsx index a01d64361e..0823ef6579 100644 --- a/explorer/src/components/Filters/Filters.tsx +++ b/explorer/src/components/Filters/Filters.tsx @@ -1,5 +1,4 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; -import { Tune } from '@mui/icons-material'; import { Button, Dialog, @@ -20,6 +19,7 @@ import { EnumFilterKey, TFilterItem, TFilters } from '../../typeDefs/filters'; import { formatOnSave, generateFilterSchema } from './filterSchema'; import { Api } from '../../api'; import { useIsMobile } from '../../hooks/useIsMobile'; +import FiltersButton from './FiltersButton'; const FilterItem = ({ label, @@ -150,15 +150,7 @@ export const Filters = () => { {mixnodes?.data?.length} mixnodes matched your criteria - +

Mixnode filters diff --git a/explorer/src/components/Filters/FiltersButton.tsx b/explorer/src/components/Filters/FiltersButton.tsx new file mode 100644 index 0000000000..1e6d3e2940 --- /dev/null +++ b/explorer/src/components/Filters/FiltersButton.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import { Button, IconButton } from '@mui/material'; +import { Tune } from '@mui/icons-material'; + +type FiltersButtonProps = { + iconOnly?: boolean; + fullWidth?: boolean; + onClick: () => void; +}; + +const FiltersButton = ({ iconOnly, fullWidth, onClick }: FiltersButtonProps) => { + if (iconOnly) { + return ( + + + + ); + } + + return ( + + ); +}; + +export default FiltersButton; diff --git a/explorer/src/components/MixNodes/DetailSection.tsx b/explorer/src/components/MixNodes/DetailSection.tsx index 6592e28f4f..6becf5efe4 100644 --- a/explorer/src/components/MixNodes/DetailSection.tsx +++ b/explorer/src/components/MixNodes/DetailSection.tsx @@ -1,10 +1,10 @@ import * as React from 'react'; import { Box, Button, Grid, Typography, useTheme } from '@mui/material'; import Identicon from 'react-identicons'; +import { useIsMobile } from '@src/hooks/useIsMobile'; import { MixnodeRowType } from '.'; import { getMixNodeStatusText, MixNodeStatus } from './Status'; import { MixNodeDescriptionResponse } from '../../typeDefs/explorer-api'; -import { useIsMobile } from '../../hooks/useIsMobile'; interface MixNodeDetailProps { mixNodeRow: MixnodeRowType; @@ -16,7 +16,7 @@ export const MixNodeDetailSection: FCWithChildren = ({ mixNo const palette = [theme.palette.text.primary]; const isMobile = useIsMobile(); const statusText = React.useMemo(() => getMixNodeStatusText(mixNodeRow.status), [mixNodeRow.status]); - console.log('mixNodeRow :>> ', mixNodeRow); + return ( diff --git a/explorer/src/components/MixNodes/index.ts b/explorer/src/components/MixNodes/index.ts new file mode 100644 index 0000000000..ccb6c5a8b3 --- /dev/null +++ b/explorer/src/components/MixNodes/index.ts @@ -0,0 +1,3 @@ +export * from './Status'; +export * from './StatusDropdown'; +export * from './mappings'; diff --git a/explorer/src/components/MixNodes/index.tsx b/explorer/src/components/MixNodes/mappings.ts similarity index 100% rename from explorer/src/components/MixNodes/index.tsx rename to explorer/src/components/MixNodes/mappings.ts diff --git a/explorer/src/components/Universal-DataGrid.tsx b/explorer/src/components/Universal-DataGrid.tsx index b396213998..4a53901f12 100644 --- a/explorer/src/components/Universal-DataGrid.tsx +++ b/explorer/src/components/Universal-DataGrid.tsx @@ -13,15 +13,13 @@ const useStyles = makeStyles({ }); export const cellStyles: SxProps = { - width: '100%', padding: 0, maxHeight: 100, color: 'inherit', textDecoration: 'none', fontWeight: 400, - fontSize: 12, lineHeight: 2, - textAlign: 'start', + fontSize: '12px', wordBreak: 'break-word', whiteSpace: 'break-spaces', }; diff --git a/explorer/src/components/index.ts b/explorer/src/components/index.ts new file mode 100644 index 0000000000..92eeebd010 --- /dev/null +++ b/explorer/src/components/index.ts @@ -0,0 +1,9 @@ +export * from './CustomColumnHeading'; +export * from './Title'; +export * from './Universal-DataGrid'; +export * from './Tooltip'; +export { default as StyledLink } from './StyledLink'; +export * from './Delegations'; +export * from './MixNodes'; +export * from './TableToolbar'; +export * from './Icons'; diff --git a/explorer/src/hooks/index.ts b/explorer/src/hooks/index.ts new file mode 100644 index 0000000000..e2c94ec1e4 --- /dev/null +++ b/explorer/src/hooks/index.ts @@ -0,0 +1,3 @@ +export * from './useIsMobile'; +export * from './useIsMounted'; +export * from './useGetMixnodeStatusColor'; diff --git a/explorer/src/hooks/useGetMixnodeStatusColor.ts b/explorer/src/hooks/useGetMixnodeStatusColor.ts new file mode 100644 index 0000000000..d9d71fe7e1 --- /dev/null +++ b/explorer/src/hooks/useGetMixnodeStatusColor.ts @@ -0,0 +1,17 @@ +import { useTheme } from '@mui/material'; +import { MixnodeStatus } from '@src/typeDefs/explorer-api'; + +export const useGetMixNodeStatusColor = (status: MixnodeStatus) => { + const theme = useTheme(); + + switch (status) { + case MixnodeStatus.active: + return theme.palette.nym.networkExplorer.mixnodes.status.active; + + case MixnodeStatus.standby: + return theme.palette.nym.networkExplorer.mixnodes.status.standby; + + default: + return theme.palette.nym.networkExplorer.mixnodes.status.inactive; + } +}; diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index b325a25f81..cf5cc789c3 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -3,7 +3,7 @@ import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; import { Button, Card, Grid, Link as MuiLink, Box } from '@mui/material'; import { Link as RRDLink, useParams, useNavigate } from 'react-router-dom'; import { SelectChangeEvent } from '@mui/material/Select'; -import { SxProps } from '@mui/system'; +import { Stack, SxProps } from '@mui/system'; import { Theme, useTheme } from '@mui/material/styles'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { useWallet } from '@cosmos-kit/react'; @@ -24,14 +24,9 @@ import { DelegateIconButton } from '../../components/Delegations/components/Dele import { DelegationModal, DelegationModalProps } from '../../components/Delegations/components/DelegationModal'; import { DelegateModal } from '../../components/Delegations/components/DelegateModal'; -const getCellFontStyle = (theme: Theme, row: MixnodeRowType, textColor?: string) => { - const color = textColor || getMixNodeStatusColor(theme, row.status); - return { - fontWeight: 400, - fontSize: 12, - color, - }; -}; +const getCellFontStyle = (theme: Theme, row: MixnodeRowType, textColor?: string) => ({ + color: textColor || getMixNodeStatusColor(theme, row.status), +}); const getCellStyles = (theme: Theme, row: MixnodeRowType, textColor?: string): SxProps => ({ ...cellStyles, @@ -99,28 +94,38 @@ export const PageMixnodes: FCWithChildren = () => { const columns: GridColDef[] = [ { - field: 'delegate', - headerName: 'Delegate', + field: 'identity_key', + headerName: 'Identity Key', disableColumnMenu: true, - disableReorder: true, - align: 'center', - renderHeader: () => , + renderHeader: () => , headerClassName: 'MuiDataGrid-header-override', - width: 80, - headerAlign: 'center', + width: 215, + headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( - { - if (wallet.status !== 'Connected') { - setConfirmationModalProps({ - status: 'info', - message: 'Please connect your wallet to delegate', - }); - } else { - setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); - } - }} - /> + + { + if (wallet.status !== 'Connected') { + setConfirmationModalProps({ + status: 'info', + message: 'Please connect your wallet to delegate', + }); + } else { + setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); + } + }} + /> + + + {splice(7, 29, params.value)} + + ), }, { @@ -129,8 +134,9 @@ export const PageMixnodes: FCWithChildren = () => { disableColumnMenu: true, renderHeader: () => , headerClassName: 'MuiDataGrid-header-override', - width: 70, - headerAlign: 'left', + width: 85, + align: 'center', + headerAlign: 'center', renderCell: (params: GridRenderCellParams) => ( { ), }, - { - field: 'identity_key', - headerName: 'Identity Key', - disableColumnMenu: true, - renderHeader: () => , - headerClassName: 'MuiDataGrid-header-override', - width: 190, - headerAlign: 'left', - renderCell: (params: GridRenderCellParams) => ( - <> - - - {splice(7, 29, params.value)} - - - ), - }, + { field: 'bond', headerName: 'Stake', @@ -175,7 +156,8 @@ export const PageMixnodes: FCWithChildren = () => { renderHeader: () => , type: 'number', headerClassName: 'MuiDataGrid-header-override', - width: 170, + width: 150, + align: 'left', headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( { ), headerClassName: 'MuiDataGrid-header-override', width: 185, - headerAlign: 'left', + align: 'center', + headerAlign: 'center', renderCell: (params: GridRenderCellParams) => ( 100 ? 'theme.palette.warning.main' : undefined), }} component={RRDLink} @@ -217,11 +199,12 @@ export const PageMixnodes: FCWithChildren = () => { field: 'pledge_amount', headerName: 'Bond', disableColumnMenu: true, - width: 175, + width: 150, headerClassName: 'MuiDataGrid-header-override', renderHeader: () => , type: 'number', headerAlign: 'left', + align: 'left', renderCell: (params: GridRenderCellParams) => ( { /> ), headerClassName: 'MuiDataGrid-header-override', - width: 160, - headerAlign: 'left', + width: 145, + headerAlign: 'center', + align: 'center', renderCell: (params: GridRenderCellParams) => ( @@ -266,7 +250,8 @@ export const PageMixnodes: FCWithChildren = () => { ), headerClassName: 'MuiDataGrid-header-override', width: 170, - headerAlign: 'left', + headerAlign: 'center', + align: 'center', disableColumnMenu: true, renderCell: (params: GridRenderCellParams) => ( { ), headerClassName: 'MuiDataGrid-header-override', width: 165, - headerAlign: 'left', + headerAlign: 'center', + align: 'center', renderCell: (params: GridRenderCellParams) => ( Date: Tue, 5 Dec 2023 21:58:36 +0000 Subject: [PATCH 132/394] tidy up mixnode and gateway tables --- explorer/src/components/DetailTable.tsx | 2 - explorer/src/components/MixNodes/Status.tsx | 26 +- explorer/src/components/StyledLink.tsx | 19 ++ .../src/components/Universal-DataGrid.tsx | 13 - explorer/src/pages/Gateways/index.tsx | 85 ++---- explorer/src/pages/Mixnodes/index.tsx | 287 ++++++++---------- explorer/src/pages/MixnodesMap/index.tsx | 18 +- 7 files changed, 182 insertions(+), 268 deletions(-) create mode 100644 explorer/src/components/StyledLink.tsx diff --git a/explorer/src/components/DetailTable.tsx b/explorer/src/components/DetailTable.tsx index d333f0eb59..39355d0607 100644 --- a/explorer/src/components/DetailTable.tsx +++ b/explorer/src/components/DetailTable.tsx @@ -14,7 +14,6 @@ import { useTheme } from '@mui/material/styles'; import { Tooltip } from '@nymproject/react/tooltip/Tooltip'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { Box } from '@mui/system'; -import { cellStyles } from './Universal-DataGrid'; import { unymToNym } from '../utils/currency'; import { GatewayEnrichedRowType } from './Gateways'; import { MixnodeRowType } from './MixNodes'; @@ -110,7 +109,6 @@ export const DetailTable: FCWithChildren<{ scope="row" variant="body" sx={{ - ...cellStyles, padding: 2, width: 200, fontSize: 14, diff --git a/explorer/src/components/MixNodes/Status.tsx b/explorer/src/components/MixNodes/Status.tsx index a2da302c87..9bcea7697f 100644 --- a/explorer/src/components/MixNodes/Status.tsx +++ b/explorer/src/components/MixNodes/Status.tsx @@ -1,29 +1,12 @@ import { Typography } from '@mui/material'; import * as React from 'react'; -import { Theme, useTheme } from '@mui/material/styles'; -import { getMixNodeIcon } from '../Icons'; -import { MixnodeStatus } from '../../typeDefs/explorer-api'; +import { getMixNodeIcon } from '@src/components/Icons'; +import { MixnodeStatus } from '@src/typeDefs/explorer-api'; +import { useGetMixNodeStatusColor } from '@src/hooks/useGetMixnodeStatusColor'; interface MixNodeStatusProps { status: MixnodeStatus; } - -export const getMixNodeStatusColor = (theme: Theme, status: MixnodeStatus) => { - let color; - switch (status) { - case MixnodeStatus.active: - color = theme.palette.nym.networkExplorer.mixnodes.status.active; - break; - case MixnodeStatus.standby: - color = theme.palette.nym.networkExplorer.mixnodes.status.standby; - break; - default: - color = theme.palette.nym.networkExplorer.mixnodes.status.inactive; - break; - } - return color; -}; - // TODO: should be done with i18n export const getMixNodeStatusText = (status: MixnodeStatus) => { switch (status) { @@ -37,9 +20,8 @@ export const getMixNodeStatusText = (status: MixnodeStatus) => { }; export const MixNodeStatus: FCWithChildren = ({ status }) => { - const theme = useTheme(); const Icon = React.useMemo(() => getMixNodeIcon(status), [status]); - const color = React.useMemo(() => getMixNodeStatusColor(theme, status), [status, theme]); + const color = React.useMemo(() => useGetMixNodeStatusColor(status), [status]); return ( diff --git a/explorer/src/components/StyledLink.tsx b/explorer/src/components/StyledLink.tsx new file mode 100644 index 0000000000..6db211d849 --- /dev/null +++ b/explorer/src/components/StyledLink.tsx @@ -0,0 +1,19 @@ +import React from 'react'; +import { Link as MuiLink } from '@mui/material'; +import { Link as RRDL } from 'react-router-dom'; + +type StyledLinkProps = { + to: string; + children: string; + target?: React.HTMLAttributeAnchorTarget; + dataTestId?: string; + color?: string; +}; + +const StyledLink = ({ to, children, dataTestId, target, color = 'inherit' }: StyledLinkProps) => ( + + {children} + +); + +export default StyledLink; diff --git a/explorer/src/components/Universal-DataGrid.tsx b/explorer/src/components/Universal-DataGrid.tsx index 4a53901f12..0dc19edda8 100644 --- a/explorer/src/components/Universal-DataGrid.tsx +++ b/explorer/src/components/Universal-DataGrid.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import { makeStyles } from '@mui/styles'; import { DataGrid, GridColDef, useGridApiContext, useGridState } from '@mui/x-data-grid'; import Pagination from '@mui/material/Pagination'; -import { SxProps } from '@mui/system'; import { LinearProgress } from '@mui/material'; import { GridInitialStateCommunity } from '@mui/x-data-grid/models/gridStateCommunity'; @@ -12,18 +11,6 @@ const useStyles = makeStyles({ }, }); -export const cellStyles: SxProps = { - padding: 0, - maxHeight: 100, - color: 'inherit', - textDecoration: 'none', - fontWeight: 400, - lineHeight: 2, - fontSize: '12px', - wordBreak: 'break-word', - whiteSpace: 'break-spaces', -}; - const CustomPagination = () => { const apiRef = useGridApiContext(); const [state] = useGridState(apiRef); diff --git a/explorer/src/pages/Gateways/index.tsx b/explorer/src/pages/Gateways/index.tsx index 028b90d8b8..78da55d1ab 100644 --- a/explorer/src/pages/Gateways/index.tsx +++ b/explorer/src/pages/Gateways/index.tsx @@ -1,6 +1,5 @@ import * as React from 'react'; -import { Link as RRDLink } from 'react-router-dom'; -import { Box, Card, Grid, Link as MuiLink } from '@mui/material'; +import { Box, Card, Grid, Stack } from '@mui/material'; import { useTheme } from '@mui/material/styles'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; @@ -13,12 +12,13 @@ import { GatewayResponse } from '../../typeDefs/explorer-api'; import { TableToolbar } from '../../components/TableToolbar'; import { CustomColumnHeading } from '../../components/CustomColumnHeading'; import { Title } from '../../components/Title'; -import { cellStyles, UniversalDataGrid } from '../../components/Universal-DataGrid'; +import { UniversalDataGrid } from '../../components/Universal-DataGrid'; import { unymToNym } from '../../utils/currency'; import { Tooltip } from '../../components/Tooltip'; import { NYM_BIG_DIPPER } from '../../api/constants'; import { splice } from '../../utils'; import { VersionDisplaySelector, VersionSelectOptions } from '../../components/Gateways/VersionDisplaySelector'; +import StyledLink from '../../components/StyledLink'; export const PageGateways: FCWithChildren = () => { const { gateways } = useMainContext(); @@ -100,28 +100,19 @@ export const PageGateways: FCWithChildren = () => { field: 'identity_key', renderHeader: () => , headerClassName: 'MuiDataGrid-header-override', - width: 380, + width: 400, disableColumnMenu: true, - headerAlign: 'left', + headerAlign: 'center', renderCell: (params: GridRenderCellParams) => ( - <> - - - {params.value} - - + + + {params.value} + ), }, { field: 'node_performance', + align: 'center', renderHeader: () => ( <> { ), - width: 175, + width: 120, disableColumnMenu: true, - headerAlign: 'left', + headerAlign: 'center', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( - + {`${params.value}%`} - + ), }, { field: 'version', + align: 'center', renderHeader: () => , width: 150, disableColumnMenu: true, - headerAlign: 'left', + headerAlign: 'center', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( - + {params.value} - + ), sortComparator: (a, b) => { if (gte(a, b)) return 1; @@ -183,7 +165,7 @@ export const PageGateways: FCWithChildren = () => { renderCell: (params: GridRenderCellParams) => ( handleSearch(params.value as string)} - sx={{ ...cellStyles, justifyContent: 'flex-start', cursor: 'pointer' }} + sx={{ justifyContent: 'flex-start', cursor: 'pointer' }} data-testid="location-button" > @@ -208,14 +190,9 @@ export const PageGateways: FCWithChildren = () => { headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( - + {params.value} - + ), }, { @@ -227,14 +204,9 @@ export const PageGateways: FCWithChildren = () => { headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( - + {splice(7, 29, params.value)} - + ), }, { @@ -246,14 +218,9 @@ export const PageGateways: FCWithChildren = () => { headerClassName: 'MuiDataGrid-header-override', headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( - - {unymToNym(params.value, 6)} - + + {`${unymToNym(params.value, 6)}`} + ), }, ]; diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index cf5cc789c3..6f3cc0b1b8 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -1,38 +1,30 @@ import * as React from 'react'; import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; -import { Button, Card, Grid, Link as MuiLink, Box } from '@mui/material'; -import { Link as RRDLink, useParams, useNavigate } from 'react-router-dom'; +import { Stack, Card, Grid, Box } from '@mui/material'; +import { useParams, useNavigate } from 'react-router-dom'; import { SelectChangeEvent } from '@mui/material/Select'; -import { Stack, SxProps } from '@mui/system'; -import { Theme, useTheme } from '@mui/material/styles'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; import { useWallet } from '@cosmos-kit/react'; -import { useMainContext } from '../../context/main'; -import { MixnodeRowType, mixnodeToGridRow } from '../../components/MixNodes'; -import { TableToolbar } from '../../components/TableToolbar'; -import { MixNodeResponse, MixnodeStatusWithAll, toMixnodeStatus } from '../../typeDefs/explorer-api'; -import { NYM_BIG_DIPPER } from '../../api/constants'; -import { CustomColumnHeading } from '../../components/CustomColumnHeading'; -import { Title } from '../../components/Title'; -import { cellStyles, UniversalDataGrid } from '../../components/Universal-DataGrid'; -import { currencyToString } from '../../utils/currency'; -import { splice } from '../../utils'; -import { getMixNodeStatusColor } from '../../components/MixNodes/Status'; -import { MixNodeStatusDropdown } from '../../components/MixNodes/StatusDropdown'; -import { Tooltip } from '../../components/Tooltip'; -import { DelegateIconButton } from '../../components/Delegations/components/DelegateIconButton'; -import { DelegationModal, DelegationModalProps } from '../../components/Delegations/components/DelegationModal'; -import { DelegateModal } from '../../components/Delegations/components/DelegateModal'; - -const getCellFontStyle = (theme: Theme, row: MixnodeRowType, textColor?: string) => ({ - color: textColor || getMixNodeStatusColor(theme, row.status), -}); - -const getCellStyles = (theme: Theme, row: MixnodeRowType, textColor?: string): SxProps => ({ - ...cellStyles, - // TODO: should these be here, or change in `cellStyles`?? - ...getCellFontStyle(theme, row, textColor), -}); +import { useMainContext } from '@src/context/main'; +import { + DelegateIconButton, + DelegationModal, + DelegationModalProps, + DelegateModal, + CustomColumnHeading, + StyledLink, + Title, + UniversalDataGrid, + TableToolbar, + Tooltip, + MixNodeStatusDropdown, + mixnodeToGridRow, +} from '@src/components'; +import { MixNodeResponse, MixnodeStatusWithAll, toMixnodeStatus } from '@src/typeDefs/explorer-api'; +import { NYM_BIG_DIPPER } from '@src/api/constants'; +import { currencyToString } from '@src/utils/currency'; +import { splice } from '@src/utils'; +import { useGetMixNodeStatusColor } from '@src/hooks'; export const PageMixnodes: FCWithChildren = () => { const { mixnodes, fetchMixnodes } = useMainContext(); @@ -46,7 +38,6 @@ export const PageMixnodes: FCWithChildren = () => { const [confirmationModalProps, setConfirmationModalProps] = React.useState(); const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>(); - const theme = useTheme(); const navigate = useNavigate(); const wallet = useWallet(); @@ -92,86 +83,90 @@ export const PageMixnodes: FCWithChildren = () => { ); }; + const handleOnDelegate = ({ identityKey, mixId }: { identityKey: string; mixId: number }) => { + if (wallet.status !== 'Connected') { + setConfirmationModalProps({ + status: 'info', + message: 'Please connect your wallet to delegate', + }); + } else { + setItemSelectedForDelegation({ identityKey, mixId }); + } + }; + const columns: GridColDef[] = [ { field: 'identity_key', + width: 215, headerName: 'Identity Key', + headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', disableColumnMenu: true, renderHeader: () => , - headerClassName: 'MuiDataGrid-header-override', - width: 215, - headerAlign: 'left', renderCell: (params: GridRenderCellParams) => ( { - if (wallet.status !== 'Connected') { - setConfirmationModalProps({ - status: 'info', - message: 'Please connect your wallet to delegate', - }); - } else { - setItemSelectedForDelegation({ identityKey: params.row.identity_key, mixId: params.row.mix_id }); - } - }} + onDelegate={() => handleOnDelegate({ identityKey: params.value, mixId: params.row.mix_id })} /> - {splice(7, 29, params.value)} - + ), }, { field: 'mix_id', - headerName: 'Mix ID', - disableColumnMenu: true, - renderHeader: () => , - headerClassName: 'MuiDataGrid-header-override', width: 85, align: 'center', + headerName: 'Mix ID', headerAlign: 'center', + headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - {params.value} - + ), }, { field: 'bond', - headerName: 'Stake', - disableColumnMenu: true, - renderHeader: () => , - type: 'number', - headerClassName: 'MuiDataGrid-header-override', width: 150, align: 'left', + type: 'number', + disableColumnMenu: true, + headerName: 'Stake', headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - - {currencyToString({ amount: params.value, dp: 2 })} - + {currencyToString(params.value)} + ), }, { field: 'stake_saturation', + width: 185, + align: 'center', headerName: 'Stake Saturation', + headerAlign: 'center', + headerClassName: 'MuiDataGrid-header-override', disableColumnMenu: true, renderHeader: () => ( { tooltipInfo="Level of stake saturation for this node. Nodes receive more rewards the higher their saturation level, up to 100%. Beyond 100% no additional rewards are granted. The current stake saturation level is 940k NYMs, computed as S/K where S is target amount of tokens staked in the network and K is the number of nodes in the reward set." /> ), - headerClassName: 'MuiDataGrid-header-override', - width: 185, - align: 'center', - headerAlign: 'center', renderCell: (params: GridRenderCellParams) => ( - 100 ? 'theme.palette.warning.main' : undefined), - }} - component={RRDLink} + - {`${params.value} %`} - + color={useGetMixNodeStatusColor(params.row.status)} + >{`${params.value} %`} ), }, { field: 'pledge_amount', - headerName: 'Bond', - disableColumnMenu: true, width: 150, - headerClassName: 'MuiDataGrid-header-override', - renderHeader: () => , - type: 'number', - headerAlign: 'left', align: 'left', + type: 'number', + headerName: 'Bond', + headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - - {currencyToString({ amount: params.value, dp: 2 })} - + {currencyToString(params.value)} + ), }, { field: 'profit_percentage', + width: 145, + align: 'center', headerName: 'Profit Margin', + headerAlign: 'center', + headerClassName: 'MuiDataGrid-header-override', disableColumnMenu: true, renderHeader: () => ( { tooltipInfo="Percentage of the delegators rewards that the operator takes as fee before rewards are distributed to the delegators." /> ), - headerClassName: 'MuiDataGrid-header-override', - width: 145, - headerAlign: 'center', - align: 'center', renderCell: (params: GridRenderCellParams) => ( - - {params.value}% - + color={useGetMixNodeStatusColor(params.row.status)} + >{`${params.value}%`} ), }, { field: 'operating_cost', + width: 170, + align: 'center', headerName: 'Operating Cost', + headerAlign: 'center', + headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, renderHeader: () => ( ), - headerClassName: 'MuiDataGrid-header-override', - width: 170, - headerAlign: 'center', - align: 'center', - disableColumnMenu: true, renderCell: (params: GridRenderCellParams) => ( - - {params.value} NYM - + color={useGetMixNodeStatusColor(params.row.status)} + >{`${params.value} NYM`} ), }, { field: 'node_performance', + width: 165, + align: 'center', headerName: 'Routing Score', + headerAlign: 'center', + headerClassName: 'MuiDataGrid-header-override', disableColumnMenu: true, renderHeader: () => ( { tooltipInfo="Mixnode's most recent score (measured in the last 15 minutes). Routing score is relative to that of the network. Each time a gateway is tested, the test packets have to go through the full path of the network (gateway + 3 nodes). If a node in the path drop packets it will affect the score of the gateway and other nodes in the test." /> ), - headerClassName: 'MuiDataGrid-header-override', - width: 165, - headerAlign: 'center', - align: 'center', renderCell: (params: GridRenderCellParams) => ( - - {params.value}% - + color={useGetMixNodeStatusColor(params.row.status)} + >{`${params.value}%`} ), }, { field: 'owner', - headerName: 'Owner', - disableColumnMenu: true, - renderHeader: () => , width: 120, + headerName: 'Owner', headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - {splice(7, 29, params.value)} - + ), }, { field: 'location', + width: 150, headerName: 'Location', - renderHeader: () => , - disableColumnMenu: true, - width: 120, headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - + + handleSearch(params.value)} + > + {params.value} + + ), }, { field: 'host', - headerName: 'Host', - renderHeader: () => , - disableColumnMenu: true, - headerClassName: 'MuiDataGrid-header-override', width: 130, + headerName: 'Host', headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', + disableColumnMenu: true, + renderHeader: () => , renderCell: (params: GridRenderCellParams) => ( - {params.value} - + ), }, ]; @@ -359,6 +329,7 @@ export const PageMixnodes: FCWithChildren = () => { const handlePageSize = (event: SelectChangeEvent) => { setPageSize(event.target.value); }; + return ( <> diff --git a/explorer/src/pages/MixnodesMap/index.tsx b/explorer/src/pages/MixnodesMap/index.tsx index c6148cb894..a7c0048a11 100644 --- a/explorer/src/pages/MixnodesMap/index.tsx +++ b/explorer/src/pages/MixnodesMap/index.tsx @@ -5,7 +5,7 @@ import { ContentCard } from '../../components/ContentCard'; import { CustomColumnHeading } from '../../components/CustomColumnHeading'; import { TableToolbar } from '../../components/TableToolbar'; import { Title } from '../../components/Title'; -import { UniversalDataGrid, cellStyles } from '../../components/Universal-DataGrid'; +import { UniversalDataGrid } from '../../components/Universal-DataGrid'; import { WorldMap } from '../../components/WorldMap'; import { useMainContext } from '../../context/main'; import { CountryDataRowType, countryDataToGridRow } from '../../utils'; @@ -31,11 +31,7 @@ export const PageMixnodesMap: FCWithChildren = () => { flex: 1, headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', - renderCell: (params: GridRenderCellParams) => ( - <Typography sx={cellStyles} data-testid="country-name"> - {params.value} - </Typography> - ), + renderCell: (params: GridRenderCellParams) => <Typography data-testid="country-name">{params.value}</Typography>, }, { field: 'nodes', @@ -44,9 +40,7 @@ export const PageMixnodesMap: FCWithChildren = () => { headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', renderCell: (params: GridRenderCellParams) => ( - <Typography sx={cellStyles} data-testid="number-of-nodes"> - {params.value} - </Typography> + <Typography data-testid="number-of-nodes">{params.value}</Typography> ), }, { @@ -55,11 +49,7 @@ export const PageMixnodesMap: FCWithChildren = () => { flex: 1, headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', - renderCell: (params: GridRenderCellParams) => ( - <Typography sx={cellStyles} data-testid="percentage"> - {params.value} - </Typography> - ), + renderCell: (params: GridRenderCellParams) => <Typography data-testid="percentage">{params.value}</Typography>, }, ]; From c3050e5d0209abee89ce4cc3da60f7b14e493774 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 5 Dec 2023 22:17:20 +0000 Subject: [PATCH 133/394] allow clear search entry fix react hooks error --- explorer/src/components/MixNodes/Status.tsx | 2 +- explorer/src/components/TableToolbar.tsx | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/explorer/src/components/MixNodes/Status.tsx b/explorer/src/components/MixNodes/Status.tsx index 9bcea7697f..627b1f5964 100644 --- a/explorer/src/components/MixNodes/Status.tsx +++ b/explorer/src/components/MixNodes/Status.tsx @@ -21,7 +21,7 @@ export const getMixNodeStatusText = (status: MixnodeStatus) => { export const MixNodeStatus: FCWithChildren<MixNodeStatusProps> = ({ status }) => { const Icon = React.useMemo(() => getMixNodeIcon(status), [status]); - const color = React.useMemo(() => useGetMixNodeStatusColor(status), [status]); + const color = useGetMixNodeStatusColor(status); return ( <Typography color={color} display="flex" alignItems="center"> diff --git a/explorer/src/components/TableToolbar.tsx b/explorer/src/components/TableToolbar.tsx index 22a25e67fd..d3af522168 100644 --- a/explorer/src/components/TableToolbar.tsx +++ b/explorer/src/components/TableToolbar.tsx @@ -1,6 +1,6 @@ import React from 'react'; -import { Box, TextField, MenuItem, FormControl } from '@mui/material'; -import Select, { SelectChangeEvent } from '@mui/material/Select'; +import { Box, TextField, MenuItem, FormControl, IconButton, Select, SelectChangeEvent } from '@mui/material'; +import { Close } from '@mui/icons-material'; import { Filters } from './Filters/Filters'; import { useIsMobile } from '../hooks/useIsMobile'; @@ -72,7 +72,14 @@ export const TableToolbar: FCWithChildren<TableToolBarProps> = ({ size="small" value={searchTerm} data-testid="search-box" - placeholder="search" + placeholder="Search" + InputProps={{ + endAdornment: searchTerm?.length ? ( + <IconButton size="small" onClick={() => onChangeSearch('')}> + <Close fontSize="small" /> + </IconButton> + ) : undefined, + }} onChange={(event) => onChangeSearch(event.target.value)} /> )} From 2817c68e2e0add388c1b19e1ae833b744c00ee1d Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Dec 2023 16:25:44 +0000 Subject: [PATCH 134/394] make mobile nav neater --- .../src/components/ConnectKeplrWallet.tsx | 4 +- explorer/src/components/MobileNav.tsx | 70 +++---------------- explorer/src/components/Nav.tsx | 4 +- explorer/src/components/NetworkTitle.tsx | 47 +++++++++++++ explorer/src/components/StyledLink.tsx | 15 +++- explorer/src/pages/Mixnodes/index.tsx | 11 ++- 6 files changed, 82 insertions(+), 69 deletions(-) create mode 100644 explorer/src/components/NetworkTitle.tsx diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx index 66f8cc1598..428c725eb2 100644 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ b/explorer/src/components/ConnectKeplrWallet.tsx @@ -69,10 +69,10 @@ export const ConnectKeplrWallet = () => { return ( <Button variant="outlined" onClick={() => connect()}> - Connect Wallet + Connect {isMobile ? '' : ' Wallet'} </Button> ); }; - return <Box sx={{ mr: 2 }}>{getGlobalbutton()}</Box>; + return <Box>{getGlobalbutton()}</Box>; }; diff --git a/explorer/src/components/MobileNav.tsx b/explorer/src/components/MobileNav.tsx index 58d0120988..224bd69b0c 100644 --- a/explorer/src/components/MobileNav.tsx +++ b/explorer/src/components/MobileNav.tsx @@ -1,43 +1,23 @@ import * as React from 'react'; -import { Link } from 'react-router-dom'; import { useTheme } from '@mui/material/styles'; -import MuiLink from '@mui/material/Link'; -import { - AppBar, - Box, - Button, - Drawer, - IconButton, - List, - ListItem, - ListItemButton, - ListItemIcon, - Toolbar, - Typography, -} from '@mui/material'; +import { AppBar, Box, Drawer, IconButton, List, ListItem, ListItemButton, ListItemIcon, Toolbar } from '@mui/material'; import { Menu } from '@mui/icons-material'; -import { NymLogo } from '@nymproject/react/logo/NymLogo'; import { MaintenanceBanner } from '@nymproject/react/banners/MaintenanceBanner'; +import { useIsMobile } from '@src/hooks/useIsMobile'; import { useMainContext } from '../context/main'; import { MobileDrawerClose } from '../icons/MobileDrawerClose'; import { Footer } from './Footer'; -import { NYM_WEBSITE } from '../api/constants'; import { ExpandableButton } from './Nav'; -import { DarkLightSwitchMobile } from './Switch'; +import { ConnectKeplrWallet } from './ConnectKeplrWallet'; +import NetworkTitle from './NetworkTitle'; export const MobileNav: FCWithChildren = ({ children }) => { const theme = useTheme(); - const { navState, updateNavState, environment } = useMainContext(); + const { navState, updateNavState } = useMainContext(); const [drawerOpen, setDrawerOpen] = React.useState(false); // Set maintenance banner to false by default to don't display it const [openMaintenance, setOpenMaintenance] = React.useState(false); - - const explorerName = - `${environment && environment.charAt(0).toUpperCase() + environment.slice(1)} Explorer` || 'Mainnet Explorer'; - - const switchNetworkText = environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet'; - const switchNetworkLink = - environment === 'mainnet' ? 'https://sandbox-explorer.nymtech.net' : 'https://explorer.nymtech.net'; + const isSmallMobile = useIsMobile(400); const toggleDrawer = () => { setDrawerOpen(!drawerOpen); @@ -62,7 +42,6 @@ export const MobileNav: FCWithChildren = ({ children }) => { > <MaintenanceBanner open={openMaintenance} onClick={() => setOpenMaintenance(false)} /> <Toolbar - disableGutters sx={{ display: 'flex', justifyContent: 'space-between', @@ -75,43 +54,14 @@ export const MobileNav: FCWithChildren = ({ children }) => { display: 'flex', flexDirection: 'row', alignItems: 'center', - justifyContent: 'space-between', - width: 'auto', }} > - <IconButton component="a" href={NYM_WEBSITE} target="_blank"> - <NymLogo height="24px" width="24px" /> + <IconButton onClick={toggleDrawer}> + <Menu sx={{ color: 'primary.contrastText' }} /> </IconButton> - <Typography - variant="h6" - noWrap - sx={{ - color: theme.palette.nym.networkExplorer.nav.text, - fontSize: '18px', - fontWeight: 600, - }} - > - <MuiLink component={Link} to="/overview" underline="none" color="inherit" fontSize={14} fontWeight={700}> - {explorerName} - </MuiLink> - <Button - size="small" - variant="outlined" - color="inherit" - href={switchNetworkLink} - sx={{ textTransform: 'none', width: 114, fontSize: '12px', fontWeight: 600, ml: 1 }} - > - {switchNetworkText} - </Button> - </Typography> - </Box> - - <Box sx={{ mr: 1 }}> - <DarkLightSwitchMobile /> - <Button onClick={toggleDrawer}> - <Menu sx={{ color: theme.palette.primary.contrastText }} /> - </Button> + {!isSmallMobile && <NetworkTitle />} </Box> + <ConnectKeplrWallet /> </Toolbar> </AppBar> <Drawer diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx index fd4a80e916..c5cfc9a00b 100644 --- a/explorer/src/components/Nav.tsx +++ b/explorer/src/components/Nav.tsx @@ -341,7 +341,9 @@ export const Nav: FCWithChildren = ({ children }) => { alignItems: 'center', }} > - <ConnectKeplrWallet /> + <Box sx={{ mr: 1 }}> + <ConnectKeplrWallet /> + </Box> <DarkLightSwitchDesktop defaultChecked /> </Box> </Box> diff --git a/explorer/src/components/NetworkTitle.tsx b/explorer/src/components/NetworkTitle.tsx new file mode 100644 index 0000000000..7dd87d7e42 --- /dev/null +++ b/explorer/src/components/NetworkTitle.tsx @@ -0,0 +1,47 @@ +import React from 'react'; +import { Button, Typography } from '@mui/material'; +import { Link } from 'react-router-dom'; +import MuiLink from '@mui/material/Link'; +import { useMainContext } from '@src/context/main'; + +type NetworkTitleProps = { + showToggleNetwork?: boolean; +}; + +const NetworkTitle = ({ showToggleNetwork }: NetworkTitleProps) => { + const { environment } = useMainContext(); + + const explorerName = + `${environment && environment.charAt(0).toUpperCase() + environment.slice(1)} Explorer` || 'Mainnet Explorer'; + + const switchNetworkText = environment === 'mainnet' ? 'Switch to Testnet' : 'Switch to Mainnet'; + const switchNetworkLink = + environment === 'mainnet' ? 'https://sandbox-explorer.nymtech.net' : 'https://explorer.nymtech.net'; + return ( + <Typography + variant="h6" + noWrap + sx={{ + color: 'nym.networkExplorer.nav.text', + fontSize: '18px', + fontWeight: 600, + }} + > + <MuiLink component={Link} to="/overview" underline="none" color="inherit" fontWeight={700}> + {explorerName} + </MuiLink> + {showToggleNetwork && ( + <Button + variant="outlined" + color="inherit" + href={switchNetworkLink} + sx={{ textTransform: 'none', width: 114, fontSize: '12px', fontWeight: 600, ml: 1 }} + > + {switchNetworkText} + </Button> + )} + </Typography> + ); +}; + +export default NetworkTitle; diff --git a/explorer/src/components/StyledLink.tsx b/explorer/src/components/StyledLink.tsx index 6db211d849..fd101e5b4a 100644 --- a/explorer/src/components/StyledLink.tsx +++ b/explorer/src/components/StyledLink.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Link as MuiLink } from '@mui/material'; +import { Link as MuiLink, SxProps } from '@mui/material'; import { Link as RRDL } from 'react-router-dom'; type StyledLinkProps = { @@ -8,10 +8,19 @@ type StyledLinkProps = { target?: React.HTMLAttributeAnchorTarget; dataTestId?: string; color?: string; + sx?: SxProps; }; -const StyledLink = ({ to, children, dataTestId, target, color = 'inherit' }: StyledLinkProps) => ( - <MuiLink color={color} target={target} underline="none" component={RRDL} to={to} data-testid={dataTestId}> +const StyledLink = ({ to, children, dataTestId, target, color = 'inherit', sx }: StyledLinkProps) => ( + <MuiLink + sx={{ ...sx }} + color={color} + target={target} + underline="none" + component={RRDL} + to={to} + data-testid={dataTestId} + > {children} </MuiLink> ); diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 6f3cc0b1b8..48831f18ac 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -97,7 +97,7 @@ export const PageMixnodes: FCWithChildren = () => { const columns: GridColDef[] = [ { field: 'identity_key', - width: 215, + width: 235, headerName: 'Identity Key', headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', @@ -109,8 +109,12 @@ export const PageMixnodes: FCWithChildren = () => { size="small" onDelegate={() => handleOnDelegate({ identityKey: params.value, mixId: params.row.mix_id })} /> - <CopyToClipboard smallIcons value={params.value} tooltip={`Copy identity key ${params.value} to clipboard`} /> - + <CopyToClipboard + sx={{ mr: 0.5, color: 'grey.400' }} + smallIcons + value={params.value} + tooltip={`Copy identity key ${params.value} to clipboard`} + /> <StyledLink to={`/network-components/mixnode/${params.row.mix_id}`} color={useGetMixNodeStatusColor(params.row.status)} @@ -125,6 +129,7 @@ export const PageMixnodes: FCWithChildren = () => { field: 'mix_id', width: 85, align: 'center', + hide: true, headerName: 'Mix ID', headerAlign: 'center', headerClassName: 'MuiDataGrid-header-override', From 0ec5fb37c2c732b4845a8097bca19a58297942a7 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Thu, 14 Dec 2023 10:31:01 +0000 Subject: [PATCH 135/394] replace delegate icon button with button fix linting --- .../Delegations/DelegateIconButton.tsx | 16 ++++++---------- explorer/src/pages/Mixnodes/index.tsx | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/explorer/src/components/Delegations/DelegateIconButton.tsx b/explorer/src/components/Delegations/DelegateIconButton.tsx index 80ae730c75..f8d9569d26 100644 --- a/explorer/src/components/Delegations/DelegateIconButton.tsx +++ b/explorer/src/components/Delegations/DelegateIconButton.tsx @@ -1,7 +1,6 @@ import * as React from 'react'; -import { IconButton, Tooltip } from '@mui/material'; +import { Button } from '@mui/material'; import { SxProps } from '@mui/system'; -import { DelegateIcon } from '../../icons/DelevateSVG'; export const DelegateIconButton: FCWithChildren<{ size?: 'small' | 'medium'; @@ -9,16 +8,13 @@ export const DelegateIconButton: FCWithChildren<{ tooltip?: React.ReactNode; sx?: SxProps; onDelegate: () => void; -}> = ({ tooltip, onDelegate, sx, disabled, size = 'medium' }) => { - const handleOnDelegate = (e: React.MouseEvent<HTMLButtonElement>) => { - e.stopPropagation(); +}> = ({ onDelegate, sx, disabled, size = 'medium' }) => { + const handleOnDelegate = () => { onDelegate(); }; return ( - <Tooltip title={tooltip || undefined}> - <IconButton size={size} disabled={disabled} onClick={handleOnDelegate} sx={sx}> - <DelegateIcon fontSize={size} /> - </IconButton> - </Tooltip> + <Button variant="outlined" size={size} disabled={disabled} onClick={handleOnDelegate} sx={sx}> + Delegate + </Button> ); }; diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 48831f18ac..65412536fd 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -97,7 +97,7 @@ export const PageMixnodes: FCWithChildren = () => { const columns: GridColDef[] = [ { field: 'identity_key', - width: 235, + width: 325, headerName: 'Identity Key', headerAlign: 'left', headerClassName: 'MuiDataGrid-header-override', From b5a3a720a4c7328a7b49079c42c74f9baec2aab0 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 9 Jan 2024 14:48:14 +0000 Subject: [PATCH 136/394] fix up delegate button in mobile view --- .../Delegations/DelegateIconButton.tsx | 15 +++++++++++- explorer/src/pages/Mixnodes/index.tsx | 23 +++++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/explorer/src/components/Delegations/DelegateIconButton.tsx b/explorer/src/components/Delegations/DelegateIconButton.tsx index f8d9569d26..36b581a010 100644 --- a/explorer/src/components/Delegations/DelegateIconButton.tsx +++ b/explorer/src/components/Delegations/DelegateIconButton.tsx @@ -1,6 +1,8 @@ import * as React from 'react'; -import { Button } from '@mui/material'; +import { Button, IconButton } from '@mui/material'; import { SxProps } from '@mui/system'; +import { useIsMobile } from '@src/hooks'; +import { DelegateIcon } from '@src/icons/DelevateSVG'; export const DelegateIconButton: FCWithChildren<{ size?: 'small' | 'medium'; @@ -9,9 +11,20 @@ export const DelegateIconButton: FCWithChildren<{ sx?: SxProps; onDelegate: () => void; }> = ({ onDelegate, sx, disabled, size = 'medium' }) => { + const isMobile = useIsMobile(); + const handleOnDelegate = () => { onDelegate(); }; + + if (isMobile) { + return ( + <IconButton size="small" disabled={disabled} onClick={handleOnDelegate}> + <DelegateIcon fontSize="small" /> + </IconButton> + ); + } + return ( <Button variant="outlined" size={size} disabled={disabled} onClick={handleOnDelegate} sx={sx}> Delegate diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 65412536fd..c304c8cf2a 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -24,7 +24,7 @@ import { MixNodeResponse, MixnodeStatusWithAll, toMixnodeStatus } from '@src/typ import { NYM_BIG_DIPPER } from '@src/api/constants'; import { currencyToString } from '@src/utils/currency'; import { splice } from '@src/utils'; -import { useGetMixNodeStatusColor } from '@src/hooks'; +import { useGetMixNodeStatusColor, useIsMobile } from '@src/hooks'; export const PageMixnodes: FCWithChildren = () => { const { mixnodes, fetchMixnodes } = useMainContext(); @@ -40,6 +40,7 @@ export const PageMixnodes: FCWithChildren = () => { const navigate = useNavigate(); const wallet = useWallet(); + const isMobile = useIsMobile(); const handleNewDelegation = (delegationModalProps: DelegationModalProps) => { setItemSelectedForDelegation(undefined); @@ -95,6 +96,22 @@ export const PageMixnodes: FCWithChildren = () => { }; const columns: GridColDef[] = [ + { + field: 'delegate', + disableColumnMenu: true, + disableReorder: true, + sortable: false, + width: isMobile ? 25 : 100, + headerAlign: 'left', + headerClassName: 'MuiDataGrid-header-override', + renderHeader: () => null, + renderCell: (params: GridRenderCellParams) => ( + <DelegateIconButton + size="small" + onDelegate={() => handleOnDelegate({ identityKey: params.row.identity_key, mixId: params.row.mix_id })} + /> + ), + }, { field: 'identity_key', width: 325, @@ -105,10 +122,6 @@ export const PageMixnodes: FCWithChildren = () => { renderHeader: () => <CustomColumnHeading headingTitle="Identity Key" />, renderCell: (params: GridRenderCellParams) => ( <Stack direction="row" alignItems="center" gap={1}> - <DelegateIconButton - size="small" - onDelegate={() => handleOnDelegate({ identityKey: params.value, mixId: params.row.mix_id })} - /> <CopyToClipboard sx={{ mr: 0.5, color: 'grey.400' }} smallIcons From 22979ce245444451de0cc8b78c812f1e22a1254f Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Mon, 12 Feb 2024 16:06:31 +0000 Subject: [PATCH 137/394] add ledger intergration --- explorer/package.json | 5 +- explorer/src/context/cosmos-kit.tsx | 3 +- yarn.lock | 392 +++++++++++++++++++++++----- 3 files changed, 327 insertions(+), 73 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index adbc37edeb..7b7cda850e 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -24,8 +24,9 @@ "@cosmjs/math": "^0.26.2", "@cosmjs/stargate": "^0.32.0", "@cosmjs/tendermint-rpc": "^0.32.0", - "@cosmos-kit/keplr": "^2.4.7", - "@cosmos-kit/react": "^2.9.6", + "@cosmos-kit/keplr": "^2.6.9", + "@cosmos-kit/ledger": "^2.6.9", + "@cosmos-kit/react": "^2.10.10", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", "@interchain-ui/react": "^1.14.2", diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 6a14f556cf..e696106e1a 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -1,10 +1,11 @@ import React from 'react'; import { ChainProvider } from '@cosmos-kit/react'; import { wallets as keplr } from '@cosmos-kit/keplr'; +import { wallets as ledger } from '@cosmos-kit/ledger'; import { assets, chains } from 'chain-registry'; const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( - <ChainProvider chains={chains} assetLists={assets} wallets={[...keplr]}> + <ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger]}> {children} </ChainProvider> ); diff --git a/yarn.lock b/yarn.lock index 8795713d04..5f49794e06 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1256,10 +1256,21 @@ resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== -"@chain-registry/keplr@1.25.0": - version "1.25.0" - resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.25.0.tgz#581a10760951c1d1185c6874199df08283a21d46" - integrity sha512-mEr5HypYEaQnYcuGp3PBTqo67WV0MQyBP2dOtl+ab2fkyB5PYa01D5B2Yu5V6V7eXLmKDvvvfiRO23NWQzFHxg== +"@chain-registry/client@^1.18.0": + version "1.19.0" + resolved "https://registry.yarnpkg.com/@chain-registry/client/-/client-1.19.0.tgz#7f40d194c942e11c413dcfeba1ac63c264e5e142" + integrity sha512-Nt25fi5yuo+W26jaMHauWP4on7p8EZuOB7oBgpvl3XSje8EIJtLMnQChKzd/6+J/8fkr1vpp1lFwaIkInh9K2Q== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.18.0" + "@chain-registry/utils" "^1.18.0" + bfs-path "^1.0.2" + cross-fetch "^3.1.5" + +"@chain-registry/keplr@1.28.0": + version "1.28.0" + resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.28.0.tgz#c53d52ff0487eb6798722eb1cf5bd4dc82a141be" + integrity sha512-MRAEgUpafyGLRDQc4SPB+R/If4CL2SREqdbxZMKHX9aeqzKXhJlEM5IPjJTZCWTbUP/eGXC9JNjxPNUYd92PqQ== dependencies: "@babel/runtime" "^7.21.0" "@chain-registry/types" "^0.17.0" @@ -1274,6 +1285,23 @@ dependencies: "@babel/runtime" "^7.21.0" +"@chain-registry/types@^0.18.0": + version "0.18.0" + resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.18.0.tgz#68d91054a5b36ff621248f2843f3ff62dc9ade7f" + integrity sha512-jRFOKOMIAcA5Qp5cXEiAPyXs13WbSP19kvcb8qm5vaRwXvHMufPd/ZxLC80yq/LB62FeZeaVYfsjorLf3M6tTw== + dependencies: + "@babel/runtime" "^7.21.0" + +"@chain-registry/utils@^1.18.0": + version "1.18.0" + resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.0.tgz#d711efc2660b3b65077a5bee90b45ddc6af2194f" + integrity sha512-FAPyP1FN1jr88GfiBWnppe5S1ddgbK9TfwkyKuNSKHlk9Q+fhdC4nPM552bEz76AuFyfv7SFHg3kDuQSgYYZBw== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.18.0" + bignumber.js "9.1.1" + sha.js "^2.4.11" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1325,6 +1353,16 @@ "@cosmjs/math" "^0.32.1" "@cosmjs/utils" "^0.32.1" +"@cosmjs/amino@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.2.tgz#ba3cf255e4e6b1ba67461f1ef7b0b8ad3f895da7" + integrity sha512-lcK5RCVm4OfdAooxKcF2+NwaDVVpghOq6o/A40c2mHXDUzUoRZ33VAHjVJ9Me6vOFxshrw/XEFn1f4KObntjYA== + dependencies: + "@cosmjs/crypto" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + "@cosmjs/cosmwasm-launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.6.tgz#b03a96c8d5b5b4742ec4c56b4a01b1f4f33f7f57" @@ -1388,6 +1426,22 @@ cosmjs-types "^0.9.0" pako "^2.0.2" +"@cosmjs/cosmwasm-stargate@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.2.tgz#32aca8b4c2043cd1bc91cf4d0225b268c166e421" + integrity sha512-OwJHzIx2CoJS6AULxOpNR6m+CI0GXxy8z9svHA1ZawzNM3ZGlL0GvHdhmF0WkpX4E7UdrYlJSLpKcgg5Fo6i7Q== + dependencies: + "@cosmjs/amino" "^0.32.2" + "@cosmjs/crypto" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/proto-signing" "^0.32.2" + "@cosmjs/stargate" "^0.32.2" + "@cosmjs/tendermint-rpc" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + cosmjs-types "^0.9.0" + pako "^2.0.2" + "@cosmjs/crypto@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.25.6.tgz#695d2d0d2195bdbdd5825d415385646244900bbb" @@ -1430,6 +1484,19 @@ elliptic "^6.5.4" libsodium-wrappers-sumo "^0.7.11" +"@cosmjs/crypto@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.2.tgz#8ed255d3d1c1c4d916a1586f8cbc33eaab82f511" + integrity sha512-RuxrYKzhrPF9g6NmU7VEq++Hn1vZJjqqJpZ9Tmw9lOYOV8BUsv+j/0BE86kmWi7xVJ7EwxiuxYsKuM8IR18CIA== + dependencies: + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + "@noble/hashes" "^1" + bn.js "^5.2.0" + elliptic "^6.5.4" + libsodium-wrappers-sumo "^0.7.11" + "@cosmjs/encoding@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" @@ -1457,6 +1524,15 @@ bech32 "^1.1.4" readonly-date "^1.0.0" +"@cosmjs/encoding@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.2.tgz#8c5c64481a85cd570740c34dccce69d024a29805" + integrity sha512-WX7m1wLpA9V/zH0zRcz4EmgZdAv1F44g4dbXOgNj1eXZw1PIGR12p58OEkLN51Ha3S4DKRtCv5CkhK1KHEvQtg== + dependencies: + base64-js "^1.3.0" + bech32 "^1.1.4" + readonly-date "^1.0.0" + "@cosmjs/json-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.25.6.tgz#4f888630e84ee114b164758ec5b48f134068656c" @@ -1481,6 +1557,14 @@ "@cosmjs/stream" "^0.32.1" xstream "^11.14.0" +"@cosmjs/json-rpc@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.2.tgz#f87fab0d6975ed1d1c7daafcf6f1f81e5e296912" + integrity sha512-lan2lOgmz4yVE/HR8eCOSiII/1OudIulk8836koyIDCsPEpt6eKBuctnAD168vABGArKccLAo7Mr2gy9nrKrOQ== + dependencies: + "@cosmjs/stream" "^0.32.2" + xstream "^11.14.0" + "@cosmjs/launchpad@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.25.6.tgz#c75f5d21be57af55fcb892f929520fa97f2d5bcc" @@ -1522,6 +1606,25 @@ dependencies: bn.js "^5.2.0" +"@cosmjs/math@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.2.tgz#4522312769197e132679e4960862bcec0eed4cb8" + integrity sha512-b8+ruAAY8aKtVKWSft2IvtCVCUH1LigIlf9ALIiY8n9jtM4kMASiaRbQ/27etnSAInV88IaezKK9rQZrtxTjcw== + dependencies: + bn.js "^5.2.0" + +"@cosmjs/proto-signing@0.32.2", "@cosmjs/proto-signing@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.2.tgz#26ed2675978ce24078981f4c15a06c5d6b808f44" + integrity sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw== + dependencies: + "@cosmjs/amino" "^0.32.2" + "@cosmjs/crypto" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + cosmjs-types "^0.9.0" + "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" @@ -1586,6 +1689,16 @@ ws "^7" xstream "^11.14.0" +"@cosmjs/socket@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.2.tgz#a66be3863d03bf2d8df0433af476df010ff10e8c" + integrity sha512-Qc8jaw4uSBJm09UwPgkqe3g9TBFx4ZR9HkXpwT6Z9I+6kbLerXPR0Gy3NSJFSUgxIfTpO8O1yqoWAyf0Ay17Mw== + dependencies: + "@cosmjs/stream" "^0.32.2" + isomorphic-ws "^4.0.1" + ws "^7" + xstream "^11.14.0" + "@cosmjs/stargate@^0.25.5", "@cosmjs/stargate@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.25.6.tgz#ed7428aafd8fe1c12dc4b86f7967deb88117f61a" @@ -1636,6 +1749,22 @@ cosmjs-types "^0.9.0" xstream "^11.14.0" +"@cosmjs/stargate@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.2.tgz#73718c5c6a3ae138682ee9987333d911eca22a13" + integrity sha512-AsJa29fT7Jd4xt9Ai+HMqhyj7UQu7fyYKdXj/8+/9PD74xe6lZSYhQPcitUmMLJ1ckKPgXSk5Dd2LbsQT0IhZg== + dependencies: + "@confio/ics23" "^0.6.8" + "@cosmjs/amino" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/proto-signing" "^0.32.2" + "@cosmjs/stream" "^0.32.2" + "@cosmjs/tendermint-rpc" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + cosmjs-types "^0.9.0" + xstream "^11.14.0" + "@cosmjs/stream@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.25.6.tgz#1bf7536ed919be3fd7fbffa477c98ef5a93eac70" @@ -1657,6 +1786,13 @@ dependencies: xstream "^11.14.0" +"@cosmjs/stream@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.2.tgz#b1e8f977d25313d659f1aa89ad21614b5391cd93" + integrity sha512-gpCufLfHAD8Zp1ZKge7AHbDf4RA0TZp66wZY6JaQR5bSiEF2Drjtp4mwXZPGejtaUMnaAgff3LrUzPJfKYdQwg== + dependencies: + xstream "^11.14.0" + "@cosmjs/tendermint-rpc@0.29.5", "@cosmjs/tendermint-rpc@^0.29.5": version "0.29.5" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" @@ -1704,6 +1840,22 @@ readonly-date "^1.0.0" xstream "^11.14.0" +"@cosmjs/tendermint-rpc@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.2.tgz#c5607b8d472e5bf9fd58d5453db7194f500ccc62" + integrity sha512-DXyJHDmcAfCix4H/7/dKR0UMdshP01KxJOXHdHxBCbLIpck94BsWD3B2ZTXwfA6sv98so9wOzhp7qGQa5malxg== + dependencies: + "@cosmjs/crypto" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/json-rpc" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/socket" "^0.32.2" + "@cosmjs/stream" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + axios "^1.6.0" + readonly-date "^1.0.0" + xstream "^11.14.0" + "@cosmjs/utils@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" @@ -1719,68 +1871,90 @@ resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.1.tgz#0f7f7cbbe38c4a7fd852e698bad4d811fba5f80a" integrity sha512-PV9pa0cVPFCNgfQKEOc6RcNFHr5wMQLcDqWoo/ekIoj1AfzAaqnojdnL80u1C9Qf+vOfRGIXubqiU7Tl7QZuig== -"@cosmos-kit/core@^2.7.7": - version "2.7.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.7.tgz#150876ddde226fd236e71a8725a6182ff4722f84" - integrity sha512-i/L66ieq3G8lB1eKXqzEYqFVQp0crsR2IuwqDXxytmy02WAydCZInAGiPXKklCBWecWGR6z305NJUynaWmYjmQ== +"@cosmjs/utils@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.2.tgz#324304aa85bfa6f10561cc17781d824d02130897" + integrity sha512-Gg5t+eR7vPJMAmhkFt6CZrzPd0EKpAslWwk5rFVYZpJsM8JG5KT9XQ99hgNM3Ov6ScNoIWbXkpX27F6A9cXR4Q== + +"@cosmos-kit/core@^2.8.9": + version "2.8.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.8.9.tgz#3e6b40fa14c5d143065d3ec6a894e386f95ea4ad" + integrity sha512-e0Fqbut9mqHlFS6QnLSbU8AFYPtXUcKVaMJsL1dKbfTotACsECgnAs4gzXaTFo3sTwEJrNZ6cq86qvqV85X6uw== dependencies: + "@chain-registry/client" "^1.18.0" "@chain-registry/types" "0.17.0" - "@walletconnect/types" "2.10.4" + "@cosmjs/amino" "^0.32.2" + "@cosmjs/cosmwasm-stargate" "^0.32.2" + "@cosmjs/proto-signing" "^0.32.2" + "@cosmjs/stargate" "^0.32.2" + "@walletconnect/types" "2.11.0" bowser "2.11.0" + cosmjs-types "^0.9.0" events "3.3.0" uuid "^9.0.1" -"@cosmos-kit/keplr-extension@^2.5.10": - version "2.5.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.10.tgz#4e27d351c3f49adc9eae6167c013dd64672bab28" - integrity sha512-Y9c8NQEoHkUNn3ziurMn7dI7JSkR6JVe8Ji/lnFSVqDqc+dOuGEpVqhn9wSJlZc6xuFm88vj9ry+83XbHuxMDA== +"@cosmos-kit/keplr-extension@^2.7.9": + version "2.7.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.7.9.tgz#16586c94452a5e65713cdead07446447c511fa0e" + integrity sha512-asIjLzJjNa1mpQRohoT5zwnutk93WaQ/Y6ndb2CITfjXzM7HWrbhUzShy3FXZjHNO9CbPTjpsHNzhyScTc7fgg== dependencies: - "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.7" + "@chain-registry/keplr" "1.28.0" + "@cosmos-kit/core" "^2.8.9" + "@keplr-wallet/types" "^0.12.58" -"@cosmos-kit/keplr-mobile@^2.4.10": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.10.tgz#2444448a3ca77da6b8274ed6a0b1be3c0e325d25" - integrity sha512-+AM7q9bDGMu8aKjU126sACVtvOMQ8+Ex0s1GL5Icybqn/6WDDpmOo801k+nvznx7mwaQP7l0n6OUnwAjU3eAjg== +"@cosmos-kit/keplr-mobile@^2.6.9": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.6.9.tgz#28fcdffc8da11c34a2ece2bbef58e29dc68d0df3" + integrity sha512-kw0g/TOBKMJMDiIld2wZ7Id47hUA7G3tauijSwbMC+scXnnmOCKZ1x0lRUvW13onV7SiRT21sOm7msl8XwUlgQ== dependencies: - "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.7" - "@cosmos-kit/walletconnect" "^2.4.10" + "@chain-registry/keplr" "1.28.0" + "@cosmos-kit/core" "^2.8.9" + "@cosmos-kit/walletconnect" "^2.5.9" -"@cosmos-kit/keplr@^2.4.7": - version "2.4.12" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.12.tgz#9e063ede4878fa2c87df94cf09787b5e48738ef5" - integrity sha512-bx5YiWN6BiTQjRTIlWxHgWCeWp0fdT0kRxayj6yMkfGWWmBE9kO6mAWmWjB6+zvKyvRRyddT5ry4WW7Gi7gnGw== +"@cosmos-kit/keplr@^2.6.9": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.6.9.tgz#d861f8ea4471fc72f54c19e287623341e586e8a2" + integrity sha512-HW+WhELS1dHokSq58NDNCIQaA0xRrg293uKM989XQgDOgD/xsEaRrwwTaj3guOXxVm8BE51PLTFbZesHhflmaQ== dependencies: - "@cosmos-kit/keplr-extension" "^2.5.10" - "@cosmos-kit/keplr-mobile" "^2.4.10" + "@cosmos-kit/keplr-extension" "^2.7.9" + "@cosmos-kit/keplr-mobile" "^2.6.9" -"@cosmos-kit/react-lite@^2.5.9": - version "2.5.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.9.tgz#1ee73d8db7e7b298c876ac12ff2133fb1bcbe847" - integrity sha512-2RWvR47RCFSyJKtit5g5TjRG504BXDj3mruo5Ukyt5p0n6O+kIDUyz0o1HlVUD4wfxRIr4jgYWU52EDYeYGavQ== +"@cosmos-kit/ledger@^2.6.9": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/ledger/-/ledger-2.6.9.tgz#e37dfb2ac5941c825477210e091c2a745daf3d61" + integrity sha512-+zn2U6v2c7vDSz8vTe/4oR4lSO/LH/FkdcrstuFTJm1Mk4tpYmJkJGmUQhYV4ZfjSHXfbfccrCl1jgu4uQgiZQ== + dependencies: + "@cosmos-kit/core" "^2.8.9" + "@ledgerhq/hw-app-cosmos" "^6.28.1" + "@ledgerhq/hw-transport-webhid" "^6.27.15" + "@ledgerhq/hw-transport-webusb" "^6.27.15" + +"@cosmos-kit/react-lite@^2.6.9": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.6.9.tgz#11d1ad07fc087bad5cac5ee623596bdf70b80681" + integrity sha512-lDD6JcJstQrrQ5ZpdK2xk2OVma8DNwBe3ng3oNKAQmFTAagRjFS+TwkYF1Onl1kAcNmk0TIYStPzzUm9RkwSNw== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.7" + "@cosmos-kit/core" "^2.8.9" -"@cosmos-kit/react@^2.9.6": - version "2.9.11" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.11.tgz#87484a62f46a442d8af7706ccf3ad38fb112b422" - integrity sha512-jlKQ76i0Cb5BxVX7hOX+MwgMQxSxGzg4maORuswD3hh4S4Qi4L2MkDPUIq294Oeaqn8IlTXVjyfVpIcpIwaAtQ== +"@cosmos-kit/react@^2.10.10": + version "2.10.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.10.10.tgz#72d2280bbbd2c188dd4ca1c8663f24dbde3ccd67" + integrity sha512-WU7XrXl64nGUIrc1HwKSpLdOtvGOYkilJ9+2aASotZdmK2ybAD2f5bHbvVqL/AscvBTT4Ie2hMB4KAoNtyvTYw== dependencies: "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.7" - "@cosmos-kit/react-lite" "^2.5.9" + "@cosmos-kit/core" "^2.8.9" + "@cosmos-kit/react-lite" "^2.6.9" "@react-icons/all-files" "^4.1.0" -"@cosmos-kit/walletconnect@^2.4.10": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.10.tgz#8de2af854a094a2000c9647f9de6d2a7f279bd8e" - integrity sha512-i/vuZPQ8XhLfh0Llv1Ri7FXjqdvh60mfroKnTlqxO2LchxNcIw3MRZkZKuhalgZNQCPRe1ME2bOxwYmat55/Jg== +"@cosmos-kit/walletconnect@^2.5.9": + version "2.5.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.5.9.tgz#10c9b6f0077801e39eedf89092deb6310b47d746" + integrity sha512-wQ3qR75Q5ZpUZMO96FwBVSuLme4z4mZ8OD8fFgs1QM16Kn81+oQ00kXDT/MkokDAVCdz91qS4XHxQEAvxSm0qw== dependencies: - "@cosmos-kit/core" "^2.7.7" + "@cosmjs/proto-signing" "0.32.2" + "@cosmos-kit/core" "^2.8.9" "@walletconnect/sign-client" "^2.9.0" - "@walletconnect/types" "2.10.4" "@walletconnect/utils" "^2.9.0" events "3.3.0" @@ -2652,6 +2826,13 @@ dependencies: long "^4.0.0" +"@keplr-wallet/types@^0.12.58": + version "0.12.67" + resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.67.tgz#4ca57ad467078a28fbcdd05b052898e46be37562" + integrity sha512-HDEYOezWq//ug/R0lkOQWsaOYh3b9ECA8LN+tAA+baWMo81X9m9L63ux7NYw0QmoLxWqWrRO/T9F28+q2dw6+A== + dependencies: + long "^4.0.0" + "@keplr-wallet/unit@0.12.28": version "0.12.28" resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.28.tgz#907c7fa0b49a729cda207fca14fc0a38871cc6c4" @@ -2661,6 +2842,65 @@ big-integer "^1.6.48" utility-types "^3.10.0" +"@ledgerhq/devices@^8.2.0": + version "8.2.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.2.0.tgz#ef67bf49628252d1779acaa151b1a941acba790e" + integrity sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ== + dependencies: + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/logs" "^6.12.0" + rxjs "^7.8.1" + semver "^7.3.5" + +"@ledgerhq/errors@^6.16.1": + version "6.16.1" + resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.16.1.tgz#df650a9ba105397dee2e8c0ceddf6931c5b25ede" + integrity sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw== + +"@ledgerhq/hw-app-cosmos@^6.28.1": + version "6.29.3" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-cosmos/-/hw-app-cosmos-6.29.3.tgz#5387b4a937392a42acf3c51c1d5464ea8e98e84c" + integrity sha512-fOGJHOdZBtkLW2woMLbLGaFO/BABXU0rriuNUjhj4wy1N0xcd5RhIU/3vnM1PE8UZcC/tBe52pIk5MaYlMj9uA== + dependencies: + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/hw-transport" "^6.30.3" + bip32-path "^0.4.2" + +"@ledgerhq/hw-transport-webhid@^6.27.15": + version "6.28.3" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.28.3.tgz#4006788713944e083870101dd35de9a12aeb2be4" + integrity sha512-MNxdK1M+35QA9A+8e4ETSefK3iTO6MaHjB1tKClEngcmcJ2no+Mw8GuMyfaKkrKs2N7KbSQdVHcu9ouCL1NZhw== + dependencies: + "@ledgerhq/devices" "^8.2.0" + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/hw-transport" "^6.30.3" + "@ledgerhq/logs" "^6.12.0" + +"@ledgerhq/hw-transport-webusb@^6.27.15": + version "6.28.3" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.28.3.tgz#6a73b7ae03dcd25e4ed18e38e74d097975645e74" + integrity sha512-Zb6UfXVuPOFUiIA9alGzE4wZfjmFfLGQR04Zc1qbdeZ9Tf89g+tgJp7zgLRVMaQF2DPO2oOwajgSiPCg8f9ZDA== + dependencies: + "@ledgerhq/devices" "^8.2.0" + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/hw-transport" "^6.30.3" + "@ledgerhq/logs" "^6.12.0" + +"@ledgerhq/hw-transport@^6.30.3": + version "6.30.3" + resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.30.3.tgz#5904adb57ac4459e219551aa97ce2d0772393f2b" + integrity sha512-eqtTCGy8wFCxl+hZSEpjVqn1EDjQhFCne/qUyY0aA36efhWUF6bCRAhkq1e5i7g2P6TbxcIM5P5PW67dILuqIQ== + dependencies: + "@ledgerhq/devices" "^8.2.0" + "@ledgerhq/errors" "^6.16.1" + "@ledgerhq/logs" "^6.12.0" + events "^3.3.0" + +"@ledgerhq/logs@^6.12.0": + version "6.12.0" + resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" + integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== + "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -3151,17 +3391,10 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== -<<<<<<< HEAD -"@nymproject/node-tester@^1.0.0": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.2.tgz#7854fb7048b1fd2cf7665dad2b4a08ef0a2fcd39" - integrity sha512-Epn48utGII5QAE9bG7AaNuIE3YA2gsTNNvs11AyYB1B4cXk7RLGORcrZ6QBLUn4S+vxqbiPlX4D5G1CdZZVISQ== -======= "@nymproject/node-tester@^1.0.0", "@nymproject/node-tester@^1.2.3": version "1.2.3" resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" integrity sha512-VDFdH2ddIcXXamwkMbeHA88Xa/S2iPWh9QxkFggppvHS1d6gmnNHAZxXm3Uuhx7pCpzKldA0OT7qohMg9GW9xg== ->>>>>>> 1a01da17e (refactor) "@nymproject/nym-validator-client@^0.18.0": version "0.18.0" @@ -7105,7 +7338,7 @@ events "^3.3.0" ws "^7.5.1" -"@walletconnect/keyvaluestorage@^1.0.2", "@walletconnect/keyvaluestorage@^1.1.1": +"@walletconnect/keyvaluestorage@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== @@ -7171,18 +7404,6 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.10.4": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.4.tgz#23f6e4bd785671812dc6ea96848a6bd7ea78f038" - integrity sha512-eQpOElyiwJp3tepuOS3TS9dXTl9jVVlrC3iVA8bytnbLagkAUxmiv/s7PyDFx+ndXwQVh8PFBkWg1oxGwgCSBA== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/keyvaluestorage" "^1.0.2" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - "@walletconnect/types@2.10.6": version "2.10.6" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.6.tgz#d9920ed4fd0113e0addbda8e7e73a5176a3163fd" @@ -7195,6 +7416,18 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" +"@walletconnect/types@2.11.0": + version "2.11.0" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.0.tgz#474a009c56faa9ef4063b76ed84415c801dc9f1e" + integrity sha512-AB5b1lrEbCGHxqS2vqfCkIoODieH+ZAUp9rA1O2ftrhnqDJiJK983Df87JhYhECsQUBHHfALphA8ydER0q+9sw== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + "@walletconnect/utils@2.10.6", "@walletconnect/utils@^2.9.0": version "2.10.6" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.6.tgz#749b37d14e291e346862e7027ec7548463350226" @@ -8412,6 +8645,11 @@ better-opn@^2.1.1: dependencies: open "^7.0.3" +bfs-path@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bfs-path/-/bfs-path-1.0.2.tgz#9b5fa4b8c4ad226597fc4d2ee15398bdcc644a07" + integrity sha512-KTKx2JJtAAAT7C/rJYDXXWA2VLPycAS4kwFktKsxUo0hj4UTtw/Gm5PJuY7Uf3xSlIQNo7HRCSWei2ivncVwbQ== + big-integer@^1.6.48, big-integer@^1.6.7: version "1.6.52" resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" @@ -8427,6 +8665,11 @@ big.js@^6.2.1: resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== +bignumber.js@9.1.1: + version "9.1.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" + integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== + bignumber.js@^9.1.1: version "9.1.2" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" @@ -8449,6 +8692,11 @@ bindings@^1.3.0, bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bip32-path@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/bip32-path/-/bip32-path-0.4.2.tgz#5db0416ad6822712f077836e2557b8697c0c7c99" + integrity sha512-ZBMCELjJfcNMkz5bDuJ1WrYvjlhEF5k6mQ8vUr4N7MbVRsXei7ZOg8VhhwMfNiW68NWmLkgkc6WvTickrLGprQ== + bip32@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" @@ -9869,6 +10117,13 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cross-fetch@^3.1.5: + version "3.1.8" + resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.8.tgz#0327eba65fd68a7d119f8fb2bf9334a1a7956f82" + integrity sha512-cvA+JwZoU0Xq+h6WkMvAUqPEYy92Obet6UdKLfW60qn99ftItKjB5T+BkyWOFWe2pUyfQ+IJHmpOTznqk1M6Kg== + dependencies: + node-fetch "^2.6.12" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -14698,8 +14953,6 @@ jest@^27.1.0: import-local "^3.0.2" jest-cli "^27.5.1" -<<<<<<< HEAD -======= jiti@^1.20.0: version "1.21.0" resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" @@ -14716,7 +14969,6 @@ joi@^17.11.0: "@sideway/formula" "^3.0.1" "@sideway/pinpoint" "^2.0.0" ->>>>>>> 1a01da17e (refactor) js-sha3@0.8.0, js-sha3@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" @@ -16750,7 +17002,7 @@ node-fetch@2.6.7: dependencies: whatwg-url "^5.0.0" -node-fetch@^2.6.1, node-fetch@^2.6.7: +node-fetch@^2.6.1, node-fetch@^2.6.12, node-fetch@^2.6.7: version "2.7.0" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== @@ -19586,7 +19838,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^7.5.5: +rxjs@^7.5.5, rxjs@^7.8.1: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== From c8b911d5d0f863650d127ffa44bc745be87babf0 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Tue, 13 Feb 2024 17:47:29 +0000 Subject: [PATCH 138/394] Make mixnet contract configurable --- explorer/src/api/constants.ts | 3 +++ explorer/src/components/Delegations/DelegateModal.tsx | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts index f00c9ec280..66618a9b1f 100644 --- a/explorer/src/api/constants.ts +++ b/explorer/src/api/constants.ts @@ -24,3 +24,6 @@ export const MIXNODE_API_ERROR = "We're having trouble finding that record, plea export const NYM_WEBSITE = 'https://nymtech.net'; export const NYM_BIG_DIPPER = 'https://mixnet.explorers.guru'; + +export const NYM_MIXNET_CONTRACT = + process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx index c2b0da2e0a..fc12f82664 100644 --- a/explorer/src/components/Delegations/DelegateModal.tsx +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -9,9 +9,9 @@ import { ModalListItem } from './ModalListItem'; import { DelegationModalProps } from './DelegationModal'; import { unymToNym, validateAmount } from '../../utils/currency'; import { urls } from '../../utils'; +import { NYM_MIXNET_CONTRACT } from '../../api/constants'; const MIN_AMOUNT_TO_DELEGATE = 10; -const MIXNET_CONTRACT_ADDRESS = 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; export const DelegateModal: FCWithChildren<{ mixId: number; @@ -97,7 +97,7 @@ export const DelegateModal: FCWithChildren<{ const signerClient = await getSigningCosmWasmClient(); const tx = await signerClient.execute( delgationAddress, - MIXNET_CONTRACT_ADDRESS, + NYM_MIXNET_CONTRACT, { delegate_to_mixnode: { mix_id: delegationMixId, From 7861a0081ac015576c1eaf48804aa4c5d6922c10 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Tue, 13 Feb 2024 18:09:18 +0000 Subject: [PATCH 139/394] Add mixnet contract to env and add CI targets to package.json --- explorer/.env.dev | 2 ++ explorer/package.json | 3 +++ 2 files changed, 5 insertions(+) diff --git a/explorer/.env.dev b/explorer/.env.dev index 3cc86ae00c..cc24e10870 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -7,3 +7,5 @@ VALIDATOR_URL=https://rpc.sandbox.nymtech.net BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx + +NYM_MIXNET_CONTRACT=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav diff --git a/explorer/package.json b/explorer/package.json index 7b7cda850e..bd3a6cd57c 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -6,6 +6,9 @@ "scripts": { "start": "webpack serve --progress --port 3000", "build": "webpack build --progress --config webpack.prod.js", + "ci:dev": "echo 'Building CI for branch preview...' && yarn --cwd .. build && cp .env.dev .env && yarn build", + "ci:prod": "echo 'Building CI for prod preview...' && yarn --cwd .. build && cp .env.prod .env && yarn build", + "ci": "[ \"$CI_PROD\" = true ] && yarn ci:prod || yarn ci:dev", "build:serve": "npx serve dist", "test": "jest", "test:watch": "jest --watch", From a3d7b541e2247ddf32be4544fdd4d1ed0ea00699 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Wed, 28 Feb 2024 10:05:07 +0000 Subject: [PATCH 140/394] Fix currencyToString function call in Mixnodes page --- explorer/src/pages/Mixnodes/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index c304c8cf2a..5baf4a546f 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -174,7 +174,7 @@ export const PageMixnodes: FCWithChildren = () => { to={`/network-components/mixnode/${params.row.mix_id}`} color={useGetMixNodeStatusColor(params.row.status)} > - {currencyToString(params.value)} + {currencyToString({ amount: params.value })} </StyledLink> ), }, @@ -214,7 +214,7 @@ export const PageMixnodes: FCWithChildren = () => { to={`/network-components/mixnode/${params.row.mix_id}`} color={useGetMixNodeStatusColor(params.row.status)} > - {currencyToString(params.value)} + {currencyToString({ amount: params.value })} </StyledLink> ), }, From 1aad5fc1bf8a7257d57f1fb1cbada898db9912e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 28 Feb 2024 11:22:46 +0000 Subject: [PATCH 141/394] created nym-id for importing credentials --- Cargo.lock | 26 ++++ Cargo.toml | 2 +- common/commands/src/coconut/check_pass.rs | 112 ++++++++++++++++++ .../src/coconut/bandwidth/issuance.rs | 20 +++- .../src/coconut/bandwidth/issued.rs | 31 ++++- common/credentials/src/error.rs | 15 ++- common/credentials/src/lib.rs | 1 + common/nym-id-lib/Cargo.toml | 20 ++++ common/nym-id-lib/src/error.rs | 20 ++++ common/nym-id-lib/src/import_credential.rs | 71 +++++++++++ common/nym-id-lib/src/lib.rs | 11 ++ nym-id/Cargo.toml | 22 ++++ nym-id/src/commands/build_info.rs | 15 +++ nym-id/src/commands/import_credential.rs | 48 ++++++++ nym-id/src/commands/mod.rs | 46 +++++++ nym-id/src/commands/setup.rs | 3 + nym-id/src/main.rs | 19 +++ 17 files changed, 477 insertions(+), 5 deletions(-) create mode 100644 common/commands/src/coconut/check_pass.rs create mode 100644 common/nym-id-lib/Cargo.toml create mode 100644 common/nym-id-lib/src/error.rs create mode 100644 common/nym-id-lib/src/import_credential.rs create mode 100644 common/nym-id-lib/src/lib.rs create mode 100644 nym-id/Cargo.toml create mode 100644 nym-id/src/commands/build_info.rs create mode 100644 nym-id/src/commands/import_credential.rs create mode 100644 nym-id/src/commands/mod.rs create mode 100644 nym-id/src/commands/setup.rs create mode 100644 nym-id/src/main.rs diff --git a/Cargo.lock b/Cargo.lock index 7dcb192b24..dd14db56db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5626,6 +5626,32 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-id" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "clap 4.4.7", + "nym-bin-common", + "nym-credential-storage", + "nym-id-lib", + "tokio", + "tracing", +] + +[[package]] +name = "nym-id-lib" +version = "0.1.0" +dependencies = [ + "nym-credential-storage", + "nym-credentials", + "thiserror", + "time", + "tracing", + "zeroize", +] + [[package]] name = "nym-inclusion-probability" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 6e78dea995..040b5132a3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -112,7 +112,7 @@ members = [ "wasm/client", # "wasm/full-nym-wasm", "wasm/mix-fetch", - "wasm/node-tester", + "wasm/node-tester", "nym-id", "common/nym-id-lib", ] default-members = [ diff --git a/common/commands/src/coconut/check_pass.rs b/common/commands/src/coconut/check_pass.rs new file mode 100644 index 0000000000..ef02d80722 --- /dev/null +++ b/common/commands/src/coconut/check_pass.rs @@ -0,0 +1,112 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::context::{QueryClient, SigningClient}; +use anyhow::{anyhow, bail}; +use clap::ArgGroup; +use clap::Parser; +use futures::StreamExt; +use log::{error, info}; +use nym_coconut_dkg_common::types::EpochId; +use nym_credential_utils::utils::block_until_coconut_is_available; +use nym_credentials::coconut::bandwidth::bandwidth_credential_params; +use nym_credentials::coconut::bandwidth::freepass::MAX_FREE_PASS_VALIDITY; +use nym_credentials::coconut::utils; +use nym_credentials::{ + obtain_aggregate_verification_key, IssuanceBandwidthCredential, IssuedBandwidthCredential, +}; +use nym_credentials_interface::VerificationKey; +use nym_validator_client::coconut::all_coconut_api_clients; +use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, NymContractsProvider}; +use nym_validator_client::nyxd::CosmWasmClient; +use nym_validator_client::signing::AccountData; +use nym_validator_client::CoconutApiClient; +use std::fs; +use std::fs::File; +use std::io::Write; +use std::path::PathBuf; +use std::sync::Arc; +use time::format_description::well_known::Rfc3339; +use time::OffsetDateTime; +use zeroize::Zeroizing; + +#[derive(Debug, Parser)] +pub struct Args { + /// Path to the output directory for generated free passes. + #[clap(long)] + pub(crate) pass: PathBuf, +} + +// async fn get_freepass( +// api_clients: Vec<CoconutApiClient>, +// aggregate_vk: &VerificationKey, +// threshold: u64, +// epoch_id: EpochId, +// signing_account: &AccountData, +// expiration_date: OffsetDateTime, +// ) -> anyhow::Result<IssuedBandwidthCredential> { +// let issuance_pass = IssuanceBandwidthCredential::new_freepass(Some(expiration_date)); +// let signing_data = issuance_pass.prepare_for_signing(); +// +// let credential_shares = Arc::new(tokio::sync::Mutex::new(Vec::new())); +// +// futures::stream::iter(api_clients) +// .for_each_concurrent(None, |client| async { +// // move the client into the block +// let client = client; +// let api_url = client.api_client.api_url(); +// +// info!("contacting {api_url} for blinded free pass"); +// +// match issuance_pass +// .obtain_partial_freepass_credential( +// &client.api_client, +// signing_account, +// &client.verification_key, +// signing_data.clone(), +// ) +// .await +// { +// Ok(partial_credential) => { +// credential_shares +// .lock() +// .await +// .push((partial_credential, client.node_id).into()); +// } +// Err(err) => { +// error!("failed to obtain partial free pass from {api_url}: {err}") +// } +// } +// }) +// .await; +// +// // SAFETY: the futures have completed, so we MUST have the only arc reference +// #[allow(clippy::unwrap_used)] +// let credential_shares = Arc::into_inner(credential_shares).unwrap().into_inner(); +// +// if credential_shares.len() < threshold as usize { +// bail!("we managed to obtain only {} partial credentials while the minimum threshold is {threshold}", credential_shares.len()); +// } +// +// let signature = issuance_pass.aggregate_signature_shares(aggregate_vk, &credential_shares)?; +// Ok(issuance_pass.into_issued_credential(signature, epoch_id)) +// } + +pub async fn execute(args: Args, client: QueryClient) -> anyhow::Result<()> { + let raw_credential = fs::read(args.pass)?; + let credential = IssuedBandwidthCredential::unpack_v1(&raw_credential)?; + + println!("{:?}", credential.get_plain_public_attributes()); + println!("{}", credential.epoch_id()); + println!("{:?}", credential.variant_data()); + + let api_clients = all_coconut_api_clients(&client, credential.epoch_id()).await?; + + let vk = utils::obtain_aggregate_verification_key(&api_clients)?; + + let foomp = credential.prepare_for_spending(&vk)?; + + let res = foomp.verify(bandwidth_credential_params(), &vk); + println!("res: {res}"); + Ok(()) +} diff --git a/common/credentials/src/coconut/bandwidth/issuance.rs b/common/credentials/src/coconut/bandwidth/issuance.rs index bc56bda0fd..53c89a300b 100644 --- a/common/credentials/src/coconut/bandwidth/issuance.rs +++ b/common/credentials/src/coconut/bandwidth/issuance.rs @@ -315,9 +315,12 @@ impl IssuanceBandwidthCredential { } // TODO: is that actually needed? + // idea: make it consistent with the issued credential and its vX serde pub fn try_from_recovered_bytes(bytes: &[u8]) -> Result<Self, Error> { use bincode::Options; - Ok(make_recovery_bincode_serializer().deserialize(bytes)?) + make_recovery_bincode_serializer() + .deserialize(bytes) + .map_err(|source| Error::RecoveryCredentialDeserializationFailure { source }) } } @@ -327,3 +330,18 @@ fn make_recovery_bincode_serializer() -> impl bincode::Options { .with_big_endian() .with_varint_encoding() } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} + + fn assert_zeroize<T: Zeroize>() {} + + #[test] + fn credential_is_zeroized() { + assert_zeroize::<IssuanceBandwidthCredential>(); + assert_zeroize_on_drop::<IssuanceBandwidthCredential>(); + } +} diff --git a/common/credentials/src/coconut/bandwidth/issued.rs b/common/credentials/src/coconut/bandwidth/issued.rs index 486fd7c7ee..5e2951d1d6 100644 --- a/common/credentials/src/coconut/bandwidth/issued.rs +++ b/common/credentials/src/coconut/bandwidth/issued.rs @@ -116,6 +116,15 @@ impl IssuedBandwidthCredential { } } + pub fn try_unpack(bytes: &[u8], revision: impl Into<Option<u8>>) -> Result<Self, Error> { + let revision = revision.into().unwrap_or(CURRENT_SERIALIZATION_REVISION); + + match revision { + 1 => Self::unpack_v1(bytes), + _ => Err(Error::UnknownSerializationRevision { revision }), + } + } + pub fn epoch_id(&self) -> EpochId { self.epoch_id } @@ -138,7 +147,12 @@ impl IssuedBandwidthCredential { /// Unpack (deserialize) the credential data from the given bytes using v1 serializer. pub fn unpack_v1(bytes: &[u8]) -> Result<Self, Error> { use bincode::Options; - Ok(make_storable_bincode_serializer().deserialize(bytes)?) + make_storable_bincode_serializer() + .deserialize(bytes) + .map_err(|source| Error::SerializationFailure { + source, + revision: 1, + }) } pub fn randomise_signature(&mut self) { @@ -191,3 +205,18 @@ fn make_storable_bincode_serializer() -> impl bincode::Options { .with_big_endian() .with_varint_encoding() } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} + + fn assert_zeroize<T: Zeroize>() {} + + #[test] + fn credential_is_zeroized() { + assert_zeroize::<IssuedBandwidthCredential>(); + assert_zeroize_on_drop::<IssuedBandwidthCredential>(); + } +} diff --git a/common/credentials/src/error.rs b/common/credentials/src/error.rs index 96d8bf4202..6487d23870 100644 --- a/common/credentials/src/error.rs +++ b/common/credentials/src/error.rs @@ -5,6 +5,7 @@ use nym_credentials_interface::CoconutError; use nym_crypto::asymmetric::encryption::KeyRecoveryError; use nym_validator_client::ValidatorClientError; +use crate::coconut::bandwidth::issued::CURRENT_SERIALIZATION_REVISION; use thiserror::Error; #[derive(Debug, Error)] @@ -12,8 +13,18 @@ pub enum Error { #[error("IO error")] IOError(#[from] std::io::Error), - #[error("failed to (de)serialize credential structure: {0}")] - SerializationFailure(#[from] bincode::Error), + #[error("failed to deserialize a recovery credential: {source}")] + RecoveryCredentialDeserializationFailure { source: bincode::Error }, + + #[error("failed to (de)serialize provided credential using revision {revision}: {source}")] + SerializationFailure { + #[source] + source: bincode::Error, + revision: u8, + }, + + #[error("unknown credential serializatio revision {revision}. the current (and max supported) version is {CURRENT_SERIALIZATION_REVISION}")] + UnknownSerializationRevision { revision: u8 }, #[error("The detailed description is yet to be determined")] BandwidthCredentialError, diff --git a/common/credentials/src/lib.rs b/common/credentials/src/lib.rs index caa16ee410..c06eeb0a05 100644 --- a/common/credentials/src/lib.rs +++ b/common/credentials/src/lib.rs @@ -9,3 +9,4 @@ pub use coconut::bandwidth::{ IssuedBandwidthCredential, }; pub use coconut::utils::{obtain_aggregate_signature, obtain_aggregate_verification_key}; +pub use error::Error; diff --git a/common/nym-id-lib/Cargo.toml b/common/nym-id-lib/Cargo.toml new file mode 100644 index 0000000000..3114f0eded --- /dev/null +++ b/common/nym-id-lib/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "nym-id-lib" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +thiserror.workspace = true +time.workspace = true +tracing.workspace = true +zeroize.workspace = true + +nym-credential-storage = { path = "../credential-storage" } +nym-credentials = { path = "../credentials" } diff --git a/common/nym-id-lib/src/error.rs b/common/nym-id-lib/src/error.rs new file mode 100644 index 0000000000..2edc03fd0e --- /dev/null +++ b/common/nym-id-lib/src/error.rs @@ -0,0 +1,20 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use std::error::Error; +use thiserror::Error; +use time::OffsetDateTime; + +#[derive(Debug, Error)] +pub enum NymIdError { + #[error("failed to deserialize provided credential: {source}")] + CredentialDeserializationFailure { source: nym_credentials::Error }, + + #[error("attempted to import an expired credential (it expired on {expiration})")] + ExpiredCredentialImport { expiration: OffsetDateTime }, + + #[error("failed to store credential in the provided store: {source}")] + StorageError { + source: Box<dyn Error + Send + Sync>, + }, +} diff --git a/common/nym-id-lib/src/import_credential.rs b/common/nym-id-lib/src/import_credential.rs new file mode 100644 index 0000000000..f5058dfe2a --- /dev/null +++ b/common/nym-id-lib/src/import_credential.rs @@ -0,0 +1,71 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::NymIdError; +use nym_credential_storage::models::StorableIssuedCredential; +use nym_credential_storage::storage::Storage; +use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; +use nym_credentials::IssuedBandwidthCredential; +use tracing::{debug, warn}; +use zeroize::Zeroizing; + +pub async fn import_credential<S>( + credentials_store: S, + raw_credential: Vec<u8>, + credential_version: impl Into<Option<u8>>, +) -> Result<(), NymIdError> +where + S: Storage, + <S as Storage>::StorageError: Send + Sync + 'static, +{ + let raw_credential = Zeroizing::new(raw_credential); + + // note: the type itself implements ZeroizeOnDrop + let credential = IssuedBandwidthCredential::try_unpack(&raw_credential, credential_version) + .map_err(|source| NymIdError::CredentialDeserializationFailure { source })?; + + debug!( + "attempting to import credential of type {}", + credential.typ() + ); + + match credential.variant_data() { + BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { + debug!("with value of {}", voucher_info.value()) + } + BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { + debug!("with expiry at {}", freepass_info.expiry_date()); + if freepass_info.expired() { + warn!("the free pass has already expired!"); + + // technically we can import it, but the gateway will just reject it so what's the point + return Err(NymIdError::ExpiredCredentialImport { + expiration: freepass_info.expiry_date(), + }); + } + } + } + + // SAFETY: + // for the epoch to run over u32::MAX, we'd have to advance it for few centuries every block... + // the alternative is a very particularly malformed serialized data, but at that point blowing up is the right call + // because we can't rely on it anyway + #[allow(clippy::expect_used)] + let storable = StorableIssuedCredential { + serialization_revision: credential.current_serialization_revision(), + credential_data: &raw_credential, + credential_type: credential.typ().to_string(), + epoch_id: credential + .epoch_id() + .try_into() + .expect("our epoch is has run over u32::MAX!"), + }; + + credentials_store + .insert_issued_credential(storable) + .await + .map_err(|source| NymIdError::StorageError { + source: Box::new(source), + })?; + Ok(()) +} diff --git a/common/nym-id-lib/src/lib.rs b/common/nym-id-lib/src/lib.rs new file mode 100644 index 0000000000..e2e3a74adc --- /dev/null +++ b/common/nym-id-lib/src/lib.rs @@ -0,0 +1,11 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + +pub mod error; +pub mod import_credential; + +pub use error::NymIdError; +pub use import_credential::import_credential; diff --git a/nym-id/Cargo.toml b/nym-id/Cargo.toml new file mode 100644 index 0000000000..49da695276 --- /dev/null +++ b/nym-id/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "nym-id" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow.workspace = true +bs58.workspace = true +clap = { workspace = true, features = ["derive"] } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +tracing.workspace = true + +nym-bin-common = { path = "../common/bin-common", features = ["output_format", "basic_tracing"] } +nym-credential-storage = { path = "../common/credential-storage" } +nym-id-lib = { path = "../common/nym-id-lib" } diff --git a/nym-id/src/commands/build_info.rs b/nym-id/src/commands/build_info.rs new file mode 100644 index 0000000000..a989a41f10 --- /dev/null +++ b/nym-id/src/commands/build_info.rs @@ -0,0 +1,15 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: Args) { + println!("{}", args.output.format(&bin_info_owned!())) +} diff --git a/nym-id/src/commands/import_credential.rs b/nym-id/src/commands/import_credential.rs new file mode 100644 index 0000000000..9422a34e8d --- /dev/null +++ b/nym-id/src/commands/import_credential.rs @@ -0,0 +1,48 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use clap::ArgGroup; +use nym_id_lib::import_credential; +use std::fs; +use std::path::PathBuf; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { + bs58::decode(raw).into_vec() +} + +#[derive(clap::Args)] +#[clap(group(ArgGroup::new("cred_data").required(true)))] +pub(crate) struct Args { + /// Explicitly provide the encoded credential data (as base58) + #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] + pub(crate) credential_data: Option<Vec<u8>>, + + /// Specifies the path to file containing binary credential data + #[clap(long, group = "cred_data")] + pub(crate) credential_path: Option<PathBuf>, + + /// Specifies path to the credentials storage + #[clap(long)] + pub credentials_store_path: PathBuf, + + // currently hidden as there exists only a single serialization standard + #[clap(long, hide = true)] + pub(crate) version: Option<u8>, +} + +pub(crate) async fn execute(args: Args) -> anyhow::Result<()> { + let credentials_store = + nym_credential_storage::initialise_persistent_storage(args.credentials_store_path).await; + + let raw_credential = match args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + #[allow(clippy::unwrap_used)] + fs::read(args.credential_path.unwrap())? + } + }; + + import_credential(credentials_store, raw_credential, args.version).await?; + Ok(()) +} diff --git a/nym-id/src/commands/mod.rs b/nym-id/src/commands/mod.rs new file mode 100644 index 0000000000..e2cf56ad46 --- /dev/null +++ b/nym-id/src/commands/mod.rs @@ -0,0 +1,46 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +mod build_info; +mod import_credential; +mod setup; + +use clap::{Parser, Subcommand}; +use nym_bin_common::bin_info; +use std::sync::OnceLock; + +fn pretty_build_info_static() -> &'static str { + static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) +} + +#[derive(Parser)] +#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)] +pub(crate) struct Cli { + #[clap(subcommand)] + command: Commands, +} + +impl Cli { + pub async fn execute(self) -> anyhow::Result<()> { + match self.command { + Commands::ImportCredential(args) => import_credential::execute(args).await?, + Commands::BuildInfo(args) => build_info::execute(args), + } + + Ok(()) + } +} + +#[derive(Subcommand)] +pub(crate) enum Commands { + // TODO: to be determined how it's going to work in nymvpn et al. + // /// + // Setup, + + /// Attempt to import a bandwidth credential into the provided storage. + ImportCredential(import_credential::Args), + + /// Show build information of this binary + BuildInfo(build_info::Args), +} diff --git a/nym-id/src/commands/setup.rs b/nym-id/src/commands/setup.rs new file mode 100644 index 0000000000..20bfe6232a --- /dev/null +++ b/nym-id/src/commands/setup.rs @@ -0,0 +1,3 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + diff --git a/nym-id/src/main.rs b/nym-id/src/main.rs new file mode 100644 index 0000000000..8d8de30903 --- /dev/null +++ b/nym-id/src/main.rs @@ -0,0 +1,19 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + +use crate::commands::Cli; +use clap::Parser; +use nym_bin_common::logging::setup_tracing_logger; + +mod commands; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + setup_tracing_logger(); + let cli = Cli::parse(); + + cli.execute().await +} From 28a0c3eb176ed14f0b401d9e951710b9b2611f1f Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Wed, 28 Feb 2024 11:31:39 +0000 Subject: [PATCH 142/394] Add buffer module to webpack.common.js --- explorer/webpack.common.js | 1 + explorer/webpack.prod.js | 4 + explorer/yarn-error.log | 23014 ----------------------------------- 3 files changed, 5 insertions(+), 23014 deletions(-) delete mode 100644 explorer/yarn-error.log diff --git a/explorer/webpack.common.js b/explorer/webpack.common.js index 70744b13f2..7bb9cb9032 100644 --- a/explorer/webpack.common.js +++ b/explorer/webpack.common.js @@ -26,6 +26,7 @@ module.exports = mergeWithRules({ crypto: false, net: false, zlib: false, + buffer: require.resolve('buffer'), }, }, }); diff --git a/explorer/webpack.prod.js b/explorer/webpack.prod.js index 155a4808a1..3205b34dcd 100644 --- a/explorer/webpack.prod.js +++ b/explorer/webpack.prod.js @@ -1,3 +1,4 @@ +const webpack = require('webpack'); const { mergeWithRules } = require('webpack-merge'); const CssMinimizerPlugin = require('css-minimizer-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); @@ -34,6 +35,9 @@ module.exports = mergeWithRules({ new MiniCssExtractPlugin({ filename: '[name].[contenthash].css', }), + new webpack.ProvidePlugin({ + Buffer: ['buffer', 'Buffer'], + }), ], output: { pathinfo: false, diff --git a/explorer/yarn-error.log b/explorer/yarn-error.log deleted file mode 100644 index e2e77eb633..0000000000 --- a/explorer/yarn-error.log +++ /dev/null @@ -1,23014 +0,0 @@ -Arguments: - /home/fmtabbara/.nvm/versions/node/v18.12.1/bin/node /home/fmtabbara/.nvm/versions/node/v18.12.1/bin/yarn add @nymproject/types - -PATH: - /home/fmtabbara/.bun/bin:/home/fmtabbara/.deno/bin:/home/fmtabbara/.bun/bin:/home/fmtabbara/.deno/bin:/home/fmtabbara/.nvm/versions/node/v18.12.1/bin:/home/fmtabbara/.cargo/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/usr/local/go/bin:/home/fmtabbara/go/bin:/home/fmtabbara/.yarn/bin:/home/fmtabbara/.yarn/bin - -Yarn version: - 1.22.19 - -Node version: - 18.12.1 - -Platform: - linux x64 - -Trace: - Error: https://registry.yarnpkg.com/@nymproject%2ftypes: Not found - at params.callback [as _callback] (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:66145:18) - at self.callback (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:140890:22) - at Request.emit (node:events:513:28) - at Request.<anonymous> (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:141862:10) - at Request.emit (node:events:513:28) - at IncomingMessage.<anonymous> (/home/fmtabbara/.nvm/versions/node/v18.12.1/lib/node_modules/yarn/lib/cli.js:141784:12) - at Object.onceWrapper (node:events:627:28) - at IncomingMessage.emit (node:events:525:35) - at endReadableNT (node:internal/streams/readable:1359:12) - at process.processTicksAndRejections (node:internal/process/task_queues:82:21) - -npm manifest: - { - "name": "@nym/network-explorer", - "version": "1.0.7", - "private": true, - "license": "Apache-2.0", - "scripts": { - "start": "webpack serve --progress --port 3000", - "build": "webpack build --progress --config webpack.prod.js", - "build:serve": "npx serve dist", - "test": "jest", - "test:watch": "jest --watch", - "tsc": "tsc --noEmit true", - "tsc:watch": "tsc --watch --noEmit true", - "lint": "eslint src", - "lint:fix": "eslint src --fix", - "prestorybook": "yarn --cwd .. build", - "storybook": "start-storybook -p 6006", - "storybook:build": "build-storybook" - }, - "dependencies": { - "@cosmjs/cosmwasm-stargate": "^0.32.0", - "@cosmjs/crypto": "^0.32.0", - "@cosmjs/encoding": "^0.32.0", - "@cosmjs/math": "^0.26.2", - "@cosmjs/stargate": "^0.32.0", - "@cosmos-kit/keplr": "^2.4.7", - "@cosmos-kit/react": "^2.9.6", - "@emotion/react": "^11.4.1", - "@emotion/styled": "^11.3.0", - "@interchain-ui/react": "^1.14.2", - "@mui/icons-material": "^5.0.0", - "@mui/material": "^5.0.1", - "@mui/styles": "^5.0.1", - "@mui/system": "^5.0.1", - "@mui/x-data-grid": "^5.0.0-beta.5", - "@nymproject/mui-theme": "^1.0.0", - "@nymproject/node-tester": "^1.0.0", - "@nymproject/nym-validator-client": "^0.18.0", - "@nymproject/react": "^1.0.0", - "@nymproject/types": "^1.0.0", - "@tauri-apps/api": "^1.5.1", - "big.js": "^6.2.1", - "bs58": "^5.0.0", - "buffer": "^6.0.3", - "chain-registry": "^1.19.0", - "d3-scale": "^4.0.0", - "date-fns": "^2.24.0", - "i18n-iso-countries": "^6.8.0", - "lodash": "^4.17.21", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-error-boundary": "^3.1.4", - "react-google-charts": "^3.0.15", - "react-identicons": "^1.2.5", - "react-router-dom": "6", - "react-simple-maps": "^2.3.0", - "react-tooltip": "^4.2.21", - "semver": "^7.3.8", - "use-clipboard-copy": "^0.2.0" - }, - "devDependencies": { - "@babel/core": "^7.15.0", - "@nymproject/eslint-config-react-typescript": "^1.0.0", - "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", - "@storybook/addon-actions": "^6.5.8", - "@storybook/addon-essentials": "^6.5.8", - "@storybook/addon-interactions": "^6.5.8", - "@storybook/addon-links": "^6.5.8", - "@storybook/react": "^6.5.15", - "@storybook/testing-library": "^0.0.9", - "@svgr/webpack": "^6.1.1", - "@testing-library/jest-dom": "^5.14.1", - "@testing-library/react": "^12.0.0", - "@types/d3-fetch": "^3.0.1", - "@types/d3-geo": "^3.0.2", - "@types/d3-scale": "^4.0.1", - "@types/geojson": "^7946.0.8", - "@types/jest": "^27.0.1", - "@types/node": "^16.7.13", - "@types/react": "^18.0.26", - "@types/react-dom": "^18.0.10", - "@types/react-simple-maps": "^1.0.6", - "@types/react-tooltip": "^4.2.4", - "@types/topojson-client": "^3.1.0", - "@typescript-eslint/eslint-plugin": "^5.13.0", - "@typescript-eslint/parser": "^5.13.0", - "babel-loader": "^8.3.0", - "babel-plugin-root-import": "^6.6.0", - "clean-webpack-plugin": "^4.0.0", - "css-loader": "^6.7.3", - "css-minimizer-webpack-plugin": "^3.0.2", - "dotenv-webpack": "^7.0.3", - "eslint": "^8.10.0", - "eslint-config-airbnb": "^19.0.4", - "eslint-config-airbnb-typescript": "^16.1.0", - "eslint-config-prettier": "^8.5.0", - "eslint-import-resolver-root-import": "^1.0.4", - "eslint-plugin-import": "^2.25.4", - "eslint-plugin-jest": "^26.1.1", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-react": "^7.29.2", - "eslint-plugin-react-hooks": "^4.3.0", - "eslint-plugin-storybook": "^0.5.12", - "favicons-webpack-plugin": "^5.0.2", - "file-loader": "^6.2.0", - "fork-ts-checker-webpack-plugin": "^7.2.1", - "html-webpack-plugin": "^5.3.2", - "jest": "^27.1.0", - "mini-css-extract-plugin": "^2.2.2", - "prettier": "^2.8.7", - "react-refresh": "^0.10.0", - "react-refresh-typescript": "^2.0.2", - "style-loader": "^3.3.1", - "ts-jest": "^27.0.5", - "ts-loader": "^9.4.2", - "tsconfig-paths-webpack-plugin": "^3.5.2", - "typescript": "^4.6.2", - "url-loader": "^4.1.1", - "webpack": "^5.75.0", - "webpack-cli": "^4.8.0", - "webpack-dev-server": "^4.5.0", - "webpack-favicons": "^1.3.8", - "webpack-merge": "^5.8.0" - }, - "browserslist": { - "production": [ - ">0.2%", - "not dead", - "not op_mini all" - ], - "development": [ - "last 1 chrome version", - "last 1 firefox version", - "last 1 safari version" - ] - } - } - -yarn manifest: - No manifest - -Lockfile: - # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. - # yarn lockfile v1 - - - "@aashutoshrathi/word-wrap@^1.2.3": - version "1.2.6" - resolved "https://registry.yarnpkg.com/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz#bd9154aec9983f77b3a034ecaa015c2e4201f6cf" - integrity sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA== - - "@adobe/css-tools@^4.0.1": - version "4.3.2" - resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.3.2.tgz#a6abc715fb6884851fca9dad37fc34739a04fd11" - integrity sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw== - - "@ampproject/remapping@^2.2.0": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.1.tgz#99e8e11851128b8702cd57c33684f1d0f260b630" - integrity sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - - "@babel/code-frame@7.12.11": - version "7.12.11" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f" - integrity sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw== - dependencies: - "@babel/highlight" "^7.10.4" - - "@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.22.13", "@babel/code-frame@^7.22.5", "@babel/code-frame@^7.23.5", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.23.5.tgz#9009b69a8c602293476ad598ff53e4562e15c244" - integrity sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA== - dependencies: - "@babel/highlight" "^7.23.4" - chalk "^2.4.2" - - "@babel/compat-data@^7.20.5", "@babel/compat-data@^7.22.6", "@babel/compat-data@^7.22.9", "@babel/compat-data@^7.23.3", "@babel/compat-data@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.23.5.tgz#ffb878728bb6bdcb6f4510aa51b1be9afb8cfd98" - integrity sha512-uU27kfDRlhfKl+w1U6vp16IuvSLtjAxdArVXPa9BvLkrr7CYIsxH5adpHObeAGY/41+syctUWOZ140a2Rvkgjw== - - "@babel/core@7.12.9": - version "7.12.9" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" - 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" - - "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.15.0", "@babel/core@^7.17.5", "@babel/core@^7.19.6", "@babel/core@^7.7.2", "@babel/core@^7.7.5", "@babel/core@^7.8.0": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.23.5.tgz#6e23f2acbcb77ad283c5ed141f824fd9f70101c7" - integrity sha512-Cwc2XjUrG4ilcfOw4wBAK+enbdgwAcAJCfGUItPBKR7Mjw4aEfAFYrLxeRp4jWgtNIKn3n2AlBOfwwafl+42/g== - dependencies: - "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.5" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helpers" "^7.23.5" - "@babel/parser" "^7.23.5" - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.5" - "@babel/types" "^7.23.5" - convert-source-map "^2.0.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.3" - semver "^6.3.1" - - "@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.23.5", "@babel/generator@^7.7.2": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.23.5.tgz#17d0a1ea6b62f351d281350a5f80b87a810c4755" - integrity sha512-BPssCHrBD+0YrxviOa3QzpqwhNIXKEtOa2jQrm4FlmkC2apYgRnQcmPWiGZDlGxiNtltnUFolMe8497Esry+jA== - dependencies: - "@babel/types" "^7.23.5" - "@jridgewell/gen-mapping" "^0.3.2" - "@jridgewell/trace-mapping" "^0.3.17" - jsesc "^2.5.1" - - "@babel/helper-annotate-as-pure@^7.18.6", "@babel/helper-annotate-as-pure@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.22.5.tgz#e7f06737b197d580a01edf75d97e2c8be99d3882" - integrity sha512-LvBTxu8bQSQkcyKOU+a1btnNFQ1dMAd0R6PyW3arXes06F6QLWLIrd681bxRPIXlrMGR3XYnW9JyML7dP3qgxg== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-builder-binary-assignment-operator-visitor@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.22.15.tgz#5426b109cf3ad47b91120f8328d8ab1be8b0b956" - integrity sha512-QkBXwGgaoC2GtGZRoma6kv7Szfv06khvhFav67ZExau2RaXzy8MpHSMO2PNoP2XtmQphJQRHFfg77Bq731Yizw== - dependencies: - "@babel/types" "^7.22.15" - - "@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.20.7", "@babel/helper-compilation-targets@^7.22.15", "@babel/helper-compilation-targets@^7.22.6": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.22.15.tgz#0698fc44551a26cf29f18d4662d5bf545a6cfc52" - integrity sha512-y6EEzULok0Qvz8yyLkCvVX+02ic+By2UdOhylwUOvOn9dvYc9mKICJuuU1n1XBI02YWsNsnrY1kc6DVbjcXbtw== - dependencies: - "@babel/compat-data" "^7.22.9" - "@babel/helper-validator-option" "^7.22.15" - browserslist "^4.21.9" - lru-cache "^5.1.1" - semver "^6.3.1" - - "@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.21.0", "@babel/helper-create-class-features-plugin@^7.22.15", "@babel/helper-create-class-features-plugin@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.23.5.tgz#2a8792357008ae9ce8c0f2b78b9f646ac96b314b" - integrity sha512-QELlRWxSpgdwdJzSJn4WAhKC+hvw/AtHbbrIoncKHkhKKR/luAlKkgBDcri1EzWAo8f8VvYVryEHN4tax/V67A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-member-expression-to-functions" "^7.23.0" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - semver "^6.3.1" - - "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.22.15", "@babel/helper-create-regexp-features-plugin@^7.22.5": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.22.15.tgz#5ee90093914ea09639b01c711db0d6775e558be1" - integrity sha512-29FkPLFjn4TPEa3RE7GpW+qbE8tlsu3jntNYNfcGsc49LphF1PQIiD+vMZ1z1xVOKt+93khA9tc2JBs3kBjA7w== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - regexpu-core "^5.3.1" - semver "^6.3.1" - - "@babel/helper-define-polyfill-provider@^0.1.5": - version "0.1.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" - integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== - dependencies: - "@babel/helper-compilation-targets" "^7.13.0" - "@babel/helper-module-imports" "^7.12.13" - "@babel/helper-plugin-utils" "^7.13.0" - "@babel/traverse" "^7.13.0" - debug "^4.1.1" - lodash.debounce "^4.0.8" - resolve "^1.14.2" - semver "^6.1.2" - - "@babel/helper-define-polyfill-provider@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.4.3.tgz#a71c10f7146d809f4a256c373f462d9bba8cf6ba" - integrity sha512-WBrLmuPP47n7PNwsZ57pqam6G/RGo1vw/87b0Blc53tZNGZ4x7YvZ6HgQe2vo1W/FR20OgjeZuGXzudPiXHFug== - dependencies: - "@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" - - "@babel/helper-environment-visitor@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz#96159db61d34a29dba454c959f5ae4a649ba9167" - integrity sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA== - - "@babel/helper-function-name@^7.22.5", "@babel/helper-function-name@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz#1f9a3cdbd5b2698a670c30d2735f9af95ed52759" - integrity sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw== - dependencies: - "@babel/template" "^7.22.15" - "@babel/types" "^7.23.0" - - "@babel/helper-hoist-variables@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz#c01a007dac05c085914e8fb652b339db50d823bb" - integrity sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-member-expression-to-functions@^7.22.15", "@babel/helper-member-expression-to-functions@^7.23.0": - version "7.23.0" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.23.0.tgz#9263e88cc5e41d39ec18c9a3e0eced59a3e7d366" - integrity sha512-6gfrPwh7OuT6gZyJZvd6WbTfrqAo7vm4xCzAXOusKqq/vWdKXphTpj5klHKNmRUU6/QRGlBsyU9mAIPaWHlqJA== - dependencies: - "@babel/types" "^7.23.0" - - "@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.16.7", "@babel/helper-module-imports@^7.22.15": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.22.15.tgz#16146307acdc40cc00c3b2c647713076464bdbf0" - integrity sha512-0pYVBnDKZO2fnSPCrgM/6WMc7eS20Fbok+0r88fp+YtWVLZrp4CkafFGIp+W0VKw4a22sgebPT99y+FDNMdP4w== - dependencies: - "@babel/types" "^7.22.15" - - "@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.23.3.tgz#d7d12c3c5d30af5b3c0fcab2a6d5217773e2d0f1" - integrity sha512-7bBs4ED9OmswdfDzpz4MpWgSrV7FXlc3zIagvLFjS5H+Mk7Snr21vQ6QwrsoCGMfNC4e4LQPdoULEt4ykz0SRQ== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-simple-access" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/helper-validator-identifier" "^7.22.20" - - "@babel/helper-optimise-call-expression@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.22.5.tgz#f21531a9ccbff644fdd156b4077c16ff0c3f609e" - integrity sha512-HBwaojN0xFRx4yIvpwGqxiV2tUfl7401jlok564NgB9EHS1y6QT17FmKWm4ztqjeVdXLuC4fSvHc5ePpQjoTbw== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-plugin-utils@7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" - integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== - - "@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.20.2", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.22.5.tgz#dd7ee3735e8a313b9f7b05a773d892e88e6d7295" - integrity sha512-uLls06UVKgFG9QD4OeFYLEGteMIAa5kpTPcFL28yuCIIzsf6ZyKZMllKVOCZFhiZ5ptnwX4mtKdWCBE/uT4amg== - - "@babel/helper-remap-async-to-generator@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.22.20.tgz#7b68e1cb4fa964d2996fd063723fb48eca8498e0" - integrity sha512-pBGyV4uBqOns+0UvhsTO8qgl8hO89PmiDYv+/COyp1aeMcmfrfruz+/nCMFiYyFF/Knn0yfrC85ZzNFjembFTw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-wrap-function" "^7.22.20" - - "@babel/helper-replace-supers@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.22.20.tgz#e37d367123ca98fe455a9887734ed2e16eb7a793" - integrity sha512-qsW0In3dbwQUbK8kejJ4R7IHVGwHJlV6lpG6UA7a9hSa2YEiAib+N1T2kr6PEeUT+Fl7najmSOS6SmAwCHK6Tw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-member-expression-to-functions" "^7.22.15" - "@babel/helper-optimise-call-expression" "^7.22.5" - - "@babel/helper-simple-access@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.22.5.tgz#4938357dc7d782b80ed6dbb03a0fba3d22b1d5de" - integrity sha512-n0H99E/K+Bika3++WNL17POvo4rKWZ7lZEp1Q+fStVbUi8nxPQEBOlTmCOxW/0JsS56SKKQ+ojAe2pHKJHN35w== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-skip-transparent-expression-wrappers@^7.20.0", "@babel/helper-skip-transparent-expression-wrappers@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.22.5.tgz#007f15240b5751c537c40e77abb4e89eeaaa8847" - integrity sha512-tK14r66JZKiC43p8Ki33yLBVJKlQDFoA8GYN67lWCDCqoL6EMMSuM9b+Iff2jHaM/RRFYl7K+iiru7hbRqNx8Q== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-split-export-declaration@^7.22.6": - version "7.22.6" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz#322c61b7310c0997fe4c323955667f18fcefb91c" - integrity sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g== - dependencies: - "@babel/types" "^7.22.5" - - "@babel/helper-string-parser@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.23.4.tgz#9478c707febcbbe1ddb38a3d91a2e054ae622d83" - integrity sha512-803gmbQdqwdf4olxrX4AJyFBV/RTr3rSmOj0rKwesmzlfhYNDEs+/iOcznzpNWlJlIlTJC2QfPFcHB6DlzdVLQ== - - "@babel/helper-validator-identifier@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz#c4ae002c61d2879e724581d96665583dbc1dc0e0" - integrity sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A== - - "@babel/helper-validator-option@^7.22.15", "@babel/helper-validator-option@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.23.5.tgz#907a3fbd4523426285365d1206c423c4c5520307" - integrity sha512-85ttAOMLsr53VgXkTbkx8oA6YTfT4q7/HzXSLEYmjcSTJPMPQtvq1BD79Byep5xMUYbGRzEpDsjUf3dyp54IKw== - - "@babel/helper-wrap-function@^7.22.20": - version "7.22.20" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.22.20.tgz#15352b0b9bfb10fc9c76f79f6342c00e3411a569" - integrity sha512-pms/UwkOpnQe/PDAEdV/d7dVCoBbB+R4FvYoHGZz+4VPcg7RtYy2KP7S2lbuWM6FCSgob5wshfGESbC/hzNXZw== - dependencies: - "@babel/helper-function-name" "^7.22.5" - "@babel/template" "^7.22.15" - "@babel/types" "^7.22.19" - - "@babel/helpers@^7.12.5", "@babel/helpers@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.23.5.tgz#52f522840df8f1a848d06ea6a79b79eefa72401e" - integrity sha512-oO7us8FzTEsG3U6ag9MfdF1iA/7Z6dz+MtFhifZk8C8o453rGJFFWUP1t+ULM9TUIAzC9uxXEiXjOiVMyd7QPg== - dependencies: - "@babel/template" "^7.22.15" - "@babel/traverse" "^7.23.5" - "@babel/types" "^7.23.5" - - "@babel/highlight@^7.10.4", "@babel/highlight@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.23.4.tgz#edaadf4d8232e1a961432db785091207ead0621b" - integrity sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A== - dependencies: - "@babel/helper-validator-identifier" "^7.22.20" - chalk "^2.4.2" - js-tokens "^4.0.0" - - "@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.22.15", "@babel/parser@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.23.5.tgz#37dee97c4752af148e1d38c34b856b2507660563" - integrity sha512-hOOqoiNXrmGdFbhgCzu6GiURxUgM27Xwd/aPuu8RfHEZPBzL1Z54okAHAQjXfcQNwvrlkAmAp4SlRTZ45vlthQ== - - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.23.3.tgz#5cd1c87ba9380d0afb78469292c954fee5d2411a" - integrity sha512-iRkKcCqb7iGnq9+3G6rZ+Ciz5VywC4XNRHe57lKM+jOeYAoR0lVqdeeDRfh0tQcTfw/+vBhHn926FmQhLtlFLQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.23.3.tgz#f6652bb16b94f8f9c20c50941e16e9756898dc5d" - integrity sha512-WwlxbfMNdVEpQjZmK5mhm7oSwD3dS6eU+Iwsi4Knl9wAletWem7kaRsGOG+8UEbRyqxY4SS5zvtfXwX+jMxUwQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-transform-optional-chaining" "^7.23.3" - - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.23.3.tgz#20c60d4639d18f7da8602548512e9d3a4c8d7098" - integrity sha512-XaJak1qcityzrX0/IU5nKHb34VaibwP3saKqG6a/tppelgllOH13LUann4ZCIBcVOeE6H18K4Vx9QKkVww3z/w== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-proposal-class-properties@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" - 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" - - "@babel/plugin-proposal-decorators@^7.12.12": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.23.5.tgz#eeaa49d0dc9229aec4d23378653738cdc5a3ea0a" - integrity sha512-6IsY8jOeWibsengGlWIezp7cuZEFzNlAghFpzh9wiZwhQ42/hRcPnY/QV9HJoKTlujupinSlnQPiEy/u2C1ZfQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.23.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/plugin-syntax-decorators" "^7.23.3" - - "@babel/plugin-proposal-export-default-from@^7.12.1": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.23.3.tgz#6f511a676c540ccc8d17a8553dbba9230b0ddac0" - integrity sha512-Q23MpLZfSGZL1kU7fWqV262q65svLSCIP5kZ/JCW/rKTCm/FrLjpvEd2kfUYMVeHh4QhV/xzyoRAHWrAZJrE3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-default-from" "^7.23.3" - - "@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" - integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== - dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - - "@babel/plugin-proposal-object-rest-spread@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" - integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.12.1" - - "@babel/plugin-proposal-object-rest-spread@^7.12.1": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.20.7.tgz#aa662940ef425779c75534a5c41e9d936edc390a" - integrity sha512-d2S98yCiLxDVmBmE8UjGcfPvNEUbA1U5q5WxaWFUGRzJSVAZqm5W6MbPct0jxnegUZ0niLeNX+IOzEs7wYg9Dg== - 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/plugin-proposal-optional-chaining@^7.12.7": - version "7.21.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.21.0.tgz#886f5c8978deb7d30f678b2e24346b287234d3ea" - integrity sha512-p4zeefM72gpmEe2fkUr/OnOXpWEf8nAgk7ZYVqqfFiyIG7oFfVZcCrU64hWn5xp4tQ9LkV4bTIa5rD0KANpKNA== - 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/plugin-proposal-private-methods@^7.12.1": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" - integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - - "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": - version "7.21.0-placeholder-for-preset-env.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" - integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== - - "@babel/plugin-proposal-private-property-in-object@^7.12.1": - version "7.21.11" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.11.tgz#69d597086b6760c4126525cfa154f34631ff272c" - integrity sha512-0QZ8qP/3RLDVBwBFoWAwCtgcDZJVwA5LUJRZU8x2YFfKNuFq161wK3cuGrALu5yiPu+vzwTAg/sMWVNeWeNyaw== - 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/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-bigint@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz#4c9a6f669f5d0cdf1b90a1671e9a146be5300cea" - integrity sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-class-properties@^7.12.13", "@babel/plugin-syntax-class-properties@^7.8.3": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - - "@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - - "@babel/plugin-syntax-decorators@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.23.3.tgz#a1d351d6c25bfdcf2e16f99b039101bc0ffcb0ca" - integrity sha512-cf7Niq4/+/juY67E0PbgH0TDhLQ5J7zS8C/Q5FFx+DWyrRa9sUQdTXkjqKu8zGvuqr7vw1muKiukseihU+PJDA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-dynamic-import@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" - integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-export-default-from@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.23.3.tgz#7e6d4bf595d5724230200fb2b7401d4734b15335" - integrity sha512-KeENO5ck1IeZ/l2lFZNy+mpobV3D2Zy5C1YFnWm+YuY5mQiAWc4yAp13dqgguwsBsFVLh4LPCEqCa5qW13N+hw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - - "@babel/plugin-syntax-flow@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.23.3.tgz#084564e0f3cc21ea6c70c44cff984a1c0509729a" - integrity sha512-YZiAIpkJAwQXBJLIQbRFayR5c+gJ35Vcz3bg954k7cd73zqjvhacJuL9RbrzPz8qPmZdgqP6EUKwy0PCNhaaPA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-import-assertions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.23.3.tgz#9c05a7f592982aff1a2768260ad84bcd3f0c77fc" - integrity sha512-lPgDSU+SJLK3xmFDTV2ZRQAiM7UuUjGidwBywFavObCiZc1BeAAcMtHJKUya92hPHO+at63JJPLygilZard8jw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-import-attributes@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.23.3.tgz#992aee922cf04512461d7dae3ff6951b90a2dc06" - integrity sha512-pawnE0P9g10xgoP7yKr6CK63K2FMsTE+FZidZO/1PwRdzmAPVs+HS1mAURUsgaoxammTJvULUdIkEK0gOcU2tA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-import-meta@^7.10.4", "@babel/plugin-syntax-import-meta@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-jsx@7.12.1": - version "7.12.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" - integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-jsx@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.23.3.tgz#8f2e4f8a9b5f9aa16067e142c1ac9cd9f810f473" - integrity sha512-EB2MELswq55OHUoRZLGg/zC7QWUKfNLpE57m/S2yr1uEneIgsTgrSzXP3NXEsMkVn76OlaVVnzN+ugObuYGwhg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-logical-assignment-operators@^7.10.4", "@babel/plugin-syntax-logical-assignment-operators@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-numeric-separator@^7.10.4", "@babel/plugin-syntax-numeric-separator@^7.8.3": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - - "@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - - "@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - - "@babel/plugin-syntax-top-level-await@^7.14.5", "@babel/plugin-syntax-top-level-await@^7.8.3": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - - "@babel/plugin-syntax-typescript@^7.23.3", "@babel/plugin-syntax-typescript@^7.7.2": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.23.3.tgz#24f460c85dbbc983cd2b9c4994178bcc01df958f" - integrity sha512-9EiNjVJOMwCO+43TqoTrgQ8jMwcAd0sWyXi9RPfIsLTj4R2MADDDQXELhffaUx/uJv2AYcxBgPwH6j4TIA4ytQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-unicode-sets-regex/-/plugin-syntax-unicode-sets-regex-7.18.6.tgz#d49a3b3e6b52e5be6740022317580234a6a47357" - integrity sha512-727YkEAPwSIQTv5im8QHz3upqp92JTWhidIC81Tdx4VJYIte/VndKf1qKrfnnhPLiPghStWfvC/iFaMCQu7Nqg== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.18.6" - "@babel/helper-plugin-utils" "^7.18.6" - - "@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.23.3.tgz#94c6dcfd731af90f27a79509f9ab7fb2120fc38b" - integrity sha512-NzQcQrzaQPkaEwoTm4Mhyl8jI1huEL/WWIEvudjTCMJ9aBZNpsJbMASx7EQECtQQPS/DcnFpo0FIh3LvEO9cxQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-async-generator-functions@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.23.4.tgz#93ac8e3531f347fba519b4703f9ff2a75c6ae27a" - integrity sha512-efdkfPhHYTtn0G6n2ddrESE91fgXxjlqLsnUtPWnJs4a4mZIbUaK7ffqKIIUKXSHwcDvaCVX6GXkaJJFqtX7jw== - dependencies: - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.20" - "@babel/plugin-syntax-async-generators" "^7.8.4" - - "@babel/plugin-transform-async-to-generator@^7.14.5", "@babel/plugin-transform-async-to-generator@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.23.3.tgz#d1f513c7a8a506d43f47df2bf25f9254b0b051fa" - integrity sha512-A7LFsKi4U4fomjqXJlZg/u0ft/n8/7n7lpffUP/ZULx/DtV9SGlNKZolHH6PE8Xl1ngCc0M11OaeZptXVkfKSw== - dependencies: - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-remap-async-to-generator" "^7.22.20" - - "@babel/plugin-transform-block-scoped-functions@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.23.3.tgz#fe1177d715fb569663095e04f3598525d98e8c77" - integrity sha512-vI+0sIaPIO6CNuM9Kk5VmXcMVRiOpDh7w2zZt9GXzmE/9KD70CUEVhvPR/etAeNK/FAEkhxQtXOzVF3EuRL41A== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.23.4.tgz#b2d38589531c6c80fbe25e6b58e763622d2d3cf5" - integrity sha512-0QqbP6B6HOh7/8iNR4CQU2Th/bbRtBp4KS9vcaZd1fZ0wSh5Fyssg0UCIHwxh+ka+pNDREbVLQnHCMHKZfPwfw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-class-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.23.3.tgz#35c377db11ca92a785a718b6aa4e3ed1eb65dc48" - integrity sha512-uM+AN8yCIjDPccsKGlw271xjJtGii+xQIF/uMPS8H15L12jZTsLfF4o5vNO7d/oUguOyfdikHGc/yi9ge4SGIg== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-class-static-block@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.23.4.tgz#2a202c8787a8964dd11dfcedf994d36bfc844ab5" - integrity sha512-nsWu/1M+ggti1SOALj3hfx5FXzAY06fwPJsUZD4/A5e1bWi46VUIWtD+kOX6/IdhXGsXBWllLFDSnqSCdUNydQ== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - - "@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.23.5": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.23.5.tgz#e7a75f815e0c534cc4c9a39c56636c84fc0d64f2" - integrity sha512-jvOTR4nicqYC9yzOHIhXG5emiFEOpappSJAl73SDSEDcybD+Puuze8Tnpb9p9qEyYup24tq891gkaygIFvWDqg== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-optimise-call-expression" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - "@babel/helper-split-export-declaration" "^7.22.6" - globals "^11.1.0" - - "@babel/plugin-transform-computed-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.23.3.tgz#652e69561fcc9d2b50ba4f7ac7f60dcf65e86474" - integrity sha512-dTj83UVTLw/+nbiHqQSFdwO9CbTtwq1DsDqm3CUEtDrZNET5rT5E6bIdTlOftDTDLMYxvxHNEYO4B9SLl8SLZw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/template" "^7.22.15" - - "@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.23.3.tgz#8c9ee68228b12ae3dff986e56ed1ba4f3c446311" - integrity sha512-n225npDqjDIr967cMScVKHXJs7rout1q+tt50inyBCPkyZ8KxeI6d+GIbSBTT/w/9WdlWDOej3V9HE5Lgk57gw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-dotall-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.23.3.tgz#3f7af6054882ede89c378d0cf889b854a993da50" - integrity sha512-vgnFYDHAKzFaTVp+mneDsIEbnJ2Np/9ng9iviHw3P/KVcgONxpNULEW/51Z/BaFojG2GI2GwwXck5uV1+1NOYQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-duplicate-keys@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.23.3.tgz#664706ca0a5dfe8d066537f99032fc1dc8b720ce" - integrity sha512-RrqQ+BQmU3Oyav3J+7/myfvRCq7Tbz+kKLLshUmMwNlDHExbGL7ARhajvoBJEvc+fCguPPu887N+3RRXBVKZUA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-dynamic-import@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.23.4.tgz#c7629e7254011ac3630d47d7f34ddd40ca535143" - integrity sha512-V6jIbLhdJK86MaLh4Jpghi8ho5fGzt3imHOBu/x0jlBaPYqDoWz4RDXjmMOfnh+JWNaQleEAByZLV0QzBT4YQQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - - "@babel/plugin-transform-exponentiation-operator@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.23.3.tgz#ea0d978f6b9232ba4722f3dbecdd18f450babd18" - integrity sha512-5fhCsl1odX96u7ILKHBj4/Y8vipoqwsJMh4csSA8qFfxrZDEA4Ssku2DyNvMJSmZNOEBT750LfFPbtrnTP90BQ== - dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-export-namespace-from@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.23.4.tgz#084c7b25e9a5c8271e987a08cf85807b80283191" - integrity sha512-GzuSBcKkx62dGzZI1WVgTWvkkz84FZO5TC5T8dl/Tht/rAla6Dg/Mz9Yhypg+ezVACf/rgDuQt3kbWEv7LdUDQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - - "@babel/plugin-transform-flow-strip-types@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.23.3.tgz#cfa7ca159cc3306fab526fc67091556b51af26ff" - integrity sha512-26/pQTf9nQSNVJCrLB1IkHUKyPxR+lMrH2QDPG89+Znu9rAMbtrybdbWeE9bb7gzjmE5iXHEY+e0HUwM6Co93Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-flow" "^7.23.3" - - "@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.23.3.tgz#afe115ff0fbce735e02868d41489093c63e15559" - integrity sha512-X8jSm8X1CMwxmK878qsUGJRmbysKNbdpTv/O1/v0LuY/ZkZrng5WYiekYSdg9m09OTmDDUWeEDsTE+17WYbAZw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-function-name@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.23.3.tgz#8f424fcd862bf84cb9a1a6b42bc2f47ed630f8dc" - integrity sha512-I1QXp1LxIvt8yLaib49dRW5Okt7Q4oaxao6tFVKS/anCdEOMtYwWVKoiOA1p34GOWIZjUK0E+zCp7+l1pfQyiw== - dependencies: - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-json-strings@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.23.4.tgz#a871d9b6bd171976efad2e43e694c961ffa3714d" - integrity sha512-81nTOqM1dMwZ/aRXQ59zVubN9wHGqk6UtqRK+/q+ciXmRy8fSolhGVvG09HHRGo4l6fr/c4ZhXUQH0uFW7PZbg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-json-strings" "^7.8.3" - - "@babel/plugin-transform-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.23.3.tgz#8214665f00506ead73de157eba233e7381f3beb4" - integrity sha512-wZ0PIXRxnwZvl9AYpqNUxpZ5BiTGrYt7kueGQ+N5FiQ7RCOD4cm8iShd6S6ggfVIWaJf2EMk8eRzAh52RfP4rQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-logical-assignment-operators@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.23.4.tgz#e599f82c51d55fac725f62ce55d3a0886279ecb5" - integrity sha512-Mc/ALf1rmZTP4JKKEhUwiORU+vcfarFVLfcFiolKUo6sewoxSEgl36ak5t+4WamRsNr6nzjZXQjM35WsU+9vbg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - - "@babel/plugin-transform-member-expression-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.23.3.tgz#e37b3f0502289f477ac0e776b05a833d853cabcc" - integrity sha512-sC3LdDBDi5x96LA+Ytekz2ZPk8i/Ck+DEuDbRAll5rknJ5XRTSaPKEYwomLcs1AA8wg9b3KjIQRsnApj+q51Ag== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-modules-amd@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.23.3.tgz#e19b55436a1416829df0a1afc495deedfae17f7d" - integrity sha512-vJYQGxeKM4t8hYCKVBlZX/gtIY2I7mRGFNcm85sgXGMTBcoV3QdVtdpbcWEbzbfUIUZKwvgFT82mRvaQIebZzw== - dependencies: - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-modules-commonjs@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.23.3.tgz#661ae831b9577e52be57dd8356b734f9700b53b4" - integrity sha512-aVS0F65LKsdNOtcz6FRCpE4OgsP2OFnW46qNxNIX9h3wuzaNcSQsJysuMwqSibC98HPrf2vCgtxKNwS0DAlgcA== - dependencies: - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-simple-access" "^7.22.5" - - "@babel/plugin-transform-modules-systemjs@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.23.3.tgz#fa7e62248931cb15b9404f8052581c302dd9de81" - integrity sha512-ZxyKGTkF9xT9YJuKQRo19ewf3pXpopuYQd8cDXqNzc3mUNbOME0RKMoZxviQk74hwzfQsEe66dE92MaZbdHKNQ== - dependencies: - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-identifier" "^7.22.20" - - "@babel/plugin-transform-modules-umd@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.23.3.tgz#5d4395fccd071dfefe6585a4411aa7d6b7d769e9" - integrity sha512-zHsy9iXX2nIsCBFPud3jKn1IRPWg3Ing1qOZgeKV39m1ZgIdpJqvlWVeiHBZC6ITRG0MfskhYe9cLgntfSFPIg== - dependencies: - "@babel/helper-module-transforms" "^7.23.3" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-named-capturing-groups-regex@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.22.5.tgz#67fe18ee8ce02d57c855185e27e3dc959b2e991f" - integrity sha512-YgLLKmS3aUBhHaxp5hi1WJTgOUb/NCuDHzGT9z9WTt3YG+CPRhJs6nprbStx6DnWM4dh6gt7SU3sZodbZ08adQ== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-new-target@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.23.3.tgz#5491bb78ed6ac87e990957cea367eab781c4d980" - integrity sha512-YJ3xKqtJMAT5/TIZnpAR3I+K+WaDowYbN3xyxI8zxx/Gsypwf9B9h0VB+1Nh6ACAAPRS5NSRje0uVv5i79HYGQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-nullish-coalescing-operator@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.23.4.tgz#45556aad123fc6e52189ea749e33ce090637346e" - integrity sha512-jHE9EVVqHKAQx+VePv5LLGHjmHSJR76vawFPTdlxR/LVJPfOEGxREQwQfjuZEOPTwG92X3LINSh3M40Rv4zpVA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - - "@babel/plugin-transform-numeric-separator@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.23.4.tgz#03d08e3691e405804ecdd19dd278a40cca531f29" - integrity sha512-mps6auzgwjRrwKEZA05cOwuDc9FAzoyFS4ZsG/8F43bTLf/TgkJg7QXOrPO1JO599iA3qgK9MXdMGOEC8O1h6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - - "@babel/plugin-transform-object-rest-spread@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.23.4.tgz#2b9c2d26bf62710460bdc0d1730d4f1048361b83" - integrity sha512-9x9K1YyeQVw0iOXJlIzwm8ltobIIv7j2iLyP2jIhEbqPRQ7ScNgwQufU2I0Gq11VjyG4gI4yMXt2VFags+1N3g== - dependencies: - "@babel/compat-data" "^7.23.3" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.23.3" - - "@babel/plugin-transform-object-super@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.23.3.tgz#81fdb636dcb306dd2e4e8fd80db5b2362ed2ebcd" - integrity sha512-BwQ8q0x2JG+3lxCVFohg+KbQM7plfpBwThdW9A6TMtWwLsbDA01Ek2Zb/AgDN39BiZsExm4qrXxjk+P1/fzGrA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-replace-supers" "^7.22.20" - - "@babel/plugin-transform-optional-catch-binding@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.23.4.tgz#318066de6dacce7d92fa244ae475aa8d91778017" - integrity sha512-XIq8t0rJPHf6Wvmbn9nFxU6ao4c7WhghTR5WyV8SrJfUFzyxhCm4nhC+iAp3HFhbAKLfYpgzhJ6t4XCtVwqO5A== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - - "@babel/plugin-transform-optional-chaining@^7.23.3", "@babel/plugin-transform-optional-chaining@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.23.4.tgz#6acf61203bdfc4de9d4e52e64490aeb3e52bd017" - integrity sha512-ZU8y5zWOfjM5vZ+asjgAPwDaBjJzgufjES89Rs4Lpq63O300R/kOz30WCLo6BxxX6QVEilwSlpClnG5cZaikTA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - - "@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.20.7", "@babel/plugin-transform-parameters@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.23.3.tgz#83ef5d1baf4b1072fa6e54b2b0999a7b2527e2af" - integrity sha512-09lMt6UsUb3/34BbECKVbVwrT9bO6lILWln237z7sLaWnMsTi7Yc9fhX5DLpkJzAGfaReXI22wP41SZmnAA3Vw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-private-methods@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.23.3.tgz#b2d7a3c97e278bfe59137a978d53b2c2e038c0e4" - integrity sha512-UzqRcRtWsDMTLrRWFvUBDwmw06tCQH9Rl1uAjfh6ijMSmGYQ+fpdB+cnqRC8EMh5tuuxSv0/TejGL+7vyj+50g== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-private-property-in-object@^7.23.4": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.23.4.tgz#3ec711d05d6608fd173d9b8de39872d8dbf68bf5" - integrity sha512-9G3K1YqTq3F4Vt88Djx1UZ79PDyj+yKRnUy7cZGSMe+a7jkwD259uKKuUzQlPkGam7R+8RJwh5z4xO27fA1o2A== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - - "@babel/plugin-transform-property-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.23.3.tgz#54518f14ac4755d22b92162e4a852d308a560875" - integrity sha512-jR3Jn3y7cZp4oEWPFAlRsSWjxKe4PZILGBSd4nis1TsC5qeSpb+nrtihJuDhNI7QHiVbUaiXa0X2RZY3/TI6Nw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-react-constant-elements@^7.18.12": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-constant-elements/-/plugin-transform-react-constant-elements-7.23.3.tgz#5efc001d07ef0f7da0d73c3a86c132f73d28e43c" - integrity sha512-zP0QKq/p6O42OL94udMgSfKXyse4RyJ0JqbQ34zDAONWjyrEsghYEyTSK5FIpmXmCpB55SHokL1cRRKHv8L2Qw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-react-display-name@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.23.3.tgz#70529f034dd1e561045ad3c8152a267f0d7b6200" - integrity sha512-GnvhtVfA2OAtzdX58FJxU19rhoGeQzyVndw3GgtdECQvQFXPEZIOVULHVZGAYmOgmqjXpVpfocAbSjh99V/Fqw== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-react-jsx-development@^7.22.5": - version "7.22.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.22.5.tgz#e716b6edbef972a92165cd69d92f1255f7e73e87" - integrity sha512-bDhuzwWMuInwCYeDeMzyi7TaBgRQei6DqxhbyniL7/VG4RSS7HtSL2QbY4eESy1KJqlWt8g3xeEBGPuo+XqC8A== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.22.5" - - "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.22.15", "@babel/plugin-transform-react-jsx@^7.22.5": - version "7.23.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.23.4.tgz#393f99185110cea87184ea47bcb4a7b0c2e39312" - integrity sha512-5xOpoPguCZCRbo/JeHlloSkTA8Bld1J/E1/kLfD1nsuiW1m8tduTA1ERCgIZokDflX/IBzKcqR3l7VlRgiIfHA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-module-imports" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-jsx" "^7.23.3" - "@babel/types" "^7.23.4" - - "@babel/plugin-transform-react-pure-annotations@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.23.3.tgz#fabedbdb8ee40edf5da96f3ecfc6958e3783b93c" - integrity sha512-qMFdSS+TUhB7Q/3HVPnEdYJDQIk57jkntAwSuz9xfSE4n+3I+vHYCli3HoHawN1Z3RfCz/y1zXA/JXjG6cVImQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-regenerator@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.23.3.tgz#141afd4a2057298602069fce7f2dc5173e6c561c" - integrity sha512-KP+75h0KghBMcVpuKisx3XTu9Ncut8Q8TuvGO4IhY+9D5DFEckQefOuIsB/gQ2tG71lCke4NMrtIPS8pOj18BQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - regenerator-transform "^0.15.2" - - "@babel/plugin-transform-reserved-words@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.23.3.tgz#4130dcee12bd3dd5705c587947eb715da12efac8" - integrity sha512-QnNTazY54YqgGxwIexMZva9gqbPa15t/x9VS+0fsEFWplwVpXYZivtgl43Z1vMpc1bdPP2PP8siFeVcnFvA3Cg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.23.3.tgz#97d82a39b0e0c24f8a981568a8ed851745f59210" - integrity sha512-ED2fgqZLmexWiN+YNFX26fx4gh5qHDhn1O2gvEhreLW2iI63Sqm4llRLCXALKrCnbN4Jy0VcMQZl/SAzqug/jg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.23.3.tgz#41d17aacb12bde55168403c6f2d6bdca563d362c" - integrity sha512-VvfVYlrlBVu+77xVTOAoxQ6mZbnIq5FM0aGBSFEcIh03qHf+zNqA4DC/3XMUozTg7bZV3e3mZQ0i13VB6v5yUg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.22.5" - - "@babel/plugin-transform-sticky-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.23.3.tgz#dec45588ab4a723cb579c609b294a3d1bd22ff04" - integrity sha512-HZOyN9g+rtvnOU3Yh7kSxXrKbzgrm5X4GncPY1QOquu7epga5MxKHVpYu2hvQnry/H+JjckSYRb93iNfsioAGg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.23.3.tgz#5f0f028eb14e50b5d0f76be57f90045757539d07" - integrity sha512-Flok06AYNp7GV2oJPZZcP9vZdszev6vPBkHLwxwSpaIqx75wn6mUd3UFWsSsA0l8nXAKkyCmL/sR02m8RYGeHg== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-typeof-symbol@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.23.3.tgz#9dfab97acc87495c0c449014eb9c547d8966bca4" - integrity sha512-4t15ViVnaFdrPC74be1gXBSMzXk3B4Us9lP7uLRQHTFpV5Dvt33pn+2MyyNxmN3VTTm3oTrZVMUmuw3oBnQ2oQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-typescript@^7.23.3": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.23.5.tgz#83da13ef62a1ebddf2872487527094b31c9adb84" - integrity sha512-2fMkXEJkrmwgu2Bsv1Saxgj30IXZdJ+84lQcKKI7sm719oXs0BBw2ZENKdJdR1PjWndgLCEBNXJOri0fk7RYQA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.22.5" - "@babel/helper-create-class-features-plugin" "^7.23.5" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/plugin-syntax-typescript" "^7.23.3" - - "@babel/plugin-transform-unicode-escapes@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.23.3.tgz#1f66d16cab01fab98d784867d24f70c1ca65b925" - integrity sha512-OMCUx/bU6ChE3r4+ZdylEqAjaQgHAgipgW8nsCfu5pGqDcFytVd91AwRvUJSBZDz0exPGgnjoqhgRYLRjFZc9Q== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-unicode-property-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.23.3.tgz#19e234129e5ffa7205010feec0d94c251083d7ad" - integrity sha512-KcLIm+pDZkWZQAFJ9pdfmh89EwVfmNovFBcXko8szpBeF8z68kWIPeKlmSOkT9BXJxs2C0uk+5LxoxIv62MROA== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-unicode-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.23.3.tgz#26897708d8f42654ca4ce1b73e96140fbad879dc" - integrity sha512-wMHpNA4x2cIA32b/ci3AfwNgheiva2W0WUKWTK7vBHBhDKfPsc5cFGNWm69WBqpwd86u1qwZ9PWevKqm1A3yAw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/plugin-transform-unicode-sets-regex@^7.23.3": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.23.3.tgz#4fb6f0a719c2c5859d11f6b55a050cc987f3799e" - integrity sha512-W7lliA/v9bNR83Qc3q1ip9CQMZ09CcHDbHfbLRDNuAhn1Mvkr1ZNF7hPmztMQvtTGVLJ9m8IZqWsTkXOml8dbw== - dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - - "@babel/preset-env@^7.12.11", "@babel/preset-env@^7.15.0", "@babel/preset-env@^7.19.4": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.23.5.tgz#350a3aedfa9f119ad045b068886457e895ba0ca1" - integrity sha512-0d/uxVD6tFGWXGDSfyMD1p2otoaKmu6+GD+NfAx0tMaH+dxORnp7T9TaVQ6mKyya7iBtCIVxHjWT7MuzzM9z+A== - dependencies: - "@babel/compat-data" "^7.23.5" - "@babel/helper-compilation-targets" "^7.22.15" - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.23.5" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.23.3" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.23.3" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.23.3" - "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@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.23.3" - "@babel/plugin-syntax-import-attributes" "^7.23.3" - "@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-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.23.3" - "@babel/plugin-transform-async-generator-functions" "^7.23.4" - "@babel/plugin-transform-async-to-generator" "^7.23.3" - "@babel/plugin-transform-block-scoped-functions" "^7.23.3" - "@babel/plugin-transform-block-scoping" "^7.23.4" - "@babel/plugin-transform-class-properties" "^7.23.3" - "@babel/plugin-transform-class-static-block" "^7.23.4" - "@babel/plugin-transform-classes" "^7.23.5" - "@babel/plugin-transform-computed-properties" "^7.23.3" - "@babel/plugin-transform-destructuring" "^7.23.3" - "@babel/plugin-transform-dotall-regex" "^7.23.3" - "@babel/plugin-transform-duplicate-keys" "^7.23.3" - "@babel/plugin-transform-dynamic-import" "^7.23.4" - "@babel/plugin-transform-exponentiation-operator" "^7.23.3" - "@babel/plugin-transform-export-namespace-from" "^7.23.4" - "@babel/plugin-transform-for-of" "^7.23.3" - "@babel/plugin-transform-function-name" "^7.23.3" - "@babel/plugin-transform-json-strings" "^7.23.4" - "@babel/plugin-transform-literals" "^7.23.3" - "@babel/plugin-transform-logical-assignment-operators" "^7.23.4" - "@babel/plugin-transform-member-expression-literals" "^7.23.3" - "@babel/plugin-transform-modules-amd" "^7.23.3" - "@babel/plugin-transform-modules-commonjs" "^7.23.3" - "@babel/plugin-transform-modules-systemjs" "^7.23.3" - "@babel/plugin-transform-modules-umd" "^7.23.3" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.22.5" - "@babel/plugin-transform-new-target" "^7.23.3" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.23.4" - "@babel/plugin-transform-numeric-separator" "^7.23.4" - "@babel/plugin-transform-object-rest-spread" "^7.23.4" - "@babel/plugin-transform-object-super" "^7.23.3" - "@babel/plugin-transform-optional-catch-binding" "^7.23.4" - "@babel/plugin-transform-optional-chaining" "^7.23.4" - "@babel/plugin-transform-parameters" "^7.23.3" - "@babel/plugin-transform-private-methods" "^7.23.3" - "@babel/plugin-transform-private-property-in-object" "^7.23.4" - "@babel/plugin-transform-property-literals" "^7.23.3" - "@babel/plugin-transform-regenerator" "^7.23.3" - "@babel/plugin-transform-reserved-words" "^7.23.3" - "@babel/plugin-transform-shorthand-properties" "^7.23.3" - "@babel/plugin-transform-spread" "^7.23.3" - "@babel/plugin-transform-sticky-regex" "^7.23.3" - "@babel/plugin-transform-template-literals" "^7.23.3" - "@babel/plugin-transform-typeof-symbol" "^7.23.3" - "@babel/plugin-transform-unicode-escapes" "^7.23.3" - "@babel/plugin-transform-unicode-property-regex" "^7.23.3" - "@babel/plugin-transform-unicode-regex" "^7.23.3" - "@babel/plugin-transform-unicode-sets-regex" "^7.23.3" - "@babel/preset-modules" "0.1.6-no-external-plugins" - babel-plugin-polyfill-corejs2 "^0.4.6" - babel-plugin-polyfill-corejs3 "^0.8.5" - babel-plugin-polyfill-regenerator "^0.5.3" - core-js-compat "^3.31.0" - semver "^6.3.1" - - "@babel/preset-flow@^7.12.1": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.23.3.tgz#8084e08b9ccec287bd077ab288b286fab96ffab1" - integrity sha512-7yn6hl8RIv+KNk6iIrGZ+D06VhVY35wLVf23Cz/mMu1zOr7u4MMP4j0nZ9tLf8+4ZFpnib8cFYgB/oYg9hfswA== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-flow-strip-types" "^7.23.3" - - "@babel/preset-modules@0.1.6-no-external-plugins": - version "0.1.6-no-external-plugins" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.6-no-external-plugins.tgz#ccb88a2c49c817236861fee7826080573b8a923a" - integrity sha512-HrcgcIESLm9aIR842yhJ5RWan/gebQUJ6E/E5+rf0y9o6oj7w0Br+sWuL6kEQ/o/AdfvR1Je9jG18/gnpwjEyA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/types" "^7.4.4" - esutils "^2.0.2" - - "@babel/preset-react@^7.12.10", "@babel/preset-react@^7.14.5", "@babel/preset-react@^7.18.6": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.23.3.tgz#f73ca07e7590f977db07eb54dbe46538cc015709" - integrity sha512-tbkHOS9axH6Ysf2OUEqoSZ6T3Fa2SrNH6WTWSPBboxKzdxNc9qOICeLXkNG0ZEwbQ1HY8liwOce4aN/Ceyuq6w== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-transform-react-display-name" "^7.23.3" - "@babel/plugin-transform-react-jsx" "^7.22.15" - "@babel/plugin-transform-react-jsx-development" "^7.22.5" - "@babel/plugin-transform-react-pure-annotations" "^7.23.3" - - "@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.15.0", "@babel/preset-typescript@^7.18.6": - version "7.23.3" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.23.3.tgz#14534b34ed5b6d435aa05f1ae1c5e7adcc01d913" - integrity sha512-17oIGVlqz6CchO9RFYn5U6ZpWRZIngayYCtrPRSgANSwC2V1Jb+iP74nVxzzXJte8b8BYxrL1yY96xfhTBrNNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.22.5" - "@babel/helper-validator-option" "^7.22.15" - "@babel/plugin-syntax-jsx" "^7.23.3" - "@babel/plugin-transform-modules-commonjs" "^7.23.3" - "@babel/plugin-transform-typescript" "^7.23.3" - - "@babel/register@^7.12.1": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.22.15.tgz#c2c294a361d59f5fa7bcc8b97ef7319c32ecaec7" - integrity sha512-V3Q3EqoQdn65RCgTLwauZaTfd1ShhwPmbBv+1dkZV/HpCGMKVyn6oFcRlI7RaKqiDQjX2Qd3AuoEguBgdjIKlg== - dependencies: - clone-deep "^4.0.1" - find-cache-dir "^2.0.0" - make-dir "^2.1.0" - pirates "^4.0.5" - source-map-support "^0.5.16" - - "@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" - integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== - - "@babel/runtime@7.7.2": - version "7.7.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" - integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== - dependencies: - regenerator-runtime "^0.13.2" - - "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.3", "@babel/runtime@^7.18.9", "@babel/runtime@^7.21.0", "@babel/runtime@^7.23.2", "@babel/runtime@^7.23.4", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.3", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.23.5.tgz#11edb98f8aeec529b82b211028177679144242db" - integrity sha512-NdUTHcPe4C99WxPub+K9l9tK5/lV4UXIoaHSYgzco9BCyjKAAwzdBI+wWtYqHt7LJdbo74ZjRPJgzVweq1sz0w== - dependencies: - regenerator-runtime "^0.14.0" - - "@babel/runtime@~7.5.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" - integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== - dependencies: - regenerator-runtime "^0.13.2" - - "@babel/template@^7.12.7", "@babel/template@^7.22.15", "@babel/template@^7.3.3": - version "7.22.15" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.22.15.tgz#09576efc3830f0430f4548ef971dde1350ef2f38" - integrity sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w== - dependencies: - "@babel/code-frame" "^7.22.13" - "@babel/parser" "^7.22.15" - "@babel/types" "^7.22.15" - - "@babel/traverse@^7.1.6", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.23.5", "@babel/traverse@^7.7.2": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.23.5.tgz#f546bf9aba9ef2b042c0e00d245990c15508e7ec" - integrity sha512-czx7Xy5a6sapWWRx61m1Ke1Ra4vczu1mCTtJam5zRTBOonfdJ+S/B6HYmGYu3fJtr8GGET3si6IhgWVBhJ/m8w== - dependencies: - "@babel/code-frame" "^7.23.5" - "@babel/generator" "^7.23.5" - "@babel/helper-environment-visitor" "^7.22.20" - "@babel/helper-function-name" "^7.23.0" - "@babel/helper-hoist-variables" "^7.22.5" - "@babel/helper-split-export-declaration" "^7.22.6" - "@babel/parser" "^7.23.5" - "@babel/types" "^7.23.5" - debug "^4.1.0" - globals "^11.1.0" - - "@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.7", "@babel/types@^7.22.15", "@babel/types@^7.22.19", "@babel/types@^7.22.5", "@babel/types@^7.23.0", "@babel/types@^7.23.4", "@babel/types@^7.23.5", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.23.5" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.23.5.tgz#48d730a00c95109fa4393352705954d74fb5b602" - integrity sha512-ON5kSOJwVO6xXVRTvOI0eOnWe7VdUcIpsovGo9U/Br4Ie4UVFQTboO2cYnDhAGU6Fp+UxSiT+pMft0SMHfuq6w== - dependencies: - "@babel/helper-string-parser" "^7.23.4" - "@babel/helper-validator-identifier" "^7.22.20" - to-fast-properties "^2.0.0" - - "@base2/pretty-print-object@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" - integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== - - "@bcoe/v8-coverage@^0.2.3": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39" - integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw== - - "@chain-registry/keplr@1.25.0": - version "1.25.0" - resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.25.0.tgz#581a10760951c1d1185c6874199df08283a21d46" - integrity sha512-mEr5HypYEaQnYcuGp3PBTqo67WV0MQyBP2dOtl+ab2fkyB5PYa01D5B2Yu5V6V7eXLmKDvvvfiRO23NWQzFHxg== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.17.0" - "@keplr-wallet/cosmos" "0.12.28" - "@keplr-wallet/crypto" "0.12.28" - semver "^7.5.0" - - "@chain-registry/types@0.17.0", "@chain-registry/types@^0.17.0": - version "0.17.0" - resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.17.0.tgz#bbe9176a6d30a491259fab1fcdcee2b7edf6141f" - integrity sha512-lavACU4oDxioUy8lZOFZN0Vrr2qR+Dg2yEh/mkrPfOldcioavREXJou0elDyyXwq4pGLC5YQ+IISCtQ4Du0bdw== - dependencies: - "@babel/runtime" "^7.21.0" - - "@cnakazawa/watch@^1.0.3": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" - integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== - dependencies: - exec-sh "^0.3.2" - minimist "^1.2.0" - - "@colors/colors@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" - integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== - - "@confio/ics23@^0.6.3", "@confio/ics23@^0.6.8": - version "0.6.8" - resolved "https://registry.yarnpkg.com/@confio/ics23/-/ics23-0.6.8.tgz#2a6b4f1f2b7b20a35d9a0745bb5a446e72930b3d" - integrity sha512-wB6uo+3A50m0sW/EWcU64xpV/8wShZ6bMTa7pF8eYsTrSkQA7oLUIJcs/wb8g4y2Oyq701BaGiO6n/ak5WXO1w== - dependencies: - "@noble/hashes" "^1.0.0" - protobufjs "^6.8.8" - - "@cosmjs/amino@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.25.6.tgz#cdf9632253bfab7b1d2ef967124953d7bf16351f" - integrity sha512-9dXN2W7LHjDtJUGNsQ9ok0DfxeN3ca/TXnxCR3Ikh/5YqBqxI8Gel1J9PQO9L6EheYyh045Wff4bsMaLjyEeqQ== - dependencies: - "@cosmjs/crypto" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - - "@cosmjs/amino@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.29.5.tgz#053b4739a90b15b9e2b781ccd484faf64bd49aec" - integrity sha512-Qo8jpC0BiziTSUqpkNatBcwtKNhCovUnFul9SlT/74JUCdLYaeG5hxr3q1cssQt++l4LvlcpF+OUXL48XjNjLw== - dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - - "@cosmjs/amino@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/amino/-/amino-0.32.0.tgz#1121b73f7d7c5287a599fde1194c8f78af0c0cb5" - integrity sha512-i1ehEZLQo8HUGY78eum+1ZrDQ48QSkHKy0zOTBOMqce6TiwACIC5kOjRSOWdRQDILcPFzPVrbS2dIgtrdd0ykg== - dependencies: - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - - "@cosmjs/cosmwasm-launchpad@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-launchpad/-/cosmwasm-launchpad-0.25.6.tgz#b03a96c8d5b5b4742ec4c56b4a01b1f4f33f7f57" - integrity sha512-rzpYg/A8tvXbY6p89LabPB1mqCtTUv+33nN+s+VWMH0oOl0LSIgLE0yIT61kwTaf2dWQvRVeFaiRLFC72/w/zw== - dependencies: - "@cosmjs/crypto" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/launchpad" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - pako "^2.0.2" - - "@cosmjs/cosmwasm-stargate@^0.25.5": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.25.6.tgz#26a788213833aaffc4bc1a87df650741e0b8fd63" - integrity sha512-STaxur5Xk5hqndLEztpa1TqvpdQyg2xD//2ZNFw2fgxf1JQtP0RfFbA3bnBkYwbGARx5cnng8QeZmSUcXnTVxA== - dependencies: - "@cosmjs/amino" "^0.25.6" - "@cosmjs/cosmwasm-launchpad" "^0.25.6" - "@cosmjs/crypto" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/proto-signing" "^0.25.6" - "@cosmjs/stargate" "^0.25.6" - "@cosmjs/tendermint-rpc" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - long "^4.0.0" - pako "^2.0.2" - protobufjs "~6.10.2" - - "@cosmjs/cosmwasm-stargate@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.0.tgz#b35bd57edf9aac9008990b366bfad9ece35d71b1" - integrity sha512-XcCedSMNV5/choH3JCXAiwytBq0uqGI2k5tzifjUifnwd4v58hVA4NUIxUaXk4nWJ5Izd8iylCSmR2owH77Eqw== - dependencies: - "@cosmjs/amino" "^0.32.0" - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/proto-signing" "^0.32.0" - "@cosmjs/stargate" "^0.32.0" - "@cosmjs/tendermint-rpc" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - cosmjs-types "^0.9.0" - pako "^2.0.2" - - "@cosmjs/crypto@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.25.6.tgz#695d2d0d2195bdbdd5825d415385646244900bbb" - integrity sha512-ec+YcQLrg2ibcxtNrh4FqQnG9kG9IE/Aik2NH6+OXQdFU/qFuBTxSFcKDgzzBOChwlkXwydllM9Jjbp+dgIzRw== - dependencies: - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - bip39 "^3.0.2" - bn.js "^4.11.8" - elliptic "^6.5.3" - js-sha3 "^0.8.0" - libsodium-wrappers "^0.7.6" - ripemd160 "^2.0.2" - sha.js "^2.4.11" - - "@cosmjs/crypto@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.29.5.tgz#ab99fc382b93d8a8db075780cf07487a0f9519fd" - integrity sha512-2bKkaLGictaNL0UipQCL6C1afaisv6k8Wr/GCLx9FqiyFkh9ZgRHDyetD64ZsjnWV/N/D44s/esI+k6oPREaiQ== - dependencies: - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - "@noble/hashes" "^1" - bn.js "^5.2.0" - elliptic "^6.5.4" - libsodium-wrappers "^0.7.6" - - "@cosmjs/crypto@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/crypto/-/crypto-0.32.0.tgz#61de86e158932321aa4f7a49ff09d726a57c33af" - integrity sha512-h8Fuff9QtHeHAZXB8Mjpk8sYQSqOd484GtD1NAJRCqfXifanNUeZOaXAQkcHbA0eg/IYa+ev7+gOPxm9HkSshQ== - dependencies: - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - "@noble/hashes" "^1" - bn.js "^5.2.0" - elliptic "^6.5.4" - libsodium-wrappers-sumo "^0.7.11" - - "@cosmjs/encoding@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.25.6.tgz#da741a33eaf063a6d3611d7d68db5ca3938e0ef5" - integrity sha512-0imUOB8XkUstI216uznPaX1hqgvLQ2Xso3zJj5IV5oJuNlsfDj9nt/iQxXWbJuettc6gvrFfpf+Vw2vBZSZ75g== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - readonly-date "^1.0.0" - - "@cosmjs/encoding@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.29.5.tgz#009a4b1c596cdfd326f30ccfa79f5e56daa264f2" - integrity sha512-G4rGl/Jg4dMCw5u6PEZHZcoHnUBlukZODHbm/wcL4Uu91fkn5jVo5cXXZcvs4VCkArVGrEj/52eUgTZCmOBGWQ== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - readonly-date "^1.0.0" - - "@cosmjs/encoding@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/encoding/-/encoding-0.32.0.tgz#1b6f5b7e3f4c8c01c7863202e7eb0de9ad91a252" - integrity sha512-dlurY3BOnv/5JTz3ziGPxvJAsfaXHcOpYP+Fqwo2OHGoWxpQJgJub4QG5V530ZQHliX+6Wqp97lFEwstpISedg== - dependencies: - base64-js "^1.3.0" - bech32 "^1.1.4" - readonly-date "^1.0.0" - - "@cosmjs/json-rpc@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.25.6.tgz#4f888630e84ee114b164758ec5b48f134068656c" - integrity sha512-Mn9og3/IEzC6jWoYXs0ONqFJc8HxVjXzrZPLgaRRdMZEUBvctxdhynau1wbE4LdkYQHbu4aiRu1q1jMYGFAj4A== - dependencies: - "@cosmjs/stream" "^0.25.6" - xstream "^11.14.0" - - "@cosmjs/json-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.29.5.tgz#5e483a9bd98a6270f935adf0dfd8a1e7eb777fe4" - integrity sha512-C78+X06l+r9xwdM1yFWIpGl03LhB9NdM1xvZpQHwgCOl0Ir/WV8pw48y3Ez2awAoUBRfTeejPe4KvrE6NoIi/w== - dependencies: - "@cosmjs/stream" "^0.29.5" - xstream "^11.14.0" - - "@cosmjs/json-rpc@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/json-rpc/-/json-rpc-0.32.0.tgz#733548f54db7cdc581d56e7e0e3d6a0b6ff42163" - integrity sha512-BhnPvgbNPjQZnpzstn6+uLGsP2E4IwREbP7L95yTid+IdTrdnFcF8Ol6xXBWsUtVHtUibX+rbK3wSSgEAV0OBA== - dependencies: - "@cosmjs/stream" "^0.32.0" - xstream "^11.14.0" - - "@cosmjs/launchpad@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/launchpad/-/launchpad-0.25.6.tgz#c75f5d21be57af55fcb892f929520fa97f2d5bcc" - integrity sha512-4Yhn4cX50UE6jZz/hWqKeeCmvrlrz0BBwOdYX/29k25FqP+oLAow1xKm6UxgYuuAq8Pg/bUvswxSqwegZJTb6g== - dependencies: - "@cosmjs/amino" "^0.25.6" - "@cosmjs/crypto" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - axios "^0.21.1" - fast-deep-equal "^3.1.3" - - "@cosmjs/math@^0.25.5", "@cosmjs/math@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.25.6.tgz#25c7b106aaded889a5b80784693caa9e654b0c28" - integrity sha512-Fmyc9FJ8KMU34n7rdapMJrT/8rx5WhMw2F7WLBu7AVLcBh0yWsXIcMSJCoPHTOnMIiABjXsnrrwEaLrOOBfu6A== - dependencies: - bn.js "^4.11.8" - - "@cosmjs/math@^0.26.2": - version "0.26.8" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.26.8.tgz#29d7fc8df96a0da25f8b110482d510af93505b0d" - integrity sha512-AfooIaqhOks5xPDc4kDEXje/90iPm2STu+0YWvDStEEib2xxPTtXU3OuK+KpJ3CCFfQwbKCrzEIzJWCYmTs7mw== - dependencies: - bn.js "^5.2.0" - - "@cosmjs/math@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.29.5.tgz#722c96e080d6c2b62215ce9f4c70da7625b241b6" - integrity sha512-2GjKcv+A9f86MAWYLUkjhw1/WpRl2R1BTb3m9qPG7lzMA7ioYff9jY5SPCfafKdxM4TIQGxXQlYGewQL16O68Q== - dependencies: - bn.js "^5.2.0" - - "@cosmjs/math@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/math/-/math-0.32.0.tgz#71f960d59813e49d9736674c5ce40b7b63ee0cf4" - integrity sha512-3h12ENHm1B2TuzZY0JrjGyShIkdUAJDmb/xnSPBBJYZH6ZWL4DFLkq2gISq8XSVCBhuNVv4R+cSCdXs8/vSUTw== - dependencies: - bn.js "^5.2.0" - - "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" - integrity sha512-JpQ+Vnv9s6i3x8f3Jo0lJZ3VMnj3R5sMgX+8ti1LtB7qEYRR85qbDrEG9hDGIKqJJabvrAuCHnO6hYi0vJEJHA== - dependencies: - "@cosmjs/amino" "^0.25.6" - long "^4.0.0" - protobufjs "~6.10.2" - - "@cosmjs/proto-signing@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.29.5.tgz#af3b62a46c2c2f1d2327d678b13b7262db1fe87c" - integrity sha512-QRrS7CiKaoETdgIqvi/7JC2qCwCR7lnWaUsTzh/XfRy3McLkEd+cXbKAW3cygykv7IN0VAEIhZd2lyIfT8KwNA== - dependencies: - "@cosmjs/amino" "^0.29.5" - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" - long "^4.0.0" - - "@cosmjs/proto-signing@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.0.tgz#3f182552257b68d040d945913356c399281df0ce" - integrity sha512-9401CI0U5rvKMmYrEN4DAl7wvRd5PwfOTPgxoee+O0d3LzK4FUbTjnNIM7DeUi0zaQw/qU3vSbA3ZcMqPifSbQ== - dependencies: - "@cosmjs/amino" "^0.32.0" - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - cosmjs-types "^0.9.0" - - "@cosmjs/socket@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.25.6.tgz#7876bc24e1f16315fbb9e97bd63dea65ba90647d" - integrity sha512-hu+pW3Fy0IuhstXgxnZ2Iq0RUnGYoTWfqrxbTsgXBJge4MpEQs2YwGXgJZPMJXedBQivG0tU3r/Wvam0EWuRkQ== - dependencies: - "@cosmjs/stream" "^0.25.6" - isomorphic-ws "^4.0.1" - ws "^7" - xstream "^11.14.0" - - "@cosmjs/socket@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.29.5.tgz#a48df6b4c45dc6a6ef8e47232725dd4aa556ac2d" - integrity sha512-5VYDupIWbIXq3ftPV1LkS5Ya/T7Ol/AzWVhNxZ79hPe/mBfv1bGau/LqIYOm2zxGlgm9hBHOTmWGqNYDwr9LNQ== - dependencies: - "@cosmjs/stream" "^0.29.5" - isomorphic-ws "^4.0.1" - ws "^7" - xstream "^11.14.0" - - "@cosmjs/socket@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.32.0.tgz#45bfaa45ae89347e5134cf115fdf2dc680559207" - integrity sha512-fzb9pBJ6RNYdMIpjCv6NHdQ7C9xSJvP0tF/Tfmmq0yexxl/xDkqSghaDub/os7QzN23RHjTreWjrz9Gov4Z5Vg== - dependencies: - "@cosmjs/stream" "^0.32.0" - isomorphic-ws "^4.0.1" - ws "^7" - xstream "^11.14.0" - - "@cosmjs/stargate@^0.25.5", "@cosmjs/stargate@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.25.6.tgz#ed7428aafd8fe1c12dc4b86f7967deb88117f61a" - integrity sha512-+LM1sK6vGuotJF9fBCBlaDL/yJhfzCV6KbsaWt3teHAKZhKYOd/9mKGiB4H9bfg4h3r+e+FZGiNkH/mdXkcgEw== - dependencies: - "@confio/ics23" "^0.6.3" - "@cosmjs/amino" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/proto-signing" "^0.25.6" - "@cosmjs/stream" "^0.25.6" - "@cosmjs/tendermint-rpc" "^0.25.6" - "@cosmjs/utils" "^0.25.6" - long "^4.0.0" - protobufjs "~6.10.2" - - "@cosmjs/stargate@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.29.5.tgz#d597af1c85a3c2af7b5bdbec34d5d40692cc09e4" - integrity sha512-hjEv8UUlJruLrYGJcUZXM/CziaINOKwfVm2BoSdUnNTMxGvY/jC1ABHKeZUYt9oXHxEJ1n9+pDqzbKc8pT0nBw== - dependencies: - "@confio/ics23" "^0.6.8" - "@cosmjs/amino" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/proto-signing" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/tendermint-rpc" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" - long "^4.0.0" - protobufjs "~6.11.3" - xstream "^11.14.0" - - "@cosmjs/stargate@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/stargate/-/stargate-0.32.0.tgz#2f1e1af50ad3156747e377a350b39673c664d324" - integrity sha512-Yo3l+A4vdy3ql30cIanY/j2uD3zxRXTQPrn2YUc67qCxacFkf7Fn3N9GdI7D/B2LQlguf/B5OwheizzWucapkw== - dependencies: - "@confio/ics23" "^0.6.8" - "@cosmjs/amino" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/proto-signing" "^0.32.0" - "@cosmjs/stream" "^0.32.0" - "@cosmjs/tendermint-rpc" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - cosmjs-types "^0.9.0" - xstream "^11.14.0" - - "@cosmjs/stream@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.25.6.tgz#1bf7536ed919be3fd7fbffa477c98ef5a93eac70" - integrity sha512-2mXIzf+WaFd+GSrRaJJETVXeZoC5sosuKChFERxSY8zXQ/f3OaG9J6m+quHpPbU3nAIEtnF1jgBVqJiD+NKwGQ== - dependencies: - xstream "^11.14.0" - - "@cosmjs/stream@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.29.5.tgz#350981cac496d04939b92ee793b9b19f44bc1d4e" - integrity sha512-TToTDWyH1p05GBtF0Y8jFw2C+4783ueDCmDyxOMM6EU82IqpmIbfwcdMOCAm0JhnyMh+ocdebbFvnX/sGKzRAA== - dependencies: - xstream "^11.14.0" - - "@cosmjs/stream@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/stream/-/stream-0.32.0.tgz#4fba49708172dffc41a37bbf63f69c8c3186330a" - integrity sha512-df3Svup2QwVr6EqmOzv3KTL0sOxN2sKvz4XJItUeDDxXbcEtTB0+kypmsRQihpXCCmetNArdnvbvkPWxsKCq0w== - dependencies: - xstream "^11.14.0" - - "@cosmjs/tendermint-rpc@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" - integrity sha512-wsvxTI7DReWJu+SVlXLblzh5NJppnh1mljuaTHodMf7HBxrXdbcCcBAO8oMbMgEqOASEY5G+z51wktxhrn9RtA== - dependencies: - "@cosmjs/crypto" "^0.25.6" - "@cosmjs/encoding" "^0.25.6" - "@cosmjs/json-rpc" "^0.25.6" - "@cosmjs/math" "^0.25.6" - "@cosmjs/socket" "^0.25.6" - "@cosmjs/stream" "^0.25.6" - axios "^0.21.1" - readonly-date "^1.0.0" - xstream "^11.14.0" - - "@cosmjs/tendermint-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" - integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== - dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/json-rpc" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/socket" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - axios "^0.21.2" - readonly-date "^1.0.0" - xstream "^11.14.0" - - "@cosmjs/tendermint-rpc@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.0.tgz#9acf9030ae20631679dfbaa0611ba618ffe3d192" - integrity sha512-bGH3C0CymIzkROltbqw1iXOEkXJkpjdngJu3hdCdB7bD9xbCWOqB9mT+aLpjNAkzSEAHR4nrWv1JF+3PU2Eggg== - dependencies: - "@cosmjs/crypto" "^0.32.0" - "@cosmjs/encoding" "^0.32.0" - "@cosmjs/json-rpc" "^0.32.0" - "@cosmjs/math" "^0.32.0" - "@cosmjs/socket" "^0.32.0" - "@cosmjs/stream" "^0.32.0" - "@cosmjs/utils" "^0.32.0" - axios "^1.6.0" - readonly-date "^1.0.0" - xstream "^11.14.0" - - "@cosmjs/utils@^0.25.6": - version "0.25.6" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.25.6.tgz#934d9a967180baa66163847616a74358732227ca" - integrity sha512-ofOYiuxVKNo238vCPPlaDzqPXy2AQ/5/nashBo5rvPZJkxt9LciGfUEQWPCOb1BIJDNx2Dzu0z4XCf/dwzl0Dg== - - "@cosmjs/utils@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.29.5.tgz#3fed1b3528ae8c5f1eb5d29b68755bebfd3294ee" - integrity sha512-m7h+RXDUxOzEOGt4P+3OVPX7PuakZT3GBmaM/Y2u+abN3xZkziykD/NvedYFvvCCdQo714XcGl33bwifS9FZPQ== - - "@cosmjs/utils@^0.32.0": - version "0.32.0" - resolved "https://registry.yarnpkg.com/@cosmjs/utils/-/utils-0.32.0.tgz#128c0d672a289c99239502d06f045e7cdb60f45e" - integrity sha512-9EWhdTtpaNBSDf2i8nwkWWHfgXGumTVAQe4KuC/R0p3A842MiZhpMAU1WxaZkEO0fcvTbfnM/svAIMVcilDtkw== - - "@cosmos-kit/core@^2.7.7": - version "2.7.7" - resolved "https://registry.yarnpkg.com/@cosmos-kit/core/-/core-2.7.7.tgz#150876ddde226fd236e71a8725a6182ff4722f84" - integrity sha512-i/L66ieq3G8lB1eKXqzEYqFVQp0crsR2IuwqDXxytmy02WAydCZInAGiPXKklCBWecWGR6z305NJUynaWmYjmQ== - dependencies: - "@chain-registry/types" "0.17.0" - "@walletconnect/types" "2.10.4" - bowser "2.11.0" - events "3.3.0" - uuid "^9.0.1" - - "@cosmos-kit/keplr-extension@^2.5.10": - version "2.5.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.5.10.tgz#4e27d351c3f49adc9eae6167c013dd64672bab28" - integrity sha512-Y9c8NQEoHkUNn3ziurMn7dI7JSkR6JVe8Ji/lnFSVqDqc+dOuGEpVqhn9wSJlZc6xuFm88vj9ry+83XbHuxMDA== - dependencies: - "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.7" - - "@cosmos-kit/keplr-mobile@^2.4.10": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.4.10.tgz#2444448a3ca77da6b8274ed6a0b1be3c0e325d25" - integrity sha512-+AM7q9bDGMu8aKjU126sACVtvOMQ8+Ex0s1GL5Icybqn/6WDDpmOo801k+nvznx7mwaQP7l0n6OUnwAjU3eAjg== - dependencies: - "@chain-registry/keplr" "1.25.0" - "@cosmos-kit/core" "^2.7.7" - "@cosmos-kit/walletconnect" "^2.4.10" - - "@cosmos-kit/keplr@^2.4.7": - version "2.4.12" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.4.12.tgz#9e063ede4878fa2c87df94cf09787b5e48738ef5" - integrity sha512-bx5YiWN6BiTQjRTIlWxHgWCeWp0fdT0kRxayj6yMkfGWWmBE9kO6mAWmWjB6+zvKyvRRyddT5ry4WW7Gi7gnGw== - dependencies: - "@cosmos-kit/keplr-extension" "^2.5.10" - "@cosmos-kit/keplr-mobile" "^2.4.10" - - "@cosmos-kit/react-lite@^2.5.9": - version "2.5.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.5.9.tgz#1ee73d8db7e7b298c876ac12ff2133fb1bcbe847" - integrity sha512-2RWvR47RCFSyJKtit5g5TjRG504BXDj3mruo5Ukyt5p0n6O+kIDUyz0o1HlVUD4wfxRIr4jgYWU52EDYeYGavQ== - dependencies: - "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.7" - - "@cosmos-kit/react@^2.9.6": - version "2.9.11" - resolved "https://registry.yarnpkg.com/@cosmos-kit/react/-/react-2.9.11.tgz#87484a62f46a442d8af7706ccf3ad38fb112b422" - integrity sha512-jlKQ76i0Cb5BxVX7hOX+MwgMQxSxGzg4maORuswD3hh4S4Qi4L2MkDPUIq294Oeaqn8IlTXVjyfVpIcpIwaAtQ== - dependencies: - "@chain-registry/types" "0.17.0" - "@cosmos-kit/core" "^2.7.7" - "@cosmos-kit/react-lite" "^2.5.9" - "@react-icons/all-files" "^4.1.0" - - "@cosmos-kit/walletconnect@^2.4.10": - version "2.4.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.4.10.tgz#8de2af854a094a2000c9647f9de6d2a7f279bd8e" - integrity sha512-i/vuZPQ8XhLfh0Llv1Ri7FXjqdvh60mfroKnTlqxO2LchxNcIw3MRZkZKuhalgZNQCPRe1ME2bOxwYmat55/Jg== - dependencies: - "@cosmos-kit/core" "^2.7.7" - "@walletconnect/sign-client" "^2.9.0" - "@walletconnect/types" "2.10.4" - "@walletconnect/utils" "^2.9.0" - events "3.3.0" - - "@cspotcode/source-map-support@^0.8.0": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" - integrity sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw== - dependencies: - "@jridgewell/trace-mapping" "0.3.9" - - "@design-systems/utils@2.12.0": - version "2.12.0" - resolved "https://registry.yarnpkg.com/@design-systems/utils/-/utils-2.12.0.tgz#955c108be07cb8f01532207cbfea8f848fa760c9" - integrity sha512-Y/d2Zzr+JJfN6u1gbuBUb1ufBuLMJJRZQk+dRmw8GaTpqKx5uf7cGUYGTwN02dIb3I+Tf+cW8jcGBTRiFxdYFg== - dependencies: - "@babel/runtime" "^7.11.2" - clsx "^1.0.4" - focus-lock "^0.8.0" - react-merge-refs "^1.0.0" - - "@devtools-ds/object-inspector@^1.1.2": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/object-inspector/-/object-inspector-1.2.1.tgz#2b380ed475d898d2828e7855c2dc2c82f091d326" - integrity sha512-nrAVVj4c4Iv9958oE4HA7Mk6T+4Mn/4xBRlFDeX4Ps6SMzsqO8bKhw/y6+bOfNyb/TYHmC0/pnPS68GDVZcg5Q== - dependencies: - "@babel/runtime" "7.7.2" - "@devtools-ds/object-parser" "^1.2.1" - "@devtools-ds/themes" "^1.2.1" - "@devtools-ds/tree" "^1.2.1" - clsx "1.1.0" - - "@devtools-ds/object-parser@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/object-parser/-/object-parser-1.2.1.tgz#5ab709a2db807ce99cb12bf35511379d6e47a3b8" - integrity sha512-6qB+THhQfJqXyHn8wpJ1KFxXcbpLTlRyCVmkelhr0c1+MPLZcC+0XJxpVZ1AOEXPa6CWVZThBYSCvnYQEvfCqw== - dependencies: - "@babel/runtime" "~7.5.4" - - "@devtools-ds/themes@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/themes/-/themes-1.2.1.tgz#060a0a1a2b38f68b01deca62240d2c94585f00dd" - integrity sha512-4/KFsHnokGxUq8CSCchINcVBb6fQ74HtEfNtMuitGtGg3VCRV0kaVSOsz6wzShzhLEaVLd5coSRQKaZj7yx72w== - dependencies: - "@babel/runtime" "~7.5.4" - "@design-systems/utils" "2.12.0" - clsx "1.1.0" - - "@devtools-ds/tree@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@devtools-ds/tree/-/tree-1.2.1.tgz#88d44dbbf96101fd8f18af92e514ed9dd00c8ceb" - integrity sha512-2ZHG28oWJno0gD+20EoSJO0yffm6JS5r7YzYhGMkrnLGvcCRZuwXSxMmIshSPLIR0cjidiAfGCqsrigHIR4ZQA== - dependencies: - "@babel/runtime" "7.7.2" - "@devtools-ds/themes" "^1.2.1" - clsx "1.1.0" - - "@discoveryjs/json-ext@^0.5.0", "@discoveryjs/json-ext@^0.5.3": - version "0.5.7" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" - integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== - - "@emotion/babel-plugin@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/babel-plugin/-/babel-plugin-11.11.0.tgz#c2d872b6a7767a9d176d007f5b31f7d504bb5d6c" - integrity sha512-m4HEDZleaaCH+XgDDsPF15Ht6wTLsgDTeR3WYj9Q/k76JtWhrJjcP4+/XlG8LGT/Rol9qUfOIztXeA84ATpqPQ== - dependencies: - "@babel/helper-module-imports" "^7.16.7" - "@babel/runtime" "^7.18.3" - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/serialize" "^1.1.2" - babel-plugin-macros "^3.1.0" - convert-source-map "^1.5.0" - escape-string-regexp "^4.0.0" - find-root "^1.1.0" - source-map "^0.5.7" - stylis "4.2.0" - - "@emotion/cache@^11.11.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.11.0.tgz#809b33ee6b1cb1a625fef7a45bc568ccd9b8f3ff" - integrity sha512-P34z9ssTCBi3e9EI1ZsWpNHcfY1r09ZO0rZbRO2ob3ZQMnFI35jB536qoXbkdesr5EUhYi22anuEJuyxifaqAQ== - dependencies: - "@emotion/memoize" "^0.8.1" - "@emotion/sheet" "^1.2.2" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" - stylis "4.2.0" - - "@emotion/hash@^0.9.0", "@emotion/hash@^0.9.1": - version "0.9.1" - resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.9.1.tgz#4ffb0055f7ef676ebc3a5a91fb621393294e2f43" - integrity sha512-gJB6HLm5rYwSLI6PQa+X1t5CFGrv1J1TWG+sOyMCeKz2ojaj6Fnl/rZEspogG+cvqbt4AE/2eIyD2QfLKTBNlQ== - - "@emotion/is-prop-valid@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.1.tgz#23116cf1ed18bfeac910ec6436561ecb1a3885cc" - integrity sha512-61Mf7Ufx4aDxx1xlDeOm8aFFigGHE4z+0sKCa+IHCeZKiyP9RLD0Mmx7m8b9/Cf37f7NAvQOOJAbQQGVr5uERw== - dependencies: - "@emotion/memoize" "^0.8.1" - - "@emotion/memoize@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.8.1.tgz#c1ddb040429c6d21d38cc945fe75c818cfb68e17" - integrity sha512-W2P2c/VRW1/1tLox0mVUalvnWXxavmv/Oum2aPsRcoDJuob75FC3Y8FbpfLwUegRcxINtGUMPq0tFCvYNTBXNA== - - "@emotion/react@^11.4.1", "@emotion/react@^11.7.0": - version "11.11.1" - resolved "https://registry.yarnpkg.com/@emotion/react/-/react-11.11.1.tgz#b2c36afac95b184f73b08da8c214fdf861fa4157" - integrity sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/cache" "^11.11.0" - "@emotion/serialize" "^1.1.2" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - "@emotion/weak-memoize" "^0.3.1" - hoist-non-react-statics "^3.3.1" - - "@emotion/serialize@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-1.1.2.tgz#017a6e4c9b8a803bd576ff3d52a0ea6fa5a62b51" - integrity sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA== - dependencies: - "@emotion/hash" "^0.9.1" - "@emotion/memoize" "^0.8.1" - "@emotion/unitless" "^0.8.1" - "@emotion/utils" "^1.2.1" - csstype "^3.0.2" - - "@emotion/sheet@^1.2.2": - version "1.2.2" - resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-1.2.2.tgz#d58e788ee27267a14342303e1abb3d508b6d0fec" - integrity sha512-0QBtGvaqtWi+nx6doRwDdBIzhNdZrXUppvTM4dtZZWEGTXL/XE/yJxLMGlDT1Gt+UHH5IX1n+jkXyytE/av7OA== - - "@emotion/styled@^11.3.0", "@emotion/styled@^11.6.0": - version "11.11.0" - resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-11.11.0.tgz#26b75e1b5a1b7a629d7c0a8b708fbf5a9cdce346" - integrity sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng== - dependencies: - "@babel/runtime" "^7.18.3" - "@emotion/babel-plugin" "^11.11.0" - "@emotion/is-prop-valid" "^1.2.1" - "@emotion/serialize" "^1.1.2" - "@emotion/use-insertion-effect-with-fallbacks" "^1.0.1" - "@emotion/utils" "^1.2.1" - - "@emotion/unitless@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.8.1.tgz#182b5a4704ef8ad91bde93f7a860a88fd92c79a3" - integrity sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ== - - "@emotion/use-insertion-effect-with-fallbacks@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.1.tgz#08de79f54eb3406f9daaf77c76e35313da963963" - integrity sha512-jT/qyKZ9rzLErtrjGgdkMBn2OP8wl0G3sQlBb3YPryvKHsjvINUhVaPFfP+fpBcOkmrVOVEEHQFJ7nbj2TH2gw== - - "@emotion/utils@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-1.2.1.tgz#bbab58465738d31ae4cb3dbb6fc00a5991f755e4" - integrity sha512-Y2tGf3I+XVnajdItskUCn6LX+VUDmP6lTL4fcqsXAv43dnlbZiuW4MWQW38rW/BVWSE7Q/7+XQocmpnRYILUmg== - - "@emotion/weak-memoize@^0.3.1": - version "0.3.1" - resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.3.1.tgz#d0fce5d07b0620caa282b5131c297bb60f9d87e6" - integrity sha512-EsBwpc7hBUJWAsNPBmJy4hxWx12v6bshQsldrVmjxJoc3isbxhOrF2IcCpaXxfvq03NwkI7sbsOLXbYuqF/8Ww== - - "@eslint-community/eslint-utils@^4.2.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz#a23514e8fb9af1269d5f7788aa556798d61c6b59" - integrity sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA== - dependencies: - eslint-visitor-keys "^3.3.0" - - "@eslint-community/regexpp@^4.4.0", "@eslint-community/regexpp@^4.6.1": - version "4.10.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.10.0.tgz#548f6de556857c8bb73bbee70c35dc82a2e74d63" - integrity sha512-Cu96Sd2By9mCNTx2iyKOmq10v22jUVQv0lQnlGNy16oE9589yE+QADPbrMGCkA51cKZSg3Pu/aTJVTGfL/qjUA== - - "@eslint/eslintrc@^0.4.3": - version "0.4.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz#9e42981ef035beb3dd49add17acb96e8ff6f394c" - integrity sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw== - dependencies: - ajv "^6.12.4" - debug "^4.1.1" - espree "^7.3.0" - globals "^13.9.0" - ignore "^4.0.6" - import-fresh "^3.2.1" - js-yaml "^3.13.1" - minimatch "^3.0.4" - strip-json-comments "^3.1.1" - - "@eslint/eslintrc@^2.1.3": - version "2.1.3" - resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-2.1.3.tgz#797470a75fe0fbd5a53350ee715e85e87baff22d" - integrity sha512-yZzuIG+jnVu6hNSzFEN07e8BxF3uAzYtQb6uDkaYZLo6oYZDCq454c5kB8zxnzfCYyP4MIuyBn10L0DqwujTmA== - dependencies: - ajv "^6.12.4" - debug "^4.3.2" - espree "^9.6.0" - globals "^13.19.0" - ignore "^5.2.0" - import-fresh "^3.2.1" - js-yaml "^4.1.0" - minimatch "^3.1.2" - strip-json-comments "^3.1.1" - - "@eslint/js@8.54.0": - version "8.54.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.54.0.tgz#4fab9a2ff7860082c304f750e94acd644cf984cf" - integrity sha512-ut5V+D+fOoWPgGGNj83GGjnntO39xDy6DWxO0wb7Jp3DcMX0TfIqdzHF85VTQkerdyGmuuMD9AKAo5KiNlf/AQ== - - "@ethersproject/address@^5.6.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.7.0.tgz#19b56c4d74a3b0a46bfdbb6cfcc0a153fc697f37" - integrity sha512-9wYhYt7aghVGo758POM5nqcOMaE168Q6aRLJZwUmiqSrAungkG74gSSeKEIR7ukixesdRZGPgVqme6vmxs1fkA== - dependencies: - "@ethersproject/bignumber" "^5.7.0" - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/keccak256" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - "@ethersproject/rlp" "^5.7.0" - - "@ethersproject/bignumber@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bignumber/-/bignumber-5.7.0.tgz#e2f03837f268ba655ffba03a57853e18a18dc9c2" - integrity sha512-n1CAdIHRWjSucQO3MC1zPSVgV/6dy/fjL9pMrPP9peL+QxEg9wOsVqwD4+818B6LUEtaXzVHQiuivzRoxPxUGw== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - bn.js "^5.2.1" - - "@ethersproject/bytes@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/bytes/-/bytes-5.7.0.tgz#a00f6ea8d7e7534d6d87f47188af1148d71f155d" - integrity sha512-nsbxwgFXWh9NyYWo+U8atvmMsSdKJprTcICAkvbBffT75qDocbuggBU0SJiVK2MuTrp0q+xvLkTnGMPK1+uA9A== - dependencies: - "@ethersproject/logger" "^5.7.0" - - "@ethersproject/keccak256@^5.5.0", "@ethersproject/keccak256@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/keccak256/-/keccak256-5.7.0.tgz#3186350c6e1cd6aba7940384ec7d6d9db01f335a" - integrity sha512-2UcPboeL/iW+pSg6vZ6ydF8tCnv3Iu/8tUmLLzWWGzxWKFFqOBQFLo6uLUv6BDrLgCDfN28RJ/wtByx+jZ4KBg== - dependencies: - "@ethersproject/bytes" "^5.7.0" - js-sha3 "0.8.0" - - "@ethersproject/logger@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" - integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== - - "@ethersproject/rlp@^5.7.0": - version "5.7.0" - resolved "https://registry.yarnpkg.com/@ethersproject/rlp/-/rlp-5.7.0.tgz#de39e4d5918b9d74d46de93af80b7685a9c21304" - integrity sha512-rBxzX2vK8mVF7b0Tol44t5Tb8gomOHkj5guL+HhzQ1yBh/ydjGnpw6at+X6Iw0Kp3OzzzkcKp8N9r0W4kYSs9w== - dependencies: - "@ethersproject/bytes" "^5.7.0" - "@ethersproject/logger" "^5.7.0" - - "@fastify/deepmerge@^1.3.0": - version "1.3.0" - resolved "https://registry.yarnpkg.com/@fastify/deepmerge/-/deepmerge-1.3.0.tgz#8116858108f0c7d9fd460d05a7d637a13fe3239a" - integrity sha512-J8TOSBq3SoZbDhM9+R/u77hP93gz/rajSA+K2kGyijPpORPWUXHUpTaleoj+92As0S9uPRP7Oi8IqMf0u+ro6A== - - "@favware/rollup-type-bundler@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@favware/rollup-type-bundler/-/rollup-type-bundler-2.0.0.tgz#5594ee64b40dc64eb02eb68a30943ff4255d25dd" - integrity sha512-RTMvx6v3b4D9V9iXHTogYjHa5fCmcUR3Bu0pFreo+80v2tD+7MSJm24nR1P/SkeTCy+zHKC1JOFQa04fcWZozg== - dependencies: - "@sapphire/utilities" "^3.11.0" - colorette "^2.0.19" - commander "^9.4.1" - js-yaml "^4.1.0" - rollup "^3.2.1" - rollup-plugin-dts "^5.0.0" - typescript "^4.8.4" - - "@floating-ui/core@^1.4.2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@floating-ui/core/-/core-1.5.0.tgz#5c05c60d5ae2d05101c3021c1a2a350ddc027f8c" - integrity sha512-kK1h4m36DQ0UHGj5Ah4db7R0rHemTqqO0QLvUqi1/mUUp3LuAWbWxdxSIf/XsnH9VS6rRVPLJCncjRzUvyCLXg== - dependencies: - "@floating-ui/utils" "^0.1.3" - - "@floating-ui/dom@^1.0.0", "@floating-ui/dom@^1.5.1", "@floating-ui/dom@^1.5.2": - version "1.5.3" - resolved "https://registry.yarnpkg.com/@floating-ui/dom/-/dom-1.5.3.tgz#54e50efcb432c06c23cd33de2b575102005436fa" - integrity sha512-ClAbQnEqJAKCJOEbbLo5IUlZHkNszqhuxS4fHAVxRPXPya6Ysf2G8KypnYcOTpx6I8xcgF9bbHb6g/2KpbV8qA== - dependencies: - "@floating-ui/core" "^1.4.2" - "@floating-ui/utils" "^0.1.3" - - "@floating-ui/react-dom@^2.0.3", "@floating-ui/react-dom@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@floating-ui/react-dom/-/react-dom-2.0.4.tgz#b076fafbdfeb881e1d86ae748b7ff95150e9f3ec" - integrity sha512-CF8k2rgKeh/49UrnIBs4BdxPUV6vize/Db1d/YbCLyp9GiVZ0BEwf5AiDSxJRCr6yOkGqTFHtmrULxkEfYZ7dQ== - dependencies: - "@floating-ui/dom" "^1.5.1" - - "@floating-ui/react@^0.26.0": - version "0.26.3" - resolved "https://registry.yarnpkg.com/@floating-ui/react/-/react-0.26.3.tgz#1ec435f35e37d5e34577ee89c7abb1eedb3a0c5d" - integrity sha512-iKH8WRR0L/nLiM6qavFZxkyegIZRMxGnM9aKEc71M4wRlUNkgTamjPsOQXy11oZbDOH37MiTbk/nAPn9M2+shA== - dependencies: - "@floating-ui/react-dom" "^2.0.3" - "@floating-ui/utils" "^0.1.5" - tabbable "^6.0.1" - - "@floating-ui/utils@^0.1.3", "@floating-ui/utils@^0.1.5": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@floating-ui/utils/-/utils-0.1.6.tgz#22958c042e10b67463997bd6ea7115fe28cbcaf9" - integrity sha512-OfX7E2oUDYxtBvsuS4e/jSn4Q9Qb6DzgeYtsAdkPZ47znpoNsMgZw0+tVijiv3uGNR6dgNlty6r9rzIzHjtd/A== - - "@formatjs/ecma402-abstract@1.18.0": - version "1.18.0" - resolved "https://registry.yarnpkg.com/@formatjs/ecma402-abstract/-/ecma402-abstract-1.18.0.tgz#e2120e7101020140661b58430a7ff4262705a2f2" - integrity sha512-PEVLoa3zBevWSCZzPIM/lvPCi8P5l4G+NXQMc/CjEiaCWgyHieUoo0nM7Bs0n/NbuQ6JpXEolivQ9pKSBHaDlA== - dependencies: - "@formatjs/intl-localematcher" "0.5.2" - tslib "^2.4.0" - - "@formatjs/fast-memoize@2.2.0": - version "2.2.0" - resolved "https://registry.yarnpkg.com/@formatjs/fast-memoize/-/fast-memoize-2.2.0.tgz#33bd616d2e486c3e8ef4e68c99648c196887802b" - integrity sha512-hnk/nY8FyrL5YxwP9e4r9dqeM6cAbo8PeU9UjyXojZMNvVad2Z06FAVHyR3Ecw6fza+0GH7vdJgiKIVXTMbSBA== - dependencies: - tslib "^2.4.0" - - "@formatjs/icu-messageformat-parser@2.7.3": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@formatjs/icu-messageformat-parser/-/icu-messageformat-parser-2.7.3.tgz#c8c95e7c9f8141bdb93bea0e92e4fcace19d3c9f" - integrity sha512-X/jy10V9S/vW+qlplqhMUxR8wErQ0mmIYSq4mrjpjDl9mbuGcCILcI1SUYkL5nlM4PJqpc0KOS0bFkkJNPxYRw== - dependencies: - "@formatjs/ecma402-abstract" "1.18.0" - "@formatjs/icu-skeleton-parser" "1.7.0" - tslib "^2.4.0" - - "@formatjs/icu-skeleton-parser@1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@formatjs/icu-skeleton-parser/-/icu-skeleton-parser-1.7.0.tgz#796938d6d0ba8fc75bb9edee038d1350bfee32cb" - integrity sha512-Cfdo/fgbZzpN/jlN/ptQVe0lRHora+8ezrEeg2RfrNjyp+YStwBy7cqDY8k5/z2LzXg6O0AdzAV91XS0zIWv+A== - dependencies: - "@formatjs/ecma402-abstract" "1.18.0" - tslib "^2.4.0" - - "@formatjs/intl-localematcher@0.5.2": - version "0.5.2" - resolved "https://registry.yarnpkg.com/@formatjs/intl-localematcher/-/intl-localematcher-0.5.2.tgz#5fcf029fd218905575e5080fa33facdcb623d532" - integrity sha512-txaaE2fiBMagLrR4jYhxzFO6wEdEG4TPMqrzBAcbr4HFUYzH/YC+lg6OIzKCHm8WgDdyQevxbAAV1OgcXctuGw== - dependencies: - tslib "^2.4.0" - - "@formkit/auto-animate@^0.8.1": - version "0.8.1" - resolved "https://registry.yarnpkg.com/@formkit/auto-animate/-/auto-animate-0.8.1.tgz#bcaba2969609ca3a7453eacd42b383a2739dfa35" - integrity sha512-0/Z2cuNXWVVIG/l0SpcHAWFhGdvLJ8DRvEfRWvmojtmRWfEy+LWNwgDazbZqY0qQYtkHcoEK3jBLkhiZaB/4Ig== - - "@gar/promisify@^1.0.1", "@gar/promisify@^1.1.3": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" - integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== - - "@hapi/hoek@^9.0.0": - version "9.3.0" - resolved "https://registry.yarnpkg.com/@hapi/hoek/-/hoek-9.3.0.tgz#8368869dcb735be2e7f5cb7647de78e167a251fb" - integrity sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ== - - "@hapi/topo@^5.0.0": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@hapi/topo/-/topo-5.1.0.tgz#dc448e332c6c6e37a4dc02fd84ba8d44b9afb012" - integrity sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg== - dependencies: - "@hapi/hoek" "^9.0.0" - - "@hookform/resolvers@^2.8.0": - version "2.9.11" - resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.11.tgz#9ce96e7746625a89239f68ca57c4f654264c17ef" - integrity sha512-bA3aZ79UgcHj7tFV7RlgThzwSSHZgvfbt2wprldRkYBcMopdMvHyO17Wwp/twcJasNFischFfS7oz8Katz8DdQ== - - "@humanwhocodes/config-array@^0.11.13": - version "0.11.13" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.13.tgz#075dc9684f40a531d9b26b0822153c1e832ee297" - integrity sha512-JSBDMiDKSzQVngfRjOdFXgFfklaXI4K9nLF49Auh21lmBWRLIK3+xTErTWD4KU54pb6coM6ESE7Awz/FNU3zgQ== - dependencies: - "@humanwhocodes/object-schema" "^2.0.1" - debug "^4.1.1" - minimatch "^3.0.5" - - "@humanwhocodes/config-array@^0.5.0": - version "0.5.0" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9" - integrity sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg== - dependencies: - "@humanwhocodes/object-schema" "^1.2.0" - debug "^4.1.1" - minimatch "^3.0.4" - - "@humanwhocodes/module-importer@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" - integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== - - "@humanwhocodes/object-schema@^1.2.0": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" - integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== - - "@humanwhocodes/object-schema@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.1.tgz#e5211452df060fa8522b55c7b3c0c4d1981cb044" - integrity sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw== - - "@hutson/parse-repository-url@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz#98c23c950a3d9b6c8f0daed06da6c3af06981340" - integrity sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q== - - "@interchain-ui/react@^1.14.2": - version "1.14.2" - resolved "https://registry.yarnpkg.com/@interchain-ui/react/-/react-1.14.2.tgz#2881eff57ce5988abecc4b7205bc2fad121d9c24" - integrity sha512-YA3Dkq4FOUOcKHoH8iTqozowo5VisaT4iPffkGnxkkShlMY/NwC5V4q5WbdkNaefKmlIoUJDKle/Pyx9UL4iyw== - dependencies: - "@fastify/deepmerge" "^1.3.0" - "@floating-ui/dom" "^1.5.2" - "@floating-ui/react" "^0.26.0" - "@formkit/auto-animate" "^0.8.1" - "@react-aria/utils" "^3.21.1" - "@vanilla-extract/css" "^1.14.0" - "@vanilla-extract/dynamic" "^2.1.0" - "@vanilla-extract/recipes" "^0.5.1" - animejs "^3.2.1" - bignumber.js "^9.1.1" - client-only "^0.0.1" - clsx "^1.2.1" - copy-to-clipboard "^3.3.3" - immer "^9.0.19" - lodash "^4.17.21" - rainbow-sprinkles "^0.17.0" - react-aria "^3.29.1" - react-stately "^3.27.1" - zustand "4.4.6" - - "@internationalized/date@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@internationalized/date/-/date-3.5.0.tgz#67f1dd62355f05140cc80e324842e9bfb4553abe" - integrity sha512-nw0Q+oRkizBWMioseI8+2TeUPEyopJVz5YxoYVzR0W1v+2YytiYah7s/ot35F149q/xAg4F1gT/6eTd+tsUpFQ== - dependencies: - "@swc/helpers" "^0.5.0" - - "@internationalized/message@^3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@internationalized/message/-/message-3.1.1.tgz#0f29c5a239b5dcd457b55f21dcd38d1a44a1236a" - integrity sha512-ZgHxf5HAPIaR0th+w0RUD62yF6vxitjlprSxmLJ1tam7FOekqRSDELMg4Cr/DdszG5YLsp5BG3FgHgqquQZbqw== - dependencies: - "@swc/helpers" "^0.5.0" - intl-messageformat "^10.1.0" - - "@internationalized/number@^3.4.0": - version "3.4.0" - resolved "https://registry.yarnpkg.com/@internationalized/number/-/number-3.4.0.tgz#1c3ebf6ac40ce649d3d97bb835ff0559957f2e1f" - integrity sha512-8TvotW3qVDHC4uv/BVoN6Qx0Dm8clHY1/vpH+dh+XRiPW/9NVpKn1P8d1A+WLphWrMwyqyWXI7uWehJPviaeIw== - dependencies: - "@swc/helpers" "^0.5.0" - - "@internationalized/string@^3.1.1": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@internationalized/string/-/string-3.1.1.tgz#2ab7372d58bbb7ffd3de62fc2a311e4690186981" - integrity sha512-fvSr6YRoVPgONiVIUhgCmIAlifMVCeej/snPZVzbzRPxGpHl3o1GRe+d/qh92D8KhgOciruDUH8I5mjdfdjzfA== - dependencies: - "@swc/helpers" "^0.5.0" - - "@ioredis/commands@^1.1.1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ioredis/commands/-/commands-1.2.0.tgz#6d61b3097470af1fdbbe622795b8921d42018e11" - integrity sha512-Sx1pU8EM64o2BrqNpEO1CNLtKQwyhuXuqyfH7oGKCk+1a33d2r5saW8zNwm3j6BTExtjrv2BxTgzzkMwts6vGg== - - "@isaacs/cliui@^8.0.2": - version "8.0.2" - resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" - integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== - dependencies: - string-width "^5.1.2" - string-width-cjs "npm:string-width@^4.2.0" - strip-ansi "^7.0.1" - strip-ansi-cjs "npm:strip-ansi@^6.0.1" - wrap-ansi "^8.1.0" - wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" - - "@istanbuljs/load-nyc-config@^1.0.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" - integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== - dependencies: - camelcase "^5.3.1" - find-up "^4.1.0" - get-package-type "^0.1.0" - js-yaml "^3.13.1" - resolve-from "^5.0.0" - - "@istanbuljs/schema@^0.1.2", "@istanbuljs/schema@^0.1.3": - version "0.1.3" - resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" - integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== - - "@jest/console@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-27.5.1.tgz#260fe7239602fe5130a94f1aa386eff54b014bba" - integrity sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - - "@jest/core@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-27.5.1.tgz#267ac5f704e09dc52de2922cbf3af9edcd64b626" - integrity sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/reporters" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - emittery "^0.8.1" - exit "^0.1.2" - graceful-fs "^4.2.9" - jest-changed-files "^27.5.1" - jest-config "^27.5.1" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-resolve-dependencies "^27.5.1" - jest-runner "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - jest-watcher "^27.5.1" - micromatch "^4.0.4" - rimraf "^3.0.0" - slash "^3.0.0" - strip-ansi "^6.0.0" - - "@jest/environment@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-27.5.1.tgz#d7425820511fe7158abbecc010140c3fd3be9c74" - integrity sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA== - dependencies: - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - - "@jest/expect-utils@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-28.1.3.tgz#58561ce5db7cd253a7edddbc051fb39dda50f525" - integrity sha512-wvbi9LUrHJLn3NlDW6wF2hvIMtd4JUl2QNVrjq+IBSHirgfrR3o9RnVtxzdEGO2n9JyIWwHnLfby5KzqBGg2YA== - dependencies: - jest-get-type "^28.0.2" - - "@jest/expect-utils@^29.7.0": - version "29.7.0" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.7.0.tgz#023efe5d26a8a70f21677d0a1afc0f0a44e3a1c6" - integrity sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA== - dependencies: - jest-get-type "^29.6.3" - - "@jest/fake-timers@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-27.5.1.tgz#76979745ce0579c8a94a4678af7a748eda8ada74" - integrity sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ== - dependencies: - "@jest/types" "^27.5.1" - "@sinonjs/fake-timers" "^8.0.1" - "@types/node" "*" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-util "^27.5.1" - - "@jest/globals@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-27.5.1.tgz#7ac06ce57ab966566c7963431cef458434601b2b" - integrity sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/types" "^27.5.1" - expect "^27.5.1" - - "@jest/reporters@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-27.5.1.tgz#ceda7be96170b03c923c37987b64015812ffec04" - integrity sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - collect-v8-coverage "^1.0.0" - exit "^0.1.2" - glob "^7.1.2" - graceful-fs "^4.2.9" - istanbul-lib-coverage "^3.0.0" - istanbul-lib-instrument "^5.1.0" - istanbul-lib-report "^3.0.0" - istanbul-lib-source-maps "^4.0.0" - istanbul-reports "^3.1.3" - jest-haste-map "^27.5.1" - jest-resolve "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - slash "^3.0.0" - source-map "^0.6.0" - string-length "^4.0.1" - terminal-link "^2.0.0" - v8-to-istanbul "^8.1.0" - - "@jest/schemas@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-28.1.3.tgz#ad8b86a66f11f33619e3d7e1dcddd7f2d40ff905" - integrity sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg== - dependencies: - "@sinclair/typebox" "^0.24.1" - - "@jest/schemas@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.6.3.tgz#430b5ce8a4e0044a7e3819663305a7b3091c8e03" - integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA== - dependencies: - "@sinclair/typebox" "^0.27.8" - - "@jest/source-map@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-27.5.1.tgz#6608391e465add4205eae073b55e7f279e04e8cf" - integrity sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg== - dependencies: - callsites "^3.0.0" - graceful-fs "^4.2.9" - source-map "^0.6.0" - - "@jest/test-result@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-27.5.1.tgz#56a6585fa80f7cdab72b8c5fc2e871d03832f5bb" - integrity sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag== - dependencies: - "@jest/console" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/istanbul-lib-coverage" "^2.0.0" - collect-v8-coverage "^1.0.0" - - "@jest/test-sequencer@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz#4057e0e9cea4439e544c6353c6affe58d095745b" - integrity sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ== - dependencies: - "@jest/test-result" "^27.5.1" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-runtime "^27.5.1" - - "@jest/transform@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" - integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^26.6.2" - babel-plugin-istanbul "^6.0.0" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.4" - jest-haste-map "^26.6.2" - jest-regex-util "^26.0.0" - jest-util "^26.6.2" - micromatch "^4.0.2" - pirates "^4.0.1" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - - "@jest/transform@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-27.5.1.tgz#6c3501dcc00c4c08915f292a600ece5ecfe1f409" - integrity sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw== - dependencies: - "@babel/core" "^7.1.0" - "@jest/types" "^27.5.1" - babel-plugin-istanbul "^6.1.1" - chalk "^4.0.0" - convert-source-map "^1.4.0" - fast-json-stable-stringify "^2.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-regex-util "^27.5.1" - jest-util "^27.5.1" - micromatch "^4.0.4" - pirates "^4.0.4" - slash "^3.0.0" - source-map "^0.6.1" - write-file-atomic "^3.0.0" - - "@jest/types@^26.6.2": - version "26.6.2" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" - integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^15.0.0" - chalk "^4.0.0" - - "@jest/types@^27.5.1": - version "27.5.1" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" - integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^16.0.0" - chalk "^4.0.0" - - "@jest/types@^28.1.3": - version "28.1.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-28.1.3.tgz#b05de80996ff12512bc5ceb1d208285a7d11748b" - integrity sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ== - dependencies: - "@jest/schemas" "^28.1.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - - "@jest/types@^29.6.3": - version "29.6.3" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.6.3.tgz#1131f8cf634e7e84c5e77bab12f052af585fba59" - integrity sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw== - dependencies: - "@jest/schemas" "^29.6.3" - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^3.0.0" - "@types/node" "*" - "@types/yargs" "^17.0.8" - chalk "^4.0.0" - - "@jridgewell/gen-mapping@^0.3.0", "@jridgewell/gen-mapping@^0.3.2": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - - "@jridgewell/resolve-uri@^3.0.3", "@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - - "@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - - "@jridgewell/source-map@^0.3.3": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" - integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - - "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": - version "1.4.15" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" - integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== - - "@jridgewell/trace-mapping@0.3.9": - version "0.3.9" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz#6534fd5933a53ba7cbf3a17615e273a0d1273ff9" - integrity sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ== - dependencies: - "@jridgewell/resolve-uri" "^3.0.3" - "@jridgewell/sourcemap-codec" "^1.4.10" - - "@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": - version "0.3.20" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz#72e45707cf240fa6b081d0366f8265b0cd10197f" - integrity sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - - "@keplr-wallet/common@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/common/-/common-0.12.28.tgz#1d5d985070aced31a34a6426c9ac4b775081acca" - integrity sha512-ESQorPZw8PRiUXhsrxED+E1FEWkAdc6Kwi3Az7ce204gMBQDI2j0XJtTd4uCUp+C24Em9fk0samdHzdoB4caIg== - dependencies: - "@keplr-wallet/crypto" "0.12.28" - "@keplr-wallet/types" "0.12.28" - buffer "^6.0.3" - delay "^4.4.0" - mobx "^6.1.7" - - "@keplr-wallet/cosmos@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/cosmos/-/cosmos-0.12.28.tgz#d56e73468256e7276a66bb41f145449dbf11efa1" - integrity sha512-IuqmSBgKgIeWBA0XGQKKs28IXFeFMCrfadCbtiZccNc7qnNr5Y/Cyyk01BPC8Dd1ZyEyAByoICgrxvtGN0GGvA== - dependencies: - "@ethersproject/address" "^5.6.0" - "@keplr-wallet/common" "0.12.28" - "@keplr-wallet/crypto" "0.12.28" - "@keplr-wallet/proto-types" "0.12.28" - "@keplr-wallet/simple-fetch" "0.12.28" - "@keplr-wallet/types" "0.12.28" - "@keplr-wallet/unit" "0.12.28" - bech32 "^1.1.4" - buffer "^6.0.3" - long "^4.0.0" - protobufjs "^6.11.2" - - "@keplr-wallet/crypto@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/crypto/-/crypto-0.12.28.tgz#28410ba1f707fa5a1506f111f6fd8baf071c394d" - integrity sha512-le1je+78/4213qshSMgQTYqhCCvzsL9+YfhjXg1kd/ali69MLWK8L8Z09ducHPS6C+LqQXXTNJQpbH2uiFSd5w== - dependencies: - "@ethersproject/keccak256" "^5.5.0" - bip32 "^2.0.6" - bip39 "^3.0.3" - bs58check "^2.1.2" - buffer "^6.0.3" - crypto-js "^4.0.0" - elliptic "^6.5.3" - sha.js "^2.4.11" - - "@keplr-wallet/proto-types@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/proto-types/-/proto-types-0.12.28.tgz#2fb2c37749ce7db974f01d07387e966c9b99027d" - integrity sha512-ukti/eCTltPUP64jxtk5TjtwJogyfKPqlBIT3KGUCGzBLIPeYMsffL5w5aoHsMjINzOITjYqzXyEF8LTIK/fmw== - dependencies: - long "^4.0.0" - protobufjs "^6.11.2" - - "@keplr-wallet/simple-fetch@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/simple-fetch/-/simple-fetch-0.12.28.tgz#44225df5b329c823076280df1ec9930a21b1373e" - integrity sha512-T2CiKS2B5n0ZA7CWw0CA6qIAH0XYI1siE50MP+i+V0ZniCGBeL+BMcDw64vFJUcEH+1L5X4sDAzV37fQxGwllA== - - "@keplr-wallet/types@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/types/-/types-0.12.28.tgz#eac3c2c9d4560856c5c403a87e67925992a04fbf" - integrity sha512-EcM9d46hYDm3AO4lf4GUbTSLRySONtTmhKb7p88q56OQOgJN3MMjRacEo2p9jX9gpPe7gRIjMUalhAfUiFpZoQ== - dependencies: - long "^4.0.0" - - "@keplr-wallet/unit@0.12.28": - version "0.12.28" - resolved "https://registry.yarnpkg.com/@keplr-wallet/unit/-/unit-0.12.28.tgz#907c7fa0b49a729cda207fca14fc0a38871cc6c4" - integrity sha512-kpXigHDBJGOmhtPkv9hqsQid9zkFo7OQPeKgO2n8GUlOINIXW6kWG5LXYTi/Yg9Uiw1CQF69gFMuZCJ8IzVHlA== - dependencies: - "@keplr-wallet/types" "0.12.28" - big-integer "^1.6.48" - utility-types "^3.10.0" - - "@leichtgewicht/ip-codec@^2.0.1": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" - integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== - - "@lerna/child-process@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/child-process/-/child-process-7.4.2.tgz#a2fd013ac2150dc288270d3e0d0b850c06bec511" - integrity sha512-je+kkrfcvPcwL5Tg8JRENRqlbzjdlZXyaR88UcnCdNW0AJ1jX9IfHRys1X7AwSroU2ug8ESNC+suoBw1vX833Q== - dependencies: - chalk "^4.1.0" - execa "^5.0.0" - strong-log-transformer "^2.1.0" - - "@lerna/create@7.4.2": - version "7.4.2" - resolved "https://registry.yarnpkg.com/@lerna/create/-/create-7.4.2.tgz#f845fad1480e46555af98bd39af29571605dddc9" - integrity sha512-1wplFbQ52K8E/unnqB0Tq39Z4e+NEoNrpovEnl6GpsTUrC6WDp8+w0Le2uCBV0hXyemxChduCkLz4/y1H1wTeg== - dependencies: - "@lerna/child-process" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - execa "5.0.0" - fs-extra "^11.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - js-yaml "4.1.0" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-queue "6.6.2" - p-reduce "^2.1.0" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.4" - signal-exit "3.0.7" - slash "^3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - - "@mdx-js/loader@^2.1.5": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-2.3.0.tgz#56a6b07eb0027b6407e953a97c52bd8619601161" - integrity sha512-IqsscXh7Q3Rzb+f5DXYk0HU71PK+WuFsEhf+mSV3fOhpLcEpgsHvTQ2h0T6TlZ5gHOaBeFjkXwB52by7ypMyNg== - dependencies: - "@mdx-js/mdx" "^2.0.0" - source-map "^0.7.0" - - "@mdx-js/mdx@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" - 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" - - "@mdx-js/mdx@^2.0.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-2.3.0.tgz#d65d8c3c28f3f46bb0e7cb3bf7613b39980671a9" - integrity sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/mdx" "^2.0.0" - estree-util-build-jsx "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-util-to-js "^1.1.0" - estree-walker "^3.0.0" - hast-util-to-estree "^2.0.0" - markdown-extensions "^1.0.0" - periscopic "^3.0.0" - remark-mdx "^2.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - unified "^10.0.0" - unist-util-position-from-estree "^1.0.0" - unist-util-stringify-position "^3.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - - "@mdx-js/react@^1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" - integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== - - "@mdx-js/util@1.6.22": - version "1.6.22" - resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" - integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== - - "@mrmlnc/readdir-enhanced@^2.2.1": - version "2.2.1" - resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" - integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== - dependencies: - call-me-maybe "^1.0.1" - glob-to-regexp "^0.3.0" - - "@mui/base@5.0.0-beta.25": - version "5.0.0-beta.25" - resolved "https://registry.yarnpkg.com/@mui/base/-/base-5.0.0-beta.25.tgz#e1bc39f7a2daa9851fa8d0774ae6d89f0453bdc3" - integrity sha512-Iiv+IcappRRv6IBlknIVmLkXxfp51NEX1+l9f+dIbBuPU4PaRULegr1lCeHKsC45KU5ruxM5xMg4R/de03aJQg== - dependencies: - "@babel/runtime" "^7.23.4" - "@floating-ui/react-dom" "^2.0.4" - "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" - "@popperjs/core" "^2.11.8" - clsx "^2.0.0" - prop-types "^15.8.1" - - "@mui/core-downloads-tracker@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/core-downloads-tracker/-/core-downloads-tracker-5.14.19.tgz#9c04ad047c378d857d529ef9c535b60a10b9a47c" - integrity sha512-y4JseIen5pmZs1n9hHy95HKKioKco8f6N2lford2AmjJigVJOv0KsU0qryiCpyuEUZmi/xCduVilHsK9DSkPcA== - - "@mui/icons-material@^5.0.0", "@mui/icons-material@^5.2.0": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/icons-material/-/icons-material-5.14.19.tgz#6e0f4e9d89f99517d3c0ee65dee7ac97753755af" - integrity sha512-yjP8nluXxZGe3Y7pS+yxBV+hWZSsSBampCxkZwaw+1l+feL+rfP74vbEFbMrX/Kil9I/Y1tWfy5bs/eNvwNpWw== - dependencies: - "@babel/runtime" "^7.23.4" - - "@mui/lab@^5.0.0-alpha.72": - version "5.0.0-alpha.154" - resolved "https://registry.yarnpkg.com/@mui/lab/-/lab-5.0.0-alpha.154.tgz#c352e164e9f0313317dd8dc1bfd17236fbefbbc8" - integrity sha512-Rrhu8eUknjV6hhPMqq52e/p4/c6rvnu/k0AhysuljsHDZcHThYEZNe1mHFLveQ1RIje2VnJSsgmcNfcZKeOOAg== - dependencies: - "@babel/runtime" "^7.23.4" - "@mui/base" "5.0.0-beta.25" - "@mui/system" "^5.14.19" - "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" - clsx "^2.0.0" - prop-types "^15.8.1" - - "@mui/material@^5.0.1", "@mui/material@^5.2.2": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/material/-/material-5.14.19.tgz#6b81f6248da04ee73f935a79d81e7819c7115089" - integrity sha512-jSPLXst/YPgDGolhiu4rbethKjLVrI1IkoK8YrFUv8ygxDuhQdsE6+ZqjSSRXk3ytTMf6ghPnQ88OFRk4XjpNw== - dependencies: - "@babel/runtime" "^7.23.4" - "@mui/base" "5.0.0-beta.25" - "@mui/core-downloads-tracker" "^5.14.19" - "@mui/system" "^5.14.19" - "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" - "@types/react-transition-group" "^4.4.9" - clsx "^2.0.0" - csstype "^3.1.2" - prop-types "^15.8.1" - react-is "^18.2.0" - react-transition-group "^4.4.5" - - "@mui/private-theming@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/private-theming/-/private-theming-5.14.19.tgz#f3bae7377f987dc5f40d0c43163ae1ed1f892961" - integrity sha512-U9w39VpXLGVM8wZlUU/47YGTsBSk60ZQRRxQZtdqPfN1N7OVllQeN4cEKZKR8PjqqR3aYRcSciQ4dc6CttRoXQ== - dependencies: - "@babel/runtime" "^7.23.4" - "@mui/utils" "^5.14.19" - prop-types "^15.8.1" - - "@mui/styled-engine@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/styled-engine/-/styled-engine-5.14.19.tgz#dee1d16044a5ef3a783b742381ea4348c159b013" - integrity sha512-jtj/Pyn/bS8PM7NXdFNTHWZfE3p+vItO4/HoQbUeAv3u+cnWXcTBGHHY/xdIn446lYGFDczTh1YyX8G4Ts0Rtg== - dependencies: - "@babel/runtime" "^7.23.4" - "@emotion/cache" "^11.11.0" - csstype "^3.1.2" - prop-types "^15.8.1" - - "@mui/styles@^5.0.1", "@mui/styles@^5.2.2": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/styles/-/styles-5.14.19.tgz#713f66a4515f2a52f965485a081d64690241c879" - integrity sha512-5yARLEJ8zPzY6zpebupK3PqDo6jQBz1s78qXnBju10toP9HT4WEydpYdm+orDAlUUxP8eVlcpK0fVwza9NwbjA== - dependencies: - "@babel/runtime" "^7.23.4" - "@emotion/hash" "^0.9.1" - "@mui/private-theming" "^5.14.19" - "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" - clsx "^2.0.0" - csstype "^3.1.2" - hoist-non-react-statics "^3.3.2" - jss "^10.10.0" - jss-plugin-camel-case "^10.10.0" - jss-plugin-default-unit "^10.10.0" - jss-plugin-global "^10.10.0" - jss-plugin-nested "^10.10.0" - jss-plugin-props-sort "^10.10.0" - jss-plugin-rule-value-function "^10.10.0" - jss-plugin-vendor-prefixer "^10.10.0" - prop-types "^15.8.1" - - "@mui/system@>= 5", "@mui/system@^5.0.1", "@mui/system@^5.14.19": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/system/-/system-5.14.19.tgz#f13387c60af129e4d61dfbf168fcee348ebe952a" - integrity sha512-4e3Q+2nx+vgEsd0h5ftxlZGB7XtkkPos/zWqCqnxUs1l/T70s0lF2YNrWHHdSQ7LgtBu0eQ0qweZG2pR7KwkAw== - dependencies: - "@babel/runtime" "^7.23.4" - "@mui/private-theming" "^5.14.19" - "@mui/styled-engine" "^5.14.19" - "@mui/types" "^7.2.10" - "@mui/utils" "^5.14.19" - clsx "^2.0.0" - csstype "^3.1.2" - prop-types "^15.8.1" - - "@mui/types@^7.2.10": - version "7.2.10" - resolved "https://registry.yarnpkg.com/@mui/types/-/types-7.2.10.tgz#13e3e9aa07ee6d593cfacd538e02e8e896d7a12f" - integrity sha512-wX1vbDC+lzF7FlhT6A3ffRZgEoKWPF8VqRoTu4lZwouFX2t90KyCMsgepMw5DxLak1BSp/KP86CmtZttikb/gQ== - - "@mui/utils@^5.10.3", "@mui/utils@^5.14.19", "@mui/utils@^5.7.0": - version "5.14.19" - resolved "https://registry.yarnpkg.com/@mui/utils/-/utils-5.14.19.tgz#39a5846a74ba199f1a2b067ea197dc6b9c8f442f" - integrity sha512-qAHvTXzk7basbyqPvhgWqN6JbmI2wLB/mf97GkSlz5c76MiKYV6Ffjvw9BjKZQ1YRb8rDX9kgdjRezOcoB91oQ== - dependencies: - "@babel/runtime" "^7.23.4" - "@types/prop-types" "^15.7.11" - prop-types "^15.8.1" - react-is "^18.2.0" - - "@mui/x-data-grid@^5.0.0-beta.5": - version "5.17.26" - resolved "https://registry.yarnpkg.com/@mui/x-data-grid/-/x-data-grid-5.17.26.tgz#1f7fa73dd3986cf052e2fd2cb56eb4678a7bd913" - integrity sha512-eGJq9J0g9cDGLFfMmugOadZx0mJeOd/yQpHwEa5gUXyONS6qF0OhXSWyDOhDdA3l2TOoQzotMN5dY/T4Wl1KYA== - dependencies: - "@babel/runtime" "^7.18.9" - "@mui/utils" "^5.10.3" - clsx "^1.2.1" - prop-types "^15.8.1" - reselect "^4.1.6" - - "@noble/hashes@^1", "@noble/hashes@^1.0.0", "@noble/hashes@^1.2.0": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.2.tgz#6f26dbc8fbc7205873ce3cee2f690eba0d421b39" - integrity sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ== - - "@nodelib/fs.scandir@2.1.5": - version "2.1.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" - integrity sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g== - dependencies: - "@nodelib/fs.stat" "2.0.5" - run-parallel "^1.1.9" - - "@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2": - version "2.0.5" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" - integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== - - "@nodelib/fs.stat@^1.1.2": - version "1.1.3" - resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" - integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== - - "@nodelib/fs.walk@^1.2.3", "@nodelib/fs.walk@^1.2.8": - version "1.2.8" - resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" - integrity sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg== - dependencies: - "@nodelib/fs.scandir" "2.1.5" - fastq "^1.6.0" - - "@npmcli/fs@^1.0.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-1.1.1.tgz#72f719fe935e687c56a4faecf3c03d06ba593257" - integrity sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ== - dependencies: - "@gar/promisify" "^1.0.1" - semver "^7.3.5" - - "@npmcli/fs@^2.1.0": - version "2.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.2.tgz#a9e2541a4a2fec2e69c29b35e6060973da79b865" - integrity sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ== - dependencies: - "@gar/promisify" "^1.1.3" - semver "^7.3.5" - - "@npmcli/fs@^3.1.0": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-3.1.0.tgz#233d43a25a91d68c3a863ba0da6a3f00924a173e" - integrity sha512-7kZUAaLscfgbwBQRbvdMYaZOWyMEcPTH/tJjnyAWJ/dvvs9Ef+CERx/qJb9GExJpl1qipaDGn7KqHnFGGixd0w== - dependencies: - semver "^7.3.5" - - "@npmcli/git@^4.0.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-4.1.0.tgz#ab0ad3fd82bc4d8c1351b6c62f0fa56e8fe6afa6" - integrity sha512-9hwoB3gStVfa0N31ymBmrX+GuDGdVA/QWShZVqE0HK2Af+7QGGrCTbZia/SW0ImUTjTne7SP91qxDmtXvDHRPQ== - dependencies: - "@npmcli/promise-spawn" "^6.0.0" - lru-cache "^7.4.4" - npm-pick-manifest "^8.0.0" - proc-log "^3.0.0" - promise-inflight "^1.0.1" - promise-retry "^2.0.1" - semver "^7.3.5" - which "^3.0.0" - - "@npmcli/installed-package-contents@^2.0.1": - version "2.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz#bfd817eccd9e8df200919e73f57f9e3d9e4f9e33" - integrity sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ== - dependencies: - npm-bundled "^3.0.0" - npm-normalize-package-bin "^3.0.0" - - "@npmcli/move-file@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-1.1.2.tgz#1a82c3e372f7cae9253eb66d72543d6b8685c674" - integrity sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - - "@npmcli/move-file@^2.0.0": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.1.tgz#26f6bdc379d87f75e55739bab89db525b06100e4" - integrity sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ== - dependencies: - mkdirp "^1.0.4" - rimraf "^3.0.2" - - "@npmcli/node-gyp@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-3.0.0.tgz#101b2d0490ef1aa20ed460e4c0813f0db560545a" - integrity sha512-gp8pRXC2oOxu0DUE1/M3bYtb1b3/DbJ5aM113+XJBgfXdussRAsX0YOrOhdd8WvnAR6auDBvJomGAkLKA5ydxA== - - "@npmcli/promise-spawn@^6.0.0", "@npmcli/promise-spawn@^6.0.1": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-6.0.2.tgz#c8bc4fa2bd0f01cb979d8798ba038f314cfa70f2" - integrity sha512-gGq0NJkIGSwdbUt4yhdF8ZrmkGKVz9vAdVzpOfnom+V8PLSmSOVhZwbNvZZS1EYcJN5hzzKBxmmVVAInM6HQLg== - dependencies: - which "^3.0.0" - - "@npmcli/run-script@6.0.2", "@npmcli/run-script@^6.0.0": - version "6.0.2" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-6.0.2.tgz#a25452d45ee7f7fb8c16dfaf9624423c0c0eb885" - integrity sha512-NCcr1uQo1k5U+SYlnIrbAh3cxy+OQT1VtqiAbxdymSlptbzBb62AjH2xXgjNCoP073hoa1CfCAcwoZ8k96C4nA== - dependencies: - "@npmcli/node-gyp" "^3.0.0" - "@npmcli/promise-spawn" "^6.0.0" - node-gyp "^9.0.0" - read-package-json-fast "^3.0.0" - which "^3.0.0" - - "@nrwl/devkit@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/devkit/-/devkit-16.10.0.tgz#ac8c5b4db00f12c4b817c937be2f7c4eb8f2593c" - integrity sha512-fRloARtsDQoQgQ7HKEy0RJiusg/HSygnmg4gX/0n/Z+SUS+4KoZzvHjXc6T5ZdEiSjvLypJ+HBM8dQzIcVACPQ== - dependencies: - "@nx/devkit" "16.10.0" - - "@nrwl/tao@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nrwl/tao/-/tao-16.10.0.tgz#94642a0380709b8e387e1e33705a5a9624933375" - integrity sha512-QNAanpINbr+Pod6e1xNgFbzK1x5wmZl+jMocgiEFXZ67KHvmbD6MAQQr0MMz+GPhIu7EE4QCTLTyCEMlAG+K5Q== - dependencies: - nx "16.10.0" - tslib "^2.3.0" - - "@nx/devkit@16.10.0", "@nx/devkit@>=16.5.1 < 17": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/devkit/-/devkit-16.10.0.tgz#7e466be2dee2dcb1ccaf286786ca2a0a639aa007" - integrity sha512-IvKQqRJFDDiaj33SPfGd3ckNHhHi6ceEoqCbAP4UuMXOPPVOX6H0KVk+9tknkPb48B7jWIw6/AgOeWkBxPRO5w== - dependencies: - "@nrwl/devkit" "16.10.0" - ejs "^3.1.7" - enquirer "~2.3.6" - ignore "^5.0.4" - semver "7.5.3" - tmp "~0.2.1" - tslib "^2.3.0" - - "@nx/nx-darwin-arm64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-arm64/-/nx-darwin-arm64-16.10.0.tgz#0c73010cac7a502549483b12bad347da9014e6f1" - integrity sha512-YF+MIpeuwFkyvM5OwgY/rTNRpgVAI/YiR0yTYCZR+X3AAvP775IVlusNgQ3oedTBRUzyRnI4Tknj1WniENFsvQ== - - "@nx/nx-darwin-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-darwin-x64/-/nx-darwin-x64-16.10.0.tgz#2ccf270418d552fd0a8e0d6089aee4944315adaa" - integrity sha512-ypi6YxwXgb0kg2ixKXE3pwf5myVNUgWf1CsV5OzVccCM8NzheMO51KDXTDmEpXdzUsfT0AkO1sk5GZeCjhVONg== - - "@nx/nx-freebsd-x64@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-freebsd-x64/-/nx-freebsd-x64-16.10.0.tgz#c3ee6914256e69493fed9355b0d6661d0e86da44" - integrity sha512-UeEYFDmdbbDkTQamqvtU8ibgu5jQLgFF1ruNb/U4Ywvwutw2d4ruOMl2e0u9hiNja9NFFAnDbvzrDcMo7jYqYw== - - "@nx/nx-linux-arm-gnueabihf@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm-gnueabihf/-/nx-linux-arm-gnueabihf-16.10.0.tgz#a961eccbb38acb2da7fc125b29d1fead0b39152f" - integrity sha512-WV3XUC2DB6/+bz1sx+d1Ai9q2Cdr+kTZRN50SOkfmZUQyEBaF6DRYpx/a4ahhxH3ktpNfyY8Maa9OEYxGCBkQA== - - "@nx/nx-linux-arm64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-gnu/-/nx-linux-arm64-gnu-16.10.0.tgz#795f20072549d03822b5c4639ef438e473dbb541" - integrity sha512-aWIkOUw995V3ItfpAi5FuxQ+1e9EWLS1cjWM1jmeuo+5WtaKToJn5itgQOkvSlPz+HSLgM3VfXMvOFALNk125g== - - "@nx/nx-linux-arm64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-arm64-musl/-/nx-linux-arm64-musl-16.10.0.tgz#f2428ee6dbe2b2c326e8973f76c97666def33607" - integrity sha512-uO6Gg+irqpVcCKMcEPIQcTFZ+tDI02AZkqkP7koQAjniLEappd8DnUBSQdcn53T086pHpdc264X/ZEpXFfrKWQ== - - "@nx/nx-linux-x64-gnu@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-gnu/-/nx-linux-x64-gnu-16.10.0.tgz#d36c2bcf94d49eaa24e3880ddaf6f1f617de539b" - integrity sha512-134PW/u/arNFAQKpqMJniC7irbChMPz+W+qtyKPAUXE0XFKPa7c1GtlI/wK2dvP9qJDZ6bKf0KtA0U/m2HMUOA== - - "@nx/nx-linux-x64-musl@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-linux-x64-musl/-/nx-linux-x64-musl-16.10.0.tgz#78bd2ab97a583b3d4ea3387b67fd7b136907493c" - integrity sha512-q8sINYLdIJxK/iUx9vRk5jWAWb/2O0PAbOJFwv4qkxBv4rLoN7y+otgCZ5v0xfx/zztFgk/oNY4lg5xYjIso2Q== - - "@nx/nx-win32-arm64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-arm64-msvc/-/nx-win32-arm64-msvc-16.10.0.tgz#ef20ec8d0c83d66e73e20df12d2c788b8f866396" - integrity sha512-moJkL9kcqxUdJSRpG7dET3UeLIciwrfP08mzBQ12ewo8K8FzxU8ZUsTIVVdNrwt01CXOdXoweGfdQLjJ4qTURA== - - "@nx/nx-win32-x64-msvc@16.10.0": - version "16.10.0" - resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" - integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== - - "@nymproject/node-tester@^1.0.0", "@nymproject/node-tester@^1.2.3": - version "1.2.3" - resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" - integrity sha512-VDFdH2ddIcXXamwkMbeHA88Xa/S2iPWh9QxkFggppvHS1d6gmnNHAZxXm3Uuhx7pCpzKldA0OT7qohMg9GW9xg== - - "@nymproject/nym-validator-client@^0.18.0": - version "0.18.0" - resolved "https://registry.yarnpkg.com/@nymproject/nym-validator-client/-/nym-validator-client-0.18.0.tgz#4dd72bafdf6c72b603242f32c0bb9a1f9e475b98" - integrity sha512-FO1T15S2BJVuMoPA2yOaH40aD3hKJPKJVyX5ix7eJEbBWIdsYNoVeVc/soHhaAU1FIy2uU0G/FZQkaUYJGGb7Q== - dependencies: - "@cosmjs/cosmwasm-stargate" "^0.25.5" - "@cosmjs/math" "^0.25.5" - "@cosmjs/proto-signing" "^0.25.5" - "@cosmjs/stargate" "^0.25.5" - axios "^0.21.1" - - "@octokit/auth-token@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@octokit/auth-token/-/auth-token-3.0.4.tgz#70e941ba742bdd2b49bdb7393e821dea8520a3db" - integrity sha512-TWFX7cZF2LXoCvdmJWY7XVPi74aSY0+FfBZNSXEXFkMpjcqsQwDSYVv5FhRFaI0V1ECnwbz4j59T/G+rXNWaIQ== - - "@octokit/core@^4.2.1": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@octokit/core/-/core-4.2.4.tgz#d8769ec2b43ff37cc3ea89ec4681a20ba58ef907" - integrity sha512-rYKilwgzQ7/imScn3M9/pFfUf4I1AZEH3KhyJmtPdE2zfaXAn2mFfUy4FbKewzc2We5y/LlKLj36fWJLKC2SIQ== - dependencies: - "@octokit/auth-token" "^3.0.0" - "@octokit/graphql" "^5.0.0" - "@octokit/request" "^6.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - before-after-hook "^2.2.0" - universal-user-agent "^6.0.0" - - "@octokit/endpoint@^7.0.0": - version "7.0.6" - resolved "https://registry.yarnpkg.com/@octokit/endpoint/-/endpoint-7.0.6.tgz#791f65d3937555141fb6c08f91d618a7d645f1e2" - integrity sha512-5L4fseVRUsDFGR00tMWD/Trdeeihn999rTMGRMC1G/Ldi1uWlWJzI98H4Iak5DB/RVvQuyMYKqSK/R6mbSOQyg== - dependencies: - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - universal-user-agent "^6.0.0" - - "@octokit/graphql@^5.0.0": - version "5.0.6" - resolved "https://registry.yarnpkg.com/@octokit/graphql/-/graphql-5.0.6.tgz#9eac411ac4353ccc5d3fca7d76736e6888c5d248" - integrity sha512-Fxyxdy/JH0MnIB5h+UQ3yCoh1FG4kWXfFKkpWqjZHw/p+Kc8Y44Hu/kCgNBT6nU1shNumEchmW/sUO1JuQnPcw== - dependencies: - "@octokit/request" "^6.0.0" - "@octokit/types" "^9.0.0" - universal-user-agent "^6.0.0" - - "@octokit/openapi-types@^18.0.0": - version "18.1.1" - resolved "https://registry.yarnpkg.com/@octokit/openapi-types/-/openapi-types-18.1.1.tgz#09bdfdabfd8e16d16324326da5148010d765f009" - integrity sha512-VRaeH8nCDtF5aXWnjPuEMIYf1itK/s3JYyJcWFJT8X9pSNnBtriDf7wlEWsGuhPLl4QIH4xM8fqTXDwJ3Mu6sw== - - "@octokit/plugin-enterprise-rest@6.0.1": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@octokit/plugin-enterprise-rest/-/plugin-enterprise-rest-6.0.1.tgz#e07896739618dab8da7d4077c658003775f95437" - integrity sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw== - - "@octokit/plugin-paginate-rest@^6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-6.1.2.tgz#f86456a7a1fe9e58fec6385a85cf1b34072341f8" - integrity sha512-qhrmtQeHU/IivxucOV1bbI/xZyC/iOBhclokv7Sut5vnejAIAEXVcGQeRpQlU39E0WwK9lNvJHphHri/DB6lbQ== - dependencies: - "@octokit/tsconfig" "^1.0.2" - "@octokit/types" "^9.2.3" - - "@octokit/plugin-request-log@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@octokit/plugin-request-log/-/plugin-request-log-1.0.4.tgz#5e50ed7083a613816b1e4a28aeec5fb7f1462e85" - integrity sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA== - - "@octokit/plugin-rest-endpoint-methods@^7.1.2": - version "7.2.3" - resolved "https://registry.yarnpkg.com/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-7.2.3.tgz#37a84b171a6cb6658816c82c4082ac3512021797" - integrity sha512-I5Gml6kTAkzVlN7KCtjOM+Ruwe/rQppp0QU372K1GP7kNOYEKe8Xn5BW4sE62JAHdwpq95OQK/qGNyKQMUzVgA== - dependencies: - "@octokit/types" "^10.0.0" - - "@octokit/request-error@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@octokit/request-error/-/request-error-3.0.3.tgz#ef3dd08b8e964e53e55d471acfe00baa892b9c69" - integrity sha512-crqw3V5Iy2uOU5Np+8M/YexTlT8zxCfI+qu+LxUB7SZpje4Qmx3mub5DfEKSO8Ylyk0aogi6TYdf6kxzh2BguQ== - dependencies: - "@octokit/types" "^9.0.0" - deprecation "^2.0.0" - once "^1.4.0" - - "@octokit/request@^6.0.0": - version "6.2.8" - resolved "https://registry.yarnpkg.com/@octokit/request/-/request-6.2.8.tgz#aaf480b32ab2b210e9dadd8271d187c93171d8eb" - integrity sha512-ow4+pkVQ+6XVVsekSYBzJC0VTVvh/FCTUUgTsboGq+DTeWdyIFV8WSCdo0RIxk6wSkBTHqIK1mYuY7nOBXOchw== - dependencies: - "@octokit/endpoint" "^7.0.0" - "@octokit/request-error" "^3.0.0" - "@octokit/types" "^9.0.0" - is-plain-object "^5.0.0" - node-fetch "^2.6.7" - universal-user-agent "^6.0.0" - - "@octokit/rest@19.0.11": - version "19.0.11" - resolved "https://registry.yarnpkg.com/@octokit/rest/-/rest-19.0.11.tgz#2ae01634fed4bd1fca5b642767205ed3fd36177c" - integrity sha512-m2a9VhaP5/tUw8FwfnW2ICXlXpLPIqxtg3XcAiGMLj/Xhw3RSBfZ8le/466ktO1Gcjr8oXudGnHhxV1TXJgFxw== - dependencies: - "@octokit/core" "^4.2.1" - "@octokit/plugin-paginate-rest" "^6.1.2" - "@octokit/plugin-request-log" "^1.0.4" - "@octokit/plugin-rest-endpoint-methods" "^7.1.2" - - "@octokit/tsconfig@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@octokit/tsconfig/-/tsconfig-1.0.2.tgz#59b024d6f3c0ed82f00d08ead5b3750469125af7" - integrity sha512-I0vDR0rdtP8p2lGMzvsJzbhdOWy405HcGovrspJ8RRibHnyRgggUSNO5AIox5LmqiwmatHKYsvj6VGFHkqS7lA== - - "@octokit/types@^10.0.0": - version "10.0.0" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-10.0.0.tgz#7ee19c464ea4ada306c43f1a45d444000f419a4a" - integrity sha512-Vm8IddVmhCgU1fxC1eyinpwqzXPEYu0NrYzD3YZjlGjyftdLBTeqNblRC0jmJmgxbJIsQlyogVeGnrNaaMVzIg== - dependencies: - "@octokit/openapi-types" "^18.0.0" - - "@octokit/types@^9.0.0", "@octokit/types@^9.2.3": - version "9.3.2" - resolved "https://registry.yarnpkg.com/@octokit/types/-/types-9.3.2.tgz#3f5f89903b69f6a2d196d78ec35f888c0013cac5" - integrity sha512-D4iHGTdAnEEVsB8fl95m1hiz7D5YiRdQ9b/OEb3BYRVwbLsGHcRVPz+u+BgRLNk0Q0/4iZCBqDN96j2XNxfXrA== - dependencies: - "@octokit/openapi-types" "^18.0.0" - - "@parcel/watcher-android-arm64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.3.0.tgz#d82e74bb564ebd4d8a88791d273a3d2bd61e27ab" - integrity sha512-f4o9eA3dgk0XRT3XhB0UWpWpLnKgrh1IwNJKJ7UJek7eTYccQ8LR7XUWFKqw6aEq5KUNlCcGvSzKqSX/vtWVVA== - - "@parcel/watcher-darwin-arm64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.3.0.tgz#c9cd03f8f233d512fcfc873d5b4e23f1569a82ad" - integrity sha512-mKY+oijI4ahBMc/GygVGvEdOq0L4DxhYgwQqYAz/7yPzuGi79oXrZG52WdpGA1wLBPrYb0T8uBaGFo7I6rvSKw== - - "@parcel/watcher-darwin-x64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.3.0.tgz#83c902994a2a49b9e1ab5050dba24876fdc2c219" - integrity sha512-20oBj8LcEOnLE3mgpy6zuOq8AplPu9NcSSSfyVKgfOhNAc4eF4ob3ldj0xWjGGbOF7Dcy1Tvm6ytvgdjlfUeow== - - "@parcel/watcher-freebsd-x64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.3.0.tgz#7a0f4593a887e2752b706aff2dae509aef430cf6" - integrity sha512-7LftKlaHunueAEiojhCn+Ef2CTXWsLgTl4hq0pkhkTBFI3ssj2bJXmH2L67mKpiAD5dz66JYk4zS66qzdnIOgw== - - "@parcel/watcher-linux-arm-glibc@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.3.0.tgz#3fc90c3ebe67de3648ed2f138068722f9b1d47da" - integrity sha512-1apPw5cD2xBv1XIHPUlq0cO6iAaEUQ3BcY0ysSyD9Kuyw4MoWm1DV+W9mneWI+1g6OeP6dhikiFE6BlU+AToTQ== - - "@parcel/watcher-linux-arm64-glibc@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.3.0.tgz#f7bbbf2497d85fd11e4c9e9c26ace8f10ea9bcbc" - integrity sha512-mQ0gBSQEiq1k/MMkgcSB0Ic47UORZBmWoAWlMrTW6nbAGoLZP+h7AtUM7H3oDu34TBFFvjy4JCGP43JlylkTQA== - - "@parcel/watcher-linux-arm64-musl@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.3.0.tgz#de131a9fcbe1fa0854e9cbf4c55bed3b35bcff43" - integrity sha512-LXZAExpepJew0Gp8ZkJ+xDZaTQjLHv48h0p0Vw2VMFQ8A+RKrAvpFuPVCVwKJCr5SE+zvaG+Etg56qXvTDIedw== - - "@parcel/watcher-linux-x64-glibc@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.3.0.tgz#193dd1c798003cdb5a1e59470ff26300f418a943" - integrity sha512-P7Wo91lKSeSgMTtG7CnBS6WrA5otr1K7shhSjKHNePVmfBHDoAOHYRXgUmhiNfbcGk0uMCHVcdbfxtuiZCHVow== - - "@parcel/watcher-linux-x64-musl@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-linux-x64-musl/-/watcher-linux-x64-musl-2.3.0.tgz#6dbdb86d96e955ab0fe4a4b60734ec0025a689dd" - integrity sha512-+kiRE1JIq8QdxzwoYY+wzBs9YbJ34guBweTK8nlzLKimn5EQ2b2FSC+tAOpq302BuIMjyuUGvBiUhEcLIGMQ5g== - - "@parcel/watcher-wasm@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-wasm/-/watcher-wasm-2.3.0.tgz#73b66c6fbd2a3326ae86a1ec77eab7139d0dd725" - integrity sha512-ejBAX8H0ZGsD8lSICDNyMbSEtPMWgDL0WFCt/0z7hyf5v8Imz4rAM8xY379mBsECkq/Wdqa5WEDLqtjZ+6NxfA== - dependencies: - is-glob "^4.0.3" - micromatch "^4.0.5" - napi-wasm "^1.1.0" - - "@parcel/watcher-win32-arm64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.3.0.tgz#59da26a431da946e6c74fa6b0f30b120ea6650b6" - integrity sha512-35gXCnaz1AqIXpG42evcoP2+sNL62gZTMZne3IackM+6QlfMcJLy3DrjuL6Iks7Czpd3j4xRBzez3ADCj1l7Aw== - - "@parcel/watcher-win32-ia32@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.3.0.tgz#3ee6a18b08929cd3b788e8cc9547fd9a540c013a" - integrity sha512-FJS/IBQHhRpZ6PiCjFt1UAcPr0YmCLHRbTc00IBTrelEjlmmgIVLeOx4MSXzx2HFEy5Jo5YdhGpxCuqCyDJ5ow== - - "@parcel/watcher-win32-x64@2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.3.0.tgz#14e7246289861acc589fd608de39fe5d8b4bb0a7" - integrity sha512-dLx+0XRdMnVI62kU3wbXvbIRhLck4aE28bIGKbRGS7BJNt54IIj9+c/Dkqb+7DJEbHUZAX1bwaoM8PqVlHJmCA== - - "@parcel/watcher@2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.4.tgz#f300fef4cc38008ff4b8c29d92588eced3ce014b" - integrity sha512-cTDi+FUDBIUOBKEtj+nhiJ71AZVlkAsQFuGQTun5tV9mwQBQgZvhCzG+URPQc8myeN32yRVZEfVAPCs1RW+Jvg== - dependencies: - node-addon-api "^3.2.1" - node-gyp-build "^4.3.0" - - "@parcel/watcher@^2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.3.0.tgz#803517abbc3981a1a1221791d9f59dc0590d50f9" - integrity sha512-pW7QaFiL11O0BphO+bq3MgqeX/INAk9jgBldVDYjlQPO4VddoZnF22TcF9onMhnLVHuNqBJeRf+Fj7eezi/+rQ== - dependencies: - detect-libc "^1.0.3" - is-glob "^4.0.3" - micromatch "^4.0.5" - node-addon-api "^7.0.0" - optionalDependencies: - "@parcel/watcher-android-arm64" "2.3.0" - "@parcel/watcher-darwin-arm64" "2.3.0" - "@parcel/watcher-darwin-x64" "2.3.0" - "@parcel/watcher-freebsd-x64" "2.3.0" - "@parcel/watcher-linux-arm-glibc" "2.3.0" - "@parcel/watcher-linux-arm64-glibc" "2.3.0" - "@parcel/watcher-linux-arm64-musl" "2.3.0" - "@parcel/watcher-linux-x64-glibc" "2.3.0" - "@parcel/watcher-linux-x64-musl" "2.3.0" - "@parcel/watcher-win32-arm64" "2.3.0" - "@parcel/watcher-win32-ia32" "2.3.0" - "@parcel/watcher-win32-x64" "2.3.0" - - "@pkgjs/parseargs@^0.11.0": - version "0.11.0" - resolved "https://registry.yarnpkg.com/@pkgjs/parseargs/-/parseargs-0.11.0.tgz#a77ea742fab25775145434eb1d2328cf5013ac33" - integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== - - "@pmmmwh/react-refresh-webpack-plugin@^0.5.3", "@pmmmwh/react-refresh-webpack-plugin@^0.5.4": - version "0.5.11" - resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.11.tgz#7c2268cedaa0644d677e8c4f377bc8fb304f714a" - integrity sha512-7j/6vdTym0+qZ6u4XbSAxrWBGYSdCfTzySkj7WAFgDLmSyWlOrWvpyzxlFh5jtw9dn0oL/jtW+06XfFiisN3JQ== - dependencies: - ansi-html-community "^0.0.8" - common-path-prefix "^3.0.0" - core-js-pure "^3.23.3" - error-stack-parser "^2.0.6" - find-up "^5.0.0" - html-entities "^2.1.0" - loader-utils "^2.0.4" - schema-utils "^3.0.0" - source-map "^0.7.3" - - "@popperjs/core@^2.11.8": - version "2.11.8" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.11.8.tgz#6b79032e760a0899cd4204710beede972a3a185f" - integrity sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A== - - "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" - integrity sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ== - - "@protobufjs/base64@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" - integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== - - "@protobufjs/codegen@^2.0.4": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" - integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== - - "@protobufjs/eventemitter@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" - integrity sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q== - - "@protobufjs/fetch@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" - integrity sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ== - dependencies: - "@protobufjs/aspromise" "^1.1.1" - "@protobufjs/inquire" "^1.1.0" - - "@protobufjs/float@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" - integrity sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ== - - "@protobufjs/inquire@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" - integrity sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q== - - "@protobufjs/path@^1.1.2": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" - integrity sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA== - - "@protobufjs/pool@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" - integrity sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw== - - "@protobufjs/utf8@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" - integrity sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw== - - "@react-aria/breadcrumbs@^3.5.8": - version "3.5.8" - resolved "https://registry.yarnpkg.com/@react-aria/breadcrumbs/-/breadcrumbs-3.5.8.tgz#243a25621066443e42f2a6a1cb82fe3c558f6dea" - integrity sha512-jeek23igeqXct7S3ShW2jtFUc5g3fS9ZEBZkF64FWBrwfCiaZwb8TcKkK/xFw36/q5mxEt+seNiqnNzvsICJuQ== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/link" "^3.6.2" - "@react-aria/utils" "^3.22.0" - "@react-types/breadcrumbs" "^3.7.2" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/button@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/button/-/button-3.9.0.tgz#df59e0628917b320c4d1655e23547eb41a9a0f08" - integrity sha512-Jri4OCN+4YmpJDPNQvk1DJoskKD9sdTxZaWWWJdAwoSIunZk3IEBXVvRfKzsEAVtI+UJN25zC2kyjXbVPS2XAA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/toggle" "^3.7.0" - "@react-types/button" "^3.9.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/calendar@^3.5.3": - version "3.5.3" - resolved "https://registry.yarnpkg.com/@react-aria/calendar/-/calendar-3.5.3.tgz#225014e7ef3124bdbc915b7283f7c5d378e1a2a9" - integrity sha512-jW48jk0TIe0HAJS+z8zqd8M86FEuqrk1qEIjMWnf8rFnA7hPPpjdjUrY9vSIeC95NcbyZbFnr1bHzQjAIzosQw== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.22.0" - "@react-stately/calendar" "^3.4.2" - "@react-types/button" "^3.9.1" - "@react-types/calendar" "^3.4.2" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/checkbox@^3.12.0": - version "3.12.0" - resolved "https://registry.yarnpkg.com/@react-aria/checkbox/-/checkbox-3.12.0.tgz#a965e975975404ecf1ff867284511e4490a69c21" - integrity sha512-CyFZoI+z9hhyB3wb7IBsZxE30vXfYO2vSyET16zlkJ4qiFMqMiVLE4ekq034MHltCdpAczgP5yfKgNnJOmj7vQ== - dependencies: - "@react-aria/form" "^3.0.0" - "@react-aria/label" "^3.7.3" - "@react-aria/toggle" "^3.9.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/checkbox" "^3.6.0" - "@react-stately/form" "^3.0.0" - "@react-stately/toggle" "^3.7.0" - "@react-types/checkbox" "^3.6.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/combobox@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-aria/combobox/-/combobox-3.8.0.tgz#1806cd5ea6c11c90802d7c0a0807d93271265c1c" - integrity sha512-lInzzZrH4vFlxmvDpXgQRkkREm7YIx258IRpQqll8Bny2vKMmZoF06zWMbcHP0CjFqYxExQeTjSYx0OTRRxkCQ== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/listbox" "^3.11.2" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/menu" "^3.11.2" - "@react-aria/overlays" "^3.19.0" - "@react-aria/selection" "^3.17.2" - "@react-aria/textfield" "^3.13.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/collections" "^3.10.3" - "@react-stately/combobox" "^3.8.0" - "@react-stately/form" "^3.0.0" - "@react-types/button" "^3.9.1" - "@react-types/combobox" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/datepicker@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/datepicker/-/datepicker-3.9.0.tgz#281d351b36a3cd186e39f587437d9a3ce9d8986d" - integrity sha512-FIpiJxwBNOM8a6hLOqQJ4JrvRiGL6Zr44E1mHtAWStp2kBEJ6+O2JRm4PQ5Pzvdw6xnCpOBdfESdNdlXN7lVqQ== - dependencies: - "@internationalized/date" "^3.5.0" - "@internationalized/number" "^3.4.0" - "@internationalized/string" "^3.1.1" - "@react-aria/focus" "^3.15.0" - "@react-aria/form" "^3.0.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/spinbutton" "^3.6.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/datepicker" "^3.9.0" - "@react-stately/form" "^3.0.0" - "@react-types/button" "^3.9.1" - "@react-types/calendar" "^3.4.2" - "@react-types/datepicker" "^3.7.0" - "@react-types/dialog" "^3.5.7" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/dialog@^3.5.8": - version "3.5.8" - resolved "https://registry.yarnpkg.com/@react-aria/dialog/-/dialog-3.5.8.tgz#3b52ff145b16e0f47b04364239bd91d39968e3c2" - integrity sha512-KIc1FORdHhZ3bWom4qHO0hmlL4e5Hup6N25EY8HP5I7Ftv9EBBGaO5grtxZ2fX8kiCJNI4y+k67ZZ71wKJvMiA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/overlays" "^3.19.0" - "@react-aria/utils" "^3.22.0" - "@react-types/dialog" "^3.5.7" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/dnd@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-aria/dnd/-/dnd-3.5.0.tgz#de803fa390e73205b600933c7fe45ac888a62f3c" - integrity sha512-6IuqmXwnfgRfeXDbfsPZzScapCmtRIkphTBPoLT575uEbZC7ROLgRJ/4NIKxvtTA6IIBqUGcvaqU9Mpg8j4U5Q== - dependencies: - "@internationalized/string" "^3.1.1" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/overlays" "^3.19.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/dnd" "^3.2.6" - "@react-types/button" "^3.9.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/focus@^3.15.0": - version "3.15.0" - resolved "https://registry.yarnpkg.com/@react-aria/focus/-/focus-3.15.0.tgz#acca3cfe94e0ba0c00276e74c6cca06975f75f87" - integrity sha512-nnxRyfqHuAjRwdQ4BpQyZPtGFKZmRU6cnaIb3pqWFCqEyJQensV7MA3TJ4Jhadq67cy1Ji5SYSlr1duBwjoYvw== - dependencies: - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - clsx "^1.1.1" - - "@react-aria/form@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-aria/form/-/form-3.0.0.tgz#d4e892687331a9cba1cfc48be5754100ab736dec" - integrity sha512-APeGph9oTO8nro4ZObuy1hk+0hpF/ji9O3odPGhLkzP/HvW2J7NI9pjKJOINfgtYr2yvVUZf/MbTMxPwtAxhaQ== - dependencies: - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/form" "^3.0.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/grid@^3.8.5": - version "3.8.5" - resolved "https://registry.yarnpkg.com/@react-aria/grid/-/grid-3.8.5.tgz#92682b36b230920d507e3ed4fb7e9564f96c9f02" - integrity sha512-0p+Bbs9rpQeOy8b75DamlzVPKylBoe/z0XwkeeTChHP2TK3TwPXh6J5EmisQx6K8zsb3iZULQRcP4QibvnMbrg== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/collections" "^3.10.3" - "@react-stately/grid" "^3.8.3" - "@react-stately/selection" "^3.14.1" - "@react-stately/virtualizer" "^3.6.5" - "@react-types/checkbox" "^3.6.0" - "@react-types/grid" "^3.2.3" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/gridlist@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-aria/gridlist/-/gridlist-3.7.2.tgz#80a1399eba438df9d8d8e721eb98b3bf1acdbe52" - integrity sha512-9keGYZz0yILVqAnFzF6hGRtHm1vfSD1mNnH8oyn7mKjyr7qOln7s5f8Nl85ueMolfrV3H2rCZgM2itNQ+Ezzgg== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/grid" "^3.8.5" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/list" "^3.10.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/i18n@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/i18n/-/i18n-3.9.0.tgz#7aa74e02e74e348de3a34b7599e71ff6920b73ee" - integrity sha512-ebGP/sVG0ZtNF4RNFzs/W01tl7waYpBManh1kKWgA4roDPFt/odkgkDBzKGl+ggBb7TQRHsfUFHuqKsrsMy9TA== - dependencies: - "@internationalized/date" "^3.5.0" - "@internationalized/message" "^3.1.1" - "@internationalized/number" "^3.4.0" - "@internationalized/string" "^3.1.1" - "@react-aria/ssr" "^3.9.0" - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/interactions@^3.20.0": - version "3.20.0" - resolved "https://registry.yarnpkg.com/@react-aria/interactions/-/interactions-3.20.0.tgz#8db350541004f50c0479cc52b82597d8248ac5db" - integrity sha512-JCCEyK2Nb4mEHucrgmqhTHTNAEqhsiM07jJmmY22eikxnCQnsEfdwXyg9cgZLG79D5V7jyqVRqOp2OsG7Qx7kQ== - dependencies: - "@react-aria/ssr" "^3.9.0" - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/label@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@react-aria/label/-/label-3.7.3.tgz#37cb12d2a9495534205b6266aa5174c2fd861368" - integrity sha512-v1zuqbpYyYaPjrBWpceGjMpwP4ne6fLoOXdoIZoKLux2jkAcyIF2kIJFiyYoPQYQJWGRNo7q1oSwamxmng4xJw== - dependencies: - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/link@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-aria/link/-/link-3.6.2.tgz#4d7fb00000219aa3ff4bd02f59d5d3bd08be0da8" - integrity sha512-v9gXgQ3Gev0JOlg2MAXcubDMgX+0BlJ+hTyFYFMuN/4jVBlAe426WKbjg+6MMzxwukWg9C3Q08JzqdFTi4cBng== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-types/link" "^3.5.2" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/listbox@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-aria/listbox/-/listbox-3.11.2.tgz#5d1d841987c1fbe300fa5d4bf5071f660b2a625b" - integrity sha512-FXdoqYLUTJn16OxodyS518PIcwzFkCfW5bxQepoy88NDMGtqp6u8fvEPpAoZbomvw/pV9MuEaMAw9qLyfkD4DA== - dependencies: - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/collections" "^3.10.3" - "@react-stately/list" "^3.10.1" - "@react-types/listbox" "^3.4.6" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/live-announcer@^3.3.1": - version "3.3.1" - resolved "https://registry.yarnpkg.com/@react-aria/live-announcer/-/live-announcer-3.3.1.tgz#bf864b8820fb02daaeefc1c972782a0174fd60b9" - integrity sha512-hsc77U7S16trM86d+peqJCOCQ7/smO1cybgdpOuzXyiwcHQw8RQ4GrXrS37P4Ux/44E9nMZkOwATQRT2aK8+Ew== - dependencies: - "@swc/helpers" "^0.5.0" - - "@react-aria/menu@^3.11.2": - version "3.11.2" - resolved "https://registry.yarnpkg.com/@react-aria/menu/-/menu-3.11.2.tgz#bf6dbf751acc09ace12d35bb034a3790f9006720" - integrity sha512-I4R5FOvRtwIQW+0naXav5giZBp935X2tXB2xBg/cSAYDXgfLmFPLHkyPbO77hR6FwazfFfJoKdn0pVcRox3lrQ== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/overlays" "^3.19.0" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/collections" "^3.10.3" - "@react-stately/menu" "^3.5.7" - "@react-stately/tree" "^3.7.4" - "@react-types/button" "^3.9.1" - "@react-types/menu" "^3.9.6" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/meter@^3.4.8": - version "3.4.8" - resolved "https://registry.yarnpkg.com/@react-aria/meter/-/meter-3.4.8.tgz#af30df03a4c35b13a873ca0847cfa705902b918d" - integrity sha512-u/pNisFs8UottonYlwqaS2i/NhHIw9LcApHo55XP7XMFCnaHPlq3mJzpSsr0zuCTvat2djoKelj41jT6Fhuw+A== - dependencies: - "@react-aria/progress" "^3.4.8" - "@react-types/meter" "^3.3.6" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/numberfield@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@react-aria/numberfield/-/numberfield-3.10.0.tgz#07d9be63346a0b8e9177a4ca9e4363e03f04afa9" - integrity sha512-ixkvkPTn18RNPnbaT726CHA+Wpr/qTYWboq8hSaJK0LiAtiEWCKg0pmVtJ4lFntAQ5GNp02xudTwhQdLN5WRig== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/spinbutton" "^3.6.0" - "@react-aria/textfield" "^3.13.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/form" "^3.0.0" - "@react-stately/numberfield" "^3.7.0" - "@react-types/button" "^3.9.1" - "@react-types/numberfield" "^3.7.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/overlays@^3.19.0": - version "3.19.0" - resolved "https://registry.yarnpkg.com/@react-aria/overlays/-/overlays-3.19.0.tgz#0568d808c61e923174e896fc342a1529538da545" - integrity sha512-VN5GkB8+uZ2cfXljBtkqmrsAhBdGoj4un/agH0Qyihi2dazsMeafczSNnqzbpVgB4Zt2UHPJUkKwihgzXRxJJA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/ssr" "^3.9.0" - "@react-aria/utils" "^3.22.0" - "@react-aria/visually-hidden" "^3.8.7" - "@react-stately/overlays" "^3.6.4" - "@react-types/button" "^3.9.1" - "@react-types/overlays" "^3.8.4" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/progress@^3.4.8": - version "3.4.8" - resolved "https://registry.yarnpkg.com/@react-aria/progress/-/progress-3.4.8.tgz#3776ebeecc27c5b03db7a260ab39a92dbf722a21" - integrity sha512-Nah3aj5BNRa0+urQZimzb0vuKQK7lsc8BrUwJuHTwGRBSWUjCADExrJYdhDIR/nLUV2TCmAQl+GJtTgbEEj0DQ== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/label" "^3.7.3" - "@react-aria/utils" "^3.22.0" - "@react-types/progress" "^3.5.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/radio@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/radio/-/radio-3.9.0.tgz#529b796ed3c5731c808af0a3da29e5535fa553b2" - integrity sha512-kr3+OQ1YU/3mURZfCsYaQmJ/c15qOm8uScaDRC39qz97bLNASakQqMImIaS+GluPKx1PEW3y2ErAgLplH28zZw== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/form" "^3.0.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/utils" "^3.22.0" - "@react-stately/radio" "^3.10.0" - "@react-types/radio" "^3.6.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/searchfield@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-aria/searchfield/-/searchfield-3.6.0.tgz#dc40310c875ba4edd288392ada7223186c5fd1eb" - integrity sha512-mHaN+sx2SLqluvF0/YIBQ9WA5LakSWl79FgC0sOWEaOZhDswAbJ9tESdi/M/ahtOnVwblE0cpHRlUKV0Oz4gOw== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/textfield" "^3.13.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/searchfield" "^3.5.0" - "@react-types/button" "^3.9.1" - "@react-types/searchfield" "^3.5.2" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/select@^3.14.0": - version "3.14.0" - resolved "https://registry.yarnpkg.com/@react-aria/select/-/select-3.14.0.tgz#81c7a3db9fec6d55f4b2820913207afc39b1600d" - integrity sha512-ulVFH8K1yr8CxQE7pzhlM3aWBltWfSbWdJV3FXDqM0kA+GHqqPwZVJcqPuegtaiju1z6nRk4q789kJa4o+4M9g== - dependencies: - "@react-aria/form" "^3.0.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/listbox" "^3.11.2" - "@react-aria/menu" "^3.11.2" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-aria/visually-hidden" "^3.8.7" - "@react-stately/select" "^3.6.0" - "@react-types/button" "^3.9.1" - "@react-types/select" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/selection@^3.17.2": - version "3.17.2" - resolved "https://registry.yarnpkg.com/@react-aria/selection/-/selection-3.17.2.tgz#74b798344df1eb90e3fdae9bc880c0488468ae3b" - integrity sha512-AXXY3eOIWnITabMn6c0bpLPXkSX7040LOZU+7pQgtZJwDdZorLuKw4i7WS5i71LcV71ywG4mtqc9mOb/GfhUbg== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/selection" "^3.14.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/separator@^3.3.8": - version "3.3.8" - resolved "https://registry.yarnpkg.com/@react-aria/separator/-/separator-3.3.8.tgz#de209f8158c4dd5d4d66f0a57525bbfdb5b00b15" - integrity sha512-u15HgH2IVKN/mx7Hp9dfNiFpPU/mq2EA7l0e2fsVSjA77nhSctUFBAqaR7FAI/y86RUhq3zplIz4BJek1/3Dvw== - dependencies: - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/slider@^3.7.3": - version "3.7.3" - resolved "https://registry.yarnpkg.com/@react-aria/slider/-/slider-3.7.3.tgz#799b47e8559acf63d9c1195fac88bd4d5ca7cad0" - integrity sha512-AbrTD9UzMn0CwxFjOhJHz2ms2zdJlBL3XnbvqkpsmpXUl0u8WT1QAEaMnS5+792gnSGZs/ARDmse53o+IO8wTA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/utils" "^3.22.0" - "@react-stately/slider" "^3.4.5" - "@react-types/shared" "^3.22.0" - "@react-types/slider" "^3.7.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/spinbutton@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-aria/spinbutton/-/spinbutton-3.6.0.tgz#b881ffd6780f90972879334268634740297197c9" - integrity sha512-I7f1gfwVRcjguEXZijk0z5g8njZ2YWnQzVzcwGf8ocLPxfw1CnSivNCzwVj2ChXPX10uXewXVMLWVCz+BRC9uQ== - dependencies: - "@react-aria/i18n" "^3.9.0" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.22.0" - "@react-types/button" "^3.9.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/ssr@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/ssr/-/ssr-3.9.0.tgz#457310129e1447b09d2f4aa2fdd62ab0e668d88c" - integrity sha512-Bz6BqP6ZorCme9tSWHZVmmY+s7AU8l6Vl2NUYmBzezD//fVHHfFo4lFBn5tBuAaJEm3AuCLaJQ6H2qhxNSb7zg== - dependencies: - "@swc/helpers" "^0.5.0" - - "@react-aria/switch@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-aria/switch/-/switch-3.5.7.tgz#b543ac69b5d5dca70c75fc6c80b9c2c9d8191403" - integrity sha512-zBEsB071zzhQ82RwAA42pFLXHgrpya0OoRAsTO6jHZwiaYMsyqJI2eiXd7F6rqklpgyO6k7jOQklGUuoSJW4pA== - dependencies: - "@react-aria/toggle" "^3.9.0" - "@react-stately/toggle" "^3.7.0" - "@react-types/switch" "^3.5.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/table@^3.13.2": - version "3.13.2" - resolved "https://registry.yarnpkg.com/@react-aria/table/-/table-3.13.2.tgz#ef73709facdd005d7d0f6051dc9bedb85eb4e58a" - integrity sha512-bJgMx2SZ8SFmTosbv6k1lZ1a0Yw3f8tzWhpIQodCaMHhtI7izA6YqDNx47NeBNYpVm9DFfAoWbb79HFJ+OKIJA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/grid" "^3.8.5" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/live-announcer" "^3.3.1" - "@react-aria/utils" "^3.22.0" - "@react-aria/visually-hidden" "^3.8.7" - "@react-stately/collections" "^3.10.3" - "@react-stately/flags" "^3.0.0" - "@react-stately/table" "^3.11.3" - "@react-stately/virtualizer" "^3.6.5" - "@react-types/checkbox" "^3.6.0" - "@react-types/grid" "^3.2.3" - "@react-types/shared" "^3.22.0" - "@react-types/table" "^3.9.1" - "@swc/helpers" "^0.5.0" - - "@react-aria/tabs@^3.8.2": - version "3.8.2" - resolved "https://registry.yarnpkg.com/@react-aria/tabs/-/tabs-3.8.2.tgz#ab11e77e6e9afaebb7549983c0aa0d66ae5d96bf" - integrity sha512-zDfeEEyJmcnH9TFvJECWIrJpxX4SmREFV1/P8hN6ZUJPYoeiGMXYYFvjcRb1r3LN8XKlbwR37AQ3Cn1/yhrUwQ== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/i18n" "^3.9.0" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/tabs" "^3.6.2" - "@react-types/shared" "^3.22.0" - "@react-types/tabs" "^3.3.4" - "@swc/helpers" "^0.5.0" - - "@react-aria/tag@^3.3.0": - version "3.3.0" - resolved "https://registry.yarnpkg.com/@react-aria/tag/-/tag-3.3.0.tgz#ba7b5e2fc3c65f9a37c4737cb96897313174b9f2" - integrity sha512-mANJTcPyut98O4D3cAKaNEV6QFfoljZCDAgC+uJkV/Zn8cU4JOFeNLAyNoLRlPvYw+msqr6wUyPkWNERuO+1Uw== - dependencies: - "@react-aria/gridlist" "^3.7.2" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/selection" "^3.17.2" - "@react-aria/utils" "^3.22.0" - "@react-stately/list" "^3.10.1" - "@react-types/button" "^3.9.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/textfield@^3.13.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@react-aria/textfield/-/textfield-3.13.0.tgz#bc8a027f93598a1ebd5013d027549a03d7b8dd04" - integrity sha512-sUlinDE+k/WhbskyqVOkuffuhiQpjgvp+iGRoralStVgb8Tcb+POxgAlw5jS4tNjdivCb3IjVJemUNJM7xsxxA== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/form" "^3.0.0" - "@react-aria/label" "^3.7.3" - "@react-aria/utils" "^3.22.0" - "@react-stately/form" "^3.0.0" - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@react-types/textfield" "^3.9.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/toggle@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-aria/toggle/-/toggle-3.9.0.tgz#c1b253d2fc05f2a673abd9fe4d62bc01a8781a92" - integrity sha512-2YMWYQUEmcoAXtrAE86QXBS9XlmJyV6IFRlMTBNaeLTdH3AmACExgsyU66Tt0sKl6LMDMI376ItMFqAz27BBdQ== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/toggle" "^3.7.0" - "@react-types/checkbox" "^3.6.0" - "@swc/helpers" "^0.5.0" - - "@react-aria/tooltip@^3.6.5": - version "3.6.5" - resolved "https://registry.yarnpkg.com/@react-aria/tooltip/-/tooltip-3.6.5.tgz#aeb4c71db46f2c9ad0ff0b6810002bdacc07fea1" - integrity sha512-hXw4Z8nYLOWz3QOQ807wWZdvDwR3gofsmZhAehg2HPRwdRfCQK+1cjVKeUd9cKCAxs0Cay7dV0oUdilLbCQ2Gg== - dependencies: - "@react-aria/focus" "^3.15.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-stately/tooltip" "^3.4.6" - "@react-types/shared" "^3.22.0" - "@react-types/tooltip" "^3.4.6" - "@swc/helpers" "^0.5.0" - - "@react-aria/utils@^3.21.1", "@react-aria/utils@^3.22.0": - version "3.22.0" - resolved "https://registry.yarnpkg.com/@react-aria/utils/-/utils-3.22.0.tgz#962a45ae95fdc21de7f22dda68253b0fb2470d06" - integrity sha512-Qi/m65GFFljXA/ayj1m5g3KZdgbZY3jacSSqD5vNUOEGiKsn4OQcsw8RfC2c0SgtLV1hLzsfvFI1OiryPlGCcw== - dependencies: - "@react-aria/ssr" "^3.9.0" - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - clsx "^1.1.1" - - "@react-aria/visually-hidden@^3.8.7": - version "3.8.7" - resolved "https://registry.yarnpkg.com/@react-aria/visually-hidden/-/visually-hidden-3.8.7.tgz#059699c70cc354ccb3699151b09071b3fc43fa82" - integrity sha512-OuIGMVQIt7GC43h4x35BgkZid8lhoPu7Xz4TQRP8nvOJWb1lH7ehrRRuGdUsK3y90nwpxTdNdg4DILblg+VaLw== - dependencies: - "@react-aria/interactions" "^3.20.0" - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-icons/all-files@^4.1.0": - version "4.1.0" - resolved "https://registry.yarnpkg.com/@react-icons/all-files/-/all-files-4.1.0.tgz#477284873a0821928224b6fc84c62d2534d6650b" - integrity sha512-hxBI2UOuVaI3O/BhQfhtb4kcGn9ft12RWAFVMUeNjqqhLsHvFtzIkFaptBJpFDANTKoDfdVoHTKZDlwKCACbMQ== - - "@react-stately/calendar@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-stately/calendar/-/calendar-3.4.2.tgz#7dd55cd2f0689bd0a5825326507dcb6b3d7f3d05" - integrity sha512-RfH40rVa2EhUnQgqH3HTZL+YhL+6tZ8T9GbN1K3AbIM5BBEtkb3P8qGhcaI7WpwNy1rlRFFFXGcqFAMUncDg2Q== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-stately/utils" "^3.9.0" - "@react-types/calendar" "^3.4.2" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/checkbox@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-stately/checkbox/-/checkbox-3.6.0.tgz#448da0b07710a120959985fb081ad3855232fdc9" - integrity sha512-e1ChMwGovcOEDcdizqXDT6eDZixIMiPQOzNV5wPQ91SlGaIry9b0lQnK18tHg3yv2iiS6Ipj96cGBUKLJqQ+cQ== - dependencies: - "@react-stately/form" "^3.0.0" - "@react-stately/utils" "^3.9.0" - "@react-types/checkbox" "^3.6.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/collections@^3.10.3": - version "3.10.3" - resolved "https://registry.yarnpkg.com/@react-stately/collections/-/collections-3.10.3.tgz#c80bd30df3bf5d2a9c6fdf25f6313c5187d0154d" - integrity sha512-fA28HIApAIz9sNGeOVXZJPgV5Kig6M72KI1t9sUbnRUr9Xq9OMJTR6ElDMXNe0iTeZffRFDOPYyqnX9zkxof6Q== - dependencies: - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/combobox@^3.8.0": - version "3.8.0" - resolved "https://registry.yarnpkg.com/@react-stately/combobox/-/combobox-3.8.0.tgz#6bd9b23ade552f04e8ebc0eeb80e077efed17d6d" - integrity sha512-F74Avf7+8ruRqEB+3Lh6/C5jXc3ESJbRf9ovUxhmNAzBGeFKesPn5HpEpo87C+3OukGb+/Buvi3Rhib9+HVBKA== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/form" "^3.0.0" - "@react-stately/list" "^3.10.1" - "@react-stately/menu" "^3.5.7" - "@react-stately/select" "^3.6.0" - "@react-stately/utils" "^3.9.0" - "@react-types/combobox" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/data@^3.11.0": - version "3.11.0" - resolved "https://registry.yarnpkg.com/@react-stately/data/-/data-3.11.0.tgz#d744d868ee810126aef4a0a827ab394e3059d33a" - integrity sha512-0BlPT58WrAtUvpiEfUuyvIsGFTzp/9vA5y+pk53kGJhOdc5tqBGHi9cg40pYE/i1vdHJGMpyHGRD9nkQb8wN3Q== - dependencies: - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/datepicker@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-stately/datepicker/-/datepicker-3.9.0.tgz#0771c66df937806f812392f8a512a2e72bebbaf0" - integrity sha512-p6BuxPbDxjIgBZmskdv2dR6XIdPEftCjS7kYe/+iLZxfz1vYiDqpJVb3ascLyBjl84bDDyr4z2vWcKhdDwyhEA== - dependencies: - "@internationalized/date" "^3.5.0" - "@internationalized/string" "^3.1.1" - "@react-stately/form" "^3.0.0" - "@react-stately/overlays" "^3.6.4" - "@react-stately/utils" "^3.9.0" - "@react-types/datepicker" "^3.7.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/dnd@^3.2.6": - version "3.2.6" - resolved "https://registry.yarnpkg.com/@react-stately/dnd/-/dnd-3.2.6.tgz#683649dce4183890528d8bea08c30f2b11c812f0" - integrity sha512-ex3Pjn+9uIoqsBb9F4ZFJb3fB0YadN8uYBOEiBb9N4UXWyANibGUYJ2FvIbvq1nFDU7On7MW1J9e3vkGglX4FQ== - dependencies: - "@react-stately/selection" "^3.14.1" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/flags@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-stately/flags/-/flags-3.0.0.tgz#c5a73965f8c90e8bf5981adddb4bdbb0ba2f5690" - integrity sha512-e3i2ItHbIa0eEwmSXAnPdD7K8syW76JjGe8ENxwFJPW/H1Pu9RJfjkCb/Mq0WSPN/TpxBb54+I9TgrGhbCoZ9w== - dependencies: - "@swc/helpers" "^0.4.14" - - "@react-stately/form@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@react-stately/form/-/form-3.0.0.tgz#584af339a128045c357c1b8ca440c87460a41b0f" - integrity sha512-C8wkfFmtx1escizibhdka5JvTy9/Vp173CS9cakjvWTmnjYYC1nOlzwp7BsYWTgerCFbRY/BU/Cf/bJDxPiUKQ== - dependencies: - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/grid@^3.8.3": - version "3.8.3" - resolved "https://registry.yarnpkg.com/@react-stately/grid/-/grid-3.8.3.tgz#42420724084a023c74e50d9c82efd8074179680d" - integrity sha512-JceGSJcuO6Zv+Aq5s2NZvmbMjdPjTtGNQR9kTgXKC/pOfM6FJ58bJiOmEllyN6oawqh4Ey8Xdqk9NuW4l2ctuw== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/selection" "^3.14.1" - "@react-types/grid" "^3.2.3" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/list@^3.10.1": - version "3.10.1" - resolved "https://registry.yarnpkg.com/@react-stately/list/-/list-3.10.1.tgz#1d926d4aef5764096ec357da8081ef09081fe5cc" - integrity sha512-iVarLMd7FmMT0H20dRWsFOHHX5+c4gK51AXP2BSr1VtDSfbL4dgaGgu7IaAMVc/rO0au1e1tPM2hutiIFvPcnA== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/selection" "^3.14.1" - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/menu@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-stately/menu/-/menu-3.5.7.tgz#3232598399b4baebfc577d5f56b4bd5570f400c2" - integrity sha512-bzTmAqzcMNatvyruWlvOdZSmMhz3+mkdxtqaZzYHq+DpR6ka57lIRj8dBnZWQGwV3RypMZfz+X6aIX4kruGVbw== - dependencies: - "@react-stately/overlays" "^3.6.4" - "@react-types/menu" "^3.9.6" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/numberfield@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@react-stately/numberfield/-/numberfield-3.7.0.tgz#a0fd05da980dbe510d1d99ea7cf21ce4f9bac1bb" - integrity sha512-DOz4jL7T30KGUXpGh/z80aHf+DEOQfvCHVDfll+IU7p3sd+bbM5uj7JdwXpZgIYUK8KTf2N49sL6lq5uCoxh8w== - dependencies: - "@internationalized/number" "^3.4.0" - "@react-stately/form" "^3.0.0" - "@react-stately/utils" "^3.9.0" - "@react-types/numberfield" "^3.7.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/overlays@^3.6.4": - version "3.6.4" - resolved "https://registry.yarnpkg.com/@react-stately/overlays/-/overlays-3.6.4.tgz#1d0d974413fa3f13d97eec2cac5b48c49978d1a0" - integrity sha512-tHEaoAGpE9dSnsskqLPVKum59yGteoSqsniTopodM+miQozbpPlSjdiQnzGLroy5Afx5OZYClE616muNHUILXA== - dependencies: - "@react-stately/utils" "^3.9.0" - "@react-types/overlays" "^3.8.4" - "@swc/helpers" "^0.5.0" - - "@react-stately/radio@^3.10.0": - version "3.10.0" - resolved "https://registry.yarnpkg.com/@react-stately/radio/-/radio-3.10.0.tgz#01750b861bfdbb048c6e1bbfb6a97a4f42c29c25" - integrity sha512-d8IgZtUq/4vhE7YhyBVg1QdVoFS0caIcvPumXqtp/5vlDgpUsVy9jSeWtbk0H4FyUcmJlQhRcTylKB9THXY1YQ== - dependencies: - "@react-stately/form" "^3.0.0" - "@react-stately/utils" "^3.9.0" - "@react-types/radio" "^3.6.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/searchfield@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-stately/searchfield/-/searchfield-3.5.0.tgz#8493eefd684bc85117b42c7c714f6541afe54816" - integrity sha512-SStjChkn/33pEn40slKQPnBnmQYyxVazVwPjiBkdeVejC42lUVairUTrGJgF0PNoZTbxn0so2/XzjqTC9T8iCw== - dependencies: - "@react-stately/utils" "^3.9.0" - "@react-types/searchfield" "^3.5.2" - "@swc/helpers" "^0.5.0" - - "@react-stately/select@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-stately/select/-/select-3.6.0.tgz#e77464f3e0367d652866806c1ab61c132c31c49a" - integrity sha512-GvSE4DXmcvdRNUc+ciPU7gedt7LfRO8FFFIzhB/bCQhUlK6/xihUPrGXayzqxLeTQKttMH323LuYFKfwpJRhsA== - dependencies: - "@react-stately/form" "^3.0.0" - "@react-stately/list" "^3.10.1" - "@react-stately/menu" "^3.5.7" - "@react-types/select" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/selection@^3.14.1": - version "3.14.1" - resolved "https://registry.yarnpkg.com/@react-stately/selection/-/selection-3.14.1.tgz#798b4fbfda940778ae1dc1f2d2390cee97cce2c6" - integrity sha512-96/CerrB6yH4Ad9FkzBzyVerSPjcIj1NBTWTFHo1N+oHECvyGsDxZl7Y4LQR++teFK66FhX5KjCJQGae4IZd6A== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/slider@^3.4.5": - version "3.4.5" - resolved "https://registry.yarnpkg.com/@react-stately/slider/-/slider-3.4.5.tgz#46d4a7e0a1644894e91b12003fa1ba8e0787f4ca" - integrity sha512-lJPZC8seYbnZDqAlZm3/QC95I5iluG8ouwkPMmvtWCz1baayV/jJtfxA/74zR7Vcob9Fe7O57g8Edhz/hv9xOQ== - dependencies: - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@react-types/slider" "^3.7.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/table@^3.11.3": - version "3.11.3" - resolved "https://registry.yarnpkg.com/@react-stately/table/-/table-3.11.3.tgz#0d9e547fc2e30df174ac4ba3728402f62fb2fc0a" - integrity sha512-r0rzSKbtMG4tjFpCGtXb8p6hOuek03c6rheJE88z4I/ujZ5EmEO6Ps8q0JMNEDCY2qigvKM+ODisMBeZCEkIJg== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/flags" "^3.0.0" - "@react-stately/grid" "^3.8.3" - "@react-stately/selection" "^3.14.1" - "@react-stately/utils" "^3.9.0" - "@react-types/grid" "^3.2.3" - "@react-types/shared" "^3.22.0" - "@react-types/table" "^3.9.1" - "@swc/helpers" "^0.5.0" - - "@react-stately/tabs@^3.6.2": - version "3.6.2" - resolved "https://registry.yarnpkg.com/@react-stately/tabs/-/tabs-3.6.2.tgz#a9825d560af58c4f876e7b619c7e8cb29b071887" - integrity sha512-f+U4D1FAVfVVcNRbtKIv4GrO37CLFClYQlXx9zIuSXjHsviapVD2IQSyAmpKo/CbgXhYRMdGwENZdOsmF/Ns7g== - dependencies: - "@react-stately/list" "^3.10.1" - "@react-types/shared" "^3.22.0" - "@react-types/tabs" "^3.3.4" - "@swc/helpers" "^0.5.0" - - "@react-stately/toggle@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@react-stately/toggle/-/toggle-3.7.0.tgz#abe2f08f37a0f41e6513d4fde3d46f49500bb5cc" - integrity sha512-TRksHkCJk/Xogq4181g3CYgJf+EfsJCqX5UZDSw1Z1Kgpvonjmdf6FAfQfCh9QR2OuXUL6hOLUDVLte5OPI+5g== - dependencies: - "@react-stately/utils" "^3.9.0" - "@react-types/checkbox" "^3.6.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/tooltip@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@react-stately/tooltip/-/tooltip-3.4.6.tgz#e240184dedc35018f7b1e2d46eaca20a90d919bb" - integrity sha512-uL93bmsXf+OOgpKLPEKfpDH4z+MK2CuqlqVxx7rshN0vjWOSoezE5nzwgee90+RpDrLNNNWTNa7n+NkDRpI1jA== - dependencies: - "@react-stately/overlays" "^3.6.4" - "@react-types/tooltip" "^3.4.6" - "@swc/helpers" "^0.5.0" - - "@react-stately/tree@^3.7.4": - version "3.7.4" - resolved "https://registry.yarnpkg.com/@react-stately/tree/-/tree-3.7.4.tgz#57cc57863837092f13b7a3887e1b5c56330b5cac" - integrity sha512-0yvVODBS8WnSivLFX5ccEjCl2NA/8lbEt1E48wVcY1xcXgISNpw5MSGK5jC6YrtJPIqVolQIkNSbMreXGBktIg== - dependencies: - "@react-stately/collections" "^3.10.3" - "@react-stately/selection" "^3.14.1" - "@react-stately/utils" "^3.9.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-stately/utils@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-stately/utils/-/utils-3.9.0.tgz#9cb2c8eea5dd1b58256ecb436b963c01526bae37" - integrity sha512-yPKFY1F88HxuZ15BG2qwAYxtpE4HnIU0Ofi4CuBE0xC6I8mwo4OQjDzi+DZjxQngM9D6AeTTD6F1V8gkozA0Gw== - dependencies: - "@swc/helpers" "^0.5.0" - - "@react-stately/virtualizer@^3.6.5": - version "3.6.5" - resolved "https://registry.yarnpkg.com/@react-stately/virtualizer/-/virtualizer-3.6.5.tgz#45891ac24b6aed0aa168e26c61a39d235d204a70" - integrity sha512-v0cZeNCGPMeo3LP4UrGuDo3Xpq7ufNaZyGObgSvdrIW49qK5F02kczcKy6NKg+QfOgC/+Nc9Tof/2S8dcxDrCA== - dependencies: - "@react-aria/utils" "^3.22.0" - "@react-types/shared" "^3.22.0" - "@swc/helpers" "^0.5.0" - - "@react-types/breadcrumbs@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@react-types/breadcrumbs/-/breadcrumbs-3.7.2.tgz#3dc0c8ccebf75844efc56ac8e53dc072df083d5f" - integrity sha512-esl6RucDW2CNMsApJxNYfMtDaUcfLlwKMPH/loYsOBbKxGl2HsgVLMcdpjEkTRs2HCTNCbBXWpeU8AY77t+bsw== - dependencies: - "@react-types/link" "^3.5.2" - "@react-types/shared" "^3.22.0" - - "@react-types/button@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-types/button/-/button-3.9.1.tgz#eb54745133bdaad345d8d589021b67ef2882e1c5" - integrity sha512-bf9iTar3PtqnyV9rA+wyFyrskZKhwmOuOd/ifYIjPs56YNVXWH5Wfqj6Dx3xdFBgtKx8mEVQxVhoX+WkHX+rtw== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/calendar@^3.4.2": - version "3.4.2" - resolved "https://registry.yarnpkg.com/@react-types/calendar/-/calendar-3.4.2.tgz#a184851c2c891e8baa06e3d11173bb4bf101a48b" - integrity sha512-tCZ21un/8OAhpNtmSXDkOVvS5Pzp+y/JwNr6VGFi8HBC5F/c8SzuwV0jKN8ymsZSWbDQ68xXGNWxFaG43Bw8Pg== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/shared" "^3.22.0" - - "@react-types/checkbox@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-types/checkbox/-/checkbox-3.6.0.tgz#ba702be25555c1520f78be39c8260354638792b6" - integrity sha512-vgbuJzQpVCNT5AZWV0OozXCnihqrXxoZKfJFIw0xro47pT2sn3t5UC4RA9wfjDGMoK4frw1K/4HQLsQIOsPBkw== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/combobox@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/combobox/-/combobox-3.9.0.tgz#f671da0357cfe3a06a24a239fcfacc5b3e5125d0" - integrity sha512-VAQWM2jrIWROgcTKxj4k37WWpK/1zRjj1HfGeuenAQyOQwImqDwCHx5YxQR1GiUEFne4v1yXe2khT0T5Kt2vDg== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/datepicker@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@react-types/datepicker/-/datepicker-3.7.0.tgz#f44632994a0cdd20f350b40910f61a7c89091810" - integrity sha512-Uh+p6pZpMFc5ZBOns5TXCBbUvJp1KVROLBn2gk5dMEFVq78Qs1VFuAt4lwr9gQBOJrX5I/l65pRTwwWwAKxYtQ== - dependencies: - "@internationalized/date" "^3.5.0" - "@react-types/calendar" "^3.4.2" - "@react-types/overlays" "^3.8.4" - "@react-types/shared" "^3.22.0" - - "@react-types/dialog@^3.5.7": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@react-types/dialog/-/dialog-3.5.7.tgz#3fd93875ff317d6014e814b6e1a2abb87272a1ef" - integrity sha512-geYoqAyQaTLG43AaXdMUVqZXYgkSifrD9cF7lR2kPAT0uGFv0YREi6ieU+aui8XJ83EW0xcxP+EPWd2YkN4D4w== - dependencies: - "@react-types/overlays" "^3.8.4" - "@react-types/shared" "^3.22.0" - - "@react-types/grid@^3.2.3": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@react-types/grid/-/grid-3.2.3.tgz#20b19b73315343630145ff9e43138e7f2855d946" - integrity sha512-GQM4RDmYhstcYZ0Odjq+xUwh1fhLmRebG6qMM8OXHTPQ77nhl3wc1UTGRhZm6mzEionplSRx4GCpEMEHMJIU0w== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/link@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/link/-/link-3.5.2.tgz#b363abca3365adc64b49c47163ce00235c01c667" - integrity sha512-/s51/WejmpLiyxOgP89s4txgxYoGaPe8pVDItVo1h4+BhU1Puyvgv/Jx8t9dPvo6LUXbraaN+SgKk/QDxaiirw== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/listbox@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@react-types/listbox/-/listbox-3.4.6.tgz#da0887dbb89a868d53b87486111bf0a51042da7b" - integrity sha512-XOQvrTqNh5WIPDvKiWiep8T07RAsMfjAXTjDbnjxVlKACUXkcwpts9kFaLnJ9LJRFt6DwItfP+WMkzvmx63/NQ== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/menu@^3.9.6": - version "3.9.6" - resolved "https://registry.yarnpkg.com/@react-types/menu/-/menu-3.9.6.tgz#1b36842cbdb4590dfff78437316aec4a3f47b1f6" - integrity sha512-w/RbFInOf4nNayQDv5c2L8IMJbcFOkBhsT3xvvpTy+CHvJcQdjggwaV1sRiw7eF/PwB81k2CwigmidUzHJhKDg== - dependencies: - "@react-types/overlays" "^3.8.4" - "@react-types/shared" "^3.22.0" - - "@react-types/meter@^3.3.6": - version "3.3.6" - resolved "https://registry.yarnpkg.com/@react-types/meter/-/meter-3.3.6.tgz#ae5960b27012f52ca33970f2ff416af71dad274d" - integrity sha512-1XYp1fA9UU0lO6kjf3TwVE8mppOJa64mBKAcLWtTyq1e/cYIAbx5o6CsuUx0YDpXKF6gdtvIWvfmxeWsmqJ1jQ== - dependencies: - "@react-types/progress" "^3.5.1" - - "@react-types/numberfield@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@react-types/numberfield/-/numberfield-3.7.0.tgz#a029bf2a8a07049c96ea5ffe1f7533ab2305bcf4" - integrity sha512-gaGi+vqm1Y8LCWRsWYUjcGftPIzl+8W2VOfkgKMLM8y76nnwTPtmAqs+Ap1cg7sEJSfsiKMq93e9yvP3udrC2w== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/overlays@^3.8.4": - version "3.8.4" - resolved "https://registry.yarnpkg.com/@react-types/overlays/-/overlays-3.8.4.tgz#a538f6f2fb9826f1da78d3b4f0f6326a709ce37d" - integrity sha512-pfgNlQnbF6RB/R2oSxyqAP3Uzz0xE/k5q4n5gUeCDNLjY5qxFHGE8xniZZ503nZYw6VBa9XMN1efDOKQyeiO0w== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/progress@^3.5.1": - version "3.5.1" - resolved "https://registry.yarnpkg.com/@react-types/progress/-/progress-3.5.1.tgz#b988cd2d2ff194c7652d74f714b230f26ab73c6c" - integrity sha512-CqsUjczUK/SfuFzDcajBBaXRTW0D3G9S/yqLDj9e8E0ii+lGDLt1PHj24t1J7E88U2rVYqmM9VL4NHTt8o3IYA== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/radio@^3.6.0": - version "3.6.0" - resolved "https://registry.yarnpkg.com/@react-types/radio/-/radio-3.6.0.tgz#519e4aa40dbb2a13852a5a6f36299a84639376a5" - integrity sha512-VOZzegxxZS55gHRVyWu278Q4y/rEQGiAVQCUqi25GmpbMe4MlHrzg16c76RiZMUK9PPoyv+XNUgAaPmxebkn7g== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/searchfield@^3.5.2": - version "3.5.2" - resolved "https://registry.yarnpkg.com/@react-types/searchfield/-/searchfield-3.5.2.tgz#e663899f42344243ea7b4cd6f0ab0bfe6020151e" - integrity sha512-JAK2/Kg4Dr393FYfbRw0TlXKnJPX77sq1x/ZBxtO6p64+MuuIYKqw0i9PwDlo1PViw2QI5u8GFhKA2TgemY9uA== - dependencies: - "@react-types/shared" "^3.22.0" - "@react-types/textfield" "^3.9.0" - - "@react-types/select@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/select/-/select-3.9.0.tgz#ddc1238194776ef161260547d25038409885ced8" - integrity sha512-0nalGmcoma4jreICLSJae/uKAuMiVyWgqWjGrGiUGGcdDchH4limKVEqNDaBwLvxVT6NB5LLsaipCTCAEEl4Rg== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/shared@^3.22.0": - version "3.22.0" - resolved "https://registry.yarnpkg.com/@react-types/shared/-/shared-3.22.0.tgz#70f85aad46cd225f7fcb29f1c2b5213163605074" - integrity sha512-yVOekZWbtSmmiThGEIARbBpnmUIuePFlLyctjvCbgJgGhz8JnEJOipLQ/a4anaWfzAgzSceQP8j/K+VOOePleA== - - "@react-types/slider@^3.7.0": - version "3.7.0" - resolved "https://registry.yarnpkg.com/@react-types/slider/-/slider-3.7.0.tgz#d9e4dbe1b2109c7accfcc0e2e330ff10cd3a837c" - integrity sha512-uyQXUVFfqc9SPUW0LZLMan2n232F/OflRafiHXz9viLFa9tVOupVa7GhASRAoHojwkjoJ1LjFlPih7g5dOZ0/Q== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/switch@^3.5.0": - version "3.5.0" - resolved "https://registry.yarnpkg.com/@react-types/switch/-/switch-3.5.0.tgz#8ebf07c60aef22b181eb4ab884cf3d2abddd66c6" - integrity sha512-/wNmUGjk69bP6t5k2QkAdrNN5Eb9Rz4dOyp0pCPmoeE+5haW6sV5NmtkvWX1NSc4DQz1xL/a5b+A0vxPCP22Jw== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/table@^3.9.1": - version "3.9.1" - resolved "https://registry.yarnpkg.com/@react-types/table/-/table-3.9.1.tgz#5d1304d412bc7e637e832e86fcb8724e61c20735" - integrity sha512-3e+Oouw9jGqNDg+JRg7v7fgPqDZd6DtST9S/UPp81f32ntnQ8Wsu7S/J4eyLHu5CVQDqcHkf4xPeeXBgPx4qmw== - dependencies: - "@react-types/grid" "^3.2.3" - "@react-types/shared" "^3.22.0" - - "@react-types/tabs@^3.3.4": - version "3.3.4" - resolved "https://registry.yarnpkg.com/@react-types/tabs/-/tabs-3.3.4.tgz#43fa93a4a67dcc53031afc56a8ad3bf5f44473a8" - integrity sha512-4mCTtFrwMRypyGTZCvNYVT9CkknexO/UYvqwDm2jMYb8JgjRvxnomu776Yh7uyiYKWyql2upm20jqasEOm620w== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/textfield@^3.9.0": - version "3.9.0" - resolved "https://registry.yarnpkg.com/@react-types/textfield/-/textfield-3.9.0.tgz#ad29f0a70421f9d2cd6cf2795df10a7712954e69" - integrity sha512-D/DiwzsfkwlAg3uv8hoIfwju+zhB/hWDEdTvxQbPkntDr0kmN/QfI17NMSzbOBCInC4ABX87ViXLGxr940ykGA== - dependencies: - "@react-types/shared" "^3.22.0" - - "@react-types/tooltip@^3.4.6": - version "3.4.6" - resolved "https://registry.yarnpkg.com/@react-types/tooltip/-/tooltip-3.4.6.tgz#1f1eb22873a5d5ad355e0de1be46f48759b55f6f" - integrity sha512-RaZewdER7ZcsNL99RhVHs8kSLyzIBkwc0W6eFZrxST2MD9J5GzkVWRhIiqtFOd5U1aYnxdJ6woq72Ef+le6Vfw== - dependencies: - "@react-types/overlays" "^3.8.4" - "@react-types/shared" "^3.22.0" - - "@remix-run/router@1.13.0": - version "1.13.0" - resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.13.0.tgz#7e29c4ee85176d9c08cb0f4456bff74d092c5065" - integrity sha512-5dMOnVnefRsl4uRnAdoWjtVTdh8e6aZqgM4puy9nmEADH72ck+uXwzpJLEKE9Q6F8ZljNewLgmTfkxUrBdv4WA== - - "@rollup/plugin-commonjs@^24.0.1": - version "24.1.0" - resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-24.1.0.tgz#79e54bd83bb64396761431eee6c44152ef322100" - integrity sha512-eSL45hjhCWI0jCCXcNtLVqM5N1JlBGvlFfY0m6oOYnLCJ6N0qEXoZql4sY2MOUArzhH4SA/qBpTxvvZp2Sc+DQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - commondir "^1.0.1" - estree-walker "^2.0.2" - glob "^8.0.3" - is-reference "1.2.1" - magic-string "^0.27.0" - - "@rollup/plugin-json@^6.0.0": - version "6.0.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.0.1.tgz#7e2efcf5ed549963f1444e010611d22f463931c0" - integrity sha512-RgVfl5hWMkxN1h/uZj8FVESvPuBJ/uf6ly6GTj0GONnkfoBN5KC0MSz+PN2OLDgYXMhtG0mWpTrkiOjoxAIevw== - dependencies: - "@rollup/pluginutils" "^5.0.1" - - "@rollup/plugin-node-resolve@^15.0.1": - version "15.2.3" - resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.2.3.tgz#e5e0b059bd85ca57489492f295ce88c2d4b0daf9" - integrity sha512-j/lym8nf5E21LwBT4Df1VD6hRO2L2iwUeUmP7litikRsVp1H6NWx20NEp0Y7su+7XGc476GnXXc4kFeZNGmaSQ== - dependencies: - "@rollup/pluginutils" "^5.0.1" - "@types/resolve" "1.20.2" - deepmerge "^4.2.2" - is-builtin-module "^3.2.1" - is-module "^1.0.0" - resolve "^1.22.1" - - "@rollup/plugin-typescript@^11.0.0": - version "11.1.5" - resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-11.1.5.tgz#039c763bf943a5921f3f42be255895e75764cb91" - integrity sha512-rnMHrGBB0IUEv69Q8/JGRD/n4/n6b3nfpufUu26axhUcboUzv/twfZU8fIBbTOphRAe0v8EyxzeDpKXqGHfyDA== - dependencies: - "@rollup/pluginutils" "^5.0.1" - resolve "^1.22.1" - - "@rollup/pluginutils@^5.0.1": - version "5.1.0" - resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" - integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^2.0.2" - picomatch "^2.3.1" - - "@sapphire/utilities@^3.11.0": - version "3.13.0" - resolved "https://registry.yarnpkg.com/@sapphire/utilities/-/utilities-3.13.0.tgz#04fd73281ad4cd63c2c87ffbac3faa393d77cf95" - integrity sha512-BD5ycPjZX5dXxrAb90dJTY8ukpPVBXgU17gA5ghK2memS4hwAzFYpvK+R+6zh4d6HYIKVuqrVhGXjvZenAa/Aw== - - "@sentry-internal/tracing@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.84.0.tgz#430da253ee5b075be4ef57f20ea842c0208bc6b0" - integrity sha512-y9bGYA0OM6PEREfd+nk4UURZy29tpIw+7vQwpxWfEVs2fqq0/5TBFX/tKFb8AKUI9lVM8v0bcF0bNSCnuPQZHQ== - dependencies: - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - - "@sentry/browser@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.84.0.tgz#7c82470f0afbb6178f26127894e40e9ce2b1e6d6" - integrity sha512-X50TlTKY9WzAnHsYc4FYrCWgm+CdVo0h02ggmodVBUpRLUBjj+cs5Q1plov/v/XeorSwmorNEMUu/n+XZNSsrA== - dependencies: - "@sentry-internal/tracing" "7.84.0" - "@sentry/core" "7.84.0" - "@sentry/replay" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - - "@sentry/core@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.84.0.tgz#01d33fc452044ffd8ea57b20f60304b9cfa2b9e1" - integrity sha512-tbuwunbBx2kSex15IHCqHDnrMfIlqPc6w/76fwkGqokz3oh9GSEGlLICwmBWL8AypWimUg13IDtFpD0TJTriWA== - dependencies: - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - - "@sentry/integrations@^7.54.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.84.0.tgz#3b016903e08f0dade74bbc152ea5605e231e39cd" - integrity sha512-aUu95BhnHSf/W/F4BvsFnf4x+piHiah5a180YTMqWcHMkJr7MnCWNIad9RJuHlcINSfyHtUr5+Z4Bajzqg60lw== - dependencies: - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - localforage "^1.8.1" - - "@sentry/react@^7.54.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/react/-/react-7.84.0.tgz#2cb3192f7fb67b7696e8ece08d67229b193ddaa4" - integrity sha512-VQZrEHwPKCYTSbRYXD2ohXcQg99G1Hgs8eevRUuRpdChmA2e3z/RvT00NlaSNNZrS86wPyKpAK6kickB/eSYrw== - dependencies: - "@sentry/browser" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - hoist-non-react-statics "^3.3.2" - - "@sentry/replay@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.84.0.tgz#7e17876d9a1802ee33800e2b2cbda4e026c0a2af" - integrity sha512-c4PxT0ZpvkR9zXNfmAk3ojkm6eZ9+NlDze09RFBOCNo69QwIN90hnvbjXFC1+vRIJsfgo78Zr0ya/Wzb3Rog7Q== - dependencies: - "@sentry-internal/tracing" "7.84.0" - "@sentry/core" "7.84.0" - "@sentry/types" "7.84.0" - "@sentry/utils" "7.84.0" - - "@sentry/types@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.84.0.tgz#e8db86c36c61659c3b2558f0aa8b6a073a756117" - integrity sha512-VqGLIF3JOUrk7yIXjLXJvAORkZL1e3dDX0Q1okRehwyt/5CRE+mdUTeJZkBo9P9mBwgMyvtwklzOGGrzjb4eMA== - - "@sentry/utils@7.84.0": - version "7.84.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.84.0.tgz#32861d922fa31e86dd2863a1d9dfc5a369e98952" - integrity sha512-qdUVuxnRBvaf05AU+28R+xYtZmi/Ymf8os3Njq9g4XuA+QEkZLbzmIpRK5W9Ja7vUtjOeg29Xgg43A8znde9LQ== - dependencies: - "@sentry/types" "7.84.0" - - "@sideway/address@^4.1.3": - version "4.1.4" - resolved "https://registry.yarnpkg.com/@sideway/address/-/address-4.1.4.tgz#03dccebc6ea47fdc226f7d3d1ad512955d4783f0" - integrity sha512-7vwq+rOHVWjyXxVlR76Agnvhy8I9rpzjosTESvmhNeXOXdZZB15Fl+TI9x1SiHZH5Jv2wTGduSxFDIaq0m3DUw== - dependencies: - "@hapi/hoek" "^9.0.0" - - "@sideway/formula@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@sideway/formula/-/formula-3.0.1.tgz#80fcbcbaf7ce031e0ef2dd29b1bfc7c3f583611f" - integrity sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg== - - "@sideway/pinpoint@^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@sideway/pinpoint/-/pinpoint-2.0.0.tgz#cff8ffadc372ad29fd3f78277aeb29e632cc70df" - integrity sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ== - - "@sigstore/bundle@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@sigstore/bundle/-/bundle-1.1.0.tgz#17f8d813b09348b16eeed66a8cf1c3d6bd3d04f1" - integrity sha512-PFutXEy0SmQxYI4texPw3dd2KewuNqv7OuK1ZFtY2fM754yhvG2KdgwIhRnoEE2uHdtdGNQ8s0lb94dW9sELog== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - - "@sigstore/protobuf-specs@^0.2.0": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@sigstore/protobuf-specs/-/protobuf-specs-0.2.1.tgz#be9ef4f3c38052c43bd399d3f792c97ff9e2277b" - integrity sha512-XTWVxnWJu+c1oCshMLwnKvz8ZQJJDVOlciMfgpJBQbThVjKTCG8dwyhgLngBD2KN0ap9F/gOV8rFDEx8uh7R2A== - - "@sigstore/sign@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@sigstore/sign/-/sign-1.0.0.tgz#6b08ebc2f6c92aa5acb07a49784cb6738796f7b4" - integrity sha512-INxFVNQteLtcfGmcoldzV6Je0sbbfh9I16DM4yJPw3j5+TFP8X6uIiA18mvpEa9yyeycAKgPmOA3X9hVdVTPUA== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - make-fetch-happen "^11.0.1" - - "@sigstore/tuf@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@sigstore/tuf/-/tuf-1.0.3.tgz#2a65986772ede996485728f027b0514c0b70b160" - integrity sha512-2bRovzs0nJZFlCN3rXirE4gwxCn97JNjMmwpecqlbgV9WcxX7WRuIrgzx/X7Ib7MYRbyUTpBYE0s2x6AmZXnlg== - dependencies: - "@sigstore/protobuf-specs" "^0.2.0" - tuf-js "^1.1.7" - - "@sinclair/typebox@^0.24.1": - version "0.24.51" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.24.51.tgz#645f33fe4e02defe26f2f5c0410e1c094eac7f5f" - integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== - - "@sinclair/typebox@^0.27.8": - version "0.27.8" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.27.8.tgz#6667fac16c436b5434a387a34dedb013198f6e6e" - integrity sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA== - - "@sinonjs/commons@^1.7.0": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@sinonjs/commons/-/commons-1.8.6.tgz#80c516a4dc264c2a69115e7578d62581ff455ed9" - integrity sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ== - dependencies: - type-detect "4.0.8" - - "@sinonjs/fake-timers@^8.0.1": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz#3fdc2b6cb58935b21bfb8d1625eb1300484316e7" - integrity sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg== - dependencies: - "@sinonjs/commons" "^1.7.0" - - "@stablelib/aead@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" - integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== - - "@stablelib/binary@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" - integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== - dependencies: - "@stablelib/int" "^1.0.1" - - "@stablelib/bytes@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" - integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== - - "@stablelib/chacha20poly1305@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" - integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== - dependencies: - "@stablelib/aead" "^1.0.1" - "@stablelib/binary" "^1.0.1" - "@stablelib/chacha" "^1.0.1" - "@stablelib/constant-time" "^1.0.1" - "@stablelib/poly1305" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/chacha@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" - integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/constant-time@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" - integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== - - "@stablelib/ed25519@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" - integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== - dependencies: - "@stablelib/random" "^1.0.2" - "@stablelib/sha512" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/hash@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" - integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== - - "@stablelib/hkdf@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" - integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== - dependencies: - "@stablelib/hash" "^1.0.1" - "@stablelib/hmac" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/hmac@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" - integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== - dependencies: - "@stablelib/constant-time" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/int@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" - integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== - - "@stablelib/keyagreement@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" - integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== - dependencies: - "@stablelib/bytes" "^1.0.1" - - "@stablelib/poly1305@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" - integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== - dependencies: - "@stablelib/constant-time" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" - integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/sha256@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" - integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/sha512@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" - integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - - "@stablelib/wipe@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" - integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== - - "@stablelib/x25519@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" - integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== - dependencies: - "@stablelib/keyagreement" "^1.0.1" - "@stablelib/random" "^1.0.2" - "@stablelib/wipe" "^1.0.1" - - "@storybook/addon-actions@6.5.16", "@storybook/addon-actions@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" - integrity sha512-aADjilFmuD6TNGz2CRPSupnyiA/IGkPJHDBTqMpsDXTUr8xnuD122xkIhg6UxmCM2y1c+ncwYXy3WPK2xXK57g== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - polished "^4.2.2" - prop-types "^15.7.2" - react-inspector "^5.1.0" - regenerator-runtime "^0.13.7" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - uuid-browser "^3.1.0" - - "@storybook/addon-backgrounds@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.5.16.tgz#a93ea53955f714b4a4432dda1b88942cc87dd390" - integrity sha512-t7qooZ892BruhilFmzYPbysFwpULt/q4zYXNSmKVbAYta8UVvitjcU4F18p8FpWd9WvhiTr0SDlyhNZuzvDfug== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/addon-controls@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.5.16.tgz#5017805b8ca413edf6e9d87b90a9436e79eb5e59" - integrity sha512-kShSGjq1MjmmyL3l8i+uPz6yddtf82mzys0l82VKtcuyjrr5944wYFJ5NTXMfZxrO/U6FeFsfuFZE/k6ex3EMg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/node-logger" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - lodash "^4.17.21" - ts-dedent "^2.0.0" - - "@storybook/addon-docs@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.5.16.tgz#3de912f51fb8e48b9a53b11a5b1cede067acbe70" - integrity sha512-QM9WDZG9P02UvbzLu947a8ZngOrQeAKAT8jCibQFM/+RJ39xBlfm8rm+cQy3dm94wgtjmVkA3mKGOV/yrrsddg== - dependencies: - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@jest/transform" "^26.6.2" - "@mdx-js/react" "^1.6.22" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/mdx1-csf" "^0.0.1" - "@storybook/node-logger" "6.5.16" - "@storybook/postinstall" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/source-loader" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - babel-loader "^8.0.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - regenerator-runtime "^0.13.7" - remark-external-links "^8.0.0" - remark-slug "^6.0.0" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/addon-essentials@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.5.16.tgz#815991366a4a90b60bf0aa4022eb0bb0c2bb536d" - integrity sha512-TeoMr6tEit4Pe91GH6f8g/oar1P4M0JL9S6oMcFxxrhhtOGO7XkWD5EnfyCx272Ok2VYfE58FNBTGPNBVIqYKQ== - dependencies: - "@storybook/addon-actions" "6.5.16" - "@storybook/addon-backgrounds" "6.5.16" - "@storybook/addon-controls" "6.5.16" - "@storybook/addon-docs" "6.5.16" - "@storybook/addon-measure" "6.5.16" - "@storybook/addon-outline" "6.5.16" - "@storybook/addon-toolbars" "6.5.16" - "@storybook/addon-viewport" "6.5.16" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - - "@storybook/addon-interactions@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-6.5.16.tgz#2855fe946c9d8595c3486ae696f1d99e7fca582b" - integrity sha512-DdTtyp3DgB/SpbM1GQgMnuSEBCkadxmj1mUcPk+Wp2iY+fDwsuoRDkr1H9Oe7IvlBKe7ciR79LEjoaABXNdw4w== - dependencies: - "@devtools-ds/object-inspector" "^1.1.2" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/instrumenter" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - jest-mock "^27.0.6" - polished "^4.2.2" - ts-dedent "^2.2.0" - - "@storybook/addon-links@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-6.5.16.tgz#cacb20cd0656f0681a874709d428d3f3577828c3" - integrity sha512-P/mmqK57NGXnR0i3d/T5B0rIt0Lg8Yq+qionRr3LK3AwG/4yGnYt4GNomLEknn/eEwABYq1Q/Z1aOpgIhNdq5A== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@types/qs" "^6.9.5" - core-js "^3.8.2" - global "^4.4.0" - prop-types "^15.7.2" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - - "@storybook/addon-measure@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-6.5.16.tgz#7f7bfdc0b624fbf18386b20a5e460027bf87115c" - integrity sha512-DMwnXkmM2L6POTh4KaOWvOAtQ2p9Tr1UUNxz6VXiN5cKFohpCs6x0txdLU5WN8eWIq0VFsO7u5ZX34CGCc6gCg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" - - "@storybook/addon-outline@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-6.5.16.tgz#6985b6a0b0122db36561c81dde2aa851604657b7" - integrity sha512-0du96nha4qltexO0Xq1xB7LeRSbqjC9XqtZLflXG7/X3ABoPD2cXgOV97eeaXUodIyb2qYBbHUfftBeA75x0+w== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - - "@storybook/addon-toolbars@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.5.16.tgz#9de04f9cc64b68d6cb680aa1c4fbf874e11afa32" - integrity sha512-y3PuUKiwOWrAvqx1YdUvArg0UaAwmboXFeR2bkrowk1xcT+xnRO3rML4npFeUl26OQ1FzwxX/cw6nknREBBLEA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - regenerator-runtime "^0.13.7" - - "@storybook/addon-viewport@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.5.16.tgz#226aa0ab93df68264269eb31adb104e7e48f6c68" - integrity sha512-1Vyqf1U6Qng6TXlf4SdqUKyizlw1Wn6+qW8YeA2q1lbkJqn3UlnHXIp8Q0t/5q1dK5BFtREox3+jkGwbJrzkmA== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - memoizerific "^1.11.3" - prop-types "^15.7.2" - regenerator-runtime "^0.13.7" - - "@storybook/addons@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.16.tgz#07e8f2205f86fa4c9dada719e3e096cb468e3cdd" - integrity sha512-p3DqQi+8QRL5k7jXhXmJZLsE/GqHqyY6PcoA1oNTJr0try48uhTGUOYkgzmqtDaa/qPFO5LP+xCPzZXckGtquQ== - dependencies: - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/theming" "6.5.16" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - global "^4.4.0" - regenerator-runtime "^0.13.7" - - "@storybook/api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.16.tgz#897915b76de05587fd702951d5d836f708043662" - integrity sha512-HOsuT8iomqeTMQJrRx5U8nsC7lJTwRr1DhdD0SzlqL4c80S/7uuCy4IZvOt4sYQjOzW5fOo/kamcoBXyLproTA== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/builder-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.16.tgz#ac468d244835a7f3bd01936398fee47244da35c1" - integrity sha512-YqDIrVNsUo8r9xc6AxsYDLxVYtMgl5Bxk+8/h1adsOko+jAFhdg6hOcAVxEmoSI0TMASOOVMFlT2hr23ppN2rQ== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - autoprefixer "^9.8.6" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - core-js "^3.8.2" - css-loader "^3.6.0" - file-loader "^6.2.0" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^4.1.6" - glob "^7.1.6" - glob-promise "^3.4.0" - global "^4.4.0" - html-webpack-plugin "^4.0.0" - pnp-webpack-plugin "1.6.4" - postcss "^7.0.36" - postcss-flexbugs-fixes "^4.2.1" - postcss-loader "^4.2.0" - raw-loader "^4.0.2" - stable "^0.1.8" - style-loader "^1.3.0" - terser-webpack-plugin "^4.2.3" - ts-dedent "^2.0.0" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-filter-warnings-plugin "^1.2.1" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.2.2" - - "@storybook/builder-webpack5@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-6.5.16.tgz#2f260e29fbc87f6f3bb3212459048ce37f3fb54e" - integrity sha512-kh8Sofm1sbijaHDWtm0sXabqACHVFjikU/fIkkW786kpjoPIPIec1a+hrLgDsZxMU3I7XapSOaCFzWt6FjVXjg== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/preview-web" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/theming" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - babel-loader "^8.0.0" - babel-plugin-named-exports-order "^0.0.2" - browser-assert "^1.2.1" - case-sensitive-paths-webpack-plugin "^2.3.0" - core-js "^3.8.2" - css-loader "^5.0.1" - fork-ts-checker-webpack-plugin "^6.0.4" - glob "^7.1.6" - glob-promise "^3.4.0" - html-webpack-plugin "^5.0.0" - path-browserify "^1.0.1" - process "^0.11.10" - stable "^0.1.8" - style-loader "^2.0.0" - terser-webpack-plugin "^5.0.3" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "^5.9.0" - webpack-dev-middleware "^4.1.0" - webpack-hot-middleware "^2.25.1" - webpack-virtual-modules "^0.4.1" - - "@storybook/channel-postmessage@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.16.tgz#06167c0a66c06b2b5f8ff01d1dd436fff8119a15" - integrity sha512-fZZSN29dsUArWOx7e7lTdMA9+7zijVwCwbvi2Fo4fqhRLh1DsTb/VXfz1FKMCWAjNlcX7QQvV25tnxbqsD6lyw== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - qs "^6.10.0" - telejson "^6.0.8" - - "@storybook/channel-websocket@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.16.tgz#41f69ca9444a4dfbf72580b4696900c5b1d2b817" - integrity sha512-wJg2lpBjmRC2GJFzmhB9kxlh109VE58r/0WhFtLbwKvPqsvGf82xkBEl6BtBCvIQ4stzYnj/XijjA8qSi2zpOg== - dependencies: - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - telejson "^6.0.8" - - "@storybook/channels@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.16.tgz#3fb9a3b5666ecb951a2d0cf8b0699b084ef2d3c6" - integrity sha512-VylzaWQZaMozEwZPJdyJoz+0jpDa8GRyaqu9TGG6QGv+KU5POoZaGLDkRE7TzWkyyP0KQLo80K99MssZCpgSeg== - dependencies: - core-js "^3.8.2" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/channels@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-7.6.2.tgz#77bb8ea5bda33fc00fea30954c15f2bdc4f74a5d" - integrity sha512-pSVpnMAfMsImPyAorYPcfkZmBY34+eHmcj8Zab0m/36/M0AQrUq7VSxA+7KD3rhoZaJjioeouxqigjiznNAbZw== - dependencies: - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" - "@storybook/global" "^5.0.0" - qs "^6.10.0" - telejson "^7.2.0" - tiny-invariant "^1.3.1" - - "@storybook/client-api@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.16.tgz#13e5a7c3d1f0f951ec4ef51cfcf2c5aafb560e12" - integrity sha512-i3UwkzzUFw8I+E6fOcgB5sc4oU2fhvaKnqC1mpd9IYGJ9JN9MnGIaVl3Ko28DtFItu/QabC9JsLIJVripFLktQ== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - "@types/qs" "^6.9.5" - "@types/webpack-env" "^1.16.0" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - store2 "^2.12.0" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/client-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.16.tgz#955cc46b389e7151c9eb1585a75e6a0605af61a1" - integrity sha512-pxcNaCj3ItDdicPTXTtmYJE3YC1SjxFrBmHcyrN+nffeNyiMuViJdOOZzzzucTUG0wcOOX8jaSyak+nnHg5H1Q== - dependencies: - core-js "^3.8.2" - global "^4.4.0" - - "@storybook/client-logger@7.6.2", "@storybook/client-logger@^6.4.0 || >=6.5.0-0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-7.6.2.tgz#4362d53e24464945fc711dcf0dcfb9b4b1c53586" - integrity sha512-9hlDm7q6jZPVBoqW8V7DTMNMsjMaL2t45h+I8veQhnC2ZW6g+lARXQQDHZpL6MKVkJn6mEA9F0nJBIknbQpqBQ== - dependencies: - "@storybook/global" "^5.0.0" - - "@storybook/components@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.16.tgz#f8dc51213bc08fe32154be964e1e8b0e2f670ed6" - integrity sha512-LzBOFJKITLtDcbW9jXl0/PaG+4xAz25PK8JxPZpIALbmOpYWOAPcO6V9C2heX6e6NgWFMUxjplkULEk9RCQMNA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - util-deprecate "^1.0.2" - - "@storybook/core-client@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.16.tgz#ed2328fd38c6111fe887f6a91b28d9dc2b17092a" - integrity sha512-14IRaDrVtKrQ+gNWC0wPwkCNfkZOKghYV/swCUnQX3rP99defsZK8Hc7xHIYoAiOP5+sc3sweRAxgmFiJeQ1Ig== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/channel-websocket" "6.5.16" - "@storybook/client-api" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/preview-web" "6.5.16" - "@storybook/store" "6.5.16" - "@storybook/ui" "6.5.16" - airbnb-js-shims "^2.2.1" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" - lodash "^4.17.21" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - unfetch "^4.2.0" - util-deprecate "^1.0.2" - - "@storybook/core-common@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.16.tgz#db80aa6f220a576a83db821f720e103190a914ae" - integrity sha512-2qtnKP3TTOzt2cp6LXKRTh7XrI9z5VanMnMTgeoFcA5ebnndD4V6BExQUdYPClE/QooLx6blUWNgS9dFEpjSqQ== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-decorators" "^7.12.12" - "@babel/plugin-proposal-export-default-from" "^7.12.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" - "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.7" - "@babel/plugin-proposal-private-methods" "^7.12.1" - "@babel/plugin-proposal-private-property-in-object" "^7.12.1" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.12" - "@babel/plugin-transform-classes" "^7.12.1" - "@babel/plugin-transform-destructuring" "^7.12.1" - "@babel/plugin-transform-for-of" "^7.12.1" - "@babel/plugin-transform-parameters" "^7.12.1" - "@babel/plugin-transform-shorthand-properties" "^7.12.1" - "@babel/plugin-transform-spread" "^7.12.1" - "@babel/preset-env" "^7.12.11" - "@babel/preset-react" "^7.12.10" - "@babel/preset-typescript" "^7.12.7" - "@babel/register" "^7.12.1" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/pretty-hrtime" "^1.0.0" - babel-loader "^8.0.0" - babel-plugin-macros "^3.0.1" - babel-plugin-polyfill-corejs3 "^0.1.0" - chalk "^4.1.0" - core-js "^3.8.2" - express "^4.17.1" - file-system-cache "^1.0.5" - find-up "^5.0.0" - fork-ts-checker-webpack-plugin "^6.0.4" - fs-extra "^9.0.1" - glob "^7.1.6" - handlebars "^4.7.7" - interpret "^2.2.0" - json5 "^2.2.3" - lazy-universal-dotenv "^3.0.1" - picomatch "^2.3.0" - pkg-dir "^5.0.0" - pretty-hrtime "^1.0.3" - resolve-from "^5.0.0" - slash "^3.0.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "4" - - "@storybook/core-events@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.16.tgz#b1c265dac755007dae172d9d4b72656c9e5d7bb3" - integrity sha512-qMZQwmvzpH5F2uwNUllTPg6eZXr2OaYZQRRN8VZJiuorZzDNdAFmiVWMWdkThwmyLEJuQKXxqCL8lMj/7PPM+g== - dependencies: - core-js "^3.8.2" - - "@storybook/core-events@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-7.6.2.tgz#13198c8020601fd74ec4eb53852f20e7f0bd68b5" - integrity sha512-JciGNDclg3hx+WkXsAzcCBYWk0xsyIbyCAwqN7XVHUpGndR/dl97Qum5MkO9kPb8r5toKpeBOQo5Kxo2GiE0dg== - dependencies: - ts-dedent "^2.0.0" - - "@storybook/core-server@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.16.tgz#f40de3413de49388129d29c74e5e48321af03f12" - integrity sha512-/3NPfmNyply395Dm0zaVZ8P9aruwO+tPx4D6/jpw8aqrRSwvAMndPMpoMCm0NXcpSm5rdX+Je4S3JW6JcggFkA== - dependencies: - "@discoveryjs/json-ext" "^0.5.3" - "@storybook/builder-webpack4" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/csf-tools" "6.5.16" - "@storybook/manager-webpack4" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@storybook/telemetry" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/node-fetch" "^2.5.7" - "@types/pretty-hrtime" "^1.0.0" - "@types/webpack" "^4.41.26" - better-opn "^2.1.1" - boxen "^5.1.2" - chalk "^4.1.0" - cli-table3 "^0.6.1" - commander "^6.2.1" - compression "^1.7.4" - core-js "^3.8.2" - cpy "^8.1.2" - detect-port "^1.3.0" - express "^4.17.1" - fs-extra "^9.0.1" - global "^4.4.0" - globby "^11.0.2" - ip "^2.0.0" - lodash "^4.17.21" - node-fetch "^2.6.7" - open "^8.4.0" - pretty-hrtime "^1.0.3" - prompts "^2.4.0" - regenerator-runtime "^0.13.7" - serve-favicon "^2.5.0" - slash "^3.0.0" - telejson "^6.0.8" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - watchpack "^2.2.0" - webpack "4" - ws "^8.2.3" - x-default-browser "^0.4.0" - - "@storybook/core@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.16.tgz#ae994f01327fe81b6e652963c35bac7a74f0da06" - integrity sha512-CEF3QFTsm/VMnMKtRNr4rRdLeIkIG0g1t26WcmxTdSThNPBd8CsWzQJ7Jqu7CKiut+MU4A1LMOwbwCE5F2gmyA== - dependencies: - "@storybook/core-client" "6.5.16" - "@storybook/core-server" "6.5.16" - - "@storybook/csf-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.16.tgz#367889a3ddb33c93261129104ec2958215ec5459" - integrity sha512-+WD4sH/OwAfXZX3IN6/LOZ9D9iGEFcN+Vvgv9wOsLRgsAZ10DG/NK6c1unXKDM/ogJtJYccNI8Hd+qNE/GFV6A== - dependencies: - "@babel/core" "^7.12.10" - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/plugin-transform-react-jsx" "^7.12.12" - "@babel/preset-env" "^7.12.11" - "@babel/traverse" "^7.12.11" - "@babel/types" "^7.12.11" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/mdx1-csf" "^0.0.1" - core-js "^3.8.2" - fs-extra "^9.0.1" - global "^4.4.0" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - - "@storybook/csf@0.0.2--canary.4566f4d.1": - version "0.0.2--canary.4566f4d.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz#dac52a21c40ef198554e71fe4d20d61e17f65327" - integrity sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ== - dependencies: - lodash "^4.17.15" - - "@storybook/csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" - integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== - dependencies: - lodash "^4.17.15" - - "@storybook/csf@^0.1.2": - version "0.1.2" - resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.1.2.tgz#8e7452f0097507f5841b5ade3f5da1525bc9afb2" - integrity sha512-ePrvE/pS1vsKR9Xr+o+YwdqNgHUyXvg+1Xjx0h9LrVx7Zq4zNe06pd63F5EvzTbCbJsHj7GHr9tkiaqm7U8WRA== - dependencies: - type-fest "^2.19.0" - - "@storybook/docs-tools@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.16.tgz#1ec5433eeab63a214d37ffc4660cdaec9704ac39" - integrity sha512-o+rAWPRGifjBF5xZzTKOqnHN3XQWkl0QFJYVDIiJYJrVll7ExCkpEq/PahOGzIBBV+tpMstJgmKM3lr/lu/jmg== - dependencies: - "@babel/core" "^7.12.10" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - core-js "^3.8.2" - doctrine "^3.0.0" - lodash "^4.17.21" - regenerator-runtime "^0.13.7" - - "@storybook/global@^5.0.0": - version "5.0.0" - resolved "https://registry.yarnpkg.com/@storybook/global/-/global-5.0.0.tgz#b793d34b94f572c1d7d9e0f44fac4e0dbc9572ed" - integrity sha512-FcOqPAXACP0I3oJ/ws6/rrPT9WGhu915Cg8D02a9YxLo0DE9zI+a9A5gRGvmQ09fiWPukqI8ZAEoQEdWUKMQdQ== - - "@storybook/instrumenter@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-6.5.16.tgz#62acd94e35f1ec403dbc0145b026dfc042ca2f65" - integrity sha512-q8/GaBk8PA/cL7m5OW+ec5t63+Zja9YvYSPGXrYtW17koSv7OnNPmk6RvI7tIHHO0mODBYnaHjF4zQfEGoyR5Q== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - core-js "^3.8.2" - global "^4.4.0" - - "@storybook/instrumenter@^6.4.0 || >=6.5.0-0": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-7.6.2.tgz#1db5415ec268e49773cd44573baea6011b0e8c23" - integrity sha512-IQQh0troFy0naXJUc47UtqJ1Bcs4SaBBxxCMlUeJLML1w0EjBSNCB6kewTU/DfjlkFm8a7YnEwxPTEh1dZiq8w== - dependencies: - "@storybook/channels" "7.6.2" - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" - "@storybook/global" "^5.0.0" - "@storybook/preview-api" "7.6.2" - "@vitest/utils" "^0.34.6" - util "^0.12.4" - - "@storybook/manager-webpack4@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.16.tgz#7033228d38f048ceff3d403ba918d7f206b926a5" - integrity sha512-5VJZwmQU6AgdsBPsYdu886UKBHQ9SJEnFMaeUxKEclXk+iRsmbzlL4GHKyVd6oGX/ZaecZtcHPR6xrzmA4Ziew== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - "@types/webpack" "^4.41.26" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - chalk "^4.1.0" - core-js "^3.8.2" - css-loader "^3.6.0" - express "^4.17.1" - file-loader "^6.2.0" - find-up "^5.0.0" - fs-extra "^9.0.1" - html-webpack-plugin "^4.0.0" - node-fetch "^2.6.7" - pnp-webpack-plugin "1.6.4" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - style-loader "^1.3.0" - telejson "^6.0.8" - terser-webpack-plugin "^4.2.3" - ts-dedent "^2.0.0" - url-loader "^4.1.1" - util-deprecate "^1.0.2" - webpack "4" - webpack-dev-middleware "^3.7.3" - webpack-virtual-modules "^0.2.2" - - "@storybook/manager-webpack5@^6.5.8": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/manager-webpack5/-/manager-webpack5-6.5.16.tgz#48b223557d9633614ff8c6e3227c01a57ab4eb55" - integrity sha512-OtxXv8JCe0r/0rE5HxaFicsNsXA+fqZxzokxquFFgrYf/1Jg4d7QX6/pG5wINF+5qInJfVkRG6xhPzv1s5bk9Q== - dependencies: - "@babel/core" "^7.12.10" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@storybook/addons" "6.5.16" - "@storybook/core-client" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/theming" "6.5.16" - "@storybook/ui" "6.5.16" - "@types/node" "^14.0.10 || ^16.0.0" - babel-loader "^8.0.0" - case-sensitive-paths-webpack-plugin "^2.3.0" - chalk "^4.1.0" - core-js "^3.8.2" - css-loader "^5.0.1" - express "^4.17.1" - find-up "^5.0.0" - fs-extra "^9.0.1" - html-webpack-plugin "^5.0.0" - node-fetch "^2.6.7" - process "^0.11.10" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - style-loader "^2.0.0" - telejson "^6.0.8" - terser-webpack-plugin "^5.0.3" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack "^5.9.0" - webpack-dev-middleware "^4.1.0" - webpack-virtual-modules "^0.4.1" - - "@storybook/mdx1-csf@^0.0.1": - version "0.0.1" - resolved "https://registry.yarnpkg.com/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz#d4184e3f6486fade9f7a6bfaf934d9bc07718d5b" - integrity sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg== - dependencies: - "@babel/generator" "^7.12.11" - "@babel/parser" "^7.12.11" - "@babel/preset-env" "^7.12.11" - "@babel/types" "^7.12.11" - "@mdx-js/mdx" "^1.6.22" - "@types/lodash" "^4.14.167" - js-string-escape "^1.0.1" - loader-utils "^2.0.0" - lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" - ts-dedent "^2.0.0" - - "@storybook/node-logger@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.16.tgz#d57fd6204c2abfbc297551d98ad5475dd73207cc" - integrity sha512-YjhBKrclQtjhqFNSO+BZK+RXOx6EQypAELJKoLFaawg331e8VUfvUuRCNB3fcEWp8G9oH13PQQte0OTjLyyOYg== - dependencies: - "@types/npmlog" "^4.1.2" - chalk "^4.1.0" - core-js "^3.8.2" - npmlog "^5.0.1" - pretty-hrtime "^1.0.3" - - "@storybook/postinstall@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.16.tgz#20aa02fd4513fa0b60ed838b413c46f351f64f60" - integrity sha512-08K2q+qN6pqyPW7PHLCZ5G5Xa6Wosd6t0F16PQ4abX2ItlJLabVoJN5mZ0gm/aeLTjD8QYr8IDvacu4eXh0SVA== - dependencies: - core-js "^3.8.2" - - "@storybook/preview-api@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/preview-api/-/preview-api-7.6.2.tgz#2b0158341510cfa87babaa13d8077a0741e2664d" - integrity sha512-5scmFblrBKBLQSZVlwNUCXhos8GJ8alzMSs0msAbguytjWEuNQ2EKoO7EoO3wvaYf7K3mkOg082RU9nH8SM6mg== - dependencies: - "@storybook/channels" "7.6.2" - "@storybook/client-logger" "7.6.2" - "@storybook/core-events" "7.6.2" - "@storybook/csf" "^0.1.2" - "@storybook/global" "^5.0.0" - "@storybook/types" "7.6.2" - "@types/qs" "^6.9.5" - dequal "^2.0.2" - lodash "^4.17.21" - memoizerific "^1.11.3" - qs "^6.10.0" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/preview-web@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.16.tgz#1d32a72be25776f9597e33ffc1914f3430fae689" - integrity sha512-IJnvfe2sKCfk7apN9Fu9U8qibbarrPX5JB55ZzK1amSHVmSDuYk5MIMc/U3NnSQNnvd1DO5v/zMcGgj563hrtg== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/channel-postmessage" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/store" "6.5.16" - ansi-to-html "^0.6.11" - core-js "^3.8.2" - global "^4.4.0" - lodash "^4.17.21" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - unfetch "^4.2.0" - util-deprecate "^1.0.2" - - "@storybook/react-docgen-typescript-plugin@1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0": - version "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0.tgz#3103532ff494fb7dc3cf835f10740ecf6a26c0f9" - integrity sha512-eVg3BxlOm2P+chijHBTByr90IZVUtgRW56qEOLX7xlww2NBuKrcavBlcmn+HH7GIUktquWkMPtvy6e0W0NgA5w== - dependencies: - debug "^4.1.1" - endent "^2.0.1" - find-cache-dir "^3.3.1" - flat-cache "^3.0.4" - micromatch "^4.0.2" - react-docgen-typescript "^2.1.1" - tslib "^2.0.0" - - "@storybook/react@^6.5.15": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.5.16.tgz#f7b82ba87f5bb73b4e4e83cce298a98710a88398" - integrity sha512-cBtNlOzf/MySpNLBK22lJ8wFU22HnfTB2xJyBk7W7Zi71Lm7Uxkhv1Pz8HdiQndJ0SlsAAQOWjQYsSZsGkZIaA== - dependencies: - "@babel/preset-flow" "^7.12.1" - "@babel/preset-react" "^7.12.10" - "@pmmmwh/react-refresh-webpack-plugin" "^0.5.3" - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core" "6.5.16" - "@storybook/core-common" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - "@storybook/docs-tools" "6.5.16" - "@storybook/node-logger" "6.5.16" - "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.6.9d540b91e815f8fc2f8829189deb00553559ff63.0" - "@storybook/semver" "^7.3.2" - "@storybook/store" "6.5.16" - "@types/estree" "^0.0.51" - "@types/node" "^14.14.20 || ^16.0.0" - "@types/webpack-env" "^1.16.0" - acorn "^7.4.1" - acorn-jsx "^5.3.1" - acorn-walk "^7.2.0" - babel-plugin-add-react-displayname "^0.0.5" - babel-plugin-react-docgen "^4.2.1" - core-js "^3.8.2" - escodegen "^2.0.0" - fs-extra "^9.0.1" - global "^4.4.0" - html-tags "^3.1.0" - lodash "^4.17.21" - prop-types "^15.7.2" - react-element-to-jsx-string "^14.3.4" - react-refresh "^0.11.0" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - webpack ">=4.43.0 <6.0.0" - - "@storybook/router@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.16.tgz#28fb4d34e8219351a40bee1fc94dcacda6e1bd8b" - integrity sha512-ZgeP8a5YV/iuKbv31V8DjPxlV4AzorRiR8OuSt/KqaiYXNXlOoQDz/qMmiNcrshrfLpmkzoq7fSo4T8lWo2UwQ== - dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - - "@storybook/semver@^7.3.2": - version "7.3.2" - resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" - integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== - dependencies: - core-js "^3.6.5" - find-up "^4.1.0" - - "@storybook/source-loader@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.5.16.tgz#b691a024e6ff36bbd1144ecb4a65986f0e149741" - integrity sha512-fyVl4jrM/5JLrb48aqXPu7sTsmySQaVGFp1zfeqvPPlJRFMastDrePm5XGPN7Qjv1wsKmpuBvuweFKOT1pru3g== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - estraverse "^5.2.0" - global "^4.4.0" - loader-utils "^2.0.4" - lodash "^4.17.21" - prettier ">=2.2.1 <=2.3.0" - regenerator-runtime "^0.13.7" - - "@storybook/store@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.16.tgz#b308701293a3a11bfcc766770584495874fd17da" - integrity sha512-g+bVL5hmMq/9cM51K04e37OviUPHT0rHHrRm5wj/hrf18Kd9120b3sxdQ5Dc+HZ292yuME0n+cyrQPTYx9Epmw== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/csf" "0.0.2--canary.4566f4d.1" - core-js "^3.8.2" - fast-deep-equal "^3.1.3" - global "^4.4.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - slash "^3.0.0" - stable "^0.1.8" - synchronous-promise "^2.0.15" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" - - "@storybook/telemetry@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.16.tgz#b13c8133e02c28e37b7716c987e7414b1ddc5363" - integrity sha512-CWr5Uko1l9jJW88yTXsZTj/3GTabPvw0o7pDPOXPp8JRZiJTxv1JFaFCafhK9UzYbgcRuGfCC8kEWPZims7iKA== - dependencies: - "@storybook/client-logger" "6.5.16" - "@storybook/core-common" "6.5.16" - chalk "^4.1.0" - core-js "^3.8.2" - detect-package-manager "^2.0.1" - fetch-retry "^5.0.2" - fs-extra "^9.0.1" - global "^4.4.0" - isomorphic-unfetch "^3.1.0" - nanoid "^3.3.1" - read-pkg-up "^7.0.1" - regenerator-runtime "^0.13.7" - - "@storybook/testing-library@^0.0.9": - version "0.0.9" - resolved "https://registry.yarnpkg.com/@storybook/testing-library/-/testing-library-0.0.9.tgz#e3d6e8077d58305bb352903e820dcae9306e7a7f" - integrity sha512-X4/Tk7RryB0tZ/9NLUHYTBXW01zRpf6+IhdhqsVl6WOWRyUaIv3zEhr43gQyZhBe4ZZyt5d90FJC9qWmY1oFKg== - dependencies: - "@storybook/client-logger" "^6.4.0 || >=6.5.0-0" - "@storybook/instrumenter" "^6.4.0 || >=6.5.0-0" - "@testing-library/dom" "^8.3.0" - "@testing-library/user-event" "^13.2.1" - ts-dedent "^2.2.0" - - "@storybook/theming@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.16.tgz#b999bdb98945b605b93b9dfdf7408535b701e2aa" - integrity sha512-hNLctkjaYLRdk1+xYTkC1mg4dYz2wSv6SqbLpcKMbkPHTE0ElhddGPHQqB362md/w9emYXNkt1LSMD8Xk9JzVQ== - dependencies: - "@storybook/client-logger" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - regenerator-runtime "^0.13.7" - - "@storybook/types@7.6.2": - version "7.6.2" - resolved "https://registry.yarnpkg.com/@storybook/types/-/types-7.6.2.tgz#4db470df5cba3da244d979fbdaafafa45b0e0f4d" - integrity sha512-GlEkG4D/BFuPrLGpTkrfmeLM/fEki0FTnMs1SgNQL10wl6Y98EDJWvCItPVPBoGBERpShxEmkSi2HmcySWZgsA== - dependencies: - "@storybook/channels" "7.6.2" - "@types/babel__core" "^7.0.0" - "@types/express" "^4.7.0" - file-system-cache "2.3.0" - - "@storybook/ui@6.5.16": - version "6.5.16" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.16.tgz#c73bf456e672ecf2370b4365070088487fc0ce57" - integrity sha512-rHn/n12WM8BaXtZ3IApNZCiS+C4Oc5+Lkl4MoctX8V7QSml0SxZBB5hsJ/AiWkgbRxjQpa/L/Nt7/Qw0FjTH/A== - dependencies: - "@storybook/addons" "6.5.16" - "@storybook/api" "6.5.16" - "@storybook/channels" "6.5.16" - "@storybook/client-logger" "6.5.16" - "@storybook/components" "6.5.16" - "@storybook/core-events" "6.5.16" - "@storybook/router" "6.5.16" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.5.16" - core-js "^3.8.2" - memoizerific "^1.11.3" - qs "^6.10.0" - regenerator-runtime "^0.13.7" - resolve-from "^5.0.0" - - "@svgr/babel-plugin-add-jsx-attribute@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-add-jsx-attribute/-/babel-plugin-add-jsx-attribute-6.5.1.tgz#74a5d648bd0347bda99d82409d87b8ca80b9a1ba" - integrity sha512-9PYGcXrAxitycIjRmZB+Q0JaN07GZIWaTBIGQzfaZv+qr1n8X1XUEJ5rZ/vx6OVD9RRYlrNnXWExQXcmZeD/BQ== - - "@svgr/babel-plugin-remove-jsx-attribute@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-attribute/-/babel-plugin-remove-jsx-attribute-8.0.0.tgz#69177f7937233caca3a1afb051906698f2f59186" - integrity sha512-BcCkm/STipKvbCl6b7QFrMh/vx00vIP63k2eM66MfHJzPr6O2U0jYEViXkHJWqXqQYjdeA9cuCl5KWmlwjDvbA== - - "@svgr/babel-plugin-remove-jsx-empty-expression@*": - version "8.0.0" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-remove-jsx-empty-expression/-/babel-plugin-remove-jsx-empty-expression-8.0.0.tgz#c2c48104cfd7dcd557f373b70a56e9e3bdae1d44" - integrity sha512-5BcGCBfBxB5+XSDSWnhTThfI9jcO5f0Ai2V24gZpG+wXF14BzwxxdDb4g6trdOux0rhibGs385BeFMSmxtS3uA== - - "@svgr/babel-plugin-replace-jsx-attribute-value@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-replace-jsx-attribute-value/-/babel-plugin-replace-jsx-attribute-value-6.5.1.tgz#fb9d22ea26d2bc5e0a44b763d4c46d5d3f596c60" - integrity sha512-8DPaVVE3fd5JKuIC29dqyMB54sA6mfgki2H2+swh+zNJoynC8pMPzOkidqHOSc6Wj032fhl8Z0TVn1GiPpAiJg== - - "@svgr/babel-plugin-svg-dynamic-title@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-dynamic-title/-/babel-plugin-svg-dynamic-title-6.5.1.tgz#01b2024a2b53ffaa5efceaa0bf3e1d5a4c520ce4" - integrity sha512-FwOEi0Il72iAzlkaHrlemVurgSQRDFbk0OC8dSvD5fSBPHltNh7JtLsxmZUhjYBZo2PpcU/RJvvi6Q0l7O7ogw== - - "@svgr/babel-plugin-svg-em-dimensions@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-svg-em-dimensions/-/babel-plugin-svg-em-dimensions-6.5.1.tgz#dd3fa9f5b24eb4f93bcf121c3d40ff5facecb217" - integrity sha512-gWGsiwjb4tw+ITOJ86ndY/DZZ6cuXMNE/SjcDRg+HLuCmwpcjOktwRF9WgAiycTqJD/QXqL2f8IzE2Rzh7aVXA== - - "@svgr/babel-plugin-transform-react-native-svg@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-react-native-svg/-/babel-plugin-transform-react-native-svg-6.5.1.tgz#1d8e945a03df65b601551097d8f5e34351d3d305" - integrity sha512-2jT3nTayyYP7kI6aGutkyfJ7UMGtuguD72OjeGLwVNyfPRBD8zQthlvL+fAbAKk5n9ZNcvFkp/b1lZ7VsYqVJg== - - "@svgr/babel-plugin-transform-svg-component@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-plugin-transform-svg-component/-/babel-plugin-transform-svg-component-6.5.1.tgz#48620b9e590e25ff95a80f811544218d27f8a250" - integrity sha512-a1p6LF5Jt33O3rZoVRBqdxL350oge54iZWHNI6LJB5tQ7EelvD/Mb1mfBiZNAan0dt4i3VArkFRjA4iObuNykQ== - - "@svgr/babel-preset@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/babel-preset/-/babel-preset-6.5.1.tgz#b90de7979c8843c5c580c7e2ec71f024b49eb828" - integrity sha512-6127fvO/FF2oi5EzSQOAjo1LE3OtNVh11R+/8FXa+mHx1ptAaS4cknIjnUA7e6j6fwGGJ17NzaTJFUwOV2zwCw== - 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/core@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/core/-/core-6.5.1.tgz#d3e8aa9dbe3fbd747f9ee4282c1c77a27410488a" - integrity sha512-/xdLSWxK5QkqG524ONSjvg3V/FkNyCv538OIBdQqPNaAta3AsXj/Bd2FbvR87yMbXO2hFSWiAe/Q6IkVPDw+mw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/plugin-jsx" "^6.5.1" - camelcase "^6.2.0" - cosmiconfig "^7.0.1" - - "@svgr/hast-util-to-babel-ast@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/hast-util-to-babel-ast/-/hast-util-to-babel-ast-6.5.1.tgz#81800bd09b5bcdb968bf6ee7c863d2288fdb80d2" - integrity sha512-1hnUxxjd83EAxbL4a0JDJoD3Dao3hmjvyvyEV8PzWmLK3B9m9NPlW7GKjFyoWE8nM7HnXzPcmmSyOW8yOddSXw== - dependencies: - "@babel/types" "^7.20.0" - entities "^4.4.0" - - "@svgr/plugin-jsx@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-jsx/-/plugin-jsx-6.5.1.tgz#0e30d1878e771ca753c94e69581c7971542a7072" - integrity sha512-+UdQxI3jgtSjCykNSlEMuy1jSRQlGC7pqBCPvkG/2dATdWo082zHTTK3uhnAju2/6XpE6B5mZ3z4Z8Ns01S8Gw== - dependencies: - "@babel/core" "^7.19.6" - "@svgr/babel-preset" "^6.5.1" - "@svgr/hast-util-to-babel-ast" "^6.5.1" - svg-parser "^2.0.4" - - "@svgr/plugin-svgo@^6.5.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/plugin-svgo/-/plugin-svgo-6.5.1.tgz#0f91910e988fc0b842f88e0960c2862e022abe84" - integrity sha512-omvZKf8ixP9z6GWgwbtmP9qQMPX4ODXi+wzbVZgomNFsUIlHA1sf4fThdwTWSsZGgvGAG6yE+b/F5gWUkcZ/iQ== - dependencies: - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - svgo "^2.8.0" - - "@svgr/webpack@^6.1.1": - version "6.5.1" - resolved "https://registry.yarnpkg.com/@svgr/webpack/-/webpack-6.5.1.tgz#ecf027814fc1cb2decc29dc92f39c3cf691e40e8" - integrity sha512-cQ/AsnBkXPkEK8cLbv4Dm7JGXq2XrumKnL1dRpJD9rIO2fTIlJI9a1uCciYG1F2aUsox/hJQyNGbt3soDxSRkA== - dependencies: - "@babel/core" "^7.19.6" - "@babel/plugin-transform-react-constant-elements" "^7.18.12" - "@babel/preset-env" "^7.19.4" - "@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" - - "@swc/helpers@^0.4.14": - version "0.4.36" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.36.tgz#fcfff76ed52c214f357e8e9d3f37b568908072d9" - integrity sha512-5lxnyLEYFskErRPenYItLRSge5DjrJngYKdVjRSrWfza9G6KkgHEXi0vUZiyUeMU5JfXH1YnvXZzSp8ul88o2Q== - dependencies: - legacy-swc-helpers "npm:@swc/helpers@=0.4.14" - tslib "^2.4.0" - - "@swc/helpers@^0.5.0": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.5.3.tgz#98c6da1e196f5f08f977658b80d6bd941b5f294f" - integrity sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A== - dependencies: - tslib "^2.4.0" - - "@tauri-apps/api@^1.2.0", "@tauri-apps/api@^1.5.1": - version "1.5.1" - resolved "https://registry.yarnpkg.com/@tauri-apps/api/-/api-1.5.1.tgz#9074476c4323f71351db624e9711c99277cdfb99" - integrity sha512-6unsZDOdlXTmauU3NhWhn+Cx0rODV+rvNvTdvolE5Kls5ybA6cqndQENDt1+FS0tF7ozCP66jwWoH6a5h90BrA== - - "@tauri-apps/cli-darwin-arm64@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-arm64/-/cli-darwin-arm64-1.5.6.tgz#0d68eaf6fa1b35197a9d4991ac5377e6085a569a" - integrity sha512-NNvG3XLtciCMsBahbDNUEvq184VZmOveTGOuy0So2R33b/6FDkuWaSgWZsR1mISpOuP034htQYW0VITCLelfqg== - - "@tauri-apps/cli-darwin-x64@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-darwin-x64/-/cli-darwin-x64-1.5.6.tgz#a48e1f66b12c33cf6c9c216865f2e9a3ff18a923" - integrity sha512-nkiqmtUQw3N1j4WoVjv81q6zWuZFhBLya/RNGUL94oafORloOZoSY0uTZJAoeieb3Y1YK0rCHSDl02MyV2Fi4A== - - "@tauri-apps/cli-linux-arm-gnueabihf@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm-gnueabihf/-/cli-linux-arm-gnueabihf-1.5.6.tgz#385cd8054be7722cc07acc2d6d86f8e20c6265ef" - integrity sha512-z6SPx+axZexmWXTIVPNs4Tg7FtvdJl9EKxYN6JPjOmDZcqA13iyqWBQal2DA/GMZ1Xqo3vyJf6EoEaKaliymPQ== - - "@tauri-apps/cli-linux-arm64-gnu@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-gnu/-/cli-linux-arm64-gnu-1.5.6.tgz#bd3f8f61637a1073909cb2d663aa0c6e8e036337" - integrity sha512-QuQjMQmpsCbzBrmtQiG4uhnfAbdFx3nzm+9LtqjuZlurc12+Mj5MTgqQ3AOwQedH3f7C+KlvbqD2AdXpwTg7VA== - - "@tauri-apps/cli-linux-arm64-musl@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.5.6.tgz#77fb4a804b77447bffba725a4b8b62df45f9ff97" - integrity sha512-8j5dH3odweFeom7bRGlfzDApWVOT4jIq8/214Wl+JeiNVehouIBo9lZGeghZBH3XKFRwEvU23i7sRVjuh2s8mg== - - "@tauri-apps/cli-linux-x64-gnu@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.6.tgz#e70a6c9dd243c2a3fa1fec69de9ebc9abf4dc795" - integrity sha512-gbFHYHfdEGW0ffk8SigDsoXks6USpilF6wR0nqB/JbWzbzFR/sBuLVNQlJl1RKNakyJHu+lsFxGy0fcTdoX8xA== - - "@tauri-apps/cli-linux-x64-musl@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.6.tgz#f25dad778b2da6ab7b2b81f81c0805026d742c33" - integrity sha512-9v688ogoLkeFYQNgqiSErfhTreLUd8B3prIBSYUt+x4+5Kcw91zWvIh+VSxL1n3KCGGsM7cuXhkGPaxwlEh1ug== - - "@tauri-apps/cli-win32-arm64-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-arm64-msvc/-/cli-win32-arm64-msvc-1.5.6.tgz#47d0f359e04d93c1fd0b527e18a56606f3df9bed" - integrity sha512-DRNDXFNZb6y5IZrw+lhTTA9l4wbzO4TNRBAlHAiXUrH+pRFZ/ZJtv5WEuAj9ocVSahVw2NaK5Yaold4NPAxHog== - - "@tauri-apps/cli-win32-ia32-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-ia32-msvc/-/cli-win32-ia32-msvc-1.5.6.tgz#54c7ec152065e8167068411b82748a25a483d948" - integrity sha512-oUYKNR/IZjF4fsOzRpw0xesl2lOjhsQEyWlgbpT25T83EU113Xgck9UjtI7xemNI/OPCv1tPiaM1e7/ABdg5iA== - - "@tauri-apps/cli-win32-x64-msvc@1.5.6": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli-win32-x64-msvc/-/cli-win32-x64-msvc-1.5.6.tgz#963280a4f7001c27d4e4745f302728297c007deb" - integrity sha512-RmEf1os9C8//uq2hbjXi7Vgz9ne7798ZxqemAZdUwo1pv3oLVZSz1/IvZmUHPdy2e6zSeySqWu1D0Y3QRNN+dg== - - "@tauri-apps/cli@^1.0.5", "@tauri-apps/cli@^1.2.2": - version "1.5.6" - resolved "https://registry.yarnpkg.com/@tauri-apps/cli/-/cli-1.5.6.tgz#5011c9dd3a36dc89073fed7d4cb429d38b37862b" - integrity sha512-k4Y19oVCnt7WZb2TnDzLqfs7o98Jq0tUoVMv+JQSzuRDJqaVu2xMBZ8dYplEn+EccdR5SOMyzaLBJWu38TVK1A== - optionalDependencies: - "@tauri-apps/cli-darwin-arm64" "1.5.6" - "@tauri-apps/cli-darwin-x64" "1.5.6" - "@tauri-apps/cli-linux-arm-gnueabihf" "1.5.6" - "@tauri-apps/cli-linux-arm64-gnu" "1.5.6" - "@tauri-apps/cli-linux-arm64-musl" "1.5.6" - "@tauri-apps/cli-linux-x64-gnu" "1.5.6" - "@tauri-apps/cli-linux-x64-musl" "1.5.6" - "@tauri-apps/cli-win32-arm64-msvc" "1.5.6" - "@tauri-apps/cli-win32-ia32-msvc" "1.5.6" - "@tauri-apps/cli-win32-x64-msvc" "1.5.6" - - "@tauri-apps/tauri-forage@^1.0.0-beta.2": - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/@tauri-apps/tauri-forage/-/tauri-forage-1.0.0-beta.2.tgz#c11b438ba32731dc7b4c8689d9fda4130baadc07" - integrity sha512-aGObWlY8sgEfImt8+Cv4D+hqWhWB4KwPLVRQTv2uPtHSrXpXrvkJ8vTjy+QsT7tGPyVhcLPBchbyGu0JReErSQ== - dependencies: - localforage "^1.7.3" - ramda "^0.26.1" - tweetnacl "^1.0.1" - tweetnacl-util "^0.15.0" - - "@testing-library/dom@^8.0.0", "@testing-library/dom@^8.3.0": - version "8.20.1" - resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.20.1.tgz#2e52a32e46fc88369eef7eef634ac2a192decd9f" - integrity sha512-/DiOQ5xBxgdYRC8LNk7U+RWat0S3qRLeIw3ZIkMQ9kkVlRmwD/Eg8k8CqIpD6GW7u20JIUOfMKbxtiLutpjQ4g== - dependencies: - "@babel/code-frame" "^7.10.4" - "@babel/runtime" "^7.12.5" - "@types/aria-query" "^5.0.1" - aria-query "5.1.3" - chalk "^4.1.0" - dom-accessibility-api "^0.5.9" - lz-string "^1.5.0" - pretty-format "^27.0.2" - - "@testing-library/jest-dom@^5.14.1": - version "5.17.0" - resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-5.17.0.tgz#5e97c8f9a15ccf4656da00fecab505728de81e0c" - integrity sha512-ynmNeT7asXyH3aSVv4vvX4Rb+0qjOhdNHnO/3vuZNqPmhDpV/+rCSGwQ7bLcmU2cJ4dvoheIO85LQj0IbJHEtg== - dependencies: - "@adobe/css-tools" "^4.0.1" - "@babel/runtime" "^7.9.2" - "@types/testing-library__jest-dom" "^5.9.1" - aria-query "^5.0.0" - chalk "^3.0.0" - css.escape "^1.5.1" - dom-accessibility-api "^0.5.6" - lodash "^4.17.15" - redent "^3.0.0" - - "@testing-library/react@^12.0.0": - version "12.1.5" - resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-12.1.5.tgz#bb248f72f02a5ac9d949dea07279095fa577963b" - integrity sha512-OfTXCJUFgjd/digLUuPxa0+/3ZxsQmE7ub9kcbW/wi96Bh3o/p5vrETcBGfP17NWPGqeYYl5LTRpwyGoMC4ysg== - dependencies: - "@babel/runtime" "^7.12.5" - "@testing-library/dom" "^8.0.0" - "@types/react-dom" "<18.0.0" - - "@testing-library/user-event@^13.2.1": - version "13.5.0" - resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" - integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== - dependencies: - "@babel/runtime" "^7.12.5" - - "@tootallnate/once@1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" - integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== - - "@tootallnate/once@2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" - integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== - - "@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - - "@tsconfig/node10@^1.0.7": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@tsconfig/node10/-/node10-1.0.9.tgz#df4907fc07a886922637b15e02d4cebc4c0021b2" - integrity sha512-jNsYVVxU8v5g43Erja32laIDHXeoNvFEpX33OK4d6hljo3jDhCBDhx5dhCCTMWUojscpAagGiRkBKxpdl9fxqA== - - "@tsconfig/node12@^1.0.7": - version "1.0.11" - resolved "https://registry.yarnpkg.com/@tsconfig/node12/-/node12-1.0.11.tgz#ee3def1f27d9ed66dac6e46a295cffb0152e058d" - integrity sha512-cqefuRsh12pWyGsIoBKJA9luFu3mRxCA+ORZvA4ktLSzIuCUtWVxGIuXigEwO5/ywWFMZ2QEGKWvkZG1zDMTag== - - "@tsconfig/node14@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@tsconfig/node14/-/node14-1.0.3.tgz#e4386316284f00b98435bf40f72f75a09dabf6c1" - integrity sha512-ysT8mhdixWK6Hw3i1V2AeRqZ5WfXg1G43mqoYlM2nc6388Fq5jcXyr5mRsqViLx/GJYdoL0bfXD8nmF+Zn/Iow== - - "@tsconfig/node16@^1.0.2": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" - integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== - - "@tufjs/canonical-json@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@tufjs/canonical-json/-/canonical-json-1.0.0.tgz#eade9fd1f537993bc1f0949f3aea276ecc4fab31" - integrity sha512-QTnf++uxunWvG2z3UFNzAoQPHxnSXOwtaI3iJ+AohhV+5vONuArPjJE7aPXPVXfXJsqrVbZBu9b81AJoSd09IQ== - - "@tufjs/models@1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@tufjs/models/-/models-1.0.4.tgz#5a689630f6b9dbda338d4b208019336562f176ef" - integrity sha512-qaGV9ltJP0EO25YfFUPhxRVK0evXFIAGicsVXuRim4Ed9cjPxYhNnNJ49SFmbeLgtxpslIkX317IgpfcHPVj/A== - dependencies: - "@tufjs/canonical-json" "1.0.0" - minimatch "^9.0.0" - - "@types/acorn@^4.0.0": - version "4.0.6" - resolved "https://registry.yarnpkg.com/@types/acorn/-/acorn-4.0.6.tgz#d61ca5480300ac41a7d973dd5b84d0a591154a22" - integrity sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ== - dependencies: - "@types/estree" "*" - - "@types/aria-query@^5.0.1": - version "5.0.4" - resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-5.0.4.tgz#1a31c3d378850d2778dabb6374d036dcba4ba708" - integrity sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw== - - "@types/babel__core@^7.0.0", "@types/babel__core@^7.1.14": - version "7.20.5" - resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.20.5.tgz#3df15f27ba85319caa07ba08d0721889bb39c017" - integrity sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA== - dependencies: - "@babel/parser" "^7.20.7" - "@babel/types" "^7.20.7" - "@types/babel__generator" "*" - "@types/babel__template" "*" - "@types/babel__traverse" "*" - - "@types/babel__generator@*": - version "7.6.7" - resolved "https://registry.yarnpkg.com/@types/babel__generator/-/babel__generator-7.6.7.tgz#a7aebf15c7bc0eb9abd638bdb5c0b8700399c9d0" - integrity sha512-6Sfsq+EaaLrw4RmdFWE9Onp63TOUue71AWb4Gpa6JxzgTYtimbM086WnYTy2U67AofR++QKCo08ZP6pwx8YFHQ== - dependencies: - "@babel/types" "^7.0.0" - - "@types/babel__template@*": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@types/babel__template/-/babel__template-7.4.4.tgz#5672513701c1b2199bc6dad636a9d7491586766f" - integrity sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A== - dependencies: - "@babel/parser" "^7.1.0" - "@babel/types" "^7.0.0" - - "@types/babel__traverse@*", "@types/babel__traverse@^7.0.4", "@types/babel__traverse@^7.0.6": - version "7.20.4" - resolved "https://registry.yarnpkg.com/@types/babel__traverse/-/babel__traverse-7.20.4.tgz#ec2c06fed6549df8bc0eb4615b683749a4a92e1b" - integrity sha512-mSM/iKUk5fDDrEV/e83qY+Cr3I1+Q3qqTuEn++HAWYjEa1+NxZr6CNrcJGf2ZTnq4HoFGC3zaTPZTobCzCFukA== - dependencies: - "@babel/types" "^7.20.7" - - "@types/big.js@^6.1.6": - version "6.2.2" - resolved "https://registry.yarnpkg.com/@types/big.js/-/big.js-6.2.2.tgz#69422ec9ef59df1330ccfde2106d9e1159a083c3" - integrity sha512-e2cOW9YlVzFY2iScnGBBkplKsrn2CsObHQ2Hiw4V1sSyiGbgWL8IyqE3zFi1Pt5o1pdAtYkDAIsF3KKUPjdzaA== - - "@types/body-parser@*": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" - integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== - dependencies: - "@types/connect" "*" - "@types/node" "*" - - "@types/bonjour@^3.5.9": - version "3.5.13" - resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.13.tgz#adf90ce1a105e81dd1f9c61fdc5afda1bfb92956" - integrity sha512-z9fJ5Im06zvUL548KvYNecEVlA7cVDkGUi6kZusb04mpyEFKCIZJvloCcmpmLaIahDpOQGHaHmG6imtPMmPXGQ== - dependencies: - "@types/node" "*" - - "@types/bs58@^4.0.1": - version "4.0.4" - resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-4.0.4.tgz#49fbcb0c7db5f7cea26f0e0f61dc4a41a2445aab" - integrity sha512-0IEpMFXXQi2zXaXl9GJ3sRwQo0uEkD+yFOv+FnAU5lkPtcu6h61xb7jc2CFPEZ5BUOaiP13ThuGc9HD4R8lR5g== - dependencies: - "@types/node" "*" - base-x "^3.0.6" - - "@types/connect-history-api-fallback@^1.3.5": - version "1.5.4" - resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.4.tgz#7de71645a103056b48ac3ce07b3520b819c1d5b3" - integrity sha512-n6Cr2xS1h4uAulPRdlw6Jl6s1oG8KrVilPN2yUITEs+K48EzMJJ3W1xy8K5eWuFvjp3R74AOIGSmp2UfBJ8HFw== - dependencies: - "@types/express-serve-static-core" "*" - "@types/node" "*" - - "@types/connect@*": - version "3.4.38" - resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.38.tgz#5ba7f3bc4fbbdeaff8dded952e5ff2cc53f8d858" - integrity sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug== - dependencies: - "@types/node" "*" - - "@types/d3-array@^3.0.3": - version "3.2.1" - resolved "https://registry.yarnpkg.com/@types/d3-array/-/d3-array-3.2.1.tgz#1f6658e3d2006c4fceac53fde464166859f8b8c5" - integrity sha512-Y2Jn2idRrLzUfAKV2LyRImR+y4oa2AntrgID95SHJxuMUrkNXmanDSed71sRNZysveJVt1hLLemQZIady0FpEg== - - "@types/d3-color@*": - version "3.1.3" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-3.1.3.tgz#368c961a18de721da8200e80bf3943fb53136af2" - integrity sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A== - - "@types/d3-color@^1": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@types/d3-color/-/d3-color-1.4.5.tgz#23bb1afda325549c6314ab60aa2aa28c4c6b1c37" - integrity sha512-5sNP3DmtSnSozxcjqmzQKsDOuVJXZkceo1KJScDc1982kk/TS9mTPc6lpli1gTu1MIBF1YWutpHpjucNWcIj5g== - - "@types/d3-dsv@*": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-dsv/-/d3-dsv-3.0.7.tgz#0a351f996dc99b37f4fa58b492c2d1c04e3dac17" - integrity sha512-n6QBF9/+XASqcKK6waudgL0pf/S5XHPPI8APyMLLUHd8NqouBGLsU8MgtO7NINGtPBtk9Kko/W4ea0oAspwh9g== - - "@types/d3-ease@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-ease/-/d3-ease-3.0.2.tgz#e28db1bfbfa617076f7770dd1d9a48eaa3b6c51b" - integrity sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA== - - "@types/d3-fetch@^3.0.1": - version "3.0.7" - resolved "https://registry.yarnpkg.com/@types/d3-fetch/-/d3-fetch-3.0.7.tgz#c04a2b4f23181aa376f30af0283dbc7b3b569980" - integrity sha512-fTAfNmxSb9SOWNB9IoG5c8Hg6R+AzUHDRlsXsDZsNp6sxAEOP0tkP3gKkNSO/qmHPoBFTxNrjDprVHDQDvo5aA== - dependencies: - "@types/d3-dsv" "*" - - "@types/d3-geo@^1": - version "1.12.7" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-1.12.7.tgz#595680bf9b9525031cef956ed80baf38b8f3b4be" - integrity sha512-QetZrWWjuMfCe0BHLjD+dOThlgk7YGZ2gj+yhFAbDN5TularNBEQiBs5/CIgX0+IBDjt7/fbkDd5V70J1LjjKA== - dependencies: - "@types/geojson" "*" - - "@types/d3-geo@^3.0.2": - version "3.1.0" - resolved "https://registry.yarnpkg.com/@types/d3-geo/-/d3-geo-3.1.0.tgz#b9e56a079449174f0a2c8684a9a4df3f60522440" - integrity sha512-856sckF0oP/diXtS4jNsiQw/UuK5fQG8l/a9VVLeSouf1/PPbBE1i1W852zVwKwYCBkFJJB7nCFTbk6UMEXBOQ== - dependencies: - "@types/geojson" "*" - - "@types/d3-interpolate@^1": - version "1.4.5" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-1.4.5.tgz#7964699575ec9c594a9a7aaea411a812ce6cd674" - integrity sha512-k9L18hXXv7OvK4PqW1kSFYIzasGOvfhPUWmHFkoZ8/ci99EAmY4HoF6zMefrHl0SGV7XYc7Qq2MNh8dK3edg5A== - dependencies: - "@types/d3-color" "^1" - - "@types/d3-interpolate@^3.0.1": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/d3-interpolate/-/d3-interpolate-3.0.4.tgz#412b90e84870285f2ff8a846c6eb60344f12a41c" - integrity sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA== - dependencies: - "@types/d3-color" "*" - - "@types/d3-path@*": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-path/-/d3-path-3.0.2.tgz#4327f4a05d475cf9be46a93fc2e0f8d23380805a" - integrity sha512-WAIEVlOCdd/NKRYTsqCpOMHQHemKBEINf8YXMYOtXH0GA7SY0dqMB78P3Uhgfy+4X+/Mlw2wDtlETkN6kQUCMA== - - "@types/d3-scale@^4.0.1", "@types/d3-scale@^4.0.2": - version "4.0.8" - resolved "https://registry.yarnpkg.com/@types/d3-scale/-/d3-scale-4.0.8.tgz#d409b5f9dcf63074464bf8ddfb8ee5a1f95945bb" - integrity sha512-gkK1VVTr5iNiYJ7vWDI+yUFFlszhNMtVeneJ6lUTKPjprsvLLI9/tgEGiXJOnlINJA8FyA88gfnQsHbybVZrYQ== - dependencies: - "@types/d3-time" "*" - - "@types/d3-selection@^1": - version "1.4.6" - resolved "https://registry.yarnpkg.com/@types/d3-selection/-/d3-selection-1.4.6.tgz#3e6056117b19d8bb6c729c872ca7234622099fb6" - integrity sha512-0MhJ/LzJe6/vQVxiYJnvNq5CD/MF6Qy0dLp4BEQ6Dz8oOaB0EMXfx1GGeBFSW+3VzgjaUrxK6uECDQj9VLa/Mg== - - "@types/d3-shape@^3.1.0": - version "3.1.6" - resolved "https://registry.yarnpkg.com/@types/d3-shape/-/d3-shape-3.1.6.tgz#65d40d5a548f0a023821773e39012805e6e31a72" - integrity sha512-5KKk5aKGu2I+O6SONMYSNflgiP0WfZIQvVUMan50wHsLG1G94JlxEVnCpQARfTtzytuY0p/9PXXZb3I7giofIA== - dependencies: - "@types/d3-path" "*" - - "@types/d3-time@*", "@types/d3-time@^3.0.0": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/d3-time/-/d3-time-3.0.3.tgz#3c186bbd9d12b9d84253b6be6487ca56b54f88be" - integrity sha512-2p6olUZ4w3s+07q3Tm2dbiMZy5pCDfYwtLXXHUnVzXgQlZ/OyPtUz6OL382BkOuGlLXqfT+wqv8Fw2v8/0geBw== - - "@types/d3-timer@^3.0.0": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@types/d3-timer/-/d3-timer-3.0.2.tgz#70bbda77dc23aa727413e22e214afa3f0e852f70" - integrity sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw== - - "@types/d3-zoom@^1": - version "1.8.7" - resolved "https://registry.yarnpkg.com/@types/d3-zoom/-/d3-zoom-1.8.7.tgz#0afdcf771e6ea518f3a4b634bbb4c8e8979c65b1" - integrity sha512-HJWci3jXwFIuFKDqGn5PmuwrhZvuFdrnUmtSKCLXFAWyf2lAIUKMKh1/lHOkWBl/f4KVupGricJiqkQy+cVTog== - dependencies: - "@types/d3-interpolate" "^1" - "@types/d3-selection" "^1" - - "@types/debug@^4.0.0": - version "4.1.12" - resolved "https://registry.yarnpkg.com/@types/debug/-/debug-4.1.12.tgz#a155f21690871953410df4b6b6f53187f0500917" - integrity sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ== - dependencies: - "@types/ms" "*" - - "@types/eslint-scope@^3.7.3": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - - "@types/eslint@*": - version "8.44.8" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-8.44.8.tgz#f4fe1dab9b3d3dd98082d4b9f80e59ab40f1261c" - integrity sha512-4K8GavROwhrYl2QXDXm0Rv9epkA8GBFu0EI+XrrnnuCl7u8CWBRusX7fXJfanhZTDWSAL24gDI/UqXyUM0Injw== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - - "@types/estree-jsx@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/estree-jsx/-/estree-jsx-1.0.3.tgz#f8aa833ec986d82b8271a294a92ed1565bf2c66a" - integrity sha512-pvQ+TKeRHeiUGRhvYwRrQ/ISnohKkSJR14fT2yqyZ4e9K5vqc7hrtY2Y1Dw0ZwAzQ6DQsxsaCUuSIIi8v0Cq6w== - dependencies: - "@types/estree" "*" - - "@types/estree@*", "@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== - - "@types/estree@^0.0.51": - version "0.0.51" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" - integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== - - "@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.33": - version "4.17.41" - resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.41.tgz#5077defa630c2e8d28aa9ffc2c01c157c305bef6" - integrity sha512-OaJ7XLaelTgrvlZD8/aa0vvvxZdUmlCn6MtWeB7TkiKW70BQLc9XEPpDLPdbo52ZhXUCrznlWdCHWxJWtdyajA== - dependencies: - "@types/node" "*" - "@types/qs" "*" - "@types/range-parser" "*" - "@types/send" "*" - - "@types/express@*", "@types/express@^4.17.13", "@types/express@^4.7.0": - version "4.17.21" - resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.21.tgz#c26d4a151e60efe0084b23dc3369ebc631ed192d" - integrity sha512-ejlPM315qwLpaQlQDTjPdsUFSc6ZsP4AN6AlWnogPjQ7CVi7PYF3YVz+CY3jE2pwYf7E/7HlDAN0rV2GxTG0HQ== - dependencies: - "@types/body-parser" "*" - "@types/express-serve-static-core" "^4.17.33" - "@types/qs" "*" - "@types/serve-static" "*" - - "@types/favicons@5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@types/favicons/-/favicons-5.5.0.tgz#c1cb3d2a14955eedf479f3cc51948630c56e3a64" - integrity sha512-s76OlRaBfqtGu2ZBobnZv2NETfqsQUVfKKlOkKNGo4ArBsqiblodKsnQ3j29hCCgmpQacEfLxealV96za+tzVQ== - dependencies: - "@types/node" "*" - - "@types/flat@^5.0.2": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@types/flat/-/flat-5.0.5.tgz#2304df0b2b1e6dde50d81f029593e0a1bc2474d3" - integrity sha512-nPLljZQKSnac53KDUDzuzdRfGI0TDb5qPrb+SrQyN3MtdQrOnGsKniHN1iYZsJEBIVQve94Y6gNz22sgISZq+Q== - - "@types/geojson@*", "@types/geojson@^7946.0.8": - version "7946.0.13" - resolved "https://registry.yarnpkg.com/@types/geojson/-/geojson-7946.0.13.tgz#e6e77ea9ecf36564980a861e24e62a095988775e" - integrity sha512-bmrNrgKMOhM3WsafmbGmC+6dsF2Z308vLFsQ3a/bT8X8Sv5clVYpPars/UPq+sAaJP+5OoLAYgwbkS5QEJdLUQ== - - "@types/glob@*": - version "8.1.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-8.1.0.tgz#b63e70155391b0584dce44e7ea25190bbc38f2fc" - integrity sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w== - dependencies: - "@types/minimatch" "^5.1.2" - "@types/node" "*" - - "@types/glob@^7.1.1": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" - integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== - dependencies: - "@types/minimatch" "*" - "@types/node" "*" - - "@types/graceful-fs@^4.1.2": - version "4.1.9" - resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.9.tgz#2a06bc0f68a20ab37b3e36aa238be6abdf49e8b4" - integrity sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ== - dependencies: - "@types/node" "*" - - "@types/hast@^2.0.0": - version "2.3.8" - resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.8.tgz#4ac5caf38b262b7bd5ca3202dda71f0271635660" - integrity sha512-aMIqAlFd2wTIDZuvLbhUT+TGvMxrNC8ECUIVtH6xxy0sQLs3iu6NO8Kp/VT5je7i5ufnebXzdV1dNDMnvaH6IQ== - dependencies: - "@types/unist" "^2" - - "@types/html-minifier-terser@^5.0.0": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" - integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== - - "@types/html-minifier-terser@^6.0.0": - version "6.1.0" - resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" - integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== - - "@types/http-errors@*": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" - integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== - - "@types/http-proxy@^1.17.8": - version "1.17.14" - resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.14.tgz#57f8ccaa1c1c3780644f8a94f9c6b5000b5e2eec" - integrity sha512-SSrD0c1OQzlFX7pGu1eXxSEjemej64aaNPRhhVYUGqXh0BtldAAx37MG8btcumvpgKyZp1F5Gn3JkktdxiFv6w== - dependencies: - "@types/node" "*" - - "@types/is-function@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.3.tgz#548f851db5d30a12abeea2569ba75890dbf89425" - integrity sha512-/CLhCW79JUeLKznI6mbVieGbl4QU5Hfn+6udw1YHZoofASjbQ5zaP5LzAUZYDpRYEjS4/P+DhEgyJ/PQmGGTWw== - - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": - version "2.0.6" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz#7739c232a1fee9b4d3ce8985f314c0c6d33549d7" - integrity sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w== - - "@types/istanbul-lib-report@*": - version "3.0.3" - resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz#53047614ae72e19fc0401d872de3ae2b4ce350bf" - integrity sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA== - dependencies: - "@types/istanbul-lib-coverage" "*" - - "@types/istanbul-reports@^3.0.0": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz#0f03e3d2f670fbdac586e34b433783070cc16f54" - integrity sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ== - dependencies: - "@types/istanbul-lib-report" "*" - - "@types/jest@*": - version "29.5.10" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-29.5.10.tgz#a10fc5bab9e426081c12b2ef73d24d4f0c9b7f50" - integrity sha512-tE4yxKEphEyxj9s4inideLHktW/x6DwesIwWZ9NN1FKf9zbJYsnhBoA9vrHA/IuIOKwPa5PcFBNV4lpMIOEzyQ== - dependencies: - expect "^29.0.0" - pretty-format "^29.0.0" - - "@types/jest@^27.0.1": - version "27.5.2" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-27.5.2.tgz#ec49d29d926500ffb9fd22b84262e862049c026c" - integrity sha512-mpT8LJJ4CMeeahobofYWIjFo0xonRS/HfxnVEPMPFSQdGUt1uHCnoPT7Zhb+sjDU2wz0oKV0OLUR0WzrHNgfeA== - dependencies: - jest-matcher-utils "^27.0.0" - pretty-format "^27.0.0" - - "@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": - version "7.0.15" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" - integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== - - "@types/json5@^0.0.29": - version "0.0.29" - resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" - integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== - - "@types/lodash@^4.14.167", "@types/lodash@^4.14.175": - version "4.14.202" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8" - integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ== - - "@types/long@^4.0.1": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.2.tgz#b74129719fc8d11c01868010082d483b7545591a" - integrity sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA== - - "@types/luxon@^2.3.2": - version "2.4.0" - resolved "https://registry.yarnpkg.com/@types/luxon/-/luxon-2.4.0.tgz#897d3abc23b68d78b69d76a12c21e01eb5adab95" - integrity sha512-oCavjEjRXuR6URJEtQm0eBdfsBiEcGBZbq21of8iGkeKxU1+1xgKuFPClaBZl2KB8ZZBSWlgk61tH6Mf+nvZVw== - - "@types/mdast@^3.0.0": - version "3.0.15" - resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.15.tgz#49c524a263f30ffa28b71ae282f813ed000ab9f5" - integrity sha512-LnwD+mUEfxWMa1QpDraczIn6k0Ee3SMicuYSSzS6ZYl2gKS09EClnJYGd8Du6rfc5r/GZEk5o1mRb8TaTj03sQ== - dependencies: - "@types/unist" "^2" - - "@types/mdx@^2.0.0": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@types/mdx/-/mdx-2.0.10.tgz#0d7b57fb1d83e27656156e4ee0dfba96532930e4" - integrity sha512-Rllzc5KHk0Al5/WANwgSPl1/CwjqCy+AZrGd78zuK+jO9aDM6ffblZ+zIjgPNAaEBmlO0RYDvLNh7wD0zKVgEg== - - "@types/mime@*": - version "3.0.4" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-3.0.4.tgz#2198ac274de6017b44d941e00261d5bc6a0e0a45" - integrity sha512-iJt33IQnVRkqeqC7PzBHPTC6fDlRNRW8vjrgqtScAhrmMwe8c4Eo7+fUGTa+XdWrpEgpyKWMYmi2dIwMAYRzPw== - - "@types/mime@^1": - version "1.3.5" - resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.5.tgz#1ef302e01cf7d2b5a0fa526790c9123bf1d06690" - integrity sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w== - - "@types/minimatch@*", "@types/minimatch@^5.1.2": - version "5.1.2" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" - integrity sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA== - - "@types/minimatch@^3.0.3": - version "3.0.5" - resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" - integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== - - "@types/minimist@^1.2.0": - version "1.2.5" - resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.5.tgz#ec10755e871497bcd83efe927e43ec46e8c0747e" - integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== - - "@types/ms@*": - version "0.7.34" - resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.34.tgz#10964ba0dee6ac4cd462e2795b6bebd407303433" - integrity sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g== - - "@types/node-fetch@^2.5.7": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.9.tgz#15f529d247f1ede1824f7e7acdaa192d5f28071e" - integrity sha512-bQVlnMLFJ2d35DkPNjEPmd9ueO/rh5EiaZt2bhqiSarPjZIuIV6bPQVqcrEyvNo+AfTrRGVazle1tl597w3gfA== - dependencies: - "@types/node" "*" - form-data "^4.0.0" - - "@types/node-forge@^1.3.0": - version "1.3.10" - resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-1.3.10.tgz#62a19d4f75a8b03290578c2b04f294b1a5a71b07" - integrity sha512-y6PJDYN4xYBxwd22l+OVH35N+1fCYWiuC3aiP2SlXVE6Lo7SS+rSx9r89hLxrP4pn6n1lBGhHJ12pj3F3Mpttw== - dependencies: - "@types/node" "*" - - "@types/node@*", "@types/node@>=13.7.0": - version "20.10.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-20.10.1.tgz#d2c96f356c3125fedc983d74c424910c3767141c" - integrity sha512-T2qwhjWwGH81vUEx4EXmBKsTJRXFXNZTL4v0gi01+zyBmCwzE6TyHszqX01m+QHTEq+EZNo13NeJIdEqf+Myrg== - dependencies: - undici-types "~5.26.4" - - "@types/node@10.12.18": - version "10.12.18" - resolved "https://registry.yarnpkg.com/@types/node/-/node-10.12.18.tgz#1d3ca764718915584fcd9f6344621b7672665c67" - integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ== - - "@types/node@^13.7.0": - version "13.13.52" - resolved "https://registry.yarnpkg.com/@types/node/-/node-13.13.52.tgz#03c13be70b9031baaed79481c0c0cfb0045e53f7" - integrity sha512-s3nugnZumCC//n4moGGe6tkNMyYEdaDBitVjwPxXmR5lnMG5dHePinH2EdxkG3Rh1ghFHHixAG4NJhpJW1rthQ== - - "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.7.13": - version "16.18.66" - resolved "https://registry.yarnpkg.com/@types/node/-/node-16.18.66.tgz#f59cc2ff96cc47f972a11a458a9b29bf0a209c34" - integrity sha512-sePmD/imfKvC4re/Wwos1NEcXYm6O96CAG5gQVY53nmDb8ePQ4qPku6uruN7n6TJ0t5FhcoUc2+yvE2/UZVDZw== - - "@types/normalize-package-data@^2.4.0": - version "2.4.4" - resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz#56e2cc26c397c038fab0e3a917a12d5c5909e901" - integrity sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA== - - "@types/npmlog@^4.1.2": - version "4.1.6" - resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.6.tgz#792341665000209ee76997df8a16300fda6d77cb" - integrity sha512-0l3z16vnlJGl2Mi/rgJFrdwfLZ4jfNYgE6ZShEpjqhHuGTqdEzNles03NpYHwUMVYZa+Tj46UxKIEpE78lQ3DQ== - dependencies: - "@types/node" "*" - - "@types/parse-json@^4.0.0": - version "4.0.2" - resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.2.tgz#5950e50960793055845e956c427fc2b0d70c5239" - integrity sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw== - - "@types/parse5@^5.0.0": - version "5.0.3" - resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" - integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== - - "@types/prettier@^2.1.5": - version "2.7.3" - resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.7.3.tgz#3e51a17e291d01d17d3fc61422015a933af7a08f" - integrity sha512-+68kP9yzs4LMp7VNh8gdzMSPZFL44MLGqiHWvttYJe+6qnuVr4Ek9wSBQoveqY/r+LwjCcU29kNVkidwim+kYA== - - "@types/pretty-hrtime@^1.0.0": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#ee1bd8c9f7a01b3445786aad0ef23aba5f511a44" - integrity sha512-nj39q0wAIdhwn7DGUyT9irmsKK1tV0bd5WFEhgpqNTMFZ8cE+jieuTphCW0tfdm47S2zVT5mr09B28b1chmQMA== - - "@types/prop-types@*", "@types/prop-types@^15.0.0", "@types/prop-types@^15.7.11": - version "15.7.11" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.11.tgz#2596fb352ee96a1379c657734d4b913a613ad563" - integrity sha512-ga8y9v9uyeiLdpKddhxYQkxNDrfvuPrlFb0N1qnZZByvcElJaXthF1UhvCh9TLWJBEHeNtdnbysW7Y6Uq8CVng== - - "@types/qrcode.react@^1.0.2": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/qrcode.react/-/qrcode.react-1.0.5.tgz#d4ddcacee8f34d22a663029a230c5f0ab908cfb7" - integrity sha512-BghPtnlwvrvq8QkGa1H25YnN+5OIgCKFuQruncGWLGJYOzeSKiix/4+B9BtfKF2wf5ja8yfyWYA3OXju995G8w== - dependencies: - "@types/react" "*" - - "@types/qs@*", "@types/qs@^6.9.5": - version "6.9.10" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.10.tgz#0af26845b5067e1c9a622658a51f60a3934d51e8" - integrity sha512-3Gnx08Ns1sEoCrWssEgTSJs/rsT2vhGP+Ja9cnnk9k4ALxinORlQneLXFeFKOTJMOeZUFD1s7w+w2AphTpvzZw== - - "@types/range-parser@*": - version "1.2.7" - resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.7.tgz#50ae4353eaaddc04044279812f52c8c65857dbcb" - integrity sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ== - - "@types/react-dom@<18.0.0": - version "17.0.25" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-17.0.25.tgz#e0e5b3571e1069625b3a3da2b279379aa33a0cb5" - integrity sha512-urx7A7UxkZQmThYA4So0NelOVjx3V4rNFVJwp0WZlbIK5eM4rNJDiN3R/E9ix0MBh6kAEojk/9YL+Te6D9zHNA== - dependencies: - "@types/react" "^17" - - "@types/react-dom@^18.0.10": - version "18.2.17" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.17.tgz#375c55fab4ae671bd98448dcfa153268d01d6f64" - integrity sha512-rvrT/M7Df5eykWFxn6MYt5Pem/Dbyc1N8Y0S9Mrkw2WFCRiqUgw9P7ul2NpwsXCSM1DVdENzdG9J5SreqfAIWg== - dependencies: - "@types/react" "*" - - "@types/react-simple-maps@^1.0.6": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@types/react-simple-maps/-/react-simple-maps-1.0.8.tgz#a21beb16cbeeadcb093a47de7888db64a2f103aa" - integrity sha512-gNXpQor+H0CCjp8GVNUeeTV+iDPdqFuCDIlYHH17KZ/tVHK1WaRIZl+s2ZnPCVQo27nEnRgU3GQxYbOYxXxgNQ== - dependencies: - "@types/d3-geo" "^1" - "@types/d3-zoom" "^1" - "@types/geojson" "*" - "@types/react" "*" - - "@types/react-tooltip@^4.2.4": - version "4.2.4" - resolved "https://registry.yarnpkg.com/@types/react-tooltip/-/react-tooltip-4.2.4.tgz#d0acad2a3061806e10aab91dd26a95a77fd35125" - integrity sha512-UzjzmgY/VH3Str6DcAGTLMA1mVVhGOyARNTANExrirtp+JgxhaIOVDxq4TIRmpSi4voLv+w4HA9CC5GvhhCA0A== - dependencies: - react-tooltip "*" - - "@types/react-transition-group@^4.4.9": - version "4.4.9" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.9.tgz#12a1a1b5b8791067198149867b0823fbace31579" - integrity sha512-ZVNmWumUIh5NhH8aMD9CR2hdW0fNuYInlocZHaZ+dgk/1K49j1w/HoAuK1ki+pgscQrOFRTlXeoURtuzEkV3dg== - dependencies: - "@types/react" "*" - - "@types/react@*", "@types/react@^18.0.26": - version "18.2.39" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.39.tgz#744bee99e053ad61fe74eb8b897f3ab5b19a7e25" - integrity sha512-Oiw+ppED6IremMInLV4HXGbfbG6GyziY3kqAwJYOR0PNbkYDmLWQA3a95EhdSmamsvbkJN96ZNN+YD+fGjzSBA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - - "@types/react@^17": - version "17.0.71" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.71.tgz#3673d446ad482b1564e44bf853b3ab5bcbc942c4" - integrity sha512-lfqOu9mp16nmaGRrS8deS2Taqhd5Ih0o92Te5Ws6I1py4ytHBcXLqh0YIqVsViqwVI5f+haiFM6hju814BzcmA== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - - "@types/resolve@1.20.2": - version "1.20.2" - resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" - integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== - - "@types/retry@0.12.0": - version "0.12.0" - resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d" - integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA== - - "@types/scheduler@*": - version "0.16.8" - resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.8.tgz#ce5ace04cfeabe7ef87c0091e50752e36707deff" - integrity sha512-WZLiwShhwLRmeV6zH+GkbOFT6Z6VklCItrDioxUnv+u4Ll+8vKeFySoFyK/0ctcRpOmwAicELfmys1sDc/Rw+A== - - "@types/semver@^7.3.12", "@types/semver@^7.3.8": - version "7.5.6" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.6.tgz#c65b2bfce1bec346582c07724e3f8c1017a20339" - integrity sha512-dn1l8LaMea/IjDoHNd9J52uBbInB796CDffS6VdIxvqYCPSG0V0DzHp76GpaWnlhg88uYyPbXCDIowa86ybd5A== - - "@types/send@*": - version "0.17.4" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" - integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== - dependencies: - "@types/mime" "^1" - "@types/node" "*" - - "@types/serve-index@^1.9.1": - version "1.9.4" - resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.4.tgz#e6ae13d5053cb06ed36392110b4f9a49ac4ec898" - integrity sha512-qLpGZ/c2fhSs5gnYsQxtDEq3Oy8SXPClIXkW5ghvAvsNuVSA8k+gCONcUCS/UjLEYvYps+e8uBtfgXgvhwfNug== - dependencies: - "@types/express" "*" - - "@types/serve-static@*", "@types/serve-static@^1.13.10": - version "1.15.5" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.5.tgz#15e67500ec40789a1e8c9defc2d32a896f05b033" - integrity sha512-PDRk21MnK70hja/YF8AHfC7yIsiQHn1rcXx7ijCFBX/k+XQJhQT/gw3xekXKJvx+5SXaMMS8oqQy09Mzvz2TuQ== - dependencies: - "@types/http-errors" "*" - "@types/mime" "*" - "@types/node" "*" - - "@types/sockjs@^0.3.33": - version "0.3.36" - resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.36.tgz#ce322cf07bcc119d4cbf7f88954f3a3bd0f67535" - integrity sha512-MK9V6NzAS1+Ud7JV9lJLFqW85VbC9dq3LmwZCuBe4wBDgKC0Kj/jd8Xl+nSviU+Qc3+m7umHHyHg//2KSa0a0Q== - dependencies: - "@types/node" "*" - - "@types/source-list-map@*": - version "0.1.6" - resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454" - integrity sha512-5JcVt1u5HDmlXkwOD2nslZVllBBc7HDuOICfiZah2Z0is8M8g+ddAEawbmd3VjedfDHBzxCaXLs07QEmb7y54g== - - "@types/stack-utils@^2.0.0": - version "2.0.3" - resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-2.0.3.tgz#6209321eb2c1712a7e7466422b8cb1fc0d9dd5d8" - integrity sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw== - - "@types/tapable@^1", "@types/tapable@^1.0.5": - version "1.0.12" - resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.12.tgz#bc2cab12e87978eee89fb21576b670350d6d86ab" - integrity sha512-bTHG8fcxEqv1M9+TD14P8ok8hjxoOCkfKc8XXLaaD05kI7ohpeI956jtDOD3XHKBQrlyPughUtzm1jtVhHpA5Q== - - "@types/testing-library__jest-dom@^5.9.1": - version "5.14.9" - resolved "https://registry.yarnpkg.com/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.9.tgz#0fb1e6a0278d87b6737db55af5967570b67cb466" - integrity sha512-FSYhIjFlfOpGSRyVoMBMuS3ws5ehFQODymf3vlI7U1K8c7PHwWwFY7VREfmsuzHSOnoKs/9/Y983ayOs7eRzqw== - dependencies: - "@types/jest" "*" - - "@types/topojson-client@^3.1.0": - version "3.1.4" - resolved "https://registry.yarnpkg.com/@types/topojson-client/-/topojson-client-3.1.4.tgz#81b83f9ecd6542dc5c3df21967f992e3fe192c33" - integrity sha512-Ntf3ZSetMYy7z3PrVCvcqmdRoVhgKA9UKN0ZuuZf8Ts2kcyL4qK34IXBs6qO5fem62EK4k03PtkJPVoroVu4/w== - dependencies: - "@types/geojson" "*" - "@types/topojson-specification" "*" - - "@types/topojson-specification@*": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/topojson-specification/-/topojson-specification-1.0.5.tgz#bf0009b2e0debb2d97237b124c00b9ea92570375" - integrity sha512-C7KvcQh+C2nr6Y2Ub4YfgvWvWCgP2nOQMtfhlnwsRL4pYmmwzBS7HclGiS87eQfDOU/DLQpX6GEscviaz4yLIQ== - dependencies: - "@types/geojson" "*" - - "@types/uglify-js@*": - version "3.17.4" - resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.17.4.tgz#3c70021f08023e5a760ce133d22966f200e1d31c" - integrity sha512-Hm/T0kV3ywpJyMGNbsItdivRhYNCQQf1IIsYsXnoVPES4t+FMLyDe0/K+Ea7ahWtMtSNb22ZdY7MIyoD9rqARg== - dependencies: - source-map "^0.6.1" - - "@types/unist@^2", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": - version "2.0.10" - resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.10.tgz#04ffa7f406ab628f7f7e97ca23e290cd8ab15efc" - integrity sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA== - - "@types/uuid@^8.3.4": - version "8.3.4" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc" - integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw== - - "@types/webpack-env@^1.16.0": - version "1.18.4" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.18.4.tgz#62879b0a9c653f9b1172d403b882f2045ecce032" - integrity sha512-I6e+9+HtWADAWeeJWDFQtdk4EVSAbj6Rtz4q8fJ7mSr1M0jzlFcs8/HZ+Xb5SHzVm1dxH7aUiI+A8kA8Gcrm0A== - - "@types/webpack-sources@*": - version "3.2.3" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.3.tgz#b667bd13e9fa15a9c26603dce502c7985418c3d8" - integrity sha512-4nZOdMwSPHZ4pTEZzSp0AsTM4K7Qmu40UKW4tJDiOVs20UzYF9l+qUe4s0ftfN0pin06n+5cWWDJXH+sbhAiDw== - dependencies: - "@types/node" "*" - "@types/source-list-map" "*" - source-map "^0.7.3" - - "@types/webpack@^4.41.26", "@types/webpack@^4.41.8": - version "4.41.38" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.38.tgz#5a40ac81bdd052bf405e8bdcf3e1236f6db6dc26" - integrity sha512-oOW7E931XJU1mVfCnxCVgv8GLFL768pDO5u2Gzk82i8yTIgX6i7cntyZOkZYb/JtYM8252SN9bQp9tgkVDSsRw== - dependencies: - "@types/node" "*" - "@types/tapable" "^1" - "@types/uglify-js" "*" - "@types/webpack-sources" "*" - anymatch "^3.0.0" - source-map "^0.6.0" - - "@types/ws@^8.5.5": - version "8.5.10" - resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.10.tgz#4acfb517970853fa6574a3a6886791d04a396787" - integrity sha512-vmQSUcfalpIq0R9q7uTo2lXs6eGIpt9wtnLdMv9LVpIjCA/+ufZRozlVoVelIYixx1ugCBKDhn89vnsEGOCx9A== - dependencies: - "@types/node" "*" - - "@types/yargs-parser@*": - version "21.0.3" - resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.3.tgz#815e30b786d2e8f0dcd85fd5bcf5e1a04d008f15" - integrity sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ== - - "@types/yargs@^15.0.0": - version "15.0.19" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.19.tgz#328fb89e46109ecbdb70c295d96ff2f46dfd01b9" - integrity sha512-2XUaGVmyQjgyAZldf0D0c14vvo/yv0MhQBSTJcejMMaitsn3nxCB6TmH4G0ZQf+uxROOa9mpanoSm8h6SG/1ZA== - dependencies: - "@types/yargs-parser" "*" - - "@types/yargs@^16.0.0": - version "16.0.9" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.9.tgz#ba506215e45f7707e6cbcaf386981155b7ab956e" - integrity sha512-tHhzvkFXZQeTECenFoRljLBYPZJ7jAVxqqtEI0qTLOmuultnFp4I9yKE17vTuhf7BkhCu7I4XuemPgikDVuYqA== - dependencies: - "@types/yargs-parser" "*" - - "@types/yargs@^17.0.8": - version "17.0.32" - resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-17.0.32.tgz#030774723a2f7faafebf645f4e5a48371dca6229" - integrity sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog== - dependencies: - "@types/yargs-parser" "*" - - "@types/zxcvbn@^4.4.1": - version "4.4.4" - resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.4.tgz#987f5fcd87e957097433c476c3a1c91a54f53131" - integrity sha512-Tuk4q7q0DnpzyJDI4aMeghGuFu2iS1QAdKpabn8JfbtfGmVDUgvZv1I7mEjP61Bvnp3ljKCC8BE6YYSTNxmvRQ== - - "@typescript-eslint/eslint-plugin@^5.13.0", "@typescript-eslint/eslint-plugin@^5.7.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.62.0.tgz#aeef0328d172b9e37d9bab6dbc13b87ed88977db" - integrity sha512-TiZzBSJja/LbhNPvk6yc0JrX9XqhQ0hdh6M2svYfsHGejaKFIAGd9MQ+ERIMzLGlN/kZoYIgdxFV0PuljTKXag== - dependencies: - "@eslint-community/regexpp" "^4.4.0" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/type-utils" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - graphemer "^1.4.0" - ignore "^5.2.0" - natural-compare-lite "^1.4.0" - semver "^7.3.7" - tsutils "^3.21.0" - - "@typescript-eslint/experimental-utils@^5.3.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/experimental-utils/-/experimental-utils-5.62.0.tgz#14559bf73383a308026b427a4a6129bae2146741" - integrity sha512-RTXpeB3eMkpoclG3ZHft6vG/Z30azNHuqY6wKPBHlVMZFuEvrtlEDe8gMqDb+SO+9hjC/pLekeSCryf9vMZlCw== - dependencies: - "@typescript-eslint/utils" "5.62.0" - - "@typescript-eslint/parser@^5.13.0", "@typescript-eslint/parser@^5.7.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.62.0.tgz#1b63d082d849a2fcae8a569248fbe2ee1b8a56c7" - integrity sha512-VlJEV0fOQ7BExOsHYAGrgbEiZoi8D+Bl2+f6V2RrXerRSylnp+ZBHmPvaIa8cz0Ajx7WO7Z5RqfgYg7ED1nRhA== - dependencies: - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - debug "^4.3.4" - - "@typescript-eslint/scope-manager@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.62.0.tgz#d9457ccc6a0b8d6b37d0eb252a23022478c5460c" - integrity sha512-VXuvVvZeQCQb5Zgf4HAxc04q5j+WrNAtNh9OwCsCgpKqESMTu3tF/jhZ3xG6T4NZwWl65Bg8KuS2uEvhSfLl0w== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - - "@typescript-eslint/type-utils@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz#286f0389c41681376cdad96b309cedd17d70346a" - integrity sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew== - dependencies: - "@typescript-eslint/typescript-estree" "5.62.0" - "@typescript-eslint/utils" "5.62.0" - debug "^4.3.4" - tsutils "^3.21.0" - - "@typescript-eslint/types@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.62.0.tgz#258607e60effa309f067608931c3df6fed41fd2f" - integrity sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ== - - "@typescript-eslint/typescript-estree@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz#7d17794b77fabcac615d6a48fb143330d962eb9b" - integrity sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA== - dependencies: - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/visitor-keys" "5.62.0" - debug "^4.3.4" - globby "^11.1.0" - is-glob "^4.0.3" - semver "^7.3.7" - tsutils "^3.21.0" - - "@typescript-eslint/utils@5.62.0", "@typescript-eslint/utils@^5.10.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.62.0.tgz#141e809c71636e4a75daa39faed2fb5f4b10df86" - integrity sha512-n8oxjeb5aIbPFEtmQxQYOLI0i9n5ySBEY/ZEHHZqKQSFnxio1rv6dthascc9dLuwrL0RC5mPCxB7vnAVGAYWAQ== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@types/json-schema" "^7.0.9" - "@types/semver" "^7.3.12" - "@typescript-eslint/scope-manager" "5.62.0" - "@typescript-eslint/types" "5.62.0" - "@typescript-eslint/typescript-estree" "5.62.0" - eslint-scope "^5.1.1" - semver "^7.3.7" - - "@typescript-eslint/visitor-keys@5.62.0": - version "5.62.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.62.0.tgz#2174011917ce582875954ffe2f6912d5931e353e" - integrity sha512-07ny+LHRzQXepkGg6w0mFY41fVUNBrL2Roj/++7V1txKugfjm/Ci/qSND03r2RhlJhJYMcTn9AhhSSqQp0Ysyw== - dependencies: - "@typescript-eslint/types" "5.62.0" - eslint-visitor-keys "^3.3.0" - - "@ungap/structured-clone@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" - integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== - - "@vanilla-extract/css@^1.14.0": - version "1.14.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/css/-/css-1.14.0.tgz#45fab9c04d893e3e363cf2cde7559d21233b7f63" - integrity sha512-rYfm7JciWZ8PFzBM/HDiE2GLnKI3xJ6/vdmVJ5BSgcCZ5CxRlM9Cjqclni9lGzF3eMOijnUhCd/KV8TOzyzbMA== - dependencies: - "@emotion/hash" "^0.9.0" - "@vanilla-extract/private" "^1.0.3" - chalk "^4.1.1" - css-what "^6.1.0" - cssesc "^3.0.0" - csstype "^3.0.7" - deep-object-diff "^1.1.9" - deepmerge "^4.2.2" - media-query-parser "^2.0.2" - modern-ahocorasick "^1.0.0" - outdent "^0.8.0" - - "@vanilla-extract/dynamic@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@vanilla-extract/dynamic/-/dynamic-2.1.0.tgz#316d3bd4adfd5f5c9fb080445c41d55abe3b463c" - integrity sha512-8zl0IgBYRtgD1h+56Zu13wHTiMTJSVEa4F7RWX9vTB/5Xe2KtjoiqApy/szHPVFA56c+ex6A4GpCQjT1bKXbYw== - dependencies: - "@vanilla-extract/private" "^1.0.3" - - "@vanilla-extract/private@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@vanilla-extract/private/-/private-1.0.3.tgz#7ec72bc2ff6fe51f9d650f962e8d1989b073690f" - integrity sha512-17kVyLq3ePTKOkveHxXuIJZtGYs+cSoev7BlP+Lf4916qfDhk/HBjvlYDe8egrea7LNPHKwSZJK/bzZC+Q6AwQ== - - "@vanilla-extract/recipes@^0.5.1": - version "0.5.1" - resolved "https://registry.yarnpkg.com/@vanilla-extract/recipes/-/recipes-0.5.1.tgz#617d1a0375af60835341770397810317d2f61998" - integrity sha512-7dCuBgPQQ/89siQ0w2lkfjgkmToPUUDzFlHf5DRmt9ykiiycfA52tmPJ2RI/mr7jXi7U/vEN2aGP9QJSXEpGlA== - - "@vitest/utils@^0.34.6": - version "0.34.6" - resolved "https://registry.yarnpkg.com/@vitest/utils/-/utils-0.34.6.tgz#38a0a7eedddb8e7291af09a2409cb8a189516968" - integrity sha512-IG5aDD8S6zlvloDsnzHw0Ut5xczlF+kv2BOTo+iXfPr54Yhi5qbVOgGB1hZaVq4iJ4C/MZ2J0y15IlsV/ZcI0A== - dependencies: - diff-sequences "^29.4.3" - loupe "^2.3.6" - pretty-format "^29.5.0" - - "@walletconnect/core@2.10.6": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.6.tgz#786b0d2e2045c210c917e29bfa0498bbc210be20" - integrity sha512-Z4vh4ZdfcoQjgPEOxeuF9HUZCVLtV3MgRbS/awLIj/omDrFnOwlBhxi5Syr4Y8muVGC0ocRetQYHae0/gX5crQ== - dependencies: - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-provider" "1.0.13" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/jsonrpc-ws-connection" "1.0.14" - "@walletconnect/keyvaluestorage" "^1.1.1" - "@walletconnect/logger" "^2.0.1" - "@walletconnect/relay-api" "^1.0.9" - "@walletconnect/relay-auth" "^1.0.4" - "@walletconnect/safe-json" "^1.0.2" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/utils" "2.10.6" - events "^3.3.0" - lodash.isequal "4.5.0" - uint8arrays "^3.1.0" - - "@walletconnect/environment@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" - integrity sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg== - dependencies: - tslib "1.14.1" - - "@walletconnect/events@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" - integrity sha512-NPTqaoi0oPBVNuLv7qPaJazmGHs5JGyO8eEAk5VGKmJzDR7AHzD4k6ilox5kxk1iwiOnFopBOOMLs86Oa76HpQ== - dependencies: - keyvaluestorage-interface "^1.0.0" - tslib "1.14.1" - - "@walletconnect/heartbeat@1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@walletconnect/heartbeat/-/heartbeat-1.2.1.tgz#afaa3a53232ae182d7c9cff41c1084472d8f32e9" - integrity sha512-yVzws616xsDLJxuG/28FqtZ5rzrTA4gUjdEMTbWB5Y8V1XHRmqq4efAxCw5ie7WjbXFSUyBHaWlMR+2/CpQC5Q== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/time" "^1.0.2" - tslib "1.14.1" - - "@walletconnect/jsonrpc-provider@1.0.13": - version "1.0.13" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" - integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== - dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.8" - "@walletconnect/safe-json" "^1.0.2" - tslib "1.14.1" - - "@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" - integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== - dependencies: - keyvaluestorage-interface "^1.0.0" - tslib "1.14.1" - - "@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" - integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== - dependencies: - "@walletconnect/environment" "^1.0.1" - "@walletconnect/jsonrpc-types" "^1.0.3" - tslib "1.14.1" - - "@walletconnect/jsonrpc-ws-connection@1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" - integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== - dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.6" - "@walletconnect/safe-json" "^1.0.2" - events "^3.3.0" - ws "^7.5.1" - - "@walletconnect/keyvaluestorage@^1.0.2", "@walletconnect/keyvaluestorage@^1.1.1": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" - integrity sha512-V7ZQq2+mSxAq7MrRqDxanTzu2RcElfK1PfNYiaVnJgJ7Q7G7hTVwF8voIBx92qsRyGHZihrwNPHuZd1aKkd0rA== - dependencies: - "@walletconnect/safe-json" "^1.0.1" - idb-keyval "^6.2.1" - unstorage "^1.9.0" - - "@walletconnect/logger@^2.0.1": - version "2.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/logger/-/logger-2.0.1.tgz#7f489b96e9a1ff6bf3e58f0fbd6d69718bf844a8" - integrity sha512-SsTKdsgWm+oDTBeNE/zHxxr5eJfZmE9/5yp/Ku+zJtcTAjELb3DXueWkDXmE9h8uHIbJzIb5wj5lPdzyrjT6hQ== - dependencies: - pino "7.11.0" - tslib "1.14.1" - - "@walletconnect/relay-api@^1.0.9": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" - integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== - dependencies: - "@walletconnect/jsonrpc-types" "^1.0.2" - tslib "1.14.1" - - "@walletconnect/relay-auth@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" - integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== - dependencies: - "@stablelib/ed25519" "^1.0.2" - "@stablelib/random" "^1.0.1" - "@walletconnect/safe-json" "^1.0.1" - "@walletconnect/time" "^1.0.2" - tslib "1.14.1" - uint8arrays "^3.0.0" - - "@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" - integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== - dependencies: - tslib "1.14.1" - - "@walletconnect/sign-client@^2.9.0": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.6.tgz#722d2c2844565e2826dce6a6d3a36c9b3ca1ea91" - integrity sha512-EvUWjaZBQu2yKnH5/5F2qzbuiIuUN9ZgrNKgvXkw5z1Dq5RJCks0S9/MFlKH/ZSGqXnLl7uAzBXtoX4sMgbCMA== - dependencies: - "@walletconnect/core" "2.10.6" - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/logger" "^2.0.1" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/utils" "2.10.6" - events "^3.3.0" - - "@walletconnect/time@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" - integrity sha512-uzdd9woDcJ1AaBZRhqy5rNC9laqWGErfc4dxA9a87mPdKOgWMD85mcFo9dIYIts/Jwocfwn07EC6EzclKubk/g== - dependencies: - tslib "1.14.1" - - "@walletconnect/types@2.10.4": - version "2.10.4" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.4.tgz#23f6e4bd785671812dc6ea96848a6bd7ea78f038" - integrity sha512-eQpOElyiwJp3tepuOS3TS9dXTl9jVVlrC3iVA8bytnbLagkAUxmiv/s7PyDFx+ndXwQVh8PFBkWg1oxGwgCSBA== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/keyvaluestorage" "^1.0.2" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - - "@walletconnect/types@2.10.6": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.6.tgz#d9920ed4fd0113e0addbda8e7e73a5176a3163fd" - integrity sha512-WgHfiTG1yakmxheaBRiXhUdEmgxwrvsAdOIWaMf/spvrzVKYh6sHI3oyEEky5qj5jjiMiyQBeB57QamzCotbcQ== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/keyvaluestorage" "^1.1.1" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - - "@walletconnect/utils@2.10.6", "@walletconnect/utils@^2.9.0": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.6.tgz#749b37d14e291e346862e7027ec7548463350226" - integrity sha512-oRsWWhN2+hi3aiDXrQEOfysz6FHQJGXLsNQPVt+WIBJplO6Szmdau9dbleD88u1iiT4GKPqE0R9FOYvvPm1H/w== - dependencies: - "@stablelib/chacha20poly1305" "1.0.1" - "@stablelib/hkdf" "1.0.1" - "@stablelib/random" "^1.0.2" - "@stablelib/sha256" "1.0.1" - "@stablelib/x25519" "^1.0.3" - "@walletconnect/relay-api" "^1.0.9" - "@walletconnect/safe-json" "^1.0.2" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/window-getters" "^1.0.1" - "@walletconnect/window-metadata" "^1.0.1" - detect-browser "5.3.0" - query-string "7.1.3" - uint8arrays "^3.1.0" - - "@walletconnect/window-getters@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" - integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== - dependencies: - tslib "1.14.1" - - "@walletconnect/window-metadata@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" - integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== - dependencies: - "@walletconnect/window-getters" "^1.0.1" - tslib "1.14.1" - - "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" - integrity sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q== - dependencies: - "@webassemblyjs/helper-numbers" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - - "@webassemblyjs/ast@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" - integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== - dependencies: - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" - - "@webassemblyjs/floating-point-hex-parser@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz#dacbcb95aff135c8260f77fa3b4c5fea600a6431" - integrity sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw== - - "@webassemblyjs/floating-point-hex-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" - integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== - - "@webassemblyjs/helper-api-error@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz#6132f68c4acd59dcd141c44b18cbebbd9f2fa768" - integrity sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q== - - "@webassemblyjs/helper-api-error@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" - integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== - - "@webassemblyjs/helper-buffer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz#b66d73c43e296fd5e88006f18524feb0f2c7c093" - integrity sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA== - - "@webassemblyjs/helper-buffer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" - integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== - - "@webassemblyjs/helper-code-frame@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" - integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== - dependencies: - "@webassemblyjs/wast-printer" "1.9.0" - - "@webassemblyjs/helper-fsm@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" - integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== - - "@webassemblyjs/helper-module-context@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" - integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== - dependencies: - "@webassemblyjs/ast" "1.9.0" - - "@webassemblyjs/helper-numbers@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz#cbce5e7e0c1bd32cf4905ae444ef64cea919f1b5" - integrity sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g== - dependencies: - "@webassemblyjs/floating-point-hex-parser" "1.11.6" - "@webassemblyjs/helper-api-error" "1.11.6" - "@xtuc/long" "4.2.2" - - "@webassemblyjs/helper-wasm-bytecode@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz#bb2ebdb3b83aa26d9baad4c46d4315283acd51e9" - integrity sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA== - - "@webassemblyjs/helper-wasm-bytecode@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" - integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== - - "@webassemblyjs/helper-wasm-section@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz#ff97f3863c55ee7f580fd5c41a381e9def4aa577" - integrity sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - - "@webassemblyjs/helper-wasm-section@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" - integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - - "@webassemblyjs/ieee754@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz#bb665c91d0b14fffceb0e38298c329af043c6e3a" - integrity sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg== - dependencies: - "@xtuc/ieee754" "^1.2.0" - - "@webassemblyjs/ieee754@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" - integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== - dependencies: - "@xtuc/ieee754" "^1.2.0" - - "@webassemblyjs/leb128@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.6.tgz#70e60e5e82f9ac81118bc25381a0b283893240d7" - integrity sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ== - dependencies: - "@xtuc/long" "4.2.2" - - "@webassemblyjs/leb128@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" - integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== - dependencies: - "@xtuc/long" "4.2.2" - - "@webassemblyjs/utf8@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" - integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== - - "@webassemblyjs/utf8@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" - integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== - - "@webassemblyjs/wasm-edit@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" - integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/helper-wasm-section" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-opt" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - "@webassemblyjs/wast-printer" "1.9.0" - - "@webassemblyjs/wasm-edit@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz#c72fa8220524c9b416249f3d94c2958dfe70ceab" - integrity sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/helper-wasm-bytecode" "1.11.6" - "@webassemblyjs/helper-wasm-section" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-opt" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - "@webassemblyjs/wast-printer" "1.11.6" - - "@webassemblyjs/wasm-gen@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz#fb5283e0e8b4551cc4e9c3c0d7184a65faf7c268" - integrity sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA== - dependencies: - "@webassemblyjs/ast" "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/wasm-gen@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" - integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - - "@webassemblyjs/wasm-opt@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz#d9a22d651248422ca498b09aa3232a81041487c2" - integrity sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@webassemblyjs/helper-buffer" "1.11.6" - "@webassemblyjs/wasm-gen" "1.11.6" - "@webassemblyjs/wasm-parser" "1.11.6" - - "@webassemblyjs/wasm-opt@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" - integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-buffer" "1.9.0" - "@webassemblyjs/wasm-gen" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - - "@webassemblyjs/wasm-parser@1.11.6", "@webassemblyjs/wasm-parser@^1.11.5": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz#bb85378c527df824004812bbdb784eea539174a1" - integrity sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@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/wasm-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" - integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-wasm-bytecode" "1.9.0" - "@webassemblyjs/ieee754" "1.9.0" - "@webassemblyjs/leb128" "1.9.0" - "@webassemblyjs/utf8" "1.9.0" - - "@webassemblyjs/wast-parser@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" - integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/floating-point-hex-parser" "1.9.0" - "@webassemblyjs/helper-api-error" "1.9.0" - "@webassemblyjs/helper-code-frame" "1.9.0" - "@webassemblyjs/helper-fsm" "1.9.0" - "@xtuc/long" "4.2.2" - - "@webassemblyjs/wast-printer@1.11.6": - version "1.11.6" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz#a7bf8dd7e362aeb1668ff43f35cb849f188eff20" - integrity sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A== - dependencies: - "@webassemblyjs/ast" "1.11.6" - "@xtuc/long" "4.2.2" - - "@webassemblyjs/wast-printer@1.9.0": - version "1.9.0" - resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" - integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/wast-parser" "1.9.0" - "@xtuc/long" "4.2.2" - - "@webpack-cli/configtest@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/configtest/-/configtest-1.2.0.tgz#7b20ce1c12533912c3b217ea68262365fa29a6f5" - integrity sha512-4FB8Tj6xyVkyqjj1OaTqCjXYULB9FMkqQ8yGrZjRDrYh0nOE+7Lhs45WioWQQMV+ceFlE368Ukhe6xdvJM9Egg== - - "@webpack-cli/info@^1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/info/-/info-1.5.0.tgz#6c78c13c5874852d6e2dd17f08a41f3fe4c261b1" - integrity sha512-e8tSXZpw2hPl2uMJY6fsMswaok5FdlGNRTktvFk2sD8RjH0hE2+XistawJx1vmKteh4NmGmNUrp+Tb2w+udPcQ== - dependencies: - envinfo "^7.7.3" - - "@webpack-cli/serve@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.7.0.tgz#e1993689ac42d2b16e9194376cfb6753f6254db1" - integrity sha512-oxnCNGj88fL+xzV+dacXs44HcDwf1ovs3AuEzvP7mqXw7fQntqIhQ1BRmynh4qEKQSSSRSWVyXRjmTbZIX9V2Q== - - "@xtuc/ieee754@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" - integrity sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA== - - "@xtuc/long@4.2.2": - version "4.2.2" - resolved "https://registry.yarnpkg.com/@xtuc/long/-/long-4.2.2.tgz#d291c6a4e97989b5c61d9acf396ae4fe133a718d" - integrity sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ== - - "@yarnpkg/lockfile@^1.1.0": - version "1.1.0" - resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" - integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== - - "@yarnpkg/parsers@3.0.0-rc.46": - version "3.0.0-rc.46" - resolved "https://registry.yarnpkg.com/@yarnpkg/parsers/-/parsers-3.0.0-rc.46.tgz#03f8363111efc0ea670e53b0282cd3ef62de4e01" - integrity sha512-aiATs7pSutzda/rq8fnuPwTglyVwjM22bNnK2ZgjrpAjQHSSl3lztd2f9evst1W/qnC58DRz7T7QndUDumAR4Q== - dependencies: - js-yaml "^3.10.0" - tslib "^2.4.0" - - "@zkochan/js-yaml@0.0.6": - version "0.0.6" - resolved "https://registry.yarnpkg.com/@zkochan/js-yaml/-/js-yaml-0.0.6.tgz#975f0b306e705e28b8068a07737fa46d3fc04826" - integrity sha512-nzvgl3VfhcELQ8LyVrYOru+UtAy1nrygk2+AGbTm8a5YcO6o8lSjAT+pfg3vJWxIoZKOUhrK6UU7xW/+00kQrg== - dependencies: - argparse "^2.0.1" - - JSONStream@^1.3.5: - version "1.3.5" - resolved "https://registry.yarnpkg.com/JSONStream/-/JSONStream-1.3.5.tgz#3208c1f08d3a4d99261ab64f92302bc15e111ca0" - integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== - dependencies: - jsonparse "^1.2.0" - through ">=2.2.7 <3" - - abab@^2.0.3, abab@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.6.tgz#41b80f2c871d19686216b82309231cfd3cb3d291" - integrity sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA== - - abbrev@1, abbrev@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" - integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== - - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" - integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== - dependencies: - mime-types "~2.1.34" - negotiator "0.6.3" - - acorn-globals@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-6.0.0.tgz#46cdd39f0f8ff08a876619b55f5ac8a6dc770b45" - integrity sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg== - dependencies: - acorn "^7.1.1" - acorn-walk "^7.1.1" - - acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== - - acorn-jsx@^5.0.0, acorn-jsx@^5.3.1, acorn-jsx@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" - integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== - - acorn-walk@^7.1.1, acorn-walk@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" - integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== - - acorn-walk@^8.1.1: - version "8.3.0" - resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.3.0.tgz#2097665af50fd0cf7a2dfccd2b9368964e66540f" - integrity sha512-FS7hV565M5l1R08MXqo8odwMTB02C2UqzB17RVgu9EyuYFBqJZ3/ZY97sQD5FewVu1UyDFc1yztUDrAwT0EypA== - - acorn@^6.4.1: - version "6.4.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" - integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== - - acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: - version "7.4.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" - integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== - - acorn@^8.0.0, acorn@^8.10.0, acorn@^8.2.4, acorn@^8.4.1, acorn@^8.7.1, acorn@^8.8.2, acorn@^8.9.0: - version "8.11.2" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.11.2.tgz#ca0d78b51895be5390a5903c5b3bdcdaf78ae40b" - integrity sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w== - - add-stream@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa" - integrity sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ== - - address@^1.0.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/address/-/address-1.2.2.tgz#2b5248dac5485a6390532c6a517fda2e3faac89e" - integrity sha512-4B/qKCfeE/ODUaAUpSwfzazo5x29WD4r3vXiWsB7I2mSDAihwEqKO+g8GELZUQSSAo5e1XTYh3ZVfLyxBc12nA== - - agent-base@6, agent-base@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-6.0.2.tgz#49fff58577cfee3f37176feab4c22e00f86d7f77" - integrity sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ== - dependencies: - debug "4" - - agentkeepalive@^4.2.1: - version "4.5.0" - resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.5.0.tgz#2673ad1389b3c418c5a20c5d7364f93ca04be923" - integrity sha512-5GG/5IbQQpC9FpkRGsSvZI5QYeSCzlJHdpBQntCsuTOxhKD8lqKhrleg2Yi7yvMIf82Ycmmqln9U8V9qwEiJew== - dependencies: - humanize-ms "^1.2.1" - - aggregate-error@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" - integrity sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA== - dependencies: - clean-stack "^2.0.0" - indent-string "^4.0.0" - - airbnb-js-shims@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" - integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== - dependencies: - array-includes "^3.0.3" - array.prototype.flat "^1.2.1" - array.prototype.flatmap "^1.2.1" - es5-shim "^4.5.13" - es6-shim "^0.35.5" - function.prototype.name "^1.1.0" - globalthis "^1.0.0" - object.entries "^1.1.0" - object.fromentries "^2.0.0 || ^1.0.0" - object.getownpropertydescriptors "^2.0.3" - object.values "^1.1.0" - promise.allsettled "^1.0.0" - promise.prototype.finally "^3.1.0" - string.prototype.matchall "^4.0.0 || ^3.0.1" - string.prototype.padend "^3.0.0" - string.prototype.padstart "^3.0.0" - symbol.prototype.description "^1.0.0" - - ajv-errors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" - integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== - - ajv-formats@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" - integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== - dependencies: - ajv "^8.0.0" - - ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" - integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== - - ajv-keywords@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" - integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== - dependencies: - fast-deep-equal "^3.1.3" - - ajv@^6.1.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.4, ajv@^6.12.5: - version "6.12.6" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" - 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" - - ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.12.0.tgz#d1a0527323e22f53562c567c00991577dfbe19d1" - 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" - - animejs@^3.2.1: - version "3.2.2" - resolved "https://registry.yarnpkg.com/animejs/-/animejs-3.2.2.tgz#59be98c58834339d5847f4a70ddba74ac75b6afc" - integrity sha512-Ao95qWLpDPXXM+WrmwcKbl6uNlC5tjnowlaRYtuVDHHoygjtIPfDUoK9NthrlZsQSKjZXlmji2TrBUAVbiH0LQ== - - ansi-align@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" - integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== - dependencies: - string-width "^4.1.0" - - ansi-colors@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" - integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== - - ansi-colors@^3.0.0: - version "3.2.4" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" - integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== - - ansi-colors@^4.1.1: - version "4.1.3" - resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" - integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== - - ansi-escapes@^4.2.1: - version "4.3.2" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" - integrity sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ== - dependencies: - type-fest "^0.21.3" - - ansi-html-community@0.0.8, ansi-html-community@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" - integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== - - ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - - ansi-regex@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" - integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== - - ansi-regex@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.0.1.tgz#3183e38fae9a65d7cb5e53945cd5897d0260a06a" - integrity sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA== - - ansi-styles@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" - integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== - dependencies: - color-convert "^1.9.0" - - ansi-styles@^4.0.0, ansi-styles@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937" - integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg== - dependencies: - color-convert "^2.0.1" - - ansi-styles@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" - integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== - - ansi-styles@^6.1.0: - version "6.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" - integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== - - ansi-to-html@^0.6.11: - version "0.6.15" - resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" - integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== - dependencies: - entities "^2.0.0" - - anymatch@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" - integrity sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw== - dependencies: - micromatch "^3.1.4" - normalize-path "^2.1.1" - - anymatch@^3.0.0, anymatch@^3.0.3, anymatch@^3.1.3, anymatch@~3.1.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" - integrity sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw== - dependencies: - normalize-path "^3.0.0" - picomatch "^2.0.4" - - app-root-dir@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" - integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== - - "aproba@^1.0.3 || ^2.0.0": - version "2.0.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" - integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== - - aproba@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" - integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== - - arch@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" - integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== - - are-we-there-yet@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" - integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - - are-we-there-yet@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.1.tgz#679df222b278c64f2cdba1175cdc00b0d96164bd" - integrity sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg== - dependencies: - delegates "^1.0.0" - readable-stream "^3.6.0" - - arg@^4.1.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" - integrity sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA== - - argparse@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" - integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== - dependencies: - sprintf-js "~1.0.2" - - argparse@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" - integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== - - aria-query@5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.1.3.tgz#19db27cd101152773631396f7a95a3b58c22c35e" - integrity sha512-R5iJ5lkuHybztUfuOAznmboyjWq8O6sqNqtK7CLOqdydi54VNbORp49mb14KbWgG1QD3JFO9hJdZ+y4KutfdOQ== - dependencies: - deep-equal "^2.0.5" - - aria-query@^5.0.0, aria-query@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.3.0.tgz#650c569e41ad90b51b3d7df5e5eed1c7549c103e" - integrity sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A== - dependencies: - dequal "^2.0.3" - - arr-diff@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== - - arr-flatten@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - - arr-union@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== - - array-buffer-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz#fabe8bc193fea865f317fe7807085ee0dee5aead" - integrity sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A== - dependencies: - call-bind "^1.0.2" - is-array-buffer "^3.0.1" - - array-differ@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-3.0.0.tgz#3cbb3d0f316810eafcc47624734237d6aee4ae6b" - integrity sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg== - - array-find-index@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" - integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== - - array-flatten@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" - integrity sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg== - - array-flatten@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" - integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== - - array-ify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/array-ify/-/array-ify-1.0.0.tgz#9e528762b4a9066ad163a6962a364418e9626ece" - integrity sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng== - - array-includes@^3.0.3, array-includes@^3.1.6, array-includes@^3.1.7: - version "3.1.7" - resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.7.tgz#8cd2e01b26f7a3086cbc87271593fe921c62abda" - integrity sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-string "^1.0.7" - - array-union@^1.0.1, array-union@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" - integrity sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng== - dependencies: - array-uniq "^1.0.1" - - array-union@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" - integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== - - array-uniq@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" - integrity sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q== - - array-unique@^0.3.2: - version "0.3.2" - resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== - - array.prototype.findlastindex@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz#b37598438f97b579166940814e2c0493a4f50207" - integrity sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - - array.prototype.flat@^1.2.1, array.prototype.flat@^1.3.1, array.prototype.flat@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz#1476217df8cff17d72ee8f3ba06738db5b387d18" - integrity sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - - array.prototype.flatmap@^1.2.1, array.prototype.flatmap@^1.3.1, array.prototype.flatmap@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz#c9a7c6831db8e719d6ce639190146c24bbd3e527" - integrity sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - - array.prototype.map@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.6.tgz#6a3d23f7192b2066eb97666ccc34118cb8163950" - integrity sha512-nK1psgF2cXqP3wSyCSq0Hc7zwNq3sfljQqaG27r/7a7ooNUnn5nGq6yYWyks9jMO5EoFQ0ax80hSg6oXSRNXaw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - - array.prototype.reduce@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.6.tgz#63149931808c5fc1e1354814923d92d45f7d96d5" - integrity sha512-UW+Mz8LG/sPSU8jRDCjVr6J/ZKAGpHfwrZ6kWTG5qCxIEiXdVshqGnu5vEZA8S1y6X4aCSbQZ0/EEsfvEvBiSg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-array-method-boxes-properly "^1.0.0" - is-string "^1.0.7" - - array.prototype.tosorted@^1.1.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.2.tgz#620eff7442503d66c799d95503f82b475745cefd" - integrity sha512-HuQCHOlk1Weat5jzStICBCd83NxiIMwqDg/dHEsoefabn/hJRj5pVdWcPUSpRrwhwxZOsQassMpgN/xRYFBMIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - get-intrinsic "^1.2.1" - - arraybuffer.prototype.slice@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz#98bd561953e3e74bb34938e77647179dfe6e9f12" - integrity sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - is-array-buffer "^3.0.2" - is-shared-array-buffer "^1.0.2" - - arrify@^1.0.0, arrify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" - integrity sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA== - - arrify@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" - integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== - - asn1.js@^5.2.0: - version "5.4.1" - resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" - integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== - dependencies: - bn.js "^4.0.0" - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - safer-buffer "^2.1.0" - - assert@^1.1.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.1.tgz#038ab248e4ff078e7bc2485ba6e6388466c78f76" - integrity sha512-zzw1uCAgLbsKwBfFc8CX78DDg+xZeBksSO3vwVIDDN5i94eOrPsSSyiVhmsSABFDM/OcpE2aagCat9dnWQLG1A== - dependencies: - object.assign "^4.1.4" - util "^0.10.4" - - assign-symbols@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== - - ast-types-flow@^0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.8.tgz#0a85e1c92695769ac13a428bb653e7538bea27d6" - integrity sha512-OH/2E5Fg20h2aPrbe+QL8JZQFko0YZaF+j4mnQ7BGhfavO7OpSLa8a0y9sBwomHdSbkhTS8TQNayBfnW5DwbvQ== - - ast-types@^0.14.2: - version "0.14.2" - resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.14.2.tgz#600b882df8583e3cd4f2df5fa20fa83759d4bdfd" - integrity sha512-O0yuUDnZeQDL+ncNGlJ78BiO4jnYI3bvMsD5prT0/nsgijG/LpNBIr63gTjVTNsiGkgQhiyCShTgxt8oXOrklA== - dependencies: - tslib "^2.0.1" - - astral-regex@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-2.0.0.tgz#483143c567aeed4785759c0865786dc77d7d2e31" - integrity sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ== - - astring@^1.8.0: - version "1.8.6" - resolved "https://registry.yarnpkg.com/astring/-/astring-1.8.6.tgz#2c9c157cf1739d67561c56ba896e6948f6b93731" - integrity sha512-ISvCdHdlTDlH5IpxQJIex7BWBywFWgjJSVdwst+/iQCoEYnyOaQ95+X1JGshuBjGp6nxKUy1jMgE3zPqN7fQdg== - - async-each@^1.0.1: - version "1.0.6" - resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.6.tgz#52f1d9403818c179b7561e11a5d1b77eb2160e77" - integrity sha512-c646jH1avxr+aVpndVMeAfYw7wAa6idufrlN3LPA4PmKS0QEGp6PIC9nwz0WQkkvBGAMEki3pFdtxaF39J9vvg== - - async@^3.2.3: - version "3.2.5" - resolved "https://registry.yarnpkg.com/async/-/async-3.2.5.tgz#ebd52a8fdaf7a2289a24df399f8d8485c8a46b66" - integrity sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg== - - asynciterator.prototype@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz#8c5df0514936cdd133604dfcc9d3fb93f09b2b62" - integrity sha512-wwHYEIS0Q80f5mosx3L/dfG5t5rjEa9Ft51GTaNt862EnpyGHpgz2RkZvLPp1oF5TnAiTohkEKVEu8pQPJI7Vg== - dependencies: - has-symbols "^1.0.3" - - asynckit@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" - integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q== - - at-least-node@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" - integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== - - atob@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" - integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== - - atomic-sleep@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/atomic-sleep/-/atomic-sleep-1.0.0.tgz#eb85b77a601fc932cfe432c5acd364a9e2c9075b" - integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== - - author-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/author-regex/-/author-regex-1.0.0.tgz#d08885be6b9bbf9439fe087c76287245f0a81450" - integrity sha512-KbWgR8wOYRAPekEmMXrYYdc7BRyhn2Ftk7KWfMUnQ43hFdojWEFRxhhRUm3/OFEdPa1r0KAvTTg9YQK57xTe0g== - - autoprefixer@^9.8.6: - version "9.8.8" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" - integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== - dependencies: - browserslist "^4.12.0" - caniuse-lite "^1.0.30001109" - normalize-range "^0.1.2" - num2fraction "^1.2.2" - picocolors "^0.2.1" - postcss "^7.0.32" - postcss-value-parser "^4.1.0" - - available-typed-arrays@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" - integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== - - axe-core@=4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.7.0.tgz#34ba5a48a8b564f67e103f0aa5768d76e15bbbbf" - integrity sha512-M0JtH+hlOL5pLQwHOLNYZaXuhqmvS8oExsqB1SBYgA4Dk7u/xx+YdGHXaK5pyUfed5mYXdlYiphWq3G8cRi5JQ== - - axios@^0.21.1, axios@^0.21.2: - version "0.21.4" - resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.4.tgz#c67b90dc0568e5c1cf2b0b858c43ba28e2eda575" - integrity sha512-ut5vewkiu8jjGBdqpM44XxjuCjq9LAKeHVmoVfHVzy8eHgxxq8SbAVQNovDA8mVi05kP0Ea/n/UzcSHcTJQfNg== - dependencies: - follow-redirects "^1.14.0" - - axios@^1.0.0, axios@^1.3.3, axios@^1.6.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2" - integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A== - dependencies: - follow-redirects "^1.15.0" - form-data "^4.0.0" - proxy-from-env "^1.1.0" - - axobject-query@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.2.1.tgz#39c378a6e3b06ca679f29138151e45b2b32da62a" - integrity sha512-jsyHu61e6N4Vbz/v18DHwWYKK0bSWLqn47eeDSKPB7m8tqMHF9YJ+mhIk2lVteyZrY8tnSj/jHOv4YiTCuCJgg== - dependencies: - dequal "^2.0.3" - - b4a@^1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/b4a/-/b4a-1.6.4.tgz#ef1c1422cae5ce6535ec191baeed7567443f36c9" - integrity sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw== - - babel-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-27.5.1.tgz#a1bf8d61928edfefd21da27eb86a695bfd691444" - integrity sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg== - dependencies: - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__core" "^7.1.14" - babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - slash "^3.0.0" - - babel-loader@^8.0.0, babel-loader@^8.2.3, babel-loader@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.3.0.tgz#124936e841ba4fe8176786d6ff28add1f134d6a8" - integrity sha512-H8SvsMF+m9t15HNLMipppzkC+Y2Yq+v3SonZyU70RBL/h1gxPkH08Ot8pEE9Z4Kd+czyWJClmFS8qzIP9OZ04Q== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^2.0.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - - babel-plugin-add-react-displayname@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/babel-plugin-add-react-displayname/-/babel-plugin-add-react-displayname-0.0.5.tgz#339d4cddb7b65fd62d1df9db9fe04de134122bd5" - integrity sha512-LY3+Y0XVDYcShHHorshrDbt4KFWL4bSeniCtl4SYZbask+Syngk1uMPCeN9+nSiZo6zX5s0RTq/J9Pnaaf/KHw== - - babel-plugin-apply-mdx-type-prop@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" - integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - "@mdx-js/util" "1.6.22" - - babel-plugin-extract-import-names@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" - integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== - dependencies: - "@babel/helper-plugin-utils" "7.10.4" - - babel-plugin-istanbul@^6.0.0, babel-plugin-istanbul@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" - integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@istanbuljs/load-nyc-config" "^1.0.0" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-instrument "^5.0.4" - test-exclude "^6.0.0" - - babel-plugin-jest-hoist@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz#9be98ecf28c331eb9f5df9c72d6f89deb8181c2e" - integrity sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ== - dependencies: - "@babel/template" "^7.3.3" - "@babel/types" "^7.3.3" - "@types/babel__core" "^7.0.0" - "@types/babel__traverse" "^7.0.6" - - babel-plugin-macros@^3.0.1, babel-plugin-macros@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" - integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== - dependencies: - "@babel/runtime" "^7.12.5" - cosmiconfig "^7.0.0" - resolve "^1.19.0" - - babel-plugin-named-exports-order@^0.0.2: - version "0.0.2" - resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" - integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== - - babel-plugin-polyfill-corejs2@^0.4.6: - version "0.4.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.4.6.tgz#b2df0251d8e99f229a8e60fc4efa9a68b41c8313" - integrity sha512-jhHiWVZIlnPbEUKSSNb9YoWcQGdlTLq7z1GHL4AjFxaoOUMuuEVJ+Y4pAaQUGOGk93YsVCKPbqbfw3m0SM6H8Q== - dependencies: - "@babel/compat-data" "^7.22.6" - "@babel/helper-define-polyfill-provider" "^0.4.3" - semver "^6.3.1" - - babel-plugin-polyfill-corejs3@^0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" - integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.1.5" - core-js-compat "^3.8.1" - - babel-plugin-polyfill-corejs3@^0.8.5: - version "0.8.6" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.8.6.tgz#25c2d20002da91fe328ff89095c85a391d6856cf" - integrity sha512-leDIc4l4tUgU7str5BWLS2h8q2N4Nf6lGZP6UrNDxdtfF2g69eJ5L0H7S8A5Ln/arfFAfHor5InAdZuIOwZdgQ== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - core-js-compat "^3.33.1" - - babel-plugin-polyfill-regenerator@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.5.3.tgz#d4c49e4b44614607c13fb769bcd85c72bb26a4a5" - integrity sha512-8sHeDOmXC8csczMrYEOf0UTNa4yE2SxV5JGeT/LP1n0OYVDUUFPxG9vdk2AlDlIit4t+Kf0xCtpgXPBwnn/9pw== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.4.3" - - babel-plugin-react-docgen@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-react-docgen/-/babel-plugin-react-docgen-4.2.1.tgz#7cc8e2f94e8dc057a06e953162f0810e4e72257b" - integrity sha512-UQ0NmGHj/HAqi5Bew8WvNfCk8wSsmdgNd8ZdMjBCICtyCJCq9LiqgqvjCYe570/Wg7AQArSq1VQ60Dd/CHN7mQ== - dependencies: - ast-types "^0.14.2" - lodash "^4.17.15" - react-docgen "^5.0.0" - - babel-plugin-root-import@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-5.1.0.tgz#80ea1cd5945b463a5e3f7e204a69478c573e328c" - integrity sha512-9VYUlnHtM7zjM9vM3kFClUDH7jjhqnvQwxWYGP18EciPsPZYZD9wGqVGwry6gQv0UdZS0+WmbPSlKSjKv1wZFw== - dependencies: - slash "^1.0.0" - - babel-plugin-root-import@^6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/babel-plugin-root-import/-/babel-plugin-root-import-6.6.0.tgz#85940840f308a8c292f66ca0b5bdd314046273ed" - integrity sha512-SPzVOHd7nDh5loZwZBxtX/oOu1MXeKjTkz+1VnnzLWC0dk8sJIGC2IDQ2uWIBjE5mUtXlQ35MTHSqN0Xn7qHrg== - dependencies: - slash "^3.0.0" - - babel-preset-current-node-syntax@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz#b4399239b89b2a011f9ddbe3e4f401fc40cff73b" - integrity sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ== - dependencies: - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-bigint" "^7.8.3" - "@babel/plugin-syntax-class-properties" "^7.8.3" - "@babel/plugin-syntax-import-meta" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.8.3" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.8.3" - "@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-top-level-await" "^7.8.3" - - babel-preset-jest@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz#91f10f58034cb7989cb4f962b69fa6eef6a6bc81" - integrity sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag== - dependencies: - babel-plugin-jest-hoist "^27.5.1" - babel-preset-current-node-syntax "^1.0.0" - - bail@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" - integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== - - bail@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/bail/-/bail-2.0.2.tgz#d26f5cd8fe5d6f832a31517b9f7c356040ba6d5d" - integrity sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw== - - balanced-match@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" - integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== - - base-x@^3.0.2, base-x@^3.0.6: - version "3.0.9" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320" - integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ== - dependencies: - safe-buffer "^5.0.1" - - base-x@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/base-x/-/base-x-4.0.0.tgz#d0e3b7753450c73f8ad2389b5c018a4af7b2224a" - integrity sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw== - - base64-js@^1.0.2, base64-js@^1.3.0, base64-js@^1.3.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" - integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== - - base@^0.11.1: - version "0.11.2" - resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" - integrity sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg== - dependencies: - cache-base "^1.0.1" - class-utils "^0.3.5" - component-emitter "^1.2.1" - define-property "^1.0.0" - isobject "^3.0.1" - mixin-deep "^1.2.0" - pascalcase "^0.1.1" - - batch@0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" - integrity sha512-x+VAiMRL6UPkx+kudNvxTl6hB2XNNCG2r+7wixVfIYwu/2HKRXimwQyaumLjMveWvT2Hkd/cAJw+QBMfJ/EKVw== - - bech32@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" - integrity sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ== - - before-after-hook@^2.2.0: - version "2.2.3" - resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.2.3.tgz#c51e809c81a4e354084422b9b26bad88249c517c" - integrity sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ== - - better-opn@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" - integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== - dependencies: - open "^7.0.3" - - big-integer@^1.6.48, big-integer@^1.6.7: - version "1.6.52" - resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.52.tgz#60a887f3047614a8e1bffe5d7173490a97dc8c85" - integrity sha512-QxD8cf2eVqJOOz63z6JIN9BzvVs/dlySa5HGSBH5xtR8dPteIRQnBxxKqkNTiT6jbDTF6jAfrd4oMcND9RGbQg== - - big.js@^5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" - integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== - - big.js@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/big.js/-/big.js-6.2.1.tgz#7205ce763efb17c2e41f26f121c420c6a7c2744f" - integrity sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ== - - bignumber.js@^9.1.1: - version "9.1.2" - resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.2.tgz#b7c4242259c008903b13707983b5f4bbd31eda0c" - integrity sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug== - - binary-extensions@^1.0.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" - integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== - - binary-extensions@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" - integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== - - bindings@^1.3.0, bindings@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" - integrity sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ== - dependencies: - file-uri-to-path "1.0.0" - - bip32@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" - integrity sha512-HpV5OMLLGTjSVblmrtYRfFFKuQB+GArM0+XP8HGWfJ5vxYBqo+DesvJwOdC2WJ3bCkZShGf0QIfoIpeomVzVdA== - dependencies: - "@types/node" "10.12.18" - bs58check "^2.1.1" - create-hash "^1.2.0" - create-hmac "^1.1.7" - tiny-secp256k1 "^1.1.3" - typeforce "^1.11.5" - wif "^2.0.6" - - bip39@^3.0.2, bip39@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" - integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== - dependencies: - "@noble/hashes" "^1.2.0" - - bl@^4.0.3, bl@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/bl/-/bl-4.1.0.tgz#451535264182bec2fbbc83a62ab98cf11d9f7b3a" - integrity sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w== - dependencies: - buffer "^5.5.0" - inherits "^2.0.4" - readable-stream "^3.4.0" - - bluebird@^3.5.5: - version "3.7.2" - resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" - integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== - - bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.8, bn.js@^4.11.9: - version "4.12.0" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" - integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== - - bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" - integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== - - body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== - dependencies: - bytes "3.1.2" - content-type "~1.0.4" - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - http-errors "2.0.0" - iconv-lite "0.4.24" - on-finished "2.4.1" - qs "6.11.0" - raw-body "2.5.1" - type-is "~1.6.18" - unpipe "1.0.0" - - bonjour-service@^1.0.11: - version "1.1.1" - resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.1.1.tgz#960948fa0e0153f5d26743ab15baf8e33752c135" - integrity sha512-Z/5lQRMOG9k7W+FkeGTNjh7htqn/2LMnfOvBZ8pynNZCM9MwkQkI3zeI4oz09uWdcgmgHugVvBqxGg4VQJ5PCg== - dependencies: - array-flatten "^2.1.2" - dns-equal "^1.0.0" - fast-deep-equal "^3.1.3" - multicast-dns "^7.2.5" - - boolbase@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e" - integrity sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww== - - bowser@2.11.0: - version "2.11.0" - resolved "https://registry.yarnpkg.com/bowser/-/bowser-2.11.0.tgz#5ca3c35757a7aa5771500c70a73a9f91ef420a8f" - integrity sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA== - - boxen@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" - integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== - 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" - - bplist-parser@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" - integrity sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q== - dependencies: - big-integer "^1.6.7" - - brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== - dependencies: - balanced-match "^1.0.0" - concat-map "0.0.1" - - brace-expansion@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" - integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== - dependencies: - balanced-match "^1.0.0" - - braces@^2.3.1, braces@^2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" - integrity sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w== - dependencies: - arr-flatten "^1.1.0" - array-unique "^0.3.2" - extend-shallow "^2.0.1" - fill-range "^4.0.0" - isobject "^3.0.1" - repeat-element "^1.1.2" - snapdragon "^0.8.1" - snapdragon-node "^2.0.1" - split-string "^3.0.2" - to-regex "^3.0.1" - - braces@^3.0.2, braces@~3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" - integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== - dependencies: - fill-range "^7.0.1" - - brorand@^1.0.1, brorand@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" - integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== - - browser-assert@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" - integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== - - browser-process-hrtime@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz#3c9b4b7d782c8121e56f10106d84c0d0ffc94626" - integrity sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow== - - browser-stdout@1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.1.tgz#baa559ee14ced73452229bad7326467c61fabd60" - integrity sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw== - - browserify-aes@^1.0.0, browserify-aes@^1.0.4: - version "1.2.0" - resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" - integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== - dependencies: - buffer-xor "^1.0.3" - cipher-base "^1.0.0" - create-hash "^1.1.0" - evp_bytestokey "^1.0.3" - inherits "^2.0.1" - safe-buffer "^5.0.1" - - browserify-cipher@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" - integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== - dependencies: - browserify-aes "^1.0.4" - browserify-des "^1.0.0" - evp_bytestokey "^1.0.0" - - browserify-des@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" - integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== - dependencies: - cipher-base "^1.0.1" - des.js "^1.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - - browserify-rsa@^4.0.0, browserify-rsa@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" - integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== - dependencies: - bn.js "^5.0.0" - randombytes "^2.0.1" - - browserify-sign@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.2.tgz#e78d4b69816d6e3dd1c747e64e9947f9ad79bc7e" - integrity sha512-1rudGyeYY42Dk6texmv7c4VcQ0EsvVbLwZkA+AQB7SxvXxmcD93jcHie8bzecJ+ChDlmAm2Qyu0+Ccg5uhZXCg== - dependencies: - bn.js "^5.2.1" - browserify-rsa "^4.1.0" - create-hash "^1.2.0" - create-hmac "^1.1.7" - elliptic "^6.5.4" - inherits "^2.0.4" - parse-asn1 "^5.1.6" - readable-stream "^3.6.2" - safe-buffer "^5.2.1" - - browserify-zlib@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" - integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== - dependencies: - pako "~1.0.5" - - browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.21.4, browserslist@^4.21.9, browserslist@^4.22.1: - version "4.22.1" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.22.1.tgz#ba91958d1a59b87dab6fed8dfbcb3da5e2e9c619" - integrity sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ== - dependencies: - caniuse-lite "^1.0.30001541" - electron-to-chromium "^1.4.535" - node-releases "^2.0.13" - update-browserslist-db "^1.0.13" - - bs-logger@0.x: - version "0.2.6" - resolved "https://registry.yarnpkg.com/bs-logger/-/bs-logger-0.2.6.tgz#eb7d365307a72cf974cc6cda76b68354ad336bd8" - integrity sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog== - dependencies: - fast-json-stable-stringify "2.x" - - bs58@^4.0.0, bs58@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" - integrity sha512-Ok3Wdf5vOIlBrgCvTq96gBkJw+JUEzdBgyaza5HLtPm7yTHkjRy8+JzNyHF7BHa0bNWOQIp3m5YF0nnFcOIKLw== - dependencies: - base-x "^3.0.2" - - bs58@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" - integrity sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ== - dependencies: - base-x "^4.0.0" - - bs58check@<3.0.0, bs58check@^2.1.1, bs58check@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.2.tgz#53b018291228d82a5aa08e7d796fdafda54aebfc" - integrity sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA== - dependencies: - bs58 "^4.0.0" - create-hash "^1.1.0" - safe-buffer "^5.1.2" - - bser@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" - integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== - dependencies: - node-int64 "^0.4.0" - - buffer-from@^1.0.0, buffer-from@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - - buffer-xor@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" - integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== - - buffer@^4.3.0: - version "4.9.2" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" - integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== - dependencies: - base64-js "^1.0.2" - ieee754 "^1.1.4" - isarray "^1.0.0" - - buffer@^5.5.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.7.1.tgz#ba62e7c13133053582197160851a8f648e99eed0" - integrity sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.1.13" - - buffer@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" - integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== - dependencies: - base64-js "^1.3.1" - ieee754 "^1.2.1" - - builtin-modules@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" - integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw== - - builtin-status-codes@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" - integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== - - builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ== - - builtins@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" - integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== - dependencies: - semver "^7.0.0" - - byte-size@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/byte-size/-/byte-size-8.1.1.tgz#3424608c62d59de5bfda05d31e0313c6174842ae" - integrity sha512-tUkzZWK0M/qdoLEqikxBWe4kumyuwjl3HO6zHTr4yEI23EojPtLYXdG1+AQY7MN0cGyNDvEaJ8wiYQm6P2bPxg== - - bytes@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" - integrity sha512-pMhOfFDPiv9t5jjIXkHosWmkSyQbvsgEVNkz0ERHbuLh2T/7j4Mqqpz523Fe8MVY89KC6Sh/QfS2sM+SjgFDcw== - - bytes@3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" - integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== - - c8@^7.6.0: - version "7.14.0" - resolved "https://registry.yarnpkg.com/c8/-/c8-7.14.0.tgz#f368184c73b125a80565e9ab2396ff0be4d732f3" - integrity sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw== - dependencies: - "@bcoe/v8-coverage" "^0.2.3" - "@istanbuljs/schema" "^0.1.3" - find-up "^5.0.0" - foreground-child "^2.0.0" - istanbul-lib-coverage "^3.2.0" - istanbul-lib-report "^3.0.0" - istanbul-reports "^3.1.4" - rimraf "^3.0.2" - test-exclude "^6.0.0" - v8-to-istanbul "^9.0.0" - yargs "^16.2.0" - yargs-parser "^20.2.9" - - cacache@^12.0.2: - version "12.0.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" - integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== - dependencies: - bluebird "^3.5.5" - chownr "^1.1.1" - figgy-pudding "^3.5.1" - glob "^7.1.4" - graceful-fs "^4.1.15" - infer-owner "^1.0.3" - lru-cache "^5.1.1" - mississippi "^3.0.0" - mkdirp "^0.5.1" - move-concurrently "^1.0.1" - promise-inflight "^1.0.1" - rimraf "^2.6.3" - ssri "^6.0.1" - unique-filename "^1.1.1" - y18n "^4.0.0" - - cacache@^15.0.5: - version "15.3.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" - integrity sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ== - dependencies: - "@npmcli/fs" "^1.0.0" - "@npmcli/move-file" "^1.0.1" - chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" - infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" - unique-filename "^1.1.1" - - cacache@^16.1.0: - version "16.1.3" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.3.tgz#a02b9f34ecfaf9a78c9f4bc16fceb94d5d67a38e" - integrity sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ== - dependencies: - "@npmcli/fs" "^2.1.0" - "@npmcli/move-file" "^2.0.0" - chownr "^2.0.0" - fs-minipass "^2.1.0" - glob "^8.0.1" - infer-owner "^1.0.4" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - mkdirp "^1.0.4" - p-map "^4.0.0" - promise-inflight "^1.0.1" - rimraf "^3.0.2" - ssri "^9.0.0" - tar "^6.1.11" - unique-filename "^2.0.0" - - cacache@^17.0.0: - version "17.1.4" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-17.1.4.tgz#b3ff381580b47e85c6e64f801101508e26604b35" - integrity sha512-/aJwG2l3ZMJ1xNAnqbMpA40of9dj/pIH3QfiuQSqjfPJF747VR0J/bHn+/KdNnHKc6XQcWt/AfRSBft82W1d2A== - dependencies: - "@npmcli/fs" "^3.1.0" - fs-minipass "^3.0.0" - glob "^10.2.2" - lru-cache "^7.7.1" - minipass "^7.0.3" - minipass-collect "^1.0.2" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - p-map "^4.0.0" - ssri "^10.0.0" - tar "^6.1.11" - unique-filename "^3.0.0" - - cache-base@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" - integrity sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ== - dependencies: - collection-visit "^1.0.0" - component-emitter "^1.2.1" - get-value "^2.0.6" - has-value "^1.0.0" - isobject "^3.0.1" - set-value "^2.0.0" - to-object-path "^0.3.0" - union-value "^1.0.0" - unset-value "^1.0.0" - - call-bind@^1.0.0, call-bind@^1.0.2, call-bind@^1.0.4, call-bind@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/call-bind/-/call-bind-1.0.5.tgz#6fa2b7845ce0ea49bf4d8b9ef64727a2c2e2e513" - integrity sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ== - dependencies: - function-bind "^1.1.2" - get-intrinsic "^1.2.1" - set-function-length "^1.1.1" - - call-me-maybe@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.2.tgz#03f964f19522ba643b1b0693acb9152fe2074baa" - integrity sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ== - - callsites@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" - integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== - - camel-case@^4.1.1, camel-case@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" - integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== - dependencies: - pascal-case "^3.1.2" - tslib "^2.0.3" - - camelcase-css@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" - integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== - - camelcase-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" - integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== - dependencies: - camelcase "^2.0.0" - map-obj "^1.0.0" - - camelcase-keys@^6.2.2: - version "6.2.2" - resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" - integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== - dependencies: - camelcase "^5.3.1" - map-obj "^4.0.0" - quick-lru "^4.0.1" - - camelcase@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" - integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== - - camelcase@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" - integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== - - camelcase@^6.0.0, camelcase@^6.2.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" - integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== - - caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" - - caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001541: - version "1.0.30001565" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001565.tgz#a528b253c8a2d95d2b415e11d8b9942acc100c4f" - integrity sha512-xrE//a3O7TP0vaJ8ikzkD2c2NgcVUvsEe2IvFTntV4Yd1Z9FVzh+gW+enX96L0psrbaFMcVcH2l90xNuGDWc8w== - - capture-exit@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" - integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== - dependencies: - rsvp "^4.8.4" - - case-sensitive-paths-webpack-plugin@^2.3.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" - integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== - - ccount@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" - integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== - - ccount@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" - integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== - - chain-registry@^1.19.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.20.0.tgz#1442a1d715a7ebf57781aeb185e3cbaa7b08196c" - integrity sha512-kBeQVdopECXasauhaA+HiJNSB0UpzNmxtv5AvIpJBAZc3nuM2wzPxaHAiPz1OG5ifYwMraOkvPNxwOnXd1nZzw== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.17.0" - - chalk@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.0.tgz#4e14870a618d9e2edd97dd8345fd9d9dc315646a" - integrity sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - - chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" - - chalk@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-3.0.0.tgz#3f73c2bf526591f574cc492c51e2456349f844e4" - integrity sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - - chalk@^4.0.0, chalk@^4.0.2, chalk@^4.1.0, chalk@^4.1.1, chalk@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - - char-regex@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/char-regex/-/char-regex-1.0.2.tgz#d744358226217f981ed58f479b1d6bcc29545dcf" - integrity sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw== - - character-entities-html4@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/character-entities-html4/-/character-entities-html4-2.1.0.tgz#1f1adb940c971a4b22ba39ddca6b618dc6e56b2b" - integrity sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA== - - character-entities-legacy@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" - integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== - - character-entities-legacy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz#76bc83a90738901d7bc223a9e93759fdd560125b" - integrity sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ== - - character-entities@^1.0.0: - version "1.2.4" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" - integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== - - character-entities@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-2.0.2.tgz#2d09c2e72cd9523076ccb21157dff66ad43fcc22" - integrity sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ== - - character-reference-invalid@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" - integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== - - character-reference-invalid@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz#85c66b041e43b47210faf401278abf808ac45cb9" - integrity sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw== - - chardet@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" - integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== - - chokidar@3.5.3, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: - version "3.5.3" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" - integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== - dependencies: - anymatch "~3.1.2" - braces "~3.0.2" - glob-parent "~5.1.2" - is-binary-path "~2.1.0" - is-glob "~4.0.1" - normalize-path "~3.0.0" - readdirp "~3.6.0" - optionalDependencies: - fsevents "~2.3.2" - - chokidar@^2.1.8: - version "2.1.8" - resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" - integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== - dependencies: - anymatch "^2.0.0" - async-each "^1.0.1" - braces "^2.3.2" - glob-parent "^3.1.0" - inherits "^2.0.3" - is-binary-path "^1.0.0" - is-glob "^4.0.0" - normalize-path "^3.0.0" - path-is-absolute "^1.0.0" - readdirp "^2.2.1" - upath "^1.1.1" - optionalDependencies: - fsevents "^1.2.7" - - chownr@^1.1.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" - integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== - - chownr@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" - integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== - - chrome-trace-event@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" - integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== - - ci-info@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" - integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== - - ci-info@^3.2.0, ci-info@^3.6.1: - version "3.9.0" - resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.9.0.tgz#4279a62028a7b1f262f3473fc9605f5e218c59b4" - integrity sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ== - - cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" - integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - - citty@^0.1.3, citty@^0.1.4: - version "0.1.5" - resolved "https://registry.yarnpkg.com/citty/-/citty-0.1.5.tgz#fe37ceae5dc764af75eb2fece99d2bf527ea4e50" - integrity sha512-AS7n5NSc0OQVMV9v6wt3ByujNIrne0/cTjiC2MYqhvao57VNfiuVksTSr2p17nVOhEr2KtqiAkGwHcgMC/qUuQ== - dependencies: - consola "^3.2.3" - - cjs-module-lexer@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz#6c370ab19f8a3394e318fe682686ec0ac684d107" - integrity sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ== - - class-utils@^0.3.5: - version "0.3.6" - resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" - integrity sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg== - dependencies: - arr-union "^3.1.0" - define-property "^0.2.5" - isobject "^3.0.0" - static-extend "^0.1.1" - - classnames@^2.3.0: - version "2.3.2" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" - integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== - - clean-css@^4.2.3: - version "4.2.4" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" - integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== - dependencies: - source-map "~0.6.0" - - clean-css@^5.2.2: - version "5.3.3" - resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.3.tgz#b330653cd3bd6b75009cc25c714cae7b93351ccd" - integrity sha512-D5J+kHaVb/wKSFcyyV75uCn8fiY4sV38XJoe4CUyGQ+mOU/fMVYUdH1hJC+CJQ5uY3EnW27SbJYS4X8BiLrAFg== - dependencies: - source-map "~0.6.0" - - clean-stack@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" - integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== - - clean-webpack-plugin@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-4.0.0.tgz#72947d4403d452f38ed61a9ff0ada8122aacd729" - integrity sha512-WuWE1nyTNAyW5T7oNyys2EN0cfP2fdRxhxnIQWiAp0bMabPdHhoGxM8A6YL2GhqwgrPnnaemVE7nv5XJ2Fhh2w== - dependencies: - del "^4.1.1" - - cli-boxes@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" - integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== - - cli-cursor@3.1.0, cli-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" - integrity sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw== - dependencies: - restore-cursor "^3.1.0" - - cli-spinners@2.6.1: - version "2.6.1" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" - integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== - - cli-spinners@^2.5.0: - version "2.9.2" - resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.9.2.tgz#1773a8f4b9c4d6ac31563df53b3fc1d79462fe41" - integrity sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg== - - cli-table3@^0.6.1: - version "0.6.3" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.3.tgz#61ab765aac156b52f222954ffc607a6f01dbeeb2" - integrity sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg== - dependencies: - string-width "^4.2.0" - optionalDependencies: - "@colors/colors" "1.5.0" - - cli-width@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" - integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== - - client-only@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/client-only/-/client-only-0.0.1.tgz#38bba5d403c41ab150bff64a95c85013cf73bca1" - integrity sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA== - - clipboard-copy@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/clipboard-copy/-/clipboard-copy-3.2.0.tgz#3c5b8651d3512dcfad295d77a9eb09e7fac8d5fb" - integrity sha512-vooFaGFL6ulEP1liiaWFBmmfuPm3cY3y7T9eB83ZTnYc/oFeAKsq3NcDrOkBC8XaauEE8zHQwI7k0+JSYiVQSQ== - - clipboardy@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/clipboardy/-/clipboardy-3.0.0.tgz#f3876247404d334c9ed01b6f269c11d09a5e3092" - integrity sha512-Su+uU5sr1jkUy1sGRpLKjKrvEOVXgSgiSInwa/qeID6aJ07yh+5NWc3h2QfjHjBnfX4LhtFcuAWKUsJ3r+fjbg== - dependencies: - arch "^2.2.0" - execa "^5.1.1" - is-wsl "^2.2.0" - - cliui@^7.0.2: - version "7.0.4" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" - integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.0" - wrap-ansi "^7.0.0" - - cliui@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa" - integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ== - dependencies: - string-width "^4.2.0" - strip-ansi "^6.0.1" - wrap-ansi "^7.0.0" - - clone-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" - integrity sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g== - - clone-deep@4.0.1, clone-deep@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/clone-deep/-/clone-deep-4.0.1.tgz#c19fd9bdbbf85942b4fd979c84dcf7d5f07c2387" - integrity sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ== - dependencies: - is-plain-object "^2.0.4" - kind-of "^6.0.2" - shallow-clone "^3.0.0" - - clone-stats@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" - integrity sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag== - - clone@^1.0.2: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" - integrity sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg== - - clone@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f" - integrity sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w== - - cloneable-readable@^1.0.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.3.tgz#120a00cb053bfb63a222e709f9683ea2e11d8cec" - integrity sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ== - dependencies: - inherits "^2.0.1" - process-nextick-args "^2.0.0" - readable-stream "^2.3.5" - - clsx@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" - integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== - - clsx@^1.0.4, clsx@^1.1.0, clsx@^1.1.1, clsx@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" - integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== - - clsx@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-2.0.0.tgz#12658f3fd98fafe62075595a5c30e43d18f3d00b" - integrity sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q== - - cluster-key-slot@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" - integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== - - cmd-shim@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/cmd-shim/-/cmd-shim-6.0.1.tgz#a65878080548e1dca760b3aea1e21ed05194da9d" - integrity sha512-S9iI9y0nKR4hwEQsVWpyxld/6kRfGepGfzff83FcaiEBpmvlbA2nnGe7Cylgrx2f/p1P5S5wpRm9oL8z1PbS3Q== - - co@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" - integrity sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ== - - collapse-white-space@^1.0.2: - version "1.0.6" - resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" - integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== - - collect-v8-coverage@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz#c0b29bcd33bcd0779a1344c2136051e6afd3d9e9" - integrity sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q== - - collection-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== - dependencies: - map-visit "^1.0.0" - object-visit "^1.0.0" - - color-convert@^1.9.0: - version "1.9.3" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" - integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg== - dependencies: - color-name "1.1.3" - - color-convert@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" - integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== - dependencies: - color-name "~1.1.4" - - color-name@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" - integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw== - - color-name@^1.0.0, color-name@~1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" - integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== - - color-string@^1.9.0: - version "1.9.1" - resolved "https://registry.yarnpkg.com/color-string/-/color-string-1.9.1.tgz#4467f9146f036f855b764dfb5bf8582bf342c7a4" - integrity sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg== - dependencies: - color-name "^1.0.0" - simple-swizzle "^0.2.2" - - color-support@^1.1.2, color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - - color@^4.0.1, color@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/color/-/color-4.2.3.tgz#d781ecb5e57224ee43ea9627560107c0e0c6463a" - integrity sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A== - dependencies: - color-convert "^2.0.1" - color-string "^1.9.0" - - colord@^2.9.1: - version "2.9.3" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.9.3.tgz#4f8ce919de456f1d5c1c368c307fe20f3e59fb43" - integrity sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw== - - colorette@^1.2.2: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" - integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== - - colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.19: - version "2.0.20" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.20.tgz#9eb793e6833067f7235902fcd3b09917a000a95a" - integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== - - colornames@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/colornames/-/colornames-1.1.1.tgz#f8889030685c7c4ff9e2a559f5077eb76a816f96" - integrity sha512-/pyV40IrsdulWv+wFPmERh9k/mjsPZ64yUMDmWrtj/k1nmgrzzIENWKdaVKyBbvFdQWqkcaRxr+polCo3VMe7A== - - colors@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" - integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== - - columnify@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/columnify/-/columnify-1.6.0.tgz#6989531713c9008bb29735e61e37acf5bd553cf3" - integrity sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q== - dependencies: - strip-ansi "^6.0.1" - wcwidth "^1.0.0" - - combined-stream@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" - integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== - dependencies: - delayed-stream "~1.0.0" - - comma-separated-tokens@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" - integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== - - comma-separated-tokens@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz#4e89c9458acb61bc8fef19f4529973b2392839ee" - integrity sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg== - - commander@2, commander@^2.19.0, commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - - commander@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" - integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== - - commander@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" - integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== - - commander@^7.0.0, commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== - - commander@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" - integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== - - commander@^9.4.1: - version "9.5.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" - integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== - - common-path-prefix@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" - integrity sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w== - - commondir@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" - integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== - - compare-func@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/compare-func/-/compare-func-2.0.0.tgz#fb65e75edbddfd2e568554e8b5b05fff7a51fcb3" - integrity sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA== - dependencies: - array-ify "^1.0.0" - dot-prop "^5.1.0" - - component-emitter@^1.2.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.3.1.tgz#ef1d5796f7d93f135ee6fb684340b26403c97d17" - integrity sha512-T0+barUSQRTUQASh8bx02dl+DhF54GtIDY13Y3m9oWTklKbb3Wv974meRpeZ3lp1JpLVECWWNHC4vaG2XHXouQ== - - compressible@~2.0.16: - version "2.0.18" - resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.18.tgz#af53cca6b070d4c3c0750fbd77286a6d7cc46fba" - integrity sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg== - dependencies: - mime-db ">= 1.43.0 < 2" - - compression@^1.7.4: - version "1.7.4" - resolved "https://registry.yarnpkg.com/compression/-/compression-1.7.4.tgz#95523eff170ca57c29a0ca41e6fe131f41e5bb8f" - integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== - dependencies: - accepts "~1.3.5" - bytes "3.0.0" - compressible "~2.0.16" - debug "2.6.9" - on-headers "~1.0.2" - safe-buffer "5.1.2" - vary "~1.1.2" - - concat-map@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" - integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== - - concat-stream@^1.5.0: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^2.2.2" - typedarray "^0.0.6" - - concat-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" - integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== - dependencies: - buffer-from "^1.0.0" - inherits "^2.0.3" - readable-stream "^3.0.2" - typedarray "^0.0.6" - - confusing-browser-globals@^1.0.10: - version "1.0.11" - resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" - integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== - - connect-history-api-fallback@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-2.0.0.tgz#647264845251a0daf25b97ce87834cace0f5f1c8" - integrity sha512-U73+6lQFmfiNPrYbXqr6kZ1i1wiRqXnp2nhMsINseWXO8lDau0LGEffJ8kQi4EjLZympVgRdvqjAgiZ1tgzDDA== - - consola@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/consola/-/consola-3.2.3.tgz#0741857aa88cfa0d6fd53f1cff0375136e98502f" - integrity sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ== - - console-browserify@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" - integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== - - console-control-strings@^1.0.0, console-control-strings@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" - integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== - - constants-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" - integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== - - content-disposition@0.5.4: - version "0.5.4" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" - integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== - dependencies: - safe-buffer "5.2.1" - - content-type@~1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" - integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== - - conventional-changelog-angular@7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz#5eec8edbff15aa9b1680a8dcfbd53e2d7eb2ba7a" - integrity sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ== - dependencies: - compare-func "^2.0.0" - - conventional-changelog-core@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-core/-/conventional-changelog-core-5.0.1.tgz#3c331b155d5b9850f47b4760aeddfc983a92ad49" - integrity sha512-Rvi5pH+LvgsqGwZPZ3Cq/tz4ty7mjijhr3qR4m9IBXNbxGGYgTVVO+duXzz9aArmHxFtwZ+LRkrNIMDQzgoY4A== - dependencies: - add-stream "^1.0.0" - conventional-changelog-writer "^6.0.0" - conventional-commits-parser "^4.0.0" - dateformat "^3.0.3" - get-pkg-repo "^4.2.1" - git-raw-commits "^3.0.0" - git-remote-origin-url "^2.0.0" - git-semver-tags "^5.0.0" - normalize-package-data "^3.0.3" - read-pkg "^3.0.0" - read-pkg-up "^3.0.0" - - conventional-changelog-preset-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-3.0.0.tgz#14975ef759d22515d6eabae6396c2ae721d4c105" - integrity sha512-qy9XbdSLmVnwnvzEisjxdDiLA4OmV3o8db+Zdg4WiFw14fP3B6XNz98X0swPPpkTd/pc1K7+adKgEDM1JCUMiA== - - conventional-changelog-writer@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/conventional-changelog-writer/-/conventional-changelog-writer-6.0.1.tgz#d8d3bb5e1f6230caed969dcc762b1c368a8f7b01" - integrity sha512-359t9aHorPw+U+nHzUXHS5ZnPBOizRxfQsWT5ZDHBfvfxQOAik+yfuhKXG66CN5LEWPpMNnIMHUTCKeYNprvHQ== - dependencies: - conventional-commits-filter "^3.0.0" - dateformat "^3.0.3" - handlebars "^4.7.7" - json-stringify-safe "^5.0.1" - meow "^8.1.2" - semver "^7.0.0" - split "^1.0.1" - - conventional-commits-filter@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-filter/-/conventional-commits-filter-3.0.0.tgz#bf1113266151dd64c49cd269e3eb7d71d7015ee2" - integrity sha512-1ymej8b5LouPx9Ox0Dw/qAO2dVdfpRFq28e5Y0jJEU8ZrLdy0vOSkkIInwmxErFGhg6SALro60ZrwYFVTUDo4Q== - dependencies: - lodash.ismatch "^4.4.0" - modify-values "^1.0.1" - - conventional-commits-parser@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/conventional-commits-parser/-/conventional-commits-parser-4.0.0.tgz#02ae1178a381304839bce7cea9da5f1b549ae505" - integrity sha512-WRv5j1FsVM5FISJkoYMR6tPk07fkKT0UodruX4je86V4owk451yjXAKzKAPOs9l7y59E2viHUS9eQ+dfUA9NSg== - dependencies: - JSONStream "^1.3.5" - is-text-path "^1.0.1" - meow "^8.1.2" - split2 "^3.2.2" - - conventional-recommended-bump@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/conventional-recommended-bump/-/conventional-recommended-bump-7.0.1.tgz#ec01f6c7f5d0e2491c2d89488b0d757393392424" - integrity sha512-Ft79FF4SlOFvX4PkwFDRnaNiIVX7YbmqGU0RwccUaiGvgp3S0a8ipR2/Qxk31vclDNM+GSdJOVs2KrsUCjblVA== - dependencies: - concat-stream "^2.0.0" - conventional-changelog-preset-loader "^3.0.0" - conventional-commits-filter "^3.0.0" - conventional-commits-parser "^4.0.0" - git-raw-commits "^3.0.0" - git-semver-tags "^5.0.0" - meow "^8.1.2" - - convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.6.0, convert-source-map@^1.7.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f" - integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A== - - convert-source-map@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" - integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== - - cookie-es@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/cookie-es/-/cookie-es-1.0.0.tgz#4759684af168dfc54365b2c2dda0a8d7ee1e4865" - integrity sha512-mWYvfOLrfEc996hlKcdABeIiPHUPC6DM2QYZdGGOvhOTbA3tjm2eBwqlJpoFdjC89NI4Qt6h0Pu06Mp+1Pj5OQ== - - cookie-signature@1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" - integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== - - cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== - - copy-concurrently@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" - integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== - dependencies: - aproba "^1.1.1" - fs-write-stream-atomic "^1.0.8" - iferr "^0.1.5" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.0" - - copy-descriptor@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== - - copy-to-clipboard@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" - integrity sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA== - dependencies: - toggle-selection "^1.0.6" - - core-js-compat@^3.31.0, core-js-compat@^3.33.1, core-js-compat@^3.8.1: - version "3.33.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.33.3.tgz#ec678b772c5a2d8a7c60a91c3a81869aa704ae01" - integrity sha512-cNzGqFsh3Ot+529GIXacjTJ7kegdt5fPXxCBVS1G0iaZpuo/tBz399ymceLJveQhFFZ8qThHiP3fzuoQjKN2ow== - dependencies: - browserslist "^4.22.1" - - core-js-pure@^3.23.3: - version "3.33.3" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.33.3.tgz#cbf9180ac4c4653823d784862bfb5c77eac0bf98" - integrity sha512-taJ00IDOP+XYQEA2dAe4ESkmHt1fL8wzYDo3mRWQey8uO9UojlBFMneA65kMyxfYP7106c6LzWaq7/haDT6BCQ== - - core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: - version "3.33.3" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.33.3.tgz#3c644a323f0f533a0d360e9191e37f7fc059088d" - integrity sha512-lo0kOocUlLKmm6kv/FswQL8zbkH7mVsLJ/FULClOhv8WRVmKLVcs6XPNQAzstfeJTCHMyButEwG+z1kHxHoDZw== - - core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - - cosmiconfig@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" - integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== - dependencies: - "@types/parse-json" "^4.0.0" - import-fresh "^3.1.0" - parse-json "^5.0.0" - path-type "^4.0.0" - yaml "^1.7.2" - - cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.1.0.tgz#1443b9afa596b670082ea46cbd8f6a62b84635f6" - integrity sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA== - 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" - - cosmiconfig@^8.2.0: - version "8.3.6" - resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-8.3.6.tgz#060a2b871d66dba6c8538ea1118ba1ac16f5fae3" - integrity sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA== - dependencies: - import-fresh "^3.3.0" - js-yaml "^4.1.0" - parse-json "^5.2.0" - path-type "^4.0.0" - - cosmjs-types@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.4.1.tgz#3b2a53ba60d33159dd075596ce8267cfa7027063" - integrity sha512-I7E/cHkIgoJzMNQdFF0YVqPlaTqrqKHrskuSTIqlEyxfB5Lf3WKCajSXVK2yHOfOFfSux/RxEdpMzw/eO4DIog== - dependencies: - long "^4.0.0" - protobufjs "~6.11.2" - - cosmjs-types@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.5.2.tgz#2d42b354946f330dfb5c90a87fdc2a36f97b965d" - integrity sha512-zxCtIJj8v3Di7s39uN4LNcN3HIE1z0B9Z0SPE8ZNQR0oSzsuSe1ACgxoFkvhkS7WBasCAFcglS11G2hyfd5tPg== - dependencies: - long "^4.0.0" - protobufjs "~6.11.2" - - cosmjs-types@^0.9.0: - version "0.9.0" - resolved "https://registry.yarnpkg.com/cosmjs-types/-/cosmjs-types-0.9.0.tgz#c3bc482d28c7dfa25d1445093fdb2d9da1f6cfcc" - integrity sha512-MN/yUe6mkJwHnCFfsNPeCfXVhyxHYW6c/xDUzrSbBycYzw++XvWDMJArXp2pLdgD6FQ8DW79vkPjeNKVrXaHeQ== - - cp-file@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" - integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== - dependencies: - graceful-fs "^4.1.2" - make-dir "^3.0.0" - nested-error-stacks "^2.0.0" - p-event "^4.1.0" - - cpy@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" - integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== - dependencies: - arrify "^2.0.1" - cp-file "^7.0.0" - globby "^9.2.0" - has-glob "^1.0.0" - junk "^3.1.0" - nested-error-stacks "^2.1.0" - p-all "^2.1.0" - p-filter "^2.1.0" - p-map "^3.0.0" - - create-ecdh@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" - integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== - dependencies: - bn.js "^4.1.0" - elliptic "^6.5.3" - - create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" - integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== - dependencies: - cipher-base "^1.0.1" - inherits "^2.0.1" - md5.js "^1.3.4" - ripemd160 "^2.0.1" - sha.js "^2.4.0" - - create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" - integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== - dependencies: - cipher-base "^1.0.3" - create-hash "^1.1.0" - inherits "^2.0.1" - ripemd160 "^2.0.0" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - - create-require@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" - integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== - - cross-spawn@^6.0.0, cross-spawn@^6.0.5: - version "6.0.5" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" - integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== - dependencies: - nice-try "^1.0.4" - path-key "^2.0.1" - semver "^5.5.0" - shebang-command "^1.2.0" - which "^1.2.9" - - cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== - dependencies: - path-key "^3.1.0" - shebang-command "^2.0.0" - which "^2.0.1" - - crypto-browserify@^3.11.0: - version "3.12.0" - resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" - integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== - dependencies: - browserify-cipher "^1.0.0" - browserify-sign "^4.0.0" - create-ecdh "^4.0.0" - create-hash "^1.1.0" - create-hmac "^1.1.0" - diffie-hellman "^5.0.0" - inherits "^2.0.1" - pbkdf2 "^3.0.3" - public-encrypt "^4.0.0" - randombytes "^2.0.0" - randomfill "^1.0.3" - - crypto-js@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.2.0.tgz#4d931639ecdfd12ff80e8186dba6af2c2e856631" - integrity sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q== - - css-declaration-sorter@^6.3.1: - version "6.4.1" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.4.1.tgz#28beac7c20bad7f1775be3a7129d7eae409a3a71" - integrity sha512-rtdthzxKuyq6IzqX6jEcIzQF/YqccluefyCYheovBOLhFT/drQA9zj/UbRAa9J7C0o6EG6u3E6g+vKkay7/k3g== - - css-loader@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" - integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== - dependencies: - camelcase "^5.3.1" - cssesc "^3.0.0" - icss-utils "^4.1.1" - loader-utils "^1.2.3" - normalize-path "^3.0.0" - postcss "^7.0.32" - postcss-modules-extract-imports "^2.0.0" - postcss-modules-local-by-default "^3.0.2" - postcss-modules-scope "^2.2.0" - postcss-modules-values "^3.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^2.7.0" - semver "^6.3.0" - - css-loader@^5.0.1: - version "5.2.7" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" - integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== - dependencies: - icss-utils "^5.1.0" - loader-utils "^2.0.0" - postcss "^8.2.15" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.1.0" - schema-utils "^3.0.0" - semver "^7.3.5" - - css-loader@^6.7.3: - version "6.8.1" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.8.1.tgz#0f8f52699f60f5e679eab4ec0fcd68b8e8a50a88" - integrity sha512-xDAXtEVGlD0gJ07iclwWVkLoZOpEvAWaSyf6W18S2pOC//K8+qUDIx8IIT3D+HjnmkJPQeesOPv5aiUaJsCM2g== - dependencies: - icss-utils "^5.1.0" - postcss "^8.4.21" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.3" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - postcss-value-parser "^4.2.0" - semver "^7.3.8" - - css-minimizer-webpack-plugin@^3.0.2: - version "3.4.1" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz#ab78f781ced9181992fe7b6e4f3422e76429878f" - integrity sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q== - dependencies: - cssnano "^5.0.6" - jest-worker "^27.0.2" - postcss "^8.3.5" - schema-utils "^4.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - - css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - 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" - - css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - - css-vendor@^2.0.8: - version "2.0.8" - resolved "https://registry.yarnpkg.com/css-vendor/-/css-vendor-2.0.8.tgz#e47f91d3bd3117d49180a3c935e62e3d9f7f449d" - integrity sha512-x9Aq0XTInxrkuFeHKbYC7zWY8ai7qJ04Kxd9MnvbC1uO5DagxoHQjm4JvG+vCdXOoFtCjbL2XSZfxmoYa9uQVQ== - dependencies: - "@babel/runtime" "^7.8.3" - is-in-browser "^1.0.2" - - css-what@^6.0.1, css-what@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - - css.escape@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" - integrity sha512-YUifsXXuknHlUsmlgyY0PKzgPOr7/FjCePfHNt0jxm83wHZi44VDMQ7/fGNkjY3/jV1MC+1CmZbaHzugyeRtpg== - - cssesc@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" - integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== - - cssnano-preset-default@^5.2.14: - version "5.2.14" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.2.14.tgz#309def4f7b7e16d71ab2438052093330d9ab45d8" - 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" - - cssnano-utils@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-3.1.0.tgz#95684d08c91511edfc70d2636338ca37ef3a6861" - integrity sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA== - - cssnano@^5.0.6: - version "5.1.15" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.1.15.tgz#ded66b5480d5127fcb44dac12ea5a983755136bf" - integrity sha512-j+BKgDcLDQA+eDifLx0EO4XSA56b7uut3BQFH+wbSaSTuGLuiyTa/wbRYthUXX8LC9mLg+WWKe8h+qJuwTAbHw== - dependencies: - cssnano-preset-default "^5.2.14" - lilconfig "^2.0.3" - yaml "^1.10.2" - - csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - - cssom@^0.4.4: - version "0.4.4" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.4.4.tgz#5a66cf93d2d0b661d80bf6a44fb65f5c2e4e0a10" - integrity sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw== - - cssom@~0.3.6: - version "0.3.8" - resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" - integrity sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg== - - cssstyle@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-2.3.0.tgz#ff665a0ddbdc31864b09647f34163443d90b0852" - integrity sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A== - dependencies: - cssom "~0.3.6" - - csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b" - integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ== - - currently-unhandled@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" - integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== - dependencies: - array-find-index "^1.0.1" - - cyclist@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.2.tgz#673b5f233bf34d8e602b949429f8171d9121bea3" - integrity sha512-0sVXIohTfLqVIW3kb/0n6IiWF3Ifj5nm2XaSrLq2DI6fKIGa2fYAZdk917rUneaeLVpYfFcyXE2ft0fe3remsA== - - "d3-array@2 - 3", "d3-array@2.10.0 - 3", d3-array@^3.1.6: - version "3.2.4" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-3.2.4.tgz#15fec33b237f97ac5d7c986dc77da273a8ed0bb5" - integrity sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg== - dependencies: - internmap "1 - 2" - - d3-array@^2.5.0: - version "2.12.1" - resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-2.12.1.tgz#e20b41aafcdffdf5d50928004ececf815a465e81" - integrity sha512-B0ErZK/66mHtEsR1TkPEEkwdy+WDesimkM5gpZr5Dsg54BiTA5RXtYW5qTLIAcekaS9xfZrzBLF/OAkB3Qn1YQ== - dependencies: - internmap "^1.0.0" - - "d3-color@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-2.0.0.tgz#8d625cab42ed9b8f601a1760a389f7ea9189d62e" - integrity sha512-SPXi0TSKPD4g9tw0NMZFnR95XVgUZiBH+uUTqQuDu1OsE2zomHU7ho0FISciaPvosimixwHFl3WHLGabv6dDgQ== - - "d3-color@1 - 3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-3.1.0.tgz#395b2833dfac71507f12ac2f7af23bf819de24e2" - integrity sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA== - - "d3-dispatch@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-2.0.0.tgz#8a18e16f76dd3fcaef42163c97b926aa9b55e7cf" - integrity sha512-S/m2VsXI7gAti2pBoLClFFTMOO1HTtT0j99AuXLoGFKO6deHDdnv6ZGTxSTTUTgO1zVcv82fCOtDjYK4EECmWA== - - d3-drag@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-drag/-/d3-drag-2.0.0.tgz#9eaf046ce9ed1c25c88661911c1d5a4d8eb7ea6d" - integrity sha512-g9y9WbMnF5uqB9qKqwIIa/921RYWzlUDv9Jl1/yONQwxbOfszAWTCm8u7HOTgJgRDXiRZN56cHT9pd24dmXs8w== - dependencies: - d3-dispatch "1 - 2" - d3-selection "2" - - "d3-ease@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-2.0.0.tgz#fd1762bfca00dae4bacea504b1d628ff290ac563" - integrity sha512-68/n9JWarxXkOWMshcT5IcjbB+agblQUaIsbnXmrzejn2O82n3p2A9R2zEB9HIEFWKFwPAEDDN8gR0VdSAyyAQ== - - d3-ease@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-ease/-/d3-ease-3.0.1.tgz#9658ac38a2140d59d346160f1f6c30fda0bd12f4" - integrity sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w== - - "d3-format@1 - 3": - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-3.1.0.tgz#9260e23a28ea5cb109e93b21a06e24e2ebd55641" - integrity sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA== - - d3-geo@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-2.0.2.tgz#c065c1b71fe8c5f1be657e5f43d9bdd010383c40" - integrity sha512-8pM1WGMLGFuhq9S+FpPURxic+gKzjluCD/CHTuUF3mXMeiCo0i6R0tO1s4+GArRFde96SLcW/kOFRjoAosPsFA== - dependencies: - d3-array "^2.5.0" - - "d3-interpolate@1 - 2": - version "2.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-2.0.1.tgz#98be499cfb8a3b94d4ff616900501a64abc91163" - integrity sha512-c5UhwwTs/yybcmTpAVqwSFl6vrQ8JZJoT5F7xNFK9pymv5C0Ymcc9/LIJHtYIggg/yS9YHw8i8O8tgb9pupjeQ== - dependencies: - d3-color "1 - 2" - - "d3-interpolate@1.2.0 - 3", d3-interpolate@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-3.0.1.tgz#3c47aa5b32c5b3dfb56ef3fd4342078a632b400d" - integrity sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g== - dependencies: - d3-color "1 - 3" - - d3-path@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-path/-/d3-path-3.1.0.tgz#22df939032fb5a71ae8b1800d61ddb7851c42526" - integrity sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ== - - d3-scale@^4.0.0, d3-scale@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-4.0.2.tgz#82b38e8e8ff7080764f8dcec77bd4be393689396" - integrity sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ== - dependencies: - d3-array "2.10.0 - 3" - d3-format "1 - 3" - d3-interpolate "1.2.0 - 3" - d3-time "2.1.1 - 3" - d3-time-format "2 - 4" - - d3-selection@2, d3-selection@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-2.0.0.tgz#94a11638ea2141b7565f883780dabc7ef6a61066" - integrity sha512-XoGGqhLUN/W14NmaqcO/bb1nqjDAw5WtSYb2X8wiuQWvSZUsUVYsOSkOybUrNvcBjaywBdYPy03eXHMXjk9nZA== - - d3-shape@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/d3-shape/-/d3-shape-3.2.0.tgz#a1a839cbd9ba45f28674c69d7f855bcf91dfc6a5" - integrity sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA== - dependencies: - d3-path "^3.1.0" - - "d3-time-format@2 - 4": - version "4.1.0" - resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-4.1.0.tgz#7ab5257a5041d11ecb4fe70a5c7d16a195bb408a" - integrity sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg== - dependencies: - d3-time "1 - 3" - - "d3-time@1 - 3", "d3-time@2.1.1 - 3", d3-time@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-3.1.0.tgz#9310db56e992e3c0175e1ef385e545e48a9bb5c7" - integrity sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q== - dependencies: - d3-array "2 - 3" - - "d3-timer@1 - 2": - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-2.0.0.tgz#055edb1d170cfe31ab2da8968deee940b56623e6" - integrity sha512-TO4VLh0/420Y/9dO3+f9abDEFYeCUr2WZRlxJvbp4HPTQcSylXNiL6yZa9FIUvV1yRiFufl1bszTCLDqv9PWNA== - - d3-timer@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/d3-timer/-/d3-timer-3.0.1.tgz#6284d2a2708285b1abb7e201eda4380af35e63b0" - integrity sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA== - - d3-transition@2: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-transition/-/d3-transition-2.0.0.tgz#366ef70c22ef88d1e34105f507516991a291c94c" - integrity sha512-42ltAGgJesfQE3u9LuuBHNbGrI/AJjNL2OAUdclE70UE6Vy239GCBEYD38uBPoLeNsOhFStGpPI0BAOV+HMxog== - dependencies: - d3-color "1 - 2" - d3-dispatch "1 - 2" - d3-ease "1 - 2" - d3-interpolate "1 - 2" - d3-timer "1 - 2" - - d3-zoom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/d3-zoom/-/d3-zoom-2.0.0.tgz#f04d0afd05518becce879d04709c47ecd93fba54" - integrity sha512-fFg7aoaEm9/jf+qfstak0IYpnesZLiMX6GZvXtUSdv8RH2o4E2qeelgdU09eKS6wGuiGMfcnMI0nTIqWzRHGpw== - dependencies: - d3-dispatch "1 - 2" - d3-drag "2" - d3-interpolate "1 - 2" - d3-selection "2" - d3-transition "2" - - damerau-levenshtein@^1.0.8: - version "1.0.8" - resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz#b43d286ccbd36bc5b2f7ed41caf2d0aba1f8a6e7" - integrity sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA== - - dargs@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/dargs/-/dargs-7.0.0.tgz#04015c41de0bcb69ec84050f3d9be0caf8d6d5cc" - integrity sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg== - - data-urls@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" - integrity sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ== - dependencies: - abab "^2.0.3" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.0.0" - - date-fns@^2.24.0, date-fns@^2.28.0: - version "2.30.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0" - integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw== - dependencies: - "@babel/runtime" "^7.21.0" - - dateformat@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" - integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== - - debug@2.6.9, debug@^2.2.0, debug@^2.3.3: - version "2.6.9" - resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" - integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== - dependencies: - ms "2.0.0" - - debug@4, debug@4.3.4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: - version "4.3.4" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" - integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== - dependencies: - ms "2.1.2" - - debug@^3.0.0, debug@^3.2.7: - version "3.2.7" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" - integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== - dependencies: - ms "^2.1.1" - - decamelize-keys@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/decamelize-keys/-/decamelize-keys-1.1.1.tgz#04a2d523b2f18d80d0158a43b895d56dff8d19d8" - integrity sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg== - dependencies: - decamelize "^1.1.0" - map-obj "^1.0.0" - - decamelize@^1.1.0, decamelize@^1.1.2: - version "1.2.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" - integrity sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA== - - decamelize@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-4.0.0.tgz#aa472d7bf660eb15f3494efd531cab7f2a709837" - integrity sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ== - - decimal.js-light@^2.4.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/decimal.js-light/-/decimal.js-light-2.5.1.tgz#134fd32508f19e208f4fb2f8dac0d2626a867934" - integrity sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg== - - decimal.js@^10.2.1: - version "10.4.3" - resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.4.3.tgz#1044092884d245d1b7f65725fa4ad4c6f781cc23" - integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== - - decode-named-character-reference@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz#daabac9690874c394c81e4162a0304b35d824f0e" - integrity sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg== - dependencies: - character-entities "^2.0.0" - - decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" - integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== - - decompress-response@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-6.0.0.tgz#ca387612ddb7e104bd16d85aab00d5ecf09c66fc" - integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== - dependencies: - mimic-response "^3.1.0" - - dedent@0.7.0, dedent@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" - integrity sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA== - - deep-equal@^2.0.5: - version "2.2.3" - resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-2.2.3.tgz#af89dafb23a396c7da3e862abc0be27cf51d56e1" - integrity sha512-ZIwpnevOurS8bpT4192sqAowWM76JDKSHYzMLty3BZGSswgq6pBaH3DhCSW5xVAZICZyKdOBPjwww5wfgT/6PA== - dependencies: - array-buffer-byte-length "^1.0.0" - call-bind "^1.0.5" - es-get-iterator "^1.1.3" - get-intrinsic "^1.2.2" - is-arguments "^1.1.1" - is-array-buffer "^3.0.2" - is-date-object "^1.0.5" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - isarray "^2.0.5" - object-is "^1.1.5" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - side-channel "^1.0.4" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.13" - - deep-extend@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" - integrity sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA== - - deep-is@^0.1.3: - version "0.1.4" - resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" - integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== - - deep-object-diff@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/deep-object-diff/-/deep-object-diff-1.1.9.tgz#6df7ef035ad6a0caa44479c536ed7b02570f4595" - integrity sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA== - - deepmerge@^4.2.2: - version "4.3.1" - resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" - integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== - - default-browser-id@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-1.0.4.tgz#e59d09a5d157b828b876c26816e61c3d2a2c203a" - integrity sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw== - dependencies: - bplist-parser "^0.1.0" - meow "^3.1.0" - untildify "^2.0.0" - - default-gateway@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" - integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== - dependencies: - execa "^5.0.0" - - defaults@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/defaults/-/defaults-1.0.4.tgz#b0b02062c1e2aa62ff5d9528f0f98baa90978d7a" - integrity sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A== - dependencies: - clone "^1.0.2" - - define-data-property@^1.0.1, define-data-property@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/define-data-property/-/define-data-property-1.1.1.tgz#c35f7cd0ab09883480d12ac5cb213715587800b3" - integrity sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ== - dependencies: - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - - define-lazy-prop@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" - integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== - - define-properties@^1.1.2, define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" - integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== - dependencies: - define-data-property "^1.0.1" - has-property-descriptors "^1.0.0" - object-keys "^1.1.1" - - define-property@^0.2.5: - version "0.2.5" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== - dependencies: - is-descriptor "^0.1.0" - - define-property@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== - dependencies: - is-descriptor "^1.0.0" - - define-property@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" - integrity sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ== - dependencies: - is-descriptor "^1.0.2" - isobject "^3.0.1" - - defu@^6.1.2, defu@^6.1.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/defu/-/defu-6.1.3.tgz#6d7f56bc61668e844f9f593ace66fd67ef1205fd" - integrity sha512-Vy2wmG3NTkmHNg/kzpuvHhkqeIx3ODWqasgCRbKtbXEN0G+HpEEv9BtJLp7ZG1CZloFaC41Ah3ZFbq7aqCqMeQ== - - del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - - delay@^4.4.0: - version "4.4.1" - resolved "https://registry.yarnpkg.com/delay/-/delay-4.4.1.tgz#6e02d02946a1b6ab98b39262ced965acba2ac4d1" - integrity sha512-aL3AhqtfhOlT/3ai6sWXeqwnw63ATNpnUiN4HL7x9q+My5QtHlO3OIkasmug9LKzpheLdmUKGRKnYXYAS7FQkQ== - - delayed-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" - integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== - - delegates@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" - integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== - - denque@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/denque/-/denque-2.1.0.tgz#e93e1a6569fb5e66f16a3c2a2964617d349d6ab1" - integrity sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw== - - depd@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" - integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== - - depd@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" - integrity sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ== - - deprecation@^2.0.0: - version "2.3.1" - resolved "https://registry.yarnpkg.com/deprecation/-/deprecation-2.3.1.tgz#6368cbdb40abf3373b525ac87e4a260c3a700919" - integrity sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ== - - dequal@^2.0.0, dequal@^2.0.2, dequal@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/dequal/-/dequal-2.0.3.tgz#2644214f1997d39ed0ee0ece72335490a7ac67be" - integrity sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA== - - des.js@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.1.0.tgz#1d37f5766f3bbff4ee9638e871a8768c173b81da" - integrity sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg== - dependencies: - inherits "^2.0.1" - minimalistic-assert "^1.0.0" - - destr@^2.0.1, destr@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/destr/-/destr-2.0.2.tgz#8d3c0ee4ec0a76df54bc8b819bca215592a8c218" - integrity sha512-65AlobnZMiCET00KaFFjUefxDX0khFA/E4myqZ7a6Sq1yZtR8+FVIvilVX66vF2uobSumxooYZChiRPCKNqhmg== - - destroy@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" - integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== - - detab@2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" - integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== - dependencies: - repeat-string "^1.5.4" - - detect-browser@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" - integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== - - detect-indent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" - integrity sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g== - - detect-libc@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" - integrity sha512-pGjwhsmsp4kL2RTz08wcOlGN83otlqHeD/Z5T8GXZB+/YcpQ/dgo+lbU8ZsGxV0HIvqqxo9l7mqYwyYMD9bKDg== - - detect-libc@^2.0.0, detect-libc@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.2.tgz#8ccf2ba9315350e1241b88d0ac3b0e1fbd99605d" - integrity sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw== - - detect-newline@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" - integrity sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA== - - detect-node@^2.0.4: - version "2.1.0" - resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" - integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== - - detect-package-manager@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" - integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== - dependencies: - execa "^5.1.1" - - detect-port@^1.3.0: - version "1.5.1" - resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.5.1.tgz#451ca9b6eaf20451acb0799b8ab40dff7718727b" - integrity sha512-aBzdj76lueB6uUst5iAs7+0H/oOjqI5D16XUWxlWMIMROhcM0rfsNVk93zTngq1dDNpoXRr++Sus7ETAExppAQ== - dependencies: - address "^1.0.1" - debug "4" - - diacritics@1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/diacritics/-/diacritics-1.3.0.tgz#3efa87323ebb863e6696cebb0082d48ff3d6f7a1" - integrity sha512-wlwEkqcsaxvPJML+rDh/2iS824jbREk6DUMUKkEaSlxdYHeS43cClJtsWglvw2RfeXGm6ohKDqsXteJ5sP5enA== - - diff-sequences@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-27.5.1.tgz#eaecc0d327fd68c8d9672a1e64ab8dccb2ef5327" - integrity sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ== - - diff-sequences@^28.1.1: - version "28.1.1" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" - integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== - - diff-sequences@^29.4.3, diff-sequences@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.6.3.tgz#4deaf894d11407c51efc8418012f9e70b84ea921" - integrity sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q== - - diff@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.0.0.tgz#7ed6ad76d859d030787ec35855f5b1daf31d852b" - integrity sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w== - - diff@^3.1.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" - integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA== - - diff@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" - integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== - - diff@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/diff/-/diff-5.1.0.tgz#bc52d298c5ea8df9194800224445ed43ffc87e40" - integrity sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw== - - diffie-hellman@^5.0.0: - version "5.0.3" - resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" - integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== - dependencies: - bn.js "^4.1.0" - miller-rabin "^4.0.0" - randombytes "^2.0.0" - - dir-glob@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" - integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== - dependencies: - path-type "^3.0.0" - - dir-glob@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" - integrity sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA== - dependencies: - path-type "^4.0.0" - - dns-equal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" - integrity sha512-z+paD6YUQsk+AbGCEM4PrOXSss5gd66QfcVBFTKR/HpFL9jCqikS94HYwKww6fQyO7IxrIIyUu+g0Ka9tUS2Cg== - - dns-packet@^5.2.2: - version "5.6.1" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.6.1.tgz#ae888ad425a9d1478a0674256ab866de1012cf2f" - integrity sha512-l4gcSouhcgIKRvyy99RNVOgxXiicE+2jZoNmaNmZ6JXiGajBOJAesk1OBlJuM5k2c+eudGdLxDqXuPCKIj6kpw== - dependencies: - "@leichtgewicht/ip-codec" "^2.0.1" - - doctrine@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-2.1.0.tgz#5cd01fc101621b42c4cd7f5d1a66243716d3f39d" - integrity sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw== - dependencies: - esutils "^2.0.2" - - doctrine@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" - integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== - dependencies: - esutils "^2.0.2" - - dom-accessibility-api@^0.5.6, dom-accessibility-api@^0.5.9: - version "0.5.16" - resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz#5a7429e6066eb3664d911e33fb0e45de8eb08453" - integrity sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg== - - dom-converter@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" - integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== - dependencies: - utila "~0.4" - - dom-helpers@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-3.4.0.tgz#e9b369700f959f62ecde5a6babde4bccd9169af8" - integrity sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA== - dependencies: - "@babel/runtime" "^7.1.2" - - dom-helpers@^5.0.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.1.tgz#d9400536b2bf8225ad98fe052e029451ac40e902" - integrity sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - - dom-serializer@^1.0.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.4.1.tgz#de5d41b1aea290215dc45a6dae8adcf1d32e2d30" - integrity sha512-VHwB3KfrcOOkelEG2ZOfxqLZdfkil8PtJi4P8N2MMXucZq2yLp75ClViUlOVwyoHEDjYU433Aq+5zWP61+RGag== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.2.0" - entities "^2.0.0" - - dom-walk@^0.1.0: - version "0.1.2" - resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" - integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== - - domain-browser@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" - integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== - - domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" - integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== - - domexception@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/domexception/-/domexception-2.0.1.tgz#fb44aefba793e1574b0af6aed2801d057529f304" - integrity sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg== - dependencies: - webidl-conversions "^5.0.0" - - domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - - domutils@^2.5.2, domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - - dot-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" - integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - - dot-prop@^5.1.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.3.0.tgz#90ccce708cd9cd82cc4dc8c3ddd9abdd55b20e88" - integrity sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q== - dependencies: - is-obj "^2.0.0" - - dotenv-defaults@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dotenv-defaults/-/dotenv-defaults-2.0.2.tgz#6b3ec2e4319aafb70940abda72d3856770ee77ac" - integrity sha512-iOIzovWfsUHU91L5i8bJce3NYK5JXeAwH50Jh6+ARUdLiiGlYWfGw6UkzsYqaXZH/hjE/eCd/PlfM/qqyK0AMg== - dependencies: - dotenv "^8.2.0" - - dotenv-expand@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" - integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== - - dotenv-expand@~10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" - integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== - - dotenv-webpack@^7.0.3: - version "7.1.1" - resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-7.1.1.tgz#ee8a699e1d736fd8eb9363fbc7054cfff1bd9dbf" - integrity sha512-xw/19VqHDkXALtBOJAnnrSU/AZDIQRXczAmJyp0lZv6SH2aBLzUTl96W1MVryJZ7okZ+djZS4Gj4KlZ0xP7deA== - dependencies: - dotenv-defaults "^2.0.2" - - dotenv@^16.0.3, dotenv@~16.3.1: - version "16.3.1" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e" - integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ== - - dotenv@^8.0.0, dotenv@^8.2.0: - version "8.6.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" - integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== - - duplexer@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" - integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== - - duplexify@^3.4.2, duplexify@^3.6.0: - version "3.7.1" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" - integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== - dependencies: - end-of-stream "^1.0.0" - inherits "^2.0.1" - readable-stream "^2.0.0" - stream-shift "^1.0.0" - - duplexify@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" - integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== - dependencies: - end-of-stream "^1.4.1" - inherits "^2.0.3" - readable-stream "^3.1.1" - stream-shift "^1.0.0" - - eastasianwidth@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" - integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== - - ee-first@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" - integrity sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow== - - ejs@^3.1.7: - version "3.1.9" - resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.9.tgz#03c9e8777fe12686a9effcef22303ca3d8eeb361" - integrity sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ== - dependencies: - jake "^10.8.5" - - electron-to-chromium@^1.4.535: - version "1.4.598" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.598.tgz#aaf1f64286001915b59210158d21b6284e96acbc" - integrity sha512-0JnipX0scPUlwsptQVCZggoCpREv+IrVD3h0ZG+sldmK9L27tSV3QjV8+QdaA4qQTzDf3PluNS45YYJky1oASw== - - elliptic@^6.4.0, elliptic@^6.5.3, elliptic@^6.5.4: - version "6.5.4" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" - integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== - dependencies: - bn.js "^4.11.9" - brorand "^1.1.0" - hash.js "^1.0.0" - hmac-drbg "^1.0.1" - inherits "^2.0.4" - minimalistic-assert "^1.0.1" - minimalistic-crypto-utils "^1.0.1" - - emittery@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/emittery/-/emittery-0.8.1.tgz#bb23cc86d03b30aa75a7f734819dee2e1ba70860" - integrity sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg== - - emoji-regex@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" - integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== - - emoji-regex@^9.2.2: - version "9.2.2" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" - integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== - - emojis-list@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" - integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== - - encodeurl@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" - integrity sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w== - - encoding@^0.1.13: - version "0.1.13" - resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" - integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== - dependencies: - iconv-lite "^0.6.2" - - end-of-stream@^1.0.0, end-of-stream@^1.1.0, end-of-stream@^1.4.1: - version "1.4.4" - resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" - integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== - dependencies: - once "^1.4.0" - - endent@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/endent/-/endent-2.1.0.tgz#5aaba698fb569e5e18e69e1ff7a28ff35373cd88" - integrity sha512-r8VyPX7XL8U01Xgnb1CjZ3XV+z90cXIJ9JPE/R9SEC9vpw2P6CfsRPJmp20DppC5N7ZAMCmjYkJIa744Iyg96w== - dependencies: - dedent "^0.7.0" - fast-json-parse "^1.0.3" - objectorarray "^1.0.5" - - enhanced-resolve@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" - integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.5.0" - tapable "^1.0.0" - - enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0, enhanced-resolve@^5.7.0: - version "5.15.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz#1af946c7d93603eb88e9896cee4904dc012e9c35" - integrity sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg== - dependencies: - graceful-fs "^4.2.4" - tapable "^2.2.0" - - enquirer@^2.3.5: - version "2.4.1" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.4.1.tgz#93334b3fbd74fc7097b224ab4a8fb7e40bf4ae56" - integrity sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ== - dependencies: - ansi-colors "^4.1.1" - strip-ansi "^6.0.1" - - enquirer@~2.3.6: - version "2.3.6" - resolved "https://registry.yarnpkg.com/enquirer/-/enquirer-2.3.6.tgz#2a7fe5dd634a1e4125a975ec994ff5456dc3734d" - integrity sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg== - dependencies: - ansi-colors "^4.1.1" - - entities@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" - integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== - - entities@^4.4.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-4.5.0.tgz#5d268ea5e7113ec74c4d033b79ea5a35a488fb48" - integrity sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw== - - env-paths@^2.2.0: - version "2.2.1" - resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" - integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== - - envinfo@7.8.1: - version "7.8.1" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475" - integrity sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw== - - envinfo@^7.7.3: - version "7.11.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.11.0.tgz#c3793f44284a55ff8c82faf1ffd91bc6478ea01f" - integrity sha512-G9/6xF1FPbIw0TtalAMaVPpiq2aDEuKLXM314jPVAO9r2fo2a4BLqMNkmRS7O/xPPZ+COAhGIz3ETvHEV3eUcg== - - err-code@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" - integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== - - errno@^0.1.3, errno@~0.1.7: - version "0.1.8" - resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" - integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== - dependencies: - prr "~1.0.1" - - error-ex@^1.2.0, error-ex@^1.3.1: - version "1.3.2" - resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" - integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== - dependencies: - is-arrayish "^0.2.1" - - error-stack-parser@^2.0.6: - version "2.1.4" - resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.1.4.tgz#229cb01cdbfa84440bfa91876285b94680188286" - integrity sha512-Sk5V6wVazPhq5MhpO+AUxJn5x7XSXGl1R93Vn7i+zS15KDVxQijejNCrz8340/2bgLBjR9GtEG8ZVKONDjcqGQ== - dependencies: - stackframe "^1.3.4" - - es-abstract@^1.22.1: - version "1.22.3" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.22.3.tgz#48e79f5573198de6dee3589195727f4f74bc4f32" - integrity sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA== - dependencies: - array-buffer-byte-length "^1.0.0" - arraybuffer.prototype.slice "^1.0.2" - available-typed-arrays "^1.0.5" - call-bind "^1.0.5" - es-set-tostringtag "^2.0.1" - es-to-primitive "^1.2.1" - function.prototype.name "^1.1.6" - get-intrinsic "^1.2.2" - get-symbol-description "^1.0.0" - globalthis "^1.0.3" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - internal-slot "^1.0.5" - is-array-buffer "^3.0.2" - is-callable "^1.2.7" - is-negative-zero "^2.0.2" - is-regex "^1.1.4" - is-shared-array-buffer "^1.0.2" - is-string "^1.0.7" - is-typed-array "^1.1.12" - is-weakref "^1.0.2" - object-inspect "^1.13.1" - object-keys "^1.1.1" - object.assign "^4.1.4" - regexp.prototype.flags "^1.5.1" - safe-array-concat "^1.0.1" - safe-regex-test "^1.0.0" - string.prototype.trim "^1.2.8" - string.prototype.trimend "^1.0.7" - string.prototype.trimstart "^1.0.7" - typed-array-buffer "^1.0.0" - typed-array-byte-length "^1.0.0" - typed-array-byte-offset "^1.0.0" - typed-array-length "^1.0.4" - unbox-primitive "^1.0.2" - which-typed-array "^1.1.13" - - es-array-method-boxes-properly@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" - integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== - - es-get-iterator@^1.0.2, es-get-iterator@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.3.tgz#3ef87523c5d464d41084b2c3c9c214f1199763d6" - integrity sha512-sPZmqHBe6JIiTfN5q2pEi//TwxmAFHwj/XEuYjTuse78i8KxaqMTTzxPoFKuzRpDpTJ+0NAbpfenkmH2rePtuw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - has-symbols "^1.0.3" - is-arguments "^1.1.1" - is-map "^2.0.2" - is-set "^2.0.2" - is-string "^1.0.7" - isarray "^2.0.5" - stop-iteration-iterator "^1.0.0" - - es-iterator-helpers@^1.0.12, es-iterator-helpers@^1.0.15: - version "1.0.15" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.15.tgz#bd81d275ac766431d19305923707c3efd9f1ae40" - integrity sha512-GhoY8uYqd6iwUl2kgjTm4CZAf6oo5mHK7BPqx3rKgx893YSsy0LGHV6gfqqQvZt/8xM8xeOnfXBCfqclMKkJ5g== - dependencies: - asynciterator.prototype "^1.0.0" - call-bind "^1.0.2" - define-properties "^1.2.1" - es-abstract "^1.22.1" - es-set-tostringtag "^2.0.1" - function-bind "^1.1.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - has-property-descriptors "^1.0.0" - has-proto "^1.0.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - iterator.prototype "^1.1.2" - safe-array-concat "^1.0.1" - - es-module-lexer@^1.2.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-1.4.1.tgz#41ea21b43908fe6a287ffcbe4300f790555331f5" - integrity sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w== - - es-set-tostringtag@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz#11f7cc9f63376930a5f20be4915834f4bc74f9c9" - integrity sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q== - dependencies: - get-intrinsic "^1.2.2" - has-tostringtag "^1.0.0" - hasown "^2.0.0" - - es-shim-unscopables@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz#1f6942e71ecc7835ed1c8a83006d8771a63a3763" - integrity sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw== - dependencies: - hasown "^2.0.0" - - es-to-primitive@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" - integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== - dependencies: - is-callable "^1.1.4" - is-date-object "^1.0.1" - is-symbol "^1.0.2" - - es5-shim@^4.5.13: - version "4.6.7" - resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" - integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== - - es6-shim@^0.35.5: - version "0.35.8" - resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.8.tgz#89216f6fbf8bacba3f897c8c0e814d2a41c05fb7" - integrity sha512-Twf7I2v4/1tLoIXMT8HlqaBSS5H2wQTs2wx3MNYCI8K1R1/clXyCazrcVCPm/FuO9cyV8+leEaZOWD5C253NDg== - - escalade@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" - integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== - - escape-html@^1.0.3, escape-html@~1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" - integrity sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow== - - escape-string-regexp@4.0.0, escape-string-regexp@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz#14ba83a5d373e3d311e5afca29cf5bfad965bf34" - integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== - - escape-string-regexp@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" - integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== - - escape-string-regexp@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz#a30304e99daa32e23b2fd20f51babd07cffca344" - integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== - - escodegen@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.1.0.tgz#ba93bbb7a43986d29d6041f99f5262da773e2e17" - integrity sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w== - dependencies: - esprima "^4.0.1" - estraverse "^5.2.0" - esutils "^2.0.2" - optionalDependencies: - source-map "~0.6.1" - - eslint-config-airbnb-base@^15.0.0: - version "15.0.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz#6b09add90ac79c2f8d723a2580e07f3925afd236" - integrity sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig== - dependencies: - confusing-browser-globals "^1.0.10" - object.assign "^4.1.2" - object.entries "^1.1.5" - semver "^6.3.0" - - eslint-config-airbnb-typescript@^16.1.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-16.2.0.tgz#9193fafd62f1cbf444895f4495eae334baf3265b" - integrity sha512-OUaMPZpTOZGKd5tXOjJ9PRU4iYNW/Z5DoHIynjsVK/FpkWdiY5+nxQW6TiJAlLwVI1l53xUOrnlZWtVBVQzuWA== - dependencies: - eslint-config-airbnb-base "^15.0.0" - - eslint-config-airbnb@^19.0.2, eslint-config-airbnb@^19.0.4: - version "19.0.4" - resolved "https://registry.yarnpkg.com/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz#84d4c3490ad70a0ffa571138ebcdea6ab085fdc3" - integrity sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew== - dependencies: - eslint-config-airbnb-base "^15.0.0" - object.assign "^4.1.2" - object.entries "^1.1.5" - - eslint-config-prettier@^8.3.0, eslint-config-prettier@^8.5.0: - version "8.10.0" - resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz#3a06a662130807e2502fc3ff8b4143d8a0658e11" - integrity sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg== - - eslint-import-resolver-node@^0.3.2, eslint-import-resolver-node@^0.3.9: - version "0.3.9" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" - integrity sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g== - dependencies: - debug "^3.2.7" - is-core-module "^2.13.0" - resolve "^1.22.4" - - eslint-import-resolver-root-import@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-root-import/-/eslint-import-resolver-root-import-1.0.4.tgz#82991138d8014b5e2283b27622ad1ba21f535609" - integrity sha512-c8cUQcELRBe0mnblBZJKEfL+jIUGR8pctK5gdru5N7bBOIve2WZ0R3KoO5GOksXJ4WzZhtcBS2xPaTJYEe4IdQ== - dependencies: - eslint-import-resolver-node "^0.3.2" - json5 "^2.1.0" - - eslint-module-utils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz#e439fee65fc33f6bba630ff621efc38ec0375c49" - integrity sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw== - dependencies: - debug "^3.2.7" - - eslint-plugin-import@^2.25.4: - version "2.29.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.0.tgz#8133232e4329ee344f2f612885ac3073b0b7e155" - integrity sha512-QPOO5NO6Odv5lpoTkddtutccQjysJuFxoPS7fAHO+9m9udNHvTCPSAMW9zGAYj8lAIdr40I8yPCdUYrncXtrwg== - dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" - array.prototype.flat "^1.3.2" - array.prototype.flatmap "^1.3.2" - debug "^3.2.7" - doctrine "^2.1.0" - eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" - is-glob "^4.0.3" - minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" - semver "^6.3.1" - tsconfig-paths "^3.14.2" - - eslint-plugin-jest@^26.1.1: - version "26.9.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest/-/eslint-plugin-jest-26.9.0.tgz#7931c31000b1c19e57dbfb71bbf71b817d1bf949" - integrity sha512-TWJxWGp1J628gxh2KhaH1H1paEdgE2J61BBF1I59c6xWeL5+D1BzMxGDN/nXAfX+aSkR5u80K+XhskK6Gwq9ng== - dependencies: - "@typescript-eslint/utils" "^5.10.0" - - eslint-plugin-jsx-a11y@^6.5.1: - version "6.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.8.0.tgz#2fa9c701d44fcd722b7c771ec322432857fcbad2" - integrity sha512-Hdh937BS3KdwwbBaKd5+PLCOmYY6U4f2h9Z2ktwtNKvIdIEu137rjYbcb9ApSbVJfWxANNuiKTD/9tOKjK9qOA== - dependencies: - "@babel/runtime" "^7.23.2" - aria-query "^5.3.0" - array-includes "^3.1.7" - array.prototype.flatmap "^1.3.2" - ast-types-flow "^0.0.8" - axe-core "=4.7.0" - axobject-query "^3.2.1" - damerau-levenshtein "^1.0.8" - emoji-regex "^9.2.2" - es-iterator-helpers "^1.0.15" - hasown "^2.0.0" - jsx-ast-utils "^3.3.5" - language-tags "^1.0.9" - minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" - - eslint-plugin-mocha@^10.0.3: - version "10.2.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-mocha/-/eslint-plugin-mocha-10.2.0.tgz#15b05ce5be4b332bb0d76826ec1c5ebf67102ad6" - integrity sha512-ZhdxzSZnd1P9LqDPF0DBcFLpRIGdh1zkF2JHnQklKQOvrQtT73kdP5K9V2mzvbLR+cCAO9OI48NXK/Ax9/ciCQ== - dependencies: - eslint-utils "^3.0.0" - rambda "^7.4.0" - - eslint-plugin-prettier@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" - integrity sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ== - dependencies: - prettier-linter-helpers "^1.0.0" - - eslint-plugin-react-hooks@^4.3.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== - - eslint-plugin-react@^7.29.2: - version "7.33.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.33.2.tgz#69ee09443ffc583927eafe86ffebb470ee737608" - integrity sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw== - dependencies: - array-includes "^3.1.6" - array.prototype.flatmap "^1.3.1" - array.prototype.tosorted "^1.1.1" - doctrine "^2.1.0" - es-iterator-helpers "^1.0.12" - estraverse "^5.3.0" - jsx-ast-utils "^2.4.1 || ^3.0.0" - minimatch "^3.1.2" - object.entries "^1.1.6" - object.fromentries "^2.0.6" - object.hasown "^1.1.2" - object.values "^1.1.6" - prop-types "^15.8.1" - resolve "^2.0.0-next.4" - semver "^6.3.1" - string.prototype.matchall "^4.0.8" - - eslint-plugin-storybook@^0.5.12: - version "0.5.13" - resolved "https://registry.yarnpkg.com/eslint-plugin-storybook/-/eslint-plugin-storybook-0.5.13.tgz#dee4056eaa59c886a9ae78fb7b2ee0ed5fad4366" - integrity sha512-82x3FH1VAi68Awu1VEjn/hLkzFZsOP8ItcC5/uGF9WszIrj6n7Q3MZD57oE26k3aKwuPfFtAPnSjFnaBkBab+g== - dependencies: - "@storybook/csf" "^0.0.1" - "@typescript-eslint/experimental-utils" "^5.3.0" - requireindex "^1.1.0" - - eslint-scope@5.1.1, eslint-scope@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" - integrity sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw== - dependencies: - esrecurse "^4.3.0" - estraverse "^4.1.1" - - eslint-scope@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" - integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== - dependencies: - esrecurse "^4.1.0" - estraverse "^4.1.1" - - eslint-scope@^7.2.2: - version "7.2.2" - resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-7.2.2.tgz#deb4f92563390f32006894af62a22dba1c46423f" - integrity sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg== - dependencies: - esrecurse "^4.3.0" - estraverse "^5.2.0" - - eslint-utils@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" - integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== - dependencies: - eslint-visitor-keys "^1.1.0" - - eslint-utils@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-3.0.0.tgz#8aebaface7345bb33559db0a1f13a1d2d48c3672" - integrity sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA== - dependencies: - eslint-visitor-keys "^2.0.0" - - eslint-visitor-keys@^1.1.0, eslint-visitor-keys@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz#30ebd1ef7c2fdff01c3a4f151044af25fab0523e" - integrity sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ== - - eslint-visitor-keys@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz#f65328259305927392c938ed44eb0a5c9b2bd303" - integrity sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw== - - eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3: - version "3.4.3" - resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" - integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== - - eslint@^7.18.0: - version "7.32.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-7.32.0.tgz#c6d328a14be3fb08c8d1d21e12c02fdb7a2a812d" - integrity sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA== - dependencies: - "@babel/code-frame" "7.12.11" - "@eslint/eslintrc" "^0.4.3" - "@humanwhocodes/config-array" "^0.5.0" - ajv "^6.10.0" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.0.1" - doctrine "^3.0.0" - enquirer "^2.3.5" - escape-string-regexp "^4.0.0" - eslint-scope "^5.1.1" - eslint-utils "^2.1.0" - eslint-visitor-keys "^2.0.0" - espree "^7.3.1" - esquery "^1.4.0" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - functional-red-black-tree "^1.0.1" - glob-parent "^5.1.2" - globals "^13.6.0" - ignore "^4.0.6" - import-fresh "^3.0.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - js-yaml "^3.13.1" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.0.4" - natural-compare "^1.4.0" - optionator "^0.9.1" - progress "^2.0.0" - regexpp "^3.1.0" - semver "^7.2.1" - strip-ansi "^6.0.0" - strip-json-comments "^3.1.0" - table "^6.0.9" - text-table "^0.2.0" - v8-compile-cache "^2.0.3" - - eslint@^8.10.0: - version "8.54.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.54.0.tgz#588e0dd4388af91a2e8fa37ea64924074c783537" - integrity sha512-NY0DfAkM8BIZDVl6PgSa1ttZbx3xHgJzSNJKYcQglem6CppHyMhRIQkBVSSMaSRnLhig3jsDbEzOjwCVt4AmmA== - dependencies: - "@eslint-community/eslint-utils" "^4.2.0" - "@eslint-community/regexpp" "^4.6.1" - "@eslint/eslintrc" "^2.1.3" - "@eslint/js" "8.54.0" - "@humanwhocodes/config-array" "^0.11.13" - "@humanwhocodes/module-importer" "^1.0.1" - "@nodelib/fs.walk" "^1.2.8" - "@ungap/structured-clone" "^1.2.0" - ajv "^6.12.4" - chalk "^4.0.0" - cross-spawn "^7.0.2" - debug "^4.3.2" - doctrine "^3.0.0" - escape-string-regexp "^4.0.0" - eslint-scope "^7.2.2" - eslint-visitor-keys "^3.4.3" - espree "^9.6.1" - esquery "^1.4.2" - esutils "^2.0.2" - fast-deep-equal "^3.1.3" - file-entry-cache "^6.0.1" - find-up "^5.0.0" - glob-parent "^6.0.2" - globals "^13.19.0" - graphemer "^1.4.0" - ignore "^5.2.0" - imurmurhash "^0.1.4" - is-glob "^4.0.0" - is-path-inside "^3.0.3" - js-yaml "^4.1.0" - json-stable-stringify-without-jsonify "^1.0.1" - levn "^0.4.1" - lodash.merge "^4.6.2" - minimatch "^3.1.2" - natural-compare "^1.4.0" - optionator "^0.9.3" - strip-ansi "^6.0.1" - text-table "^0.2.0" - - espree@^7.3.0, espree@^7.3.1: - version "7.3.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" - integrity sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g== - dependencies: - acorn "^7.4.0" - acorn-jsx "^5.3.1" - eslint-visitor-keys "^1.3.0" - - espree@^9.6.0, espree@^9.6.1: - version "9.6.1" - resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" - integrity sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ== - dependencies: - acorn "^8.9.0" - acorn-jsx "^5.3.2" - eslint-visitor-keys "^3.4.1" - - esprima@^4.0.0, esprima@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" - integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== - - esquery@^1.4.0, esquery@^1.4.2: - version "1.5.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.5.0.tgz#6ce17738de8577694edd7361c57182ac8cb0db0b" - integrity sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg== - dependencies: - estraverse "^5.1.0" - - esrecurse@^4.1.0, esrecurse@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" - integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== - dependencies: - estraverse "^5.2.0" - - estraverse@^4.1.1: - version "4.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" - integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== - - estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123" - integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA== - - estree-to-babel@^3.1.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/estree-to-babel/-/estree-to-babel-3.2.1.tgz#82e78315275c3ca74475fdc8ac1a5103c8a75bf5" - integrity sha512-YNF+mZ/Wu2FU/gvmzuWtYc8rloubL7wfXCTgouFrnjGVXPA/EeYYA7pupXWrb3Iv1cTBeSSxxJIbK23l4MRNqg== - dependencies: - "@babel/traverse" "^7.1.6" - "@babel/types" "^7.2.0" - c8 "^7.6.0" - - estree-util-attach-comments@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz#ee44f4ff6890ee7dfb3237ac7810154c94c63f84" - integrity sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w== - dependencies: - "@types/estree" "^1.0.0" - - estree-util-build-jsx@^2.0.0: - version "2.2.2" - resolved "https://registry.yarnpkg.com/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz#32f8a239fb40dc3f3dca75bb5dcf77a831e4e47b" - integrity sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg== - dependencies: - "@types/estree-jsx" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - estree-walker "^3.0.0" - - estree-util-is-identifier-name@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz#fb70a432dcb19045e77b05c8e732f1364b4b49b2" - integrity sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ== - - estree-util-to-js@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz#0f80d42443e3b13bd32f7012fffa6f93603f4a36" - integrity sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA== - dependencies: - "@types/estree-jsx" "^1.0.0" - astring "^1.8.0" - source-map "^0.7.0" - - estree-util-visit@^1.0.0: - version "1.2.1" - resolved "https://registry.yarnpkg.com/estree-util-visit/-/estree-util-visit-1.2.1.tgz#8bc2bc09f25b00827294703835aabee1cc9ec69d" - integrity sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/unist" "^2.0.0" - - estree-walker@^0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-0.6.1.tgz#53049143f40c6eb918b23671d1fe3219f3a1b362" - integrity sha512-SqmZANLWS0mnatqbSfRP5g8OXZC12Fgg1IwNtLsyHDzJizORW4khDfjPqJZsemPWBB2uqykUah5YpQ6epsqC/w== - - estree-walker@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" - integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== - - estree-walker@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-3.0.3.tgz#67c3e549ec402a487b4fc193d1953a524752340d" - integrity sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g== - dependencies: - "@types/estree" "^1.0.0" - - esutils@^2.0.2: - version "2.0.3" - resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" - integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== - - etag@~1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" - integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== - - eventemitter3@^4.0.0, eventemitter3@^4.0.1, eventemitter3@^4.0.4: - version "4.0.7" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" - integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== - - events@3.3.0, events@^3.0.0, events@^3.2.0, events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - - evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" - integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== - dependencies: - md5.js "^1.3.4" - safe-buffer "^5.1.1" - - exec-sh@^0.3.2: - version "0.3.6" - resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" - integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== - - execa@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.0.0.tgz#4029b0007998a841fbd1032e5f4de86a3c1e3376" - integrity sha512-ov6w/2LCiuyO4RLYGdpFGjkcs0wMTgGE8PrkTHikeUy5iJekXyPIKUjifk5CsE0pt7sMCrMZ3YNqoCj6idQOnQ== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - - execa@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" - integrity sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA== - dependencies: - cross-spawn "^6.0.0" - get-stream "^4.0.0" - is-stream "^1.1.0" - npm-run-path "^2.0.0" - p-finally "^1.0.0" - signal-exit "^3.0.0" - strip-eof "^1.0.0" - - execa@^5.0.0, execa@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" - integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== - dependencies: - cross-spawn "^7.0.3" - get-stream "^6.0.0" - human-signals "^2.1.0" - is-stream "^2.0.0" - merge-stream "^2.0.0" - npm-run-path "^4.0.1" - onetime "^5.1.2" - signal-exit "^3.0.3" - strip-final-newline "^2.0.0" - - exit@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" - integrity sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ== - - expand-brackets@^2.1.4: - version "2.1.4" - resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== - dependencies: - debug "^2.3.3" - define-property "^0.2.5" - extend-shallow "^2.0.1" - posix-character-classes "^0.1.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - expand-template@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/expand-template/-/expand-template-2.0.3.tgz#6e14b3fcee0f3a6340ecb57d2e8918692052a47c" - integrity sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg== - - expect@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/expect/-/expect-27.5.1.tgz#83ce59f1e5bdf5f9d2b94b61d2050db48f3fef74" - integrity sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw== - dependencies: - "@jest/types" "^27.5.1" - jest-get-type "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - - expect@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/expect/-/expect-28.1.3.tgz#90a7c1a124f1824133dd4533cce2d2bdcb6603ec" - integrity sha512-eEh0xn8HlsuOBxFgIss+2mX85VAS4Qy3OSkjV7rlBWljtA4oWH37glVGyOZSZvErDT/yBywZdPGwCXuTvSG85g== - dependencies: - "@jest/expect-utils" "^28.1.3" - jest-get-type "^28.0.2" - jest-matcher-utils "^28.1.3" - jest-message-util "^28.1.3" - jest-util "^28.1.3" - - expect@^29.0.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.7.0.tgz#578874590dcb3214514084c08115d8aee61e11bc" - integrity sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw== - dependencies: - "@jest/expect-utils" "^29.7.0" - jest-get-type "^29.6.3" - jest-matcher-utils "^29.7.0" - jest-message-util "^29.7.0" - jest-util "^29.7.0" - - exponential-backoff@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/exponential-backoff/-/exponential-backoff-3.1.1.tgz#64ac7526fe341ab18a39016cd22c787d01e00bf6" - integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== - - express@^4.17.1, express@^4.17.3, express@^4.18.2: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== - dependencies: - accepts "~1.3.8" - array-flatten "1.1.1" - body-parser "1.20.1" - content-disposition "0.5.4" - content-type "~1.0.4" - cookie "0.5.0" - cookie-signature "1.0.6" - debug "2.6.9" - depd "2.0.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - finalhandler "1.2.0" - fresh "0.5.2" - http-errors "2.0.0" - merge-descriptors "1.0.1" - methods "~1.1.2" - on-finished "2.4.1" - parseurl "~1.3.3" - path-to-regexp "0.1.7" - proxy-addr "~2.0.7" - qs "6.11.0" - range-parser "~1.2.1" - safe-buffer "5.2.1" - send "0.18.0" - serve-static "1.15.0" - setprototypeof "1.2.0" - statuses "2.0.1" - type-is "~1.6.18" - utils-merge "1.0.1" - vary "~1.1.2" - - extend-shallow@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== - dependencies: - is-extendable "^0.1.0" - - extend-shallow@^3.0.0, extend-shallow@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== - dependencies: - assign-symbols "^1.0.0" - is-extendable "^1.0.1" - - extend@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" - integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== - - external-editor@^3.0.3: - version "3.1.0" - resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-3.1.0.tgz#cb03f740befae03ea4d283caed2741a83f335495" - integrity sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew== - dependencies: - chardet "^0.7.0" - iconv-lite "^0.4.24" - tmp "^0.0.33" - - extglob@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" - integrity sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw== - dependencies: - array-unique "^0.3.2" - define-property "^1.0.0" - expand-brackets "^2.1.4" - extend-shallow "^2.0.1" - fragment-cache "^0.2.1" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: - version "3.1.3" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" - integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== - - fast-diff@^1.1.2: - version "1.3.0" - resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" - integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== - - fast-equals@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/fast-equals/-/fast-equals-5.0.1.tgz#a4eefe3c5d1c0d021aeed0bc10ba5e0c12ee405d" - integrity sha512-WF1Wi8PwwSY7/6Kx0vKXtw8RwuSGoM1bvDaJbu7MxDlR1vovZjIAKrnzyrThgAjm6JDTu0fVgWXDlMGspodfoQ== - - fast-fifo@^1.1.0, fast-fifo@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/fast-fifo/-/fast-fifo-1.3.2.tgz#286e31de96eb96d38a97899815740ba2a4f3640c" - integrity sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ== - - fast-glob@^2.2.6: - version "2.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" - integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== - dependencies: - "@mrmlnc/readdir-enhanced" "^2.2.1" - "@nodelib/fs.stat" "^1.1.2" - glob-parent "^3.1.0" - is-glob "^4.0.0" - merge2 "^1.2.3" - micromatch "^3.1.10" - - fast-glob@^3.2.9: - version "3.3.2" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" - integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.2" - merge2 "^1.3.0" - micromatch "^4.0.4" - - fast-json-parse@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/fast-json-parse/-/fast-json-parse-1.0.3.tgz#43e5c61ee4efa9265633046b770fb682a7577c4d" - integrity sha512-FRWsaZRWEJ1ESVNbDWmsAlqDk96gPQezzLghafp5J4GUKjbCz3OkAHuZs5TuPEtkbVQERysLp9xv6c24fBm8Aw== - - fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" - integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== - - fast-levenshtein@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" - integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== - - fast-redact@^3.0.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.3.0.tgz#7c83ce3a7be4898241a46560d51de10f653f7634" - integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== - - fastest-levenshtein@^1.0.12: - version "1.0.16" - resolved "https://registry.yarnpkg.com/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz#210e61b6ff181de91ea9b3d1b84fdedd47e034e5" - integrity sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg== - - fastq@^1.6.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.15.0.tgz#d04d07c6a2a68fe4599fea8d2e103a937fae6b3a" - integrity sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw== - dependencies: - reusify "^1.0.4" - - favicons-webpack-plugin@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/favicons-webpack-plugin/-/favicons-webpack-plugin-5.0.2.tgz#0837a753ee4485785fa2cec1c3b83472f9ff60ce" - integrity sha512-D/A+Ze0x57+YZBU69hK/lR3NI636qQnKduWyQm0THGl1y3jt16whPHHsi8yjsuXvetv84Eh/I/yYJbAMC2iQxg== - dependencies: - "@types/favicons" "5.5.0" - find-root "^1.1.0" - parse-author "^2.0.0" - parse5 "^6.0.1" - optionalDependencies: - html-webpack-plugin ">=5.0.0" - - favicons@7.0.0-beta.1: - version "7.0.0-beta.1" - resolved "https://registry.yarnpkg.com/favicons/-/favicons-7.0.0-beta.1.tgz#57a7319d75bb004590b5bae8c2388858135535eb" - integrity sha512-68NaOyryvZpQlQw1w1K40AH6bl8KfhpL2Nb/EBedeBseYS7Rpz1d3t4eBaLIdOBRM2/353EKkZeKzBvQnp6LvA== - dependencies: - colors "^1.4.0" - escape-html "^1.0.3" - lodash.defaultsdeep "^4.6.1" - sharp "^0.29.1" - through2 "^4.0.2" - vinyl "^2.2.1" - xml2js "^0.4.23" - - favicons@^7.0.2: - version "7.1.4" - resolved "https://registry.yarnpkg.com/favicons/-/favicons-7.1.4.tgz#bc0ed1a8d752f94a36912294681925e272d25ff0" - integrity sha512-lnZpVgT7Fzz+DUjioKF1dMwLYlpqWCaB4gIksIfIKwtlhHO1Q7w23hERwHQjEsec+43iENwbTAPRDW3XvpLhbg== - dependencies: - escape-html "^1.0.3" - sharp "^0.32.4" - xml2js "^0.6.1" - - faye-websocket@^0.11.3: - version "0.11.4" - resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" - integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== - dependencies: - websocket-driver ">=0.5.1" - - fb-watchman@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.2.tgz#e9524ee6b5c77e9e5001af0f85f3adbb8623255c" - integrity sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA== - dependencies: - bser "2.1.1" - - fetch-retry@^5.0.2: - version "5.0.6" - resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.6.tgz#17d0bc90423405b7a88b74355bf364acd2a7fa56" - integrity sha512-3yurQZ2hD9VISAhJJP9bpYFNQrHHBXE2JxxjY5aLEcDi46RmAzJE2OC9FAde0yis5ElW0jTTzs0zfg/Cca4XqQ== - - figgy-pudding@^3.5.1: - version "3.5.2" - resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" - integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== - - figures@3.2.0, figures@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" - integrity sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg== - dependencies: - escape-string-regexp "^1.0.5" - - file-entry-cache@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" - integrity sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg== - dependencies: - flat-cache "^3.0.4" - - file-loader@^6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" - integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - - file-system-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-2.3.0.tgz#201feaf4c8cd97b9d0d608e96861bb6005f46fe6" - integrity sha512-l4DMNdsIPsVnKrgEXbJwDJsA5mB8rGwHYERMgqQx/xAUtChPJMre1bXBzDEqqVbWv9AIbFezXMxeEkZDSrXUOQ== - dependencies: - fs-extra "11.1.1" - ramda "0.29.0" - - file-system-cache@^1.0.5: - version "1.1.0" - resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.1.0.tgz#984de17b976b75a77a27e08d6828137c1aa80fa1" - integrity sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw== - dependencies: - fs-extra "^10.1.0" - ramda "^0.28.0" - - file-uri-to-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" - integrity sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw== - - filelist@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/filelist/-/filelist-1.0.4.tgz#f78978a1e944775ff9e62e744424f215e58352b5" - integrity sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q== - dependencies: - minimatch "^5.0.1" - - fill-range@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== - dependencies: - extend-shallow "^2.0.1" - is-number "^3.0.0" - repeat-string "^1.6.1" - to-regex-range "^2.1.0" - - fill-range@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-7.0.1.tgz#1919a6a7c75fe38b2c7c77e5198535da9acdda40" - integrity sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ== - dependencies: - to-regex-range "^5.0.1" - - filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== - - finalhandler@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" - integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== - dependencies: - debug "2.6.9" - encodeurl "~1.0.2" - escape-html "~1.0.3" - on-finished "2.4.1" - parseurl "~1.3.3" - statuses "2.0.1" - unpipe "~1.0.0" - - find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" - integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== - dependencies: - commondir "^1.0.1" - make-dir "^2.0.0" - pkg-dir "^3.0.0" - - find-cache-dir@^3.3.1: - version "3.3.2" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.2.tgz#b30c5b6eff0730731aea9bbd9dbecbd80256d64b" - integrity sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig== - dependencies: - commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" - - find-root@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" - integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== - - find-up@5.0.0, find-up@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" - integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== - dependencies: - locate-path "^6.0.0" - path-exists "^4.0.0" - - find-up@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" - integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== - dependencies: - path-exists "^2.0.0" - pinkie-promise "^2.0.0" - - find-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" - integrity sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ== - dependencies: - locate-path "^2.0.0" - - find-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" - integrity sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg== - dependencies: - locate-path "^3.0.0" - - find-up@^4.0.0, find-up@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" - integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== - dependencies: - locate-path "^5.0.0" - path-exists "^4.0.0" - - flat-cache@^3.0.4: - version "3.2.0" - resolved "https://registry.yarnpkg.com/flat-cache/-/flat-cache-3.2.0.tgz#2c0c2d5040c99b1632771a9d105725c0115363ee" - integrity sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw== - dependencies: - flatted "^3.2.9" - keyv "^4.5.3" - rimraf "^3.0.2" - - flat@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/flat/-/flat-5.0.2.tgz#8ca6fe332069ffa9d324c327198c598259ceb241" - integrity sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ== - - flatted@^3.2.9: - version "3.2.9" - resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.2.9.tgz#7eb4c67ca1ba34232ca9d2d93e9886e611ad7daf" - integrity sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ== - - flush-write-stream@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" - integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== - dependencies: - inherits "^2.0.3" - readable-stream "^2.3.6" - - focus-lock@^0.8.0: - version "0.8.1" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" - integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== - dependencies: - tslib "^1.9.3" - - follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.0: - version "1.15.3" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a" - integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q== - - for-each@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e" - integrity sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw== - dependencies: - is-callable "^1.1.3" - - for-in@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== - - foreground-child@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-2.0.0.tgz#71b32800c9f15aa8f2f83f4a6bd9bff35d861a53" - integrity sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^3.0.2" - - foreground-child@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.1.1.tgz#1d173e776d75d2772fed08efe4a0de1ea1b12d0d" - integrity sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg== - dependencies: - cross-spawn "^7.0.0" - signal-exit "^4.0.1" - - fork-ts-checker-webpack-plugin@^4.1.6: - version "4.1.6" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" - integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== - dependencies: - "@babel/code-frame" "^7.5.5" - chalk "^2.4.1" - micromatch "^3.1.10" - minimatch "^3.0.4" - semver "^5.6.0" - tapable "^1.0.0" - worker-rpc "^0.1.0" - - fork-ts-checker-webpack-plugin@^6.0.4: - version "6.5.3" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.3.tgz#eda2eff6e22476a2688d10661688c47f611b37f3" - integrity sha512-SbH/l9ikmMWycd5puHJKTkZJKddF4iRLyW3DeZ08HTI7NGyLS38MXd/KGgeWumQO7YNQbW2u/NtPT2YowbPaGQ== - dependencies: - "@babel/code-frame" "^7.8.3" - "@types/json-schema" "^7.0.5" - chalk "^4.1.0" - chokidar "^3.4.2" - cosmiconfig "^6.0.0" - deepmerge "^4.2.2" - fs-extra "^9.0.0" - glob "^7.1.6" - memfs "^3.1.2" - minimatch "^3.0.4" - schema-utils "2.7.0" - semver "^7.3.2" - tapable "^1.0.0" - - fork-ts-checker-webpack-plugin@^7.2.1: - version "7.3.0" - resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-7.3.0.tgz#a9c984a018493962360d7c7e77a67b44a2d5f3aa" - integrity sha512-IN+XTzusCjR5VgntYFgxbxVx3WraPRnKehBFrf00cMSrtUuW9MsG9dhL6MWpY6MkjC3wVwoujfCDgZZCQwbswA== - dependencies: - "@babel/code-frame" "^7.16.7" - chalk "^4.1.2" - chokidar "^3.5.3" - cosmiconfig "^7.0.1" - deepmerge "^4.2.2" - fs-extra "^10.0.0" - memfs "^3.4.1" - minimatch "^3.0.4" - node-abort-controller "^3.0.1" - schema-utils "^3.1.1" - semver "^7.3.5" - tapable "^2.2.1" - - form-data@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" - integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - - form-data@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.0.tgz#93919daeaf361ee529584b9b31664dc12c9fa452" - integrity sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww== - dependencies: - asynckit "^0.4.0" - combined-stream "^1.0.8" - mime-types "^2.1.12" - - forwarded@0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" - integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== - - fragment-cache@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== - dependencies: - map-cache "^0.2.2" - - fresh@0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" - integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== - - from2@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" - integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== - dependencies: - inherits "^2.0.1" - readable-stream "^2.0.0" - - fs-constants@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" - integrity sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow== - - fs-extra@11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.1.1.tgz#da69f7c39f3b002378b0954bb6ae7efdc0876e2d" - integrity sha512-MGIE4HOvQCeUCzmlHs0vXpih4ysz4wg9qiSAu6cd42lVwPbTM1TjV7RusoyQqMmk/95gdQZX72u+YW+c3eEpFQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - - fs-extra@^10.0.0, fs-extra@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" - integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - - fs-extra@^11.1.0, fs-extra@^11.1.1: - version "11.2.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-11.2.0.tgz#e70e17dfad64232287d01929399e0ea7c86b0e5b" - integrity sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw== - dependencies: - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - - fs-extra@^9.0.0, fs-extra@^9.0.1: - version "9.1.0" - resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" - integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== - dependencies: - at-least-node "^1.0.0" - graceful-fs "^4.2.0" - jsonfile "^6.0.1" - universalify "^2.0.0" - - fs-minipass@^2.0.0, fs-minipass@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" - integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg== - dependencies: - minipass "^3.0.0" - - fs-minipass@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-3.0.3.tgz#79a85981c4dc120065e96f62086bf6f9dc26cc54" - integrity sha512-XUBA9XClHbnJWSfBzjkm6RvPsyg3sryZt06BEQoXcF7EK/xpGaQYJgQKDJSUH5SGZ76Y7pFx1QBnXz09rU5Fbw== - dependencies: - minipass "^7.0.3" - - fs-monkey@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.5.tgz#fe450175f0db0d7ea758102e1d84096acb925788" - integrity sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew== - - fs-write-stream-atomic@^1.0.8: - version "1.0.10" - resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" - integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== - dependencies: - graceful-fs "^4.1.2" - iferr "^0.1.5" - imurmurhash "^0.1.4" - readable-stream "1 || 2" - - fs.realpath@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" - integrity sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw== - - fsevents@^1.2.7: - version "1.2.13" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.13.tgz#f325cb0455592428bcf11b383370ef70e3bfcc38" - integrity sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw== - dependencies: - bindings "^1.5.0" - nan "^2.12.1" - - fsevents@^2.1.2, fsevents@^2.3.2, fsevents@~2.3.2: - version "2.3.3" - resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" - integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== - - function-bind@^1.1.1, function-bind@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" - integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== - - function.prototype.name@^1.1.0, function.prototype.name@^1.1.5, function.prototype.name@^1.1.6: - version "1.1.6" - resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.6.tgz#cdf315b7d90ee77a4c6ee216c3c3362da07533fd" - integrity sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - functions-have-names "^1.2.3" - - functional-red-black-tree@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz#1b0ab3bd553b2a0d6399d29c0e3ea0b252078327" - integrity sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g== - - functions-have-names@^1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" - integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== - - gauge@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" - integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.2" - console-control-strings "^1.0.0" - has-unicode "^2.0.1" - object-assign "^4.1.1" - signal-exit "^3.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.2" - - gauge@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.4.tgz#52ff0652f2bbf607a989793d53b751bef2328dce" - integrity sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg== - dependencies: - aproba "^1.0.3 || ^2.0.0" - color-support "^1.1.3" - console-control-strings "^1.1.0" - has-unicode "^2.0.1" - signal-exit "^3.0.7" - string-width "^4.2.3" - strip-ansi "^6.0.1" - wide-align "^1.1.5" - - gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: - version "1.0.0-beta.2" - resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" - integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== - - get-caller-file@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" - integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== - - get-func-name@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.2.tgz#0d7cf20cd13fda808669ffa88f4ffc7a3943fc41" - integrity sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ== - - get-intrinsic@^1.0.2, get-intrinsic@^1.1.1, get-intrinsic@^1.1.3, get-intrinsic@^1.2.0, get-intrinsic@^1.2.1, get-intrinsic@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.2.2.tgz#281b7622971123e1ef4b3c90fd7539306da93f3b" - integrity sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA== - dependencies: - function-bind "^1.1.2" - has-proto "^1.0.1" - has-symbols "^1.0.3" - hasown "^2.0.0" - - get-package-type@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" - integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== - - get-pkg-repo@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz#75973e1c8050c73f48190c52047c4cee3acbf385" - integrity sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA== - dependencies: - "@hutson/parse-repository-url" "^3.0.0" - hosted-git-info "^4.0.0" - through2 "^2.0.0" - yargs "^16.2.0" - - get-port-please@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/get-port-please/-/get-port-please-3.1.1.tgz#2556623cddb4801d823c0a6a15eec038abb483be" - integrity sha512-3UBAyM3u4ZBVYDsxOQfJDxEa6XTbpBDrOjp4mf7ExFRt5BKs/QywQQiJsh2B+hxcZLSapWqCRvElUe8DnKcFHA== - - get-port@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" - integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== - - get-stdin@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" - integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== - - get-stream@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.0.tgz#3e0012cb6827319da2706e601a1583e8629a6718" - integrity sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg== - - get-stream@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" - integrity sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w== - dependencies: - pump "^3.0.0" - - get-stream@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" - integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== - - get-symbol-description@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" - integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - - get-value@^2.0.3, get-value@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== - - git-raw-commits@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/git-raw-commits/-/git-raw-commits-3.0.0.tgz#5432f053a9744f67e8db03dbc48add81252cfdeb" - integrity sha512-b5OHmZ3vAgGrDn/X0kS+9qCfNKWe4K/jFnhwzVWWg0/k5eLa3060tZShrRg8Dja5kPc+YjS0Gc6y7cRr44Lpjw== - dependencies: - dargs "^7.0.0" - meow "^8.1.2" - split2 "^3.2.2" - - git-remote-origin-url@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz#5282659dae2107145a11126112ad3216ec5fa65f" - integrity sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw== - dependencies: - gitconfiglocal "^1.0.0" - pify "^2.3.0" - - git-semver-tags@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/git-semver-tags/-/git-semver-tags-5.0.1.tgz#db748aa0e43d313bf38dcd68624d8443234e1c15" - integrity sha512-hIvOeZwRbQ+7YEUmCkHqo8FOLQZCEn18yevLHADlFPZY02KJGsu5FZt9YW/lybfK2uhWFI7Qg/07LekJiTv7iA== - dependencies: - meow "^8.1.2" - semver "^7.0.0" - - git-up@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-7.0.0.tgz#bace30786e36f56ea341b6f69adfd83286337467" - integrity sha512-ONdIrbBCFusq1Oy0sC71F5azx8bVkvtZtMJAsv+a6lz5YAmbNnLD6HAB4gptHZVLPR8S2/kVN6Gab7lryq5+lQ== - dependencies: - is-ssh "^1.4.0" - parse-url "^8.1.0" - - git-url-parse@13.1.0: - version "13.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-13.1.0.tgz#07e136b5baa08d59fabdf0e33170de425adf07b4" - integrity sha512-5FvPJP/70WkIprlUZ33bm4UAaFdjcLkJLpWft1BeZKqwR0uhhNGoKwlUaPtVb4LxCSQ++erHapRak9kWGj+FCA== - dependencies: - git-up "^7.0.0" - - gitconfiglocal@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz#41d045f3851a5ea88f03f24ca1c6178114464b9b" - integrity sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ== - dependencies: - ini "^1.3.2" - - github-from-package@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/github-from-package/-/github-from-package-0.0.0.tgz#97fb5d96bfde8973313f20e8288ef9a167fa64ce" - integrity sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw== - - github-slugger@^1.0.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.5.0.tgz#17891bbc73232051474d68bd867a34625c955f7d" - integrity sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw== - - glob-parent@5.1.2, glob-parent@^5.1.2, glob-parent@~5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" - integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== - dependencies: - is-glob "^4.0.1" - - glob-parent@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== - dependencies: - is-glob "^3.1.0" - path-dirname "^1.0.0" - - glob-parent@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" - integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== - dependencies: - is-glob "^4.0.3" - - glob-promise@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" - integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== - dependencies: - "@types/glob" "*" - - glob-to-regexp@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" - integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== - - glob-to-regexp@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" - integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== - - glob@7.1.4: - version "7.1.4" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.4.tgz#aa608a2f6c577ad357e1ae5a5c26d9a8d1969255" - integrity sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - glob@7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" - integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.0.4" - once "^1.3.0" - path-is-absolute "^1.0.0" - - glob@^10.2.2: - version "10.3.10" - resolved "https://registry.yarnpkg.com/glob/-/glob-10.3.10.tgz#0351ebb809fd187fe421ab96af83d3a70715df4b" - integrity sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g== - dependencies: - foreground-child "^3.1.0" - jackspeak "^2.3.5" - minimatch "^9.0.1" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - path-scurry "^1.10.1" - - glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: - version "7.2.3" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" - integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^3.1.1" - once "^1.3.0" - path-is-absolute "^1.0.0" - - glob@^8.0.1, glob@^8.0.3: - version "8.1.0" - resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e" - integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ== - dependencies: - fs.realpath "^1.0.0" - inflight "^1.0.4" - inherits "2" - minimatch "^5.0.1" - once "^1.3.0" - - glob@^9.2.0: - version "9.3.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" - integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - - global@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" - integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== - dependencies: - min-document "^2.19.0" - process "^0.11.10" - - globals@^11.1.0: - version "11.12.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" - integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== - - globals@^13.19.0, globals@^13.6.0, globals@^13.9.0: - version "13.23.0" - resolved "https://registry.yarnpkg.com/globals/-/globals-13.23.0.tgz#ef31673c926a0976e1f61dab4dca57e0c0a8af02" - integrity sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA== - dependencies: - type-fest "^0.20.2" - - globalthis@^1.0.0, globalthis@^1.0.1, globalthis@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" - integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== - dependencies: - define-properties "^1.1.3" - - globby@11.1.0, globby@^11.0.2, globby@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" - integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.2.9" - ignore "^5.2.0" - merge2 "^1.4.1" - slash "^3.0.0" - - globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha512-KVbFv2TQtbzCoxAnfD6JcHZTYCzyliEaaeM/gH8qQdkKr5s0OP9scEgvdcngyk7AVdY6YVW/TJHd+lQ/Df3Daw== - dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" - - globby@^9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" - integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== - dependencies: - "@types/glob" "^7.1.1" - array-union "^1.0.2" - dir-glob "^2.2.2" - fast-glob "^2.2.6" - glob "^7.1.3" - ignore "^4.0.3" - pify "^4.0.1" - slash "^2.0.0" - - gopd@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.0.1.tgz#29ff76de69dac7489b7c0918a5788e56477c332c" - integrity sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA== - dependencies: - get-intrinsic "^1.1.3" - - graceful-fs@4.2.11, graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: - version "4.2.11" - resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" - integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== - - graphemer@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6" - integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag== - - h3@^1.8.1, h3@^1.8.2: - version "1.9.0" - resolved "https://registry.yarnpkg.com/h3/-/h3-1.9.0.tgz#c5f512a93026df9837db6f30c9ef51135dd46752" - integrity sha512-+F3ZqrNV/CFXXfZ2lXBINHi+rM4Xw3CDC5z2CDK3NMPocjonKipGLLDSkrqY9DOrioZNPTIdDMWfQKm//3X2DA== - dependencies: - cookie-es "^1.0.0" - defu "^6.1.3" - destr "^2.0.2" - iron-webcrypto "^1.0.0" - radix3 "^1.1.0" - ufo "^1.3.2" - uncrypto "^0.1.3" - unenv "^1.7.4" - - handle-thing@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" - integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== - - handlebars@^4.7.7: - version "4.7.8" - resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.8.tgz#41c42c18b1be2365439188c77c6afae71c0cd9e9" - integrity sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ== - dependencies: - minimist "^1.2.5" - neo-async "^2.6.2" - source-map "^0.6.1" - wordwrap "^1.0.0" - optionalDependencies: - uglify-js "^3.1.4" - - hard-rejection@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" - integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== - - has-bigints@^1.0.1, has-bigints@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" - integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== - - has-flag@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" - integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw== - - has-flag@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" - integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== - - has-glob@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" - integrity sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g== - dependencies: - is-glob "^3.0.0" - - has-property-descriptors@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz#52ba30b6c5ec87fd89fa574bc1c39125c6f65340" - integrity sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg== - dependencies: - get-intrinsic "^1.2.2" - - has-proto@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/has-proto/-/has-proto-1.0.1.tgz#1885c1305538958aff469fef37937c22795408e0" - integrity sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg== - - has-symbols@^1.0.2, has-symbols@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" - integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== - - has-tostringtag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" - integrity sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ== - dependencies: - has-symbols "^1.0.2" - - has-unicode@2.0.1, has-unicode@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" - integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== - - has-value@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== - dependencies: - get-value "^2.0.3" - has-values "^0.1.4" - isobject "^2.0.0" - - has-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== - dependencies: - get-value "^2.0.6" - has-values "^1.0.0" - isobject "^3.0.0" - - has-values@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== - - has-values@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== - dependencies: - is-number "^3.0.0" - kind-of "^4.0.0" - - hash-base@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" - integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== - dependencies: - inherits "^2.0.4" - readable-stream "^3.6.0" - safe-buffer "^5.2.0" - - hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.7" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" - integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== - dependencies: - inherits "^2.0.3" - minimalistic-assert "^1.0.1" - - hasown@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.0.tgz#f4c513d454a57b7c7e1650778de226b11700546c" - integrity sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA== - dependencies: - function-bind "^1.1.2" - - hast-to-hyperscript@^9.0.0: - version "9.0.1" - resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" - integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== - 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" - - hast-util-from-parse5@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" - integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== - 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" - - hast-util-parse-selector@^2.0.0: - version "2.2.5" - resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" - integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== - - hast-util-raw@6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" - 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" - - hast-util-to-estree@^2.0.0: - version "2.3.3" - resolved "https://registry.yarnpkg.com/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz#da60142ffe19a6296923ec222aba73339c8bf470" - integrity sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ== - dependencies: - "@types/estree" "^1.0.0" - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - estree-util-attach-comments "^2.0.0" - estree-util-is-identifier-name "^2.0.0" - hast-util-whitespace "^2.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdxjs-esm "^1.0.0" - property-information "^6.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.1" - unist-util-position "^4.0.0" - zwitch "^2.0.0" - - hast-util-to-parse5@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" - integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== - 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" - - hast-util-whitespace@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz#0ec64e257e6fc216c7d14c8a1b74d27d650b4557" - integrity sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng== - - hastscript@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" - integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== - 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" - - he@1.2.0, he@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" - integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== - - hex-rgb@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/hex-rgb/-/hex-rgb-4.3.0.tgz#af5e974e83bb2fefe44d55182b004ec818c07776" - integrity sha512-Ox1pJVrDCyGHMG9CFg1tmrRUMRPRsAWYc/PinY0XzJU4K7y7vjNoLKIQ7BR5UJMCxNN8EM1MNDmHWA/B3aZUuw== - - hmac-drbg@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" - integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== - dependencies: - hash.js "^1.0.3" - minimalistic-assert "^1.0.0" - minimalistic-crypto-utils "^1.0.1" - - hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.1, hoist-non-react-statics@^3.3.2: - version "3.3.2" - resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45" - integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw== - dependencies: - react-is "^16.7.0" - - hosted-git-info@^2.1.4: - version "2.8.9" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" - integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== - - hosted-git-info@^3.0.6: - version "3.0.8" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.8.tgz#6e35d4cc87af2c5f816e4cb9ce350ba87a3f370d" - integrity sha512-aXpmwoOhRBrw6X3j0h5RloK4x1OzsxMPyxqIHyNfSe2pypkVTZFpEiRoSipPEPlMrh0HW/XsjkJ5WgnCirpNUw== - dependencies: - lru-cache "^6.0.0" - - hosted-git-info@^4.0.0, hosted-git-info@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.1.0.tgz#827b82867e9ff1c8d0c4d9d53880397d2c86d224" - integrity sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA== - dependencies: - lru-cache "^6.0.0" - - hosted-git-info@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-6.1.1.tgz#629442c7889a69c05de604d52996b74fe6f26d58" - integrity sha512-r0EI+HBMcXadMrugk0GCQ+6BQV39PiWAZVfq7oIckeGiN7sjRGyQxPdft3nQekFTCQbYxLBH+/axZMeH8UX6+w== - dependencies: - lru-cache "^7.5.1" - - hpack.js@^2.1.6: - version "2.1.6" - resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" - integrity sha512-zJxVehUdMGIKsRaNt7apO2Gqp0BdqW5yaiGHXXmbpvxgBYVZnAql+BJb4RO5ad2MgpbZKn5G6nMnegrH1FcNYQ== - dependencies: - inherits "^2.0.1" - obuf "^1.0.0" - readable-stream "^2.0.1" - wbuf "^1.1.0" - - html-encoding-sniffer@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz#42a6dc4fd33f00281176e8b23759ca4e4fa185f3" - integrity sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ== - dependencies: - whatwg-encoding "^1.0.5" - - html-entities@^2.1.0, html-entities@^2.3.2: - version "2.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.4.0.tgz#edd0cee70402584c8c76cc2c0556db09d1f45061" - integrity sha512-igBTJcNNNhvZFRtm8uA6xMY6xYleeDwn3PeBCkDz7tHttv4F2hsDI2aPgNERWzvRcNYHNT3ymRaQzllmXj4YsQ== - - html-escaper@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/html-escaper/-/html-escaper-2.0.2.tgz#dfd60027da36a36dfcbe236262c00a5822681453" - integrity sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg== - - html-minifier-terser@^5.0.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" - integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== - dependencies: - camel-case "^4.1.1" - clean-css "^4.2.3" - commander "^4.1.1" - he "^1.2.0" - param-case "^3.0.3" - relateurl "^0.2.7" - terser "^4.6.3" - - html-minifier-terser@^6.0.2: - version "6.1.0" - resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" - 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" - - html-tags@^3.1.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" - integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== - - html-void-elements@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" - integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== - - html-webpack-plugin@>=5.0.0, html-webpack-plugin@^5.0.0, html-webpack-plugin@^5.3.2: - version "5.5.3" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" - integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== - dependencies: - "@types/html-minifier-terser" "^6.0.0" - html-minifier-terser "^6.0.2" - lodash "^4.17.21" - pretty-error "^4.0.0" - tapable "^2.0.0" - - html-webpack-plugin@^4.0.0: - version "4.5.2" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" - integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== - dependencies: - "@types/html-minifier-terser" "^5.0.0" - "@types/tapable" "^1.0.5" - "@types/webpack" "^4.41.8" - html-minifier-terser "^5.0.1" - loader-utils "^1.2.3" - lodash "^4.17.20" - pretty-error "^2.1.1" - tapable "^1.1.3" - util.promisify "1.0.0" - - htmlparser2@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" - integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - domutils "^2.5.2" - entities "^2.0.0" - - http-cache-semantics@^4.1.0, http-cache-semantics@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz#abe02fcb2985460bf0323be664436ec3476a6d5a" - integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== - - http-deceiver@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" - integrity sha512-LmpOGxTfbpgtGVxJrj5k7asXHCgNZp5nLfp+hWc8QQRqtb7fUy6kRY3BO1h9ddF6yIPYUARgxGOwB42DnxIaNw== - - http-errors@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" - integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== - dependencies: - depd "2.0.0" - inherits "2.0.4" - setprototypeof "1.2.0" - statuses "2.0.1" - toidentifier "1.0.1" - - http-errors@~1.6.2: - version "1.6.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.3.tgz#8b55680bb4be283a0b5bf4ea2e38580be1d9320d" - integrity sha512-lks+lVC8dgGyh97jxvxeYTWQFvh4uw4yC12gVl63Cg30sjPX4wuGcdkICVXDAESr6OJGjqGA8Iz5mkeN6zlD7A== - dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.0" - statuses ">= 1.4.0 < 2" - - http-parser-js@>=0.5.1: - version "0.5.8" - resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" - integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== - - http-proxy-agent@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz#8a8c8ef7f5932ccf953c296ca8291b95aa74aa3a" - integrity sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg== - dependencies: - "@tootallnate/once" "1" - agent-base "6" - debug "4" - - http-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" - integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== - dependencies: - "@tootallnate/once" "2" - agent-base "6" - debug "4" - - http-proxy-middleware@^2.0.3, http-proxy-middleware@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" - integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== - dependencies: - "@types/http-proxy" "^1.17.8" - http-proxy "^1.18.1" - is-glob "^4.0.1" - is-plain-obj "^3.0.0" - micromatch "^4.0.2" - - http-proxy@^1.18.1: - version "1.18.1" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" - integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== - dependencies: - eventemitter3 "^4.0.0" - follow-redirects "^1.0.0" - requires-port "^1.0.0" - - http-shutdown@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/http-shutdown/-/http-shutdown-1.2.2.tgz#41bc78fc767637c4c95179bc492f312c0ae64c5f" - integrity sha512-S9wWkJ/VSY9/k4qcjG318bqJNruzE4HySUhFYknwmu6LBP97KLLfwNf+n4V1BHurvFNkSKLFnK/RsuUnRTf9Vw== - - https-browserify@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== - - https-proxy-agent@^5.0.0: - version "5.0.1" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" - integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== - dependencies: - agent-base "6" - debug "4" - - human-signals@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" - integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== - - humanize-ms@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" - integrity sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ== - dependencies: - ms "^2.0.0" - - hyphenate-style-name@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d" - integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ== - - i18n-iso-countries@^6.8.0: - version "6.8.0" - resolved "https://registry.yarnpkg.com/i18n-iso-countries/-/i18n-iso-countries-6.8.0.tgz#eebbc75594c6832aff86176c1bb38daa133d6dfd" - integrity sha512-jJs/+CA6+VUICFxqGcB0vFMERGfhfvyNk+8Vb9EagSZkl7kSpm/kT0VyhvzM/zixDWEV/+oN9L7v/GT9BwzoGg== - dependencies: - diacritics "1.3.0" - - iconv-lite@0.4.24, iconv-lite@^0.4.24: - version "0.4.24" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" - integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA== - dependencies: - safer-buffer ">= 2.1.2 < 3" - - iconv-lite@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" - integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== - dependencies: - safer-buffer ">= 2.1.2 < 3.0.0" - - icss-utils@^4.0.0, icss-utils@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" - integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== - dependencies: - postcss "^7.0.14" - - icss-utils@^5.0.0, icss-utils@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - - idb-keyval@^6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" - integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== - - ieee754@^1.1.13, ieee754@^1.1.4, ieee754@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" - integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== - - iferr@^0.1.5: - version "0.1.5" - resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" - integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== - - ignore-by-default@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" - integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== - - ignore-walk@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" - integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== - dependencies: - minimatch "^5.0.1" - - ignore-walk@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-6.0.4.tgz#89950be94b4f522225eb63a13c56badb639190e9" - integrity sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw== - dependencies: - minimatch "^9.0.0" - - ignore@^4.0.3, ignore@^4.0.6: - version "4.0.6" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" - integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== - - ignore@^5.0.4, ignore@^5.2.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.0.tgz#67418ae40d34d6999c95ff56016759c718c82f78" - integrity sha512-g7dmpshy+gD7mh88OC9NwSGTKoc3kyLAZQRU1mt53Aw/vnvfXnbC+F/7F7QoYVKbV+KNvJx8wArewKy1vXMtlg== - - immediate@~3.0.5: - version "3.0.6" - resolved "https://registry.yarnpkg.com/immediate/-/immediate-3.0.6.tgz#9db1dbd0faf8de6fbe0f5dd5e56bb606280de69b" - integrity sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ== - - immer@^9.0.19: - version "9.0.21" - resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.21.tgz#1e025ea31a40f24fb064f1fef23e931496330176" - integrity sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA== - - import-fresh@^3.0.0, import-fresh@^3.1.0, import-fresh@^3.2.1, import-fresh@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" - integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== - dependencies: - parent-module "^1.0.0" - resolve-from "^4.0.0" - - import-local@3.1.0, import-local@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-3.1.0.tgz#b4479df8a5fd44f6cdce24070675676063c95cb4" - integrity sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg== - dependencies: - pkg-dir "^4.2.0" - resolve-cwd "^3.0.0" - - imurmurhash@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" - integrity sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA== - - indent-string@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" - integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== - dependencies: - repeating "^2.0.0" - - indent-string@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" - integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== - - infer-owner@^1.0.3, infer-owner@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" - integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== - - inflight@^1.0.4: - version "1.0.6" - resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" - integrity sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA== - dependencies: - once "^1.3.0" - wrappy "1" - - inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" - integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== - - inherits@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" - integrity sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw== - - ini@^1.3.2, ini@^1.3.8, ini@~1.3.0: - version "1.3.8" - resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" - integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== - - init-package-json@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/init-package-json/-/init-package-json-5.0.0.tgz#030cf0ea9c84cfc1b0dc2e898b45d171393e4b40" - integrity sha512-kBhlSheBfYmq3e0L1ii+VKe3zBTLL5lDCDWR+f9dLmEGSB3MqLlMlsolubSsyI88Bg6EA+BIMlomAnQ1SwgQBw== - dependencies: - npm-package-arg "^10.0.0" - promzard "^1.0.0" - read "^2.0.0" - read-package-json "^6.0.0" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - validate-npm-package-name "^5.0.0" - - inline-style-parser@0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" - integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== - - inquirer@^8.2.4: - version "8.2.6" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.6.tgz#733b74888195d8d400a67ac332011b5fae5ea562" - integrity sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg== - dependencies: - ansi-escapes "^4.2.1" - chalk "^4.1.1" - cli-cursor "^3.1.0" - cli-width "^3.0.0" - external-editor "^3.0.3" - figures "^3.0.0" - lodash "^4.17.21" - mute-stream "0.0.8" - ora "^5.4.1" - run-async "^2.4.0" - rxjs "^7.5.5" - string-width "^4.1.0" - strip-ansi "^6.0.0" - through "^2.3.6" - wrap-ansi "^6.0.1" - - internal-slot@^1.0.4, internal-slot@^1.0.5: - version "1.0.6" - resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.6.tgz#37e756098c4911c5e912b8edbf71ed3aa116f930" - integrity sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg== - dependencies: - get-intrinsic "^1.2.2" - hasown "^2.0.0" - side-channel "^1.0.4" - - "internmap@1 - 2": - version "2.0.3" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-2.0.3.tgz#6685f23755e43c524e251d29cbc97248e3061009" - integrity sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg== - - internmap@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/internmap/-/internmap-1.0.1.tgz#0017cc8a3b99605f0302f2b198d272e015e5df95" - integrity sha512-lDB5YccMydFBtasVtxnZ3MRBHuaoE8GKsppq+EchKL2U4nK/DmEpPHNH8MZe5HkMtpSiTSOZwfN0tzYjO/lJEw== - - interpret@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" - integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== - - intl-messageformat@^10.1.0: - version "10.5.8" - resolved "https://registry.yarnpkg.com/intl-messageformat/-/intl-messageformat-10.5.8.tgz#7184da425f360a53a5483a6194e16d666b011fc0" - integrity sha512-NRf0jpBWV0vd671G5b06wNofAN8tp7WWDogMZyaU8GUAsmbouyvgwmFJI7zLjfAMpm3zK+vSwRP3jzaoIcMbaA== - dependencies: - "@formatjs/ecma402-abstract" "1.18.0" - "@formatjs/fast-memoize" "2.2.0" - "@formatjs/icu-messageformat-parser" "2.7.3" - tslib "^2.4.0" - - ioredis@^5.3.2: - version "5.3.2" - resolved "https://registry.yarnpkg.com/ioredis/-/ioredis-5.3.2.tgz#9139f596f62fc9c72d873353ac5395bcf05709f7" - integrity sha512-1DKMMzlIHM02eBBVOFQ1+AolGjs6+xEcM4PDL7NqOS6szq7H9jSaEkIUH6/a5Hl241LzW6JLSiAbNvTQjUupUA== - dependencies: - "@ioredis/commands" "^1.1.1" - cluster-key-slot "^1.1.0" - debug "^4.3.4" - denque "^2.1.0" - lodash.defaults "^4.2.0" - lodash.isarguments "^3.1.0" - redis-errors "^1.2.0" - redis-parser "^3.0.0" - standard-as-callback "^2.1.0" - - ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== - - ipaddr.js@1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" - integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== - - ipaddr.js@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.1.0.tgz#2119bc447ff8c257753b196fc5f1ce08a4cdf39f" - integrity sha512-LlbxQ7xKzfBusov6UMi4MFpEg0m+mAm9xyNGEduwXMEDuf4WfzB/RZwMVYEd7IKGvh4IUkEXYxtAVu9T3OelJQ== - - iron-webcrypto@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/iron-webcrypto/-/iron-webcrypto-1.0.0.tgz#e3b689c0c61b434a0a4cb82d0aeabbc8b672a867" - integrity sha512-anOK1Mktt8U1Xi7fCM3RELTuYbnFikQY5VtrDj7kPgpejV7d43tWKhzgioO0zpkazLEL/j/iayRqnJhrGfqUsg== - - is-absolute-url@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" - integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== - - is-accessor-descriptor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.1.tgz#3223b10628354644b86260db29b3e693f5ceedd4" - integrity sha512-YBUanLI8Yoihw923YeFUS5fs0fF2f5TSFTNiYAAzhhDscDa3lEqYuz1pDOEP5KvX94I9ey3vsqjJcLVFVU+3QA== - dependencies: - hasown "^2.0.0" - - is-alphabetical@1.0.4, is-alphabetical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" - integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== - - is-alphabetical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-2.0.1.tgz#01072053ea7c1036df3c7d19a6daaec7f19e789b" - integrity sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ== - - is-alphanumerical@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" - integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== - dependencies: - is-alphabetical "^1.0.0" - is-decimal "^1.0.0" - - is-alphanumerical@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz#7c03fbe96e3e931113e57f964b0a368cc2dfd875" - integrity sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw== - dependencies: - is-alphabetical "^2.0.0" - is-decimal "^2.0.0" - - is-arguments@^1.0.4, is-arguments@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" - integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - - is-array-buffer@^3.0.1, is-array-buffer@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-array-buffer/-/is-array-buffer-3.0.2.tgz#f2653ced8412081638ecb0ebbd0c41c6e0aecbbe" - integrity sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.0" - is-typed-array "^1.1.10" - - is-arrayish@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" - integrity sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg== - - is-arrayish@^0.3.1: - version "0.3.2" - resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.3.2.tgz#4574a2ae56f7ab206896fb431eaeed066fdf8f03" - integrity sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ== - - is-async-function@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-async-function/-/is-async-function-2.0.0.tgz#8e4418efd3e5d3a6ebb0164c05ef5afb69aa9646" - integrity sha512-Y1JXKrfykRJGdlDwdKlLpLyMIiWqWvuSd17TvZk68PLAOGOoF4Xyav1z0Xhoi+gCYjZVeC5SI+hYFOfvXmGRCA== - dependencies: - has-tostringtag "^1.0.0" - - is-bigint@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" - integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== - dependencies: - has-bigints "^1.0.1" - - is-binary-path@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== - dependencies: - binary-extensions "^1.0.0" - - is-binary-path@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" - integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== - dependencies: - binary-extensions "^2.0.0" - - is-boolean-object@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" - integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - - is-buffer@^1.1.5: - version "1.1.6" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" - integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== - - is-buffer@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" - integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== - - is-builtin-module@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-3.2.1.tgz#f03271717d8654cfcaf07ab0463faa3571581169" - integrity sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A== - dependencies: - builtin-modules "^3.3.0" - - is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: - version "1.2.7" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" - integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== - - is-ci@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-3.0.1.tgz#db6ecbed1bd659c43dac0f45661e7674103d1867" - integrity sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ== - dependencies: - ci-info "^3.2.0" - - is-ci@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" - integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== - dependencies: - ci-info "^2.0.0" - - is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0, is-core-module@^2.8.1: - version "2.13.1" - resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.13.1.tgz#ad0d7532c6fea9da1ebdc82742d74525c6273384" - integrity sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw== - dependencies: - hasown "^2.0.0" - - is-data-descriptor@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.1.tgz#2109164426166d32ea38c405c1e0945d9e6a4eeb" - integrity sha512-bc4NlCDiCr28U4aEsQ3Qs2491gVq4V8G7MQyws968ImqjKuYtTJXrl7Vq7jsN7Ly/C3xj5KWFrY7sHNeDkAzXw== - dependencies: - hasown "^2.0.0" - - is-date-object@^1.0.1, is-date-object@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.5.tgz#0841d5536e724c25597bf6ea62e1bd38298df31f" - integrity sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ== - dependencies: - has-tostringtag "^1.0.0" - - is-decimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" - integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== - - is-decimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-2.0.1.tgz#9469d2dc190d0214fd87d78b78caecc0cc14eef7" - integrity sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A== - - is-descriptor@^0.1.0: - version "0.1.7" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.7.tgz#2727eb61fd789dcd5bdf0ed4569f551d2fe3be33" - integrity sha512-C3grZTvObeN1xud4cRWl366OMXZTj0+HGyk4hvfpx4ZHt1Pb60ANSXqCK7pdOTeUQpRzECBSTphqvD7U+l22Eg== - dependencies: - is-accessor-descriptor "^1.0.1" - is-data-descriptor "^1.0.1" - - is-descriptor@^1.0.0, is-descriptor@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.3.tgz#92d27cb3cd311c4977a4db47df457234a13cb306" - integrity sha512-JCNNGbwWZEVaSPtS45mdtrneRWJFp07LLmykxeFV5F6oBvNF8vHSfJuJgoT472pSfk+Mf8VnlrspaFBHWM8JAw== - dependencies: - is-accessor-descriptor "^1.0.1" - is-data-descriptor "^1.0.1" - - is-docker@^2.0.0, is-docker@^2.1.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" - integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== - - is-dom@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" - integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== - dependencies: - is-object "^1.0.1" - is-window "^1.0.2" - - is-extendable@^0.1.0, is-extendable@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== - - is-extendable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" - integrity sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA== - dependencies: - is-plain-object "^2.0.4" - - is-extglob@^2.1.0, is-extglob@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" - integrity sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ== - - is-finalizationregistry@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-finalizationregistry/-/is-finalizationregistry-1.0.2.tgz#c8749b65f17c133313e661b1289b95ad3dbd62e6" - integrity sha512-0by5vtUJs8iFQb5TYUHHPudOR+qXYIMKtiUzvLIZITZUjknFmziyBJuLhVRc+Ds0dREFlskDNJKYIdIzu/9pfw== - dependencies: - call-bind "^1.0.2" - - is-finite@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" - integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== - - is-fullwidth-code-point@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" - integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== - - is-function@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" - integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== - - is-generator-fn@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-2.1.0.tgz#7d140adc389aaf3011a8f2a2a4cfa6faadffb118" - integrity sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ== - - is-generator-function@^1.0.10, is-generator-function@^1.0.7: - version "1.0.10" - resolved "https://registry.yarnpkg.com/is-generator-function/-/is-generator-function-1.0.10.tgz#f1558baf1ac17e0deea7c0415c438351ff2b3c72" - integrity sha512-jsEjy9l3yiXEQ+PsXdmBwEPcOxaXWLspKdplFUVI9vq1iZgIekeC0L167qeu86czQaxed3q/Uzuw0swL0irL8A== - dependencies: - has-tostringtag "^1.0.0" - - is-glob@^3.0.0, is-glob@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== - dependencies: - is-extglob "^2.1.0" - - is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: - version "4.0.3" - resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" - integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== - dependencies: - is-extglob "^2.1.1" - - is-hexadecimal@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" - integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== - - is-hexadecimal@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz#86b5bf668fca307498d319dfc03289d781a90027" - integrity sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg== - - is-in-browser@^1.0.2, is-in-browser@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/is-in-browser/-/is-in-browser-1.1.3.tgz#56ff4db683a078c6082eb95dad7dc62e1d04f835" - integrity sha512-FeXIBgG/CPGd/WUxuEyvgGTEfwiG9Z4EKGxjNMRqviiIIfsmgrpnHLffEDdwUHqNva1VEW91o3xBT/m8Elgl9g== - - is-interactive@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" - integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== - - is-lambda@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" - integrity sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ== - - is-map@^2.0.1, is-map@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" - integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== - - is-module@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" - integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== - - is-negative-zero@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" - integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== - - is-number-object@^1.0.4: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" - integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== - dependencies: - has-tostringtag "^1.0.0" - - is-number@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== - dependencies: - kind-of "^3.0.2" - - is-number@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" - integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== - - is-obj@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-obj/-/is-obj-2.0.0.tgz#473fb05d973705e3fd9620545018ca8e22ef4982" - integrity sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w== - - is-object@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" - integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== - - is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - - is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - - is-path-inside@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" - - is-path-inside@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.3.tgz#d231362e53a07ff2b0e0ea7fed049161ffd16283" - integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== - - is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" - integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== - - is-plain-obj@^2.0.0, is-plain-obj@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" - integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== - - is-plain-obj@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" - integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== - - is-plain-obj@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-4.1.0.tgz#d65025edec3657ce032fd7db63c97883eaed71f0" - integrity sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg== - - is-plain-object@5.0.0, is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - - is-plain-object@^2.0.3, is-plain-object@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" - integrity sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og== - dependencies: - isobject "^3.0.1" - - is-potential-custom-element-name@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz#171ed6f19e3ac554394edf78caa05784a45bebb5" - integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== - - is-reference@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" - integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== - dependencies: - "@types/estree" "*" - - is-reference@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-3.0.2.tgz#154747a01f45cd962404ee89d43837af2cba247c" - integrity sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg== - dependencies: - "@types/estree" "*" - - is-regex@^1.1.2, is-regex@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" - integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== - dependencies: - call-bind "^1.0.2" - has-tostringtag "^1.0.0" - - is-set@^2.0.1, is-set@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" - integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== - - is-shared-array-buffer@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" - integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== - dependencies: - call-bind "^1.0.2" - - is-ssh@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/is-ssh/-/is-ssh-1.4.0.tgz#4f8220601d2839d8fa624b3106f8e8884f01b8b2" - integrity sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ== - dependencies: - protocols "^2.0.1" - - is-stream@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.0.tgz#bde9c32680d6fae04129d6ac9d921ce7815f78e3" - integrity sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw== - - is-stream@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" - integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== - - is-stream@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" - integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== - - is-string@^1.0.5, is-string@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" - integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== - dependencies: - has-tostringtag "^1.0.0" - - is-symbol@^1.0.2, is-symbol@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" - integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== - dependencies: - has-symbols "^1.0.2" - - is-text-path@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/is-text-path/-/is-text-path-1.0.1.tgz#4e1aa0fb51bfbcb3e92688001397202c1775b66e" - integrity sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w== - dependencies: - text-extensions "^1.0.0" - - is-typed-array@^1.1.10, is-typed-array@^1.1.12, is-typed-array@^1.1.3, is-typed-array@^1.1.9: - version "1.1.12" - resolved "https://registry.yarnpkg.com/is-typed-array/-/is-typed-array-1.1.12.tgz#d0bab5686ef4a76f7a73097b95470ab199c57d4a" - integrity sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg== - dependencies: - which-typed-array "^1.1.11" - - is-typedarray@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" - integrity sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA== - - is-unicode-supported@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" - integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== - - is-utf8@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" - integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== - - is-weakmap@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" - integrity sha512-NSBR4kH5oVj1Uwvv970ruUkCV7O1mzgVFO4/rev2cLRda9Tm9HrL70ZPut4rOHgY0FNrUu9BCbXA2sdQ+x0chA== - - is-weakref@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" - integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== - dependencies: - call-bind "^1.0.2" - - is-weakset@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/is-weakset/-/is-weakset-2.0.2.tgz#4569d67a747a1ce5a994dfd4ef6dcea76e7c0a1d" - integrity sha512-t2yVvttHkQktwnNNmBQ98AhENLdPUTDTE21uPqAQ0ARwQfGeQKRVS0NNurH7bTf7RrvcVn1OOge45CnBeHCSmg== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.1" - - is-whitespace-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" - integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== - - is-window@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" - integrity sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg== - - is-windows@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" - integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== - - is-word-character@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" - integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== - - is-wsl@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== - - is-wsl@^2.1.1, is-wsl@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" - integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== - dependencies: - is-docker "^2.0.0" - - isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - - isarray@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" - integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== - - isexe@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" - integrity sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw== - - isobject@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== - dependencies: - isarray "1.0.0" - - isobject@^3.0.0, isobject@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" - integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== - - isobject@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" - integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== - - isomorphic-unfetch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" - integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== - dependencies: - node-fetch "^2.6.1" - unfetch "^4.2.0" - - isomorphic-ws@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/isomorphic-ws/-/isomorphic-ws-4.0.1.tgz#55fd4cd6c5e6491e76dc125938dd863f5cd4f2dc" - integrity sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w== - - istanbul-lib-coverage@^3.0.0, istanbul-lib-coverage@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz#2d166c4b0644d43a39f04bf6c2edd1e585f31756" - integrity sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg== - - istanbul-lib-instrument@^5.0.4, istanbul-lib-instrument@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz#d10c8885c2125574e1c231cacadf955675e1ce3d" - integrity sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg== - dependencies: - "@babel/core" "^7.12.3" - "@babel/parser" "^7.14.7" - "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.2.0" - semver "^6.3.0" - - istanbul-lib-report@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz#908305bac9a5bd175ac6a74489eafd0fc2445a7d" - integrity sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw== - dependencies: - istanbul-lib-coverage "^3.0.0" - make-dir "^4.0.0" - supports-color "^7.1.0" - - istanbul-lib-source-maps@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz#895f3a709fcfba34c6de5a42939022f3e4358551" - integrity sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw== - dependencies: - debug "^4.1.1" - istanbul-lib-coverage "^3.0.0" - source-map "^0.6.1" - - istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: - version "3.1.6" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.6.tgz#2544bcab4768154281a2f0870471902704ccaa1a" - integrity sha512-TLgnMkKg3iTDsQ9PbPTdpfAK2DzjF9mqUG7RMgcQl8oFjad8ob4laGxv5XV5U9MAfx8D6tSJiUyuAwzLicaxlg== - dependencies: - html-escaper "^2.0.0" - istanbul-lib-report "^3.0.0" - - iterate-iterator@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" - integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== - - iterate-value@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" - integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== - dependencies: - es-get-iterator "^1.0.2" - iterate-iterator "^1.0.1" - - iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== - dependencies: - define-properties "^1.2.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - reflect.getprototypeof "^1.0.4" - set-function-name "^2.0.1" - - jackspeak@^2.3.5: - version "2.3.6" - resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-2.3.6.tgz#647ecc472238aee4b06ac0e461acc21a8c505ca8" - integrity sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ== - dependencies: - "@isaacs/cliui" "^8.0.2" - optionalDependencies: - "@pkgjs/parseargs" "^0.11.0" - - jake@^10.8.5: - version "10.8.7" - resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.7.tgz#63a32821177940c33f356e0ba44ff9d34e1c7d8f" - integrity sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w== - dependencies: - async "^3.2.3" - chalk "^4.0.2" - filelist "^1.0.4" - minimatch "^3.1.2" - - javascript-stringify@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/javascript-stringify/-/javascript-stringify-2.1.0.tgz#27c76539be14d8bd128219a2d731b09337904e79" - integrity sha512-JVAfqNPTvNq3sB/VHQJAFxN/sPgKnsKrCwyRt15zwNCdrMMJDdcEOdubuy+DuJYYdm0ox1J4uzEuYKkN+9yhVg== - - jest-changed-files@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-27.5.1.tgz#a348aed00ec9bf671cc58a66fcbe7c3dfd6a68f5" - integrity sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw== - dependencies: - "@jest/types" "^27.5.1" - execa "^5.0.0" - throat "^6.0.1" - - jest-circus@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-27.5.1.tgz#37a5a4459b7bf4406e53d637b49d22c65d125ecc" - integrity sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - dedent "^0.7.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - throat "^6.0.1" - - jest-cli@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-27.5.1.tgz#278794a6e6458ea8029547e6c6cbf673bd30b145" - integrity sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw== - dependencies: - "@jest/core" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - exit "^0.1.2" - graceful-fs "^4.2.9" - import-local "^3.0.2" - jest-config "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - prompts "^2.0.1" - yargs "^16.2.0" - - jest-config@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-27.5.1.tgz#5c387de33dca3f99ad6357ddeccd91bf3a0e4a41" - integrity sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA== - dependencies: - "@babel/core" "^7.8.0" - "@jest/test-sequencer" "^27.5.1" - "@jest/types" "^27.5.1" - babel-jest "^27.5.1" - chalk "^4.0.0" - ci-info "^3.2.0" - deepmerge "^4.2.2" - glob "^7.1.1" - graceful-fs "^4.2.9" - jest-circus "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-get-type "^27.5.1" - jest-jasmine2 "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runner "^27.5.1" - jest-util "^27.5.1" - jest-validate "^27.5.1" - micromatch "^4.0.4" - parse-json "^5.2.0" - pretty-format "^27.5.1" - slash "^3.0.0" - strip-json-comments "^3.1.1" - - "jest-diff@>=29.4.3 < 30", jest-diff@^29.4.1, jest-diff@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.7.0.tgz#017934a66ebb7ecf6f205e84699be10afd70458a" - integrity sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw== - dependencies: - chalk "^4.0.0" - diff-sequences "^29.6.3" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - - jest-diff@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-27.5.1.tgz#a07f5011ac9e6643cf8a95a462b7b1ecf6680def" - integrity sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw== - dependencies: - chalk "^4.0.0" - diff-sequences "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - - jest-diff@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-28.1.3.tgz#948a192d86f4e7a64c5264ad4da4877133d8792f" - integrity sha512-8RqP1B/OXzjjTWkqMX67iqgwBVJRgCyKD3L9nq+6ZqJMdvjE8RgHktqZ6jNrkdMT+dJuYNI3rhQpxaz7drJHfw== - dependencies: - chalk "^4.0.0" - diff-sequences "^28.1.1" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - - jest-docblock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-27.5.1.tgz#14092f364a42c6108d42c33c8cf30e058e25f6c0" - integrity sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ== - dependencies: - detect-newline "^3.0.0" - - jest-each@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-27.5.1.tgz#5bc87016f45ed9507fed6e4702a5b468a5b2c44e" - integrity sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - jest-get-type "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - - jest-environment-jsdom@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz#ea9ccd1fc610209655a77898f86b2b559516a546" - integrity sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - jsdom "^16.6.0" - - jest-environment-node@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-27.5.1.tgz#dedc2cfe52fab6b8f5714b4808aefa85357a365e" - integrity sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - jest-mock "^27.5.1" - jest-util "^27.5.1" - - jest-get-type@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-27.5.1.tgz#3cd613c507b0f7ace013df407a1c1cd578bcb4f1" - integrity sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw== - - jest-get-type@^28.0.2: - version "28.0.2" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" - integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== - - jest-get-type@^29.6.3: - version "29.6.3" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.6.3.tgz#36f499fdcea197c1045a127319c0481723908fd1" - integrity sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw== - - jest-haste-map@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" - integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== - dependencies: - "@jest/types" "^26.6.2" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.4" - jest-regex-util "^26.0.0" - jest-serializer "^26.6.2" - jest-util "^26.6.2" - jest-worker "^26.6.2" - micromatch "^4.0.2" - sane "^4.0.3" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.1.2" - - jest-haste-map@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-27.5.1.tgz#9fd8bd7e7b4fa502d9c6164c5640512b4e811e7f" - integrity sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng== - dependencies: - "@jest/types" "^27.5.1" - "@types/graceful-fs" "^4.1.2" - "@types/node" "*" - anymatch "^3.0.3" - fb-watchman "^2.0.0" - graceful-fs "^4.2.9" - jest-regex-util "^27.5.1" - jest-serializer "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - micromatch "^4.0.4" - walker "^1.0.7" - optionalDependencies: - fsevents "^2.3.2" - - jest-jasmine2@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz#a037b0034ef49a9f3d71c4375a796f3b230d1ac4" - integrity sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - co "^4.6.0" - expect "^27.5.1" - is-generator-fn "^2.0.0" - jest-each "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-runtime "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - pretty-format "^27.5.1" - throat "^6.0.1" - - jest-leak-detector@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz#6ec9d54c3579dd6e3e66d70e3498adf80fde3fb8" - integrity sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ== - dependencies: - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - - jest-matcher-utils@^27.0.0, jest-matcher-utils@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz#9c0cdbda8245bc22d2331729d1091308b40cf8ab" - integrity sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw== - dependencies: - chalk "^4.0.0" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - pretty-format "^27.5.1" - - jest-matcher-utils@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-28.1.3.tgz#5a77f1c129dd5ba3b4d7fc20728806c78893146e" - integrity sha512-kQeJ7qHemKfbzKoGjHHrRKH6atgxMk8Enkk2iPQ3XwO6oE/KYD8lMYOziCkeSB9G4adPM4nR1DE8Tf5JeWH6Bw== - dependencies: - chalk "^4.0.0" - jest-diff "^28.1.3" - jest-get-type "^28.0.2" - pretty-format "^28.1.3" - - jest-matcher-utils@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz#ae8fec79ff249fd592ce80e3ee474e83a6c44f12" - integrity sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g== - dependencies: - chalk "^4.0.0" - jest-diff "^29.7.0" - jest-get-type "^29.6.3" - pretty-format "^29.7.0" - - jest-message-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-27.5.1.tgz#bdda72806da10d9ed6425e12afff38cd1458b6cf" - integrity sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^27.5.1" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^27.5.1" - slash "^3.0.0" - stack-utils "^2.0.3" - - jest-message-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-28.1.3.tgz#232def7f2e333f1eecc90649b5b94b0055e7c43d" - integrity sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^28.1.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^28.1.3" - slash "^3.0.0" - stack-utils "^2.0.3" - - jest-message-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.7.0.tgz#8bc392e204e95dfe7564abbe72a404e28e51f7f3" - integrity sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w== - dependencies: - "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.6.3" - "@types/stack-utils" "^2.0.0" - chalk "^4.0.0" - graceful-fs "^4.2.9" - micromatch "^4.0.4" - pretty-format "^29.7.0" - slash "^3.0.0" - stack-utils "^2.0.3" - - jest-mock@^27.0.6, jest-mock@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" - integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - - jest-pnp-resolver@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" - integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== - - jest-regex-util@^26.0.0: - version "26.0.0" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" - integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== - - jest-regex-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-27.5.1.tgz#4da143f7e9fd1e542d4aa69617b38e4a78365b95" - integrity sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg== - - jest-resolve-dependencies@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz#d811ecc8305e731cc86dd79741ee98fed06f1da8" - integrity sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg== - dependencies: - "@jest/types" "^27.5.1" - jest-regex-util "^27.5.1" - jest-snapshot "^27.5.1" - - jest-resolve@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-27.5.1.tgz#a2f1c5a0796ec18fe9eb1536ac3814c23617b384" - integrity sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw== - dependencies: - "@jest/types" "^27.5.1" - chalk "^4.0.0" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-pnp-resolver "^1.2.2" - jest-util "^27.5.1" - jest-validate "^27.5.1" - resolve "^1.20.0" - resolve.exports "^1.1.0" - slash "^3.0.0" - - jest-runner@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-27.5.1.tgz#071b27c1fa30d90540805c5645a0ec167c7b62e5" - integrity sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ== - dependencies: - "@jest/console" "^27.5.1" - "@jest/environment" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - emittery "^0.8.1" - graceful-fs "^4.2.9" - jest-docblock "^27.5.1" - jest-environment-jsdom "^27.5.1" - jest-environment-node "^27.5.1" - jest-haste-map "^27.5.1" - jest-leak-detector "^27.5.1" - jest-message-util "^27.5.1" - jest-resolve "^27.5.1" - jest-runtime "^27.5.1" - jest-util "^27.5.1" - jest-worker "^27.5.1" - source-map-support "^0.5.6" - throat "^6.0.1" - - jest-runtime@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-27.5.1.tgz#4896003d7a334f7e8e4a53ba93fb9bcd3db0a1af" - integrity sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A== - dependencies: - "@jest/environment" "^27.5.1" - "@jest/fake-timers" "^27.5.1" - "@jest/globals" "^27.5.1" - "@jest/source-map" "^27.5.1" - "@jest/test-result" "^27.5.1" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - chalk "^4.0.0" - cjs-module-lexer "^1.0.0" - collect-v8-coverage "^1.0.0" - execa "^5.0.0" - glob "^7.1.3" - graceful-fs "^4.2.9" - jest-haste-map "^27.5.1" - jest-message-util "^27.5.1" - jest-mock "^27.5.1" - jest-regex-util "^27.5.1" - jest-resolve "^27.5.1" - jest-snapshot "^27.5.1" - jest-util "^27.5.1" - slash "^3.0.0" - strip-bom "^4.0.0" - - jest-serializer@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" - integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.4" - - jest-serializer@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-27.5.1.tgz#81438410a30ea66fd57ff730835123dea1fb1f64" - integrity sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w== - dependencies: - "@types/node" "*" - graceful-fs "^4.2.9" - - jest-snapshot@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-27.5.1.tgz#b668d50d23d38054a51b42c4039cab59ae6eb6a1" - integrity sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA== - dependencies: - "@babel/core" "^7.7.2" - "@babel/generator" "^7.7.2" - "@babel/plugin-syntax-typescript" "^7.7.2" - "@babel/traverse" "^7.7.2" - "@babel/types" "^7.0.0" - "@jest/transform" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/babel__traverse" "^7.0.4" - "@types/prettier" "^2.1.5" - babel-preset-current-node-syntax "^1.0.0" - chalk "^4.0.0" - expect "^27.5.1" - graceful-fs "^4.2.9" - jest-diff "^27.5.1" - jest-get-type "^27.5.1" - jest-haste-map "^27.5.1" - jest-matcher-utils "^27.5.1" - jest-message-util "^27.5.1" - jest-util "^27.5.1" - natural-compare "^1.4.0" - pretty-format "^27.5.1" - semver "^7.3.2" - - jest-util@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" - integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== - dependencies: - "@jest/types" "^26.6.2" - "@types/node" "*" - chalk "^4.0.0" - graceful-fs "^4.2.4" - is-ci "^2.0.0" - micromatch "^4.0.2" - - jest-util@^27.0.0, jest-util@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-27.5.1.tgz#3ba9771e8e31a0b85da48fe0b0891fb86c01c2f9" - integrity sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw== - dependencies: - "@jest/types" "^27.5.1" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - - jest-util@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-28.1.3.tgz#f4f932aa0074f0679943220ff9cbba7e497028b0" - integrity sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ== - dependencies: - "@jest/types" "^28.1.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - - jest-util@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.7.0.tgz#23c2b62bfb22be82b44de98055802ff3710fc0bc" - integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA== - dependencies: - "@jest/types" "^29.6.3" - "@types/node" "*" - chalk "^4.0.0" - ci-info "^3.2.0" - graceful-fs "^4.2.9" - picomatch "^2.2.3" - - jest-validate@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-27.5.1.tgz#9197d54dc0bdb52260b8db40b46ae668e04df067" - integrity sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ== - dependencies: - "@jest/types" "^27.5.1" - camelcase "^6.2.0" - chalk "^4.0.0" - jest-get-type "^27.5.1" - leven "^3.1.0" - pretty-format "^27.5.1" - - jest-watcher@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-27.5.1.tgz#71bd85fb9bde3a2c2ec4dc353437971c43c642a2" - integrity sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw== - dependencies: - "@jest/test-result" "^27.5.1" - "@jest/types" "^27.5.1" - "@types/node" "*" - ansi-escapes "^4.2.1" - chalk "^4.0.0" - jest-util "^27.5.1" - string-length "^4.0.1" - - jest-worker@^26.5.0, jest-worker@^26.6.2: - version "26.6.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" - integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^7.0.0" - - jest-worker@^27.0.2, jest-worker@^27.4.5, jest-worker@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" - integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== - dependencies: - "@types/node" "*" - merge-stream "^2.0.0" - supports-color "^8.0.0" - - jest@^27.1.0: - version "27.5.1" - resolved "https://registry.yarnpkg.com/jest/-/jest-27.5.1.tgz#dadf33ba70a779be7a6fc33015843b51494f63fc" - integrity sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ== - dependencies: - "@jest/core" "^27.5.1" - import-local "^3.0.2" - jest-cli "^27.5.1" - - jiti@^1.20.0: - version "1.21.0" - resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.0.tgz#7c97f8fe045724e136a397f7340475244156105d" - integrity sha512-gFqAIbuKyyso/3G2qhiO2OM6shY6EPP/R0+mkDbyspxKazh8BXDC5FiFsUjlczgdNz/vfra0da2y+aHrusLG/Q== - - joi@^17.11.0: - version "17.11.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-17.11.0.tgz#aa9da753578ec7720e6f0ca2c7046996ed04fc1a" - integrity sha512-NgB+lZLNoqISVy1rZocE9PZI36bL/77ie924Ri43yEvi9GUUMPeyVIr8KdFTMUlby1p0PBYMk9spIxEUQYqrJQ== - dependencies: - "@hapi/hoek" "^9.0.0" - "@hapi/topo" "^5.0.0" - "@sideway/address" "^4.1.3" - "@sideway/formula" "^3.0.1" - "@sideway/pinpoint" "^2.0.0" - - js-sha3@0.8.0, js-sha3@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.8.0.tgz#b9b7a5da73afad7dedd0f8c463954cbde6818840" - integrity sha512-gF1cRrHhIzNfToc802P800N8PpXS+evLLXfsVpowqmAFR9uwbi89WvXg2QspOmXL8QL86J4T1EpFu+yUkwJY3Q== - - js-string-escape@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" - integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== - - "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" - integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== - - js-yaml@4.1.0, js-yaml@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" - integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== - dependencies: - argparse "^2.0.1" - - js-yaml@^3.10.0, js-yaml@^3.13.1: - version "3.14.1" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.14.1.tgz#dae812fdb3825fa306609a8717383c50c36a0537" - integrity sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g== - dependencies: - argparse "^1.0.7" - esprima "^4.0.0" - - jsdom@^16.6.0: - version "16.7.0" - resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-16.7.0.tgz#918ae71965424b197c819f8183a754e18977b710" - integrity sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw== - dependencies: - abab "^2.0.5" - acorn "^8.2.4" - acorn-globals "^6.0.0" - cssom "^0.4.4" - cssstyle "^2.3.0" - data-urls "^2.0.0" - decimal.js "^10.2.1" - domexception "^2.0.1" - escodegen "^2.0.0" - form-data "^3.0.0" - html-encoding-sniffer "^2.0.1" - http-proxy-agent "^4.0.1" - https-proxy-agent "^5.0.0" - is-potential-custom-element-name "^1.0.1" - nwsapi "^2.2.0" - parse5 "6.0.1" - saxes "^5.0.1" - symbol-tree "^3.2.4" - tough-cookie "^4.0.0" - w3c-hr-time "^1.0.2" - w3c-xmlserializer "^2.0.0" - webidl-conversions "^6.1.0" - whatwg-encoding "^1.0.5" - whatwg-mimetype "^2.3.0" - whatwg-url "^8.5.0" - ws "^7.4.6" - xml-name-validator "^3.0.0" - - jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - - jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== - - json-buffer@3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13" - integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== - - json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" - integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== - - json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" - integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== - - json-parse-even-better-errors@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz#02bb29fb5da90b5444581749c22cedd3597c6cb0" - integrity sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg== - - json-schema-traverse@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" - integrity sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg== - - json-schema-traverse@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz#ae7bcb3656ab77a73ba5c49bf654f38e6b6860e2" - integrity sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug== - - json-stable-stringify-without-jsonify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz#9db7b59496ad3f3cfef30a75142d2d930ad72651" - integrity sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw== - - json-stringify-safe@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" - integrity sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA== - - json5@2.x, json5@^2.1.0, json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: - version "2.2.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" - integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== - - json5@^1.0.1, json5@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.2.tgz#63d98d60f21b313b77c4d6da18bfa69d80e1d593" - integrity sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA== - dependencies: - minimist "^1.2.0" - - jsonc-parser@3.2.0, jsonc-parser@^3.0.0, jsonc-parser@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.2.0.tgz#31ff3f4c2b9793f89c67212627c51c6394f88e76" - integrity sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w== - - jsonfile@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" - integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== - dependencies: - universalify "^2.0.0" - optionalDependencies: - graceful-fs "^4.1.6" - - jsonparse@^1.2.0, jsonparse@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" - integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== - - jss-plugin-camel-case@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-camel-case/-/jss-plugin-camel-case-10.10.0.tgz#27ea159bab67eb4837fa0260204eb7925d4daa1c" - integrity sha512-z+HETfj5IYgFxh1wJnUAU8jByI48ED+v0fuTuhKrPR+pRBYS2EDwbusU8aFOpCdYhtRc9zhN+PJ7iNE8pAWyPw== - dependencies: - "@babel/runtime" "^7.3.1" - hyphenate-style-name "^1.0.3" - jss "10.10.0" - - jss-plugin-default-unit@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-default-unit/-/jss-plugin-default-unit-10.10.0.tgz#db3925cf6a07f8e1dd459549d9c8aadff9804293" - integrity sha512-SvpajxIECi4JDUbGLefvNckmI+c2VWmP43qnEy/0eiwzRUsafg5DVSIWSzZe4d2vFX1u9nRDP46WCFV/PXVBGQ== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - - jss-plugin-global@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-global/-/jss-plugin-global-10.10.0.tgz#1c55d3c35821fab67a538a38918292fc9c567efd" - integrity sha512-icXEYbMufiNuWfuazLeN+BNJO16Ge88OcXU5ZDC2vLqElmMybA31Wi7lZ3lf+vgufRocvPj8443irhYRgWxP+A== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - - jss-plugin-nested@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-nested/-/jss-plugin-nested-10.10.0.tgz#db872ed8925688806e77f1fc87f6e62264513219" - integrity sha512-9R4JHxxGgiZhurDo3q7LdIiDEgtA1bTGzAbhSPyIOWb7ZubrjQe8acwhEQ6OEKydzpl8XHMtTnEwHXCARLYqYA== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - tiny-warning "^1.0.2" - - jss-plugin-props-sort@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-props-sort/-/jss-plugin-props-sort-10.10.0.tgz#67f4dd4c70830c126f4ec49b4b37ccddb680a5d7" - integrity sha512-5VNJvQJbnq/vRfje6uZLe/FyaOpzP/IH1LP+0fr88QamVrGJa0hpRRyAa0ea4U/3LcorJfBFVyC4yN2QC73lJg== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - - jss-plugin-rule-value-function@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-rule-value-function/-/jss-plugin-rule-value-function-10.10.0.tgz#7d99e3229e78a3712f78ba50ab342e881d26a24b" - integrity sha512-uEFJFgaCtkXeIPgki8ICw3Y7VMkL9GEan6SqmT9tqpwM+/t+hxfMUdU4wQ0MtOiMNWhwnckBV0IebrKcZM9C0g== - dependencies: - "@babel/runtime" "^7.3.1" - jss "10.10.0" - tiny-warning "^1.0.2" - - jss-plugin-vendor-prefixer@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss-plugin-vendor-prefixer/-/jss-plugin-vendor-prefixer-10.10.0.tgz#c01428ef5a89f2b128ec0af87a314d0c767931c7" - integrity sha512-UY/41WumgjW8r1qMCO8l1ARg7NHnfRVWRhZ2E2m0DMYsr2DD91qIXLyNhiX83hHswR7Wm4D+oDYNC1zWCJWtqg== - dependencies: - "@babel/runtime" "^7.3.1" - css-vendor "^2.0.8" - jss "10.10.0" - - jss@10.10.0, jss@^10.10.0: - version "10.10.0" - resolved "https://registry.yarnpkg.com/jss/-/jss-10.10.0.tgz#a75cc85b0108c7ac8c7b7d296c520a3e4fbc6ccc" - integrity sha512-cqsOTS7jqPsPMjtKYDUpdFC0AbhYFLTcuGRqymgmdJIeQ8cH7+AgX7YSgQy79wXloZq2VvATYxUOUQEvS1V/Zw== - dependencies: - "@babel/runtime" "^7.3.1" - csstype "^3.0.2" - is-in-browser "^1.1.3" - tiny-warning "^1.0.2" - - "jsx-ast-utils@^2.4.1 || ^3.0.0", jsx-ast-utils@^3.3.5: - version "3.3.5" - resolved "https://registry.yarnpkg.com/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz#4766bd05a8e2a11af222becd19e15575e52a853a" - integrity sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ== - dependencies: - array-includes "^3.1.6" - array.prototype.flat "^1.3.1" - object.assign "^4.1.4" - object.values "^1.1.6" - - junk@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" - integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== - - keyv@^4.5.3: - version "4.5.4" - resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.5.4.tgz#a879a99e29452f942439f2a405e3af8b31d4de93" - integrity sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw== - dependencies: - json-buffer "3.0.1" - - keyvaluestorage-interface@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/keyvaluestorage-interface/-/keyvaluestorage-interface-1.0.0.tgz#13ebdf71f5284ad54be94bd1ad9ed79adad515ff" - integrity sha512-8t6Q3TclQ4uZynJY9IGr2+SsIGwK9JHcO6ootkHCGA0CrQCRy+VkouYNO2xicET6b9al7QKzpebNow+gkpCL8g== - - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== - dependencies: - is-buffer "^1.1.5" - - kind-of@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== - dependencies: - is-buffer "^1.1.5" - - kind-of@^6.0.2, kind-of@^6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" - integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== - - kleur@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" - integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== - - kleur@^4.0.3: - version "4.1.5" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.1.5.tgz#95106101795f7050c6c650f350c683febddb1780" - integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== - - klona@^2.0.4: - version "2.0.6" - resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.6.tgz#85bffbf819c03b2f53270412420a4555ef882e22" - integrity sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA== - - language-subtag-registry@^0.3.20: - version "0.3.22" - resolved "https://registry.yarnpkg.com/language-subtag-registry/-/language-subtag-registry-0.3.22.tgz#2e1500861b2e457eba7e7ae86877cbd08fa1fd1d" - integrity sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w== - - language-tags@^1.0.9: - version "1.0.9" - resolved "https://registry.yarnpkg.com/language-tags/-/language-tags-1.0.9.tgz#1ffdcd0ec0fafb4b1be7f8b11f306ad0f9c08777" - integrity sha512-MbjN408fEndfiQXbFQ1vnd+1NoLDsnQW41410oQBXiyXDMYH5z505juWa4KUE1LqxRC7DgOgZDbKLxHIwm27hA== - dependencies: - language-subtag-registry "^0.3.20" - - launch-editor@^2.6.0: - version "2.6.1" - resolved "https://registry.yarnpkg.com/launch-editor/-/launch-editor-2.6.1.tgz#f259c9ef95cbc9425620bbbd14b468fcdb4ffe3c" - integrity sha512-eB/uXmFVpY4zezmGp5XtU21kwo7GBbKB+EQ+UZeWtGb9yAM5xt/Evk+lYH3eRNAtId+ej4u7TYPFZ07w4s7rRw== - dependencies: - picocolors "^1.0.0" - shell-quote "^1.8.1" - - lazy-universal-dotenv@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" - integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== - dependencies: - "@babel/runtime" "^7.5.0" - app-root-dir "^1.0.2" - core-js "^3.0.4" - dotenv "^8.0.0" - dotenv-expand "^5.1.0" - - "legacy-swc-helpers@npm:@swc/helpers@=0.4.14": - version "0.4.14" - resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74" - integrity sha512-4C7nX/dvpzB7za4Ql9K81xK3HPxCpHMgwTZVyf+9JQ6VUbn9jjZVN7/Nkdz/Ugzs2CSjqnL/UPXroiVBVHUWUw== - dependencies: - tslib "^2.4.0" - - lerna@^7.3.0: - version "7.4.2" - resolved "https://registry.yarnpkg.com/lerna/-/lerna-7.4.2.tgz#03497125d7b7c8d463eebfe17a701b16bde2ad09" - integrity sha512-gxavfzHfJ4JL30OvMunmlm4Anw7d7Tq6tdVHzUukLdS9nWnxCN/QB21qR+VJYp5tcyXogHKbdUEGh6qmeyzxSA== - dependencies: - "@lerna/child-process" "7.4.2" - "@lerna/create" "7.4.2" - "@npmcli/run-script" "6.0.2" - "@nx/devkit" ">=16.5.1 < 17" - "@octokit/plugin-enterprise-rest" "6.0.1" - "@octokit/rest" "19.0.11" - byte-size "8.1.1" - chalk "4.1.0" - clone-deep "4.0.1" - cmd-shim "6.0.1" - columnify "1.6.0" - conventional-changelog-angular "7.0.0" - conventional-changelog-core "5.0.1" - conventional-recommended-bump "7.0.1" - cosmiconfig "^8.2.0" - dedent "0.7.0" - envinfo "7.8.1" - execa "5.0.0" - fs-extra "^11.1.1" - get-port "5.1.1" - get-stream "6.0.0" - git-url-parse "13.1.0" - glob-parent "5.1.2" - globby "11.1.0" - graceful-fs "4.2.11" - has-unicode "2.0.1" - import-local "3.1.0" - ini "^1.3.8" - init-package-json "5.0.0" - inquirer "^8.2.4" - is-ci "3.0.1" - is-stream "2.0.0" - jest-diff ">=29.4.3 < 30" - js-yaml "4.1.0" - libnpmaccess "7.0.2" - libnpmpublish "7.3.0" - load-json-file "6.2.0" - lodash "^4.17.21" - make-dir "4.0.0" - minimatch "3.0.5" - multimatch "5.0.0" - node-fetch "2.6.7" - npm-package-arg "8.1.1" - npm-packlist "5.1.1" - npm-registry-fetch "^14.0.5" - npmlog "^6.0.2" - nx ">=16.5.1 < 17" - p-map "4.0.0" - p-map-series "2.1.0" - p-pipe "3.1.0" - p-queue "6.6.2" - p-reduce "2.1.0" - p-waterfall "2.1.1" - pacote "^15.2.0" - pify "5.0.0" - read-cmd-shim "4.0.0" - read-package-json "6.0.4" - resolve-from "5.0.0" - rimraf "^4.4.1" - semver "^7.3.8" - signal-exit "3.0.7" - slash "3.0.0" - ssri "^9.0.1" - strong-log-transformer "2.1.0" - tar "6.1.11" - temp-dir "1.0.0" - typescript ">=3 < 6" - upath "2.0.1" - uuid "^9.0.0" - validate-npm-package-license "3.0.4" - validate-npm-package-name "5.0.0" - write-file-atomic "5.0.1" - write-pkg "4.0.0" - yargs "16.2.0" - yargs-parser "20.2.4" - - leven@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" - integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== - - levn@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/levn/-/levn-0.4.1.tgz#ae4562c007473b932a6200d403268dd2fffc6ade" - integrity sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ== - dependencies: - prelude-ls "^1.2.1" - type-check "~0.4.0" - - libnpmaccess@7.0.2: - version "7.0.2" - resolved "https://registry.yarnpkg.com/libnpmaccess/-/libnpmaccess-7.0.2.tgz#7f056c8c933dd9c8ba771fa6493556b53c5aac52" - integrity sha512-vHBVMw1JFMTgEk15zRsJuSAg7QtGGHpUSEfnbcRL1/gTBag9iEfJbyjpDmdJmwMhvpoLoNBtdAUCdGnaP32hhw== - dependencies: - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - - libnpmpublish@7.3.0: - version "7.3.0" - resolved "https://registry.yarnpkg.com/libnpmpublish/-/libnpmpublish-7.3.0.tgz#2ceb2b36866d75a6cd7b4aa748808169f4d17e37" - integrity sha512-fHUxw5VJhZCNSls0KLNEG0mCD2PN1i14gH5elGOgiVnU3VgTcRahagYP2LKI1m0tFCJ+XrAm0zVYyF5RCbXzcg== - dependencies: - ci-info "^3.6.1" - normalize-package-data "^5.0.0" - npm-package-arg "^10.1.0" - npm-registry-fetch "^14.0.3" - proc-log "^3.0.0" - semver "^7.3.7" - sigstore "^1.4.0" - ssri "^10.0.1" - - libsodium-sumo@^0.7.13: - version "0.7.13" - resolved "https://registry.yarnpkg.com/libsodium-sumo/-/libsodium-sumo-0.7.13.tgz#533b97d2be44b1277e59c1f9f60805978ac5542d" - integrity sha512-zTGdLu4b9zSNLfovImpBCbdAA4xkpkZbMnSQjP8HShyOutnGjRHmSOKlsylh1okao6QhLiz7nG98EGn+04cZjQ== - - libsodium-wrappers-sumo@^0.7.11: - version "0.7.13" - resolved "https://registry.yarnpkg.com/libsodium-wrappers-sumo/-/libsodium-wrappers-sumo-0.7.13.tgz#a33aea845a0bb56db067548f04feba28c730ab8e" - integrity sha512-lz4YdplzDRh6AhnLGF2Dj2IUj94xRN6Bh8T0HLNwzYGwPehQJX6c7iYVrFUPZ3QqxE0bqC+K0IIqqZJYWumwSQ== - dependencies: - libsodium-sumo "^0.7.13" - - libsodium-wrappers@^0.7.6: - version "0.7.13" - resolved "https://registry.yarnpkg.com/libsodium-wrappers/-/libsodium-wrappers-0.7.13.tgz#83299e06ee1466057ba0e64e532777d2929b90d3" - integrity sha512-kasvDsEi/r1fMzKouIDv7B8I6vNmknXwGiYodErGuESoFTohGSKZplFtVxZqHaoQ217AynyIFgnOVRitpHs0Qw== - dependencies: - libsodium "^0.7.13" - - libsodium@^0.7.13: - version "0.7.13" - resolved "https://registry.yarnpkg.com/libsodium/-/libsodium-0.7.13.tgz#230712ec0b7447c57b39489c48a4af01985fb393" - integrity sha512-mK8ju0fnrKXXfleL53vtp9xiPq5hKM0zbDQtcxQIsSmxNgSxqCj6R7Hl9PkrNe2j29T4yoDaF7DJLK9/i5iWUw== - - lie@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/lie/-/lie-3.1.1.tgz#9a436b2cc7746ca59de7a41fa469b3efb76bd87e" - integrity sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw== - dependencies: - immediate "~3.0.5" - - lilconfig@^2.0.3: - version "2.1.0" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.1.0.tgz#78e23ac89ebb7e1bfbf25b18043de756548e7f52" - integrity sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ== - - lines-and-columns@^1.1.6: - version "1.2.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632" - integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg== - - lines-and-columns@~2.0.3: - version "2.0.4" - resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-2.0.4.tgz#d00318855905d2660d8c0822e3f5a4715855fc42" - integrity sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A== - - listhen@^1.5.5: - version "1.5.5" - resolved "https://registry.yarnpkg.com/listhen/-/listhen-1.5.5.tgz#58915512af70f770aa3e9fb19367adf479bb58c4" - integrity sha512-LXe8Xlyh3gnxdv4tSjTjscD1vpr/2PRpzq8YIaMJgyKzRG8wdISlWVWnGThJfHnlJ6hmLt2wq1yeeix0TEbuoA== - dependencies: - "@parcel/watcher" "^2.3.0" - "@parcel/watcher-wasm" "2.3.0" - citty "^0.1.4" - clipboardy "^3.0.0" - consola "^3.2.3" - defu "^6.1.2" - get-port-please "^3.1.1" - h3 "^1.8.1" - http-shutdown "^1.2.2" - jiti "^1.20.0" - mlly "^1.4.2" - node-forge "^1.3.1" - pathe "^1.1.1" - std-env "^3.4.3" - ufo "^1.3.0" - untun "^0.1.2" - uqr "^0.1.2" - - load-json-file@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-6.2.0.tgz#5c7770b42cafa97074ca2848707c61662f4251a1" - integrity sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ== - dependencies: - graceful-fs "^4.1.15" - parse-json "^5.0.0" - strip-bom "^4.0.0" - type-fest "^0.6.0" - - load-json-file@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" - integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== - dependencies: - graceful-fs "^4.1.2" - parse-json "^2.2.0" - pify "^2.0.0" - pinkie-promise "^2.0.0" - strip-bom "^2.0.0" - - load-json-file@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" - integrity sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw== - dependencies: - graceful-fs "^4.1.2" - parse-json "^4.0.0" - pify "^3.0.0" - strip-bom "^3.0.0" - - loader-runner@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" - integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== - - loader-runner@^4.1.0, loader-runner@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.3.0.tgz#c1b4a163b99f614830353b16755e7149ac2314e1" - integrity sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg== - - loader-utils@^1.2.3: - version "1.4.2" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.2.tgz#29a957f3a63973883eb684f10ffd3d151fec01a3" - integrity sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^1.0.1" - - loader-utils@^2.0.0, loader-utils@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.4.tgz#8b5cb38b5c34a9a018ee1fc0e6a066d1dfcc528c" - integrity sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" - - localforage@^1.7.3, localforage@^1.8.1: - version "1.10.0" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.10.0.tgz#5c465dc5f62b2807c3a84c0c6a1b1b3212781dd4" - integrity sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg== - dependencies: - lie "3.1.1" - - locate-path@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" - integrity sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA== - dependencies: - p-locate "^2.0.0" - path-exists "^3.0.0" - - locate-path@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" - integrity sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A== - dependencies: - p-locate "^3.0.0" - path-exists "^3.0.0" - - locate-path@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-5.0.0.tgz#1afba396afd676a6d42504d0a67a3a7eb9f62aa0" - integrity sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g== - dependencies: - p-locate "^4.1.0" - - locate-path@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" - integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== - dependencies: - p-locate "^5.0.0" - - lodash-es@^4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - - lodash.debounce@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" - integrity sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow== - - lodash.defaults@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.defaults/-/lodash.defaults-4.2.0.tgz#d09178716ffea4dde9e5fb7b37f6f0802274580c" - integrity sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ== - - lodash.defaultsdeep@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz#512e9bd721d272d94e3d3a63653fa17516741ca6" - integrity sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA== - - lodash.isarguments@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" - integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== - - lodash.isequal@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - - lodash.ismatch@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" - integrity sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g== - - lodash.memoize@4.x, lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha512-t7j+NzmgnQzTAYXcsHYLgimltOV1MXHtlOWf6GjL9Kj8GK5FInw5JotxvbOs+IvV1/Dzo04/fCGfLVs7aXb4Ag== - - lodash.merge@^4.6.2: - version "4.6.2" - resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" - integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== - - lodash.padend@^4.6.1: - version "4.6.1" - resolved "https://registry.yarnpkg.com/lodash.padend/-/lodash.padend-4.6.1.tgz#53ccba047d06e158d311f45da625f4e49e6f166e" - integrity sha512-sOQs2aqGpbl27tmCS1QNZA09Uqp01ZzWfDUoD+xzTii0E7dSQfRKcRetFwa+uXaxaqL+TKm7CgD2JdKP7aZBSw== - - lodash.trimstart@^4.5.1: - version "4.5.1" - resolved "https://registry.yarnpkg.com/lodash.trimstart/-/lodash.trimstart-4.5.1.tgz#8ff4dec532d82486af59573c39445914e944a7f1" - integrity sha512-b/+D6La8tU76L/61/aN0jULWHkT0EeJCmVstPBn/K9MtD2qBW83AsBNrr63dKuWYwVMO7ucv13QNO/Ek/2RKaQ== - - lodash.truncate@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/lodash.truncate/-/lodash.truncate-4.4.2.tgz#5a350da0b1113b837ecfffd5812cbe58d6eae193" - integrity sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw== - - lodash.uniq@4.5.0, lodash.uniq@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== - - lodash.words@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/lodash.words/-/lodash.words-4.2.0.tgz#5ecfeaf8ecf8acaa8e0c8386295f1993c9cf4036" - integrity sha512-mXxqd8Yx9BGPij3lZKFSdOsjOTbL4krbCCp9slEozaN4EMppA2dFmK/f8HeohodprY6W0vOdiQ5WFgPaTI75xQ== - - lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" - integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== - - log-symbols@4.1.0, log-symbols@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-4.1.0.tgz#3fbdbb95b4683ac9fc785111e792e558d4abd503" - integrity sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg== - dependencies: - chalk "^4.1.0" - is-unicode-supported "^0.1.0" - - long@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" - integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== - - longest-streak@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/longest-streak/-/longest-streak-3.1.0.tgz#62fa67cd958742a1574af9f39866364102d90cd4" - integrity sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g== - - loose-envify@^1.1.0, loose-envify@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" - integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== - dependencies: - js-tokens "^3.0.0 || ^4.0.0" - - loud-rejection@^1.0.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" - integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== - dependencies: - currently-unhandled "^0.4.1" - signal-exit "^3.0.0" - - loupe@^2.3.6: - version "2.3.7" - resolved "https://registry.yarnpkg.com/loupe/-/loupe-2.3.7.tgz#6e69b7d4db7d3ab436328013d37d1c8c3540c697" - integrity sha512-zSMINGVYkdpYSOBmLi0D1Uo7JU9nVdQKrHxC8eYlV+9YKK9WePqAlL7lSlorG/U2Fw1w0hTBmaa/jrQ3UbPHtA== - dependencies: - get-func-name "^2.0.1" - - lower-case@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" - integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== - dependencies: - tslib "^2.0.3" - - lru-cache@^10.0.2, "lru-cache@^9.1.1 || ^10.0.0": - version "10.1.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.1.0.tgz#2098d41c2dc56500e6c88584aa656c84de7d0484" - integrity sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag== - - lru-cache@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" - integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== - dependencies: - yallist "^3.0.2" - - lru-cache@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" - integrity sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA== - dependencies: - yallist "^4.0.0" - - lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: - version "7.18.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" - integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== - - lunr@^2.3.9: - version "2.3.9" - resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" - integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== - - luxon@^2.3.0: - version "2.5.2" - resolved "https://registry.yarnpkg.com/luxon/-/luxon-2.5.2.tgz#17ed497f0277e72d58a4756d6a9abee4681457b6" - integrity sha512-Yg7/RDp4nedqmLgyH0LwgGRvMEKVzKbUdkBYyCosbHgJ+kaOUx0qzSiSatVc3DFygnirTPYnMM2P5dg2uH1WvA== - - lz-string@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" - integrity sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ== - - magic-string@^0.25.3: - version "0.25.9" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.9.tgz#de7f9faf91ef8a1c91d02c2e5314c8277dbcdd1c" - integrity sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ== - dependencies: - sourcemap-codec "^1.4.8" - - magic-string@^0.27.0: - version "0.27.0" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3" - integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.13" - - magic-string@^0.30.2: - version "0.30.5" - resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.5.tgz#1994d980bd1c8835dc6e78db7cbd4ae4f24746f9" - integrity sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA== - dependencies: - "@jridgewell/sourcemap-codec" "^1.4.15" - - make-dir@4.0.0, make-dir@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-4.0.0.tgz#c3c2307a771277cd9638305f915c29ae741b614e" - integrity sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw== - dependencies: - semver "^7.5.3" - - make-dir@^2.0.0, make-dir@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" - integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== - dependencies: - pify "^4.0.1" - semver "^5.6.0" - - make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" - integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== - dependencies: - semver "^6.0.0" - - make-error@1.x, make-error@^1.1.1: - version "1.3.6" - resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" - integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== - - make-fetch-happen@^10.0.3: - version "10.2.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz#f5e3835c5e9817b617f2770870d9492d28678164" - integrity sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^16.1.0" - http-cache-semantics "^4.1.0" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^3.1.6" - minipass-collect "^1.0.2" - minipass-fetch "^2.0.3" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^9.0.0" - - make-fetch-happen@^11.0.0, make-fetch-happen@^11.0.1, make-fetch-happen@^11.1.1: - version "11.1.1" - resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-11.1.1.tgz#85ceb98079584a9523d4bf71d32996e7e208549f" - integrity sha512-rLWS7GCSTcEujjVBs2YqG7Y4643u8ucvCJeSRqiLYhesrDuzeuFIk37xREzAsfQaqzl8b9rNCE4m6J8tvX4Q8w== - dependencies: - agentkeepalive "^4.2.1" - cacache "^17.0.0" - http-cache-semantics "^4.1.1" - http-proxy-agent "^5.0.0" - https-proxy-agent "^5.0.0" - is-lambda "^1.0.1" - lru-cache "^7.7.1" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-flush "^1.0.5" - minipass-pipeline "^1.2.4" - negotiator "^0.6.3" - promise-retry "^2.0.1" - socks-proxy-agent "^7.0.0" - ssri "^10.0.0" - - makeerror@1.0.12: - version "1.0.12" - resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" - integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== - dependencies: - tmpl "1.0.5" - - map-age-cleaner@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" - integrity sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w== - dependencies: - p-defer "^1.0.0" - - map-cache@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== - - map-obj@^1.0.0, map-obj@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" - integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== - - map-obj@^4.0.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" - integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== - - map-or-similar@^1.5.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" - integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== - - map-visit@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== - dependencies: - object-visit "^1.0.0" - - markdown-escapes@^1.0.0: - version "1.0.4" - resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" - integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== - - markdown-extensions@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/markdown-extensions/-/markdown-extensions-1.1.1.tgz#fea03b539faeaee9b4ef02a3769b455b189f7fc3" - integrity sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q== - - marked@^4.0.16: - version "4.3.0" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.3.0.tgz#796362821b019f734054582038b116481b456cf3" - integrity sha512-PRsaiG84bK+AMvxziE/lCFss8juXjNaWzVbN5tXAm4XjeaS9NAHhop+PjQxz2A9h8Q4M/xGmzP8vqNwy6JeK0A== - - md5.js@^1.3.4: - version "1.3.5" - resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" - integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - safe-buffer "^5.1.2" - - mdast-squeeze-paragraphs@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" - integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== - dependencies: - unist-util-remove "^2.0.0" - - mdast-util-definitions@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" - integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== - dependencies: - unist-util-visit "^2.0.0" - - mdast-util-definitions@^5.0.0: - version "5.1.2" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz#9910abb60ac5d7115d6819b57ae0bcef07a3f7a7" - integrity sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - - mdast-util-from-markdown@^1.0.0, mdast-util-from-markdown@^1.1.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz#9421a5a247f10d31d2faed2a30df5ec89ceafcf0" - integrity sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - decode-named-character-reference "^1.0.0" - mdast-util-to-string "^3.1.0" - micromark "^3.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-decode-string "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-stringify-position "^3.0.0" - uvu "^0.5.0" - - mdast-util-mdx-expression@^1.0.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz#d027789e67524d541d6de543f36d51ae2586f220" - integrity sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - - mdast-util-mdx-jsx@^2.0.0: - version "2.1.4" - resolved "https://registry.yarnpkg.com/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz#7c1f07f10751a78963cfabee38017cbc8b7786d1" - integrity sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - ccount "^2.0.0" - mdast-util-from-markdown "^1.1.0" - mdast-util-to-markdown "^1.3.0" - parse-entities "^4.0.0" - stringify-entities "^4.0.0" - unist-util-remove-position "^4.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - - mdast-util-mdx@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz#49b6e70819b99bb615d7223c088d295e53bb810f" - integrity sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw== - dependencies: - mdast-util-from-markdown "^1.0.0" - mdast-util-mdx-expression "^1.0.0" - mdast-util-mdx-jsx "^2.0.0" - mdast-util-mdxjs-esm "^1.0.0" - mdast-util-to-markdown "^1.0.0" - - mdast-util-mdxjs-esm@^1.0.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz#645d02cd607a227b49721d146fd81796b2e2d15b" - integrity sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w== - dependencies: - "@types/estree-jsx" "^1.0.0" - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - mdast-util-to-markdown "^1.0.0" - - mdast-util-phrasing@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz#c7c21d0d435d7fb90956038f02e8702781f95463" - integrity sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg== - dependencies: - "@types/mdast" "^3.0.0" - unist-util-is "^5.0.0" - - mdast-util-to-hast@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" - integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== - 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" - - mdast-util-to-hast@^12.1.0: - version "12.3.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz#045d2825fb04374e59970f5b3f279b5700f6fb49" - integrity sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-definitions "^5.0.0" - micromark-util-sanitize-uri "^1.1.0" - trim-lines "^3.0.0" - unist-util-generated "^2.0.0" - unist-util-position "^4.0.0" - unist-util-visit "^4.0.0" - - mdast-util-to-markdown@^1.0.0, mdast-util-to-markdown@^1.3.0: - version "1.5.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz#c13343cb3fc98621911d33b5cd42e7d0731171c6" - integrity sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A== - dependencies: - "@types/mdast" "^3.0.0" - "@types/unist" "^2.0.0" - longest-streak "^3.0.0" - mdast-util-phrasing "^3.0.0" - mdast-util-to-string "^3.0.0" - micromark-util-decode-string "^1.0.0" - unist-util-visit "^4.0.0" - zwitch "^2.0.0" - - mdast-util-to-string@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" - integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== - - mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz#66f7bb6324756741c5f47a53557f0cbf16b6f789" - integrity sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg== - dependencies: - "@types/mdast" "^3.0.0" - - mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - - mdurl@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" - integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== - - media-query-parser@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/media-query-parser/-/media-query-parser-2.0.2.tgz#ff79e56cee92615a304a1c2fa4f2bd056c0a1d29" - integrity sha512-1N4qp+jE0pL5Xv4uEcwVUhIkwdUO3S/9gML90nqKA7v7FcOS5vUtatfzok9S9U1EJU8dHWlcv95WLnKmmxZI9w== - dependencies: - "@babel/runtime" "^7.12.5" - - media-typer@0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" - integrity sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ== - - mem@^8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/mem/-/mem-8.1.1.tgz#cf118b357c65ab7b7e0817bdf00c8062297c0122" - integrity sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA== - dependencies: - map-age-cleaner "^0.1.3" - mimic-fn "^3.1.0" - - memfs@^3.1.2, memfs@^3.2.2, memfs@^3.4.1, memfs@^3.4.3: - version "3.6.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.6.0.tgz#d7a2110f86f79dd950a8b6df6d57bc984aa185f6" - integrity sha512-EGowvkkgbMcIChjMTMkESFDbZeSh8xZ7kNSF0hAiAN4Jh6jgHCRS0Ga/+C8y6Au+oqpezRHCfPsmJ2+DwAgiwQ== - dependencies: - fs-monkey "^1.0.4" - - memoizerific@^1.11.3: - version "1.11.3" - resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" - integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== - dependencies: - map-or-similar "^1.5.0" - - memory-fs@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - - memory-fs@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" - integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== - dependencies: - errno "^0.1.3" - readable-stream "^2.0.1" - - memorystream@^0.3.1: - version "0.3.1" - resolved "https://registry.yarnpkg.com/memorystream/-/memorystream-0.3.1.tgz#86d7090b30ce455d63fbae12dda51a47ddcaf9b2" - integrity sha512-S3UwM3yj5mtUSEfP41UZmt/0SCoVYUcU1rkXv+BQ5Ig8ndL4sPoJNBUJERafdPb5jjHJGuMgytgKvKIf58XNBw== - - meow@^3.1.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" - integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== - dependencies: - camelcase-keys "^2.0.0" - decamelize "^1.1.2" - loud-rejection "^1.0.0" - map-obj "^1.0.1" - minimist "^1.1.3" - normalize-package-data "^2.3.4" - object-assign "^4.0.1" - read-pkg-up "^1.0.1" - redent "^1.0.0" - trim-newlines "^1.0.0" - - meow@^8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/meow/-/meow-8.1.2.tgz#bcbe45bda0ee1729d350c03cffc8395a36c4e897" - integrity sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q== - dependencies: - "@types/minimist" "^1.2.0" - camelcase-keys "^6.2.2" - decamelize-keys "^1.1.0" - hard-rejection "^2.1.0" - minimist-options "4.1.0" - normalize-package-data "^3.0.0" - read-pkg-up "^7.0.1" - redent "^3.0.0" - trim-newlines "^3.0.0" - type-fest "^0.18.0" - yargs-parser "^20.2.3" - - merge-descriptors@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" - integrity sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w== - - merge-stream@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" - integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== - - merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" - integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== - - methods@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" - integrity sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w== - - microevent.ts@~0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" - integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== - - micromark-core-commonmark@^1.0.0, micromark-core-commonmark@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz#1386628df59946b2d39fb2edfd10f3e8e0a75bb8" - integrity sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-factory-destination "^1.0.0" - micromark-factory-label "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-factory-title "^1.0.0" - micromark-factory-whitespace "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-classify-character "^1.0.0" - micromark-util-html-tag-name "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - - micromark-extension-mdx-expression@^1.0.0: - version "1.0.8" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz#5bc1f5fd90388e8293b3ef4f7c6f06c24aff6314" - integrity sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw== - dependencies: - "@types/estree" "^1.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - - micromark-extension-mdx-jsx@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz#e72d24b7754a30d20fb797ece11e2c4e2cae9e82" - integrity sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - estree-util-is-identifier-name "^2.0.0" - micromark-factory-mdx-expression "^1.0.0" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - - micromark-extension-mdx-md@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz#595d4b2f692b134080dca92c12272ab5b74c6d1a" - integrity sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA== - dependencies: - micromark-util-types "^1.0.0" - - micromark-extension-mdxjs-esm@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz#e4f8be9c14c324a80833d8d3a227419e2b25dec1" - integrity sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w== - dependencies: - "@types/estree" "^1.0.0" - micromark-core-commonmark "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.1.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - - micromark-extension-mdxjs@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz#f78d4671678d16395efeda85170c520ee795ded8" - integrity sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q== - dependencies: - acorn "^8.0.0" - acorn-jsx "^5.0.0" - micromark-extension-mdx-expression "^1.0.0" - micromark-extension-mdx-jsx "^1.0.0" - micromark-extension-mdx-md "^1.0.0" - micromark-extension-mdxjs-esm "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-factory-destination@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz#eb815957d83e6d44479b3df640f010edad667b9f" - integrity sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-factory-label@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz#cc95d5478269085cfa2a7282b3de26eb2e2dec68" - integrity sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - - micromark-factory-mdx-expression@^1.0.0: - version "1.0.9" - resolved "https://registry.yarnpkg.com/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz#57ba4571b69a867a1530f34741011c71c73a4976" - integrity sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA== - dependencies: - "@types/estree" "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-events-to-acorn "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - unist-util-position-from-estree "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - - micromark-factory-space@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz#c8f40b0640a0150751d3345ed885a080b0d15faf" - integrity sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-factory-title@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz#dd0fe951d7a0ac71bdc5ee13e5d1465ad7f50ea1" - integrity sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-factory-whitespace@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz#798fb7489f4c8abafa7ca77eed6b5745853c9705" - integrity sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ== - dependencies: - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-util-character@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/micromark-util-character/-/micromark-util-character-1.2.0.tgz#4fedaa3646db249bc58caeb000eb3549a8ca5dcc" - integrity sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg== - dependencies: - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-util-chunked@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz#37a24d33333c8c69a74ba12a14651fd9ea8a368b" - integrity sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ== - dependencies: - micromark-util-symbol "^1.0.0" - - micromark-util-classify-character@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz#6a7f8c8838e8a120c8e3c4f2ae97a2bff9190e9d" - integrity sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-util-combine-extensions@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz#192e2b3d6567660a85f735e54d8ea6e3952dbe84" - integrity sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-types "^1.0.0" - - micromark-util-decode-numeric-character-reference@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz#b1e6e17009b1f20bc652a521309c5f22c85eb1c6" - integrity sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw== - dependencies: - micromark-util-symbol "^1.0.0" - - micromark-util-decode-string@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz#dc12b078cba7a3ff690d0203f95b5d5537f2809c" - integrity sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ== - dependencies: - decode-named-character-reference "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-symbol "^1.0.0" - - micromark-util-encode@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz#92e4f565fd4ccb19e0dcae1afab9a173bbeb19a5" - integrity sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw== - - micromark-util-events-to-acorn@^1.0.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz#a4ab157f57a380e646670e49ddee97a72b58b557" - integrity sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w== - dependencies: - "@types/acorn" "^4.0.0" - "@types/estree" "^1.0.0" - "@types/unist" "^2.0.0" - estree-util-visit "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - vfile-message "^3.0.0" - - micromark-util-html-tag-name@^1.0.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz#48fd7a25826f29d2f71479d3b4e83e94829b3588" - integrity sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q== - - micromark-util-normalize-identifier@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz#7a73f824eb9f10d442b4d7f120fecb9b38ebf8b7" - integrity sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q== - dependencies: - micromark-util-symbol "^1.0.0" - - micromark-util-resolve-all@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz#4652a591ee8c8fa06714c9b54cd6c8e693671188" - integrity sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA== - dependencies: - micromark-util-types "^1.0.0" - - micromark-util-sanitize-uri@^1.0.0, micromark-util-sanitize-uri@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz#613f738e4400c6eedbc53590c67b197e30d7f90d" - integrity sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A== - dependencies: - micromark-util-character "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-symbol "^1.0.0" - - micromark-util-subtokenize@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz#941c74f93a93eaf687b9054aeb94642b0e92edb1" - integrity sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A== - dependencies: - micromark-util-chunked "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.0" - uvu "^0.5.0" - - micromark-util-symbol@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz#813cd17837bdb912d069a12ebe3a44b6f7063142" - integrity sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag== - - micromark-util-types@^1.0.0, micromark-util-types@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/micromark-util-types/-/micromark-util-types-1.1.0.tgz#e6676a8cae0bb86a2171c498167971886cb7e283" - integrity sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg== - - micromark@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/micromark/-/micromark-3.2.0.tgz#1af9fef3f995ea1ea4ac9c7e2f19c48fd5c006e9" - integrity sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA== - dependencies: - "@types/debug" "^4.0.0" - debug "^4.0.0" - decode-named-character-reference "^1.0.0" - micromark-core-commonmark "^1.0.1" - micromark-factory-space "^1.0.0" - micromark-util-character "^1.0.0" - micromark-util-chunked "^1.0.0" - micromark-util-combine-extensions "^1.0.0" - micromark-util-decode-numeric-character-reference "^1.0.0" - micromark-util-encode "^1.0.0" - micromark-util-normalize-identifier "^1.0.0" - micromark-util-resolve-all "^1.0.0" - micromark-util-sanitize-uri "^1.0.0" - micromark-util-subtokenize "^1.0.0" - micromark-util-symbol "^1.0.0" - micromark-util-types "^1.0.1" - uvu "^0.5.0" - - micromatch@^3.1.10, micromatch@^3.1.4: - version "3.1.10" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" - integrity sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - braces "^2.3.1" - define-property "^2.0.2" - extend-shallow "^3.0.2" - extglob "^2.0.4" - fragment-cache "^0.2.1" - kind-of "^6.0.2" - nanomatch "^1.2.9" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.2" - - micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: - version "4.0.5" - resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" - integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== - dependencies: - braces "^3.0.2" - picomatch "^2.3.1" - - miller-rabin@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" - integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== - dependencies: - bn.js "^4.0.0" - brorand "^1.0.1" - - mime-db@1.52.0, "mime-db@>= 1.43.0 < 2": - version "1.52.0" - resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" - integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== - - mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.30, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.24, mime-types@~2.1.34: - version "2.1.35" - resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" - integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== - dependencies: - mime-db "1.52.0" - - mime@1.6.0: - version "1.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" - integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== - - mime@^2.4.4: - version "2.6.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" - integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== - - mime@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mime/-/mime-3.0.0.tgz#b374550dca3a0c18443b0c950a6a58f1931cf7a7" - integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== - - mimic-fn@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" - integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== - - mimic-fn@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" - integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== - - mimic-response@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-3.1.0.tgz#2d1d59af9c1b129815accc2c46a022a5ce1fa3c9" - integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== - - min-document@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" - integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== - dependencies: - dom-walk "^0.1.0" - - min-indent@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.1.tgz#a63f681673b30571fbe8bc25686ae746eefa9869" - integrity sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg== - - mini-css-extract-plugin@^2.2.2: - version "2.7.6" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" - integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== - dependencies: - schema-utils "^4.0.0" - - minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" - integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== - - minimalistic-crypto-utils@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" - integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== - - minimatch@3.0.5: - version "3.0.5" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" - integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== - dependencies: - brace-expansion "^1.1.7" - - minimatch@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" - integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== - dependencies: - brace-expansion "^2.0.1" - - minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" - integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== - dependencies: - brace-expansion "^1.1.7" - - minimatch@^5.0.1, minimatch@^5.1.0: - version "5.1.6" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96" - integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g== - dependencies: - brace-expansion "^2.0.1" - - minimatch@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" - integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== - dependencies: - brace-expansion "^2.0.1" - - minimatch@^9.0.0, minimatch@^9.0.1: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - - minimist-options@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" - integrity sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A== - dependencies: - arrify "^1.0.1" - is-plain-obj "^1.1.0" - kind-of "^6.0.3" - - minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0, minimist@^1.2.3, minimist@^1.2.5, minimist@^1.2.6: - version "1.2.8" - resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" - integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== - - minipass-collect@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/minipass-collect/-/minipass-collect-1.0.2.tgz#22b813bf745dc6edba2576b940022ad6edc8c617" - integrity sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA== - dependencies: - minipass "^3.0.0" - - minipass-fetch@^2.0.3: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.2.tgz#95560b50c472d81a3bc76f20ede80eaed76d8add" - integrity sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA== - dependencies: - minipass "^3.1.6" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - - minipass-fetch@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-3.0.4.tgz#4d4d9b9f34053af6c6e597a64be8e66e42bf45b7" - integrity sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg== - dependencies: - minipass "^7.0.3" - minipass-sized "^1.0.3" - minizlib "^2.1.2" - optionalDependencies: - encoding "^0.1.13" - - minipass-flush@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" - integrity sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw== - dependencies: - minipass "^3.0.0" - - minipass-json-stream@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/minipass-json-stream/-/minipass-json-stream-1.0.1.tgz#7edbb92588fbfc2ff1db2fc10397acb7b6b44aa7" - integrity sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg== - dependencies: - jsonparse "^1.3.1" - minipass "^3.0.0" - - minipass-pipeline@^1.2.2, minipass-pipeline@^1.2.4: - version "1.2.4" - resolved "https://registry.yarnpkg.com/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz#68472f79711c084657c067c5c6ad93cddea8214c" - integrity sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A== - dependencies: - minipass "^3.0.0" - - minipass-sized@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/minipass-sized/-/minipass-sized-1.0.3.tgz#70ee5a7c5052070afacfbc22977ea79def353b70" - integrity sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g== - dependencies: - minipass "^3.0.0" - - minipass@^3.0.0, minipass@^3.1.1, minipass@^3.1.6: - version "3.3.6" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.3.6.tgz#7bba384db3a1520d18c9c0e5251c3444e95dd94a" - integrity sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw== - dependencies: - yallist "^4.0.0" - - minipass@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - - minipass@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" - integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== - - "minipass@^5.0.0 || ^6.0.2 || ^7.0.0", minipass@^7.0.3: - version "7.0.4" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.0.4.tgz#dbce03740f50a4786ba994c1fb908844d27b038c" - integrity sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ== - - minizlib@^2.1.1, minizlib@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" - integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== - dependencies: - minipass "^3.0.0" - yallist "^4.0.0" - - mississippi@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" - integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== - dependencies: - concat-stream "^1.5.0" - duplexify "^3.4.2" - end-of-stream "^1.1.0" - flush-write-stream "^1.0.0" - from2 "^2.1.0" - parallel-transform "^1.1.0" - pump "^3.0.0" - pumpify "^1.3.3" - stream-each "^1.1.0" - through2 "^2.0.0" - - mixin-deep@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" - integrity sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA== - dependencies: - for-in "^1.0.2" - is-extendable "^1.0.1" - - mkdirp-classic@^0.5.2, mkdirp-classic@^0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz#fa10c9115cc6d8865be221ba47ee9bed78601113" - integrity sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A== - - mkdirp@^0.5.1, mkdirp@^0.5.3: - version "0.5.6" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" - integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== - dependencies: - minimist "^1.2.6" - - mkdirp@^1.0.3, mkdirp@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" - integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== - - mlly@^1.2.0, mlly@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/mlly/-/mlly-1.4.2.tgz#7cf406aa319ff6563d25da6b36610a93f2a8007e" - integrity sha512-i/Ykufi2t1EZ6NaPLdfnZk2AX8cs0d+mTzVKuPfqPKPatxLApaBoxJQ9x1/uckXtrS/U5oisPMDkNs0yQTaBRg== - dependencies: - acorn "^8.10.0" - pathe "^1.1.1" - pkg-types "^1.0.3" - ufo "^1.3.0" - - mobx@^6.1.7: - version "6.12.0" - resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.12.0.tgz#72b2685ca5af031aaa49e77a4d76ed67fcbf9135" - integrity sha512-Mn6CN6meXEnMa0a5u6a5+RKrqRedHBhZGd15AWLk9O6uFY4KYHzImdt8JI8WODo1bjTSRnwXhJox+FCUZhCKCQ== - - mocha@^10.0.0: - version "10.2.0" - resolved "https://registry.yarnpkg.com/mocha/-/mocha-10.2.0.tgz#1fd4a7c32ba5ac372e03a17eef435bd00e5c68b8" - integrity sha512-IDY7fl/BecMwFHzoqF2sg/SHHANeBoMMXFlS9r0OXKDssYE1M5O43wUY/9BVPeIvfH2zmEbBfseqN9gBQZzXkg== - dependencies: - ansi-colors "4.1.1" - browser-stdout "1.3.1" - chokidar "3.5.3" - debug "4.3.4" - diff "5.0.0" - escape-string-regexp "4.0.0" - find-up "5.0.0" - glob "7.2.0" - he "1.2.0" - js-yaml "4.1.0" - log-symbols "4.1.0" - minimatch "5.0.1" - ms "2.1.3" - nanoid "3.3.3" - serialize-javascript "6.0.0" - strip-json-comments "3.1.1" - supports-color "8.1.1" - workerpool "6.2.1" - yargs "16.2.0" - yargs-parser "20.2.4" - yargs-unparser "2.0.0" - - modern-ahocorasick@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modern-ahocorasick/-/modern-ahocorasick-1.0.1.tgz#dec373444f51b5458ac05216a8ec376e126dd283" - integrity sha512-yoe+JbhTClckZ67b2itRtistFKf8yPYelHLc7e5xAwtNAXxM6wJTUx2C7QeVSJFDzKT7bCIFyBVybPMKvmB9AA== - - modify-values@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" - integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== - - moq.ts@^7.3.4: - version "7.4.1" - resolved "https://registry.yarnpkg.com/moq.ts/-/moq.ts-7.4.1.tgz#1bb7e808324dc5b0143fa8b1a94f539203d475cb" - integrity sha512-P97MjGUkkMKQrAHbNScyJvSv3S7pMxnuxd3HgaOrPuoC6okwPqru3ZX8W/mTdU7Ms74622MeeWHqoDaGyYKonw== - dependencies: - tslib "2.1.0" - - move-concurrently@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" - integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== - dependencies: - aproba "^1.1.1" - copy-concurrently "^1.0.0" - fs-write-stream-atomic "^1.0.8" - mkdirp "^0.5.1" - rimraf "^2.5.4" - run-queue "^1.0.3" - - mri@^1.1.0, mri@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/mri/-/mri-1.2.0.tgz#6721480fec2a11a4889861115a48b6cbe7cc8f0b" - integrity sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA== - - ms@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" - integrity sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A== - - ms@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.1.tgz#30a5864eb3ebb0a66f2ebe6d727af06a09d86e0a" - integrity sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg== - - ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - - ms@2.1.3, ms@^2.0.0, ms@^2.1.1: - version "2.1.3" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" - integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== - - multicast-dns@^7.2.5: - version "7.2.5" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" - integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== - dependencies: - dns-packet "^5.2.2" - thunky "^1.0.2" - - multiformats@^9.4.2: - version "9.9.0" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" - integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== - - multimatch@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" - integrity sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA== - dependencies: - "@types/minimatch" "^3.0.3" - array-differ "^3.0.0" - array-union "^2.1.0" - arrify "^2.0.1" - minimatch "^3.0.4" - - mute-stream@0.0.8: - version "0.0.8" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d" - integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== - - mute-stream@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-1.0.0.tgz#e31bd9fe62f0aed23520aa4324ea6671531e013e" - integrity sha512-avsJQhyd+680gKXyG/sQc0nXaC6rBkPOfyHYcFb9+hdkqQkR9bdnkJ0AMZhke0oesPqIO+mFFJ+IdBc7mst4IA== - - nan@^2.12.1, nan@^2.13.2: - version "2.18.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554" - integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w== - - nanoclone@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4" - integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== - - nanoid@3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.3.tgz#fd8e8b7aa761fe807dba2d1b98fb7241bb724a25" - integrity sha512-p1sjXuopFs0xg+fPASzQ28agW1oHD7xDsd9Xkf3T15H3c/cifrFHVwrh74PdoklAPi+i7MdRsE47vm2r6JoB+w== - - nanoid@^3.3.1, nanoid@^3.3.6: - version "3.3.7" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8" - integrity sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g== - - nanomatch@^1.2.9: - version "1.2.13" - resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" - integrity sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA== - dependencies: - arr-diff "^4.0.0" - array-unique "^0.3.2" - define-property "^2.0.2" - extend-shallow "^3.0.2" - fragment-cache "^0.2.1" - is-windows "^1.0.2" - kind-of "^6.0.2" - object.pick "^1.3.0" - regex-not "^1.0.0" - snapdragon "^0.8.1" - to-regex "^3.0.1" - - napi-build-utils@^1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/napi-build-utils/-/napi-build-utils-1.0.2.tgz#b1fddc0b2c46e380a0b7a76f984dd47c41a13806" - integrity sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg== - - napi-wasm@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/napi-wasm/-/napi-wasm-1.1.0.tgz#bbe617823765ae9c1bc12ff5942370eae7b2ba4e" - integrity sha512-lHwIAJbmLSjF9VDRm9GoVOy9AGp3aIvkjv+Kvz9h16QR3uSVYH78PNQUnT2U4X53mhlnV2M7wrhibQ3GHicDmg== - - natural-compare-lite@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz#17b09581988979fddafe0201e931ba933c96cbb4" - integrity sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g== - - natural-compare@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" - integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== - - negotiator@0.6.3, negotiator@^0.6.3: - version "0.6.3" - resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" - integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== - - neo-async@^2.5.0, neo-async@^2.6.1, neo-async@^2.6.2: - version "2.6.2" - resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" - integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== - - nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" - integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== - - nice-try@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" - integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== - - no-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" - integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== - dependencies: - lower-case "^2.0.2" - tslib "^2.0.3" - - node-abi@^3.3.0: - version "3.51.0" - resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-3.51.0.tgz#970bf595ef5a26a271307f8a4befa02823d4e87d" - integrity sha512-SQkEP4hmNWjlniS5zdnfIXTk1x7Ome85RDzHlTbBtzE97Gfwz/Ipw4v/Ryk20DWIy3yCNVLVlGKApCnmvYoJbA== - dependencies: - semver "^7.3.5" - - node-abort-controller@^3.0.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/node-abort-controller/-/node-abort-controller-3.1.1.tgz#a94377e964a9a37ac3976d848cb5c765833b8548" - integrity sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ== - - node-addon-api@^3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" - integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== - - node-addon-api@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-4.3.0.tgz#52a1a0b475193e0928e98e0426a0d1254782b77f" - integrity sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ== - - node-addon-api@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-6.1.0.tgz#ac8470034e58e67d0c6f1204a18ae6995d9c0d76" - integrity sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA== - - node-addon-api@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-7.0.0.tgz#8136add2f510997b3b94814f4af1cce0b0e3962e" - integrity sha512-vgbBJTS4m5/KkE16t5Ly0WW9hz46swAstv0hYYwMtbG7AznRhNyfLRe8HZAiWIpcHzoO7HxhLuBQj9rJ/Ho0ZA== - - node-dir@^0.1.10: - version "0.1.17" - resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.17.tgz#5f5665d93351335caabef8f1c554516cf5f1e4e5" - integrity sha512-tmPX422rYgofd4epzrNoOXiE8XFZYOcCq1vD7MAXCDO+O+zndlA2ztdKKMa+EeuBG5tHETpr4ml4RGgpqDCCAg== - dependencies: - minimatch "^3.0.2" - - node-fetch-native@^1.4.0, node-fetch-native@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/node-fetch-native/-/node-fetch-native-1.4.1.tgz#5a336e55b4e1b1e72b9927da09fecd2b374c9be5" - integrity sha512-NsXBU0UgBxo2rQLOeWNZqS3fvflWePMECr8CoSWoSTqCqGbVVsvl9vZu1HfQicYN0g5piV9Gh8RTEvo/uP752w== - - node-fetch@2.6.7: - version "2.6.7" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" - integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== - dependencies: - whatwg-url "^5.0.0" - - node-fetch@^2.6.1, node-fetch@^2.6.7: - version "2.7.0" - resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.7.0.tgz#d0f0fa6e3e2dc1d27efcd8ad99d550bda94d187d" - integrity sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A== - dependencies: - whatwg-url "^5.0.0" - - node-forge@^1, node-forge@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" - integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== - - node-gyp-build@^4.3.0: - version "4.7.1" - resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.7.1.tgz#cd7d2eb48e594874053150a9418ac85af83ca8f7" - integrity sha512-wTSrZ+8lsRRa3I3H8Xr65dLWSgCvY2l4AOnaeKdPA9TB/WYMPaTcrzf3rXvFoVvjKNVnu0CcWSx54qq9GKRUYg== - - node-gyp@^9.0.0, node-gyp@^9.3.1: - version "9.4.1" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-9.4.1.tgz#8a1023e0d6766ecb52764cc3a734b36ff275e185" - integrity sha512-OQkWKbjQKbGkMf/xqI1jjy3oCTgMKJac58G2+bjZb3fza6gW2YrCSdMQYaoTb70crvE//Gngr4f0AgVHmqHvBQ== - dependencies: - env-paths "^2.2.0" - exponential-backoff "^3.1.1" - glob "^7.1.4" - graceful-fs "^4.2.6" - make-fetch-happen "^10.0.3" - nopt "^6.0.0" - npmlog "^6.0.0" - rimraf "^3.0.2" - semver "^7.3.5" - tar "^6.1.2" - which "^2.0.2" - - node-int64@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" - integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== - - node-libs-browser@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" - integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== - dependencies: - assert "^1.1.1" - browserify-zlib "^0.2.0" - buffer "^4.3.0" - console-browserify "^1.1.0" - constants-browserify "^1.0.0" - crypto-browserify "^3.11.0" - domain-browser "^1.1.1" - events "^3.0.0" - https-browserify "^1.0.0" - os-browserify "^0.3.0" - path-browserify "0.0.1" - process "^0.11.10" - punycode "^1.2.4" - querystring-es3 "^0.2.0" - readable-stream "^2.3.3" - stream-browserify "^2.0.1" - stream-http "^2.7.2" - string_decoder "^1.0.0" - timers-browserify "^2.0.4" - tty-browserify "0.0.0" - url "^0.11.0" - util "^0.11.0" - vm-browserify "^1.0.1" - - node-machine-id@1.1.12: - version "1.1.12" - resolved "https://registry.yarnpkg.com/node-machine-id/-/node-machine-id-1.1.12.tgz#37904eee1e59b320bb9c5d6c0a59f3b469cb6267" - integrity sha512-QNABxbrPa3qEIfrE6GOJ7BYIuignnJw7iQ2YPbc3Nla1HzRJjXzZOiikfF8m7eAMfichLt3M4VgLOetqgDmgGQ== - - node-releases@^2.0.13: - version "2.0.13" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.13.tgz#d5ed1627c23e3461e819b02e57b75e4899b1c81d" - integrity sha512-uYr7J37ae/ORWdZeQ1xxMJe3NtdmqMC/JZK+geofDrkLUApKRHPd18/TxtBOJ4A0/+uUIliorNrfYV6s1b02eQ== - - nodemon@^2.0.21: - version "2.0.22" - resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-2.0.22.tgz#182c45c3a78da486f673d6c1702e00728daf5258" - integrity sha512-B8YqaKMmyuCO7BowF1Z1/mkPqLk6cs/l63Ojtd6otKjMx47Dq1utxfRxcavH1I7VSaL8n5BUaoutadnsX3AAVQ== - dependencies: - chokidar "^3.5.2" - debug "^3.2.7" - ignore-by-default "^1.0.1" - minimatch "^3.1.2" - pstree.remy "^1.1.8" - semver "^5.7.1" - simple-update-notifier "^1.0.7" - supports-color "^5.5.0" - touch "^3.1.0" - undefsafe "^2.0.5" - - nopt@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-6.0.0.tgz#245801d8ebf409c6df22ab9d95b65e1309cdb16d" - integrity sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g== - dependencies: - abbrev "^1.0.0" - - nopt@~1.0.10: - version "1.0.10" - resolved "https://registry.yarnpkg.com/nopt/-/nopt-1.0.10.tgz#6ddd21bd2a31417b92727dd585f8a6f37608ebee" - integrity sha512-NWmpvLSqUrgrAC9HCuxEvb+PSloHpqVu+FqcO4eeF2h5qYRhA7ev6KvelyQAKtegUbC6RypJnlEOhd8vloNKYg== - dependencies: - abbrev "1" - - normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" - integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== - dependencies: - hosted-git-info "^2.1.4" - resolve "^1.10.0" - semver "2 || 3 || 4 || 5" - validate-npm-package-license "^3.0.1" - - normalize-package-data@^3.0.0, normalize-package-data@^3.0.3: - version "3.0.3" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-3.0.3.tgz#dbcc3e2da59509a0983422884cd172eefdfa525e" - integrity sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA== - dependencies: - hosted-git-info "^4.0.1" - is-core-module "^2.5.0" - semver "^7.3.4" - validate-npm-package-license "^3.0.1" - - normalize-package-data@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-5.0.0.tgz#abcb8d7e724c40d88462b84982f7cbf6859b4588" - integrity sha512-h9iPVIfrVZ9wVYQnxFgtw1ugSvGEMOlyPWWtm8BMJhnwyEL/FLbYbTY3V3PpjI/BUK67n9PEWDu6eHzu1fB15Q== - dependencies: - hosted-git-info "^6.0.0" - is-core-module "^2.8.1" - semver "^7.3.5" - validate-npm-package-license "^3.0.4" - - normalize-path@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== - dependencies: - remove-trailing-separator "^1.0.1" - - normalize-path@^3.0.0, normalize-path@~3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" - integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== - - normalize-range@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" - integrity sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA== - - normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - - notistack@^2.0.3: - version "2.0.8" - resolved "https://registry.yarnpkg.com/notistack/-/notistack-2.0.8.tgz#78cdf34c64e311bf1d1d71c2123396bcdea5e95b" - integrity sha512-/IY14wkFp5qjPgKNvAdfL5Jp6q90+MjgKTPh4c81r/lW70KeuX6b9pE/4f8L4FG31cNudbN9siiFS5ql1aSLRw== - dependencies: - clsx "^1.1.0" - hoist-non-react-statics "^3.3.0" - - npm-bundled@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" - integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== - dependencies: - npm-normalize-package-bin "^1.0.1" - - npm-bundled@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-3.0.0.tgz#7e8e2f8bb26b794265028491be60321a25a39db7" - integrity sha512-Vq0eyEQy+elFpzsKjMss9kxqb9tG3YHg4dsyWuUENuzvSUWe1TCnW/vV9FkhvBk/brEDoDiVd+M1Btosa6ImdQ== - dependencies: - npm-normalize-package-bin "^3.0.0" - - npm-install-checks@^6.0.0: - version "6.3.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-6.3.0.tgz#046552d8920e801fa9f919cad569545d60e826fe" - integrity sha512-W29RiK/xtpCGqn6f3ixfRYGk+zRyr+Ew9F2E20BfXxT5/euLdA/Nm7fO7OeTGuAmTs30cpgInyJ0cYe708YTZw== - dependencies: - semver "^7.1.1" - - npm-normalize-package-bin@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" - integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== - - npm-normalize-package-bin@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz#25447e32a9a7de1f51362c61a559233b89947832" - integrity sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ== - - npm-package-arg@8.1.1: - version "8.1.1" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.1.tgz#00ebf16ac395c63318e67ce66780a06db6df1b04" - integrity sha512-CsP95FhWQDwNqiYS+Q0mZ7FAEDytDZAkNxQqea6IaAFJTAY9Lhhqyl0irU/6PMc7BGfUmnsbHcqxJD7XuVM/rg== - dependencies: - hosted-git-info "^3.0.6" - semver "^7.0.0" - validate-npm-package-name "^3.0.0" - - npm-package-arg@^10.0.0, npm-package-arg@^10.1.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-10.1.0.tgz#827d1260a683806685d17193073cc152d3c7e9b1" - integrity sha512-uFyyCEmgBfZTtrKk/5xDfHp6+MdrqGotX/VoOyEEl3mBwiEE5FlBaePanazJSVMPT7vKepcjYBY2ztg9A3yPIA== - dependencies: - hosted-git-info "^6.0.0" - proc-log "^3.0.0" - semver "^7.3.5" - validate-npm-package-name "^5.0.0" - - npm-packlist@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.1.tgz#79bcaf22a26b6c30aa4dd66b976d69cc286800e0" - integrity sha512-UfpSvQ5YKwctmodvPPkK6Fwk603aoVsf8AEbmVKAEECrfvL8SSe1A2YIwrJ6xmTHAITKPwwZsWo7WwEbNk0kxw== - dependencies: - glob "^8.0.1" - ignore-walk "^5.0.1" - npm-bundled "^1.1.2" - npm-normalize-package-bin "^1.0.1" - - npm-packlist@^7.0.0: - version "7.0.4" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-7.0.4.tgz#033bf74110eb74daf2910dc75144411999c5ff32" - integrity sha512-d6RGEuRrNS5/N84iglPivjaJPxhDbZmlbTwTDX2IbcRHG5bZCdtysYMhwiPvcF4GisXHGn7xsxv+GQ7T/02M5Q== - dependencies: - ignore-walk "^6.0.0" - - npm-pick-manifest@^8.0.0: - version "8.0.2" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-8.0.2.tgz#2159778d9c7360420c925c1a2287b5a884c713aa" - integrity sha512-1dKY+86/AIiq1tkKVD3l0WI+Gd3vkknVGAggsFeBkTvbhMQ1OND/LKkYv4JtXPKUJ8bOTCyLiqEg2P6QNdK+Gg== - dependencies: - npm-install-checks "^6.0.0" - npm-normalize-package-bin "^3.0.0" - npm-package-arg "^10.0.0" - semver "^7.3.5" - - npm-registry-fetch@^14.0.0, npm-registry-fetch@^14.0.3, npm-registry-fetch@^14.0.5: - version "14.0.5" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-14.0.5.tgz#fe7169957ba4986a4853a650278ee02e568d115d" - integrity sha512-kIDMIo4aBm6xg7jOttupWZamsZRkAqMqwqqbVXnUqstY5+tapvv6bkH/qMR76jdgV+YljEUCyWx3hRYMrJiAgA== - dependencies: - make-fetch-happen "^11.0.0" - minipass "^5.0.0" - minipass-fetch "^3.0.0" - minipass-json-stream "^1.0.1" - minizlib "^2.1.2" - npm-package-arg "^10.0.0" - proc-log "^3.0.0" - - npm-run-all@^4.1.5: - version "4.1.5" - resolved "https://registry.yarnpkg.com/npm-run-all/-/npm-run-all-4.1.5.tgz#04476202a15ee0e2e214080861bff12a51d98fba" - integrity sha512-Oo82gJDAVcaMdi3nuoKFavkIHBRVqQ1qvMb+9LHk/cF4P6B2m8aP04hGf7oL6wZ9BuGwX1onlLhpuoofSyoQDQ== - dependencies: - ansi-styles "^3.2.1" - chalk "^2.4.1" - cross-spawn "^6.0.5" - memorystream "^0.3.1" - minimatch "^3.0.4" - pidtree "^0.3.0" - read-pkg "^3.0.0" - shell-quote "^1.6.1" - string.prototype.padend "^3.0.0" - - npm-run-path@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" - integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== - dependencies: - path-key "^2.0.0" - - npm-run-path@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" - integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== - dependencies: - path-key "^3.0.0" - - npmlog@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" - integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== - dependencies: - are-we-there-yet "^2.0.0" - console-control-strings "^1.1.0" - gauge "^3.0.0" - set-blocking "^2.0.0" - - npmlog@^6.0.0, npmlog@^6.0.2: - version "6.0.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.2.tgz#c8166017a42f2dea92d6453168dd865186a70830" - integrity sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg== - dependencies: - are-we-there-yet "^3.0.0" - console-control-strings "^1.1.0" - gauge "^4.0.3" - set-blocking "^2.0.0" - - nth-check@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" - integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== - dependencies: - boolbase "^1.0.0" - - num2fraction@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== - - nwsapi@^2.2.0: - version "2.2.7" - resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.2.7.tgz#738e0707d3128cb750dddcfe90e4610482df0f30" - integrity sha512-ub5E4+FBPKwAZx0UwIQOjYWGHTEq5sPqHQNRN8Z9e4A7u3Tj1weLJsL59yH9vmvqEtBHaOmT6cYQKIZOxp35FQ== - - nx@16.10.0, "nx@>=16.5.1 < 17": - version "16.10.0" - resolved "https://registry.yarnpkg.com/nx/-/nx-16.10.0.tgz#b070461f7de0a3d7988bd78558ea84cda3543ace" - integrity sha512-gZl4iCC0Hx0Qe1VWmO4Bkeul2nttuXdPpfnlcDKSACGu3ZIo+uySqwOF8yBAxSTIf8xe2JRhgzJN1aFkuezEBg== - dependencies: - "@nrwl/tao" "16.10.0" - "@parcel/watcher" "2.0.4" - "@yarnpkg/lockfile" "^1.1.0" - "@yarnpkg/parsers" "3.0.0-rc.46" - "@zkochan/js-yaml" "0.0.6" - axios "^1.0.0" - chalk "^4.1.0" - cli-cursor "3.1.0" - cli-spinners "2.6.1" - cliui "^8.0.1" - dotenv "~16.3.1" - dotenv-expand "~10.0.0" - enquirer "~2.3.6" - figures "3.2.0" - flat "^5.0.2" - fs-extra "^11.1.0" - glob "7.1.4" - ignore "^5.0.4" - jest-diff "^29.4.1" - js-yaml "4.1.0" - jsonc-parser "3.2.0" - lines-and-columns "~2.0.3" - minimatch "3.0.5" - node-machine-id "1.1.12" - npm-run-path "^4.0.1" - open "^8.4.0" - semver "7.5.3" - string-width "^4.2.3" - strong-log-transformer "^2.1.0" - tar-stream "~2.2.0" - tmp "~0.2.1" - tsconfig-paths "^4.1.2" - tslib "^2.3.0" - v8-compile-cache "2.3.0" - yargs "^17.6.2" - yargs-parser "21.1.1" - optionalDependencies: - "@nx/nx-darwin-arm64" "16.10.0" - "@nx/nx-darwin-x64" "16.10.0" - "@nx/nx-freebsd-x64" "16.10.0" - "@nx/nx-linux-arm-gnueabihf" "16.10.0" - "@nx/nx-linux-arm64-gnu" "16.10.0" - "@nx/nx-linux-arm64-musl" "16.10.0" - "@nx/nx-linux-x64-gnu" "16.10.0" - "@nx/nx-linux-x64-musl" "16.10.0" - "@nx/nx-win32-arm64-msvc" "16.10.0" - "@nx/nx-win32-x64-msvc" "16.10.0" - - object-assign@^4.0.1, object-assign@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" - integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== - - object-copy@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== - dependencies: - copy-descriptor "^0.1.0" - define-property "^0.2.5" - kind-of "^3.0.3" - - object-inspect@^1.13.1, object-inspect@^1.9.0: - version "1.13.1" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.13.1.tgz#b96c6109324ccfef6b12216a956ca4dc2ff94bc2" - integrity sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ== - - object-is@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.1.5.tgz#b9deeaa5fc7f1846a0faecdceec138e5778f53ac" - integrity sha512-3cyDsyHgtmi7I7DfSSI2LDp6SK2lwvtbg0p0R1e0RvTqF5ceGx+K2dfSjm1bKDMVCFEDAQvy+o8c6a7VujOddw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.1.3" - - object-keys@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" - integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== - - object-visit@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== - dependencies: - isobject "^3.0.0" - - object.assign@^4.1.2, object.assign@^4.1.4: - version "4.1.5" - resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.5.tgz#3a833f9ab7fdb80fc9e8d2300c803d216d8fdbb0" - integrity sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ== - dependencies: - call-bind "^1.0.5" - define-properties "^1.2.1" - has-symbols "^1.0.3" - object-keys "^1.1.1" - - object.entries@^1.1.0, object.entries@^1.1.5, object.entries@^1.1.6, object.entries@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.7.tgz#2b47760e2a2e3a752f39dd874655c61a7f03c131" - integrity sha512-jCBs/0plmPsOnrKAfFQXRG2NFjlhZgjjcBLSmTnEhU8U6vVTsVe8ANeQJCHTl3gSsI4J+0emOoCgoKlmQPMgmA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - "object.fromentries@^2.0.0 || ^1.0.0", object.fromentries@^2.0.6, object.fromentries@^2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.7.tgz#71e95f441e9a0ea6baf682ecaaf37fa2a8d7e616" - integrity sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: - version "2.1.7" - resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.7.tgz#7a466a356cd7da4ba8b9e94ff6d35c3eeab5d56a" - integrity sha512-PrJz0C2xJ58FNn11XV2lr4Jt5Gzl94qpy9Lu0JlfEj14z88sqbSBJCBEzdlNUCzY2gburhbrwOZ5BHCmuNUy0g== - dependencies: - array.prototype.reduce "^1.0.6" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - safe-array-concat "^1.0.0" - - object.groupby@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.1.tgz#d41d9f3c8d6c778d9cbac86b4ee9f5af103152ee" - integrity sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - - object.hasown@^1.1.2: - version "1.1.3" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.3.tgz#6a5f2897bb4d3668b8e79364f98ccf971bda55ae" - integrity sha512-fFI4VcYpRHvSLXxP7yiZOMAd331cPfd2p7PFDVbgUsYOfCT3tICVqXWngbjr4m49OvsBwUBQ6O2uQoJvy3RexA== - dependencies: - define-properties "^1.2.0" - es-abstract "^1.22.1" - - object.pick@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== - dependencies: - isobject "^3.0.1" - - object.values@^1.1.0, object.values@^1.1.6, object.values@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.7.tgz#617ed13272e7e1071b43973aa1655d9291b8442a" - integrity sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - objectorarray@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/objectorarray/-/objectorarray-1.0.5.tgz#2c05248bbefabd8f43ad13b41085951aac5e68a5" - integrity sha512-eJJDYkhJFFbBBAxeh8xW+weHlkI28n2ZdQV/J/DNfWfSKlGEf2xcfAbZTv3riEXHAhL9SVOTs2pRmXiSTf78xg== - - obuf@^1.0.0, obuf@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" - integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== - - ofetch@^1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/ofetch/-/ofetch-1.3.3.tgz#588cb806a28e5c66c2c47dd8994f9059a036d8c0" - integrity sha512-s1ZCMmQWXy4b5K/TW9i/DtiN8Ku+xCiHcjQ6/J/nDdssirrQNOoB165Zu8EqLMA2lln1JUth9a0aW9Ap2ctrUg== - dependencies: - destr "^2.0.1" - node-fetch-native "^1.4.0" - ufo "^1.3.0" - - on-exit-leak-free@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz#b39c9e3bf7690d890f4861558b0d7b90a442d209" - integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== - - on-finished@2.4.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" - integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== - dependencies: - ee-first "1.1.1" - - on-headers@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.2.tgz#772b0ae6aaa525c399e489adfad90c403eb3c28f" - integrity sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA== - - once@^1.3.0, once@^1.3.1, once@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" - integrity sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w== - dependencies: - wrappy "1" - - onetime@^5.1.0, onetime@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" - integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== - dependencies: - mimic-fn "^2.1.0" - - open@^7.0.3: - version "7.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" - integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== - dependencies: - is-docker "^2.0.0" - is-wsl "^2.1.1" - - open@^8.0.9, open@^8.4.0: - version "8.4.2" - resolved "https://registry.yarnpkg.com/open/-/open-8.4.2.tgz#5b5ffe2a8f793dcd2aad73e550cb87b59cb084f9" - integrity sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ== - dependencies: - define-lazy-prop "^2.0.0" - is-docker "^2.1.1" - is-wsl "^2.2.0" - - optionator@^0.9.1, optionator@^0.9.3: - version "0.9.3" - resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.3.tgz#007397d44ed1872fdc6ed31360190f81814e2c64" - integrity sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg== - dependencies: - "@aashutoshrathi/word-wrap" "^1.2.3" - deep-is "^0.1.3" - fast-levenshtein "^2.0.6" - levn "^0.4.1" - prelude-ls "^1.2.1" - type-check "^0.4.0" - - ora@^5.4.1: - version "5.4.1" - resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" - integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== - dependencies: - bl "^4.1.0" - chalk "^4.1.0" - cli-cursor "^3.1.0" - cli-spinners "^2.5.0" - is-interactive "^1.0.0" - is-unicode-supported "^0.1.0" - log-symbols "^4.1.0" - strip-ansi "^6.0.0" - wcwidth "^1.0.1" - - os-browserify@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" - integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== - - os-homedir@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" - integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== - - os-tmpdir@~1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" - integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g== - - outdent@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/outdent/-/outdent-0.8.0.tgz#2ebc3e77bf49912543f1008100ff8e7f44428eb0" - integrity sha512-KiOAIsdpUTcAXuykya5fnVVT+/5uS0Q1mrkRHcF89tpieSmY33O/tmc54CqwA+bfhbtEfZUNLHaPUiB9X3jt1A== - - p-all@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" - integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== - dependencies: - p-map "^2.0.0" - - p-defer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" - integrity sha512-wB3wfAxZpk2AzOfUMJNL+d36xothRSyj8EXOa4f6GMqYDN9BJaaSISbsk+wS9abmnebVw95C2Kb5t85UmpCxuw== - - p-event@^4.1.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" - integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== - dependencies: - p-timeout "^3.1.0" - - p-filter@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" - integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== - dependencies: - p-map "^2.0.0" - - p-finally@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" - integrity sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow== - - p-limit@^1.1.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" - integrity sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q== - dependencies: - p-try "^1.0.0" - - p-limit@^2.0.0, p-limit@^2.2.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1" - integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w== - dependencies: - p-try "^2.0.0" - - p-limit@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" - integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== - dependencies: - yocto-queue "^0.1.0" - - p-locate@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" - integrity sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg== - dependencies: - p-limit "^1.1.0" - - p-locate@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-3.0.0.tgz#322d69a05c0264b25997d9f40cd8a891ab0064a4" - integrity sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ== - dependencies: - p-limit "^2.0.0" - - p-locate@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-4.1.0.tgz#a3428bb7088b3a60292f66919278b7c297ad4f07" - integrity sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A== - dependencies: - p-limit "^2.2.0" - - p-locate@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" - integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== - dependencies: - p-limit "^3.0.2" - - p-map-series@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-2.1.0.tgz#7560d4c452d9da0c07e692fdbfe6e2c81a2a91f2" - integrity sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q== - - p-map@4.0.0, p-map@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" - integrity sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ== - dependencies: - aggregate-error "^3.0.0" - - p-map@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" - integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== - - p-map@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" - integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== - dependencies: - aggregate-error "^3.0.0" - - p-pipe@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/p-pipe/-/p-pipe-3.1.0.tgz#48b57c922aa2e1af6a6404cb7c6bf0eb9cc8e60e" - integrity sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw== - - p-queue@6.6.2: - version "6.6.2" - resolved "https://registry.yarnpkg.com/p-queue/-/p-queue-6.6.2.tgz#2068a9dcf8e67dd0ec3e7a2bcb76810faa85e426" - integrity sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ== - dependencies: - eventemitter3 "^4.0.4" - p-timeout "^3.2.0" - - p-reduce@2.1.0, p-reduce@^2.0.0, p-reduce@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-2.1.0.tgz#09408da49507c6c274faa31f28df334bc712b64a" - integrity sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw== - - p-retry@^4.5.0: - version "4.6.2" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.2.tgz#9baae7184057edd4e17231cee04264106e092a16" - integrity sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ== - dependencies: - "@types/retry" "0.12.0" - retry "^0.13.1" - - p-timeout@^3.1.0, p-timeout@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" - integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== - dependencies: - p-finally "^1.0.0" - - p-try@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" - integrity sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww== - - p-try@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" - integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== - - p-waterfall@2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/p-waterfall/-/p-waterfall-2.1.1.tgz#63153a774f472ccdc4eb281cdb2967fcf158b2ee" - integrity sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw== - dependencies: - p-reduce "^2.0.0" - - pacote@^15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-15.2.0.tgz#0f0dfcc3e60c7b39121b2ac612bf8596e95344d3" - integrity sha512-rJVZeIwHTUta23sIZgEIM62WYwbmGbThdbnkt81ravBplQv+HjyroqnLRNH2+sLJHcGZmLRmhPwACqhfTcOmnA== - dependencies: - "@npmcli/git" "^4.0.0" - "@npmcli/installed-package-contents" "^2.0.1" - "@npmcli/promise-spawn" "^6.0.1" - "@npmcli/run-script" "^6.0.0" - cacache "^17.0.0" - fs-minipass "^3.0.0" - minipass "^5.0.0" - npm-package-arg "^10.0.0" - npm-packlist "^7.0.0" - npm-pick-manifest "^8.0.0" - npm-registry-fetch "^14.0.0" - proc-log "^3.0.0" - promise-retry "^2.0.1" - read-package-json "^6.0.0" - read-package-json-fast "^3.0.0" - sigstore "^1.3.0" - ssri "^10.0.0" - tar "^6.1.11" - - pako@^2.0.2: - version "2.1.0" - resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86" - integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug== - - pako@~1.0.5: - version "1.0.11" - resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" - integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== - - parallel-transform@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" - integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== - dependencies: - cyclist "^1.0.1" - inherits "^2.0.3" - readable-stream "^2.1.5" - - param-case@^3.0.3, param-case@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" - integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== - dependencies: - dot-case "^3.0.4" - tslib "^2.0.3" - - parent-module@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" - integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g== - dependencies: - callsites "^3.0.0" - - parse-asn1@^5.0.0, parse-asn1@^5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" - integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== - dependencies: - asn1.js "^5.2.0" - browserify-aes "^1.0.0" - evp_bytestokey "^1.0.0" - pbkdf2 "^3.0.3" - safe-buffer "^5.1.1" - - parse-author@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-author/-/parse-author-2.0.0.tgz#d3460bf1ddd0dfaeed42da754242e65fb684a81f" - integrity sha512-yx5DfvkN8JsHL2xk2Os9oTia467qnvRgey4ahSm2X8epehBLx/gWLcy5KI+Y36ful5DzGbCS6RazqZGgy1gHNw== - dependencies: - author-regex "^1.0.0" - - parse-entities@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" - integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== - 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" - - parse-entities@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-4.0.1.tgz#4e2a01111fb1c986549b944af39eeda258fc9e4e" - integrity sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w== - dependencies: - "@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" - - parse-json@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" - integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== - dependencies: - error-ex "^1.2.0" - - parse-json@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" - integrity sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw== - dependencies: - error-ex "^1.3.1" - json-parse-better-errors "^1.0.1" - - parse-json@^5.0.0, parse-json@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" - integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg== - dependencies: - "@babel/code-frame" "^7.0.0" - error-ex "^1.3.1" - json-parse-even-better-errors "^2.3.0" - lines-and-columns "^1.1.6" - - parse-path@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-7.0.0.tgz#605a2d58d0a749c8594405d8cc3a2bf76d16099b" - integrity sha512-Euf9GG8WT9CdqwuWJGdf3RkUcTBArppHABkO7Lm8IzRQp0e2r/kkFnmhu4TSK30Wcu5rVAZLmfPKSBBi9tWFog== - dependencies: - protocols "^2.0.0" - - parse-url@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-8.1.0.tgz#972e0827ed4b57fc85f0ea6b0d839f0d8a57a57d" - integrity sha512-xDvOoLU5XRrcOZvnI6b8zA6n9O9ejNk/GExuz1yBuWUGn9KA97GI6HTs6u02wKara1CeVmZhH+0TZFdWScR89w== - dependencies: - parse-path "^7.0.0" - - parse5@6.0.1, parse5@^6.0.0, parse5@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" - integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== - - parseurl@~1.3.2, parseurl@~1.3.3: - version "1.3.3" - resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" - integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== - - pascal-case@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" - integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== - dependencies: - no-case "^3.0.4" - tslib "^2.0.3" - - pascalcase@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== - - path-browserify@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" - integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== - - path-browserify@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" - integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== - - path-dirname@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== - - path-exists@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" - integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== - dependencies: - pinkie-promise "^2.0.0" - - path-exists@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" - integrity sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ== - - path-exists@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" - integrity sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w== - - path-is-absolute@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" - integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== - - path-is-inside@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" - integrity sha512-DUWJr3+ULp4zXmol/SZkFf3JGsS9/SIv+Y3Rt93/UjPpDpklB5f1er4O3POIbUuUJ3FXgqte2Q7SrU6zAqwk8w== - - path-key@^2.0.0, path-key@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" - integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== - - path-key@^3.0.0, path-key@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" - integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== - - path-parse@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" - integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== - - path-scurry@^1.10.1, path-scurry@^1.6.1: - version "1.10.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.10.1.tgz#9ba6bf5aa8500fe9fd67df4f0d9483b2b0bfc698" - integrity sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ== - dependencies: - lru-cache "^9.1.1 || ^10.0.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" - - path-to-regexp@0.1.7: - version "0.1.7" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" - integrity sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ== - - path-type@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" - integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== - dependencies: - graceful-fs "^4.1.2" - pify "^2.0.0" - pinkie-promise "^2.0.0" - - path-type@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" - integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== - dependencies: - pify "^3.0.0" - - path-type@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" - integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== - - pathe@^1.1.0, pathe@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/pathe/-/pathe-1.1.1.tgz#1dd31d382b974ba69809adc9a7a347e65d84829a" - integrity sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q== - - pbkdf2@^3.0.3: - version "3.1.2" - resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" - integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== - dependencies: - create-hash "^1.1.2" - create-hmac "^1.1.4" - ripemd160 "^2.0.1" - safe-buffer "^5.0.1" - sha.js "^2.4.8" - - periscopic@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/periscopic/-/periscopic-3.1.0.tgz#7e9037bf51c5855bd33b48928828db4afa79d97a" - integrity sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw== - dependencies: - "@types/estree" "^1.0.0" - estree-walker "^3.0.0" - is-reference "^3.0.0" - - picocolors@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" - integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== - - picocolors@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" - integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ== - - picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0, picomatch@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" - integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== - - pidtree@^0.3.0: - version "0.3.1" - resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" - integrity sha512-qQbW94hLHEqCg7nhby4yRC7G2+jYHY4Rguc2bjw7Uug4GIJuu1tvf2uHaZv5Q8zdt+WKJ6qK1FOI6amaWUo5FA== - - pify@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" - integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== - - pify@^2.0.0, pify@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" - integrity sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog== - - pify@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" - integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== - - pify@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" - integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== - - pinkie-promise@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" - integrity sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw== - dependencies: - pinkie "^2.0.0" - - pinkie@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" - integrity sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg== - - pino-abstract-transport@v0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz#4b54348d8f73713bfd14e3dc44228739aa13d9c0" - integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== - dependencies: - duplexify "^4.1.2" - split2 "^4.0.0" - - pino-std-serializers@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz#1791ccd2539c091ae49ce9993205e2cd5dbba1e2" - integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== - - pino@7.11.0: - version "7.11.0" - resolved "https://registry.yarnpkg.com/pino/-/pino-7.11.0.tgz#0f0ea5c4683dc91388081d44bff10c83125066f6" - integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== - dependencies: - atomic-sleep "^1.0.0" - fast-redact "^3.0.0" - on-exit-leak-free "^0.2.0" - pino-abstract-transport v0.5.0 - pino-std-serializers "^4.0.0" - process-warning "^1.0.0" - quick-format-unescaped "^4.0.3" - real-require "^0.1.0" - safe-stable-stringify "^2.1.0" - sonic-boom "^2.2.1" - thread-stream "^0.15.1" - - pirates@^4.0.1, pirates@^4.0.4, pirates@^4.0.5: - version "4.0.6" - resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" - integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== - - pkg-dir@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" - integrity sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw== - dependencies: - find-up "^3.0.0" - - pkg-dir@^4.1.0, pkg-dir@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-4.2.0.tgz#f099133df7ede422e81d1d8448270eeb3e4261f3" - integrity sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ== - dependencies: - find-up "^4.0.0" - - pkg-dir@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" - integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== - dependencies: - find-up "^5.0.0" - - pkg-types@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pkg-types/-/pkg-types-1.0.3.tgz#988b42ab19254c01614d13f4f65a2cfc7880f868" - integrity sha512-nN7pYi0AQqJnoLPC9eHFQ8AcyaixBUOwvqc5TDnIKCMEE6I0y8P7OKA7fPexsXGCGxQDl/cmrLAp26LhcwxZ4A== - dependencies: - jsonc-parser "^3.2.0" - mlly "^1.2.0" - pathe "^1.1.0" - - pnp-webpack-plugin@1.6.4: - version "1.6.4" - resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" - integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== - dependencies: - ts-pnp "^1.1.6" - - polished@^4.2.2: - version "4.2.2" - resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1" - integrity sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ== - dependencies: - "@babel/runtime" "^7.17.8" - - posix-character-classes@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== - - postcss-calc@^8.2.3: - version "8.2.4" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.2.4.tgz#77b9c29bfcbe8a07ff6693dc87050828889739a5" - integrity sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q== - dependencies: - postcss-selector-parser "^6.0.9" - postcss-value-parser "^4.2.0" - - postcss-colormin@^5.3.1: - version "5.3.1" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.3.1.tgz#86c27c26ed6ba00d96c79e08f3ffb418d1d1988f" - integrity sha512-UsWQG0AqTFQmpBegeLLc1+c3jIqBNB0zlDGRWR+dQ3pRKJL1oeMzyqmH3o2PIfn9MBdNrVPWhDbT769LxCTLJQ== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - colord "^2.9.1" - postcss-value-parser "^4.2.0" - - postcss-convert-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.1.3.tgz#04998bb9ba6b65aa31035d669a6af342c5f9d393" - integrity sha512-82pC1xkJZtcJEfiLw6UXnXVXScgtBrjlO5CBmuDQc+dlb88ZYheFsjTn40+zBVi3DkfF7iezO0nJUPLcJK3pvA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - - postcss-discard-comments@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.1.2.tgz#8df5e81d2925af2780075840c1526f0660e53696" - integrity sha512-+L8208OVbHVF2UQf1iDmRcbdjJkuBF6IS29yBDSiWUIzpYaAhtNl6JYnYm12FnkeCwQqF5LeklOu6rAqgfBZqQ== - - postcss-discard-duplicates@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz#9eb4fe8456706a4eebd6d3b7b777d07bad03e848" - integrity sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw== - - postcss-discard-empty@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz#e57762343ff7f503fe53fca553d18d7f0c369c6c" - integrity sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A== - - postcss-discard-overridden@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz#7e8c5b53325747e9d90131bb88635282fb4a276e" - integrity sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw== - - postcss-flexbugs-fixes@^4.2.1: - version "4.2.1" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" - integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== - dependencies: - postcss "^7.0.26" - - postcss-loader@^4.2.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" - integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== - dependencies: - cosmiconfig "^7.0.0" - klona "^2.0.4" - loader-utils "^2.0.0" - schema-utils "^3.0.0" - semver "^7.3.4" - - postcss-merge-longhand@^5.1.7: - version "5.1.7" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.1.7.tgz#24a1bdf402d9ef0e70f568f39bdc0344d568fb16" - integrity sha512-YCI9gZB+PLNskrK0BB3/2OzPnGhPkBEwmwhfYk1ilBHYVAZB7/tkTHFBAnCrvBBOmeYyMYw3DMjT55SyxMBzjQ== - dependencies: - postcss-value-parser "^4.2.0" - stylehacks "^5.1.1" - - postcss-merge-rules@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.1.4.tgz#2f26fa5cacb75b1402e213789f6766ae5e40313c" - integrity sha512-0R2IuYpgU93y9lhVbO/OylTtKMVcHb67zjWIfCiKR9rWL3GUk1677LAqD/BcHizukdZEjT8Ru3oHRoAYoJy44g== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - cssnano-utils "^3.1.0" - postcss-selector-parser "^6.0.5" - - postcss-minify-font-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz#f1df0014a726083d260d3bd85d7385fb89d1f01b" - integrity sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-minify-gradients@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz#f1fe1b4f498134a5068240c2f25d46fcd236ba2c" - integrity sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw== - dependencies: - colord "^2.9.1" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - - postcss-minify-params@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.1.4.tgz#c06a6c787128b3208b38c9364cfc40c8aa5d7352" - integrity sha512-+mePA3MgdmVmv6g+30rn57USjOGSAyuxUmkfiWpzalZ8aiBkdPYjXWtHuwJGm1v5Ojy0Z0LaSYhHaLJQB0P8Jw== - dependencies: - browserslist "^4.21.4" - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - - postcss-minify-selectors@^5.2.1: - version "5.2.1" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.2.1.tgz#d4e7e6b46147b8117ea9325a915a801d5fe656c6" - integrity sha512-nPJu7OjZJTsVUmPdm2TcaiohIwxP+v8ha9NehQ2ye9szv4orirRU3SDdtUmKH+10nzn0bAyOXZ0UEr7OpvLehg== - dependencies: - postcss-selector-parser "^6.0.5" - - postcss-modules-extract-imports@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" - integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== - dependencies: - postcss "^7.0.5" - - postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - - postcss-modules-local-by-default@^3.0.2: - version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" - integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== - dependencies: - icss-utils "^4.1.1" - postcss "^7.0.32" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - - postcss-modules-local-by-default@^4.0.0, postcss-modules-local-by-default@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.3.tgz#b08eb4f083050708998ba2c6061b50c2870ca524" - integrity sha512-2/u2zraspoACtrbFRnTijMiQtb4GW4BvatjaG/bCjYQo8kLTdevCUlwuBHx2sCnSyrI3x3qj4ZK1j5LQBgzmwA== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - - postcss-modules-scope@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" - integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== - dependencies: - postcss "^7.0.6" - postcss-selector-parser "^6.0.0" - - postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - - postcss-modules-values@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" - integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== - dependencies: - icss-utils "^4.0.0" - postcss "^7.0.6" - - postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - - postcss-normalize-charset@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz#9302de0b29094b52c259e9b2cf8dc0879879f0ed" - integrity sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg== - - postcss-normalize-display-values@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz#72abbae58081960e9edd7200fcf21ab8325c3da8" - integrity sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-normalize-positions@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.1.1.tgz#ef97279d894087b59325b45c47f1e863daefbb92" - integrity sha512-6UpCb0G4eofTCQLFVuI3EVNZzBNPiIKcA1AKVka+31fTVySphr3VUgAIULBhxZkKgwLImhzMR2Bw1ORK+37INg== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-normalize-repeat-style@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.1.tgz#e9eb96805204f4766df66fd09ed2e13545420fb2" - integrity sha512-mFpLspGWkQtBcWIRFLmewo8aC3ImN2i/J3v8YCFUwDnPu3Xz4rLohDO26lGjwNsQxB3YF0KKRwspGzE2JEuS0g== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-normalize-string@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz#411961169e07308c82c1f8c55f3e8a337757e228" - integrity sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-normalize-timing-functions@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz#d5614410f8f0b2388e9f240aa6011ba6f52dafbb" - integrity sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-normalize-unicode@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.1.tgz#f67297fca3fea7f17e0d2caa40769afc487aa030" - integrity sha512-qnCL5jzkNUmKVhZoENp1mJiGNPcsJCs1aaRmURmeJGES23Z/ajaln+EPTD+rBeNkSryI+2WTdW+lwcVdOikrpA== - dependencies: - browserslist "^4.21.4" - postcss-value-parser "^4.2.0" - - postcss-normalize-url@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz#ed9d88ca82e21abef99f743457d3729a042adcdc" - integrity sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew== - dependencies: - normalize-url "^6.0.1" - postcss-value-parser "^4.2.0" - - postcss-normalize-whitespace@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz#08a1a0d1ffa17a7cc6efe1e6c9da969cc4493cfa" - integrity sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-ordered-values@^5.1.3: - version "5.1.3" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.1.3.tgz#b6fd2bd10f937b23d86bc829c69e7732ce76ea38" - integrity sha512-9UO79VUhPwEkzbb3RNpqqghc6lcYej1aveQteWY+4POIwlqkYE21HKWaLDF6lWNuqCobEAyTovVhtI32Rbv2RQ== - dependencies: - cssnano-utils "^3.1.0" - postcss-value-parser "^4.2.0" - - postcss-reduce-initial@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.1.2.tgz#798cd77b3e033eae7105c18c9d371d989e1382d6" - integrity sha512-dE/y2XRaqAi6OvjzD22pjTUQ8eOfc6m/natGHgKFBK9DxFmIm69YmaRVQrGgFlEfc1HePIurY0TmDeROK05rIg== - dependencies: - browserslist "^4.21.4" - caniuse-api "^3.0.0" - - postcss-reduce-transforms@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz#333b70e7758b802f3dd0ddfe98bb1ccfef96b6e9" - integrity sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ== - dependencies: - postcss-value-parser "^4.2.0" - - postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5, postcss-selector-parser@^6.0.9: - version "6.0.13" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.13.tgz#d05d8d76b1e8e173257ef9d60b706a8e5e99bf1b" - integrity sha512-EaV1Gl4mUEV4ddhDnv/xtj7sxwrwxdetHdWUGnT4VJQf+4d05v6lHYZr8N573k5Z0BViss7BDhfWtKS3+sfAqQ== - dependencies: - cssesc "^3.0.0" - util-deprecate "^1.0.2" - - postcss-svgo@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.1.0.tgz#0a317400ced789f233a28826e77523f15857d80d" - integrity sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA== - dependencies: - postcss-value-parser "^4.2.0" - svgo "^2.7.0" - - postcss-unique-selectors@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz#a9f273d1eacd09e9aa6088f4b0507b18b1b541b6" - integrity sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA== - dependencies: - postcss-selector-parser "^6.0.5" - - postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" - integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== - - postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: - version "7.0.39" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" - integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== - dependencies: - picocolors "^0.2.1" - source-map "^0.6.1" - - postcss@^8.2.15, postcss@^8.3.5, postcss@^8.4.21: - version "8.4.31" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.31.tgz#92b451050a9f914da6755af352bdc0192508656d" - integrity sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ== - dependencies: - nanoid "^3.3.6" - picocolors "^1.0.0" - source-map-js "^1.0.2" - - prebuild-install@^7.0.0, prebuild-install@^7.1.1: - version "7.1.1" - resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-7.1.1.tgz#de97d5b34a70a0c81334fd24641f2a1702352e45" - integrity sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw== - dependencies: - detect-libc "^2.0.0" - expand-template "^2.0.3" - github-from-package "0.0.0" - minimist "^1.2.3" - mkdirp-classic "^0.5.3" - napi-build-utils "^1.0.1" - node-abi "^3.3.0" - pump "^3.0.0" - rc "^1.2.7" - simple-get "^4.0.0" - tar-fs "^2.0.0" - tunnel-agent "^0.6.0" - - prelude-ls@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz#debc6489d7a6e6b0e7611888cec880337d316396" - integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g== - - prettier-linter-helpers@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" - integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== - dependencies: - fast-diff "^1.1.2" - - "prettier@>=2.2.1 <=2.3.0": - version "2.3.0" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" - integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== - - prettier@^2.8.7: - version "2.8.8" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.8.tgz#e8c5d7e98a4305ffe3de2e1fc4aca1a71c28b1da" - integrity sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q== - - pretty-bytes@^6.0.0: - version "6.1.1" - resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-6.1.1.tgz#38cd6bb46f47afbf667c202cfc754bffd2016a3b" - integrity sha512-mQUvGU6aUFQ+rNvTIAcZuWGRT9a6f6Yrg9bHs4ImKF+HZCEK+plBvnAZYSIQztknZF2qnzNtr6F8s0+IuptdlQ== - - pretty-error@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" - integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== - dependencies: - lodash "^4.17.20" - renderkid "^2.0.4" - - pretty-error@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" - integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== - dependencies: - lodash "^4.17.20" - renderkid "^3.0.0" - - pretty-format@^27.0.0, pretty-format@^27.0.2, pretty-format@^27.5.1: - version "27.5.1" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" - integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== - dependencies: - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^17.0.1" - - pretty-format@^28.1.3: - version "28.1.3" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-28.1.3.tgz#c9fba8cedf99ce50963a11b27d982a9ae90970d5" - integrity sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q== - dependencies: - "@jest/schemas" "^28.1.3" - ansi-regex "^5.0.1" - ansi-styles "^5.0.0" - react-is "^18.0.0" - - pretty-format@^29.0.0, pretty-format@^29.5.0, pretty-format@^29.7.0: - version "29.7.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.7.0.tgz#ca42c758310f365bfa71a0bda0a807160b776812" - integrity sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ== - dependencies: - "@jest/schemas" "^29.6.3" - ansi-styles "^5.0.0" - react-is "^18.0.0" - - pretty-hrtime@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" - integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== - - proc-log@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-3.0.0.tgz#fb05ef83ccd64fd7b20bbe9c8c1070fc08338dd8" - integrity sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A== - - process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== - - process-warning@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/process-warning/-/process-warning-1.0.0.tgz#980a0b25dc38cd6034181be4b7726d89066b4616" - integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== - - process@^0.11.10: - version "0.11.10" - resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" - integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== - - progress@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8" - integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA== - - promise-inflight@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" - integrity sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g== - - promise-retry@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/promise-retry/-/promise-retry-2.0.1.tgz#ff747a13620ab57ba688f5fc67855410c370da22" - integrity sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g== - dependencies: - err-code "^2.0.2" - retry "^0.12.0" - - promise.allsettled@^1.0.0: - version "1.0.7" - resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.7.tgz#b9dd51e9cffe496243f5271515652c468865f2d8" - integrity sha512-hezvKvQQmsFkOdrZfYxUxkyxl8mgFQeT259Ajj9PXdbg9VzBCWrItOev72JyWxkCD5VSSqAeHmlN3tWx4DlmsA== - dependencies: - array.prototype.map "^1.0.5" - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - iterate-value "^1.0.2" - - promise.prototype.finally@^3.1.0: - version "3.1.7" - resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.7.tgz#9d163f58edf3004d14878c988a22b1cb45e03407" - integrity sha512-iL9OcJRUZcCE5xn6IwhZxO+eMM0VEXjkETHy+Nk+d9q3s7kxVtPg+mBlMO+ZGxNKNMODyKmy/bOyt/yhxTnvEw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.1" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - set-function-name "^2.0.1" - - prompts@^2.0.1, prompts@^2.4.0: - version "2.4.2" - resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" - integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== - dependencies: - kleur "^3.0.3" - sisteransi "^1.0.5" - - promzard@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/promzard/-/promzard-1.0.0.tgz#3246f8e6c9895a77c0549cefb65828ac0f6c006b" - integrity sha512-KQVDEubSUHGSt5xLakaToDFrSoZhStB8dXLzk2xvwR67gJktrHFvpR63oZgHyK19WKbHFLXJqCPXdVR3aBP8Ig== - dependencies: - read "^2.0.0" - - prop-types@^15.0.0, prop-types@^15.6.0, prop-types@^15.6.2, prop-types@^15.7.2, prop-types@^15.8.1: - version "15.8.1" - resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" - integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== - dependencies: - loose-envify "^1.4.0" - object-assign "^4.1.1" - react-is "^16.13.1" - - property-expr@^2.0.4, property-expr@^2.0.5: - version "2.0.6" - resolved "https://registry.yarnpkg.com/property-expr/-/property-expr-2.0.6.tgz#f77bc00d5928a6c748414ad12882e83f24aec1e8" - integrity sha512-SVtmxhRE/CGkn3eZY1T6pC8Nln6Fr/lu1mKSgRud0eC73whjGfoAogbn78LkD8aFL0zz3bAFerKSnOl7NlErBA== - - property-information@^5.0.0, property-information@^5.3.0: - version "5.6.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" - integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== - dependencies: - xtend "^4.0.0" - - property-information@^6.0.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.4.0.tgz#6bc4c618b0c2d68b3bb8b552cbb97f8e300a0f82" - integrity sha512-9t5qARVofg2xQqKtytzt+lZ4d1Qvj8t5B8fEwXK6qOfgRLgH/b13QlgEyDh033NOS31nXeFbYv7CLUDG1CeifQ== - - protobufjs@^6.11.2, protobufjs@^6.8.8, protobufjs@~6.11.2, protobufjs@~6.11.3: - version "6.11.4" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.11.4.tgz#29a412c38bf70d89e537b6d02d904a6f448173aa" - integrity sha512-5kQWPaJHi1WoCpjTGszzQ32PG2F4+wRY6BmAT4Vfw56Q2FZ4YZzK20xUYQH4YkfehY1e6QSICrJquM6xXZNcrw== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" ">=13.7.0" - long "^4.0.0" - - protobufjs@~6.10.2: - version "6.10.3" - resolved "https://registry.yarnpkg.com/protobufjs/-/protobufjs-6.10.3.tgz#11ed1dd02acbfcb330becf1611461d4b407f9eef" - integrity sha512-yvAslS0hNdBhlSKckI4R1l7wunVilX66uvrjzE4MimiAt7/qw1nLpMhZrn/ObuUTM/c3Xnfl01LYMdcSJe6dwg== - dependencies: - "@protobufjs/aspromise" "^1.1.2" - "@protobufjs/base64" "^1.1.2" - "@protobufjs/codegen" "^2.0.4" - "@protobufjs/eventemitter" "^1.1.0" - "@protobufjs/fetch" "^1.1.0" - "@protobufjs/float" "^1.0.2" - "@protobufjs/inquire" "^1.1.0" - "@protobufjs/path" "^1.1.2" - "@protobufjs/pool" "^1.1.0" - "@protobufjs/utf8" "^1.1.0" - "@types/long" "^4.0.1" - "@types/node" "^13.7.0" - long "^4.0.0" - - protocols@^2.0.0, protocols@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/protocols/-/protocols-2.0.1.tgz#8f155da3fc0f32644e83c5782c8e8212ccf70a86" - integrity sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q== - - proxy-addr@~2.0.7: - version "2.0.7" - resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" - integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== - dependencies: - forwarded "0.2.0" - ipaddr.js "1.9.1" - - proxy-from-env@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" - integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== - - prr@~1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" - integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== - - psl@^1.1.33: - version "1.9.0" - resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" - integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== - - pstree.remy@^1.1.8: - version "1.1.8" - resolved "https://registry.yarnpkg.com/pstree.remy/-/pstree.remy-1.1.8.tgz#c242224f4a67c21f686839bbdb4ac282b8373d3a" - integrity sha512-77DZwxQmxKnu3aR542U+X8FypNzbfJ+C5XQDk3uWjWxn6151aIMGthWYRXTqT1E5oJvg+ljaa2OJi+VfvCOQ8w== - - public-encrypt@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" - integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== - dependencies: - bn.js "^4.1.0" - browserify-rsa "^4.0.0" - create-hash "^1.1.0" - parse-asn1 "^5.0.0" - randombytes "^2.0.1" - safe-buffer "^5.1.2" - - pump@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" - integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - - pump@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" - integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww== - dependencies: - end-of-stream "^1.1.0" - once "^1.3.1" - - pumpify@^1.3.3: - version "1.5.1" - resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" - integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== - dependencies: - duplexify "^3.6.0" - inherits "^2.0.3" - pump "^2.0.0" - - punycode@^1.2.4, punycode@^1.4.1: - version "1.4.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" - integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== - - punycode@^2.1.0, punycode@^2.1.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" - integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== - - qr.js@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/qr.js/-/qr.js-0.0.0.tgz#cace86386f59a0db8050fa90d9b6b0e88a1e364f" - integrity sha512-c4iYnWb+k2E+vYpRimHqSu575b1/wKl4XFeJGpFmrJQz5I88v9aY2czh7s0w36srfCM1sXgC/xpoJz5dJfq+OQ== - - qrcode.react@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/qrcode.react/-/qrcode.react-1.0.1.tgz#2834bb50e5e275ffe5af6906eff15391fe9e38a5" - integrity sha512-8d3Tackk8IRLXTo67Y+c1rpaiXjoz/Dd2HpcMdW//62/x8J1Nbho14Kh8x974t9prsLHN6XqVgcnRiBGFptQmg== - dependencies: - loose-envify "^1.4.0" - prop-types "^15.6.0" - qr.js "0.0.0" - - qs@6.11.0: - version "6.11.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" - integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== - dependencies: - side-channel "^1.0.4" - - qs@^6.10.0, qs@^6.11.2: - version "6.11.2" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.2.tgz#64bea51f12c1f5da1bc01496f48ffcff7c69d7d9" - integrity sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA== - dependencies: - side-channel "^1.0.4" - - query-string@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" - integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== - dependencies: - decode-uri-component "^0.2.2" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - - querystring-es3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" - integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== - - querystringify@^2.1.1: - version "2.2.0" - resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" - integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== - - queue-microtask@^1.2.2: - version "1.2.3" - resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" - integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== - - queue-tick@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/queue-tick/-/queue-tick-1.0.1.tgz#f6f07ac82c1fd60f82e098b417a80e52f1f4c142" - integrity sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag== - - quick-format-unescaped@^4.0.3: - version "4.0.4" - resolved "https://registry.yarnpkg.com/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz#93ef6dd8d3453cbc7970dd614fad4c5954d6b5a7" - integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== - - quick-lru@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" - integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== - - radix3@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/radix3/-/radix3-1.1.0.tgz#9745df67a49c522e94a33d0a93cf743f104b6e0d" - integrity sha512-pNsHDxbGORSvuSScqNJ+3Km6QAVqk8CfsCBIEoDgpqLrkD2f3QM4I7d1ozJJ172OmIcoUcerZaNWqtLkRXTV3A== - - rainbow-sprinkles@^0.17.0: - version "0.17.0" - resolved "https://registry.yarnpkg.com/rainbow-sprinkles/-/rainbow-sprinkles-0.17.0.tgz#6ee06c6decc767b89bf01fc5fe87ecf859fd4c2f" - integrity sha512-ok3NrylQ0szvJtuBYaB/w09L9zOvvqcSQrvycT2A5XJxQNvwvkeADvTqQWGOQ3b6MkO8UmYccBPt8g8vVvxM9A== - - rambda@^7.4.0: - version "7.5.0" - resolved "https://registry.yarnpkg.com/rambda/-/rambda-7.5.0.tgz#1865044c59bc0b16f63026c6e5a97e4b1bbe98fe" - integrity sha512-y/M9weqWAH4iopRd7EHDEQQvpFPHj1AA3oHozE9tfITHUtTR7Z9PSlIRRG2l1GuW7sefC1cXFfIcF+cgnShdBA== - - ramda@0.29.0: - version "0.29.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.29.0.tgz#fbbb67a740a754c8a4cbb41e2a6e0eb8507f55fb" - integrity sha512-BBea6L67bYLtdbOqfp8f58fPMqEwx0doL+pAi8TZyp2YWz8R9G8z9x75CZI8W+ftqhFHCpEX2cRnUUXK130iKA== - - ramda@^0.26.1: - version "0.26.1" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.26.1.tgz#8d41351eb8111c55353617fc3bbffad8e4d35d06" - integrity sha512-hLWjpy7EnsDBb0p+Z3B7rPi3GDeRG5ZtiI33kJhTt+ORCd38AbAIjB/9zRIUoeTbE/AVX5ZkU7m6bznsvrf8eQ== - - ramda@^0.28.0: - version "0.28.0" - resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" - integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== - - randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - - randomfill@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" - integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== - dependencies: - randombytes "^2.0.5" - safe-buffer "^5.1.0" - - range-parser@^1.2.1, range-parser@~1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" - integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== - - raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== - dependencies: - bytes "3.1.2" - http-errors "2.0.0" - iconv-lite "0.4.24" - unpipe "1.0.0" - - raw-loader@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" - integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - - rc@^1.2.7: - version "1.2.8" - resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" - integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw== - dependencies: - deep-extend "^0.6.0" - ini "~1.3.0" - minimist "^1.2.0" - strip-json-comments "~2.0.1" - - react-aria@^3.29.1: - version "3.30.0" - resolved "https://registry.yarnpkg.com/react-aria/-/react-aria-3.30.0.tgz#dd53d2103050e7279ec8f3faacce5ae8521f61ce" - integrity sha512-ULMlmH68/jXzkDaMjuM9O8dKCxnAYviW4E5sywfLX4J6mC6eGsQzoqtwWeQgr1M9SJqLfgKaVoDP1dLvb4XzEA== - dependencies: - "@react-aria/breadcrumbs" "^3.5.8" - "@react-aria/button" "^3.9.0" - "@react-aria/calendar" "^3.5.3" - "@react-aria/checkbox" "^3.12.0" - "@react-aria/combobox" "^3.8.0" - "@react-aria/datepicker" "^3.9.0" - "@react-aria/dialog" "^3.5.8" - "@react-aria/dnd" "^3.5.0" - "@react-aria/focus" "^3.15.0" - "@react-aria/gridlist" "^3.7.2" - "@react-aria/i18n" "^3.9.0" - "@react-aria/interactions" "^3.20.0" - "@react-aria/label" "^3.7.3" - "@react-aria/link" "^3.6.2" - "@react-aria/listbox" "^3.11.2" - "@react-aria/menu" "^3.11.2" - "@react-aria/meter" "^3.4.8" - "@react-aria/numberfield" "^3.10.0" - "@react-aria/overlays" "^3.19.0" - "@react-aria/progress" "^3.4.8" - "@react-aria/radio" "^3.9.0" - "@react-aria/searchfield" "^3.6.0" - "@react-aria/select" "^3.14.0" - "@react-aria/selection" "^3.17.2" - "@react-aria/separator" "^3.3.8" - "@react-aria/slider" "^3.7.3" - "@react-aria/ssr" "^3.9.0" - "@react-aria/switch" "^3.5.7" - "@react-aria/table" "^3.13.2" - "@react-aria/tabs" "^3.8.2" - "@react-aria/tag" "^3.3.0" - "@react-aria/textfield" "^3.13.0" - "@react-aria/tooltip" "^3.6.5" - "@react-aria/utils" "^3.22.0" - "@react-aria/visually-hidden" "^3.8.7" - "@react-types/shared" "^3.22.0" - - react-docgen-typescript@^2.1.1: - version "2.2.2" - resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.2.2.tgz#4611055e569edc071204aadb20e1c93e1ab1659c" - integrity sha512-tvg2ZtOpOi6QDwsb3GZhOjDkkX0h8Z2gipvTg6OVMUyoYoURhEiRNePT8NZItTVCDh39JJHnLdfCOkzoLbFnTg== - - react-docgen@^5.0.0: - version "5.4.3" - resolved "https://registry.yarnpkg.com/react-docgen/-/react-docgen-5.4.3.tgz#7d297f73b977d0c7611402e5fc2a168acf332b26" - integrity sha512-xlLJyOlnfr8lLEEeaDZ+X2J/KJoe6Nr9AzxnkdQWush5hz2ZSu66w6iLMOScMmxoSHWpWMn+k3v5ZiyCfcWsOA== - dependencies: - "@babel/core" "^7.7.5" - "@babel/generator" "^7.12.11" - "@babel/runtime" "^7.7.6" - ast-types "^0.14.2" - commander "^2.19.0" - doctrine "^3.0.0" - estree-to-babel "^3.1.0" - neo-async "^2.6.1" - node-dir "^0.1.10" - strip-indent "^3.0.0" - - react-dom@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d" - integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g== - dependencies: - loose-envify "^1.1.0" - scheduler "^0.23.0" - - react-element-to-jsx-string@^14.3.4: - version "14.3.4" - resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz#709125bc72f06800b68f9f4db485f2c7d31218a8" - integrity sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg== - dependencies: - "@base2/pretty-print-object" "1.0.1" - is-plain-object "5.0.0" - react-is "17.0.2" - - react-error-boundary@^3.1.3, react-error-boundary@^3.1.4: - version "3.1.4" - resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-3.1.4.tgz#255db92b23197108757a888b01e5b729919abde0" - integrity sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA== - dependencies: - "@babel/runtime" "^7.12.5" - - react-google-charts@^3.0.15: - version "3.0.15" - resolved "https://registry.yarnpkg.com/react-google-charts/-/react-google-charts-3.0.15.tgz#30759a470f48336e744fd383d054122b039a1ff2" - integrity sha512-78s5xOQOJvL+jIewrWQZEHtlVk+5Yh4zZy+ODA1on1o1FaRjKWXxoo4n4JQl1XuqkF/A9NWque3KqM6pMggjzQ== - dependencies: - react-load-script "^0.0.6" - - react-hook-form@^7.14.2: - version "7.48.2" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.48.2.tgz#01150354d2be61412ff56a030b62a119283b9935" - integrity sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A== - - react-identicons@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/react-identicons/-/react-identicons-1.2.5.tgz#3502249e49d88f4e3500092694410a984bb102fa" - integrity sha512-x7prkDoc2pD7wSl2C1pGxS+XAoSdq1ABWJWTBUimVTDVJArKOLd0B4wRUJpDm4r+9y7pgf8ylyPGsmlWSV5n2g== - - react-inspector@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" - integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== - dependencies: - "@babel/runtime" "^7.0.0" - is-dom "^1.0.0" - prop-types "^15.0.0" - - react-is@17.0.2, react-is@^17.0.1: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" - integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== - - react-is@^16.10.2, react-is@^16.13.1, react-is@^16.7.0: - version "16.13.1" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" - integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== - - react-is@^18.0.0, react-is@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b" - integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w== - - react-lifecycles-compat@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" - integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== - - react-load-script@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/react-load-script/-/react-load-script-0.0.6.tgz#db6851236aaa25bb622677a2eb51dad4f8d2c258" - integrity sha512-aRGxDGP9VoLxcsaYvKWIW+LRrMOzz2eEcubTS4NvQPPugjk2VvMhow0wWTkSl7RxookomD1MwcP4l5UStg5ShQ== - - react-markdown@^8.0.4: - version "8.0.7" - resolved "https://registry.yarnpkg.com/react-markdown/-/react-markdown-8.0.7.tgz#c8dbd1b9ba5f1c5e7e5f2a44de465a3caafdf89b" - integrity sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ== - dependencies: - "@types/hast" "^2.0.0" - "@types/prop-types" "^15.0.0" - "@types/unist" "^2.0.0" - comma-separated-tokens "^2.0.0" - hast-util-whitespace "^2.0.0" - prop-types "^15.0.0" - property-information "^6.0.0" - react-is "^18.0.0" - remark-parse "^10.0.0" - remark-rehype "^10.0.0" - space-separated-tokens "^2.0.0" - style-to-object "^0.4.0" - unified "^10.0.0" - unist-util-visit "^4.0.0" - vfile "^5.0.0" - - react-merge-refs@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" - integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== - - react-refresh-typescript@^2.0.2: - version "2.0.9" - resolved "https://registry.yarnpkg.com/react-refresh-typescript/-/react-refresh-typescript-2.0.9.tgz#f8a86efcb34f8d717100230564b9b57477d74b10" - integrity sha512-chAnOO4vpxm/3WkgOVmti+eN8yUtkJzeGkOigV6UA9eDFz12W34e/SsYe2H5+RwYJ3+sfSZkVbiXcG1chEBxlg== - - react-refresh@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.10.0.tgz#2f536c9660c0b9b1d500684d9e52a65e7404f7e3" - integrity sha512-PgidR3wST3dDYKr6b4pJoqQFpPGNKDSCDx4cZoshjXipw3LzO7mG1My2pwEzz2JVkF+inx3xRpDeQLFQGH/hsQ== - - react-refresh@^0.11.0: - version "0.11.0" - resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.11.0.tgz#77198b944733f0f1f1a90e791de4541f9f074046" - integrity sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A== - - react-router-dom@6, react-router-dom@^6.7.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.20.0.tgz#7b9527a1e29c7fb90736a5f89d54ca01f40e264b" - integrity sha512-CbcKjEyiSVpA6UtCHOIYLUYn/UJfwzp55va4yEfpk7JBN3GPqWfHrdLkAvNCcpXr8QoihcDMuk0dzWZxtlB/mQ== - dependencies: - "@remix-run/router" "1.13.0" - react-router "6.20.0" - - react-router@6.20.0: - version "6.20.0" - resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.20.0.tgz#4275a3567ecc55f7703073158048db10096bb539" - integrity sha512-pVvzsSsgUxxtuNfTHC4IxjATs10UaAtvLGVSA1tbUE4GDaOSU1Esu2xF5nWLz7KPiMuW8BJWuPFdlGYJ7/rW0w== - dependencies: - "@remix-run/router" "1.13.0" - - react-simple-maps@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/react-simple-maps/-/react-simple-maps-2.3.0.tgz#7fdb55120335a9b1ef5bf62e0dcb669511705f3e" - integrity sha512-IZVeiPSRZKwD6I/2NvXpQ2uENYGDGZp8DvZjkapcxuJ/LQHTfl+Byb+KNgY7s+iatRA2ad8LnZ3AgqcjziCCsw== - dependencies: - d3-geo "^2.0.1" - d3-selection "^2.0.0" - d3-zoom "^2.0.0" - topojson-client "^3.1.0" - - react-smooth@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/react-smooth/-/react-smooth-2.0.5.tgz#d153b7dffc7143d0c99e82db1532f8cf93f20ecd" - integrity sha512-BMP2Ad42tD60h0JW6BFaib+RJuV5dsXJK9Baxiv/HlNFjvRLqA9xrNKxVWnUIZPQfzUwGXIlU/dSYLU+54YGQA== - dependencies: - fast-equals "^5.0.0" - react-transition-group "2.9.0" - - react-stately@^3.27.1: - version "3.28.0" - resolved "https://registry.yarnpkg.com/react-stately/-/react-stately-3.28.0.tgz#f2831e50b70b0dcec7e3d7e3787f9dc1df42d9c3" - integrity sha512-owEHRGS1zRMwtiR/jeXUjUWyqk8oe53wNtedMvg9+8+NNhDKL4/DXHcIp2A13q08v09xYWgVPtnu8fsF53x2PQ== - dependencies: - "@react-stately/calendar" "^3.4.2" - "@react-stately/checkbox" "^3.6.0" - "@react-stately/collections" "^3.10.3" - "@react-stately/combobox" "^3.8.0" - "@react-stately/data" "^3.11.0" - "@react-stately/datepicker" "^3.9.0" - "@react-stately/dnd" "^3.2.6" - "@react-stately/form" "^3.0.0" - "@react-stately/list" "^3.10.1" - "@react-stately/menu" "^3.5.7" - "@react-stately/numberfield" "^3.7.0" - "@react-stately/overlays" "^3.6.4" - "@react-stately/radio" "^3.10.0" - "@react-stately/searchfield" "^3.5.0" - "@react-stately/select" "^3.6.0" - "@react-stately/selection" "^3.14.1" - "@react-stately/slider" "^3.4.5" - "@react-stately/table" "^3.11.3" - "@react-stately/tabs" "^3.6.2" - "@react-stately/toggle" "^3.7.0" - "@react-stately/tooltip" "^3.4.6" - "@react-stately/tree" "^3.7.4" - "@react-types/shared" "^3.22.0" - - react-tooltip@*: - version "5.24.0" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-5.24.0.tgz#c134e4c00d49a111986711696bcd9abf672caff6" - integrity sha512-HjstgpOrUwP4eN6mHU4EThpbxVuKO5SvqumRt1aAcPq0ya+pIVVxlwltndtdIIMBJ7w3jnN05vNfcfh2sxE2mQ== - dependencies: - "@floating-ui/dom" "^1.0.0" - classnames "^2.3.0" - - react-tooltip@^4.2.21: - version "4.5.1" - resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-4.5.1.tgz#77eccccdf16adec804132e558ec20ca5783b866a" - integrity sha512-Zo+CSFUGXar1uV+bgXFFDe7VeS2iByeIp5rTgTcc2HqtuOS5D76QapejNNfx320MCY91TlhTQat36KGFTqgcvw== - dependencies: - prop-types "^15.8.1" - uuid "^7.0.3" - - react-transition-group@2.9.0: - version "2.9.0" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-2.9.0.tgz#df9cdb025796211151a436c69a8f3b97b5b07c8d" - integrity sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg== - dependencies: - dom-helpers "^3.4.0" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react-lifecycles-compat "^3.0.4" - - react-transition-group@^4.4.5: - version "4.4.5" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.5.tgz#e53d4e3f3344da8521489fbef8f2581d42becdd1" - integrity sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - - react@^18.2.0: - version "18.2.0" - resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" - integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== - dependencies: - loose-envify "^1.1.0" - - read-cmd-shim@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/read-cmd-shim/-/read-cmd-shim-4.0.0.tgz#640a08b473a49043e394ae0c7a34dd822c73b9bb" - integrity sha512-yILWifhaSEEytfXI76kB9xEEiG1AiozaCJZ83A87ytjRiN+jVibXjedjCRNjoZviinhG+4UkalO3mWTd8u5O0Q== - - read-package-json-fast@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz#394908a9725dc7a5f14e70c8e7556dff1d2b1049" - integrity sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw== - dependencies: - json-parse-even-better-errors "^3.0.0" - npm-normalize-package-bin "^3.0.0" - - read-package-json@6.0.4, read-package-json@^6.0.0: - version "6.0.4" - resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-6.0.4.tgz#90318824ec456c287437ea79595f4c2854708836" - integrity sha512-AEtWXYfopBj2z5N5PbkAOeNHRPUg5q+Nen7QLxV8M2zJq1ym6/lCz3fYNTCXe19puu2d06jfHhrP7v/S2PtMMw== - dependencies: - glob "^10.2.2" - json-parse-even-better-errors "^3.0.0" - normalize-package-data "^5.0.0" - npm-normalize-package-bin "^3.0.0" - - read-pkg-up@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" - integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== - dependencies: - find-up "^1.0.0" - read-pkg "^1.0.0" - - read-pkg-up@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" - integrity sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw== - dependencies: - find-up "^2.0.0" - read-pkg "^3.0.0" - - read-pkg-up@^7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" - integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== - dependencies: - find-up "^4.1.0" - read-pkg "^5.2.0" - type-fest "^0.8.1" - - read-pkg@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" - integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== - dependencies: - load-json-file "^1.0.0" - normalize-package-data "^2.3.2" - path-type "^1.0.0" - - read-pkg@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" - integrity sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA== - dependencies: - load-json-file "^4.0.0" - normalize-package-data "^2.3.2" - path-type "^3.0.0" - - read-pkg@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" - integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== - dependencies: - "@types/normalize-package-data" "^2.4.0" - normalize-package-data "^2.5.0" - parse-json "^5.0.0" - type-fest "^0.6.0" - - read@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/read/-/read-2.1.0.tgz#69409372c54fe3381092bc363a00650b6ac37218" - integrity sha512-bvxi1QLJHcaywCAEsAk4DG3nVoqiY2Csps3qzWalhj5hFqRn1d/OixkFXtLO1PrgHUcAP0FNaSY/5GYNfENFFQ== - dependencies: - mute-stream "~1.0.0" - - "readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - - readable-stream@3, readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.4.0, readable-stream@^3.6.0, readable-stream@^3.6.2: - version "3.6.2" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" - integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== - dependencies: - inherits "^2.0.3" - string_decoder "^1.1.1" - util-deprecate "^1.0.1" - - readdirp@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.2.1.tgz#0e87622a3325aa33e892285caf8b4e846529a525" - integrity sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ== - dependencies: - graceful-fs "^4.1.11" - micromatch "^3.1.10" - readable-stream "^2.0.2" - - readdirp@~3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" - integrity sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA== - dependencies: - picomatch "^2.2.1" - - readonly-date@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/readonly-date/-/readonly-date-1.0.0.tgz#5af785464d8c7d7c40b9d738cbde8c646f97dcd9" - integrity sha512-tMKIV7hlk0h4mO3JTmmVuIlJVXjKk3Sep9Bf5OH0O+758ruuVkUy2J9SttDLm91IEX/WHlXPSpxMGjPj4beMIQ== - - real-require@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/real-require/-/real-require-0.1.0.tgz#736ac214caa20632847b7ca8c1056a0767df9381" - integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== - - recharts-scale@^0.4.4: - version "0.4.5" - resolved "https://registry.yarnpkg.com/recharts-scale/-/recharts-scale-0.4.5.tgz#0969271f14e732e642fcc5bd4ab270d6e87dd1d9" - integrity sha512-kivNFO+0OcUNu7jQquLXAxz1FIwZj8nrj+YkOKc5694NbjCvcT6aSZiIzNzd2Kul4o4rTto8QVR9lMNtxD4G1w== - dependencies: - decimal.js-light "^2.4.1" - - recharts@^2.1.13: - version "2.10.2" - resolved "https://registry.yarnpkg.com/recharts/-/recharts-2.10.2.tgz#919e9ccba463c7face91438c807340f300435e55" - integrity sha512-goasBqGqpH8SLty+a24xG1KkZWowo793mgoNVrOkBRXZCG2xX+BUbCgaWrB/G+DGIpN2AX/arCttLuHdg/A6LQ== - dependencies: - clsx "^2.0.0" - eventemitter3 "^4.0.1" - lodash "^4.17.19" - react-is "^16.10.2" - react-smooth "^2.0.5" - recharts-scale "^0.4.4" - tiny-invariant "^1.3.1" - victory-vendor "^36.6.8" - - rechoir@^0.7.0: - version "0.7.1" - resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.7.1.tgz#9478a96a1ca135b5e88fc027f03ee92d6c645686" - integrity sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg== - dependencies: - resolve "^1.9.0" - - redent@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" - integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== - dependencies: - indent-string "^2.1.0" - strip-indent "^1.0.1" - - redent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" - integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== - dependencies: - indent-string "^4.0.0" - strip-indent "^3.0.0" - - redis-errors@^1.0.0, redis-errors@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/redis-errors/-/redis-errors-1.2.0.tgz#eb62d2adb15e4eaf4610c04afe1529384250abad" - integrity sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w== - - redis-parser@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/redis-parser/-/redis-parser-3.0.0.tgz#b66d828cdcafe6b4b8a428a7def4c6bcac31c8b4" - integrity sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A== - dependencies: - redis-errors "^1.0.0" - - reflect.getprototypeof@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reflect.getprototypeof/-/reflect.getprototypeof-1.0.4.tgz#aaccbf41aca3821b87bb71d9dcbc7ad0ba50a3f3" - integrity sha512-ECkTw8TmJwW60lOTR+ZkODISW6RQ8+2CL3COqtiJKLd6MmB45hN51HprHFziKLGkAuTGQhBb91V8cy+KHlaCjw== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - globalthis "^1.0.3" - which-builtin-type "^1.1.3" - - regenerate-unicode-properties@^10.1.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" - integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== - dependencies: - regenerate "^1.4.2" - - regenerate@^1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" - integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== - - regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.7: - version "0.13.11" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9" - integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg== - - regenerator-runtime@^0.14.0: - version "0.14.0" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.14.0.tgz#5e19d68eb12d486f797e15a3c6a918f7cec5eb45" - integrity sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA== - - regenerator-transform@^0.15.2: - version "0.15.2" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.2.tgz#5bbae58b522098ebdf09bca2f83838929001c7a4" - integrity sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg== - dependencies: - "@babel/runtime" "^7.8.4" - - regex-not@^1.0.0, regex-not@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" - integrity sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A== - dependencies: - extend-shallow "^3.0.2" - safe-regex "^1.1.0" - - regexp.prototype.flags@^1.5.0, regexp.prototype.flags@^1.5.1: - version "1.5.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz#90ce989138db209f81492edd734183ce99f9677e" - integrity sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - set-function-name "^2.0.0" - - regexpp@^3.1.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" - integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== - - regexpu-core@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" - integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== - dependencies: - "@babel/regjsgen" "^0.8.0" - regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsparser "^0.9.1" - unicode-match-property-ecmascript "^2.0.0" - unicode-match-property-value-ecmascript "^2.1.0" - - regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== - dependencies: - jsesc "~0.5.0" - - relateurl@^0.2.7: - version "0.2.7" - resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" - integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== - - remark-external-links@^8.0.0: - version "8.0.0" - resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" - integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== - dependencies: - extend "^3.0.0" - is-absolute-url "^3.0.0" - mdast-util-definitions "^4.0.0" - space-separated-tokens "^1.0.0" - unist-util-visit "^2.0.0" - - remark-footnotes@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" - integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== - - remark-mdx@1.6.22: - version "1.6.22" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" - integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== - 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" - - remark-mdx@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-2.3.0.tgz#efe678025a8c2726681bde8bf111af4a93943db4" - integrity sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g== - dependencies: - mdast-util-mdx "^2.0.0" - micromark-extension-mdxjs "^1.0.0" - - remark-parse@8.0.3: - version "8.0.3" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" - 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" - - remark-parse@^10.0.0: - version "10.0.2" - resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-10.0.2.tgz#ca241fde8751c2158933f031a4e3efbaeb8bc262" - integrity sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw== - dependencies: - "@types/mdast" "^3.0.0" - mdast-util-from-markdown "^1.0.0" - unified "^10.0.0" - - remark-rehype@^10.0.0: - version "10.1.0" - resolved "https://registry.yarnpkg.com/remark-rehype/-/remark-rehype-10.1.0.tgz#32dc99d2034c27ecaf2e0150d22a6dcccd9a6279" - integrity sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw== - dependencies: - "@types/hast" "^2.0.0" - "@types/mdast" "^3.0.0" - mdast-util-to-hast "^12.1.0" - unified "^10.0.0" - - remark-slug@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" - integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== - dependencies: - github-slugger "^1.0.0" - mdast-util-to-string "^1.0.0" - unist-util-visit "^2.0.0" - - remark-squeeze-paragraphs@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" - integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== - dependencies: - mdast-squeeze-paragraphs "^4.0.0" - - remove-trailing-separator@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== - - renderkid@^2.0.4: - version "2.0.7" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" - integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^3.0.1" - - renderkid@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" - integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== - dependencies: - css-select "^4.1.3" - dom-converter "^0.2.0" - htmlparser2 "^6.1.0" - lodash "^4.17.21" - strip-ansi "^6.0.1" - - repeat-element@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" - integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== - - repeat-string@^1.5.4, repeat-string@^1.6.1: - version "1.6.1" - resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== - - repeating@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" - integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== - dependencies: - is-finite "^1.0.0" - - replace-ext@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.1.tgz#2d6d996d04a15855d967443631dd5f77825b016a" - integrity sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw== - - require-directory@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" - integrity sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q== - - require-from-string@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" - integrity sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw== - - requireindex@^1.1.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" - integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== - - requires-port@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" - integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== - - reselect@^4.1.6: - version "4.1.8" - resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.8.tgz#3f5dc671ea168dccdeb3e141236f69f02eaec524" - integrity sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ== - - resolve-cwd@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-3.0.0.tgz#0f0075f1bb2544766cf73ba6a6e2adfebcb13f2d" - integrity sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg== - dependencies: - resolve-from "^5.0.0" - - resolve-from@5.0.0, resolve-from@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" - integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== - - resolve-from@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" - integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== - - resolve-url@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== - - resolve.exports@^1.1.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/resolve.exports/-/resolve.exports-1.1.1.tgz#05cfd5b3edf641571fd46fa608b610dda9ead999" - integrity sha512-/NtpHNDN7jWhAaQ9BvBUYZ6YTXsRBgfqWFWP7BZBaoMJO/I3G5OFzvTuWNlZC3aPjins1F+TNrLKsGbH4rfsRQ== - - resolve@^1.10.0, resolve@^1.14.2, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1, resolve@^1.22.4, resolve@^1.3.2, resolve@^1.9.0: - version "1.22.8" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" - integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - - resolve@^2.0.0-next.4: - version "2.0.0-next.5" - resolved "https://registry.yarnpkg.com/resolve/-/resolve-2.0.0-next.5.tgz#6b0ec3107e671e52b68cd068ef327173b90dc03c" - integrity sha512-U7WjGVG9sH8tvjW5SmGbQuui75FiyjAX72HX15DwBBwF9dNiQZRQAg9nnPhYy+TUnE0+VcrttuvNI8oSxZcocA== - dependencies: - is-core-module "^2.13.0" - path-parse "^1.0.7" - supports-preserve-symlinks-flag "^1.0.0" - - restore-cursor@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-3.1.0.tgz#39f67c54b3a7a58cea5236d95cf0034239631f7e" - integrity sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA== - dependencies: - onetime "^5.1.0" - signal-exit "^3.0.2" - - ret@~0.1.10: - version "0.1.15" - resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" - integrity sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg== - - retry@^0.12.0: - version "0.12.0" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" - integrity sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow== - - retry@^0.13.1: - version "0.13.1" - resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" - integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== - - reusify@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" - integrity sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw== - - rgb-hex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/rgb-hex/-/rgb-hex-3.0.0.tgz#eab0168cc1279563b18a14605315389142e2e487" - integrity sha512-8h7ZcwxCBDKvchSWbWngJuSCqJGQ6nDuLLg+QcRyQDbX9jMWt+PpPeXAhSla0GOooEomk3lCprUpGkMdsLjKyg== - - rimraf@^2.5.4, rimraf@^2.6.3: - version "2.7.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec" - integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w== - dependencies: - glob "^7.1.3" - - rimraf@^3.0.0, rimraf@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-3.0.2.tgz#f1a5402ba6220ad52cc1282bac1ae3aa49fd061a" - integrity sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA== - dependencies: - glob "^7.1.3" - - rimraf@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" - integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== - dependencies: - glob "^9.2.0" - - ripemd160@^2.0.0, ripemd160@^2.0.1, ripemd160@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" - integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== - dependencies: - hash-base "^3.0.0" - inherits "^2.0.1" - - rollup-plugin-dts@^5.0.0, rollup-plugin-dts@^5.2.0: - version "5.3.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-dts/-/rollup-plugin-dts-5.3.1.tgz#c2841269a3a5cb986b7791b0328e6a178eba108f" - integrity sha512-gusMi+Z4gY/JaEQeXnB0RUdU82h1kF0WYzCWgVmV4p3hWXqelaKuCvcJawfeg+EKn2T1Ie+YWF2OiN1/L8bTVg== - dependencies: - magic-string "^0.30.2" - optionalDependencies: - "@babel/code-frame" "^7.22.5" - - rollup-plugin-inject@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/rollup-plugin-inject/-/rollup-plugin-inject-3.0.2.tgz#e4233855bfba6c0c12a312fd6649dff9a13ee9f4" - integrity sha512-ptg9PQwzs3orn4jkgXJ74bfs5vYz1NCZlSQMBUA0wKcGp5i5pA1AO3fOUEte8enhGUC+iapTCzEWw2jEFFUO/w== - dependencies: - estree-walker "^0.6.1" - magic-string "^0.25.3" - rollup-pluginutils "^2.8.1" - - rollup-plugin-node-polyfills@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/rollup-plugin-node-polyfills/-/rollup-plugin-node-polyfills-0.2.1.tgz#53092a2744837164d5b8a28812ba5f3ff61109fd" - integrity sha512-4kCrKPTJ6sK4/gLL/U5QzVT8cxJcofO0OU74tnB19F40cmuAKSzH5/siithxlofFEjwvw1YAhPmbvGNA6jEroA== - dependencies: - rollup-plugin-inject "^3.0.0" - - rollup-pluginutils@^2.8.1: - version "2.8.2" - resolved "https://registry.yarnpkg.com/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz#72f2af0748b592364dbd3389e600e5a9444a351e" - integrity sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ== - dependencies: - estree-walker "^0.6.1" - - rollup@^3.17.2, rollup@^3.2.1: - version "3.29.4" - resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.29.4.tgz#4d70c0f9834146df8705bfb69a9a19c9e1109981" - integrity sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw== - optionalDependencies: - fsevents "~2.3.2" - - rsvp@^4.8.4: - version "4.8.5" - resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" - integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== - - run-async@^2.4.0: - version "2.4.1" - resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" - integrity sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ== - - run-parallel@^1.1.9: - version "1.2.0" - resolved "https://registry.yarnpkg.com/run-parallel/-/run-parallel-1.2.0.tgz#66d1368da7bdf921eb9d95bd1a9229e7f21a43ee" - integrity sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA== - dependencies: - queue-microtask "^1.2.2" - - run-queue@^1.0.0, run-queue@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" - integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== - dependencies: - aproba "^1.1.1" - - rxjs@^7.5.5: - version "7.8.1" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" - integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== - dependencies: - tslib "^2.1.0" - - sade@^1.7.3: - version "1.8.1" - resolved "https://registry.yarnpkg.com/sade/-/sade-1.8.1.tgz#0a78e81d658d394887be57d2a409bf703a3b2701" - integrity sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A== - dependencies: - mri "^1.1.0" - - safe-array-concat@^1.0.0, safe-array-concat@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.0.1.tgz#91686a63ce3adbea14d61b14c99572a8ff84754c" - integrity sha512-6XbUAseYE2KtOuGueyeobCySj9L4+66Tn6KQMOPQJrAJEowYKW/YR/MGJZl7FdydUdaFu4LYyDZjxf4/Nmo23Q== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - isarray "^2.0.5" - - safe-buffer@5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" - integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== - - safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - - safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@^5.2.1, safe-buffer@~5.2.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - - safe-regex-test@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" - integrity sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.1.3" - is-regex "^1.1.4" - - safe-regex@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== - dependencies: - ret "~0.1.10" - - safe-stable-stringify@^2.1.0: - version "2.4.3" - resolved "https://registry.yarnpkg.com/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz#138c84b6f6edb3db5f8ef3ef7115b8f55ccbf886" - integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== - - "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@^2.1.0: - version "2.1.2" - resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" - integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== - - sane@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" - integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== - dependencies: - "@cnakazawa/watch" "^1.0.3" - anymatch "^2.0.0" - capture-exit "^2.0.0" - exec-sh "^0.3.2" - execa "^1.0.0" - fb-watchman "^2.0.0" - micromatch "^3.1.4" - minimist "^1.1.1" - walker "~1.0.5" - - sax@>=0.6.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.3.0.tgz#a5dbe77db3be05c9d1ee7785dbd3ea9de51593d0" - integrity sha512-0s+oAmw9zLl1V1cS9BtZN7JAd0cW5e0QH4W3LWEK6a4LaLEA2OTpGYWDY+6XasBLtz6wkm3u1xRw95mRuJ59WA== - - saxes@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/saxes/-/saxes-5.0.1.tgz#eebab953fa3b7608dbe94e5dadb15c888fa6696d" - integrity sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw== - dependencies: - xmlchars "^2.2.0" - - scheduler@^0.23.0: - version "0.23.0" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe" - integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw== - dependencies: - loose-envify "^1.1.0" - - schema-utils@2.7.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" - integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== - dependencies: - "@types/json-schema" "^7.0.4" - ajv "^6.12.2" - ajv-keywords "^3.4.1" - - schema-utils@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" - integrity sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g== - dependencies: - ajv "^6.1.0" - ajv-errors "^1.0.0" - ajv-keywords "^3.1.0" - - schema-utils@^2.6.5, schema-utils@^2.7.0: - version "2.7.1" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.1.tgz#1ca4f32d1b24c590c203b8e7a50bf0ea4cd394d7" - integrity sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg== - dependencies: - "@types/json-schema" "^7.0.5" - ajv "^6.12.4" - ajv-keywords "^3.5.2" - - schema-utils@^3.0.0, schema-utils@^3.1.1, schema-utils@^3.2.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.3.0.tgz#f50a88877c3c01652a15b622ae9e9795df7a60fe" - integrity sha512-pN/yOAvcC+5rQ5nERGuwrjLlYvLTbCibnZ1I7B1LaiAz9BRBlE9GMgE/eqV30P7aJQUf7Ddimy/RsbYO/GrVGg== - dependencies: - "@types/json-schema" "^7.0.8" - ajv "^6.12.5" - ajv-keywords "^3.5.2" - - schema-utils@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.2.0.tgz#70d7c93e153a273a805801882ebd3bff20d89c8b" - integrity sha512-L0jRsrPpjdckP3oPug3/VxNKt2trR8TcabrM6FOAAlvC/9Phcmm+cuAgTlxBqdBR1WJx7Naj9WHw+aOmheSVbw== - dependencies: - "@types/json-schema" "^7.0.9" - ajv "^8.9.0" - ajv-formats "^2.1.1" - ajv-keywords "^5.1.0" - - select-hose@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" - integrity sha512-mEugaLK+YfkijB4fx0e6kImuJdCIt2LxCRcbEYPqRGCs4F2ogyfZU5IAZRdjCP8JPq2AtdNoC/Dux63d9Kiryg== - - selfsigned@^2.1.1: - version "2.4.1" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.4.1.tgz#560d90565442a3ed35b674034cec4e95dceb4ae0" - integrity sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q== - dependencies: - "@types/node-forge" "^1.3.0" - node-forge "^1" - - "semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0, semver@^5.7.1: - version "5.7.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.2.tgz#48d55db737c3287cd4835e17fa13feace1c41ef8" - integrity sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g== - - semver@7.5.3: - version "7.5.3" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.3.tgz#161ce8c2c6b4b3bdca6caadc9fa3317a4c4fe88e" - integrity sha512-QBlUtyVk/5EeHbi7X0fw6liDZc7BBmEaSYn01fMU1OUYbf6GPsbTtd8WmnqbI20SeycoHSeiybkE/q1Q+qlThQ== - dependencies: - lru-cache "^6.0.0" - - semver@7.x, semver@^7.0.0, semver@^7.1.1, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.0, semver@^7.5.3, semver@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.5.4.tgz#483986ec4ed38e1c6c48c34894a9182dbff68a6e" - integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== - dependencies: - lru-cache "^6.0.0" - - semver@^6.0.0, semver@^6.1.2, semver@^6.3.0, semver@^6.3.1: - version "6.3.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" - integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== - - semver@~7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" - integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== - - send@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" - integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== - dependencies: - debug "2.6.9" - depd "2.0.0" - destroy "1.2.0" - encodeurl "~1.0.2" - escape-html "~1.0.3" - etag "~1.8.1" - fresh "0.5.2" - http-errors "2.0.0" - mime "1.6.0" - ms "2.1.3" - on-finished "2.4.1" - range-parser "~1.2.1" - statuses "2.0.1" - - serialize-javascript@6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.0.tgz#efae5d88f45d7924141da8b5c3a7a7e663fefeb8" - integrity sha512-Qr3TosvguFt8ePWqsvRfrKyQXIiW+nGbYpy8XK24NQHE83caxWt+mIymTT19DGFbNWNLfEwsrkSmN64lVWB9ag== - dependencies: - randombytes "^2.1.0" - - serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - - serialize-javascript@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" - integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== - dependencies: - randombytes "^2.1.0" - - serialize-javascript@^6.0.0, serialize-javascript@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== - dependencies: - randombytes "^2.1.0" - - serve-favicon@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" - integrity sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA== - dependencies: - etag "~1.8.1" - fresh "0.5.2" - ms "2.1.1" - parseurl "~1.3.2" - safe-buffer "5.1.1" - - serve-index@^1.9.1: - version "1.9.1" - resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" - integrity sha512-pXHfKNP4qujrtteMrSBb0rc8HJ9Ms/GrXwcUtUtD5s4ewDJI8bT3Cz2zTVRMKtri49pLx2e0Ya8ziP5Ya2pZZw== - dependencies: - accepts "~1.3.4" - batch "0.6.1" - debug "2.6.9" - escape-html "~1.0.3" - http-errors "~1.6.2" - mime-types "~2.1.17" - parseurl "~1.3.2" - - serve-static@1.15.0: - version "1.15.0" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" - integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== - dependencies: - encodeurl "~1.0.2" - escape-html "~1.0.3" - parseurl "~1.3.3" - send "0.18.0" - - set-blocking@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" - integrity sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw== - - set-function-length@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/set-function-length/-/set-function-length-1.1.1.tgz#4bc39fafb0307224a33e106a7d35ca1218d659ed" - integrity sha512-VoaqjbBJKiWtg4yRcKBQ7g7wnGnLV3M8oLvVWwOk2PdYY6PEFegR1vezXR0tw6fZGF9csVakIRjrJiy2veSBFQ== - dependencies: - define-data-property "^1.1.1" - get-intrinsic "^1.2.1" - gopd "^1.0.1" - has-property-descriptors "^1.0.0" - - set-function-name@^2.0.0, set-function-name@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-function-name/-/set-function-name-2.0.1.tgz#12ce38b7954310b9f61faa12701620a0c882793a" - integrity sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA== - dependencies: - define-data-property "^1.0.1" - functions-have-names "^1.2.3" - has-property-descriptors "^1.0.0" - - set-value@^2.0.0, set-value@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b" - integrity sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw== - dependencies: - extend-shallow "^2.0.1" - is-extendable "^0.1.1" - is-plain-object "^2.0.3" - split-string "^3.0.1" - - setimmediate@^1.0.4: - version "1.0.5" - resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" - integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== - - setprototypeof@1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" - integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== - - setprototypeof@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" - integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== - - sha.js@^2.4.0, sha.js@^2.4.11, sha.js@^2.4.8: - version "2.4.11" - resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" - integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== - dependencies: - inherits "^2.0.1" - safe-buffer "^5.0.1" - - shallow-clone@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shallow-clone/-/shallow-clone-3.0.1.tgz#8f2981ad92531f55035b01fb230769a40e02efa3" - integrity sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA== - dependencies: - kind-of "^6.0.2" - - sharp@^0.29.1: - version "0.29.3" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.29.3.tgz#0da183d626094c974516a48fab9b3e4ba92eb5c2" - integrity sha512-fKWUuOw77E4nhpyzCCJR1ayrttHoFHBT2U/kR/qEMRhvPEcluG4BKj324+SCO1e84+knXHwhJ1HHJGnUt4ElGA== - dependencies: - color "^4.0.1" - detect-libc "^1.0.3" - node-addon-api "^4.2.0" - prebuild-install "^7.0.0" - semver "^7.3.5" - simple-get "^4.0.0" - tar-fs "^2.1.1" - tunnel-agent "^0.6.0" - - sharp@^0.32.4: - version "0.32.6" - resolved "https://registry.yarnpkg.com/sharp/-/sharp-0.32.6.tgz#6ad30c0b7cd910df65d5f355f774aa4fce45732a" - integrity sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w== - dependencies: - color "^4.2.3" - detect-libc "^2.0.2" - node-addon-api "^6.1.0" - prebuild-install "^7.1.1" - semver "^7.5.4" - simple-get "^4.0.1" - tar-fs "^3.0.4" - tunnel-agent "^0.6.0" - - shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - - shebang-command@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" - integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== - dependencies: - shebang-regex "^3.0.0" - - shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - - shebang-regex@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" - integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== - - shell-quote@^1.6.1, shell-quote@^1.8.1: - version "1.8.1" - resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.8.1.tgz#6dbf4db75515ad5bac63b4f1894c3a154c766680" - integrity sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA== - - shiki@^0.10.1: - version "0.10.1" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14" - integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng== - dependencies: - jsonc-parser "^3.0.0" - vscode-oniguruma "^1.6.1" - vscode-textmate "5.2.0" - - side-channel@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" - integrity sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw== - dependencies: - call-bind "^1.0.0" - get-intrinsic "^1.0.2" - object-inspect "^1.9.0" - - signal-exit@3.0.7, signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: - version "3.0.7" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" - integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== - - signal-exit@^4.0.1: - version "4.1.0" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-4.1.0.tgz#952188c1cbd546070e2dd20d0f41c0ae0530cb04" - integrity sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw== - - sigstore@^1.3.0, sigstore@^1.4.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/sigstore/-/sigstore-1.9.0.tgz#1e7ad8933aa99b75c6898ddd0eeebc3eb0d59875" - integrity sha512-0Zjz0oe37d08VeOtBIuB6cRriqXse2e8w+7yIy2XSXjshRKxbc2KkhXjL229jXSxEm7UbcjS76wcJDGQddVI9A== - dependencies: - "@sigstore/bundle" "^1.1.0" - "@sigstore/protobuf-specs" "^0.2.0" - "@sigstore/sign" "^1.0.0" - "@sigstore/tuf" "^1.0.3" - make-fetch-happen "^11.0.1" - - simple-concat@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/simple-concat/-/simple-concat-1.0.1.tgz#f46976082ba35c2263f1c8ab5edfe26c41c9552f" - integrity sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q== - - simple-get@^4.0.0, simple-get@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/simple-get/-/simple-get-4.0.1.tgz#4a39db549287c979d352112fa03fd99fd6bc3543" - integrity sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA== - dependencies: - decompress-response "^6.0.0" - once "^1.3.1" - simple-concat "^1.0.0" - - simple-swizzle@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/simple-swizzle/-/simple-swizzle-0.2.2.tgz#a4da6b635ffcccca33f70d17cb92592de95e557a" - integrity sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg== - dependencies: - is-arrayish "^0.3.1" - - simple-update-notifier@^1.0.7: - version "1.1.0" - resolved "https://registry.yarnpkg.com/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz#67694c121de354af592b347cdba798463ed49c82" - integrity sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg== - dependencies: - semver "~7.0.0" - - sisteransi@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" - integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== - - slash@3.0.0, slash@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" - integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== - - slash@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" - integrity sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg== - - slash@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" - integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== - - slice-ansi@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-4.0.0.tgz#500e8dd0fd55b05815086255b3195adf2a45fe6b" - integrity sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ== - dependencies: - ansi-styles "^4.0.0" - astral-regex "^2.0.0" - is-fullwidth-code-point "^3.0.0" - - smart-buffer@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" - integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== - - snapdragon-node@^2.0.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" - integrity sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw== - dependencies: - define-property "^1.0.0" - isobject "^3.0.0" - snapdragon-util "^3.0.1" - - snapdragon-util@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" - integrity sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ== - dependencies: - kind-of "^3.2.0" - - snapdragon@^0.8.1: - version "0.8.2" - resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" - integrity sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg== - dependencies: - base "^0.11.1" - debug "^2.2.0" - define-property "^0.2.5" - extend-shallow "^2.0.1" - map-cache "^0.2.2" - source-map "^0.5.6" - source-map-resolve "^0.5.0" - use "^3.1.0" - - sockjs@^0.3.24: - version "0.3.24" - resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.24.tgz#c9bc8995f33a111bea0395ec30aa3206bdb5ccce" - integrity sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ== - dependencies: - faye-websocket "^0.11.3" - uuid "^8.3.2" - websocket-driver "^0.7.4" - - socks-proxy-agent@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" - integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== - dependencies: - agent-base "^6.0.2" - debug "^4.3.3" - socks "^2.6.2" - - socks@^2.6.2: - version "2.7.1" - resolved "https://registry.yarnpkg.com/socks/-/socks-2.7.1.tgz#d8e651247178fde79c0663043e07240196857d55" - integrity sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ== - dependencies: - ip "^2.0.0" - smart-buffer "^4.2.0" - - sonic-boom@^2.2.1: - version "2.8.0" - resolved "https://registry.yarnpkg.com/sonic-boom/-/sonic-boom-2.8.0.tgz#c1def62a77425090e6ad7516aad8eb402e047611" - integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== - dependencies: - atomic-sleep "^1.0.0" - - sort-keys@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" - integrity sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg== - dependencies: - is-plain-obj "^1.0.0" - - source-list-map@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" - integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== - - source-map-js@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" - integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== - - source-map-resolve@^0.5.0: - version "0.5.3" - resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" - integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== - dependencies: - atob "^2.1.2" - decode-uri-component "^0.2.0" - resolve-url "^0.2.1" - source-map-url "^0.4.0" - urix "^0.1.0" - - source-map-support@^0.5.16, source-map-support@^0.5.6, source-map-support@~0.5.12, source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - - source-map-url@^0.4.0: - version "0.4.1" - resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56" - integrity sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw== - - source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: - version "0.5.7" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" - integrity sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ== - - source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0, source-map@~0.6.1: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - - source-map@^0.7.0, source-map@^0.7.3, source-map@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" - integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== - - sourcemap-codec@^1.4.8: - version "1.4.8" - resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" - integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== - - space-separated-tokens@^1.0.0: - version "1.1.5" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" - integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== - - space-separated-tokens@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz#1ecd9d2350a3844572c3f4a312bceb018348859f" - integrity sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q== - - spdx-correct@^3.0.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.2.0.tgz#4f5ab0668f0059e34f9c00dce331784a12de4e9c" - integrity sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA== - dependencies: - spdx-expression-parse "^3.0.0" - spdx-license-ids "^3.0.0" - - spdx-exceptions@^2.1.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" - integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== - - spdx-expression-parse@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" - integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== - dependencies: - spdx-exceptions "^2.1.0" - spdx-license-ids "^3.0.0" - - spdx-license-ids@^3.0.0: - version "3.0.16" - resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.16.tgz#a14f64e0954f6e25cc6587bd4f392522db0d998f" - integrity sha512-eWN+LnM3GR6gPu35WxNgbGl8rmY1AEmoMDvL/QD6zYmPWgywxWqJWNdLGT+ke8dKNWrcYgYjPpG5gbTfghP8rw== - - spdy-transport@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" - integrity sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw== - dependencies: - debug "^4.1.0" - detect-node "^2.0.4" - hpack.js "^2.1.6" - obuf "^1.1.2" - readable-stream "^3.0.6" - wbuf "^1.7.3" - - spdy@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/spdy/-/spdy-4.0.2.tgz#b74f466203a3eda452c02492b91fb9e84a27677b" - integrity sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA== - dependencies: - debug "^4.1.0" - handle-thing "^2.0.0" - http-deceiver "^1.2.7" - select-hose "^2.0.0" - spdy-transport "^3.0.0" - - split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - - split-string@^3.0.1, split-string@^3.0.2: - version "3.1.0" - resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" - integrity sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw== - dependencies: - extend-shallow "^3.0.0" - - split2@^3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/split2/-/split2-3.2.2.tgz#bf2cf2a37d838312c249c89206fd7a17dd12365f" - integrity sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg== - dependencies: - readable-stream "^3.0.0" - - split2@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" - integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== - - split@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" - integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== - dependencies: - through "2" - - sprintf-js@~1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" - integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== - - ssri@^10.0.0, ssri@^10.0.1: - version "10.0.5" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-10.0.5.tgz#e49efcd6e36385196cb515d3a2ad6c3f0265ef8c" - integrity sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A== - dependencies: - minipass "^7.0.3" - - ssri@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" - integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== - dependencies: - figgy-pudding "^3.5.1" - - ssri@^8.0.1: - version "8.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" - integrity sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ== - dependencies: - minipass "^3.1.1" - - ssri@^9.0.0, ssri@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" - integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== - dependencies: - minipass "^3.1.1" - - stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - - stack-utils@^2.0.3: - version "2.0.6" - resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.6.tgz#aaf0748169c02fc33c8232abccf933f54a1cc34f" - integrity sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ== - dependencies: - escape-string-regexp "^2.0.0" - - stackframe@^1.3.4: - version "1.3.4" - resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.3.4.tgz#b881a004c8c149a5e8efef37d51b16e412943310" - integrity sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw== - - standard-as-callback@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/standard-as-callback/-/standard-as-callback-2.1.0.tgz#8953fc05359868a77b5b9739a665c5977bb7df45" - integrity sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A== - - state-toggle@^1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" - integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== - - static-extend@^0.1.1: - version "0.1.2" - resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== - dependencies: - define-property "^0.2.5" - object-copy "^0.1.0" - - statuses@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" - integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== - - "statuses@>= 1.4.0 < 2": - version "1.5.0" - resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" - integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA== - - std-env@^3.4.3: - version "3.5.0" - resolved "https://registry.yarnpkg.com/std-env/-/std-env-3.5.0.tgz#83010c9e29bd99bf6f605df87c19012d82d63b97" - integrity sha512-JGUEaALvL0Mf6JCfYnJOTcobY+Nc7sG/TemDRBqCA0wEr4DER7zDchaaixTlmOxAjG1uRJmX82EQcxwTQTkqVA== - - stop-iteration-iterator@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz#6a60be0b4ee757d1ed5254858ec66b10c49285e4" - integrity sha512-iCGQj+0l0HOdZ2AEeBADlsRC+vsnDsZsbdSiH1yNSjcfKM7fdpCMfqAL/dwF5BLiw/XhRft/Wax6zQbhq2BcjQ== - dependencies: - internal-slot "^1.0.4" - - store2@^2.12.0: - version "2.14.2" - resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" - integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== - - stream-browserify@^2.0.1: - version "2.0.2" - resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" - integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== - dependencies: - inherits "~2.0.1" - readable-stream "^2.0.2" - - stream-each@^1.1.0: - version "1.2.3" - resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" - integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== - dependencies: - end-of-stream "^1.1.0" - stream-shift "^1.0.0" - - stream-http@^2.7.2: - version "2.8.3" - resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" - integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== - dependencies: - builtin-status-codes "^3.0.0" - inherits "^2.0.1" - readable-stream "^2.3.6" - to-arraybuffer "^1.0.0" - xtend "^4.0.0" - - stream-shift@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" - integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== - - streamx@^2.15.0: - version "2.15.5" - resolved "https://registry.yarnpkg.com/streamx/-/streamx-2.15.5.tgz#87bcef4dc7f0b883f9359671203344a4e004c7f1" - integrity sha512-9thPGMkKC2GctCzyCUjME3yR03x2xNo0GPKGkRw2UMYN+gqWa9uqpyNWhmsNCutU5zHmkUum0LsCRQTXUgUCAg== - dependencies: - fast-fifo "^1.1.0" - queue-tick "^1.0.1" - - strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== - - string-length@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" - integrity sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ== - dependencies: - char-regex "^1.0.2" - strip-ansi "^6.0.0" - - string-to-color@^2.2.2: - version "2.2.2" - resolved "https://registry.yarnpkg.com/string-to-color/-/string-to-color-2.2.2.tgz#46210bf7777dc9198dcdf997bd18ae6749cc9a73" - integrity sha512-XeA2goP7PNsSlz8RRn6KhYswnMf5Tl+38ajfy8n4oZJyMGC4qqKgHNHsZ/3qwvr42NRIjf9eSr721SyetDeMkA== - dependencies: - colornames "^1.1.1" - hex-rgb "^4.1.0" - lodash.padend "^4.6.1" - lodash.trimstart "^4.5.1" - lodash.words "^4.2.0" - rgb-hex "^3.0.0" - - "string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" - 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" - - string-width@^5.0.1, string-width@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" - integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== - dependencies: - eastasianwidth "^0.2.0" - emoji-regex "^9.2.2" - strip-ansi "^7.0.1" - - "string.prototype.matchall@^4.0.0 || ^3.0.1", string.prototype.matchall@^4.0.8: - version "4.0.10" - resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.10.tgz#a1553eb532221d4180c51581d6072cd65d1ee100" - integrity sha512-rGXbGmOEosIQi6Qva94HUjgPs9vKW+dkG7Y8Q5O2OYkWL6wFaTRZO8zM4mhP94uX55wgyrXzfS2aGtGzUL7EJQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - get-intrinsic "^1.2.1" - has-symbols "^1.0.3" - internal-slot "^1.0.5" - regexp.prototype.flags "^1.5.0" - set-function-name "^2.0.0" - side-channel "^1.0.4" - - string.prototype.padend@^3.0.0: - version "3.1.5" - resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.5.tgz#311ef3a4e3c557dd999cdf88fbdde223f2ac0f95" - integrity sha512-DOB27b/2UTTD+4myKUFh+/fXWcu/UDyASIXfg+7VzoCNNGOfWvoyU/x5pvVHr++ztyt/oSYI1BcWBBG/hmlNjA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - string.prototype.padstart@^3.0.0: - version "3.1.5" - resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.5.tgz#ce435e145e4d68b701d1db51cb546ba100177d98" - integrity sha512-R57IsE3JIfModQWrVXYZ8ZHWMBNDpIoniDwhYCR1nx+iHwDkjjk26a8xM9BYgf7SAXJO7sdNPng5J+0ccr5LFQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - string.prototype.trim@^1.2.8: - version "1.2.8" - resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz#f9ac6f8af4bd55ddfa8895e6aea92a96395393bd" - integrity sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - string.prototype.trimend@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz#1bb3afc5008661d73e2dc015cd4853732d6c471e" - integrity sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - string.prototype.trimstart@^1.0.7: - version "1.0.7" - resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz#d4cdb44b83a4737ffbac2d406e405d43d0184298" - integrity sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - - string_decoder@^1.0.0, string_decoder@^1.1.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" - integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== - dependencies: - safe-buffer "~5.2.0" - - string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - - stringify-entities@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/stringify-entities/-/stringify-entities-4.0.3.tgz#cfabd7039d22ad30f3cc435b0ca2c1574fc88ef8" - integrity sha512-BP9nNHMhhfcMbiuQKCqMjhDP5yBCAxsPu4pHFFzJ6Alo9dZgY4VLDPutXqIjpRiMoKdp7Av85Gr73Q5uH9k7+g== - dependencies: - character-entities-html4 "^2.0.0" - character-entities-legacy "^3.0.0" - - "strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: - version "6.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" - integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== - dependencies: - ansi-regex "^5.0.1" - - strip-ansi@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - - strip-ansi@^7.0.1: - version "7.1.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" - integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== - dependencies: - ansi-regex "^6.0.1" - - strip-bom@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" - integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== - dependencies: - is-utf8 "^0.2.0" - - strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== - - strip-bom@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" - integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== - - strip-eof@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" - integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== - - strip-final-newline@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" - integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== - - strip-indent@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" - integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== - dependencies: - get-stdin "^4.0.1" - - strip-indent@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" - integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== - dependencies: - min-indent "^1.0.0" - - strip-json-comments@3.1.1, strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006" - integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== - - strip-json-comments@~2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" - integrity sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ== - - strong-log-transformer@2.1.0, strong-log-transformer@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" - integrity sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA== - dependencies: - duplexer "^0.1.1" - minimist "^1.2.0" - through "^2.3.4" - - style-loader@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" - integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== - dependencies: - loader-utils "^2.0.0" - schema-utils "^2.7.0" - - style-loader@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" - integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== - dependencies: - loader-utils "^2.0.0" - schema-utils "^3.0.0" - - style-loader@^3.3.1: - version "3.3.3" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.3.3.tgz#bba8daac19930169c0c9c96706749a597ae3acff" - integrity sha512-53BiGLXAcll9maCYtZi2RCQZKa8NQQai5C4horqKyRmHj9H7QmcUyucrH+4KW/gBQbXM2AsB0axoEcFZPlfPcw== - - style-to-object@0.3.0, style-to-object@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" - integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== - dependencies: - inline-style-parser "0.1.1" - - style-to-object@^0.4.0, style-to-object@^0.4.1: - version "0.4.4" - resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.4.4.tgz#266e3dfd56391a7eefb7770423612d043c3f33ec" - integrity sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg== - dependencies: - inline-style-parser "0.1.1" - - stylehacks@^5.1.1: - version "5.1.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.1.1.tgz#7934a34eb59d7152149fa69d6e9e56f2fc34bcc9" - integrity sha512-sBpcd5Hx7G6seo7b1LkpttvTz7ikD0LlH5RmdcBNb6fFR0Fl7LQwHDFr300q4cwUqi+IYrFGmsIHieMBfnN/Bw== - dependencies: - browserslist "^4.21.4" - postcss-selector-parser "^6.0.4" - - stylis@4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.2.0.tgz#79daee0208964c8fe695a42fcffcac633a211a51" - integrity sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw== - - supports-color@8.1.1, supports-color@^8.0.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-8.1.1.tgz#cd6fc17e28500cff56c1b86c0a7fd4a54a73005c" - integrity sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q== - dependencies: - has-flag "^4.0.0" - - supports-color@^5.3.0, supports-color@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" - integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow== - dependencies: - has-flag "^3.0.0" - - supports-color@^7.0.0, supports-color@^7.1.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" - integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== - dependencies: - has-flag "^4.0.0" - - supports-hyperlinks@^2.0.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz#3943544347c1ff90b15effb03fc14ae45ec10624" - integrity sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA== - dependencies: - has-flag "^4.0.0" - supports-color "^7.0.0" - - supports-preserve-symlinks-flag@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" - integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== - - svg-parser@^2.0.4: - version "2.0.4" - resolved "https://registry.yarnpkg.com/svg-parser/-/svg-parser-2.0.4.tgz#fdc2e29e13951736140b76cb122c8ee6630eb6b5" - integrity sha512-e4hG1hRwoOdRb37cIMSgzNsxyzKfayW6VOflrwvR+/bzrkyxY/31WkbgnQpgtrNp1SdpJvpUAGTa/ZoiPNDuRQ== - - svgo@^2.7.0, svgo@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - 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" - - symbol-observable@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a" - integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA== - - symbol-tree@^3.2.4: - version "3.2.4" - resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" - integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== - - symbol.prototype.description@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz#d30e01263b6020fbbd2d2884a6276ce4d49ab568" - integrity sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ== - dependencies: - call-bind "^1.0.2" - get-symbol-description "^1.0.0" - has-symbols "^1.0.2" - object.getownpropertydescriptors "^2.1.2" - - synchronous-promise@^2.0.15: - version "2.0.17" - resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.17.tgz#38901319632f946c982152586f2caf8ddc25c032" - integrity sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g== - - tabbable@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-6.2.0.tgz#732fb62bc0175cfcec257330be187dcfba1f3b97" - integrity sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew== - - table@^6.0.9: - version "6.8.1" - resolved "https://registry.yarnpkg.com/table/-/table-6.8.1.tgz#ea2b71359fe03b017a5fbc296204471158080bdf" - integrity sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA== - dependencies: - ajv "^8.0.1" - lodash.truncate "^4.4.2" - slice-ansi "^4.0.0" - string-width "^4.2.3" - strip-ansi "^6.0.1" - - tapable@^1.0.0, tapable@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" - integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== - - tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0, tapable@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" - integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== - - tar-fs@^2.0.0, tar-fs@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-2.1.1.tgz#489a15ab85f1f0befabb370b7de4f9eb5cbe8784" - 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" - - tar-fs@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/tar-fs/-/tar-fs-3.0.4.tgz#a21dc60a2d5d9f55e0089ccd78124f1d3771dbbf" - integrity sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w== - dependencies: - mkdirp-classic "^0.5.2" - pump "^3.0.0" - tar-stream "^3.1.5" - - tar-stream@^2.1.4, tar-stream@~2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.2.0.tgz#acad84c284136b060dc3faa64474aa9aebd77287" - 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" - - tar-stream@^3.1.5: - version "3.1.6" - resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-3.1.6.tgz#6520607b55a06f4a2e2e04db360ba7d338cc5bab" - integrity sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg== - dependencies: - b4a "^1.6.4" - fast-fifo "^1.2.0" - streamx "^2.15.0" - - tar@6.1.11: - version "6.1.11" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" - integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^3.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - - tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.2.0" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.0.tgz#b14ce49a79cb1cd23bc9b016302dea5474493f73" - integrity sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ== - dependencies: - chownr "^2.0.0" - fs-minipass "^2.0.0" - minipass "^5.0.0" - minizlib "^2.1.1" - mkdirp "^1.0.3" - yallist "^4.0.0" - - telejson@^6.0.8: - version "6.0.8" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" - integrity sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg== - dependencies: - "@types/is-function" "^1.0.0" - global "^4.4.0" - is-function "^1.0.2" - is-regex "^1.1.2" - is-symbol "^1.0.3" - isobject "^4.0.0" - lodash "^4.17.21" - memoizerific "^1.11.3" - - telejson@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-7.2.0.tgz#3994f6c9a8f8d7f2dba9be2c7c5bbb447e876f32" - integrity sha512-1QTEcJkJEhc8OnStBx/ILRu5J2p0GjvWsBx56bmZRqnrkdBMUe+nX92jxV+p3dB4CP6PZCdJMQJwCggkNBMzkQ== - dependencies: - memoizerific "^1.11.3" - - temp-dir@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" - integrity sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ== - - terminal-link@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/terminal-link/-/terminal-link-2.1.1.tgz#14a64a27ab3c0df933ea546fba55f2d078edc994" - integrity sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ== - dependencies: - ansi-escapes "^4.2.1" - supports-hyperlinks "^2.0.0" - - terser-webpack-plugin@^1.4.3: - version "1.4.5" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" - integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== - dependencies: - cacache "^12.0.2" - find-cache-dir "^2.1.0" - is-wsl "^1.1.0" - schema-utils "^1.0.0" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.1.2" - webpack-sources "^1.4.0" - worker-farm "^1.7.0" - - terser-webpack-plugin@^4.2.3: - version "4.2.3" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" - integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== - dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - jest-worker "^26.5.0" - p-limit "^3.0.2" - schema-utils "^3.0.0" - serialize-javascript "^5.0.1" - source-map "^0.6.1" - terser "^5.3.4" - webpack-sources "^1.4.3" - - terser-webpack-plugin@^5.0.3, terser-webpack-plugin@^5.3.7: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.8" - - terser@^4.1.2, terser@^4.6.3: - version "4.8.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" - integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== - dependencies: - commander "^2.20.0" - source-map "~0.6.1" - source-map-support "~0.5.12" - - terser@^5.10.0, terser@^5.16.8, terser@^5.3.4: - version "5.24.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.24.0.tgz#4ae50302977bca4831ccc7b4fef63a3c04228364" - integrity sha512-ZpGR4Hy3+wBEzVEnHvstMvqpD/nABNelQn/z2r0fjVWGQsN3bpOLzQlqDxmb4CDZnXq5lpjnQ+mHQLAOpfM5iw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - - test-exclude@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" - integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== - dependencies: - "@istanbuljs/schema" "^0.1.2" - glob "^7.1.4" - minimatch "^3.0.4" - - text-extensions@^1.0.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/text-extensions/-/text-extensions-1.9.0.tgz#1853e45fee39c945ce6f6c36b2d659b5aabc2a26" - integrity sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ== - - text-table@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" - integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== - - thread-loader@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/thread-loader/-/thread-loader-3.0.4.tgz#c392e4c0241fbc80430eb680e4886819b504a31b" - integrity sha512-ByaL2TPb+m6yArpqQUZvP+5S1mZtXsEP7nWKKlAUTm7fCml8kB5s1uI3+eHRP2bk5mVYfRSBI7FFf+tWEyLZwA== - dependencies: - json-parse-better-errors "^1.0.2" - loader-runner "^4.1.0" - loader-utils "^2.0.0" - neo-async "^2.6.2" - schema-utils "^3.0.0" - - thread-stream@^0.15.1: - version "0.15.2" - resolved "https://registry.yarnpkg.com/thread-stream/-/thread-stream-0.15.2.tgz#fb95ad87d2f1e28f07116eb23d85aba3bc0425f4" - integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== - dependencies: - real-require "^0.1.0" - - throat@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/throat/-/throat-6.0.2.tgz#51a3fbb5e11ae72e2cf74861ed5c8020f89f29fe" - integrity sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ== - - through2@^2.0.0: - version "2.0.5" - resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" - integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== - dependencies: - readable-stream "~2.3.6" - xtend "~4.0.1" - - through2@^4.0.2: - version "4.0.2" - resolved "https://registry.yarnpkg.com/through2/-/through2-4.0.2.tgz#a7ce3ac2a7a8b0b966c80e7c49f0484c3b239764" - integrity sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw== - dependencies: - readable-stream "3" - - through@2, "through@>=2.2.7 <3", through@^2.3.4, through@^2.3.6: - version "2.3.8" - resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" - integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== - - thunky@^1.0.2: - version "1.1.0" - resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" - integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== - - timers-browserify@^2.0.4: - version "2.0.12" - resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" - integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== - dependencies: - setimmediate "^1.0.4" - - tiny-case@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-case/-/tiny-case-1.0.3.tgz#d980d66bc72b5d5a9ca86fb7c9ffdb9c898ddd03" - integrity sha512-Eet/eeMhkO6TX8mnUteS9zgPbUMQa4I6Kkp5ORiBD5476/m+PIRiumP5tmh5ioJpH7k51Kehawy2UDfsnxxY8Q== - - tiny-invariant@^1.3.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.1.tgz#8560808c916ef02ecfd55e66090df23a4b7aa642" - integrity sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw== - - tiny-secp256k1@^1.1.3: - version "1.1.6" - resolved "https://registry.yarnpkg.com/tiny-secp256k1/-/tiny-secp256k1-1.1.6.tgz#7e224d2bee8ab8283f284e40e6b4acb74ffe047c" - integrity sha512-FmqJZGduTyvsr2cF3375fqGHUovSwDi/QytexX1Se4BPuPZpTE5Ftp5fg+EFSuEf3lhZqgCRjEG3ydUQ/aNiwA== - dependencies: - bindings "^1.3.0" - bn.js "^4.11.8" - create-hmac "^1.1.7" - elliptic "^6.4.0" - nan "^2.13.2" - - tiny-warning@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" - integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== - - tmp@^0.0.33: - version "0.0.33" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" - integrity sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw== - dependencies: - os-tmpdir "~1.0.2" - - tmp@~0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.2.1.tgz#8457fc3037dcf4719c251367a1af6500ee1ccf14" - integrity sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ== - dependencies: - rimraf "^3.0.0" - - tmpl@1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" - integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== - - to-arraybuffer@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" - integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== - - to-fast-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" - integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog== - - to-object-path@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== - dependencies: - kind-of "^3.0.2" - - to-regex-range@^2.1.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== - dependencies: - is-number "^3.0.0" - repeat-string "^1.6.1" - - to-regex-range@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" - integrity sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ== - dependencies: - is-number "^7.0.0" - - to-regex@^3.0.1, to-regex@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" - integrity sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw== - dependencies: - define-property "^2.0.2" - extend-shallow "^3.0.2" - regex-not "^1.0.2" - safe-regex "^1.1.0" - - toggle-selection@^1.0.6: - version "1.0.6" - resolved "https://registry.yarnpkg.com/toggle-selection/-/toggle-selection-1.0.6.tgz#6e45b1263f2017fa0acc7d89d78b15b8bf77da32" - integrity sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ== - - toidentifier@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" - integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== - - topojson-client@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/topojson-client/-/topojson-client-3.1.0.tgz#22e8b1ed08a2b922feeb4af6f53b6ef09a467b99" - integrity sha512-605uxS6bcYxGXw9qi62XyrV6Q3xwbndjachmNxu8HWTtVPxZfEJN9fd/SZS1Q54Sn2y0TMyMxFj/cJINqGHrKw== - dependencies: - commander "2" - - toposort@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/toposort/-/toposort-2.0.2.tgz#ae21768175d1559d48bef35420b2f4962f09c330" - integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== - - touch@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/touch/-/touch-3.1.0.tgz#fe365f5f75ec9ed4e56825e0bb76d24ab74af83b" - integrity sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA== - dependencies: - nopt "~1.0.10" - - tough-cookie@^4.0.0: - version "4.1.3" - resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.1.3.tgz#97b9adb0728b42280aa3d814b6b999b2ff0318bf" - integrity sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw== - dependencies: - psl "^1.1.33" - punycode "^2.1.1" - universalify "^0.2.0" - url-parse "^1.5.3" - - tr46@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-2.1.0.tgz#fa87aa81ca5d5941da8cbf1f9b749dc969a4e240" - integrity sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw== - dependencies: - punycode "^2.1.1" - - tr46@~0.0.3: - version "0.0.3" - resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" - integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== - - trim-lines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-lines/-/trim-lines-3.0.1.tgz#d802e332a07df861c48802c04321017b1bd87338" - integrity sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg== - - trim-newlines@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" - integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== - - trim-newlines@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" - integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== - - trim-trailing-lines@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" - integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== - - trim@0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" - integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== - - trough@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" - integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== - - trough@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/trough/-/trough-2.1.0.tgz#0f7b511a4fde65a46f18477ab38849b22c554876" - integrity sha512-AqTiAOLcj85xS7vQ8QkAV41hPDIJ71XJB4RCUrzo/1GM2CQwhkJGaf9Hgr7BOugMRpgGUrqRg/DrBDl4H40+8g== - - ts-dedent@^2.0.0, ts-dedent@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" - integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== - - ts-jest@^27.0.5: - version "27.1.5" - resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-27.1.5.tgz#0ddf1b163fbaae3d5b7504a1e65c914a95cff297" - integrity sha512-Xv6jBQPoBEvBq/5i2TeSG9tt/nqkbpcurrEG1b+2yfBrcJelOZF9Ml6dmyMh7bcW9JyFbRYpR5rxROSlBLTZHA== - dependencies: - bs-logger "0.x" - fast-json-stable-stringify "2.x" - jest-util "^27.0.0" - json5 "2.x" - lodash.memoize "4.x" - make-error "1.x" - semver "7.x" - yargs-parser "20.x" - - ts-loader@^9.4.2: - version "9.5.1" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" - integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.0.0" - micromatch "^4.0.0" - semver "^7.3.4" - source-map "^0.7.4" - - ts-mocha@^10.0.0: - version "10.0.0" - resolved "https://registry.yarnpkg.com/ts-mocha/-/ts-mocha-10.0.0.tgz#41a8d099ac90dbbc64b06976c5025ffaebc53cb9" - integrity sha512-VRfgDO+iiuJFlNB18tzOfypJ21xn2xbuZyDvJvqpTbWgkAgD17ONGr8t+Tl8rcBtOBdjXp5e/Rk+d39f7XBHRw== - dependencies: - ts-node "7.0.1" - optionalDependencies: - tsconfig-paths "^3.5.0" - - ts-node@10: - version "10.9.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-10.9.1.tgz#e73de9102958af9e1f0b168a6ff320e25adcff4b" - integrity sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw== - dependencies: - "@cspotcode/source-map-support" "^0.8.0" - "@tsconfig/node10" "^1.0.7" - "@tsconfig/node12" "^1.0.7" - "@tsconfig/node14" "^1.0.0" - "@tsconfig/node16" "^1.0.2" - acorn "^8.4.1" - acorn-walk "^8.1.1" - arg "^4.1.0" - create-require "^1.1.0" - diff "^4.0.1" - make-error "^1.1.1" - v8-compile-cache-lib "^3.0.1" - yn "3.1.1" - - ts-node@7.0.1: - version "7.0.1" - resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-7.0.1.tgz#9562dc2d1e6d248d24bc55f773e3f614337d9baf" - integrity sha512-BVwVbPJRspzNh2yfslyT1PSbl5uIk03EZlb493RKHN4qej/D06n1cEhjlOJG69oFsE7OT8XjpTUcYf6pKTLMhw== - dependencies: - arrify "^1.0.0" - buffer-from "^1.1.0" - diff "^3.1.0" - make-error "^1.1.1" - minimist "^1.2.0" - mkdirp "^0.5.1" - source-map-support "^0.5.6" - yn "^2.0.0" - - ts-pnp@^1.1.6: - version "1.2.0" - resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" - integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== - - tsconfig-paths-webpack-plugin@^3.5.2: - version "3.5.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz#01aafff59130c04a8c4ebc96a3045c43c376449a" - integrity sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw== - dependencies: - chalk "^4.1.0" - enhanced-resolve "^5.7.0" - tsconfig-paths "^3.9.0" - - tsconfig-paths@^3.14.2, tsconfig-paths@^3.5.0, tsconfig-paths@^3.9.0: - version "3.14.2" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" - integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== - dependencies: - "@types/json5" "^0.0.29" - json5 "^1.0.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - - tsconfig-paths@^4.1.2: - version "4.2.0" - resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz#ef78e19039133446d244beac0fd6a1632e2d107c" - integrity sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg== - dependencies: - json5 "^2.2.2" - minimist "^1.2.6" - strip-bom "^3.0.0" - - tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - - tslib@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - - tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.4.0: - version "2.6.2" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.6.2.tgz#703ac29425e7b37cd6fd456e92404d46d1f3e4ae" - integrity sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q== - - tsutils@^3.21.0: - version "3.21.0" - resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" - integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== - dependencies: - tslib "^1.8.1" - - tty-browserify@0.0.0: - version "0.0.0" - resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" - integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== - - tuf-js@^1.1.7: - version "1.1.7" - resolved "https://registry.yarnpkg.com/tuf-js/-/tuf-js-1.1.7.tgz#21b7ae92a9373015be77dfe0cb282a80ec3bbe43" - integrity sha512-i3P9Kgw3ytjELUfpuKVDNBJvk4u5bXL6gskv572mcevPbSKCV3zt3djhmlEQ65yERjIbOSncy7U4cQJaB1CBCg== - dependencies: - "@tufjs/models" "1.0.4" - debug "^4.3.4" - make-fetch-happen "^11.1.1" - - tunnel-agent@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" - integrity sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w== - dependencies: - safe-buffer "^5.0.1" - - tweetnacl-util@^0.15.0: - version "0.15.1" - resolved "https://registry.yarnpkg.com/tweetnacl-util/-/tweetnacl-util-0.15.1.tgz#b80fcdb5c97bcc508be18c44a4be50f022eea00b" - integrity sha512-RKJBIj8lySrShN4w6i/BonWp2Z/uxwC3h4y7xsRrpP59ZboCd0GpEVsOnMDYLMmKBpYhb5TgHzZXy7wTfYFBRw== - - tweetnacl@^1.0.1: - version "1.0.3" - resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-1.0.3.tgz#ac0af71680458d8a6378d0d0d050ab1407d35596" - integrity sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw== - - type-check@^0.4.0, type-check@~0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1" - integrity sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew== - dependencies: - prelude-ls "^1.2.1" - - type-detect@4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/type-detect/-/type-detect-4.0.8.tgz#7646fb5f18871cfbb7749e69bd39a6388eb7450c" - integrity sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g== - - type-fest@^0.18.0: - version "0.18.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.18.1.tgz#db4bc151a4a2cf4eebf9add5db75508db6cc841f" - integrity sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw== - - type-fest@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" - integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== - - type-fest@^0.21.3: - version "0.21.3" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" - integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== - - type-fest@^0.4.1: - version "0.4.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.4.1.tgz#8bdf77743385d8a4f13ba95f610f5ccd68c728f8" - integrity sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw== - - type-fest@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" - integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== - - type-fest@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" - integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== - - type-fest@^2.19.0: - version "2.19.0" - resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" - integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== - - type-is@~1.6.18: - version "1.6.18" - resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" - integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== - dependencies: - media-typer "0.3.0" - mime-types "~2.1.24" - - typed-array-buffer@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz#18de3e7ed7974b0a729d3feecb94338d1472cd60" - integrity sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw== - dependencies: - call-bind "^1.0.2" - get-intrinsic "^1.2.1" - is-typed-array "^1.1.10" - - typed-array-byte-length@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz#d787a24a995711611fb2b87a4052799517b230d0" - integrity sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - - typed-array-byte-offset@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz#cbbe89b51fdef9cd6aaf07ad4707340abbc4ea0b" - integrity sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.2" - for-each "^0.3.3" - has-proto "^1.0.1" - is-typed-array "^1.1.10" - - typed-array-length@^1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/typed-array-length/-/typed-array-length-1.0.4.tgz#89d83785e5c4098bec72e08b319651f0eac9c1bb" - integrity sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng== - dependencies: - call-bind "^1.0.2" - for-each "^0.3.3" - is-typed-array "^1.1.9" - - typedarray-to-buffer@^3.1.5: - version "3.1.5" - resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" - integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== - dependencies: - is-typedarray "^1.0.0" - - typedarray@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" - integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== - - typedoc@^0.22.13: - version "0.22.18" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.22.18.tgz#1d000c33b66b88fd8cdfea14a26113a83b7e6591" - integrity sha512-NK9RlLhRUGMvc6Rw5USEYgT4DVAUFk7IF7Q6MYfpJ88KnTZP7EneEa4RcP+tX1auAcz7QT1Iy0bUSZBYYHdoyA== - dependencies: - glob "^8.0.3" - lunr "^2.3.9" - marked "^4.0.16" - minimatch "^5.1.0" - shiki "^0.10.1" - - typeforce@^1.11.5: - version "1.18.0" - resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.18.0.tgz#d7416a2c5845e085034d70fcc5b6cc4a90edbfdc" - integrity sha512-7uc1O8h1M1g0rArakJdf0uLRSSgFcYexrVoKo+bzJd32gd4gDy2L/Z+8/FjPnU9ydY3pEnVPtr9FyscYY60K1g== - - "typescript@>=3 < 6": - version "5.3.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.3.2.tgz#00d1c7c1c46928c5845c1ee8d0cc2791031d4c43" - integrity sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ== - - typescript@^4.6.2, typescript@^4.8.4: - version "4.9.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" - integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g== - - ufo@^1.3.0, ufo@^1.3.1, ufo@^1.3.2: - version "1.3.2" - resolved "https://registry.yarnpkg.com/ufo/-/ufo-1.3.2.tgz#c7d719d0628a1c80c006d2240e0d169f6e3c0496" - integrity sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA== - - uglify-js@^3.1.4: - version "3.17.4" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" - integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== - - uint8arrays@^3.0.0, uint8arrays@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" - integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== - dependencies: - multiformats "^9.4.2" - - unbox-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" - integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== - dependencies: - call-bind "^1.0.2" - has-bigints "^1.0.2" - has-symbols "^1.0.3" - which-boxed-primitive "^1.0.2" - - uncrypto@^0.1.3: - version "0.1.3" - resolved "https://registry.yarnpkg.com/uncrypto/-/uncrypto-0.1.3.tgz#e1288d609226f2d02d8d69ee861fa20d8348ef2b" - integrity sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q== - - undefsafe@^2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/undefsafe/-/undefsafe-2.0.5.tgz#38733b9327bdcd226db889fb723a6efd162e6e2c" - integrity sha512-WxONCrssBM8TSPRqN5EmsjVrsv4A8X12J4ArBiiayv3DyyG3ZlIg6yysuuSYdZsVz3TKcTg2fd//Ujd4CHV1iA== - - undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - - unenv@^1.7.4: - version "1.8.0" - resolved "https://registry.yarnpkg.com/unenv/-/unenv-1.8.0.tgz#0f860d5278405700bd95d47b23bc01f3a735d68c" - integrity sha512-uIGbdCWZfhRRmyKj1UioCepQ0jpq638j/Cf0xFTn4zD1nGJ2lSdzYHLzfdXN791oo/0juUiSWW1fBklXMTsuqg== - dependencies: - consola "^3.2.3" - defu "^6.1.3" - mime "^3.0.0" - node-fetch-native "^1.4.1" - pathe "^1.1.1" - - unfetch@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" - integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== - - unherit@^1.0.4: - version "1.1.3" - resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" - integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== - dependencies: - inherits "^2.0.0" - xtend "^4.0.0" - - unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== - - unicode-match-property-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" - integrity sha512-5kaZCrbp5mmbz5ulBkDkbY0SsPOjKqVS35VpL9ulMPfSl0J0Xsm+9Evphv9CoIZFwre7aJoa94AY6seMKGVN5Q== - dependencies: - unicode-canonical-property-names-ecmascript "^2.0.0" - unicode-property-aliases-ecmascript "^2.0.0" - - unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" - integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== - - unicode-property-aliases-ecmascript@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz#43d41e3be698bd493ef911077c9b131f827e8ccd" - integrity sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w== - - unified@9.2.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" - integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== - 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" - - unified@^10.0.0: - version "10.1.2" - resolved "https://registry.yarnpkg.com/unified/-/unified-10.1.2.tgz#b1d64e55dafe1f0b98bb6c719881103ecf6c86df" - integrity sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q== - dependencies: - "@types/unist" "^2.0.0" - bail "^2.0.0" - extend "^3.0.0" - is-buffer "^2.0.0" - is-plain-obj "^4.0.0" - trough "^2.0.0" - vfile "^5.0.0" - - union-value@^1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" - integrity sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg== - dependencies: - arr-union "^3.1.0" - get-value "^2.0.6" - is-extendable "^0.1.1" - set-value "^2.0.1" - - unique-filename@^1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" - integrity sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ== - dependencies: - unique-slug "^2.0.0" - - unique-filename@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-2.0.1.tgz#e785f8675a9a7589e0ac77e0b5c34d2eaeac6da2" - integrity sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A== - dependencies: - unique-slug "^3.0.0" - - unique-filename@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-3.0.0.tgz#48ba7a5a16849f5080d26c760c86cf5cf05770ea" - integrity sha512-afXhuC55wkAmZ0P18QsVE6kp8JaxrEokN2HGIoIVv2ijHQd419H0+6EigAFcIzXeMIkcIkNBpB3L/DXB3cTS/g== - dependencies: - unique-slug "^4.0.0" - - unique-slug@^2.0.0: - version "2.0.2" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.2.tgz#baabce91083fc64e945b0f3ad613e264f7cd4e6c" - integrity sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w== - dependencies: - imurmurhash "^0.1.4" - - unique-slug@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-3.0.0.tgz#6d347cf57c8a7a7a6044aabd0e2d74e4d76dc7c9" - integrity sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w== - dependencies: - imurmurhash "^0.1.4" - - unique-slug@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-4.0.0.tgz#6bae6bb16be91351badd24cdce741f892a6532e3" - integrity sha512-WrcA6AyEfqDX5bWige/4NQfPZMtASNVxdmWR76WESYQVAACSgWcR6e9i0mofqqBxYFtL4oAxPIptY73/0YE1DQ== - dependencies: - imurmurhash "^0.1.4" - - unist-builder@2.0.3, unist-builder@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" - integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== - - unist-util-generated@^1.0.0: - version "1.1.6" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" - integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== - - unist-util-generated@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-2.0.1.tgz#e37c50af35d3ed185ac6ceacb6ca0afb28a85cae" - integrity sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A== - - unist-util-is@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" - integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== - - unist-util-is@^5.0.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-5.2.1.tgz#b74960e145c18dcb6226bc57933597f5486deae9" - integrity sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw== - dependencies: - "@types/unist" "^2.0.0" - - unist-util-position-from-estree@^1.0.0, unist-util-position-from-estree@^1.1.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz#8ac2480027229de76512079e377afbcabcfcce22" - integrity sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww== - dependencies: - "@types/unist" "^2.0.0" - - unist-util-position@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" - integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== - - unist-util-position@^4.0.0: - version "4.0.4" - resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-4.0.4.tgz#93f6d8c7d6b373d9b825844645877c127455f037" - integrity sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg== - dependencies: - "@types/unist" "^2.0.0" - - unist-util-remove-position@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" - integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== - dependencies: - unist-util-visit "^2.0.0" - - unist-util-remove-position@^4.0.0: - version "4.0.2" - resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz#a89be6ea72e23b1a402350832b02a91f6a9afe51" - integrity sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-visit "^4.0.0" - - unist-util-remove@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" - integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== - dependencies: - unist-util-is "^4.0.0" - - unist-util-stringify-position@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" - integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== - dependencies: - "@types/unist" "^2.0.2" - - unist-util-stringify-position@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz#03ad3348210c2d930772d64b489580c13a7db39d" - integrity sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg== - dependencies: - "@types/unist" "^2.0.0" - - unist-util-visit-parents@^3.0.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" - integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - - unist-util-visit-parents@^5.1.1: - version "5.1.3" - resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz#b4520811b0ca34285633785045df7a8d6776cfeb" - integrity sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - - unist-util-visit@2.0.3, unist-util-visit@^2.0.0: - version "2.0.3" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" - integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^4.0.0" - unist-util-visit-parents "^3.0.0" - - unist-util-visit@^4.0.0: - version "4.1.2" - resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-4.1.2.tgz#125a42d1eb876283715a3cb5cceaa531828c72e2" - integrity sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg== - dependencies: - "@types/unist" "^2.0.0" - unist-util-is "^5.0.0" - unist-util-visit-parents "^5.1.1" - - universal-user-agent@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/universal-user-agent/-/universal-user-agent-6.0.1.tgz#15f20f55da3c930c57bddbf1734c6654d5fd35aa" - integrity sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ== - - universalify@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" - integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== - - universalify@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.1.tgz#168efc2180964e6386d061e094df61afe239b18d" - integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== - - unpipe@1.0.0, unpipe@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" - integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== - - unset-value@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== - dependencies: - has-value "^0.3.1" - isobject "^3.0.0" - - unstorage@^1.9.0: - version "1.10.1" - resolved "https://registry.yarnpkg.com/unstorage/-/unstorage-1.10.1.tgz#bf8cc00a406e40a6293e893da9807057d95875b0" - integrity sha512-rWQvLRfZNBpF+x8D3/gda5nUCQL2PgXy2jNG4U7/Rc9BGEv9+CAJd0YyGCROUBKs9v49Hg8huw3aih5Bf5TAVw== - dependencies: - anymatch "^3.1.3" - chokidar "^3.5.3" - destr "^2.0.2" - h3 "^1.8.2" - ioredis "^5.3.2" - listhen "^1.5.5" - lru-cache "^10.0.2" - mri "^1.2.0" - node-fetch-native "^1.4.1" - ofetch "^1.3.3" - ufo "^1.3.1" - - untildify@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" - integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== - dependencies: - os-homedir "^1.0.0" - - untun@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/untun/-/untun-0.1.2.tgz#fa42a62ae24c1c5c6f3209692a2b0e1f573f1353" - integrity sha512-wLAMWvxfqyTiBODA1lg3IXHQtjggYLeTK7RnSfqtOXixWJ3bAa2kK/HHmOOg19upteqO3muLvN6O/icbyQY33Q== - dependencies: - citty "^0.1.3" - consola "^3.2.3" - pathe "^1.1.1" - - upath@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/upath/-/upath-2.0.1.tgz#50c73dea68d6f6b990f51d279ce6081665d61a8b" - integrity sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w== - - upath@^1.1.1: - version "1.2.0" - resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" - integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== - - update-browserslist-db@^1.0.13: - version "1.0.13" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz#3c5e4f5c083661bd38ef64b6328c26ed6c8248c4" - integrity sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg== - dependencies: - escalade "^3.1.1" - picocolors "^1.0.0" - - uqr@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/uqr/-/uqr-0.1.2.tgz#5c6cd5dcff9581f9bb35b982cb89e2c483a41d7d" - integrity sha512-MJu7ypHq6QasgF5YRTjqscSzQp/W11zoUk6kvmlH+fmWEs63Y0Eib13hYFwAzagRJcVY8WVnlV+eBDUGMJ5IbA== - - uri-js@^4.2.2: - version "4.4.1" - resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" - integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== - dependencies: - punycode "^2.1.0" - - urix@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== - - url-loader@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" - integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== - dependencies: - loader-utils "^2.0.0" - mime-types "^2.1.27" - schema-utils "^3.0.0" - - url-parse@^1.5.3: - version "1.5.10" - resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.10.tgz#9d3c2f736c1d75dd3bd2be507dcc111f1e2ea9c1" - integrity sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ== - dependencies: - querystringify "^2.1.1" - requires-port "^1.0.0" - - url@^0.11.0: - version "0.11.3" - resolved "https://registry.yarnpkg.com/url/-/url-0.11.3.tgz#6f495f4b935de40ce4a0a52faee8954244f3d3ad" - integrity sha512-6hxOLGfZASQK/cijlZnZJTq8OXAkt/3YGfQX45vvMYXpZoo8NdWZcY73K108Jf759lS1Bv/8wXnHDTSz17dSRw== - dependencies: - punycode "^1.4.1" - qs "^6.11.2" - - use-clipboard-copy@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/use-clipboard-copy/-/use-clipboard-copy-0.2.0.tgz#e1f31f2b21e369bc79b5d7b358e2c8aece6ef264" - integrity sha512-f0PMMwZ2/Hh9/54L12capx4s6ASdd6edNJxg2OcqWVNM8BPvtOSmNFIN1Dg/q//fPp8MpUZceHfr7cnWOS0RxA== - dependencies: - clipboard-copy "^3.0.0" - - use-sync-external-store@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a" - integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA== - - use@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" - integrity sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ== - - util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" - integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== - - util.promisify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" - integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== - dependencies: - define-properties "^1.1.2" - object.getownpropertydescriptors "^2.0.3" - - util@^0.10.4: - version "0.10.4" - resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" - integrity sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A== - dependencies: - inherits "2.0.3" - - util@^0.11.0: - version "0.11.1" - resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" - integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== - dependencies: - inherits "2.0.3" - - util@^0.12.4: - version "0.12.5" - resolved "https://registry.yarnpkg.com/util/-/util-0.12.5.tgz#5f17a6059b73db61a875668781a1c2b136bd6fbc" - integrity sha512-kZf/K6hEIrWHI6XqOFUiiMa+79wE/D8Q+NCNAWclkyg3b4d2k7s0QGepNjiABc+aR3N1PAyHL7p6UcLY6LmrnA== - dependencies: - inherits "^2.0.3" - is-arguments "^1.0.4" - is-generator-function "^1.0.7" - is-typed-array "^1.1.3" - which-typed-array "^1.1.2" - - utila@~0.4: - version "0.4.0" - resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" - integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== - - utility-types@^3.10.0: - version "3.10.0" - resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b" - integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg== - - utils-merge@1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" - integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== - - uuid-browser@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" - integrity sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg== - - uuid@^3.3.2: - version "3.4.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" - integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== - - uuid@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" - integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== - - uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - - uuid@^9.0.0, uuid@^9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.1.tgz#e188d4c8853cc722220392c424cd637f32293f30" - integrity sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA== - - uvu@^0.5.0: - version "0.5.6" - resolved "https://registry.yarnpkg.com/uvu/-/uvu-0.5.6.tgz#2754ca20bcb0bb59b64e9985e84d2e81058502df" - integrity sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA== - dependencies: - dequal "^2.0.0" - diff "^5.0.0" - kleur "^4.0.3" - sade "^1.7.3" - - v8-compile-cache-lib@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" - integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== - - v8-compile-cache@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee" - integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA== - - v8-compile-cache@^2.0.3: - version "2.4.0" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz#cdada8bec61e15865f05d097c5f4fd30e94dc128" - integrity sha512-ocyWc3bAHBB/guyqJQVI5o4BZkPhznPYUG2ea80Gond/BgNWpap8TOmLSeeQG7bnh2KMISxskdADG59j7zruhw== - - v8-to-istanbul@^8.1.0: - version "8.1.1" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz#77b752fd3975e31bbcef938f85e9bd1c7a8d60ed" - integrity sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^1.6.0" - source-map "^0.7.3" - - v8-to-istanbul@^9.0.0: - version "9.2.0" - resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz#2ed7644a245cddd83d4e087b9b33b3e62dfd10ad" - integrity sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.12" - "@types/istanbul-lib-coverage" "^2.0.1" - convert-source-map "^2.0.0" - - validate-npm-package-license@3.0.4, validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" - integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== - dependencies: - spdx-correct "^3.0.0" - spdx-expression-parse "^3.0.0" - - validate-npm-package-name@5.0.0, validate-npm-package-name@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-5.0.0.tgz#f16afd48318e6f90a1ec101377fa0384cfc8c713" - integrity sha512-YuKoXDAhBYxY7SfOKxHBDoSyENFeW5VvIIQp2TGQuit8gpK6MnWaQelBKxso72DoxTZfZdcP3W90LqpSkgPzLQ== - dependencies: - builtins "^5.0.0" - - validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw== - dependencies: - builtins "^1.0.3" - - vary@~1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" - integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== - - vfile-location@^3.0.0, vfile-location@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" - integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== - - vfile-message@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" - integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^2.0.0" - - vfile-message@^3.0.0: - version "3.1.4" - resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-3.1.4.tgz#15a50816ae7d7c2d1fa87090a7f9f96612b59dea" - integrity sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw== - dependencies: - "@types/unist" "^2.0.0" - unist-util-stringify-position "^3.0.0" - - vfile@^4.0.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" - integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^2.0.0" - vfile-message "^2.0.0" - - vfile@^5.0.0: - version "5.3.7" - resolved "https://registry.yarnpkg.com/vfile/-/vfile-5.3.7.tgz#de0677e6683e3380fafc46544cfe603118826ab7" - integrity sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g== - dependencies: - "@types/unist" "^2.0.0" - is-buffer "^2.0.0" - unist-util-stringify-position "^3.0.0" - vfile-message "^3.0.0" - - victory-vendor@^36.6.8: - version "36.7.0" - resolved "https://registry.yarnpkg.com/victory-vendor/-/victory-vendor-36.7.0.tgz#e02af33e249e74e659fa65c6d5936042c42e7aa8" - integrity sha512-nqYuTkLSdTTeACyXcCLbL7rl0y6jpzLPtTNGOtSnajdR+xxMxBdjMxDjfNJNlhR+ZU8vbXz+QejntcbY7h9/ZA== - dependencies: - "@types/d3-array" "^3.0.3" - "@types/d3-ease" "^3.0.0" - "@types/d3-interpolate" "^3.0.1" - "@types/d3-scale" "^4.0.2" - "@types/d3-shape" "^3.1.0" - "@types/d3-time" "^3.0.0" - "@types/d3-timer" "^3.0.0" - d3-array "^3.1.6" - d3-ease "^3.0.1" - d3-interpolate "^3.0.1" - d3-scale "^4.0.2" - d3-shape "^3.1.0" - d3-time "^3.0.0" - d3-timer "^3.0.1" - - vinyl@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.1.tgz#23cfb8bbab5ece3803aa2c0a1eb28af7cbba1974" - integrity sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw== - dependencies: - clone "^2.1.1" - clone-buffer "^1.0.0" - clone-stats "^1.0.0" - cloneable-readable "^1.0.0" - remove-trailing-separator "^1.0.1" - replace-ext "^1.0.0" - - vm-browserify@^1.0.1: - version "1.1.2" - resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" - integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== - - vscode-oniguruma@^1.6.1: - version "1.7.0" - resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.7.0.tgz#439bfad8fe71abd7798338d1cd3dc53a8beea94b" - integrity sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA== - - vscode-textmate@5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e" - integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ== - - w3c-hr-time@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz#0a89cdf5cc15822df9c360543676963e0cc308cd" - integrity sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ== - dependencies: - browser-process-hrtime "^1.0.0" - - w3c-xmlserializer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz#3e7104a05b75146cc60f564380b7f683acf1020a" - integrity sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA== - dependencies: - xml-name-validator "^3.0.0" - - walker@^1.0.7, walker@~1.0.5: - version "1.0.8" - resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" - integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== - dependencies: - makeerror "1.0.12" - - watchpack-chokidar2@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" - integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== - dependencies: - chokidar "^2.1.8" - - watchpack@^1.7.4: - version "1.7.5" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" - integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== - dependencies: - graceful-fs "^4.1.2" - neo-async "^2.5.0" - optionalDependencies: - chokidar "^3.4.1" - watchpack-chokidar2 "^2.0.1" - - watchpack@^2.2.0, watchpack@^2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" - integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== - dependencies: - glob-to-regexp "^0.4.1" - graceful-fs "^4.1.2" - - wbuf@^1.1.0, wbuf@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.3.tgz#c1d8d149316d3ea852848895cb6a0bfe887b87df" - integrity sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA== - dependencies: - minimalistic-assert "^1.0.0" - - wcwidth@^1.0.0, wcwidth@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/wcwidth/-/wcwidth-1.0.1.tgz#f0b0dcf915bc5ff1528afadb2c0e17b532da2fe8" - integrity sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg== - dependencies: - defaults "^1.0.3" - - web-namespaces@^1.0.0: - version "1.1.4" - resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" - integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== - - webidl-conversions@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" - integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== - - webidl-conversions@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-5.0.0.tgz#ae59c8a00b121543a2acc65c0434f57b0fc11aff" - integrity sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA== - - webidl-conversions@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-6.1.0.tgz#9111b4d7ea80acd40f5270d666621afa78b69514" - integrity sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w== - - webpack-cli@^4.8.0: - version "4.10.0" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-4.10.0.tgz#37c1d69c8d85214c5a65e589378f53aec64dab31" - integrity sha512-NLhDfH/h4O6UOy+0LSso42xvYypClINuMNBVVzX4vX98TmTaTUxwRbXdhucbFMd2qLaCTcLq/PdYrvi8onw90w== - dependencies: - "@discoveryjs/json-ext" "^0.5.0" - "@webpack-cli/configtest" "^1.2.0" - "@webpack-cli/info" "^1.5.0" - "@webpack-cli/serve" "^1.7.0" - colorette "^2.0.14" - commander "^7.0.0" - cross-spawn "^7.0.3" - fastest-levenshtein "^1.0.12" - import-local "^3.0.2" - interpret "^2.2.0" - rechoir "^0.7.0" - webpack-merge "^5.7.3" - - webpack-dev-middleware@^3.7.3: - version "3.7.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" - integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== - dependencies: - memory-fs "^0.4.1" - mime "^2.4.4" - mkdirp "^0.5.1" - range-parser "^1.2.1" - webpack-log "^2.0.0" - - webpack-dev-middleware@^4.1.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz#179cc40795882cae510b1aa7f3710cbe93c9333e" - integrity sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w== - dependencies: - colorette "^1.2.2" - mem "^8.1.1" - memfs "^3.2.2" - mime-types "^2.1.30" - range-parser "^1.2.1" - schema-utils "^3.0.0" - - webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== - dependencies: - colorette "^2.0.10" - memfs "^3.4.3" - mime-types "^2.1.31" - range-parser "^1.2.1" - schema-utils "^4.0.0" - - webpack-dev-server@^4.5.0: - version "4.15.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.15.1.tgz#8944b29c12760b3a45bdaa70799b17cb91b03df7" - integrity sha512-5hbAst3h3C3L8w6W4P96L5vaV0PxSmJhxZvWKYIdgxOQm8pNZ5dEOmmSLBVpP85ReeyRt6AS1QJNyo/oFFPeVA== - dependencies: - "@types/bonjour" "^3.5.9" - "@types/connect-history-api-fallback" "^1.3.5" - "@types/express" "^4.17.13" - "@types/serve-index" "^1.9.1" - "@types/serve-static" "^1.13.10" - "@types/sockjs" "^0.3.33" - "@types/ws" "^8.5.5" - ansi-html-community "^0.0.8" - bonjour-service "^1.0.11" - chokidar "^3.5.3" - colorette "^2.0.10" - compression "^1.7.4" - connect-history-api-fallback "^2.0.0" - default-gateway "^6.0.3" - express "^4.17.3" - graceful-fs "^4.2.6" - html-entities "^2.3.2" - http-proxy-middleware "^2.0.3" - ipaddr.js "^2.0.1" - launch-editor "^2.6.0" - open "^8.0.9" - p-retry "^4.5.0" - rimraf "^3.0.2" - schema-utils "^4.0.0" - selfsigned "^2.1.1" - serve-index "^1.9.1" - sockjs "^0.3.24" - spdy "^4.0.2" - webpack-dev-middleware "^5.3.1" - ws "^8.13.0" - - webpack-favicons@^1.3.8: - version "1.3.8" - resolved "https://registry.yarnpkg.com/webpack-favicons/-/webpack-favicons-1.3.8.tgz#cc986bf8f4cd7629af44a726ca142e14c66e7be5" - integrity sha512-c40JTAUOorQSle2X1p5eRBpNl/zWw4rqR5EvCvLGZqMaXHUtJM/waCLgz0H4Pg1nXvvqV/LoYoqSvoAI0WiD0g== - dependencies: - favicons "7.0.0-beta.1" - - webpack-filter-warnings-plugin@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" - integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== - - webpack-hot-middleware@^2.25.1: - version "2.25.4" - resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.4.tgz#d8bc9e9cb664fc3105c8e83d2b9ed436bee4e193" - integrity sha512-IRmTspuHM06aZh98OhBJtqLpeWFM8FXJS5UYpKYxCJzyFoyWj1w6VGFfomZU7OPA55dMLrQK0pRT1eQ3PACr4w== - dependencies: - ansi-html-community "0.0.8" - html-entities "^2.1.0" - strip-ansi "^6.0.0" - - webpack-log@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/webpack-log/-/webpack-log-2.0.0.tgz#5b7928e0637593f119d32f6227c1e0ac31e1b47f" - integrity sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg== - dependencies: - ansi-colors "^3.0.0" - uuid "^3.3.2" - - webpack-merge@^5.7.3, webpack-merge@^5.8.0: - version "5.10.0" - resolved "https://registry.yarnpkg.com/webpack-merge/-/webpack-merge-5.10.0.tgz#a3ad5d773241e9c682803abf628d4cd62b8a4177" - integrity sha512-+4zXKdx7UnO+1jaN4l2lHVD+mFvnlZQP/6ljaJVb4SZiwIKeUnrT5l0gkT8z+n4hKpC+jpOv6O9R+gLtag7pSA== - dependencies: - clone-deep "^4.0.1" - flat "^5.0.2" - wildcard "^2.0.0" - - webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: - version "1.4.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" - integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== - dependencies: - source-list-map "^2.0.0" - source-map "~0.6.1" - - webpack-sources@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" - integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== - - webpack-virtual-modules@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" - integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== - dependencies: - debug "^3.0.0" - - webpack-virtual-modules@^0.4.1: - version "0.4.6" - resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.6.tgz#3e4008230731f1db078d9cb6f68baf8571182b45" - integrity sha512-5tyDlKLqPfMqjT3Q9TAqf2YqjwmnUleZwzJi1A5qXnlBCdj2AtOJ6wAWdglTIDOPgOiOrXeBeFcsQ8+aGQ6QbA== - - webpack@4: - version "4.47.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.47.0.tgz#8b8a02152d7076aeb03b61b47dad2eeed9810ebc" - integrity sha512-td7fYwgLSrky3fI1EuU5cneU4+pbH6GgOfuKNS1tNPcfdGinGELAqsb/BP4nnvZyKSG2i/xFGU7+n2PvZA8HJQ== - dependencies: - "@webassemblyjs/ast" "1.9.0" - "@webassemblyjs/helper-module-context" "1.9.0" - "@webassemblyjs/wasm-edit" "1.9.0" - "@webassemblyjs/wasm-parser" "1.9.0" - acorn "^6.4.1" - ajv "^6.10.2" - ajv-keywords "^3.4.1" - chrome-trace-event "^1.0.2" - enhanced-resolve "^4.5.0" - eslint-scope "^4.0.3" - json-parse-better-errors "^1.0.2" - loader-runner "^2.4.0" - loader-utils "^1.2.3" - memory-fs "^0.4.1" - micromatch "^3.1.10" - mkdirp "^0.5.3" - neo-async "^2.6.1" - node-libs-browser "^2.2.1" - schema-utils "^1.0.0" - tapable "^1.1.3" - terser-webpack-plugin "^1.4.3" - watchpack "^1.7.4" - webpack-sources "^1.4.1" - - "webpack@>=4.43.0 <6.0.0", webpack@^5.75.0, webpack@^5.9.0: - version "5.89.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.89.0.tgz#56b8bf9a34356e93a6625770006490bf3a7f32dc" - integrity sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw== - dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" - acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" - chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" - es-module-lexer "^1.2.1" - eslint-scope "5.1.1" - events "^3.2.0" - glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" - json-parse-even-better-errors "^2.3.1" - loader-runner "^4.2.0" - mime-types "^2.1.27" - neo-async "^2.6.2" - schema-utils "^3.2.0" - tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" - webpack-sources "^3.2.3" - - websocket-driver@>=0.5.1, websocket-driver@^0.7.4: - version "0.7.4" - resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.7.4.tgz#89ad5295bbf64b480abcba31e4953aca706f5760" - integrity sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg== - dependencies: - http-parser-js ">=0.5.1" - safe-buffer ">=5.1.0" - websocket-extensions ">=0.1.1" - - websocket-extensions@>=0.1.1: - version "0.1.4" - resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" - integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== - - whatwg-encoding@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz#5abacf777c32166a51d085d6b4f3e7d27113ddb0" - integrity sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw== - dependencies: - iconv-lite "0.4.24" - - whatwg-mimetype@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" - integrity sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g== - - whatwg-url@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" - integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== - dependencies: - tr46 "~0.0.3" - webidl-conversions "^3.0.0" - - whatwg-url@^8.0.0, whatwg-url@^8.5.0: - version "8.7.0" - resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-8.7.0.tgz#656a78e510ff8f3937bc0bcbe9f5c0ac35941b77" - integrity sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg== - dependencies: - lodash "^4.7.0" - tr46 "^2.1.0" - webidl-conversions "^6.1.0" - - which-boxed-primitive@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" - integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== - dependencies: - is-bigint "^1.0.1" - is-boolean-object "^1.1.0" - is-number-object "^1.0.4" - is-string "^1.0.5" - is-symbol "^1.0.3" - - which-builtin-type@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/which-builtin-type/-/which-builtin-type-1.1.3.tgz#b1b8443707cc58b6e9bf98d32110ff0c2cbd029b" - integrity sha512-YmjsSMDBYsM1CaFiayOVT06+KJeXf0o5M/CAd4o1lTadFAtacTUM49zoYxr/oroopFDfhvN6iEcBxUyc3gvKmw== - dependencies: - function.prototype.name "^1.1.5" - has-tostringtag "^1.0.0" - is-async-function "^2.0.0" - is-date-object "^1.0.5" - is-finalizationregistry "^1.0.2" - is-generator-function "^1.0.10" - is-regex "^1.1.4" - is-weakref "^1.0.2" - isarray "^2.0.5" - which-boxed-primitive "^1.0.2" - which-collection "^1.0.1" - which-typed-array "^1.1.9" - - which-collection@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/which-collection/-/which-collection-1.0.1.tgz#70eab71ebbbd2aefaf32f917082fc62cdcb70906" - integrity sha512-W8xeTUwaln8i3K/cY1nGXzdnVZlidBcagyNFtBdD5kxnb4TvGKR7FfSIS3mYpwWS1QUCutfKz8IY8RjftB0+1A== - dependencies: - is-map "^2.0.1" - is-set "^2.0.1" - is-weakmap "^2.0.1" - is-weakset "^2.0.1" - - which-typed-array@^1.1.11, which-typed-array@^1.1.13, which-typed-array@^1.1.2, which-typed-array@^1.1.9: - version "1.1.13" - resolved "https://registry.yarnpkg.com/which-typed-array/-/which-typed-array-1.1.13.tgz#870cd5be06ddb616f504e7b039c4c24898184d36" - integrity sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow== - dependencies: - available-typed-arrays "^1.0.5" - call-bind "^1.0.4" - for-each "^0.3.3" - gopd "^1.0.1" - has-tostringtag "^1.0.0" - - which@^1.2.9: - version "1.3.1" - resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" - integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== - dependencies: - isexe "^2.0.0" - - which@^2.0.1, which@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" - integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== - dependencies: - isexe "^2.0.0" - - which@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/which/-/which-3.0.1.tgz#89f1cd0c23f629a8105ffe69b8172791c87b4be1" - integrity sha512-XA1b62dzQzLfaEOSQFTCOd5KFf/1VSzZo7/7TUjnya6u0vGGKzU96UQBZTAThCb2j4/xjBAyii1OhRLJEivHvg== - dependencies: - isexe "^2.0.0" - - wide-align@^1.1.2, wide-align@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" - integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== - dependencies: - string-width "^1.0.2 || 2 || 3 || 4" - - widest-line@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" - integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== - dependencies: - string-width "^4.0.0" - - wif@^2.0.6: - version "2.0.6" - resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" - integrity sha512-HIanZn1zmduSF+BQhkE+YXIbEiH0xPr1012QbFEGB0xsKqJii0/SqJjyn8dFv6y36kOznMgMB+LGcbZTJ1xACQ== - dependencies: - bs58check "<3.0.0" - - wildcard@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.1.tgz#5ab10d02487198954836b6349f74fff961e10f67" - integrity sha512-CC1bOL87PIWSBhDcTrdeLo6eGT7mCFtrg0uIJtqJUFyK+eJnzl8A1niH56uu7KMa5XFrtiV+AQuHO3n7DsHnLQ== - - wordwrap@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" - integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== - - worker-farm@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" - integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== - dependencies: - errno "~0.1.7" - - worker-rpc@^0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" - integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== - dependencies: - microevent.ts "~0.1.1" - - workerpool@6.2.1: - version "6.2.1" - resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.2.1.tgz#46fc150c17d826b86a008e5a4508656777e9c343" - integrity sha512-ILEIE97kDZvF9Wb9f6h5aXK4swSlKGUcOEGiIYb2OOu/IrDU9iwj0fD//SsA6E5ibwJxpEvhullJY4Sl4GcpAw== - - "wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - - wrap-ansi@^6.0.1: - version "6.2.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" - integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - - wrap-ansi@^8.1.0: - version "8.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" - integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== - dependencies: - ansi-styles "^6.1.0" - string-width "^5.0.1" - strip-ansi "^7.0.1" - - wrappy@1: - version "1.0.2" - resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" - integrity sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ== - - write-file-atomic@5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-5.0.1.tgz#68df4717c55c6fa4281a7860b4c2ba0a6d2b11e7" - integrity sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw== - dependencies: - imurmurhash "^0.1.4" - signal-exit "^4.0.1" - - write-file-atomic@^2.4.2: - version "2.4.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.4.3.tgz#1fd2e9ae1df3e75b8d8c367443c692d4ca81f481" - integrity sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ== - dependencies: - graceful-fs "^4.1.11" - imurmurhash "^0.1.4" - signal-exit "^3.0.2" - - write-file-atomic@^3.0.0: - version "3.0.3" - resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" - integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== - dependencies: - imurmurhash "^0.1.4" - is-typedarray "^1.0.0" - signal-exit "^3.0.2" - typedarray-to-buffer "^3.1.5" - - write-json-file@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/write-json-file/-/write-json-file-3.2.0.tgz#65bbdc9ecd8a1458e15952770ccbadfcff5fe62a" - integrity sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ== - dependencies: - detect-indent "^5.0.0" - graceful-fs "^4.1.15" - make-dir "^2.1.0" - pify "^4.0.1" - sort-keys "^2.0.0" - write-file-atomic "^2.4.2" - - write-pkg@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/write-pkg/-/write-pkg-4.0.0.tgz#675cc04ef6c11faacbbc7771b24c0abbf2a20039" - integrity sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA== - dependencies: - sort-keys "^2.0.0" - type-fest "^0.4.1" - write-json-file "^3.2.0" - - ws@^7, ws@^7.4.6, ws@^7.5.1: - version "7.5.9" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" - integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== - - ws@^8.13.0, ws@^8.2.3: - version "8.14.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f" - integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g== - - x-default-browser@^0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" - integrity sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw== - optionalDependencies: - default-browser-id "^1.0.4" - - xml-name-validator@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" - integrity sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw== - - xml2js@^0.4.23: - version "0.4.23" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" - integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - - xml2js@^0.6.1: - version "0.6.2" - resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499" - integrity sha512-T4rieHaC1EXcES0Kxxj4JWgaUQHDk+qwHcYOCFHfiwKz7tOVPLq7Hjq9dM1WCMhylqMEfP7hMcOIChvotiZegA== - dependencies: - sax ">=0.6.0" - xmlbuilder "~11.0.0" - - xmlbuilder@~11.0.0: - version "11.0.1" - resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" - integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== - - xmlchars@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/xmlchars/-/xmlchars-2.2.0.tgz#060fe1bcb7f9c76fe2a17db86a9bc3ab894210cb" - integrity sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw== - - xstream@^11.14.0: - version "11.14.0" - resolved "https://registry.yarnpkg.com/xstream/-/xstream-11.14.0.tgz#2c071d26b18310523b6877e86b4e54df068a9ae5" - integrity sha512-1bLb+kKKtKPbgTK6i/BaoAn03g47PpFstlbe1BA+y3pNS/LfvcaghS5BFf9+EE1J+KwSQsEpfJvFN5GqFtiNmw== - dependencies: - globalthis "^1.0.1" - symbol-observable "^2.0.3" - - xtend@^4.0.0, xtend@^4.0.1, xtend@~4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" - integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== - - y18n@^4.0.0: - version "4.0.3" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" - integrity sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ== - - y18n@^5.0.5: - version "5.0.8" - resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" - integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== - - yallist@^3.0.2: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" - integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== - - yallist@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" - integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== - - yaml-loader@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/yaml-loader/-/yaml-loader-0.8.0.tgz#c839325e3fdee082b3768b2a21fe34fde5d96f61" - integrity sha512-LjeKnTzVBKWiQBeE2L9ssl6WprqaUIxCSNs5tle8PaDydgu3wVFXTbMfsvF2MSErpy9TDVa092n4q6adYwJaWg== - dependencies: - javascript-stringify "^2.0.1" - loader-utils "^2.0.0" - yaml "^2.0.0" - - yaml@^1.10.0, yaml@^1.10.2, yaml@^1.7.2: - version "1.10.2" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" - integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== - - yaml@^2.0.0: - version "2.3.4" - resolved "https://registry.yarnpkg.com/yaml/-/yaml-2.3.4.tgz#53fc1d514be80aabf386dc6001eb29bf3b7523b2" - integrity sha512-8aAvwVUSHpfEqTQ4w/KMlf3HcRdt50E5ODIQJBw1fQ5RL34xabzxtUlzTXVqc4rkZsPbvrXKWnABCD7kWSmocA== - - yargs-parser@20.2.4: - version "20.2.4" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.4.tgz#b42890f14566796f85ae8e3a25290d205f154a54" - integrity sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA== - - yargs-parser@20.x, yargs-parser@^20.2.2, yargs-parser@^20.2.3, yargs-parser@^20.2.9: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== - - yargs-parser@21.1.1, yargs-parser@^21.1.1: - version "21.1.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35" - integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw== - - yargs-unparser@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yargs-unparser/-/yargs-unparser-2.0.0.tgz#f131f9226911ae5d9ad38c432fe809366c2325eb" - integrity sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA== - dependencies: - camelcase "^6.0.0" - decamelize "^4.0.0" - flat "^5.0.2" - is-plain-obj "^2.1.0" - - yargs@16.2.0, yargs@^16.2.0: - version "16.2.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" - integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== - dependencies: - cliui "^7.0.2" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.0" - y18n "^5.0.5" - yargs-parser "^20.2.2" - - yargs@^17.6.2: - version "17.7.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269" - integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w== - dependencies: - cliui "^8.0.1" - escalade "^3.1.1" - get-caller-file "^2.0.5" - require-directory "^2.1.1" - string-width "^4.2.3" - y18n "^5.0.5" - yargs-parser "^21.1.1" - - yn@3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" - integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== - - yn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a" - integrity sha512-uTv8J/wiWTgUTg+9vLTi//leUl5vDQS6uii/emeTb2ssY7vl6QWf2fFbIIGjnhjvbdKlU0ed7QPgY1htTC86jQ== - - yocto-queue@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" - integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== - - yup@^0.32.9: - version "0.32.11" - resolved "https://registry.yarnpkg.com/yup/-/yup-0.32.11.tgz#d67fb83eefa4698607982e63f7ca4c5ed3cf18c5" - integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg== - dependencies: - "@babel/runtime" "^7.15.4" - "@types/lodash" "^4.14.175" - lodash "^4.17.21" - lodash-es "^4.17.21" - nanoclone "^0.2.1" - property-expr "^2.0.4" - toposort "^2.0.2" - - yup@^1.2.0: - version "1.3.2" - resolved "https://registry.yarnpkg.com/yup/-/yup-1.3.2.tgz#afffc458f1513ed386e6aaf4bcaa4e67a9e270dc" - integrity sha512-6KCM971iQtJ+/KUaHdrhVr2LDkfhBtFPRnsG1P8F4q3uUVQ2RfEM9xekpha9aA4GXWJevjM10eDcPQ1FfWlmaQ== - dependencies: - property-expr "^2.0.5" - tiny-case "^1.0.3" - toposort "^2.0.2" - type-fest "^2.19.0" - - zustand@4.4.6: - version "4.4.6" - resolved "https://registry.yarnpkg.com/zustand/-/zustand-4.4.6.tgz#03c78e3e2686c47095c93714c0c600b72a6512bd" - integrity sha512-Rb16eW55gqL4W2XZpJh0fnrATxYEG3Apl2gfHTyDSE965x/zxslTikpNch0JgNjJA9zK6gEFW8Fl6d1rTZaqgg== - dependencies: - use-sync-external-store "1.2.0" - - zwitch@^1.0.0: - version "1.0.5" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" - integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== - - zwitch@^2.0.0: - version "2.0.4" - resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.4.tgz#c827d4b0acb76fc3e685a4c6ec2902d51070e9d7" - integrity sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A== - - zxcvbn@^4.4.2: - version "4.4.2" - resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30" - integrity sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ== From 2bff66e2c7b3da6512bfadecfbf7532f10c4011e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 28 Feb 2024 16:45:00 +0000 Subject: [PATCH 143/394] Remove rustls feature on workspace deps (#4422) * Remove rustls feature on workspace deps * Cargo.lock for nym-connect and nym-wallet --- Cargo.lock | 12 ++---------- Cargo.toml | 6 +++--- nym-connect/desktop/Cargo.lock | 11 +---------- nym-wallet/Cargo.lock | 7 ------- 4 files changed, 6 insertions(+), 30 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7dcb192b24..de96670731 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4280,7 +4280,7 @@ dependencies = [ "rw-stream-sink", "soketto", "url", - "webpki-roots 0.22.6", + "webpki-roots", ] [[package]] @@ -8014,7 +8014,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.25.2", "winreg", ] @@ -9177,7 +9176,7 @@ dependencies = [ "time", "tokio-stream", "url", - "webpki-roots 0.22.6", + "webpki-roots", ] [[package]] @@ -9824,7 +9823,6 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.10", "tokio", "tungstenite", ] @@ -10842,12 +10840,6 @@ dependencies = [ "webpki 0.22.4", ] -[[package]] -name = "webpki-roots" -version = "0.25.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "14247bb57be4f377dfb94c72830b8ce8fc6beac03cf4bf7b9732eadd414123fc" - [[package]] name = "webrtc" version = "0.6.0" diff --git a/Cargo.toml b/Cargo.toml index 6e78dea995..e90561c0bb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -159,7 +159,7 @@ log = "0.4" once_cell = "1.7.2" parking_lot = "0.12.1" rand = "0.8.5" -reqwest = { version = "0.11.22", default_features = false, features = ["rustls-tls"] } +reqwest = { version = "0.11.22", default_features = false } schemars = "0.8.1" serde = "1.0.152" serde_json = "1.0.91" @@ -169,9 +169,9 @@ time = "0.3.30" thiserror = "1.0.48" tokio = "1.33.0" tokio-util = "0.7.10" -tokio-tungstenite = { version = "0.20.1", features = ["rustls"] } +tokio-tungstenite = { version = "0.20.1" } tracing = "0.1.37" -tungstenite = { version = "0.20.1", default-features = false, features = ["rustls"] } +tungstenite = { version = "0.20.1", default-features = false } ts-rs = "7.0.0" utoipa = "3.5.0" utoipa-swagger-ui = "3.1.5" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index f8ee12014b..cdd144c175 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -5516,7 +5516,6 @@ dependencies = [ "wasm-bindgen-futures", "wasm-streams", "web-sys", - "webpki-roots 0.25.4", "winreg 0.50.0", ] @@ -6483,7 +6482,7 @@ dependencies = [ "thiserror", "tokio-stream", "url", - "webpki-roots 0.22.6", + "webpki-roots", ] [[package]] @@ -7272,7 +7271,6 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.7", "tokio", "tungstenite", ] @@ -7454,7 +7452,6 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.7", "sha1", "thiserror", "url", @@ -7898,12 +7895,6 @@ dependencies = [ "webpki", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webview2-com" version = "0.19.1" diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 0c61b55042..5fc7e020bd 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -4444,7 +4444,6 @@ dependencies = [ "wasm-bindgen", "wasm-bindgen-futures", "web-sys", - "webpki-roots", "winreg", ] @@ -6272,12 +6271,6 @@ dependencies = [ "system-deps 6.1.1", ] -[[package]] -name = "webpki-roots" -version = "0.25.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1" - [[package]] name = "webview2-com" version = "0.19.1" From 208ec4574bfed1ad12551f58257df58a009be845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 29 Feb 2024 15:29:41 +0000 Subject: [PATCH 144/394] using the shared code for credentials import --- Cargo.lock | 4 ++ clients/native/Cargo.toml | 1 + .../native/src/commands/import_credential.rs | 62 +++---------------- clients/native/src/error.rs | 26 ++------ clients/socks5/Cargo.toml | 1 + .../socks5/src/commands/import_credential.rs | 62 +++---------------- clients/socks5/src/error.rs | 24 ++----- common/commands/Cargo.toml | 1 + .../commands/src/coconut/import_credential.rs | 45 ++------------ .../network-requester/Cargo.toml | 2 +- .../src/cli/import_credential.rs | 62 +++---------------- .../network-requester/src/error.rs | 24 ++----- 12 files changed, 59 insertions(+), 255 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index dd14db56db..f77a763245 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5128,6 +5128,7 @@ dependencies = [ "nym-credentials", "nym-credentials-interface", "nym-crypto", + "nym-id-lib", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -5168,6 +5169,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-gateway-requests", + "nym-id-lib", "nym-network-defaults", "nym-pemstore", "nym-sphinx", @@ -5890,6 +5892,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-exit-policy", + "nym-id-lib", "nym-network-defaults", "nym-ordered-buffer", "nym-sdk", @@ -6177,6 +6180,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-gateway-requests", + "nym-id-lib", "nym-network-defaults", "nym-ordered-buffer", "nym-pemstore", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index b113ecc3e6..9da09cd0d0 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -51,5 +51,6 @@ nym-task = { path = "../../common/task" } nym-topology = { path = "../../common/topology" } nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] } nym-client-websocket-requests = { path = "websocket-requests" } +nym-id-lib = { path = "../../common/nym-id-lib" } [dev-dependencies] diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index de211aef01..437cffd37c 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -4,14 +4,15 @@ use crate::commands::try_load_current_config; use crate::error::ClientError; use clap::ArgGroup; -use log::{error, info}; -use nym_credential_storage::models::StorableIssuedCredential; -use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; -use nym_credentials::IssuedBandwidthCredential; + + + + + +use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; -use zeroize::Zeroizing; + fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() @@ -33,8 +34,8 @@ pub(crate) struct Args { pub(crate) credential_path: Option<PathBuf>, // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true, default_value_t = 1)] - pub(crate) version: u8, + #[clap(long, hide = true)] + pub(crate) version: Option<u8>, } pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { @@ -52,50 +53,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { fs::read(args.credential_path.unwrap())? } }; - let raw_credential = Zeroizing::new(raw_credential); - // we're unpacking the data in order to make sure it's valid - // and to extract relevant metadata for storage purposes - let credential = match args.version { - 1 => Zeroizing::new( - IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { - ClientError::CredentialDeserializationFailure { - storage_revision: 1, - source, - } - })?, - ), - other => panic!("unknown credential serialization version {other}"), - }; - - info!("importing {}", credential.typ()); - match credential.variant_data() { - BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { - info!("with value of {}", voucher_info.value()) - } - BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { - info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expired() { - error!("the free pass has already expired!"); - - // technically we can import it, but the gateway will just reject it so what's the point - return Err(ClientError::ExpiredCredentialImport { - expiration: freepass_info.expiry_date(), - }); - } - } - } - - let storable = StorableIssuedCredential { - serialization_revision: args.version, - credential_data: &raw_credential, - credential_type: credential.typ().to_string(), - epoch_id: credential - .epoch_id() - .try_into() - .expect("our epoch is has run over u32::MAX!"), - }; - - credentials_store.insert_issued_credential(storable).await?; + import_credential(credentials_store, raw_credential, args.version).await?; Ok(()) } diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 8a21803736..2b7d0bfc8b 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -1,6 +1,7 @@ use nym_client_core::error::ClientCoreError; -use nym_credential_storage::error::StorageError; -use time::OffsetDateTime; + + +use nym_id_lib::NymIdError; #[derive(thiserror::Error, Debug)] pub enum ClientError { @@ -22,22 +23,7 @@ pub enum ClientError { #[error("Attempted to start the client in invalid socket mode")] InvalidSocketMode, - - #[error("failed to store credential: {source}")] - CredentialStorageFailure { - #[from] - source: StorageError, - }, - - #[error( - "failed to deserialize provided credential using revision {storage_revision}: {source}" - )] - CredentialDeserializationFailure { - storage_revision: u8, - #[source] - source: nym_credentials::error::Error, - }, - - #[error("attempted to import an expired credential (it expired on {expiration})")] - ExpiredCredentialImport { expiration: OffsetDateTime }, + + #[error(transparent)] + NymIdError(#[from] NymIdError) } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 37477d9d18..0af4c34770 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -35,6 +35,7 @@ nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" } nym-pemstore = { path = "../../common/pemstore" } nym-topology = { path = "../../common/topology" } nym-socks5-client-core = { path = "../../common/socks5-client-core" } +nym-id-lib = { path = "../../common/nym-id-lib" } [features] default = [] diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index 2ce3457015..502d49c3a3 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -4,14 +4,15 @@ use crate::commands::try_load_current_config; use crate::error::Socks5ClientError; use clap::ArgGroup; -use log::{error, info}; -use nym_credential_storage::models::StorableIssuedCredential; -use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; -use nym_credentials::IssuedBandwidthCredential; + + + + + +use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; -use zeroize::Zeroizing; + fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() @@ -33,8 +34,8 @@ pub(crate) struct Args { pub(crate) credential_path: Option<PathBuf>, // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true, default_value_t = 1)] - pub(crate) version: u8, + #[clap(long, hide = true)] + pub(crate) version: Option<u8>, } pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { @@ -52,50 +53,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { fs::read(args.credential_path.unwrap())? } }; - let raw_credential = Zeroizing::new(raw_credential); - // we're unpacking the data in order to make sure it's valid - // and to extract relevant metadata for storage purposes - let credential = match args.version { - 1 => Zeroizing::new( - IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { - Socks5ClientError::CredentialDeserializationFailure { - storage_revision: 1, - source, - } - })?, - ), - other => panic!("unknown credential serialization version {other}"), - }; - - info!("importing {}", credential.typ()); - match credential.variant_data() { - BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { - info!("with value of {}", voucher_info.value()) - } - BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { - info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expired() { - error!("the free pass has already expired!"); - - // technically we can import it, but the gateway will just reject it so what's the point - return Err(Socks5ClientError::ExpiredCredentialImport { - expiration: freepass_info.expiry_date(), - }); - } - } - } - - let storable = StorableIssuedCredential { - serialization_revision: args.version, - credential_data: &raw_credential, - credential_type: credential.typ().to_string(), - epoch_id: credential - .epoch_id() - .try_into() - .expect("our epoch is has run over u32::MAX!"), - }; - - credentials_store.insert_issued_credential(storable).await?; + import_credential(credentials_store, raw_credential, args.version).await?; Ok(()) } diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index bed06bd385..23ec79509b 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -1,6 +1,7 @@ use nym_client_core::error::ClientCoreError; -use nym_credential_storage::error::StorageError; -use time::OffsetDateTime; + +use nym_id_lib::NymIdError; + #[derive(thiserror::Error, Debug)] pub enum Socks5ClientError { @@ -23,21 +24,6 @@ pub enum Socks5ClientError { #[error(transparent)] ClientCoreError(#[from] ClientCoreError), - #[error("failed to store credential: {source}")] - CredentialStorageFailure { - #[from] - source: StorageError, - }, - - #[error( - "failed to deserialize provided credential using revision {storage_revision}: {source}" - )] - CredentialDeserializationFailure { - storage_revision: u8, - #[source] - source: nym_credentials::error::Error, - }, - - #[error("attempted to import an expired credential (it expired on {expiration})")] - ExpiredCredentialImport { expiration: OffsetDateTime }, + #[error(transparent)] + NymIdError(#[from] NymIdError), } diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index b2ef8bc3ea..dba6b7a9b5 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -55,6 +55,7 @@ nym-credentials = { path = "../../common/credentials" } nym-credentials-interface = { path = "../../common/credentials-interface" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credential-utils = { path = "../../common/credential-utils" } +nym-id-lib = { path = "../../common/nym-id-lib" } nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } nym-types = { path = "../../common/types" } diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs index 337bf9125b..225a617bff 100644 --- a/common/commands/src/coconut/import_credential.rs +++ b/common/commands/src/coconut/import_credential.rs @@ -11,6 +11,7 @@ use nym_credential_storage::models::StorableIssuedCredential; use nym_credential_storage::storage::Storage; use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; use nym_credentials::IssuedBandwidthCredential; +use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; use zeroize::Zeroizing; @@ -35,8 +36,8 @@ pub struct Args { pub(crate) credential_path: Option<PathBuf>, // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true, default_value_t = 1)] - pub(crate) version: u8, + #[clap(long, hide = true)] + pub(crate) version: Option<u8>, } pub async fn execute(args: Args) -> anyhow::Result<()> { @@ -54,6 +55,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> { "using credentials store at '{}'", credentials_store.display() ); + let credentials_store = initialise_persistent_storage(credentials_store).await; let raw_credential = match args.credential_data { Some(data) => data, @@ -62,44 +64,7 @@ pub async fn execute(args: Args) -> anyhow::Result<()> { fs::read(args.credential_path.unwrap())? } }; - let raw_credential = Zeroizing::new(raw_credential); - // we're unpacking the data in order to make sure it's valid - // and to extract relevant metadata for storage purposes - let credential = match args.version { - 1 => Zeroizing::new(IssuedBandwidthCredential::unpack_v1(&raw_credential)?), - other => panic!("unknown credential serialization version {other}"), - }; - let persistent_storage = initialise_persistent_storage(credentials_store).await; - - info!("importing {}", credential.typ()); - match credential.variant_data() { - BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { - info!("with value of {}", voucher_info.value()) - } - BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { - info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expired() { - error!("the free pass has already expired!"); - - // technically we can, but the gateway will just reject it so what's the point - bail!("can't import an expired free pass") - } - } - } - - let storable = StorableIssuedCredential { - serialization_revision: args.version, - credential_data: &raw_credential, - credential_type: credential.typ().to_string(), - epoch_id: credential - .epoch_id() - .try_into() - .expect("our epoch is has run over u32::MAX!"), - }; - - persistent_storage - .insert_issued_credential(storable) - .await?; + import_credential(credentials_store, raw_credential, args.version).await?; Ok(()) } diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 4b9b1c8003..65ca6c2aa3 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -61,7 +61,7 @@ nym-statistics-common = { path = "../../common/statistics" } nym-task = { path = "../../common/task" } nym-types = { path = "../../common/types" } nym-exit-policy = { path = "../../common/exit-policy", features = ["client"] } - +nym-id-lib = { path = "../../common/nym-id-lib" } [dev-dependencies] tempfile = "3.5.0" diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index 6d0b8fffb1..6c530b6119 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -4,14 +4,15 @@ use crate::cli::try_load_current_config; use crate::error::NetworkRequesterError; use clap::ArgGroup; -use log::{error, info}; -use nym_credential_storage::models::StorableIssuedCredential; -use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; -use nym_credentials::IssuedBandwidthCredential; + + + + + +use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; -use zeroize::Zeroizing; + fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() @@ -33,8 +34,8 @@ pub(crate) struct Args { pub(crate) credential_path: Option<PathBuf>, // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true, default_value_t = 1)] - pub(crate) version: u8, + #[clap(long, hide = true)] + pub(crate) version: Option<u8>, } pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { @@ -52,50 +53,7 @@ pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { fs::read(args.credential_path.unwrap())? } }; - let raw_credential = Zeroizing::new(raw_credential); - // we're unpacking the data in order to make sure it's valid - // and to extract relevant metadata for storage purposes - let credential = match args.version { - 1 => Zeroizing::new( - IssuedBandwidthCredential::unpack_v1(&raw_credential).map_err(|source| { - NetworkRequesterError::CredentialDeserializationFailure { - storage_revision: 1, - source, - } - })?, - ), - other => panic!("unknown credential serialization version {other}"), - }; - - info!("importing {}", credential.typ()); - match credential.variant_data() { - BandwidthCredentialIssuedDataVariant::Voucher(voucher_info) => { - info!("with value of {}", voucher_info.value()) - } - BandwidthCredentialIssuedDataVariant::FreePass(freepass_info) => { - info!("with expiry at {}", freepass_info.expiry_date()); - if freepass_info.expired() { - error!("the free pass has already expired!"); - - // technically we can import it, but the gateway will just reject it so what's the point - return Err(NetworkRequesterError::ExpiredCredentialImport { - expiration: freepass_info.expiry_date(), - }); - } - } - } - - let storable = StorableIssuedCredential { - serialization_revision: args.version, - credential_data: &raw_credential, - credential_type: credential.typ().to_string(), - epoch_id: credential - .epoch_id() - .try_into() - .expect("our epoch is has run over u32::MAX!"), - }; - - credentials_store.insert_issued_credential(storable).await?; + import_credential(credentials_store, raw_credential, args.version).await?; Ok(()) } diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index ce14ed7cf9..3ee55e3d44 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -2,11 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only pub use nym_client_core::error::ClientCoreError; -use nym_credential_storage::error::StorageError; + use nym_exit_policy::policy::PolicyError; +use nym_id_lib::NymIdError; use nym_socks5_requests::{RemoteAddress, Socks5RequestError}; use std::net::SocketAddr; -use time::OffsetDateTime; + #[derive(thiserror::Error, Debug)] pub enum NetworkRequesterError { @@ -70,21 +71,6 @@ pub enum NetworkRequesterError { #[error("can't setup an exit policy without any upstream urls")] NoUpstreamExitPolicy, - #[error("failed to store credential: {source}")] - CredentialStorageFailure { - #[from] - source: StorageError, - }, - - #[error( - "failed to deserialize provided credential using revision {storage_revision}: {source}" - )] - CredentialDeserializationFailure { - storage_revision: u8, - #[source] - source: nym_credentials::error::Error, - }, - - #[error("attempted to import an expired credential (it expired on {expiration})")] - ExpiredCredentialImport { expiration: OffsetDateTime }, + #[error(transparent)] + NymIdError(#[from] NymIdError), } From 41b7a2a20d5341053934dc51c87abe467c4040c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 29 Feb 2024 15:57:48 +0000 Subject: [PATCH 145/394] cargo fmt --- clients/native/src/commands/import_credential.rs | 5 ----- clients/native/src/error.rs | 5 ++--- clients/socks5/src/commands/import_credential.rs | 5 ----- clients/socks5/src/error.rs | 1 - nym-id/src/commands/mod.rs | 1 - nym-id/src/commands/setup.rs | 1 - .../network-requester/src/cli/import_credential.rs | 5 ----- service-providers/network-requester/src/error.rs | 1 - 8 files changed, 2 insertions(+), 22 deletions(-) diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 437cffd37c..aac7feaa64 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -5,15 +5,10 @@ use crate::commands::try_load_current_config; use crate::error::ClientError; use clap::ArgGroup; - - - - use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; - fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() } diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 2b7d0bfc8b..b4f47cf90b 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -1,6 +1,5 @@ use nym_client_core::error::ClientCoreError; - use nym_id_lib::NymIdError; #[derive(thiserror::Error, Debug)] @@ -23,7 +22,7 @@ pub enum ClientError { #[error("Attempted to start the client in invalid socket mode")] InvalidSocketMode, - + #[error(transparent)] - NymIdError(#[from] NymIdError) + NymIdError(#[from] NymIdError), } diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index 502d49c3a3..25285870f8 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -5,15 +5,10 @@ use crate::commands::try_load_current_config; use crate::error::Socks5ClientError; use clap::ArgGroup; - - - - use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; - fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() } diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index 23ec79509b..788d1250f8 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -2,7 +2,6 @@ use nym_client_core::error::ClientCoreError; use nym_id_lib::NymIdError; - #[derive(thiserror::Error, Debug)] pub enum Socks5ClientError { #[error("I/O error: {0}")] diff --git a/nym-id/src/commands/mod.rs b/nym-id/src/commands/mod.rs index e2cf56ad46..362dfd554b 100644 --- a/nym-id/src/commands/mod.rs +++ b/nym-id/src/commands/mod.rs @@ -37,7 +37,6 @@ pub(crate) enum Commands { // TODO: to be determined how it's going to work in nymvpn et al. // /// // Setup, - /// Attempt to import a bandwidth credential into the provided storage. ImportCredential(import_credential::Args), diff --git a/nym-id/src/commands/setup.rs b/nym-id/src/commands/setup.rs index 20bfe6232a..755fb6cc8b 100644 --- a/nym-id/src/commands/setup.rs +++ b/nym-id/src/commands/setup.rs @@ -1,3 +1,2 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 - diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index 6c530b6119..1fe0d3de52 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -5,15 +5,10 @@ use crate::cli::try_load_current_config; use crate::error::NetworkRequesterError; use clap::ArgGroup; - - - - use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; - fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() } diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index 3ee55e3d44..0143494696 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -8,7 +8,6 @@ use nym_id_lib::NymIdError; use nym_socks5_requests::{RemoteAddress, Socks5RequestError}; use std::net::SocketAddr; - #[derive(thiserror::Error, Debug)] pub enum NetworkRequesterError { #[error("I/O error: {0}")] From ae20d2afb854ca50727088cab7bb206c0813138b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 29 Feb 2024 16:04:07 +0000 Subject: [PATCH 146/394] removed old test code --- common/commands/src/coconut/check_pass.rs | 112 ---------------------- 1 file changed, 112 deletions(-) delete mode 100644 common/commands/src/coconut/check_pass.rs diff --git a/common/commands/src/coconut/check_pass.rs b/common/commands/src/coconut/check_pass.rs deleted file mode 100644 index ef02d80722..0000000000 --- a/common/commands/src/coconut/check_pass.rs +++ /dev/null @@ -1,112 +0,0 @@ -// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: Apache-2.0 - -use crate::context::{QueryClient, SigningClient}; -use anyhow::{anyhow, bail}; -use clap::ArgGroup; -use clap::Parser; -use futures::StreamExt; -use log::{error, info}; -use nym_coconut_dkg_common::types::EpochId; -use nym_credential_utils::utils::block_until_coconut_is_available; -use nym_credentials::coconut::bandwidth::bandwidth_credential_params; -use nym_credentials::coconut::bandwidth::freepass::MAX_FREE_PASS_VALIDITY; -use nym_credentials::coconut::utils; -use nym_credentials::{ - obtain_aggregate_verification_key, IssuanceBandwidthCredential, IssuedBandwidthCredential, -}; -use nym_credentials_interface::VerificationKey; -use nym_validator_client::coconut::all_coconut_api_clients; -use nym_validator_client::nyxd::contract_traits::{DkgQueryClient, NymContractsProvider}; -use nym_validator_client::nyxd::CosmWasmClient; -use nym_validator_client::signing::AccountData; -use nym_validator_client::CoconutApiClient; -use std::fs; -use std::fs::File; -use std::io::Write; -use std::path::PathBuf; -use std::sync::Arc; -use time::format_description::well_known::Rfc3339; -use time::OffsetDateTime; -use zeroize::Zeroizing; - -#[derive(Debug, Parser)] -pub struct Args { - /// Path to the output directory for generated free passes. - #[clap(long)] - pub(crate) pass: PathBuf, -} - -// async fn get_freepass( -// api_clients: Vec<CoconutApiClient>, -// aggregate_vk: &VerificationKey, -// threshold: u64, -// epoch_id: EpochId, -// signing_account: &AccountData, -// expiration_date: OffsetDateTime, -// ) -> anyhow::Result<IssuedBandwidthCredential> { -// let issuance_pass = IssuanceBandwidthCredential::new_freepass(Some(expiration_date)); -// let signing_data = issuance_pass.prepare_for_signing(); -// -// let credential_shares = Arc::new(tokio::sync::Mutex::new(Vec::new())); -// -// futures::stream::iter(api_clients) -// .for_each_concurrent(None, |client| async { -// // move the client into the block -// let client = client; -// let api_url = client.api_client.api_url(); -// -// info!("contacting {api_url} for blinded free pass"); -// -// match issuance_pass -// .obtain_partial_freepass_credential( -// &client.api_client, -// signing_account, -// &client.verification_key, -// signing_data.clone(), -// ) -// .await -// { -// Ok(partial_credential) => { -// credential_shares -// .lock() -// .await -// .push((partial_credential, client.node_id).into()); -// } -// Err(err) => { -// error!("failed to obtain partial free pass from {api_url}: {err}") -// } -// } -// }) -// .await; -// -// // SAFETY: the futures have completed, so we MUST have the only arc reference -// #[allow(clippy::unwrap_used)] -// let credential_shares = Arc::into_inner(credential_shares).unwrap().into_inner(); -// -// if credential_shares.len() < threshold as usize { -// bail!("we managed to obtain only {} partial credentials while the minimum threshold is {threshold}", credential_shares.len()); -// } -// -// let signature = issuance_pass.aggregate_signature_shares(aggregate_vk, &credential_shares)?; -// Ok(issuance_pass.into_issued_credential(signature, epoch_id)) -// } - -pub async fn execute(args: Args, client: QueryClient) -> anyhow::Result<()> { - let raw_credential = fs::read(args.pass)?; - let credential = IssuedBandwidthCredential::unpack_v1(&raw_credential)?; - - println!("{:?}", credential.get_plain_public_attributes()); - println!("{}", credential.epoch_id()); - println!("{:?}", credential.variant_data()); - - let api_clients = all_coconut_api_clients(&client, credential.epoch_id()).await?; - - let vk = utils::obtain_aggregate_verification_key(&api_clients)?; - - let foomp = credential.prepare_for_spending(&vk)?; - - let res = foomp.verify(bandwidth_credential_params(), &vk); - println!("res: {res}"); - Ok(()) -} From 160db346512494c6e04461d6de0e4a3c8cea8238 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 29 Feb 2024 16:53:50 +0000 Subject: [PATCH 147/394] clippy --- common/commands/src/coconut/import_credential.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs index 225a617bff..388961ace4 100644 --- a/common/commands/src/coconut/import_credential.rs +++ b/common/commands/src/coconut/import_credential.rs @@ -5,16 +5,10 @@ use crate::utils::CommonConfigsWrapper; use anyhow::bail; use clap::ArgGroup; use clap::Parser; -use log::{error, info}; use nym_credential_storage::initialise_persistent_storage; -use nym_credential_storage::models::StorableIssuedCredential; -use nym_credential_storage::storage::Storage; -use nym_credentials::coconut::bandwidth::issued::BandwidthCredentialIssuedDataVariant; -use nym_credentials::IssuedBandwidthCredential; use nym_id_lib::import_credential; use std::fs; use std::path::PathBuf; -use zeroize::Zeroizing; fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() From 9a6f96b5e015ef29818458c33ba30c7d17ce7fdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= <bogdan@nymtech.net> Date: Fri, 1 Mar 2024 12:07:38 +0200 Subject: [PATCH 148/394] Fix windows build (#4426) * Fix windows build * Fix in another place too * Install clang * With sudo * Revert "cargo update -p rustls@0.21.7 (#4404)" This reverts commit ecc47cd41832f929484f0d221922abb05e27e695. --- common/client-libs/gateway-client/src/client.rs | 4 ++-- common/client-libs/gateway-client/src/socket_state.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index da2ee34f96..46b4816e2d 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -33,14 +33,14 @@ use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(unix)] use std::os::fd::RawFd; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::connect_async; -#[cfg(target_arch = "wasm32")] +#[cfg(not(unix))] use std::os::raw::c_int as RawFd; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index c42e2d7d08..afc50c7233 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -15,7 +15,7 @@ use std::os::raw::c_int as RawFd; use std::sync::Arc; use tungstenite::Message; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(unix)] use std::os::fd::AsRawFd; #[cfg(not(target_arch = "wasm32"))] use tokio::net::TcpStream; @@ -41,14 +41,14 @@ type WsConn = JSWebsocket; type SplitStreamReceiver = oneshot::Receiver<Result<SplitStream<WsConn>, GatewayClientError>>; pub(crate) fn ws_fd(_conn: &WsConn) -> Option<RawFd> { - #[cfg(not(target_arch = "wasm32"))] + #[cfg(unix)] match _conn.get_ref() { MaybeTlsStream::Plain(stream) => Some(stream.as_raw_fd()), &_ => unreachable!( "If tls features are enabled, the inner stream needs to be unpacked into raw fd" ), } - #[cfg(target_arch = "wasm32")] + #[cfg(not(unix))] None } From aebd386382e0bfdc66680ae1d6c895ffed68429a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= <bogdan@nymtech.net> Date: Fri, 1 Mar 2024 19:28:21 +0200 Subject: [PATCH 149/394] Add IPv6 support to IPPR (#4431) --- common/ip-packet-requests/src/lib.rs | 13 +- common/ip-packet-requests/src/request.rs | 27 +- common/ip-packet-requests/src/response.rs | 10 +- common/tun/src/linux/tun_device.rs | 52 ++-- .../ip-packet-router/src/constants.rs | 8 +- .../ip-packet-router/src/error.rs | 4 + .../ip-packet-router/src/ip_packet_router.rs | 8 +- .../ip-packet-router/src/mixnet_listener.rs | 230 +++++++++++------- .../ip-packet-router/src/tun_listener.rs | 42 +++- .../src/util/generate_new_ip.rs | 53 ++-- 10 files changed, 293 insertions(+), 154 deletions(-) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index fc97d13042..f61e3f266f 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -1,8 +1,19 @@ +use serde::{Deserialize, Serialize}; +use std::net::{Ipv4Addr, Ipv6Addr}; + pub mod codec; pub mod request; pub mod response; -pub const CURRENT_VERSION: u8 = 3; +// version 3: initial version +// version 4: IPv6 support +pub const CURRENT_VERSION: u8 = 4; + +#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct IPPair { + pub ipv4: Ipv4Addr, + pub ipv6: Ipv6Addr, +} fn make_bincode_serializer() -> impl bincode::Options { use bincode::Options; diff --git a/common/ip-packet-requests/src/request.rs b/common/ip-packet-requests/src/request.rs index 6f4b17ffea..011ff5bfe6 100644 --- a/common/ip-packet-requests/src/request.rs +++ b/common/ip-packet-requests/src/request.rs @@ -1,9 +1,15 @@ -use std::net::IpAddr; +use std::fmt::{Display, Formatter}; use nym_sphinx::addressing::clients::Recipient; use serde::{Deserialize, Serialize}; -use crate::{make_bincode_serializer, CURRENT_VERSION}; +use crate::{make_bincode_serializer, IPPair, CURRENT_VERSION}; + +impl Display for IPPair { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + writeln!(f, "IPv4: {}, IPV6: {}", self.ipv4, self.ipv6) + } +} fn generate_random() -> u64 { use rand::RngCore; @@ -19,7 +25,7 @@ pub struct IpPacketRequest { impl IpPacketRequest { pub fn new_static_connect_request( - ip: IpAddr, + ips: IPPair, reply_to: Recipient, reply_to_hops: Option<u8>, reply_to_avg_mix_delays: Option<f64>, @@ -31,7 +37,7 @@ impl IpPacketRequest { version: CURRENT_VERSION, data: IpPacketRequestData::StaticConnect(StaticConnectRequest { request_id, - ip, + ips, reply_to, reply_to_hops, reply_to_avg_mix_delays, @@ -137,7 +143,7 @@ pub enum IpPacketRequestData { pub struct StaticConnectRequest { pub request_id: u64, - pub ip: IpAddr, + pub ips: IPPair, // The nym-address the response should be sent back to pub reply_to: Recipient, @@ -210,6 +216,8 @@ pub struct HealthRequest { #[cfg(test)] mod tests { use super::*; + use std::net::{Ipv4Addr, Ipv6Addr}; + use std::str::FromStr; #[test] fn check_size_of_request() { @@ -218,15 +226,18 @@ mod tests { data: IpPacketRequestData::StaticConnect( StaticConnectRequest { request_id: 123, - ip: IpAddr::from([10, 0, 0, 1]), + ips: IPPair { + ipv4: Ipv4Addr::from_str("10.0.0.1").unwrap(), + ipv6: Ipv6Addr::from_str("2001:db8:a160::1").unwrap(), + }, reply_to: Recipient::try_from_base58_string("D1rrpsysCGCYXy9saP8y3kmNpGtJZUXN9SvFoUcqAsM9.9Ssso1ea5NfkbMASdiseDSjTN1fSWda5SgEVjdSN4CvV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN").unwrap(), reply_to_hops: None, reply_to_avg_mix_delays: None, buffer_timeout: None, }, - ) + ), }; - assert_eq!(connect.to_bytes().unwrap().len(), 108); + assert_eq!(connect.to_bytes().unwrap().len(), 123); } #[test] diff --git a/common/ip-packet-requests/src/response.rs b/common/ip-packet-requests/src/response.rs index 29553fa3e9..91972a35a3 100644 --- a/common/ip-packet-requests/src/response.rs +++ b/common/ip-packet-requests/src/response.rs @@ -1,9 +1,7 @@ -use std::net::IpAddr; - use nym_sphinx::addressing::clients::Recipient; use serde::{Deserialize, Serialize}; -use crate::{make_bincode_serializer, CURRENT_VERSION}; +use crate::{make_bincode_serializer, IPPair, CURRENT_VERSION}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct IpPacketResponse { @@ -38,13 +36,13 @@ impl IpPacketResponse { } } - pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ip: IpAddr) -> Self { + pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IPPair) -> Self { Self { version: CURRENT_VERSION, data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { request_id, reply_to, - reply: DynamicConnectResponseReply::Success(DynamicConnectSuccess { ip }), + reply: DynamicConnectResponseReply::Success(DynamicConnectSuccess { ips }), }), } } @@ -263,7 +261,7 @@ impl DynamicConnectResponseReply { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DynamicConnectSuccess { - pub ip: IpAddr, + pub ips: IPPair, } #[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)] diff --git a/common/tun/src/linux/tun_device.rs b/common/tun/src/linux/tun_device.rs index 20f514f4a9..94aea718de 100644 --- a/common/tun/src/linux/tun_device.rs +++ b/common/tun/src/linux/tun_device.rs @@ -1,3 +1,4 @@ +use std::net::Ipv6Addr; use std::{ collections::HashMap, net::{IpAddr, Ipv4Addr}, @@ -19,6 +20,12 @@ const TUN_WRITE_TIMEOUT_MS: u64 = 1000; #[derive(thiserror::Error, Debug)] pub enum TunDeviceError { + #[error("{0}")] + IO(#[from] std::io::Error), + + #[error("{0}")] + TokioTun(#[from] tokio_tun::Error), + #[error("timeout writing to tun device, dropping packet")] TunWriteTimeout, @@ -44,14 +51,18 @@ pub enum TunDeviceError { FailedToLockPeer, } -fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> tokio_tun::Tun { +fn setup_tokio_tun_device( + name: &str, + address: Ipv4Addr, + netmask: Ipv4Addr, +) -> Result<tokio_tun::Tun, TunDeviceError> { log::info!("Creating TUN device with: address={address}, netmask={netmask}"); // Read MTU size from env variable NYM_MTU_SIZE, else default to 1420. let mtu = std::env::var("NYM_MTU_SIZE") .map(|mtu| mtu.parse().expect("NYM_MTU_SIZE must be a valid integer")) .unwrap_or(1420); log::info!("Using MTU size: {mtu}"); - tokio_tun::Tun::builder() + Ok(tokio_tun::Tun::builder() .name(name) .tap(false) .packet_info(false) @@ -59,8 +70,7 @@ fn setup_tokio_tun_device(name: &str, address: Ipv4Addr, netmask: Ipv4Addr) -> t .up() .address(address) .netmask(netmask) - .try_build() - .expect("Failed to setup tun device, do you have permission?") + .try_build()?) } pub struct TunDevice { @@ -103,16 +113,18 @@ pub struct NatInner { pub struct TunDeviceConfig { pub base_name: String, - pub ip: Ipv4Addr, - pub netmask: Ipv4Addr, + pub ipv4: Ipv4Addr, + pub netmaskv4: Ipv4Addr, + pub ipv6: Ipv6Addr, + pub netmaskv6: String, } impl TunDevice { pub fn new( routing_mode: RoutingMode, config: TunDeviceConfig, - ) -> (Self, TunTaskTx, TunTaskResponseRx) { - let tun = Self::new_device_only(config); + ) -> Result<(Self, TunTaskTx, TunTaskResponseRx), TunDeviceError> { + let tun = Self::new_device_only(config)?; // Channels to communicate with the other tasks let (tun_task_tx, tun_task_rx) = tun_task_channel(); @@ -125,20 +137,32 @@ impl TunDevice { routing_mode, }; - (tun_device, tun_task_tx, tun_task_response_rx) + Ok((tun_device, tun_task_tx, tun_task_response_rx)) } - pub fn new_device_only(config: TunDeviceConfig) -> tokio_tun::Tun { + pub fn new_device_only(config: TunDeviceConfig) -> Result<tokio_tun::Tun, TunDeviceError> { let TunDeviceConfig { base_name, - ip, - netmask, + ipv4, + netmaskv4, + ipv6, + netmaskv6, } = config; let name = format!("{base_name}%d"); - let tun = setup_tokio_tun_device(&name, ip, netmask); + let tun = setup_tokio_tun_device(&name, ipv4, netmaskv4)?; log::info!("Created TUN device: {}", tun.name()); - tun + std::process::Command::new("ip") + .args([ + "-6", + "addr", + "add", + &format!("{}/{}", ipv6, netmaskv6), + "dev", + &tun.name(), + ]) + .output()?; + Ok(tun) } // Send outbound packets out on the wild internet diff --git a/service-providers/ip-packet-router/src/constants.rs b/service-providers/ip-packet-router/src/constants.rs index 04e3bd1a6b..eb7874f902 100644 --- a/service-providers/ip-packet-router/src/constants.rs +++ b/service-providers/ip-packet-router/src/constants.rs @@ -1,9 +1,13 @@ +use std::net::{Ipv4Addr, Ipv6Addr}; use std::time::Duration; // The interface used to route traffic pub const TUN_BASE_NAME: &str = "nymtun"; -pub const TUN_DEVICE_ADDRESS: &str = "10.0.0.1"; -pub const TUN_DEVICE_NETMASK: &str = "255.255.255.0"; +pub const TUN_DEVICE_ADDRESS_V4: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 1); +pub const TUN_DEVICE_NETMASK_V4: Ipv4Addr = Ipv4Addr::new(255, 255, 255, 0); +pub const TUN_DEVICE_ADDRESS_V6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0xa160, 0, 0, 0, 0, 0x1); // 2001:db8:a160::1 + +pub const TUN_DEVICE_NETMASK_V6: &str = "120"; // We routinely check if any clients needs to be disconnected at this interval pub(crate) const DISCONNECT_TIMER_INTERVAL: Duration = Duration::from_secs(10); diff --git a/service-providers/ip-packet-router/src/error.rs b/service-providers/ip-packet-router/src/error.rs index d4e0940b48..4732177191 100644 --- a/service-providers/ip-packet-router/src/error.rs +++ b/service-providers/ip-packet-router/src/error.rs @@ -11,6 +11,10 @@ pub enum IpPacketRouterError { #[error("client-core error: {0}")] ClientCoreError(#[from] ClientCoreError), + #[cfg(target_os = "linux")] + #[error("tun device error: {0}")] + TunDeviceError(#[from] nym_tun::tun_device::TunDeviceError), + #[error("failed to load configuration file: {0}")] FailedToLoadConfig(String), diff --git a/service-providers/ip-packet-router/src/ip_packet_router.rs b/service-providers/ip-packet-router/src/ip_packet_router.rs index c6cd08e59d..85f2ce2f3f 100644 --- a/service-providers/ip-packet-router/src/ip_packet_router.rs +++ b/service-providers/ip-packet-router/src/ip_packet_router.rs @@ -133,11 +133,13 @@ impl IpPacketRouter { // Create the TUN device that we interact with the rest of the world with let config = nym_tun::tun_device::TunDeviceConfig { base_name: crate::constants::TUN_BASE_NAME.to_string(), - ip: crate::constants::TUN_DEVICE_ADDRESS.parse().unwrap(), - netmask: crate::constants::TUN_DEVICE_NETMASK.parse().unwrap(), + ipv4: crate::constants::TUN_DEVICE_ADDRESS_V4, + netmaskv4: crate::constants::TUN_DEVICE_NETMASK_V4, + ipv6: crate::constants::TUN_DEVICE_ADDRESS_V6, + netmaskv6: crate::constants::TUN_DEVICE_NETMASK_V6.to_string(), }; let (tun_reader, tun_writer) = - tokio::io::split(nym_tun::tun_device::TunDevice::new_device_only(config)); + tokio::io::split(nym_tun::tun_device::TunDevice::new_device_only(config)?); // Channel used by the IpPacketRouter to signal connected and disconnected clients to the // TunListener diff --git a/service-providers/ip-packet-router/src/mixnet_listener.rs b/service-providers/ip-packet-router/src/mixnet_listener.rs index 1f14c18218..813c4b2e52 100644 --- a/service-providers/ip-packet-router/src/mixnet_listener.rs +++ b/service-providers/ip-packet-router/src/mixnet_listener.rs @@ -1,7 +1,6 @@ -use std::{ - collections::HashMap, - net::{IpAddr, SocketAddr}, -}; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use std::sync::Arc; +use std::{collections::HashMap, net::SocketAddr}; use bytes::{Bytes, BytesMut}; use futures::StreamExt; @@ -12,6 +11,7 @@ use nym_ip_packet_requests::{ DynamicConnectFailureReason, ErrorResponseReply, IpPacketResponse, StaticConnectFailureReason, }, + IPPair, }; use nym_sdk::mixnet::{MixnetMessageSender, Recipient}; use nym_sphinx::receiver::ReconstructedMessage; @@ -19,6 +19,7 @@ use nym_task::TaskHandle; use tap::TapFallible; #[cfg(target_os = "linux")] use tokio::io::AsyncWriteExt; +use tokio::sync::RwLock; use tokio_util::codec::Decoder; use crate::{ @@ -37,7 +38,8 @@ use crate::{ pub(crate) struct ConnectedClients { // The set of connected clients - clients: HashMap<IpAddr, ConnectedClient>, + clients_ipv4_mapping: HashMap<Ipv4Addr, ConnectedClient>, + clients_ipv6_mapping: HashMap<Ipv6Addr, ConnectedClient>, // Notify the tun listener when a new client connects or disconnects tun_listener_connected_client_tx: tokio::sync::mpsc::UnboundedSender<ConnectedClientEvent>, @@ -48,46 +50,62 @@ impl ConnectedClients { let (connected_client_tx, connected_client_rx) = tokio::sync::mpsc::unbounded_channel(); ( Self { - clients: Default::default(), + clients_ipv4_mapping: Default::default(), + clients_ipv6_mapping: Default::default(), tun_listener_connected_client_tx: connected_client_tx, }, tun_listener::ConnectedClientsListener::new(connected_client_rx), ) } - fn is_ip_connected(&self, ip: &IpAddr) -> bool { - self.clients.contains_key(ip) + fn is_ip_connected(&self, ips: &IPPair) -> bool { + self.clients_ipv4_mapping.contains_key(&ips.ipv4) + || self.clients_ipv6_mapping.contains_key(&ips.ipv6) } fn get_client_from_ip_mut(&mut self, ip: &IpAddr) -> Option<&mut ConnectedClient> { - self.clients.get_mut(ip) + match ip { + IpAddr::V4(ip) => self.clients_ipv4_mapping.get_mut(ip), + IpAddr::V6(ip) => self.clients_ipv6_mapping.get_mut(ip), + } } fn is_nym_address_connected(&self, nym_address: &Recipient) -> bool { - self.clients + self.clients_ipv4_mapping .values() .any(|client| client.nym_address == *nym_address) } - fn lookup_ip_from_nym_address(&self, nym_address: &Recipient) -> Option<IpAddr> { - self.clients.iter().find_map(|(ip, client)| { - if client.nym_address == *nym_address { - Some(*ip) - } else { - None - } - }) + fn lookup_ip_from_nym_address(&self, nym_address: &Recipient) -> Option<IPPair> { + self.clients_ipv4_mapping + .iter() + .find_map(|(ipv4, connected_client)| { + if connected_client.nym_address == *nym_address { + Some(IPPair { + ipv4: *ipv4, + ipv6: connected_client.ipv6, + }) + } else { + None + } + }) } fn lookup_client_from_nym_address(&self, nym_address: &Recipient) -> Option<&ConnectedClient> { - self.clients - .values() - .find(|client| client.nym_address == *nym_address) + self.clients_ipv4_mapping + .iter() + .find_map(|(_, connected_client)| { + if connected_client.nym_address == *nym_address { + Some(connected_client) + } else { + None + } + }) } fn connect( &mut self, - ip: IpAddr, + ips: IPPair, nym_address: Recipient, mix_hops: Option<u8>, forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, @@ -96,21 +114,25 @@ impl ConnectedClients { ) { // The map of connected clients that the mixnet listener keeps track of. It monitors // activity and disconnects clients that have been inactive for too long. - self.clients.insert( - ip, - ConnectedClient { + let client = ConnectedClient { + nym_address, + ipv6: ips.ipv6, + mix_hops, + last_activity: Arc::new(RwLock::new(std::time::Instant::now())), + _close_tx: Arc::new(CloseTx { nym_address, - mix_hops, - last_activity: std::time::Instant::now(), - close_tx: Some(close_tx), - handle, - }, - ); + inner: Some(close_tx), + }), + handle: Arc::new(handle), + }; + log::info!("Inserting {} and {}", ips.ipv4, ips.ipv6); + self.clients_ipv4_mapping.insert(ips.ipv4, client.clone()); + self.clients_ipv6_mapping.insert(ips.ipv6, client); // Send the connected client info to the tun listener, which will use it to forward packets // to the connected client handler. self.tun_listener_connected_client_tx .send(ConnectedClientEvent::Connect(Box::new(ConnectEvent { - ip, + ips, forward_from_tun_tx, }))) .tap_err(|err| { @@ -119,9 +141,9 @@ impl ConnectedClients { .ok(); } - fn update_activity(&mut self, ip: &IpAddr) -> Result<()> { - if let Some(client) = self.clients.get_mut(ip) { - client.last_activity = std::time::Instant::now(); + async fn update_activity(&mut self, ips: &IPPair) -> Result<()> { + if let Some(client) = self.clients_ipv4_mapping.get(&ips.ipv4) { + *client.last_activity.write().await = std::time::Instant::now(); Ok(()) } else { Err(IpPacketRouterError::FailedToUpdateClientActivity) @@ -129,12 +151,18 @@ impl ConnectedClients { } // Identify connected client handlers that have stopped without being told to stop - fn get_finished_client_handlers(&mut self) -> Vec<(IpAddr, Recipient)> { - self.clients + fn get_finished_client_handlers(&mut self) -> Vec<(IPPair, Recipient)> { + self.clients_ipv4_mapping .iter_mut() - .filter_map(|(ip, client)| { - if client.handle.is_finished() { - Some((*ip, client.nym_address)) + .filter_map(|(ip, connected_client)| { + if connected_client.handle.is_finished() { + Some(( + IPPair { + ipv4: *ip, + ipv6: connected_client.ipv6, + }, + connected_client.nym_address, + )) } else { None } @@ -142,26 +170,32 @@ impl ConnectedClients { .collect() } - fn get_inactive_clients(&mut self) -> Vec<(IpAddr, Recipient)> { + async fn get_inactive_clients(&mut self) -> Vec<(IPPair, Recipient)> { let now = std::time::Instant::now(); - self.clients - .iter() - .filter_map(|(ip, client)| { - if now.duration_since(client.last_activity) > CLIENT_MIXNET_INACTIVITY_TIMEOUT { - Some((*ip, client.nym_address)) - } else { - None - } - }) - .collect() + let mut ret = vec![]; + for (ip, connected_client) in self.clients_ipv4_mapping.iter() { + if now.duration_since(*connected_client.last_activity.read().await) + > CLIENT_MIXNET_INACTIVITY_TIMEOUT + { + ret.push(( + IPPair { + ipv4: *ip, + ipv6: connected_client.ipv6, + }, + connected_client.nym_address, + )) + } + } + ret } - fn disconnect_stopped_client_handlers(&mut self, stopped_clients: Vec<(IpAddr, Recipient)>) { - for (ip, _) in &stopped_clients { - log::info!("Disconnect stopped client: {ip}"); - self.clients.remove(ip); + fn disconnect_stopped_client_handlers(&mut self, stopped_clients: Vec<(IPPair, Recipient)>) { + for (ips, _) in &stopped_clients { + log::info!("Disconnect stopped client: {ips}"); + self.clients_ipv4_mapping.remove(&ips.ipv4); + self.clients_ipv6_mapping.remove(&ips.ipv6); self.tun_listener_connected_client_tx - .send(ConnectedClientEvent::Disconnect(DisconnectEvent(*ip))) + .send(ConnectedClientEvent::Disconnect(DisconnectEvent(*ips))) .tap_err(|err| { log::error!("Failed to send disconnect event: {err}"); }) @@ -169,12 +203,13 @@ impl ConnectedClients { } } - fn disconnect_inactive_clients(&mut self, inactive_clients: Vec<(IpAddr, Recipient)>) { - for (ip, _) in &inactive_clients { - log::info!("Disconnect inactive client: {ip}"); - self.clients.remove(ip); + fn disconnect_inactive_clients(&mut self, inactive_clients: Vec<(IPPair, Recipient)>) { + for (ips, _) in &inactive_clients { + log::info!("Disconnect inactive client: {ips}"); + self.clients_ipv4_mapping.remove(&ips.ipv4); + self.clients_ipv6_mapping.remove(&ips.ipv6); self.tun_listener_connected_client_tx - .send(ConnectedClientEvent::Disconnect(DisconnectEvent(*ip))) + .send(ConnectedClientEvent::Disconnect(DisconnectEvent(*ips))) .tap_err(|err| { log::error!("Failed to send disconnect event: {err}"); }) @@ -182,40 +217,49 @@ impl ConnectedClients { } } - fn find_new_ip(&self) -> Option<IpAddr> { - generate_new_ip::find_new_ip(&self.clients) + fn find_new_ip(&self) -> Option<IPPair> { + generate_new_ip::find_new_ips(&self.clients_ipv4_mapping, &self.clients_ipv6_mapping) } } +pub(crate) struct CloseTx { + pub(crate) nym_address: Recipient, + // Send to connected clients listener to stop. This is option only because we need to take + // ownership of it when the client is dropped. + pub(crate) inner: Option<tokio::sync::oneshot::Sender<()>>, +} + +#[derive(Clone)] pub(crate) struct ConnectedClient { // The nym address of the connected client that we are communicating with on the other side of // the mixnet pub(crate) nym_address: Recipient, + // The assigned IPv6 address of this client + pub(crate) ipv6: Ipv6Addr, + // Number of mix node hops that the client has requested to use pub(crate) mix_hops: Option<u8>, // Keep track of last activity so we can disconnect inactive clients - pub(crate) last_activity: std::time::Instant, + pub(crate) last_activity: Arc<RwLock<std::time::Instant>>, - // Send to connected clients listener to stop. This is option only because we need to take - // ownership of it when the client is dropped. - pub(crate) close_tx: Option<tokio::sync::oneshot::Sender<()>>, + pub(crate) _close_tx: Arc<CloseTx>, // Handle for the connected client handler - pub(crate) handle: tokio::task::JoinHandle<()>, + pub(crate) handle: Arc<tokio::task::JoinHandle<()>>, } impl ConnectedClient { - fn update_activity(&mut self) { - self.last_activity = std::time::Instant::now(); + async fn update_activity(&self) { + *self.last_activity.write().await = std::time::Instant::now(); } } -impl Drop for ConnectedClient { +impl Drop for CloseTx { fn drop(&mut self) { log::debug!("signal to close client: {}", self.nym_address); - if let Some(close_tx) = self.close_tx.take() { + if let Some(close_tx) = self.inner.take() { close_tx.send(()).ok(); } } @@ -259,7 +303,7 @@ impl MixnetListener { ); let request_id = connect_request.request_id; - let requested_ip = connect_request.ip; + let requested_ips = connect_request.ips; let reply_to = connect_request.reply_to; let reply_to_hops = connect_request.reply_to_hops; // TODO: add to connect request @@ -267,7 +311,7 @@ impl MixnetListener { // TODO: ignoring reply_to_avg_mix_delays for now // Check that the IP is available in the set of connected clients - let is_ip_taken = self.connected_clients.is_ip_connected(&requested_ip); + let is_ip_taken = self.connected_clients.is_ip_connected(&requested_ips); // Check that the nym address isn't already registered let is_nym_address_taken = self.connected_clients.is_nym_address_connected(&reply_to); @@ -277,7 +321,8 @@ impl MixnetListener { log::info!("Connecting an already connected client"); if self .connected_clients - .update_activity(&requested_ip) + .update_activity(&requested_ips) + .await .is_err() { log::error!("Failed to update activity for client"); @@ -300,7 +345,7 @@ impl MixnetListener { // Register the new client in the set of connected clients self.connected_clients.connect( - requested_ip, + requested_ips, reply_to, reply_to_hops, forward_from_tun_tx, @@ -350,11 +395,12 @@ impl MixnetListener { // TODO: this is problematic. Until we sign connect requests this means you can spam people // with return traffic - if let Some(existing_ip) = self.connected_clients.lookup_ip_from_nym_address(&reply_to) { + if let Some(existing_ips) = self.connected_clients.lookup_ip_from_nym_address(&reply_to) { log::info!("Found existing client for nym address"); if self .connected_clients - .update_activity(&existing_ip) + .update_activity(&existing_ips) + .await .is_err() { log::error!("Failed to update activity for client"); @@ -362,11 +408,11 @@ impl MixnetListener { return Ok(Some(IpPacketResponse::new_dynamic_connect_success( request_id, reply_to, - existing_ip, + existing_ips, ))); } - let Some(new_ip) = self.connected_clients.find_new_ip() else { + let Some(new_ips) = self.connected_clients.find_new_ip() else { log::info!("No available IP address"); return Ok(Some(IpPacketResponse::new_dynamic_connect_failure( request_id, @@ -386,7 +432,7 @@ impl MixnetListener { // Register the new client in the set of connected clients self.connected_clients.connect( - new_ip, + new_ips, reply_to, reply_to_hops, forward_from_tun_tx, @@ -394,7 +440,7 @@ impl MixnetListener { handle, ); Ok(Some(IpPacketResponse::new_dynamic_connect_success( - request_id, reply_to, new_ip, + request_id, reply_to, new_ips, ))) } @@ -428,7 +474,7 @@ impl MixnetListener { if let Some(connected_client) = self.connected_clients.get_client_from_ip_mut(&src_addr) { // Keep track of activity so we can disconnect inactive clients - connected_client.update_activity(); + connected_client.update_activity().await; // For packets without a port, use 0. let dst = dst.unwrap_or_else(|| SocketAddr::new(dst_addr, 0)); @@ -539,9 +585,9 @@ impl MixnetListener { } } - fn handle_disconnect_timer(&mut self) { + async fn handle_disconnect_timer(&mut self) { let stopped_clients = self.connected_clients.get_finished_client_handlers(); - let inactive_clients = self.connected_clients.get_inactive_clients(); + let inactive_clients = self.connected_clients.get_inactive_clients().await; // TODO: Send disconnect responses to all disconnected clients //for (ip, nym_address) in stopped_clients.iter().chain(disconnected_clients.iter()) { @@ -571,10 +617,14 @@ impl MixnetListener { })?; // We could avoid this lookup if we check this when we create the response. - let mix_hops = self + let mix_hops = if let Some(c) = self .connected_clients .lookup_client_from_nym_address(recipient) - .and_then(|c| c.mix_hops); + { + c.mix_hops + } else { + None + }; let input_message = create_input_message(*recipient, response_packet, mix_hops); self.mixnet_client @@ -613,7 +663,7 @@ impl MixnetListener { log::debug!("IpPacketRouter [main loop]: received shutdown"); }, _ = disconnect_timer.tick() => { - self.handle_disconnect_timer(); + self.handle_disconnect_timer().await; }, msg = self.mixnet_client.next() => { if let Some(msg) = msg { @@ -642,9 +692,9 @@ pub(crate) enum ConnectedClientEvent { Connect(Box<ConnectEvent>), } -pub(crate) struct DisconnectEvent(pub(crate) IpAddr); +pub(crate) struct DisconnectEvent(pub(crate) IPPair); pub(crate) struct ConnectEvent { - pub(crate) ip: IpAddr, + pub(crate) ips: IPPair, pub(crate) forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, } diff --git a/service-providers/ip-packet-router/src/tun_listener.rs b/service-providers/ip-packet-router/src/tun_listener.rs index 34fb12526e..8d2ba41371 100644 --- a/service-providers/ip-packet-router/src/tun_listener.rs +++ b/service-providers/ip-packet-router/src/tun_listener.rs @@ -1,5 +1,7 @@ -use std::{collections::HashMap, net::IpAddr}; +use std::collections::HashMap; +use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; +use nym_ip_packet_requests::IPPair; use nym_task::TaskClient; #[cfg(target_os = "linux")] use tokio::io::AsyncReadExt; @@ -15,10 +17,12 @@ use crate::{ // It's even ok if this is slightly out of date pub(crate) struct ConnectedClientMirror { pub(crate) forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, + pub(crate) ips: IPPair, } pub(crate) struct ConnectedClientsListener { - clients: HashMap<IpAddr, ConnectedClientMirror>, + clients_ipv4: HashMap<Ipv4Addr, ConnectedClientMirror>, + clients_ipv6: HashMap<Ipv6Addr, ConnectedClientMirror>, connected_client_rx: tokio::sync::mpsc::UnboundedReceiver<mixnet_listener::ConnectedClientEvent>, } @@ -30,35 +34,48 @@ impl ConnectedClientsListener { >, ) -> Self { ConnectedClientsListener { - clients: HashMap::new(), + clients_ipv4: HashMap::new(), + clients_ipv6: HashMap::new(), connected_client_rx, } } pub(crate) fn get(&self, ip: &IpAddr) -> Option<&ConnectedClientMirror> { - self.clients.get(ip) + match ip { + IpAddr::V4(ip) => self.clients_ipv4.get(ip), + IpAddr::V6(ip) => self.clients_ipv6.get(ip), + } } pub(crate) fn update(&mut self, event: mixnet_listener::ConnectedClientEvent) { match event { mixnet_listener::ConnectedClientEvent::Connect(connected_event) => { let mixnet_listener::ConnectEvent { - ip, + ips, forward_from_tun_tx, } = *connected_event; - log::trace!("Connect client: {ip}"); - self.clients.insert( - ip, + log::trace!("Connect client: {ips}"); + self.clients_ipv4.insert( + ips.ipv4, + ConnectedClientMirror { + forward_from_tun_tx: forward_from_tun_tx.clone(), + ips, + }, + ); + self.clients_ipv6.insert( + ips.ipv6, ConnectedClientMirror { forward_from_tun_tx, + ips, }, ); } mixnet_listener::ConnectedClientEvent::Disconnect( - mixnet_listener::DisconnectEvent(ip), + mixnet_listener::DisconnectEvent(ips), ) => { - log::trace!("Disconnect client: {ip}"); - self.clients.remove(&ip); + log::trace!("Disconnect client: {ips}"); + self.clients_ipv4.remove(&ips.ipv4); + self.clients_ipv6.remove(&ips.ipv6); } } } @@ -82,6 +99,7 @@ impl TunListener { if let Some(ConnectedClientMirror { forward_from_tun_tx, + ips, }) = self.connected_clients.get(&dst_addr) { let packet = buf[..len].to_vec(); @@ -89,7 +107,7 @@ impl TunListener { log::warn!("Failed to forward packet to connected client {dst_addr}: disconnecting it from tun listener"); self.connected_clients .update(mixnet_listener::ConnectedClientEvent::Disconnect( - mixnet_listener::DisconnectEvent(dst_addr), + mixnet_listener::DisconnectEvent(*ips), )); } } else { diff --git a/service-providers/ip-packet-router/src/util/generate_new_ip.rs b/service-providers/ip-packet-router/src/util/generate_new_ip.rs index 5824ce7bba..8e7a688853 100644 --- a/service-providers/ip-packet-router/src/util/generate_new_ip.rs +++ b/service-providers/ip-packet-router/src/util/generate_new_ip.rs @@ -1,38 +1,55 @@ -use std::{ - collections::HashMap, - net::{IpAddr, Ipv4Addr}, -}; +use nym_ip_packet_requests::IPPair; +use std::net::Ipv6Addr; +use std::{collections::HashMap, net::Ipv4Addr}; -use crate::{constants::TUN_DEVICE_ADDRESS, mixnet_listener::ConnectedClient}; +use crate::constants::{TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6}; // Find an available IP address in self.connected_clients // TODO: make this nicer -fn generate_random_ip_within_subnet() -> Ipv4Addr { +fn generate_random_ips_within_subnet() -> IPPair { let mut rng = rand::thread_rng(); // Generate a random number in the range 1-254 let last_octet = rand::Rng::gen_range(&mut rng, 1..=254); - Ipv4Addr::new(10, 0, 0, last_octet) + let ipv4 = Ipv4Addr::new(10, 0, 0, last_octet); + let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_octet as u16); + IPPair { ipv4, ipv6 } } -fn is_ip_taken( - connected_clients: &HashMap<IpAddr, ConnectedClient>, - tun_ip: Ipv4Addr, - ip: Ipv4Addr, +fn is_ip_taken<T>( + connected_clients_ipv4: &HashMap<Ipv4Addr, T>, + connected_clients_ipv6: &HashMap<Ipv6Addr, T>, + tun_ips: IPPair, + ips: IPPair, ) -> bool { - connected_clients.contains_key(&ip.into()) || ip == tun_ip + connected_clients_ipv4.contains_key(&ips.ipv4) + || connected_clients_ipv6.contains_key(&ips.ipv6) + || ips.ipv4 == tun_ips.ipv4 + || ips.ipv6 == tun_ips.ipv6 } // TODO: brute force approach. We could consider using a more efficient algorithm -pub(crate) fn find_new_ip(connected_clients: &HashMap<IpAddr, ConnectedClient>) -> Option<IpAddr> { - let mut new_ip = generate_random_ip_within_subnet(); +pub(crate) fn find_new_ips<T>( + connected_clients_ipv4: &HashMap<Ipv4Addr, T>, + connected_clients_ipv6: &HashMap<Ipv6Addr, T>, +) -> Option<IPPair> { + let mut new_ips = generate_random_ips_within_subnet(); let mut tries = 0; - let tun_ip = TUN_DEVICE_ADDRESS.parse::<Ipv4Addr>().unwrap(); - while is_ip_taken(connected_clients, tun_ip, new_ip) { - new_ip = generate_random_ip_within_subnet(); + let tun_ips = IPPair { + ipv4: TUN_DEVICE_ADDRESS_V4, + ipv6: TUN_DEVICE_ADDRESS_V6, + }; + + while is_ip_taken( + connected_clients_ipv4, + connected_clients_ipv6, + tun_ips, + new_ips, + ) { + new_ips = generate_random_ips_within_subnet(); tries += 1; if tries > 100 { return None; } } - Some(new_ip.into()) + Some(new_ips) } From f5d9fda0b153591ac84bace7e872ccebe23a7bd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 4 Mar 2024 09:38:29 +0000 Subject: [PATCH 150/394] moved and renamed nym-id to nym-id-cli --- Cargo.lock | 2 +- Cargo.toml | 4 +++- {nym-id => tools/nym-id-cli}/Cargo.toml | 8 ++++---- {nym-id => tools/nym-id-cli}/src/commands/build_info.rs | 0 .../nym-id-cli}/src/commands/import_credential.rs | 0 {nym-id => tools/nym-id-cli}/src/commands/mod.rs | 0 {nym-id => tools/nym-id-cli}/src/commands/setup.rs | 0 {nym-id => tools/nym-id-cli}/src/main.rs | 0 8 files changed, 8 insertions(+), 6 deletions(-) rename {nym-id => tools/nym-id-cli}/Cargo.toml (67%) rename {nym-id => tools/nym-id-cli}/src/commands/build_info.rs (100%) rename {nym-id => tools/nym-id-cli}/src/commands/import_credential.rs (100%) rename {nym-id => tools/nym-id-cli}/src/commands/mod.rs (100%) rename {nym-id => tools/nym-id-cli}/src/commands/setup.rs (100%) rename {nym-id => tools/nym-id-cli}/src/main.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 2bd734b3f6..0dc8ab742c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5629,7 +5629,7 @@ dependencies = [ ] [[package]] -name = "nym-id" +name = "nym-id-cli" version = "0.1.0" dependencies = [ "anyhow", diff --git a/Cargo.toml b/Cargo.toml index 0f369f0a80..f479a81f57 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,6 +56,7 @@ members = [ "common/node-tester-utils", "common/nonexhaustive-delayqueue", "common/nymcoconut", + "common/nym-id-lib", "common/nymsphinx", "common/nymsphinx/acknowledgements", "common/nymsphinx/addressing", @@ -106,13 +107,14 @@ members = [ "tools/internal/ssl-inject", # "tools/internal/sdk-version-bump", "tools/nym-cli", + "tools/nym-id-cli", "tools/nym-nr-query", "tools/nymvisor", "tools/ts-rs-cli", "wasm/client", # "wasm/full-nym-wasm", "wasm/mix-fetch", - "wasm/node-tester", "nym-id", "common/nym-id-lib", + "wasm/node-tester", ] default-members = [ diff --git a/nym-id/Cargo.toml b/tools/nym-id-cli/Cargo.toml similarity index 67% rename from nym-id/Cargo.toml rename to tools/nym-id-cli/Cargo.toml index 49da695276..c57404397a 100644 --- a/nym-id/Cargo.toml +++ b/tools/nym-id-cli/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "nym-id" +name = "nym-id-cli" version = "0.1.0" authors.workspace = true repository.workspace = true @@ -17,6 +17,6 @@ clap = { workspace = true, features = ["derive"] } tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } tracing.workspace = true -nym-bin-common = { path = "../common/bin-common", features = ["output_format", "basic_tracing"] } -nym-credential-storage = { path = "../common/credential-storage" } -nym-id-lib = { path = "../common/nym-id-lib" } +nym-bin-common = { path = "../../common/bin-common", features = ["output_format", "basic_tracing"] } +nym-credential-storage = { path = "../../common/credential-storage" } +nym-id-lib = { path = "../../common/nym-id-lib" } diff --git a/nym-id/src/commands/build_info.rs b/tools/nym-id-cli/src/commands/build_info.rs similarity index 100% rename from nym-id/src/commands/build_info.rs rename to tools/nym-id-cli/src/commands/build_info.rs diff --git a/nym-id/src/commands/import_credential.rs b/tools/nym-id-cli/src/commands/import_credential.rs similarity index 100% rename from nym-id/src/commands/import_credential.rs rename to tools/nym-id-cli/src/commands/import_credential.rs diff --git a/nym-id/src/commands/mod.rs b/tools/nym-id-cli/src/commands/mod.rs similarity index 100% rename from nym-id/src/commands/mod.rs rename to tools/nym-id-cli/src/commands/mod.rs diff --git a/nym-id/src/commands/setup.rs b/tools/nym-id-cli/src/commands/setup.rs similarity index 100% rename from nym-id/src/commands/setup.rs rename to tools/nym-id-cli/src/commands/setup.rs diff --git a/nym-id/src/main.rs b/tools/nym-id-cli/src/main.rs similarity index 100% rename from nym-id/src/main.rs rename to tools/nym-id-cli/src/main.rs From a04a782dbf7c5ca5b989d5e93821f95ff8587717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 4 Mar 2024 09:40:11 +0000 Subject: [PATCH 151/394] renamed nym-id-lib to nym-id --- Cargo.lock | 38 +++++++++---------- Cargo.toml | 2 +- clients/native/Cargo.toml | 2 +- .../native/src/commands/import_credential.rs | 2 +- clients/native/src/error.rs | 2 +- clients/socks5/Cargo.toml | 2 +- .../socks5/src/commands/import_credential.rs | 2 +- clients/socks5/src/error.rs | 2 +- common/commands/Cargo.toml | 2 +- .../commands/src/coconut/import_credential.rs | 2 +- common/{nym-id-lib => nym-id}/Cargo.toml | 2 +- common/{nym-id-lib => nym-id}/src/error.rs | 0 .../src/import_credential.rs | 0 common/{nym-id-lib => nym-id}/src/lib.rs | 0 .../network-requester/Cargo.toml | 2 +- .../src/cli/import_credential.rs | 2 +- .../network-requester/src/error.rs | 2 +- tools/nym-id-cli/Cargo.toml | 2 +- .../src/commands/import_credential.rs | 2 +- 19 files changed, 34 insertions(+), 34 deletions(-) rename common/{nym-id-lib => nym-id}/Cargo.toml (96%) rename common/{nym-id-lib => nym-id}/src/error.rs (100%) rename common/{nym-id-lib => nym-id}/src/import_credential.rs (100%) rename common/{nym-id-lib => nym-id}/src/lib.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index 0dc8ab742c..c3df2e1c05 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5128,7 +5128,7 @@ dependencies = [ "nym-credentials", "nym-credentials-interface", "nym-crypto", - "nym-id-lib", + "nym-id", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -5169,7 +5169,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-gateway-requests", - "nym-id-lib", + "nym-id", "nym-network-defaults", "nym-pemstore", "nym-sphinx", @@ -5629,21 +5629,7 @@ dependencies = [ ] [[package]] -name = "nym-id-cli" -version = "0.1.0" -dependencies = [ - "anyhow", - "bs58 0.5.0", - "clap 4.4.7", - "nym-bin-common", - "nym-credential-storage", - "nym-id-lib", - "tokio", - "tracing", -] - -[[package]] -name = "nym-id-lib" +name = "nym-id" version = "0.1.0" dependencies = [ "nym-credential-storage", @@ -5654,6 +5640,20 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-id-cli" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "clap 4.4.7", + "nym-bin-common", + "nym-credential-storage", + "nym-id", + "tokio", + "tracing", +] + [[package]] name = "nym-inclusion-probability" version = "0.1.0" @@ -5892,7 +5892,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-exit-policy", - "nym-id-lib", + "nym-id", "nym-network-defaults", "nym-ordered-buffer", "nym-sdk", @@ -6180,7 +6180,7 @@ dependencies = [ "nym-credentials", "nym-crypto", "nym-gateway-requests", - "nym-id-lib", + "nym-id", "nym-network-defaults", "nym-ordered-buffer", "nym-pemstore", diff --git a/Cargo.toml b/Cargo.toml index f479a81f57..d67b66149a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -56,7 +56,7 @@ members = [ "common/node-tester-utils", "common/nonexhaustive-delayqueue", "common/nymcoconut", - "common/nym-id-lib", + "common/nym-id", "common/nymsphinx", "common/nymsphinx/acknowledgements", "common/nymsphinx/addressing", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 9da09cd0d0..a85b73e5a4 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -51,6 +51,6 @@ nym-task = { path = "../../common/task" } nym-topology = { path = "../../common/topology" } nym-validator-client = { path = "../../common/client-libs/validator-client", features = ["http-client"] } nym-client-websocket-requests = { path = "websocket-requests" } -nym-id-lib = { path = "../../common/nym-id-lib" } +nym-id = { path = "../../common/nym-id" } [dev-dependencies] diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index aac7feaa64..8554f74ee7 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -5,7 +5,7 @@ use crate::commands::try_load_current_config; use crate::error::ClientError; use clap::ArgGroup; -use nym_id_lib::import_credential; +use nym_id::import_credential; use std::fs; use std::path::PathBuf; diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index b4f47cf90b..33daa1247d 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -1,6 +1,6 @@ use nym_client_core::error::ClientCoreError; -use nym_id_lib::NymIdError; +use nym_id::NymIdError; #[derive(thiserror::Error, Debug)] pub enum ClientError { diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 0af4c34770..2665f6355c 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -35,7 +35,7 @@ nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" } nym-pemstore = { path = "../../common/pemstore" } nym-topology = { path = "../../common/topology" } nym-socks5-client-core = { path = "../../common/socks5-client-core" } -nym-id-lib = { path = "../../common/nym-id-lib" } +nym-id = { path = "../../common/nym-id" } [features] default = [] diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index 25285870f8..8a13e799d3 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -5,7 +5,7 @@ use crate::commands::try_load_current_config; use crate::error::Socks5ClientError; use clap::ArgGroup; -use nym_id_lib::import_credential; +use nym_id::import_credential; use std::fs; use std::path::PathBuf; diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index 788d1250f8..de40ccfefa 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -1,6 +1,6 @@ use nym_client_core::error::ClientCoreError; -use nym_id_lib::NymIdError; +use nym_id::NymIdError; #[derive(thiserror::Error, Debug)] pub enum Socks5ClientError { diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index dba6b7a9b5..6c96a3f93d 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -55,7 +55,7 @@ nym-credentials = { path = "../../common/credentials" } nym-credentials-interface = { path = "../../common/credentials-interface" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credential-utils = { path = "../../common/credential-utils" } -nym-id-lib = { path = "../../common/nym-id-lib" } +nym-id = { path = "../nym-id" } nym-pemstore = { path = "../../common/pemstore", version = "0.3.0" } nym-types = { path = "../../common/types" } diff --git a/common/commands/src/coconut/import_credential.rs b/common/commands/src/coconut/import_credential.rs index 388961ace4..852f94e34a 100644 --- a/common/commands/src/coconut/import_credential.rs +++ b/common/commands/src/coconut/import_credential.rs @@ -6,7 +6,7 @@ use anyhow::bail; use clap::ArgGroup; use clap::Parser; use nym_credential_storage::initialise_persistent_storage; -use nym_id_lib::import_credential; +use nym_id::import_credential; use std::fs; use std::path::PathBuf; diff --git a/common/nym-id-lib/Cargo.toml b/common/nym-id/Cargo.toml similarity index 96% rename from common/nym-id-lib/Cargo.toml rename to common/nym-id/Cargo.toml index 3114f0eded..eb80073fb7 100644 --- a/common/nym-id-lib/Cargo.toml +++ b/common/nym-id/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "nym-id-lib" +name = "nym-id" version = "0.1.0" authors.workspace = true repository.workspace = true diff --git a/common/nym-id-lib/src/error.rs b/common/nym-id/src/error.rs similarity index 100% rename from common/nym-id-lib/src/error.rs rename to common/nym-id/src/error.rs diff --git a/common/nym-id-lib/src/import_credential.rs b/common/nym-id/src/import_credential.rs similarity index 100% rename from common/nym-id-lib/src/import_credential.rs rename to common/nym-id/src/import_credential.rs diff --git a/common/nym-id-lib/src/lib.rs b/common/nym-id/src/lib.rs similarity index 100% rename from common/nym-id-lib/src/lib.rs rename to common/nym-id/src/lib.rs diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 65ca6c2aa3..ac8d641719 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -61,7 +61,7 @@ nym-statistics-common = { path = "../../common/statistics" } nym-task = { path = "../../common/task" } nym-types = { path = "../../common/types" } nym-exit-policy = { path = "../../common/exit-policy", features = ["client"] } -nym-id-lib = { path = "../../common/nym-id-lib" } +nym-id = { path = "../../common/nym-id" } [dev-dependencies] tempfile = "3.5.0" diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index 1fe0d3de52..d46b0442bf 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -5,7 +5,7 @@ use crate::cli::try_load_current_config; use crate::error::NetworkRequesterError; use clap::ArgGroup; -use nym_id_lib::import_credential; +use nym_id::import_credential; use std::fs; use std::path::PathBuf; diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index 0143494696..048ca2a5d2 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -4,7 +4,7 @@ pub use nym_client_core::error::ClientCoreError; use nym_exit_policy::policy::PolicyError; -use nym_id_lib::NymIdError; +use nym_id::NymIdError; use nym_socks5_requests::{RemoteAddress, Socks5RequestError}; use std::net::SocketAddr; diff --git a/tools/nym-id-cli/Cargo.toml b/tools/nym-id-cli/Cargo.toml index c57404397a..bada736bfd 100644 --- a/tools/nym-id-cli/Cargo.toml +++ b/tools/nym-id-cli/Cargo.toml @@ -19,4 +19,4 @@ tracing.workspace = true nym-bin-common = { path = "../../common/bin-common", features = ["output_format", "basic_tracing"] } nym-credential-storage = { path = "../../common/credential-storage" } -nym-id-lib = { path = "../../common/nym-id-lib" } +nym-id = { path = "../../common/nym-id" } diff --git a/tools/nym-id-cli/src/commands/import_credential.rs b/tools/nym-id-cli/src/commands/import_credential.rs index 9422a34e8d..e04bb89af5 100644 --- a/tools/nym-id-cli/src/commands/import_credential.rs +++ b/tools/nym-id-cli/src/commands/import_credential.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use clap::ArgGroup; -use nym_id_lib::import_credential; +use nym_id::import_credential; use std::fs; use std::path::PathBuf; From d3ba008b88131124f458f603a60a8351848cec9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= <bogdan@nymtech.net> Date: Mon, 4 Mar 2024 12:56:10 +0200 Subject: [PATCH 152/394] Add IPPair constructor (#4440) * Add IPPair constructor * Rename --- common/ip-packet-requests/src/lib.rs | 15 ++++++- common/ip-packet-requests/src/request.rs | 19 ++------- common/ip-packet-requests/src/response.rs | 6 +-- .../ip-packet-router/src/mixnet_listener.rs | 39 +++++++------------ .../ip-packet-router/src/tun_listener.rs | 4 +- .../src/util/generate_new_ip.rs | 17 ++++---- 6 files changed, 45 insertions(+), 55 deletions(-) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index f61e3f266f..f3de2fb675 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -1,4 +1,5 @@ use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; use std::net::{Ipv4Addr, Ipv6Addr}; pub mod codec; @@ -10,11 +11,23 @@ pub mod response; pub const CURRENT_VERSION: u8 = 4; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] -pub struct IPPair { +pub struct IpPair { pub ipv4: Ipv4Addr, pub ipv6: Ipv6Addr, } +impl IpPair { + pub fn new(ipv4: Ipv4Addr, ipv6: Ipv6Addr) -> Self { + IpPair { ipv4, ipv6 } + } +} + +impl Display for IpPair { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + writeln!(f, "IPv4: {}, IPV6: {}", self.ipv4, self.ipv6) + } +} + fn make_bincode_serializer() -> impl bincode::Options { use bincode::Options; bincode::DefaultOptions::new() diff --git a/common/ip-packet-requests/src/request.rs b/common/ip-packet-requests/src/request.rs index 011ff5bfe6..9f59b8ba0e 100644 --- a/common/ip-packet-requests/src/request.rs +++ b/common/ip-packet-requests/src/request.rs @@ -1,15 +1,7 @@ -use std::fmt::{Display, Formatter}; - use nym_sphinx::addressing::clients::Recipient; use serde::{Deserialize, Serialize}; -use crate::{make_bincode_serializer, IPPair, CURRENT_VERSION}; - -impl Display for IPPair { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - writeln!(f, "IPv4: {}, IPV6: {}", self.ipv4, self.ipv6) - } -} +use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; fn generate_random() -> u64 { use rand::RngCore; @@ -25,7 +17,7 @@ pub struct IpPacketRequest { impl IpPacketRequest { pub fn new_static_connect_request( - ips: IPPair, + ips: IpPair, reply_to: Recipient, reply_to_hops: Option<u8>, reply_to_avg_mix_delays: Option<f64>, @@ -143,7 +135,7 @@ pub enum IpPacketRequestData { pub struct StaticConnectRequest { pub request_id: u64, - pub ips: IPPair, + pub ips: IpPair, // The nym-address the response should be sent back to pub reply_to: Recipient, @@ -226,10 +218,7 @@ mod tests { data: IpPacketRequestData::StaticConnect( StaticConnectRequest { request_id: 123, - ips: IPPair { - ipv4: Ipv4Addr::from_str("10.0.0.1").unwrap(), - ipv6: Ipv6Addr::from_str("2001:db8:a160::1").unwrap(), - }, + ips: IpPair::new(Ipv4Addr::from_str("10.0.0.1").unwrap(), Ipv6Addr::from_str("2001:db8:a160::1").unwrap()), reply_to: Recipient::try_from_base58_string("D1rrpsysCGCYXy9saP8y3kmNpGtJZUXN9SvFoUcqAsM9.9Ssso1ea5NfkbMASdiseDSjTN1fSWda5SgEVjdSN4CvV@GJqd3ZxpXWSNxTfx7B1pPtswpetH4LnJdFeLeuY5KUuN").unwrap(), reply_to_hops: None, reply_to_avg_mix_delays: None, diff --git a/common/ip-packet-requests/src/response.rs b/common/ip-packet-requests/src/response.rs index 91972a35a3..b07f1a97af 100644 --- a/common/ip-packet-requests/src/response.rs +++ b/common/ip-packet-requests/src/response.rs @@ -1,7 +1,7 @@ use nym_sphinx::addressing::clients::Recipient; use serde::{Deserialize, Serialize}; -use crate::{make_bincode_serializer, IPPair, CURRENT_VERSION}; +use crate::{make_bincode_serializer, IpPair, CURRENT_VERSION}; #[derive(Clone, Debug, Serialize, Deserialize)] pub struct IpPacketResponse { @@ -36,7 +36,7 @@ impl IpPacketResponse { } } - pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IPPair) -> Self { + pub fn new_dynamic_connect_success(request_id: u64, reply_to: Recipient, ips: IpPair) -> Self { Self { version: CURRENT_VERSION, data: IpPacketResponseData::DynamicConnect(DynamicConnectResponse { @@ -261,7 +261,7 @@ impl DynamicConnectResponseReply { #[derive(Clone, Debug, Serialize, Deserialize)] pub struct DynamicConnectSuccess { - pub ips: IPPair, + pub ips: IpPair, } #[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)] diff --git a/service-providers/ip-packet-router/src/mixnet_listener.rs b/service-providers/ip-packet-router/src/mixnet_listener.rs index 813c4b2e52..af3c7214f0 100644 --- a/service-providers/ip-packet-router/src/mixnet_listener.rs +++ b/service-providers/ip-packet-router/src/mixnet_listener.rs @@ -11,7 +11,7 @@ use nym_ip_packet_requests::{ DynamicConnectFailureReason, ErrorResponseReply, IpPacketResponse, StaticConnectFailureReason, }, - IPPair, + IpPair, }; use nym_sdk::mixnet::{MixnetMessageSender, Recipient}; use nym_sphinx::receiver::ReconstructedMessage; @@ -58,7 +58,7 @@ impl ConnectedClients { ) } - fn is_ip_connected(&self, ips: &IPPair) -> bool { + fn is_ip_connected(&self, ips: &IpPair) -> bool { self.clients_ipv4_mapping.contains_key(&ips.ipv4) || self.clients_ipv6_mapping.contains_key(&ips.ipv6) } @@ -76,15 +76,12 @@ impl ConnectedClients { .any(|client| client.nym_address == *nym_address) } - fn lookup_ip_from_nym_address(&self, nym_address: &Recipient) -> Option<IPPair> { + fn lookup_ip_from_nym_address(&self, nym_address: &Recipient) -> Option<IpPair> { self.clients_ipv4_mapping .iter() .find_map(|(ipv4, connected_client)| { if connected_client.nym_address == *nym_address { - Some(IPPair { - ipv4: *ipv4, - ipv6: connected_client.ipv6, - }) + Some(IpPair::new(*ipv4, connected_client.ipv6)) } else { None } @@ -105,7 +102,7 @@ impl ConnectedClients { fn connect( &mut self, - ips: IPPair, + ips: IpPair, nym_address: Recipient, mix_hops: Option<u8>, forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, @@ -141,7 +138,7 @@ impl ConnectedClients { .ok(); } - async fn update_activity(&mut self, ips: &IPPair) -> Result<()> { + async fn update_activity(&mut self, ips: &IpPair) -> Result<()> { if let Some(client) = self.clients_ipv4_mapping.get(&ips.ipv4) { *client.last_activity.write().await = std::time::Instant::now(); Ok(()) @@ -151,16 +148,13 @@ impl ConnectedClients { } // Identify connected client handlers that have stopped without being told to stop - fn get_finished_client_handlers(&mut self) -> Vec<(IPPair, Recipient)> { + fn get_finished_client_handlers(&mut self) -> Vec<(IpPair, Recipient)> { self.clients_ipv4_mapping .iter_mut() .filter_map(|(ip, connected_client)| { if connected_client.handle.is_finished() { Some(( - IPPair { - ipv4: *ip, - ipv6: connected_client.ipv6, - }, + IpPair::new(*ip, connected_client.ipv6), connected_client.nym_address, )) } else { @@ -170,7 +164,7 @@ impl ConnectedClients { .collect() } - async fn get_inactive_clients(&mut self) -> Vec<(IPPair, Recipient)> { + async fn get_inactive_clients(&mut self) -> Vec<(IpPair, Recipient)> { let now = std::time::Instant::now(); let mut ret = vec![]; for (ip, connected_client) in self.clients_ipv4_mapping.iter() { @@ -178,10 +172,7 @@ impl ConnectedClients { > CLIENT_MIXNET_INACTIVITY_TIMEOUT { ret.push(( - IPPair { - ipv4: *ip, - ipv6: connected_client.ipv6, - }, + IpPair::new(*ip, connected_client.ipv6), connected_client.nym_address, )) } @@ -189,7 +180,7 @@ impl ConnectedClients { ret } - fn disconnect_stopped_client_handlers(&mut self, stopped_clients: Vec<(IPPair, Recipient)>) { + fn disconnect_stopped_client_handlers(&mut self, stopped_clients: Vec<(IpPair, Recipient)>) { for (ips, _) in &stopped_clients { log::info!("Disconnect stopped client: {ips}"); self.clients_ipv4_mapping.remove(&ips.ipv4); @@ -203,7 +194,7 @@ impl ConnectedClients { } } - fn disconnect_inactive_clients(&mut self, inactive_clients: Vec<(IPPair, Recipient)>) { + fn disconnect_inactive_clients(&mut self, inactive_clients: Vec<(IpPair, Recipient)>) { for (ips, _) in &inactive_clients { log::info!("Disconnect inactive client: {ips}"); self.clients_ipv4_mapping.remove(&ips.ipv4); @@ -217,7 +208,7 @@ impl ConnectedClients { } } - fn find_new_ip(&self) -> Option<IPPair> { + fn find_new_ip(&self) -> Option<IpPair> { generate_new_ip::find_new_ips(&self.clients_ipv4_mapping, &self.clients_ipv6_mapping) } } @@ -692,9 +683,9 @@ pub(crate) enum ConnectedClientEvent { Connect(Box<ConnectEvent>), } -pub(crate) struct DisconnectEvent(pub(crate) IPPair); +pub(crate) struct DisconnectEvent(pub(crate) IpPair); pub(crate) struct ConnectEvent { - pub(crate) ips: IPPair, + pub(crate) ips: IpPair, pub(crate) forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, } diff --git a/service-providers/ip-packet-router/src/tun_listener.rs b/service-providers/ip-packet-router/src/tun_listener.rs index 8d2ba41371..ce3a70ca68 100644 --- a/service-providers/ip-packet-router/src/tun_listener.rs +++ b/service-providers/ip-packet-router/src/tun_listener.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; -use nym_ip_packet_requests::IPPair; +use nym_ip_packet_requests::IpPair; use nym_task::TaskClient; #[cfg(target_os = "linux")] use tokio::io::AsyncReadExt; @@ -17,7 +17,7 @@ use crate::{ // It's even ok if this is slightly out of date pub(crate) struct ConnectedClientMirror { pub(crate) forward_from_tun_tx: tokio::sync::mpsc::UnboundedSender<Vec<u8>>, - pub(crate) ips: IPPair, + pub(crate) ips: IpPair, } pub(crate) struct ConnectedClientsListener { diff --git a/service-providers/ip-packet-router/src/util/generate_new_ip.rs b/service-providers/ip-packet-router/src/util/generate_new_ip.rs index 8e7a688853..71809cac00 100644 --- a/service-providers/ip-packet-router/src/util/generate_new_ip.rs +++ b/service-providers/ip-packet-router/src/util/generate_new_ip.rs @@ -1,4 +1,4 @@ -use nym_ip_packet_requests::IPPair; +use nym_ip_packet_requests::IpPair; use std::net::Ipv6Addr; use std::{collections::HashMap, net::Ipv4Addr}; @@ -6,20 +6,20 @@ use crate::constants::{TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6}; // Find an available IP address in self.connected_clients // TODO: make this nicer -fn generate_random_ips_within_subnet() -> IPPair { +fn generate_random_ips_within_subnet() -> IpPair { let mut rng = rand::thread_rng(); // Generate a random number in the range 1-254 let last_octet = rand::Rng::gen_range(&mut rng, 1..=254); let ipv4 = Ipv4Addr::new(10, 0, 0, last_octet); let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_octet as u16); - IPPair { ipv4, ipv6 } + IpPair::new(ipv4, ipv6) } fn is_ip_taken<T>( connected_clients_ipv4: &HashMap<Ipv4Addr, T>, connected_clients_ipv6: &HashMap<Ipv6Addr, T>, - tun_ips: IPPair, - ips: IPPair, + tun_ips: IpPair, + ips: IpPair, ) -> bool { connected_clients_ipv4.contains_key(&ips.ipv4) || connected_clients_ipv6.contains_key(&ips.ipv6) @@ -31,13 +31,10 @@ fn is_ip_taken<T>( pub(crate) fn find_new_ips<T>( connected_clients_ipv4: &HashMap<Ipv4Addr, T>, connected_clients_ipv6: &HashMap<Ipv6Addr, T>, -) -> Option<IPPair> { +) -> Option<IpPair> { let mut new_ips = generate_random_ips_within_subnet(); let mut tries = 0; - let tun_ips = IPPair { - ipv4: TUN_DEVICE_ADDRESS_V4, - ipv6: TUN_DEVICE_ADDRESS_V6, - }; + let tun_ips = IpPair::new(TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6); while is_ip_taken( connected_clients_ipv4, From 5b35cfcfb2ce7a89f5a7cfac85c5d84d22ed475d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 4 Mar 2024 11:16:48 +0000 Subject: [PATCH 153/394] build-information: pick up vergen from consuming crate (#4424) --- .../bin-common/src/build_information/mod.rs | 59 +++++++++++++++++++ 1 file changed, 59 insertions(+) diff --git a/common/bin-common/src/build_information/mod.rs b/common/bin-common/src/build_information/mod.rs index a29e5ccf29..7b1a9d3321 100644 --- a/common/bin-common/src/build_information/mod.rs +++ b/common/bin-common/src/build_information/mod.rs @@ -69,6 +69,35 @@ impl BinaryBuildInformation { } } + // Varient where we want to use the metadata generated by vergen in the consuming crate. + pub const fn new_with_local_vergen( + binary_name: &'static str, + build_timestamp: &'static str, + build_version: &'static str, + commit_sha: &'static str, + commit_timestamp: &'static str, + commit_branch: &'static str, + ) -> Self { + let cargo_debug = env!("VERGEN_CARGO_DEBUG"); + let cargo_profile = if const_str::equal!(cargo_debug, "true") { + "debug" + } else { + "release" + }; + + BinaryBuildInformation { + binary_name, + build_timestamp, + build_version, + commit_sha, + commit_timestamp, + commit_branch, + rustc_version: env!("VERGEN_RUSTC_SEMVER"), + rustc_channel: env!("VERGEN_RUSTC_CHANNEL"), + cargo_profile, + } + } + pub fn to_owned(&self) -> BinaryBuildInformationOwned { BinaryBuildInformationOwned { binary_name: self.binary_name.to_owned(), @@ -187,3 +216,33 @@ macro_rules! bin_info_owned { .to_owned() }; } + +// variant that picks up the vergen build information generated by the build.rs in the consumer +// crate. +#[macro_export] +macro_rules! bin_info_local_vergen { + () => { + $crate::build_information::BinaryBuildInformation::new_vergen( + env!("CARGO_PKG_NAME"), + env!("VERGEN_BUILD_TIMESTAMP"), + env!("CARGO_PKG_VERSION"), + env!("VERGEN_GIT_SHA"), + env!("VERGEN_GIT_COMMIT_TIMESTAMP"), + env!("VERGEN_GIT_BRANCH"), + ) + }; +} + +#[macro_export] +macro_rules! bin_info_local_vergen_owned { + () => { + $crate::build_information::BinaryBuildInformation::new_vergen( + env!("CARGO_PKG_NAME"), + env!("VERGEN_BUILD_TIMESTAMP"), + env!("CARGO_PKG_VERSION"), + env!("VERGEN_GIT_SHA"), + env!("VERGEN_GIT_COMMIT_TIMESTAMP"), + env!("VERGEN_GIT_BRANCH"), + ) + }; +} From bd0cbbc18a305624a684473385f466cc086cdd5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 4 Mar 2024 13:48:43 +0000 Subject: [PATCH 154/394] Fix typo in macro invocation (#4441) --- common/bin-common/src/build_information/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/bin-common/src/build_information/mod.rs b/common/bin-common/src/build_information/mod.rs index 7b1a9d3321..90d495c288 100644 --- a/common/bin-common/src/build_information/mod.rs +++ b/common/bin-common/src/build_information/mod.rs @@ -222,7 +222,7 @@ macro_rules! bin_info_owned { #[macro_export] macro_rules! bin_info_local_vergen { () => { - $crate::build_information::BinaryBuildInformation::new_vergen( + $crate::build_information::BinaryBuildInformation::new_with_local_vergen( env!("CARGO_PKG_NAME"), env!("VERGEN_BUILD_TIMESTAMP"), env!("CARGO_PKG_VERSION"), @@ -236,7 +236,7 @@ macro_rules! bin_info_local_vergen { #[macro_export] macro_rules! bin_info_local_vergen_owned { () => { - $crate::build_information::BinaryBuildInformation::new_vergen( + $crate::build_information::BinaryBuildInformation::new_with_local_vergen( env!("CARGO_PKG_NAME"), env!("VERGEN_BUILD_TIMESTAMP"), env!("CARGO_PKG_VERSION"), From 154dfa089b773b777251ba3416311af5105ca952 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Tue, 5 Mar 2024 15:07:38 +0000 Subject: [PATCH 155/394] [DOC]: Hotfix - remove unexisting page (#4438) * [DOC]: Hotfix - remove unexisting page * update modules and run build * installed with nvm 18 * yarn version solved * remove extra files * attempt to resolve module versioning * Update package versions and fix keplr example --------- Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com> --- .../docs/components/cosmos-kit/index.tsx | 2 +- sdk/typescript/docs/package.json | 21 ++++++++++--------- sdk/typescript/docs/pages/integrations.mdx | 1 - 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sdk/typescript/docs/components/cosmos-kit/index.tsx b/sdk/typescript/docs/components/cosmos-kit/index.tsx index c7d5abbf56..0f575ec77a 100644 --- a/sdk/typescript/docs/components/cosmos-kit/index.tsx +++ b/sdk/typescript/docs/components/cosmos-kit/index.tsx @@ -1,7 +1,7 @@ import React, { FC } from 'react'; import { ChainProvider, useChain } from '@cosmos-kit/react'; import { assets, chains } from 'chain-registry'; -import { wallets as keplr } from '@cosmos-kit/keplr'; +import { wallets as keplr } from '@cosmos-kit/keplr-extension'; import { wallets as ledger } from '@cosmos-kit/ledger'; import Button from '@mui/material/Button'; import CircularProgress from '@mui/material/CircularProgress'; diff --git a/sdk/typescript/docs/package.json b/sdk/typescript/docs/package.json index f4c99e0a38..4d0bb71c80 100644 --- a/sdk/typescript/docs/package.json +++ b/sdk/typescript/docs/package.json @@ -12,16 +12,17 @@ "start": "next start" }, "dependencies": { - "@cosmjs/amino": "^0.31.1", + "@cosmjs/amino": "^0.32.2", "@cosmjs/cosmwasm-launchpad": "^0.25.6", - "@cosmjs/cosmwasm-stargate": "^0.31.1", - "@cosmjs/encoding": "^0.31.1", - "@cosmjs/proto-signing": "^0.31.1", - "@cosmjs/stargate": "^0.31.0", - "@cosmos-kit/core": "^2.6.2", - "@cosmos-kit/keplr": "^2.3.9", - "@cosmos-kit/ledger": "^2.4.3", - "@cosmos-kit/react": "^2.8.0", + "@cosmjs/cosmwasm-stargate": "^0.32.2", + "@cosmjs/encoding": "^0.32.2", + "@cosmjs/proto-signing": "^0.32.2", + "@cosmjs/stargate": "^0.32.2", + "@cosmos-kit/core": "^2.8.9", + "@cosmos-kit/keplr": "^2.6.9", + "@cosmos-kit/keplr-extension": "^2.7.9", + "@cosmos-kit/ledger": "^2.6.9", + "@cosmos-kit/react": "^2.10.11", "@emotion/react": "^11.11.1", "@emotion/styled": "^11.11.0", "@interchain-ui/react": "^1.8.0", @@ -32,7 +33,7 @@ "@nymproject/mix-fetch-full-fat": ">=1.2.4-rc.2 || ^1", "@nymproject/sdk-full-fat": ">=1.2.4-rc.2 || ^1", "chain-registry": "^1.19.0", - "cosmjs-types": "^0.8.0", + "cosmjs-types": "^0.9.0", "next": "^13.4.19", "nextra": "latest", "nextra-theme-docs": "latest", diff --git a/sdk/typescript/docs/pages/integrations.mdx b/sdk/typescript/docs/pages/integrations.mdx index d22fdccf25..50b1522002 100644 --- a/sdk/typescript/docs/pages/integrations.mdx +++ b/sdk/typescript/docs/pages/integrations.mdx @@ -32,7 +32,6 @@ If you're unsure where to start, the following set of questions should help you ### Use one of our standalone Nym clients If you've answered 'No' to all of the above, you may need to use one of our [standalone clients](https://nymtech.net/docs/clients/overview.html). All Nym client packages present basically the same capabilities to the privacy application developer. They need to run as a persistent process in order to stay connected and ready to receive any incoming messages from their gateway nodes. They register and authenticate to gateways, and construct Sphinx packets. While setting up those, and depending on your usecase, you may need to set-up and run a Service Provider. Read below the "How to deal with Service Providers" section for more details. - You can find more information about the different standalone clients and the ways to interact with them [in this page](https://nymtech.net/developers/integrations/mixnet-integration.html). From 3bda5f59a3c98f35fe84b64bf26a62690686b97e Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 07:58:31 +0100 Subject: [PATCH 156/394] Bump ip from 2.0.0 to 2.0.1 (#4417) Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1. - [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index a711579c53..3ab8f0a0d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11174,9 +11174,9 @@ interpret@^2.2.0: integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== ipaddr.js@1.9.1: version "1.9.1" From 9e5890a0d783df9763a8993d62d9a4137e21eaaa Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 08:15:03 +0100 Subject: [PATCH 157/394] Bump ip in /clients/native/examples/js-examples/websocket (#4421) Bumps [ip](https://github.com/indutny/node-ip) from 1.1.5 to 1.1.9. - [Commits](https://github.com/indutny/node-ip/compare/v1.1.5...v1.1.9) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../examples/js-examples/websocket/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 97239acad7..99ca088e7e 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -2160,9 +2160,9 @@ } }, "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "node_modules/ipaddr.js": { @@ -6157,9 +6157,9 @@ "dev": true }, "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==", "dev": true }, "ipaddr.js": { From 3369aa51bc95ea13066990cb8f6cb1ba5ac5ed19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:20:13 +0100 Subject: [PATCH 158/394] Add nym- prefix to async-file-watcher --- common/async-file-watcher/Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/common/async-file-watcher/Cargo.toml b/common/async-file-watcher/Cargo.toml index eb7ddd6ff3..5f74d110d3 100644 --- a/common/async-file-watcher/Cargo.toml +++ b/common/async-file-watcher/Cargo.toml @@ -1,13 +1,13 @@ [package] -name = "async-file-watcher" +name = "nym-async-file-watcher" version = "0.1.0" -edition = "2021" +edition.workspace = true license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -log = "0.4" -tokio = { workspace = true, features = ["time"] } futures = { workspace = true } +log = "0.4" notify = "5.1.0" +tokio = { workspace = true, features = ["time"] } From 0f5157f7d1497a773371351bee899a40787defcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:24:21 +0100 Subject: [PATCH 159/394] Update dependency names --- service-providers/network-requester/Cargo.toml | 2 +- tools/nymvisor/Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index ac8d641719..03923f46ad 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -42,7 +42,7 @@ time = "0.3.30" zeroize = "1.6.0" # internal -async-file-watcher = { path = "../../common/async-file-watcher" } +nym-async-file-watcher = { path = "../../common/async-file-watcher" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } nym-client-core = { path = "../../common/client-core", features = ["cli"] } nym-client-websocket-requests = { path = "../../clients/native/websocket-requests" } diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index 47c2ab9101..7dd7fef743 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -32,7 +32,7 @@ thiserror = { workspace = true } tracing = { workspace = true } url = { workspace = true, features = ["serde"] } -async-file-watcher = { path = "../../common/async-file-watcher" } +nym-async-file-watcher = { path = "../../common/async-file-watcher" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format", "basic_tracing"] } nym-config = { path = "../../common/config" } nym-task = { path = "../../common/task"} From 30facbcec4ab3c8e5c68d6ebde23d6caa1b4f559 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:26:15 +0100 Subject: [PATCH 160/394] Update module imports --- Cargo.lock | 24 +++++++++---------- .../allowed_hosts/stored_allowed_hosts.rs | 2 +- tools/nymvisor/src/error.rs | 2 +- tools/nymvisor/src/tasks/launcher/mod.rs | 2 +- .../src/tasks/upgrade_plan_watcher.rs | 2 +- 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c3df2e1c05..a937d692ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,16 +389,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-file-watcher" -version = "0.1.0" -dependencies = [ - "futures", - "log", - "notify", - "tokio", -] - [[package]] name = "async-io" version = "1.13.0" @@ -5012,6 +5002,16 @@ dependencies = [ "ts-rs", ] +[[package]] +name = "nym-async-file-watcher" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "notify", + "tokio", +] + [[package]] name = "nym-bandwidth-controller" version = "0.1.0" @@ -5875,7 +5875,6 @@ version = "1.1.33" dependencies = [ "addr", "anyhow", - "async-file-watcher", "async-trait", "bs58 0.5.0", "clap 4.4.7", @@ -5884,6 +5883,7 @@ dependencies = [ "humantime-serde", "ipnetwork 0.20.0", "log", + "nym-async-file-watcher", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", @@ -6695,7 +6695,6 @@ name = "nymvisor" version = "0.1.0" dependencies = [ "anyhow", - "async-file-watcher", "bytes", "clap 4.4.7", "dotenvy", @@ -6705,6 +6704,7 @@ dependencies = [ "humantime 2.1.0", "humantime-serde", "nix 0.27.1", + "nym-async-file-watcher", "nym-bin-common", "nym-config", "nym-task", diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs index aeccebff05..a2e2537dba 100644 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs +++ b/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::request_filter::allowed_hosts::HostsStore; -use async_file_watcher::{AsyncFileWatcher, FileWatcherEventReceiver}; use futures::channel::mpsc; use futures::StreamExt; +use nym_async_file_watcher::{AsyncFileWatcher, FileWatcherEventReceiver}; use nym_task::TaskClient; use std::io; use std::path::Path; diff --git a/tools/nymvisor/src/error.rs b/tools/nymvisor/src/error.rs index 9d12c78861..5160bd3c00 100644 --- a/tools/nymvisor/src/error.rs +++ b/tools/nymvisor/src/error.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: Apache-2.0 use crate::upgrades::types::{CurrentVersionInfo, DigestAlgorithm, UpgradeInfo}; -use async_file_watcher::NotifyError; use nix::errno::Errno; use nix::sys::signal::Signal; +use nym_async_file_watcher::NotifyError; use nym_bin_common::build_information::BinaryBuildInformationOwned; use std::ffi::OsString; use std::io; diff --git a/tools/nymvisor/src/tasks/launcher/mod.rs b/tools/nymvisor/src/tasks/launcher/mod.rs index a091ba1866..74e9195d8c 100644 --- a/tools/nymvisor/src/tasks/launcher/mod.rs +++ b/tools/nymvisor/src/tasks/launcher/mod.rs @@ -7,9 +7,9 @@ use crate::error::NymvisorError; use crate::tasks::launcher::backup::BackupBuilder; use crate::upgrades::types::{CurrentVersionInfo, UpgradeInfo}; use crate::upgrades::{perform_upgrade, types::UpgradePlan, UpgradeResult}; -use async_file_watcher::FileWatcherEventReceiver; use futures::future::{FusedFuture, OptionFuture}; use futures::{FutureExt, StreamExt}; +use nym_async_file_watcher::FileWatcherEventReceiver; use nym_task::signal::wait_for_signal; use std::time::Duration; use time::OffsetDateTime; diff --git a/tools/nymvisor/src/tasks/upgrade_plan_watcher.rs b/tools/nymvisor/src/tasks/upgrade_plan_watcher.rs index 7ca896946b..5d7b937afc 100644 --- a/tools/nymvisor/src/tasks/upgrade_plan_watcher.rs +++ b/tools/nymvisor/src/tasks/upgrade_plan_watcher.rs @@ -3,8 +3,8 @@ use crate::config::Config; use crate::error::NymvisorError; -use async_file_watcher::{AsyncFileWatcher, FileWatcherEventReceiver, NotifyResult}; use futures::channel::mpsc; +use nym_async_file_watcher::{AsyncFileWatcher, FileWatcherEventReceiver, NotifyResult}; use tokio::task::JoinHandle; use tracing::warn; From 3265d58052272503e28b4854cb9b3e028c7ca961 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:27:42 +0100 Subject: [PATCH 161/394] Add nym- prefix to ledger crate --- Cargo.lock | 22 +++++++++++----------- common/ledger/Cargo.toml | 2 +- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a937d692ef..9ebf0dbb43 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3872,17 +3872,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "ledger" -version = "0.1.0" -dependencies = [ - "bip32", - "k256", - "ledger-transport", - "ledger-transport-hid", - "thiserror", -] - [[package]] name = "ledger-apdu" version = "0.10.0" @@ -5717,6 +5706,17 @@ dependencies = [ "url", ] +[[package]] +name = "nym-ledger" +version = "0.1.0" +dependencies = [ + "bip32", + "k256", + "ledger-transport", + "ledger-transport-hid", + "thiserror", +] + [[package]] name = "nym-mixnet-client" version = "0.1.0" diff --git a/common/ledger/Cargo.toml b/common/ledger/Cargo.toml index b3a6bb6f95..272433d055 100644 --- a/common/ledger/Cargo.toml +++ b/common/ledger/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "ledger" +name = "nym-ledger" version = "0.1.0" edition = "2021" license.workspace = true From 2f4f303223f61f2a52f548062fe1fea731a2c54f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:32:52 +0100 Subject: [PATCH 162/394] Add nym- prefix to http-api-client --- Cargo.lock | 34 +++++++++---------- .../client-libs/validator-client/Cargo.toml | 2 +- common/http-api-client/Cargo.toml | 4 +-- nym-node/nym-node-requests/Cargo.toml | 4 +-- wasm/mix-fetch/Cargo.toml | 2 +- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9ebf0dbb43..b07b2d9343 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3288,20 +3288,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -4514,9 +4500,9 @@ version = "1.2.4-rc.2" dependencies = [ "async-trait", "futures", - "http-api-client", "js-sys", "nym-bin-common", + "nym-http-api-client", "nym-ordered-buffer", "nym-service-providers-common", "nym-socks5-requests", @@ -5617,6 +5603,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-id" version = "0.1.0" @@ -5978,10 +5978,10 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.4", - "http-api-client", "nym-bin-common", "nym-crypto", "nym-exit-policy", + "nym-http-api-client", "nym-wireguard-types", "schemars", "serde", @@ -6559,7 +6559,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools 0.10.5", "log", "nym-api-requests", @@ -6570,6 +6569,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", diff --git a/common/client-libs/validator-client/Cargo.toml b/common/client-libs/validator-client/Cargo.toml index 3a0b2340d9..158062138a 100644 --- a/common/client-libs/validator-client/Cargo.toml +++ b/common/client-libs/validator-client/Cargo.toml @@ -25,7 +25,7 @@ nym-service-provider-directory-common = { path = "../../cosmwasm-smart-contracts serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } reqwest = { workspace = true, features = ["json"] } -http-api-client = { path = "../../../common/http-api-client"} +nym-http-api-client = { path = "../../../common/http-api-client"} thiserror = { workspace = true } log = { workspace = true } url = { workspace = true, features = ["serde"] } diff --git a/common/http-api-client/Cargo.toml b/common/http-api-client/Cargo.toml index ac43b59576..253a253aea 100644 --- a/common/http-api-client/Cargo.toml +++ b/common/http-api-client/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "http-api-client" +name = "nym-http-api-client" version = "0.1.0" authors.workspace = true repository.workspace = true @@ -22,4 +22,4 @@ tracing = { workspace = true } # for request timeout until https://github.com/seanmonstar/reqwest/issues/1135 is fixed [target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] workspace = true -features = ["tokio"] \ No newline at end of file +features = ["tokio"] diff --git a/nym-node/nym-node-requests/Cargo.toml b/nym-node/nym-node-requests/Cargo.toml index bea55fbffb..2761a1c9ec 100644 --- a/nym-node/nym-node-requests/Cargo.toml +++ b/nym-node/nym-node-requests/Cargo.toml @@ -25,7 +25,7 @@ nym-wireguard-types = { path = "../../common/wireguard-types", default-features ## client: async-trait = { workspace = true, optional = true } -http-api-client = { path = "../../common/http-api-client", optional = true } +nym-http-api-client = { path = "../../common/http-api-client", optional = true } ## openapi: utoipa = { workspace = true, optional = true } @@ -36,5 +36,5 @@ tokio = { workspace = true, features = ["full"] } [features] default = ["client"] -client = ["http-api-client", "async-trait"] +client = ["nym-http-api-client", "async-trait"] openapi = ["utoipa", "nym-bin-common/openapi", "nym-wireguard-types/openapi", "nym-exit-policy/openapi"] diff --git a/wasm/mix-fetch/Cargo.toml b/wasm/mix-fetch/Cargo.toml index 298335d6b5..336cee63e3 100644 --- a/wasm/mix-fetch/Cargo.toml +++ b/wasm/mix-fetch/Cargo.toml @@ -28,7 +28,7 @@ thiserror = { workspace = true } tsify = { workspace = true, features = ["js"] } nym-bin-common = { path = "../../common/bin-common" } -http-api-client = { path = "../../common/http-api-client" } +nym-http-api-client = { path = "../../common/http-api-client" } nym-socks5-requests = { path = "../../common/socks5/requests" } nym-ordered-buffer = { path = "../../common/socks5/ordered-buffer" } nym-service-providers-common = { path = "../../service-providers/common" } From a9ff4ccb103c91462e9e43e03440fcb530b7ad04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 10:39:33 +0100 Subject: [PATCH 163/394] Update imports --- common/client-libs/validator-client/src/nym_api/error.rs | 2 +- common/client-libs/validator-client/src/nym_api/mod.rs | 4 ++-- nym-node/nym-node-requests/src/api/client.rs | 4 ++-- wasm/mix-fetch/src/harbourmaster.rs | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/common/client-libs/validator-client/src/nym_api/error.rs b/common/client-libs/validator-client/src/nym_api/error.rs index 554a0826d4..3f4e9c65a4 100644 --- a/common/client-libs/validator-client/src/nym_api/error.rs +++ b/common/client-libs/validator-client/src/nym_api/error.rs @@ -1,7 +1,7 @@ // Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use http_api_client::HttpClientError; use nym_api_requests::models::RequestError; +use nym_http_api_client::HttpClientError; pub type NymAPIError = HttpClientError<RequestError>; diff --git a/common/client-libs/validator-client/src/nym_api/mod.rs b/common/client-libs/validator-client/src/nym_api/mod.rs index 5cf79d462e..22b13ef576 100644 --- a/common/client-libs/validator-client/src/nym_api/mod.rs +++ b/common/client-libs/validator-client/src/nym_api/mod.rs @@ -4,7 +4,6 @@ use crate::nym_api::error::NymAPIError; use crate::nym_api::routes::{CORE_STATUS_COUNT, SINCE_ARG}; use async_trait::async_trait; -use http_api_client::{ApiClient, NO_PARAMS}; pub use nym_api_requests::{ coconut::{ models::{ @@ -23,6 +22,7 @@ pub use nym_api_requests::{ }, }; pub use nym_coconut_dkg_common::types::EpochId; +use nym_http_api_client::{ApiClient, NO_PARAMS}; use nym_mixnet_contract_common::mixnode::MixNodeDetails; use nym_mixnet_contract_common::{GatewayBond, IdentityKeyRef, MixId}; use nym_name_service_common::response::NamesListResponse; @@ -31,9 +31,9 @@ use nym_service_provider_directory_common::response::ServicesListResponse; pub mod error; pub mod routes; -pub use http_api_client::Client; use nym_api_requests::coconut::models::FreePassNonceResponse; use nym_api_requests::coconut::FreePassRequest; +pub use nym_http_api_client::Client; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] diff --git a/nym-node/nym-node-requests/src/api/client.rs b/nym-node/nym-node-requests/src/api/client.rs index c4c89e2514..d6239a3bcd 100644 --- a/nym-node/nym-node-requests/src/api/client.rs +++ b/nym-node/nym-node-requests/src/api/client.rs @@ -6,15 +6,15 @@ use crate::api::v1::node::models::SignedHostInformation; use crate::api::ErrorResponse; use crate::routes; use async_trait::async_trait; -use http_api_client::{ApiClient, HttpClientError}; use nym_bin_common::build_information::BinaryBuildInformationOwned; +use nym_http_api_client::{ApiClient, HttpClientError}; use nym_wireguard_types::{ClientMessage, ClientRegistrationResponse}; use crate::api::v1::health::models::NodeHealth; use crate::api::v1::ip_packet_router::models::IpPacketRouter; use crate::api::v1::network_requester::exit_policy::models::UsedExitPolicy; use crate::api::v1::network_requester::models::NetworkRequester; -pub use http_api_client::Client; +pub use nym_http_api_client::Client; pub type NymNodeApiClientError = HttpClientError<ErrorResponse>; diff --git a/wasm/mix-fetch/src/harbourmaster.rs b/wasm/mix-fetch/src/harbourmaster.rs index 089919d9d5..cf09dc467f 100644 --- a/wasm/mix-fetch/src/harbourmaster.rs +++ b/wasm/mix-fetch/src/harbourmaster.rs @@ -5,10 +5,10 @@ // until the API is finalised and endpoints are moved to nym-api use async_trait::async_trait; -use http_api_client::{ApiClient, HttpClientError, NO_PARAMS}; +use nym_http_api_client::{ApiClient, HttpClientError, NO_PARAMS}; use serde::Deserialize; -pub use http_api_client::Client; +pub use nym_http_api_client::Client; pub type HarbourMasterApiError = HttpClientError; From 67b893175fc85d2e16097fcec8fbd0bfd2d1a78b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:19:51 +0100 Subject: [PATCH 164/394] Bump ip in /sdk/typescript/tests/integration-tests/mix-fetch (#4420) Bumps [ip](https://github.com/indutny/node-ip) from 1.1.8 to 1.1.9. - [Commits](https://github.com/indutny/node-ip/compare/v1.1.8...v1.1.9) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: benedettadavico <benedetta.davico@gmail.com> --- .../integration-tests/mix-fetch/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json b/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json index 8659d27038..fcf414162d 100644 --- a/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json +++ b/sdk/typescript/tests/integration-tests/mix-fetch/package-lock.json @@ -600,9 +600,9 @@ } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.9.tgz", + "integrity": "sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==" }, "node_modules/is-arrayish": { "version": "0.2.1", @@ -976,9 +976,9 @@ } }, "node_modules/socks/node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==" }, "node_modules/source-map": { "version": "0.6.1", From b94c81a78484da11cb99e84ed9a555e88cdf4957 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:48:56 +0100 Subject: [PATCH 165/394] Bump ip from 2.0.0 to 2.0.1 in /wasm/client/internal-dev-node (#4418) Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1. - [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: benedettadavico <benedetta.davico@gmail.com> --- wasm/client/internal-dev-node/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/client/internal-dev-node/yarn.lock b/wasm/client/internal-dev-node/yarn.lock index 3932b9c4b2..35968ffdf7 100644 --- a/wasm/client/internal-dev-node/yarn.lock +++ b/wasm/client/internal-dev-node/yarn.lock @@ -376,9 +376,9 @@ inherits@2, inherits@^2.0.3: integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ip@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" From fbba59f0014d9be76a290337827cda7e02cd0b75 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:49:27 +0100 Subject: [PATCH 166/394] Bump ip from 2.0.0 to 2.0.1 in /wasm/mix-fetch/internal-dev-node (#4419) Bumps [ip](https://github.com/indutny/node-ip) from 2.0.0 to 2.0.1. - [Commits](https://github.com/indutny/node-ip/compare/v2.0.0...v2.0.1) --- updated-dependencies: - dependency-name: ip dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: benedettadavico <benedetta.davico@gmail.com> --- wasm/mix-fetch/internal-dev-node/package-lock.json | 10 ++++------ wasm/mix-fetch/internal-dev-node/yarn.lock | 6 +++--- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/wasm/mix-fetch/internal-dev-node/package-lock.json b/wasm/mix-fetch/internal-dev-node/package-lock.json index 51943d47e5..9ede843aa0 100644 --- a/wasm/mix-fetch/internal-dev-node/package-lock.json +++ b/wasm/mix-fetch/internal-dev-node/package-lock.json @@ -17,8 +17,7 @@ }, "../../../dist/node/wasm/mix-fetch": { "name": "@nymproject/mix-fetch-wasm", - "version": "1.2.0-rc.2", - "license": "Apache-2.0" + "version": "1.2.0-rc.2" }, "node_modules/@gar/promisify": { "version": "1.1.3", @@ -643,10 +642,9 @@ "license": "ISC" }, "node_modules/ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==", - "license": "MIT", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", "optional": true }, "node_modules/is-fullwidth-code-point": { diff --git a/wasm/mix-fetch/internal-dev-node/yarn.lock b/wasm/mix-fetch/internal-dev-node/yarn.lock index a89db430e7..c15faf4ccc 100644 --- a/wasm/mix-fetch/internal-dev-node/yarn.lock +++ b/wasm/mix-fetch/internal-dev-node/yarn.lock @@ -396,9 +396,9 @@ inherits@2, inherits@^2.0.3: integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== ip@^2.0.0: - version "2.0.0" - resolved "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz" - integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.1.tgz#e8f3595d33a3ea66490204234b77636965307105" + integrity sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ== is-fullwidth-code-point@^3.0.0: version "3.0.0" From 846fd6aeaadd9bab14c04030a57aeec31fe8d94d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 14:50:44 +0100 Subject: [PATCH 167/394] Bump mio from 0.8.10 to 0.8.11 in /sdk/ffi/cpp (#4443) Bumps [mio](https://github.com/tokio-rs/mio) from 0.8.10 to 0.8.11. - [Release notes](https://github.com/tokio-rs/mio/releases) - [Changelog](https://github.com/tokio-rs/mio/blob/master/CHANGELOG.md) - [Commits](https://github.com/tokio-rs/mio/compare/v0.8.10...v0.8.11) --- updated-dependencies: - dependency-name: mio dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- sdk/ffi/cpp/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/cpp/Cargo.lock b/sdk/ffi/cpp/Cargo.lock index 7222de08de..e7174a3505 100644 --- a/sdk/ffi/cpp/Cargo.lock +++ b/sdk/ffi/cpp/Cargo.lock @@ -2300,9 +2300,9 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.10" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "wasi 0.11.0+wasi-snapshot-preview1", From df1b648fa07ac30af7664ac928e95347b41aeff9 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:05:34 +0100 Subject: [PATCH 168/394] Bump es5-ext in /sdk/typescript/packages/mix-fetch-node (#4433) Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64. - [Release notes](https://github.com/medikoo/es5-ext/releases) - [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md) - [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64) --- updated-dependencies: - dependency-name: es5-ext dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: benedettadavico <benedetta.davico@gmail.com> --- .../packages/mix-fetch-node/yarn.lock | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/sdk/typescript/packages/mix-fetch-node/yarn.lock b/sdk/typescript/packages/mix-fetch-node/yarn.lock index e0bdcadf88..f104bf5210 100644 --- a/sdk/typescript/packages/mix-fetch-node/yarn.lock +++ b/sdk/typescript/packages/mix-fetch-node/yarn.lock @@ -621,10 +621,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nymproject/mix-fetch-wasm-node@>=1.2.0-rc.10 || ^1": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@nymproject/mix-fetch-wasm-node/-/mix-fetch-wasm-node-1.2.0.tgz#76439db4eb5fd4b95dcf6b6883cb5a059aeb5ad2" - integrity sha512-vdEO4WfY1ql+DXIMR4nHvIlTB9tzhALiVjzbbf7UBgrQLxPSFTD2oGwGOVfgpNvXv0F92rDj3AHRommKKGa5pw== +"@nymproject/mix-fetch-wasm-node@>=1.2.4-rc.2 || ^1": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@nymproject/mix-fetch-wasm-node/-/mix-fetch-wasm-node-1.2.3.tgz#f600df714782e6eb691faa14683e44c2507a8e53" + integrity sha512-J9mj52WSpsGpuCeW65zEj8RWJ3GvWG0VqVWIDD6w1RK4SesXiGb7ghD7F1rChRMlSbl9rP9reYkmAHz63Sb6Cw== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -1648,13 +1648,14 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@^2.0.3: @@ -1887,6 +1888,16 @@ eslint@^8.10.0: strip-ansi "^6.0.1" text-table "^0.2.0" +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" From bc19fa7a788e21e612373e803f5ce5296dba9563 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 6 Mar 2024 15:11:32 +0100 Subject: [PATCH 169/394] Bump es5-ext in /sdk/typescript/packages/nodejs-client (#4434) Bumps [es5-ext](https://github.com/medikoo/es5-ext) from 0.10.62 to 0.10.64. - [Release notes](https://github.com/medikoo/es5-ext/releases) - [Changelog](https://github.com/medikoo/es5-ext/blob/main/CHANGELOG.md) - [Commits](https://github.com/medikoo/es5-ext/compare/v0.10.62...v0.10.64) --- updated-dependencies: - dependency-name: es5-ext dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: benedettadavico <benedetta.davico@gmail.com> --- .../packages/nodejs-client/yarn.lock | 153 ++++-------------- 1 file changed, 35 insertions(+), 118 deletions(-) diff --git a/sdk/typescript/packages/nodejs-client/yarn.lock b/sdk/typescript/packages/nodejs-client/yarn.lock index 943e1eb3de..cbfb0e71ed 100644 --- a/sdk/typescript/packages/nodejs-client/yarn.lock +++ b/sdk/typescript/packages/nodejs-client/yarn.lock @@ -65,46 +65,11 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz#b520529ec21d8e5945a1851dfd1c32e94e39ff45" integrity sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA== -"@jridgewell/gen-mapping@^0.3.0": - version "0.3.3" - resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz#7e02e6eb5df901aaedb08514203b096614024098" - integrity sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ== - dependencies: - "@jridgewell/set-array" "^1.0.1" - "@jridgewell/sourcemap-codec" "^1.4.10" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/resolve-uri@^3.1.0": - version "3.1.1" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz#c08679063f279615a3326583ba3a90d1d82cc721" - integrity sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA== - -"@jridgewell/set-array@^1.0.1": - version "1.1.2" - resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" - integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== - -"@jridgewell/source-map@^0.3.3": - version "0.3.5" - resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.5.tgz#a3bb4d5c6825aab0d281268f47f6ad5853431e91" - integrity sha512-UTYAUj/wviwdsMfzoSJspJxbkH5o1snzwX0//0ENX1u/55kkZZkcTZP6u9bwKGkv+dkk9at4m1Cpt0uY80kcpQ== - dependencies: - "@jridgewell/gen-mapping" "^0.3.0" - "@jridgewell/trace-mapping" "^0.3.9" - -"@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.14", "@jridgewell/sourcemap-codec@^1.4.15": +"@jridgewell/sourcemap-codec@^1.4.13", "@jridgewell/sourcemap-codec@^1.4.15": version "1.4.15" resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz#d7c6e6755c78567a951e04ab52ef0fd26de59f32" integrity sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg== -"@jridgewell/trace-mapping@^0.3.9": - version "0.3.19" - resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.19.tgz#f8a3249862f91be48d3127c3cfe992f79b4b8811" - integrity sha512-kf37QtfW+Hwx/buWGMPcR60iF9ziHa6r/CZJIHbmcm4+0qrXiVdxegAH0F6yddEVQ7zdkjcGCgCzUu+BcbhQxw== - dependencies: - "@jridgewell/resolve-uri" "^3.1.0" - "@jridgewell/sourcemap-codec" "^1.4.14" - "@nodelib/fs.scandir@2.1.5": version "2.1.5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" @@ -126,10 +91,10 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" -"@nymproject/nym-client-wasm-node@^1.2.0": - version "1.2.0" - resolved "https://registry.yarnpkg.com/@nymproject/nym-client-wasm-node/-/nym-client-wasm-node-1.2.0.tgz#46abe6b7535e80107d837bc6cc47edc1734aa773" - integrity sha512-L2hvMuudTQJgS/ZGGCSCD2oroccf7jWYXrq/E0Qqu0IxLlyjnTJ1xWWwXzUuwzBs+V5YZb0VIdB0kAovGLA+VA== +"@nymproject/nym-client-wasm-node@>=1.2.4-rc.2 || ^1": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@nymproject/nym-client-wasm-node/-/nym-client-wasm-node-1.2.3.tgz#e75e234714494fafffb86115cdee6759dcede366" + integrity sha512-fUGld4MJOgnvyqk5/KIpFePIXn8Nsl/7T/jh9a9WdTWntECnnJ/DBqoO+6NzDkyXaLYhByqR7reO8ZApNR0YCw== "@rollup/plugin-commonjs@^24.0.1": version "24.1.0" @@ -143,14 +108,12 @@ is-reference "1.2.1" magic-string "^0.27.0" -"@rollup/plugin-inject@^5.0.3": - version "5.0.5" - resolved "https://registry.yarnpkg.com/@rollup/plugin-inject/-/plugin-inject-5.0.5.tgz#616f3a73fe075765f91c5bec90176608bed277a3" - integrity sha512-2+DEJbNBoPROPkgTDNe8/1YXWcqxbN5DTjASVIOx8HS+pITXushyNiBV56RB08zuptzz8gT3YfkqriTBVycepg== +"@rollup/plugin-json@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-6.1.0.tgz#fbe784e29682e9bb6dee28ea75a1a83702e7b805" + integrity sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA== dependencies: - "@rollup/pluginutils" "^5.0.1" - estree-walker "^2.0.2" - magic-string "^0.30.3" + "@rollup/pluginutils" "^5.1.0" "@rollup/plugin-node-resolve@^15.0.1": version "15.2.3" @@ -172,15 +135,6 @@ "@rollup/pluginutils" "^5.0.1" magic-string "^0.30.3" -"@rollup/plugin-terser@^0.2.1": - version "0.2.1" - resolved "https://registry.yarnpkg.com/@rollup/plugin-terser/-/plugin-terser-0.2.1.tgz#dcf0b163216dafb64611b170a7667e76a7f03d2b" - integrity sha512-hV52c8Oo6/cXZZxVVoRNBb4zh+EKSHS4I1sedWV5pf0O+hTLSkrf6w86/V0AZutYtwBguB6HLKwz89WDBfwGOA== - dependencies: - serialize-javascript "^6.0.0" - smob "^0.0.6" - terser "^5.15.1" - "@rollup/plugin-typescript@^10.0.1": version "10.0.1" resolved "https://registry.yarnpkg.com/@rollup/plugin-typescript/-/plugin-typescript-10.0.1.tgz#270b515b116ea28320e6bb62451c4767d49072d6" @@ -223,6 +177,15 @@ estree-walker "^2.0.2" picomatch "^2.3.1" +"@rollup/pluginutils@^5.1.0": + version "5.1.0" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.0.tgz#7e53eddc8c7f483a4ad0b94afb1f7f5fd3c771e0" + integrity sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + "@types/estree@*", "@types/estree@^1.0.0": version "1.0.2" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.2.tgz#ff02bc3dc8317cd668dfec247b750ba1f1d62453" @@ -352,7 +315,7 @@ acorn-jsx@^5.3.2: resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.2.tgz#7ed5bb55908b3b2f1bc55c6af1653bada7f07937" integrity sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ== -acorn@^8.8.2, acorn@^8.9.0: +acorn@^8.9.0: version "8.10.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.10.0.tgz#8be5b3907a67221a81ab23c7889c4c5526b62ec5" integrity sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw== @@ -549,11 +512,6 @@ braces@^3.0.2, braces@~3.0.2: dependencies: fill-range "^7.0.1" -buffer-from@^1.0.0: - version "1.1.2" - resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" - integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== - builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6" @@ -623,11 +581,6 @@ comlink@^4.3.1: resolved "https://registry.yarnpkg.com/comlink/-/comlink-4.4.1.tgz#e568b8e86410b809e8600eb2cf40c189371ef981" integrity sha512-+1dlx0aY5Jo1vHy/tSsIGpSkN4tS9rZSW8FIhG0JH/crs9wwweswIo/POr451r7bZww3hFbPAKnTpimzL/mm4Q== -commander@^2.20.0: - version "2.20.3" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" - integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== - commander@~9.4.0: version "9.4.1" resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.1.tgz#d1dd8f2ce6faf93147295c0df13c7c21141cfbdd" @@ -880,13 +833,14 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" -es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: - version "0.10.62" - resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5" - integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA== +es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.53, es5-ext@^0.10.61, es5-ext@^0.10.62, es5-ext@~0.10.14, es5-ext@~0.10.2, es5-ext@~0.10.46: + version "0.10.64" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.64.tgz#12e4ffb48f1ba2ea777f1fcdd1918ef73ea21714" + integrity sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg== dependencies: es6-iterator "^2.0.3" es6-symbol "^3.1.3" + esniff "^2.0.1" next-tick "^1.1.0" es6-iterator@^2.0.3: @@ -1131,6 +1085,16 @@ eslint@^8.10.0: strip-ansi "^6.0.1" text-table "^0.2.0" +esniff@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308" + integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg== + dependencies: + d "^1.0.1" + es5-ext "^0.10.62" + event-emitter "^0.3.5" + type "^2.7.2" + espree@^9.6.0, espree@^9.6.1: version "9.6.1" resolved "https://registry.yarnpkg.com/espree/-/espree-9.6.1.tgz#a2a17b8e434690a5432f2f8018ce71d331a48c6f" @@ -2243,13 +2207,6 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" - integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== - dependencies: - safe-buffer "^5.1.0" - range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" @@ -2400,11 +2357,6 @@ safe-array-concat@^1.0.1: has-symbols "^1.0.3" isarray "^2.0.5" -safe-buffer@^5.1.0: - version "5.2.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" - integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== - safe-regex-test@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.0.0.tgz#793b874d524eb3640d1873aad03596db2d4f2295" @@ -2445,13 +2397,6 @@ send@0.18.0: range-parser "~1.2.1" statuses "2.0.1" -serialize-javascript@^6.0.0: - version "6.0.1" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-6.0.1.tgz#b206efb27c3da0b0ab6b52f48d170b7996458e5c" - integrity sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w== - dependencies: - randombytes "^2.1.0" - serve-static@~1.15.0: version "1.15.0" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" @@ -2519,24 +2464,6 @@ slash@^3.0.0: resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -smob@^0.0.6: - version "0.0.6" - resolved "https://registry.yarnpkg.com/smob/-/smob-0.0.6.tgz#09b268fea916158a2781c152044c6155adbb8aa1" - integrity sha512-V21+XeNni+tTyiST1MHsa84AQhT1aFZipzPpOFAVB8DkHzwJyjjAmt9bgwnuZiZWnIbMo2duE29wybxv/7HWUw== - -source-map-support@~0.5.20: - version "0.5.21" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" - integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== - dependencies: - buffer-from "^1.0.0" - source-map "^0.6.0" - -source-map@^0.6.0: - version "0.6.1" - resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" - integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== - source-map@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" @@ -2640,16 +2567,6 @@ tapable@^2.2.0: resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -terser@^5.15.1: - version "5.22.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.22.0.tgz#4f18103f84c5c9437aafb7a14918273310a8a49d" - integrity sha512-hHZVLgRA2z4NWcN6aS5rQDc+7Dcy58HOf2zbYwmFcQ+ua3h6eEFf5lIDKTzbWwlazPyOZsFQO8V80/IjVNExEw== - dependencies: - "@jridgewell/source-map" "^0.3.3" - acorn "^8.8.2" - commander "^2.20.0" - source-map-support "~0.5.20" - text-table@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" From fa8e81d9dd1e93e133c666ef777757edd7fdce25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 6 Mar 2024 17:26:51 +0100 Subject: [PATCH 170/394] Re-export Location type in explorer-client (#4445) --- explorer-api/explorer-client/src/lib.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/explorer-api/explorer-client/src/lib.rs b/explorer-api/explorer-client/src/lib.rs index 6a8790bd34..3ff4807b2b 100644 --- a/explorer-api/explorer-client/src/lib.rs +++ b/explorer-api/explorer-client/src/lib.rs @@ -6,7 +6,9 @@ use thiserror::Error; use url::Url; // Re-export request types -pub use nym_explorer_api_requests::{PrettyDetailedGatewayBond, PrettyDetailedMixNodeBond}; +pub use nym_explorer_api_requests::{ + Location, PrettyDetailedGatewayBond, PrettyDetailedMixNodeBond, +}; // Paths const API_VERSION: &str = "v1"; From aa5691447df6606de208da811dbd8dfc3da2b8a3 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 7 Mar 2024 13:00:46 +0100 Subject: [PATCH 171/394] update version, new script and simplify releases var --- documentation/dev-portal/book.toml | 2 +- .../dev-portal/src/nymvpn/cli-linux.md | 4 +- .../dev-portal/src/nymvpn/cli-mac.md | 4 +- documentation/dev-portal/src/nymvpn/cli.md | 16 +---- .../dev-portal/src/nymvpn/gui-linux.md | 15 +++-- .../dev-portal/src/nymvpn/gui-mac.md | 4 +- documentation/dev-portal/src/nymvpn/gui.md | 13 ++-- .../dev-portal/src/nymvpn/old-gui-mac.md | 61 ------------------- .../dev-portal/src/nymvpn/testing.md | 2 +- 9 files changed, 26 insertions(+), 95 deletions(-) delete mode 100644 documentation/dev-portal/src/nymvpn/old-gui-mac.md diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 3b6b9f077d..5e6c22b0a0 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -31,7 +31,7 @@ assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install` minimum_rust_version = "1.66" wallet_release_version = "1.2.8" # nym-vpn related variables -nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.4" +nym_vpn_releases = "https://github.com/nymtech/nym-vpn-client/releases" nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" [preprocessor.last-changed] diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index eb08043535..92f129f5e3 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -8,8 +8,8 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for Debian based Linux -2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux +2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releasesl}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c diff --git a/documentation/dev-portal/src/nymvpn/cli-mac.md b/documentation/dev-portal/src/nymvpn/cli-mac.md index a4093168db..85b65cd551 100644 --- a/documentation/dev-portal/src/nymvpn/cli-mac.md +++ b/documentation/dev-portal/src/nymvpn/cli-mac.md @@ -8,8 +8,8 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS -2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for MacOS +2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releasesl}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index ea0a7f0e9a..2c2ae285a7 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -16,22 +16,12 @@ We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8 1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/0cbcdd18f7ee94f559692b936061248ebbbf2773/execute-nym-vpn-cli-binary.sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/0cbcdd18f7ee94f559692b936061248ebbbf2773/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh ``` -2. Make the script executable -```sh -chmod u+x execute-nym-vpn-cli-binary.sh -``` +2. Follow the prompts in the program -3. Start the script, turn off any VPN and run -```sh -sudo -E ./execute-nym-vpn-cli-binary.sh -``` - -4. Follow the prompts in the program - -5. The script will automatically start the client. Make sure to **turn off any other VPNs** and follow the prompts: +3. The script will automatically start the client. Make sure to **turn off any other VPNs** and follow the prompts: * It prints a JSON view of existing Gateways and prompt you to: - *Make sure to use two different Gateways for entry and exit!* diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 713142c2eb..794b22904f 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -12,8 +12,8 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ### Installation -1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for Debian based Linux -2. Required (if you don't want to check shasum, skip this point): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux +2. Required (if you don't want to check shasum, skip this point): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c @@ -30,15 +30,14 @@ tar -xvf <BINARY> 4. If you prefer to run `.AppImage` make executable by running: ```sh # make sure you cd into the right sub-directory after extraction -chmod u+x ./appimage/nym-vpn_0.0.4_amd64.AppImage +chmod u+x ./nym-vpn_0.0.5-dev_amd64.AppImage ``` 5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run: ```sh -cd deb - -sudo dpkg -i ./nym-vpn_0.0.4_amd64.deb +# make sure you cd into the right sub-directory after extraction +sudo dpkg -i ./nym-vpn_0.0.5-dev_amd64.deb # or -sudo apt-get install -f ./nym-vpn_0.0.4_amd64.deb +sudo apt-get install -f ./nym-vpn-dev_0.0.5_amd64.deb ``` NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. @@ -72,7 +71,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn_0.0.4_amd64.AppImage +sudo -E ./nym-vpn-dev_0.0.5_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 336a0cede2..854e5dcaf8 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -17,9 +17,9 @@ mkdir -p "$HOME/nym-vpn-latest" ``` --> -1. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for your version of MacOS +1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for your version of MacOS -2. Recommended (skip this point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +2. Recommended (skip this point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index 779ddab4dd..dc12e610b5 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -10,23 +10,26 @@ This is the alpha version of NymVPN desktop application (GUI). A demo of how the Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for your distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . -Visit NymVPN alpha latest [release page]({{nym_vpn_latest_binary_url}}) to check sha sums or download the binaries directly. +Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. ## Automated Script for GUI Installation -We wrote a [script](https://gist.github.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically. Turn off all VPNs and follow the steps below. +We wrote a [script](https://gist.github.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically. Turn off all VPNs and follow the steps below. 1. Open a terminal window in a directory where you want the script to be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/serinko/e0a9f7ff3d79e974ec6f6783caa1137e/raw/227c8c348a1e58f68cb500e4504b22412177c680/nym-vpn-desktop-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/8e673170da309996b31de2cfcd3a65bd4d7c158f/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh ``` 2. Follow the prompts in the program To start the application again, reconnect your wifi and run ```sh -# Linux -sudo -E ~/nym-vpn-latest/nym-vpn_0.0.4_amd64.AppImage +# Linux .AppImage +sudo -E ~/nym-vpn-latest/nym-vpn-desktop_0.0.5-dev_ubuntu-22.04_x86_64/nym-vpn_0.0.5_amd64.AppImage + +# Linux .deb +sudo -E nym-vpn # MacOS sudo -E $HOME/nym-vpn-latest/nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/old-gui-mac.md b/documentation/dev-portal/src/nymvpn/old-gui-mac.md deleted file mode 100644 index ba74a23f41..0000000000 --- a/documentation/dev-portal/src/nymvpn/old-gui-mac.md +++ /dev/null @@ -1,61 +0,0 @@ -# NymVPN alpha - Desktop: Guide for Mac OS - -```admonish info -NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. -``` - -## Preparation - -> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. - -### Installation - -1. Create a directory `~/nym-vpn-latest` -```sh -mkdir -p "$HOME/nym-vpn-latest" -``` -2. Open Github [releases page]({{nym_vpn_latest_binary_url}}) and download the binary for MacOS -3. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_latest_binary_url}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: -```sh -echo "<SHA_STRING>" | shasum -a 256 -c - -# choose a correct one according to your binary, this is just an example -# echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c -``` -4. Extract files: -```sh -tar -xvf <BINARY> -# for example -# tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz -``` -5. Move to the application directory and make executable -```sh -cd "macos/nym-vpn.app/Contents/MacOS" - -chmod u+x nym-vpn -``` -6. Move `nym-vpn` to your `~/nym-vpn-latest` directory -```sh -mv nym-vpn "$HOME/nym-vpn-latest" -``` - -### Configuration - -7. Create the configuration file by opening a text editor and saving the lines below as `config.toml` in the same directory `~/nym-vpn-latest` -```toml -env_config_file = ".env" -``` -8. Create testnet configuration file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `.env` in the same directory `~/nym-vpn-latest` -```sh -curl -L "https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env" -o "$HOME/nym-vpn-latest/.env" -``` -## Run NymVPN - -**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. - -Run: -```sh -sudo -E $HOME/nym-vpn-latest/nym-vpn -``` - -In case of errors check out the [troubleshooting](troubleshooting.html#installing-gui-on-macos-not-working) section. diff --git a/documentation/dev-portal/src/nymvpn/testing.md b/documentation/dev-portal/src/nymvpn/testing.md index f5e6558bf4..849b670d8f 100644 --- a/documentation/dev-portal/src/nymvpn/testing.md +++ b/documentation/dev-portal/src/nymvpn/testing.md @@ -14,7 +14,7 @@ One of the main aims of NymVPN alpha release is testing; your results will help > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary ([download here]({{nym_vpn_latest_binary_url}})) +1. Create a directory called `nym-vpn-tests` and copy your `nym-vpn-cli` binary ([download here]({{nym_vpn_releases}})) 2. Copy or download [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) testnet config file to the same directory ```sh curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env From 8371bf898f860bb7c6203c17d1f51add532ece9a Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:09:19 +0100 Subject: [PATCH 172/394] upgrade guide 0.0.5-dev -> 0.0.5 --- documentation/dev-portal/src/nymvpn/gui-linux.md | 10 +++++----- documentation/dev-portal/src/nymvpn/gui-mac.md | 4 ++-- documentation/dev-portal/src/nymvpn/gui.md | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 794b22904f..49cb36a17b 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -22,7 +22,7 @@ echo "<SHA_STRING>" | shasum -a 256 -c ``` 3. Extract files: ```sh -tar -xvf <BINARY> +tar -xvf <BINARY>.tar.gz # for example # tar -xvf nym-vpn-desktop_0.0.4_ubuntu-22.04_x86_64.tar.gz ``` @@ -30,14 +30,14 @@ tar -xvf <BINARY> 4. If you prefer to run `.AppImage` make executable by running: ```sh # make sure you cd into the right sub-directory after extraction -chmod u+x ./nym-vpn_0.0.5-dev_amd64.AppImage +chmod u+x ./nym-vpn_0.0.5_amd64.AppImage ``` 5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run: ```sh # make sure you cd into the right sub-directory after extraction -sudo dpkg -i ./nym-vpn_0.0.5-dev_amd64.deb +sudo dpkg -i ./nym-vpn_0.0.5_amd64.deb # or -sudo apt-get install -f ./nym-vpn-dev_0.0.5_amd64.deb +sudo apt-get install -f ./nym-vpn_0.0.5_amd64.deb ``` NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. @@ -71,7 +71,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn-dev_0.0.5_amd64.AppImage +sudo -E ./nym-vpn_0.0.5_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 854e5dcaf8..d2c9cf50a2 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -29,7 +29,7 @@ echo "<SHA_STRING>" | shasum -a 256 -c 3. Extract the downloaded file manually or by a command: ```sh -tar -xvf <BINARY> +tar -xvf <BINARY>.tar.gz # for example # tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz ``` @@ -71,7 +71,7 @@ env_config_file = "sandbox.env" ``` Alternatively do it by using this command: ```sh -echo "env_config_file = sandbox.env" > /Applications/nym-vpn.app/Contents/MacOS//config.toml +echo "env_config_file = sandbox.env" > /Applications/nym-vpn.app/Contents/MacOS/config.toml ``` ## Run NymVPN diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index dc12e610b5..54924c40d4 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -18,7 +18,7 @@ We wrote a [script](https://gist.github.com/tommyv1987/7d210d4daa8f7abc61f9a696d 1. Open a terminal window in a directory where you want the script to be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/8e673170da309996b31de2cfcd3a65bd4d7c158f/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/163abd7ebc45d1f44d93ba12fb904bcd54e5793f/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh ``` 2. Follow the prompts in the program @@ -26,7 +26,7 @@ curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tom To start the application again, reconnect your wifi and run ```sh # Linux .AppImage -sudo -E ~/nym-vpn-latest/nym-vpn-desktop_0.0.5-dev_ubuntu-22.04_x86_64/nym-vpn_0.0.5_amd64.AppImage +sudo -E ~/nym-vpn-latest/nym-vpn-desktop_0.0.5_ubuntu-22.04_x86_64/nym-vpn_0.0.5_amd64.AppImage # Linux .deb sudo -E nym-vpn From 57b9372050aa7f2592b926b3d983d7950ef68d21 Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:22:05 +0100 Subject: [PATCH 173/394] comment out qualitative testing --- documentation/dev-portal/src/SUMMARY.md | 1 - documentation/dev-portal/src/nymvpn/cli.md | 2 -- documentation/dev-portal/src/nymvpn/intro.md | 8 +++----- documentation/dev-portal/src/nymvpn/troubleshooting.md | 2 ++ 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index 3a14919b99..8a0db815c4 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -25,7 +25,6 @@ - [CLI](nymvpn/cli.md) - [Linux](nymvpn/cli-linux.md) - [MacOS](nymvpn/cli-mac.md) - - [Testing](nymvpn/testing.md) - [Troubleshooting](nymvpn/troubleshooting.md) - [NymVPN FAQ](nymvpn/faq.md) - [NymConnect X Monero](tutorials/monero.md) diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index 2c2ae285a7..73f0511a79 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -6,8 +6,6 @@ Our alpha testing round is done with participants at live workshop events. This **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` -NymVPN CLI is a fundamental way to run the client for different purposes, currently it is a must for users who want to run the [testing scripts](testing.md). - Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). ## Automated Script for CLI Installation diff --git a/documentation/dev-portal/src/nymvpn/intro.md b/documentation/dev-portal/src/nymvpn/intro.md index b6da352656..3c1f1c7d71 100644 --- a/documentation/dev-portal/src/nymvpn/intro.md +++ b/documentation/dev-portal/src/nymvpn/intro.md @@ -5,7 +5,7 @@ **Nym proudly presents NymVPN alpha** - a client that uses [Nym Mixnet](https://nymtech.net) to anonymise all of a user's internet traffic through either a 5-hop mixnet (for a full network privacy) or the faster 2-hop decentralised VPN (with some extra features). -**You are invited to take part in the alpha testing** of this new application. The following pages provide a how-to guide, explaining steps to install and run NymVPN [CLI](cli.md) and [GUI](gui.md) on the Sandbox testnet environment as well as provide some scripts for [qualitative testing](testing.md). +**You are invited to take part in the alpha testing** of this new application. The following pages provide a how-to guide, explaining steps to install and run NymVPN [CLI](cli.md) and [GUI](gui.md) on the Sandbox testnet environment. **Here is how** @@ -13,9 +13,8 @@ 2. Please consent to the GDPR so we can use the results 3. To test the GUI, [go here](gui.md) 4. To test the CLI, [go here](cli.md) -5. Run [qualitative testing script](testing.md) -6. Fill and submit the [form!]({{nym_vpn_form_url}}) -7. Join the [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) if you have any questions, comments or blockers +5. Fill and submit the [form!]({{nym_vpn_form_url}}) +6. Join the [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) if you have any questions, comments or blockers ***NymVPN alpha testing will last from 15th of January - 15th of February.*** @@ -48,7 +47,6 @@ The client can optionally do the first hop (local client to Entry Gateway) using * [Alpha release page]({{nym_vpn_latest_binary_url}}) * [NymVPN application (GUI) guide](gui.md) * [NymVPN Command Line Interface (CLI) guide](cli.md) -* [Testing scripts](testing.md) * [Troubleshooting](troubleshooting.md) * [NymVPN FAQ](faq.md) * [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) diff --git a/documentation/dev-portal/src/nymvpn/troubleshooting.md b/documentation/dev-portal/src/nymvpn/troubleshooting.md index 32f9139516..bc94a2bb9b 100644 --- a/documentation/dev-portal/src/nymvpn/troubleshooting.md +++ b/documentation/dev-portal/src/nymvpn/troubleshooting.md @@ -68,6 +68,7 @@ In that case, comment the `jq` check in the script as follows: When running `sudo sh ./test.sh` you may see an error like: `93: current_time: not found`. This has something to do with the `current_time` setup of your system and on itself shall not have a negative impact on the test. It has nothing to do with the client at all as it only relates to the code in our testing script. +<!-- #### Not connecting to the endpoint In case the automatic download of all the Gateways fail (and it shouldn't), you do an easy manual work around: @@ -84,3 +85,4 @@ NEW_ENDPOINT="http://localhost:8000/data.json" python3 -m http.server 8000 ``` 6. Continue with the steps listed in [testing section](testing.md) +--> From fe3c6bdad45d6bae35872bdf1549b4455bb710bf Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Thu, 7 Mar 2024 19:24:21 +0100 Subject: [PATCH 174/394] comment out qualitative testing --- documentation/dev-portal/src/nymvpn/intro.md | 2 +- documentation/dev-portal/src/nymvpn/troubleshooting.md | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/intro.md b/documentation/dev-portal/src/nymvpn/intro.md index 3c1f1c7d71..7a42df06ca 100644 --- a/documentation/dev-portal/src/nymvpn/intro.md +++ b/documentation/dev-portal/src/nymvpn/intro.md @@ -18,7 +18,7 @@ ***NymVPN alpha testing will last from 15th of January - 15th of February.*** -*NOTE: NymVPN alpha is experimental software for [testing purposes](testing.md) only.* +*NOTE: NymVPN alpha is experimental software for testing purposes only.* ## NymVPN Overview diff --git a/documentation/dev-portal/src/nymvpn/troubleshooting.md b/documentation/dev-portal/src/nymvpn/troubleshooting.md index bc94a2bb9b..7d33991c75 100644 --- a/documentation/dev-portal/src/nymvpn/troubleshooting.md +++ b/documentation/dev-portal/src/nymvpn/troubleshooting.md @@ -45,7 +45,7 @@ If you are running NymVPN on mac OS for the first time, you may see this alert m 2. Confirm with your password or TouchID 3. Possibly you may have to confirm again upon running the application - +<!-- #### Missing `jq` error In case of missing `jq` on Linux (Debian) install it with: @@ -68,7 +68,6 @@ In that case, comment the `jq` check in the script as follows: When running `sudo sh ./test.sh` you may see an error like: `93: current_time: not found`. This has something to do with the `current_time` setup of your system and on itself shall not have a negative impact on the test. It has nothing to do with the client at all as it only relates to the code in our testing script. -<!-- #### Not connecting to the endpoint In case the automatic download of all the Gateways fail (and it shouldn't), you do an easy manual work around: From c13297d18d97435f33bfb6b576cac926af9a527a Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Fri, 8 Mar 2024 12:32:43 +0100 Subject: [PATCH 175/394] implement nym-vpn version vars --- documentation/dev-portal/book.toml | 2 ++ documentation/dev-portal/src/nymvpn/cli-linux.md | 6 +++--- documentation/dev-portal/src/nymvpn/cli-mac.md | 4 ++-- documentation/dev-portal/src/nymvpn/gui-linux.md | 10 +++++----- documentation/dev-portal/src/nymvpn/gui-mac.md | 2 +- documentation/dev-portal/src/nymvpn/gui.md | 2 +- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 5e6c22b0a0..9f57151580 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -33,6 +33,8 @@ wallet_release_version = "1.2.8" # nym-vpn related variables nym_vpn_releases = "https://github.com/nymtech/nym-vpn-client/releases" nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" +nym_vpn_gui_version = "0.0.6" +nym_vpn_cli_version = "0.0.4" [preprocessor.last-changed] command = "mdbook-last-changed" diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index 92f129f5e3..fcf80f84a2 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -14,17 +14,17 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_0.1.0_ubuntu-22.04_amd64.zip" | shasum -a 256 -c +# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_{{nym_vpn_cli_version}}_ubuntu-22.04_amd64.zip" | shasum -a 256 -c ``` 1. Extract files: ```sh tar -xvf <BINARY> # for example -# tar -xvf nym-vpn-cli_0.0.2_ubuntu-22.04_x86_64.tar.gz +# tar -xvf nym-vpn-cli_{{nym_vpn_cli_version}}_ubuntu-22.04_x86_64.tar.gz ``` 2. Make executable by running: ```sh -# possibly you may have to cd into a sub-directory +# make sure you are in the right sub-directory chmod u+x ./nym-vpn-cli ``` 5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: diff --git a/documentation/dev-portal/src/nymvpn/cli-mac.md b/documentation/dev-portal/src/nymvpn/cli-mac.md index 85b65cd551..745b8601ed 100644 --- a/documentation/dev-portal/src/nymvpn/cli-mac.md +++ b/documentation/dev-portal/src/nymvpn/cli-mac.md @@ -14,13 +14,13 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_0.1.0_macos_x86_64.zip" | shasum -a 256 -c +# echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_{{nym_vpn_cli_version}}_macos_x86_64.zip" | shasum -a 256 -c ``` 3. Extract files: ```sh tar -xvf <BINARY> # for example -# tar -xvf nym-vpn-cli_0.0.2_macos_aarch64.tar.gz +# tar -xvf nym-vpn-cli_{{nym_vpn_cli_version}}_macos_aarch64.tar.gz ``` 4. Make executable by running: ```sh diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 49cb36a17b..46506ac528 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -24,20 +24,20 @@ echo "<SHA_STRING>" | shasum -a 256 -c ```sh tar -xvf <BINARY>.tar.gz # for example -# tar -xvf nym-vpn-desktop_0.0.4_ubuntu-22.04_x86_64.tar.gz +# tar -xvf nym-vpn-desktop_{{nym_vpn_gui_version}}_ubuntu-22.04_x86_64.tar.gz ``` 4. If you prefer to run `.AppImage` make executable by running: ```sh # make sure you cd into the right sub-directory after extraction -chmod u+x ./nym-vpn_0.0.5_amd64.AppImage +chmod u+x ./nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage ``` 5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run: ```sh # make sure you cd into the right sub-directory after extraction -sudo dpkg -i ./nym-vpn_0.0.5_amd64.deb +sudo dpkg -i ./nym-vpn_{{nym_vpn_gui_version}}_amd64.deb # or -sudo apt-get install -f ./nym-vpn_0.0.5_amd64.deb +sudo apt-get install -f ./nym-vpn_{{nym_vpn_gui_version}}_amd64.deb ``` NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. @@ -71,7 +71,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn_0.0.5_amd64.AppImage +sudo -E ./nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index d2c9cf50a2..0b1653f5dd 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -31,7 +31,7 @@ echo "<SHA_STRING>" | shasum -a 256 -c ```sh tar -xvf <BINARY>.tar.gz # for example -# tar -xvf nym-vpn-desktop_0.0.4_macos_aarch64.tar.gz +# tar -xvf nym-vpn-desktop_{{nym_vpn_gui_version}}_macos_aarch64.tar.gz ``` <!-- seems redundant 5. Move to the application content directory: diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index 54924c40d4..b822380319 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -26,7 +26,7 @@ curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tom To start the application again, reconnect your wifi and run ```sh # Linux .AppImage -sudo -E ~/nym-vpn-latest/nym-vpn-desktop_0.0.5_ubuntu-22.04_x86_64/nym-vpn_0.0.5_amd64.AppImage +sudo -E ~/nym-vpn-latest/nym-vpn-desktop_{{nym_vpn_gui_version}}_ubuntu-22.04_x86_64/nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage # Linux .deb sudo -E nym-vpn From 0e56d8c2f733f37ae5cdeace779b58083b12baeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 8 Mar 2024 15:21:41 +0100 Subject: [PATCH 176/394] Add severity level to IPR response and downgrade filter check failed (#4447) * Add info level to response from ipr * Downgrade exit policy filter check failed to warning * Bump ipr request response version --- common/ip-packet-requests/src/lib.rs | 3 +- common/ip-packet-requests/src/response.rs | 36 +++++++++++++------ .../ip-packet-router/src/mixnet_listener.rs | 8 +++-- 3 files changed, 32 insertions(+), 15 deletions(-) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index f3de2fb675..462472b2e3 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -8,7 +8,8 @@ pub mod response; // version 3: initial version // version 4: IPv6 support -pub const CURRENT_VERSION: u8 = 4; +// version 5: Add severity level to info response +pub const CURRENT_VERSION: u8 = 5; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct IpPair { diff --git a/common/ip-packet-requests/src/response.rs b/common/ip-packet-requests/src/response.rs index b07f1a97af..d2baf16f6e 100644 --- a/common/ip-packet-requests/src/response.rs +++ b/common/ip-packet-requests/src/response.rs @@ -116,24 +116,30 @@ impl IpPacketResponse { ) -> Self { Self { version: CURRENT_VERSION, - data: IpPacketResponseData::Error(ErrorResponse { + data: IpPacketResponseData::Info(InfoResponse { request_id, reply_to, - reply: ErrorResponseReply::VersionMismatch { + reply: InfoResponseReply::VersionMismatch { request_version, response_version: our_version, }, + level: InfoLevel::Error, }), } } - pub fn new_data_error_response(reply_to: Recipient, reply: ErrorResponseReply) -> Self { + pub fn new_data_info_response( + reply_to: Recipient, + reply: InfoResponseReply, + level: InfoLevel, + ) -> Self { Self { version: CURRENT_VERSION, - data: IpPacketResponseData::Error(ErrorResponse { + data: IpPacketResponseData::Info(InfoResponse { request_id: 0, reply_to, reply, + level, }), } } @@ -147,7 +153,7 @@ impl IpPacketResponse { IpPacketResponseData::Data(_) => None, IpPacketResponseData::Pong(response) => Some(response.request_id), IpPacketResponseData::Health(response) => Some(response.request_id), - IpPacketResponseData::Error(response) => Some(response.request_id), + IpPacketResponseData::Info(response) => Some(response.request_id), } } @@ -160,7 +166,7 @@ impl IpPacketResponse { IpPacketResponseData::Data(_) => None, IpPacketResponseData::Pong(response) => Some(&response.reply_to), IpPacketResponseData::Health(response) => Some(&response.reply_to), - IpPacketResponseData::Error(response) => Some(&response.reply_to), + IpPacketResponseData::Info(response) => Some(&response.reply_to), } } @@ -201,8 +207,8 @@ pub enum IpPacketResponseData { // Response for a health request Health(HealthResponse), - // Error response - Error(ErrorResponse), + // Info response. This can be anything from informative messages to errors + Info(InfoResponse), } #[derive(Clone, Debug, Serialize, Deserialize)] @@ -338,14 +344,15 @@ pub struct HealthResponseReply { } #[derive(Clone, Debug, Serialize, Deserialize)] -pub struct ErrorResponse { +pub struct InfoResponse { pub request_id: u64, pub reply_to: Recipient, - pub reply: ErrorResponseReply, + pub reply: InfoResponseReply, + pub level: InfoLevel, } #[derive(Clone, Debug, Serialize, Deserialize, thiserror::Error)] -pub enum ErrorResponseReply { +pub enum InfoResponseReply { #[error("{msg}")] Generic { msg: String }, #[error( @@ -358,3 +365,10 @@ pub enum ErrorResponseReply { #[error("destination failed exit policy filter check: {dst}")] ExitPolicyFilterCheckFailed { dst: String }, } + +#[derive(Clone, Debug, Serialize, Deserialize)] +pub enum InfoLevel { + Info, + Warn, + Error, +} diff --git a/service-providers/ip-packet-router/src/mixnet_listener.rs b/service-providers/ip-packet-router/src/mixnet_listener.rs index af3c7214f0..bc577b53d2 100644 --- a/service-providers/ip-packet-router/src/mixnet_listener.rs +++ b/service-providers/ip-packet-router/src/mixnet_listener.rs @@ -4,11 +4,12 @@ use std::{collections::HashMap, net::SocketAddr}; use bytes::{Bytes, BytesMut}; use futures::StreamExt; +use nym_ip_packet_requests::response::InfoLevel; use nym_ip_packet_requests::{ codec::MultiIpPacketCodec, request::{IpPacketRequest, IpPacketRequestData}, response::{ - DynamicConnectFailureReason, ErrorResponseReply, IpPacketResponse, + DynamicConnectFailureReason, InfoResponseReply, IpPacketResponse, StaticConnectFailureReason, }, IpPair, @@ -480,11 +481,12 @@ impl MixnetListener { Ok(None) } else { log::info!("Denied filter check: {dst}"); - Ok(Some(IpPacketResponse::new_data_error_response( + Ok(Some(IpPacketResponse::new_data_info_response( connected_client.nym_address, - ErrorResponseReply::ExitPolicyFilterCheckFailed { + InfoResponseReply::ExitPolicyFilterCheckFailed { dst: dst.to_string(), }, + InfoLevel::Warn, ))) } } else { From 1f41eca0b247d59b2924322df70bfd2a89ab9d1b Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Fri, 8 Mar 2024 15:43:13 +0100 Subject: [PATCH 177/394] automate GUI script for latest version pull --- documentation/dev-portal/src/nymvpn/gui.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index b822380319..c1043abab8 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -18,7 +18,7 @@ We wrote a [script](https://gist.github.com/tommyv1987/7d210d4daa8f7abc61f9a696d 1. Open a terminal window in a directory where you want the script to be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/163abd7ebc45d1f44d93ba12fb904bcd54e5793f/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/6c81619ec26b092dfa174bce79335f4163c657ff/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh ``` 2. Follow the prompts in the program From ca86bbc3a5e36afec78bbdb6ce4618de9754a8dd Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Fri, 8 Mar 2024 22:37:31 +0100 Subject: [PATCH 178/394] troubleshoot all script issues - full auto mode now --- documentation/dev-portal/src/nymvpn/cli.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index 73f0511a79..0fc239b0e9 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -8,13 +8,15 @@ Our alpha testing round is done with participants at live workshop events. This Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). +Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. + ## Automated Script for CLI Installation -We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8fb31) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: +We wrote a [script](https://gist.github.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: 1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/0cbcdd18f7ee94f559692b936061248ebbbf2773/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/df78e30101c7357b57b311e06d5487e15d3335cb/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh ``` 2. Follow the prompts in the program From f26d4ab8829f97edcaf2fe52ba67cc1941d0fd3f Mon Sep 17 00:00:00 2001 From: serinko <97586125+serinko@users.noreply.github.com> Date: Fri, 8 Mar 2024 23:47:03 +0100 Subject: [PATCH 179/394] final version with automated commands update --- documentation/dev-portal/book.toml | 6 ++++-- documentation/dev-portal/src/nymvpn/cli-linux.md | 16 ++++++++++------ documentation/dev-portal/src/nymvpn/cli-mac.md | 6 +++--- documentation/dev-portal/src/nymvpn/cli.md | 5 ++--- documentation/dev-portal/src/nymvpn/gui-linux.md | 15 +++++++++------ documentation/dev-portal/src/nymvpn/gui-mac.md | 4 ++-- documentation/dev-portal/src/nymvpn/gui.md | 2 +- documentation/dev-portal/src/nymvpn/intro.md | 2 +- .../src/nymvpn/scripts/nym_vpn_cli_version.sh | 6 ++++++ .../nymvpn/scripts/nym_vpn_desktop_version.sh | 6 ++++++ .../dev-portal/src/nymvpn/troubleshooting.md | 2 ++ 11 files changed, 46 insertions(+), 24 deletions(-) create mode 100755 documentation/dev-portal/src/nymvpn/scripts/nym_vpn_cli_version.sh create mode 100755 documentation/dev-portal/src/nymvpn/scripts/nym_vpn_desktop_version.sh diff --git a/documentation/dev-portal/book.toml b/documentation/dev-portal/book.toml index 9f57151580..8533a08344 100644 --- a/documentation/dev-portal/book.toml +++ b/documentation/dev-portal/book.toml @@ -33,8 +33,10 @@ wallet_release_version = "1.2.8" # nym-vpn related variables nym_vpn_releases = "https://github.com/nymtech/nym-vpn-client/releases" nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" -nym_vpn_gui_version = "0.0.6" -nym_vpn_cli_version = "0.0.4" + +# versions are pulled by cmdrun now +# nym_vpn_gui_version = "0.0.6" +# nym_vpn_cli_version = "0.0.4" [preprocessor.last-changed] command = "mdbook-last-changed" diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index fcf80f84a2..2c8f932e0a 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -9,24 +9,28 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. 1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux -2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releasesl}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: + +2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_{{nym_vpn_cli_version}}_ubuntu-22.04_amd64.zip" | shasum -a 256 -c +# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_ubuntu-22.04_amd64.tar.gz" | shasum -a 256 -c ``` -1. Extract files: + +3. Extract files: ```sh -tar -xvf <BINARY> +tar -xvf <BINARY>.tar.gz # for example -# tar -xvf nym-vpn-cli_{{nym_vpn_cli_version}}_ubuntu-22.04_x86_64.tar.gz +# tar -xvf nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_ubuntu-22.04_x86_64.tar.gz ``` -2. Make executable by running: + +4. Make executable by running: ```sh # make sure you are in the right sub-directory chmod u+x ./nym-vpn-cli ``` + 5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: ```sh curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env diff --git a/documentation/dev-portal/src/nymvpn/cli-mac.md b/documentation/dev-portal/src/nymvpn/cli-mac.md index 745b8601ed..fa75a90659 100644 --- a/documentation/dev-portal/src/nymvpn/cli-mac.md +++ b/documentation/dev-portal/src/nymvpn/cli-mac.md @@ -9,18 +9,18 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. 1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for MacOS -2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releasesl}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_{{nym_vpn_cli_version}}_macos_x86_64.zip" | shasum -a 256 -c +# echo "96623ccc69bc4cc0e4e3e18528b6dae6be69f645d0a592d926a3158ce2d0c269 nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_macos_x86_64.zip" | shasum -a 256 -c ``` 3. Extract files: ```sh tar -xvf <BINARY> # for example -# tar -xvf nym-vpn-cli_{{nym_vpn_cli_version}}_macos_aarch64.tar.gz +# tar -xvf nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_macos_aarch64.tar.gz ``` 4. Make executable by running: ```sh diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index 0fc239b0e9..7151082e2a 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -5,18 +5,17 @@ Our alpha testing round is done with participants at live workshop events. This **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` - Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. ## Automated Script for CLI Installation -We wrote a [script](https://gist.github.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: +We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8fb31) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: 1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/df78e30101c7357b57b311e06d5487e15d3335cb/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/4b70371fb000fd08910c0f778e78566d002e1319/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh ``` 2. Follow the prompts in the program diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 46506ac528..2f66420bf1 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -13,31 +13,34 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ### Installation 1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux + 2. Required (if you don't want to check shasum, skip this point): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "a5f91f20d587975e30b6a75d3a9e195234cf1269eac278139a5b9c39b039e807 nym-vpn-desktop_0.0.3_ubuntu-22.04_x86_64.zip" | shasum -a 256 -c +# echo "a5f91f20d587975e30b6a75d3a9e195234cf1269eac278139a5b9c39b039e807 nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_ubuntu-22.04_x86_64.tar.gz" | shasum -a 256 -c ``` + 3. Extract files: ```sh tar -xvf <BINARY>.tar.gz # for example -# tar -xvf nym-vpn-desktop_{{nym_vpn_gui_version}}_ubuntu-22.04_x86_64.tar.gz +# tar -xvf nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_ubuntu-22.04_x86_64.tar.gz ``` 4. If you prefer to run `.AppImage` make executable by running: ```sh # make sure you cd into the right sub-directory after extraction -chmod u+x ./nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage +chmod u+x ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.AppImage ``` + 5. If you prefer to use the `.deb` version for installation (works on Debian based Linux only), open terminal in the same directory and run: ```sh # make sure you cd into the right sub-directory after extraction -sudo dpkg -i ./nym-vpn_{{nym_vpn_gui_version}}_amd64.deb +sudo dpkg -i ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.deb # or -sudo apt-get install -f ./nym-vpn_{{nym_vpn_gui_version}}_amd64.deb +sudo apt-get install -f ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.deb ``` NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. @@ -71,7 +74,7 @@ Open terminal and run: ```sh # .AppImage must be run from the same directory as the binary -sudo -E ./nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage +sudo -E ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.AppImage # .deb installation shall be executable from anywhere as sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 0b1653f5dd..9602f608cf 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -24,14 +24,14 @@ mkdir -p "$HOME/nym-vpn-latest" echo "<SHA_STRING>" | shasum -a 256 -c # choose a correct one according to your binary, this is just an example -# echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_0.0.3_macos_x86_64.zip" | shasum -a 256 -c +# echo "da4c0bf8e8b52658312d341fa3581954cfcb6efd516d9a448c76d042a454b5df nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_macos_x86_64.zip" | shasum -a 256 -c ``` 3. Extract the downloaded file manually or by a command: ```sh tar -xvf <BINARY>.tar.gz # for example -# tar -xvf nym-vpn-desktop_{{nym_vpn_gui_version}}_macos_aarch64.tar.gz +# tar -xvf nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_macos_aarch64.tar.gz ``` <!-- seems redundant 5. Move to the application content directory: diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index c1043abab8..ca75730cc4 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -26,7 +26,7 @@ curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tom To start the application again, reconnect your wifi and run ```sh # Linux .AppImage -sudo -E ~/nym-vpn-latest/nym-vpn-desktop_{{nym_vpn_gui_version}}_ubuntu-22.04_x86_64/nym-vpn_{{nym_vpn_gui_version}}_amd64.AppImage +sudo -E ~/nym-vpn-latest/nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_ubuntu-22.04_x86_64/nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.AppImage # Linux .deb sudo -E nym-vpn diff --git a/documentation/dev-portal/src/nymvpn/intro.md b/documentation/dev-portal/src/nymvpn/intro.md index 7a42df06ca..b0648c063e 100644 --- a/documentation/dev-portal/src/nymvpn/intro.md +++ b/documentation/dev-portal/src/nymvpn/intro.md @@ -44,7 +44,7 @@ The client can optionally do the first hop (local client to Entry Gateway) using ## NymVPN Resources & Guides * [NymVPN webpage](https://nymvpn.com) -* [Alpha release page]({{nym_vpn_latest_binary_url}}) +* [Alpha release page]({{nym_vpn_releases}}) * [NymVPN application (GUI) guide](gui.md) * [NymVPN Command Line Interface (CLI) guide](cli.md) * [Troubleshooting](troubleshooting.md) diff --git a/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_cli_version.sh b/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_cli_version.sh new file mode 100755 index 0000000000..2801762bbf --- /dev/null +++ b/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_cli_version.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +release_url="https://api.github.com/repos/nymtech/nym-vpn-client/releases" +current_cli_version=$(curl -s $release_url | jq -r '.[].tag_name' | grep '^nym-vpn-cli-v' | sort -Vr | head -n 1 | awk -F'-v' '{print $NF}') + +echo "${current_cli_version}" diff --git a/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_desktop_version.sh b/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_desktop_version.sh new file mode 100755 index 0000000000..443509b70b --- /dev/null +++ b/documentation/dev-portal/src/nymvpn/scripts/nym_vpn_desktop_version.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +release_url="https://api.github.com/repos/nymtech/nym-vpn-client/releases" +version=$(curl -s $release_url | jq -r '.[].tag_name' | grep '^nym-vpn-desktop-v' | sort -Vr | head -n 1 | awk -F'-v' '{print $NF}') + +echo "${version}" diff --git a/documentation/dev-portal/src/nymvpn/troubleshooting.md b/documentation/dev-portal/src/nymvpn/troubleshooting.md index 7d33991c75..9e00554518 100644 --- a/documentation/dev-portal/src/nymvpn/troubleshooting.md +++ b/documentation/dev-portal/src/nymvpn/troubleshooting.md @@ -45,7 +45,9 @@ If you are running NymVPN on mac OS for the first time, you may see this alert m 2. Confirm with your password or TouchID 3. Possibly you may have to confirm again upon running the application + <!-- + #### Missing `jq` error In case of missing `jq` on Linux (Debian) install it with: From 0282251016330c24d224e160ed1e03220205038b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 11 Mar 2024 15:01:02 +0100 Subject: [PATCH 180/394] Add TaskStatus::ReadyWithGateway (#4449) * Add TaskStatus::ReadyWithGateway * Explicitly set starting status --- common/socks5-client-core/src/lib.rs | 5 ++++- common/task/src/manager.rs | 10 ++++++++-- nym-connect/desktop/src-tauri/src/events.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 7 ++++++- 4 files changed, 19 insertions(+), 5 deletions(-) diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index 44747c8753..ecef31354f 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -23,6 +23,7 @@ use nym_client_core::init::types::GatewaySetup; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::params::PacketType; +use nym_task::manager::TaskStatus; use nym_task::{TaskClient, TaskHandle}; use anyhow::anyhow; @@ -177,7 +178,9 @@ where ))?; // Listen to status messages from task, that we forward back to the caller - shutdown.start_status_listener(sender).await; + shutdown + .start_status_listener(sender, TaskStatus::Ready) + .await; let res = tokio::select! { biased; diff --git a/common/task/src/manager.rs b/common/task/src/manager.rs index 6a913fdc47..5cd0254a79 100644 --- a/common/task/src/manager.rs +++ b/common/task/src/manager.rs @@ -46,6 +46,8 @@ enum TaskError { pub enum TaskStatus { #[error("Ready")] Ready, + #[error("Ready and connected to gateway: {0}")] + ReadyWithGateway(String), } /// Listens to status and error messages from tasks, as well as notifying them to gracefully @@ -161,10 +163,14 @@ impl TaskManager { self.notify_tx.send(()) } - pub async fn start_status_listener(&mut self, mut sender: StatusSender) { + pub async fn start_status_listener( + &mut self, + mut sender: StatusSender, + start_status: TaskStatus, + ) { // Announce that we are operational. This means that in the application where this is used, // everything is up and running and ready to go. - if let Err(msg) = sender.send(Box::new(TaskStatus::Ready)).await { + if let Err(msg) = sender.send(Box::new(start_status)).await { log::error!("Error sending status message: {}", msg); }; diff --git a/nym-connect/desktop/src-tauri/src/events.rs b/nym-connect/desktop/src-tauri/src/events.rs index fb9186913f..09197b388d 100644 --- a/nym-connect/desktop/src-tauri/src/events.rs +++ b/nym-connect/desktop/src-tauri/src/events.rs @@ -39,7 +39,7 @@ pub async fn handle_task_status( window: &tauri::Window, ) { match task_status { - TaskStatus::Ready => { + TaskStatus::Ready | TaskStatus::ReadyWithGateway(_) => { { let mut state_w = state.write().await; state_w.mark_connected(window); diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 1c18a5f3d0..69995214b8 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -650,7 +650,9 @@ where // TODO: more graceful handling here, surely both variants should work... I think? if let TaskHandle::Internal(task_manager) = &mut started_client.task_handle { - task_manager.start_status_listener(socks5_status_tx).await; + task_manager + .start_status_listener(socks5_status_tx, TaskStatus::Ready) + .await; match socks5_status_rx .next() .await @@ -661,6 +663,9 @@ where TaskStatus::Ready => { log::debug!("Socks5 connected"); } + TaskStatus::ReadyWithGateway(gateway) => { + log::debug!("Socks5 connected to {gateway}"); + } } } else { return Err(Error::new_unsupported( From 5bb9e36842e93d06c67ac8860dfdbf58fb354b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 11 Mar 2024 18:03:39 +0100 Subject: [PATCH 181/394] Tweak display impl for IpPair (#4454) --- common/ip-packet-requests/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index 462472b2e3..d0357d0aa4 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -25,7 +25,7 @@ impl IpPair { impl Display for IpPair { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - writeln!(f, "IPv4: {}, IPV6: {}", self.ipv4, self.ipv6) + write!(f, "IPv4: {}, IPv6: {}", self.ipv4, self.ipv6) } } From a0958cddb4a39f4c1210065acefb0624b08cd3f7 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Tue, 12 Mar 2024 10:03:02 +0000 Subject: [PATCH 182/394] Rework hash GitHub Action to be pre-bundled (#4462) * Add released GitHub Action bundle * Add settings from `owner` and `repo` * fix typo * Remove module type * Move to subdir * Publish with dependencies in bundle * Change handling of version --------- Co-authored-by: Mark Sinclair <mmsinclair@users.noreply.github.com> Co-authored-by: pierre <dommerc.pierre@gmail.com> --- .github/actions/nym-hash-releases/action.yml | 12 +- .../nym-hash-releases/dist/37.index.js | 450 + .../actions/nym-hash-releases/dist/index.js | 24274 ++++++++++++++++ .../actions/nym-hash-releases/dist/thread.js | 57 + .github/actions/nym-hash-releases/index.js | 15 - .../actions/nym-hash-releases/package.json | 15 +- .../actions/nym-hash-releases/src/README.md | 14 + .../{ => src}/create-hashes.mjs | 12 +- .../actions/nym-hash-releases/src/index.js | 21 + .../{ => src}/package-lock.json | 107 +- .../nym-hash-releases/src/package.json | 23 + .../nym-hash-releases/{ => src}/run-local.mjs | 0 12 files changed, 24931 insertions(+), 69 deletions(-) create mode 100644 .github/actions/nym-hash-releases/dist/37.index.js create mode 100644 .github/actions/nym-hash-releases/dist/index.js create mode 100644 .github/actions/nym-hash-releases/dist/thread.js delete mode 100644 .github/actions/nym-hash-releases/index.js create mode 100644 .github/actions/nym-hash-releases/src/README.md rename .github/actions/nym-hash-releases/{ => src}/create-hashes.mjs (97%) create mode 100644 .github/actions/nym-hash-releases/src/index.js rename .github/actions/nym-hash-releases/{ => src}/package-lock.json (84%) create mode 100644 .github/actions/nym-hash-releases/src/package.json rename .github/actions/nym-hash-releases/{ => src}/run-local.mjs (100%) diff --git a/.github/actions/nym-hash-releases/action.yml b/.github/actions/nym-hash-releases/action.yml index fbd57ea39d..4aac45db17 100644 --- a/.github/actions/nym-hash-releases/action.yml +++ b/.github/actions/nym-hash-releases/action.yml @@ -14,12 +14,20 @@ inputs: description: 'The tag/release to process. Uses the release id when trigger from a release.' required: false default: '' + repo: + description: 'The repo to use. Defaults to "nym".' + required: false + default: 'nym' + owner: + description: 'The repo owner to use. Defaults to "nymtech".' + required: false + default: 'nymtech' outputs: hashes: description: 'A string containing JSON with the release asset hashes and signatures' runs: - using: 'node16' - main: 'index.js' + using: 'node20' + main: 'dist/index.js' branding: icon: 'hash' color: 'green' diff --git a/.github/actions/nym-hash-releases/dist/37.index.js b/.github/actions/nym-hash-releases/dist/37.index.js new file mode 100644 index 0000000000..62eb6b6493 --- /dev/null +++ b/.github/actions/nym-hash-releases/dist/37.index.js @@ -0,0 +1,450 @@ +export const id = 37; +export const ids = [37]; +export const modules = { + +/***/ 4037: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __webpack_require__) => { + +__webpack_require__.r(__webpack_exports__); +/* harmony export */ __webpack_require__.d(__webpack_exports__, { +/* harmony export */ "toFormData": () => (/* binding */ toFormData) +/* harmony export */ }); +/* harmony import */ var fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(2777); +/* harmony import */ var formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(8010); + + + +let s = 0; +const S = { + START_BOUNDARY: s++, + HEADER_FIELD_START: s++, + HEADER_FIELD: s++, + HEADER_VALUE_START: s++, + HEADER_VALUE: s++, + HEADER_VALUE_ALMOST_DONE: s++, + HEADERS_ALMOST_DONE: s++, + PART_DATA_START: s++, + PART_DATA: s++, + END: s++ +}; + +let f = 1; +const F = { + PART_BOUNDARY: f, + LAST_BOUNDARY: f *= 2 +}; + +const LF = 10; +const CR = 13; +const SPACE = 32; +const HYPHEN = 45; +const COLON = 58; +const A = 97; +const Z = 122; + +const lower = c => c | 0x20; + +const noop = () => {}; + +class MultipartParser { + /** + * @param {string} boundary + */ + constructor(boundary) { + this.index = 0; + this.flags = 0; + + this.onHeaderEnd = noop; + this.onHeaderField = noop; + this.onHeadersEnd = noop; + this.onHeaderValue = noop; + this.onPartBegin = noop; + this.onPartData = noop; + this.onPartEnd = noop; + + this.boundaryChars = {}; + + boundary = '\r\n--' + boundary; + const ui8a = new Uint8Array(boundary.length); + for (let i = 0; i < boundary.length; i++) { + ui8a[i] = boundary.charCodeAt(i); + this.boundaryChars[ui8a[i]] = true; + } + + this.boundary = ui8a; + this.lookbehind = new Uint8Array(this.boundary.length + 8); + this.state = S.START_BOUNDARY; + } + + /** + * @param {Uint8Array} data + */ + write(data) { + let i = 0; + const length_ = data.length; + let previousIndex = this.index; + let {lookbehind, boundary, boundaryChars, index, state, flags} = this; + const boundaryLength = this.boundary.length; + const boundaryEnd = boundaryLength - 1; + const bufferLength = data.length; + let c; + let cl; + + const mark = name => { + this[name + 'Mark'] = i; + }; + + const clear = name => { + delete this[name + 'Mark']; + }; + + const callback = (callbackSymbol, start, end, ui8a) => { + if (start === undefined || start !== end) { + this[callbackSymbol](ui8a && ui8a.subarray(start, end)); + } + }; + + const dataCallback = (name, clear) => { + const markSymbol = name + 'Mark'; + if (!(markSymbol in this)) { + return; + } + + if (clear) { + callback(name, this[markSymbol], i, data); + delete this[markSymbol]; + } else { + callback(name, this[markSymbol], data.length, data); + this[markSymbol] = 0; + } + }; + + for (i = 0; i < length_; i++) { + c = data[i]; + + switch (state) { + case S.START_BOUNDARY: + if (index === boundary.length - 2) { + if (c === HYPHEN) { + flags |= F.LAST_BOUNDARY; + } else if (c !== CR) { + return; + } + + index++; + break; + } else if (index - 1 === boundary.length - 2) { + if (flags & F.LAST_BOUNDARY && c === HYPHEN) { + state = S.END; + flags = 0; + } else if (!(flags & F.LAST_BOUNDARY) && c === LF) { + index = 0; + callback('onPartBegin'); + state = S.HEADER_FIELD_START; + } else { + return; + } + + break; + } + + if (c !== boundary[index + 2]) { + index = -2; + } + + if (c === boundary[index + 2]) { + index++; + } + + break; + case S.HEADER_FIELD_START: + state = S.HEADER_FIELD; + mark('onHeaderField'); + index = 0; + // falls through + case S.HEADER_FIELD: + if (c === CR) { + clear('onHeaderField'); + state = S.HEADERS_ALMOST_DONE; + break; + } + + index++; + if (c === HYPHEN) { + break; + } + + if (c === COLON) { + if (index === 1) { + // empty header field + return; + } + + dataCallback('onHeaderField', true); + state = S.HEADER_VALUE_START; + break; + } + + cl = lower(c); + if (cl < A || cl > Z) { + return; + } + + break; + case S.HEADER_VALUE_START: + if (c === SPACE) { + break; + } + + mark('onHeaderValue'); + state = S.HEADER_VALUE; + // falls through + case S.HEADER_VALUE: + if (c === CR) { + dataCallback('onHeaderValue', true); + callback('onHeaderEnd'); + state = S.HEADER_VALUE_ALMOST_DONE; + } + + break; + case S.HEADER_VALUE_ALMOST_DONE: + if (c !== LF) { + return; + } + + state = S.HEADER_FIELD_START; + break; + case S.HEADERS_ALMOST_DONE: + if (c !== LF) { + return; + } + + callback('onHeadersEnd'); + state = S.PART_DATA_START; + break; + case S.PART_DATA_START: + state = S.PART_DATA; + mark('onPartData'); + // falls through + case S.PART_DATA: + previousIndex = index; + + if (index === 0) { + // boyer-moore derrived algorithm to safely skip non-boundary data + i += boundaryEnd; + while (i < bufferLength && !(data[i] in boundaryChars)) { + i += boundaryLength; + } + + i -= boundaryEnd; + c = data[i]; + } + + if (index < boundary.length) { + if (boundary[index] === c) { + if (index === 0) { + dataCallback('onPartData', true); + } + + index++; + } else { + index = 0; + } + } else if (index === boundary.length) { + index++; + if (c === CR) { + // CR = part boundary + flags |= F.PART_BOUNDARY; + } else if (c === HYPHEN) { + // HYPHEN = end boundary + flags |= F.LAST_BOUNDARY; + } else { + index = 0; + } + } else if (index - 1 === boundary.length) { + if (flags & F.PART_BOUNDARY) { + index = 0; + if (c === LF) { + // unset the PART_BOUNDARY flag + flags &= ~F.PART_BOUNDARY; + callback('onPartEnd'); + callback('onPartBegin'); + state = S.HEADER_FIELD_START; + break; + } + } else if (flags & F.LAST_BOUNDARY) { + if (c === HYPHEN) { + callback('onPartEnd'); + state = S.END; + flags = 0; + } else { + index = 0; + } + } else { + index = 0; + } + } + + if (index > 0) { + // when matching a possible boundary, keep a lookbehind reference + // in case it turns out to be a false lead + lookbehind[index - 1] = c; + } else if (previousIndex > 0) { + // if our boundary turned out to be rubbish, the captured lookbehind + // belongs to partData + const _lookbehind = new Uint8Array(lookbehind.buffer, lookbehind.byteOffset, lookbehind.byteLength); + callback('onPartData', 0, previousIndex, _lookbehind); + previousIndex = 0; + mark('onPartData'); + + // reconsider the current character even so it interrupted the sequence + // it could be the beginning of a new sequence + i--; + } + + break; + case S.END: + break; + default: + throw new Error(`Unexpected state entered: ${state}`); + } + } + + dataCallback('onHeaderField'); + dataCallback('onHeaderValue'); + dataCallback('onPartData'); + + // Update properties for the next call + this.index = index; + this.state = state; + this.flags = flags; + } + + end() { + if ((this.state === S.HEADER_FIELD_START && this.index === 0) || + (this.state === S.PART_DATA && this.index === this.boundary.length)) { + this.onPartEnd(); + } else if (this.state !== S.END) { + throw new Error('MultipartParser.end(): stream ended unexpectedly'); + } + } +} + +function _fileName(headerValue) { + // matches either a quoted-string or a token (RFC 2616 section 19.5.1) + const m = headerValue.match(/\bfilename=("(.*?)"|([^()<>@,;:\\"/[\]?={}\s\t]+))($|;\s)/i); + if (!m) { + return; + } + + const match = m[2] || m[3] || ''; + let filename = match.slice(match.lastIndexOf('\\') + 1); + filename = filename.replace(/%22/g, '"'); + filename = filename.replace(/&#(\d{4});/g, (m, code) => { + return String.fromCharCode(code); + }); + return filename; +} + +async function toFormData(Body, ct) { + if (!/multipart/i.test(ct)) { + throw new TypeError('Failed to fetch'); + } + + const m = ct.match(/boundary=(?:"([^"]+)"|([^;]+))/i); + + if (!m) { + throw new TypeError('no or bad content-type header, no multipart boundary'); + } + + const parser = new MultipartParser(m[1] || m[2]); + + let headerField; + let headerValue; + let entryValue; + let entryName; + let contentType; + let filename; + const entryChunks = []; + const formData = new formdata_polyfill_esm_min_js__WEBPACK_IMPORTED_MODULE_1__/* .FormData */ .Ct(); + + const onPartData = ui8a => { + entryValue += decoder.decode(ui8a, {stream: true}); + }; + + const appendToFile = ui8a => { + entryChunks.push(ui8a); + }; + + const appendFileToFormData = () => { + const file = new fetch_blob_from_js__WEBPACK_IMPORTED_MODULE_0__/* .File */ .$B(entryChunks, filename, {type: contentType}); + formData.append(entryName, file); + }; + + const appendEntryToFormData = () => { + formData.append(entryName, entryValue); + }; + + const decoder = new TextDecoder('utf-8'); + decoder.decode(); + + parser.onPartBegin = function () { + parser.onPartData = onPartData; + parser.onPartEnd = appendEntryToFormData; + + headerField = ''; + headerValue = ''; + entryValue = ''; + entryName = ''; + contentType = ''; + filename = null; + entryChunks.length = 0; + }; + + parser.onHeaderField = function (ui8a) { + headerField += decoder.decode(ui8a, {stream: true}); + }; + + parser.onHeaderValue = function (ui8a) { + headerValue += decoder.decode(ui8a, {stream: true}); + }; + + parser.onHeaderEnd = function () { + headerValue += decoder.decode(); + headerField = headerField.toLowerCase(); + + if (headerField === 'content-disposition') { + // matches either a quoted-string or a token (RFC 2616 section 19.5.1) + const m = headerValue.match(/\bname=("([^"]*)"|([^()<>@,;:\\"/[\]?={}\s\t]+))/i); + + if (m) { + entryName = m[2] || m[3] || ''; + } + + filename = _fileName(headerValue); + + if (filename) { + parser.onPartData = appendToFile; + parser.onPartEnd = appendFileToFormData; + } + } else if (headerField === 'content-type') { + contentType = headerValue; + } + + headerValue = ''; + headerField = ''; + }; + + for await (const chunk of Body) { + parser.write(chunk); + } + + parser.end(); + + return formData; +} + + +/***/ }) + +}; diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js new file mode 100644 index 0000000000..6759b28f93 --- /dev/null +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -0,0 +1,24274 @@ +import { createRequire as __WEBPACK_EXTERNAL_createRequire } from "module"; +/******/ var __webpack_modules__ = ({ + +/***/ 7351: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.issue = exports.issueCommand = void 0; +const os = __importStar(__nccwpck_require__(2037)); +const utils_1 = __nccwpck_require__(5278); +/** + * Commands + * + * Command Format: + * ::name key=value,key=value::message + * + * Examples: + * ::warning::This is the message + * ::set-env name=MY_VAR::some value + */ +function issueCommand(command, properties, message) { + const cmd = new Command(command, properties, message); + process.stdout.write(cmd.toString() + os.EOL); +} +exports.issueCommand = issueCommand; +function issue(name, message = '') { + issueCommand(name, {}, message); +} +exports.issue = issue; +const CMD_STRING = '::'; +class Command { + constructor(command, properties, message) { + if (!command) { + command = 'missing.command'; + } + this.command = command; + this.properties = properties; + this.message = message; + } + toString() { + let cmdStr = CMD_STRING + this.command; + if (this.properties && Object.keys(this.properties).length > 0) { + cmdStr += ' '; + let first = true; + for (const key in this.properties) { + if (this.properties.hasOwnProperty(key)) { + const val = this.properties[key]; + if (val) { + if (first) { + first = false; + } + else { + cmdStr += ','; + } + cmdStr += `${key}=${escapeProperty(val)}`; + } + } + } + } + cmdStr += `${CMD_STRING}${escapeData(this.message)}`; + return cmdStr; + } +} +function escapeData(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A'); +} +function escapeProperty(s) { + return utils_1.toCommandValue(s) + .replace(/%/g, '%25') + .replace(/\r/g, '%0D') + .replace(/\n/g, '%0A') + .replace(/:/g, '%3A') + .replace(/,/g, '%2C'); +} +//# sourceMappingURL=command.js.map + +/***/ }), + +/***/ 2186: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getIDToken = exports.getState = exports.saveState = exports.group = exports.endGroup = exports.startGroup = exports.info = exports.notice = exports.warning = exports.error = exports.debug = exports.isDebug = exports.setFailed = exports.setCommandEcho = exports.setOutput = exports.getBooleanInput = exports.getMultilineInput = exports.getInput = exports.addPath = exports.setSecret = exports.exportVariable = exports.ExitCode = void 0; +const command_1 = __nccwpck_require__(7351); +const file_command_1 = __nccwpck_require__(717); +const utils_1 = __nccwpck_require__(5278); +const os = __importStar(__nccwpck_require__(2037)); +const path = __importStar(__nccwpck_require__(1017)); +const oidc_utils_1 = __nccwpck_require__(8041); +/** + * The code to exit an action + */ +var ExitCode; +(function (ExitCode) { + /** + * A code indicating that the action was successful + */ + ExitCode[ExitCode["Success"] = 0] = "Success"; + /** + * A code indicating that the action was a failure + */ + ExitCode[ExitCode["Failure"] = 1] = "Failure"; +})(ExitCode = exports.ExitCode || (exports.ExitCode = {})); +//----------------------------------------------------------------------- +// Variables +//----------------------------------------------------------------------- +/** + * Sets env variable for this action and future actions in the job + * @param name the name of the variable to set + * @param val the value of the variable. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function exportVariable(name, val) { + const convertedVal = utils_1.toCommandValue(val); + process.env[name] = convertedVal; + const filePath = process.env['GITHUB_ENV'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('ENV', file_command_1.prepareKeyValueMessage(name, val)); + } + command_1.issueCommand('set-env', { name }, convertedVal); +} +exports.exportVariable = exportVariable; +/** + * Registers a secret which will get masked from logs + * @param secret value of the secret + */ +function setSecret(secret) { + command_1.issueCommand('add-mask', {}, secret); +} +exports.setSecret = setSecret; +/** + * Prepends inputPath to the PATH (for this action and future actions) + * @param inputPath + */ +function addPath(inputPath) { + const filePath = process.env['GITHUB_PATH'] || ''; + if (filePath) { + file_command_1.issueFileCommand('PATH', inputPath); + } + else { + command_1.issueCommand('add-path', {}, inputPath); + } + process.env['PATH'] = `${inputPath}${path.delimiter}${process.env['PATH']}`; +} +exports.addPath = addPath; +/** + * Gets the value of an input. + * Unless trimWhitespace is set to false in InputOptions, the value is also trimmed. + * Returns an empty string if the value is not defined. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string + */ +function getInput(name, options) { + const val = process.env[`INPUT_${name.replace(/ /g, '_').toUpperCase()}`] || ''; + if (options && options.required && !val) { + throw new Error(`Input required and not supplied: ${name}`); + } + if (options && options.trimWhitespace === false) { + return val; + } + return val.trim(); +} +exports.getInput = getInput; +/** + * Gets the values of an multiline input. Each value is also trimmed. + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns string[] + * + */ +function getMultilineInput(name, options) { + const inputs = getInput(name, options) + .split('\n') + .filter(x => x !== ''); + if (options && options.trimWhitespace === false) { + return inputs; + } + return inputs.map(input => input.trim()); +} +exports.getMultilineInput = getMultilineInput; +/** + * Gets the input value of the boolean type in the YAML 1.2 "core schema" specification. + * Support boolean input list: `true | True | TRUE | false | False | FALSE` . + * The return value is also in boolean type. + * ref: https://yaml.org/spec/1.2/spec.html#id2804923 + * + * @param name name of the input to get + * @param options optional. See InputOptions. + * @returns boolean + */ +function getBooleanInput(name, options) { + const trueValue = ['true', 'True', 'TRUE']; + const falseValue = ['false', 'False', 'FALSE']; + const val = getInput(name, options); + if (trueValue.includes(val)) + return true; + if (falseValue.includes(val)) + return false; + throw new TypeError(`Input does not meet YAML 1.2 "Core Schema" specification: ${name}\n` + + `Support boolean input list: \`true | True | TRUE | false | False | FALSE\``); +} +exports.getBooleanInput = getBooleanInput; +/** + * Sets the value of an output. + * + * @param name name of the output to set + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function setOutput(name, value) { + const filePath = process.env['GITHUB_OUTPUT'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('OUTPUT', file_command_1.prepareKeyValueMessage(name, value)); + } + process.stdout.write(os.EOL); + command_1.issueCommand('set-output', { name }, utils_1.toCommandValue(value)); +} +exports.setOutput = setOutput; +/** + * Enables or disables the echoing of commands into stdout for the rest of the step. + * Echoing is disabled by default if ACTIONS_STEP_DEBUG is not set. + * + */ +function setCommandEcho(enabled) { + command_1.issue('echo', enabled ? 'on' : 'off'); +} +exports.setCommandEcho = setCommandEcho; +//----------------------------------------------------------------------- +// Results +//----------------------------------------------------------------------- +/** + * Sets the action status to failed. + * When the action exits it will be with an exit code of 1 + * @param message add error issue message + */ +function setFailed(message) { + process.exitCode = ExitCode.Failure; + error(message); +} +exports.setFailed = setFailed; +//----------------------------------------------------------------------- +// Logging Commands +//----------------------------------------------------------------------- +/** + * Gets whether Actions Step Debug is on or not + */ +function isDebug() { + return process.env['RUNNER_DEBUG'] === '1'; +} +exports.isDebug = isDebug; +/** + * Writes debug message to user log + * @param message debug message + */ +function debug(message) { + command_1.issueCommand('debug', {}, message); +} +exports.debug = debug; +/** + * Adds an error issue + * @param message error issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function error(message, properties = {}) { + command_1.issueCommand('error', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.error = error; +/** + * Adds a warning issue + * @param message warning issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function warning(message, properties = {}) { + command_1.issueCommand('warning', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.warning = warning; +/** + * Adds a notice issue + * @param message notice issue message. Errors will be converted to string via toString() + * @param properties optional properties to add to the annotation. + */ +function notice(message, properties = {}) { + command_1.issueCommand('notice', utils_1.toCommandProperties(properties), message instanceof Error ? message.toString() : message); +} +exports.notice = notice; +/** + * Writes info to log with console.log. + * @param message info message + */ +function info(message) { + process.stdout.write(message + os.EOL); +} +exports.info = info; +/** + * Begin an output group. + * + * Output until the next `groupEnd` will be foldable in this group + * + * @param name The name of the output group + */ +function startGroup(name) { + command_1.issue('group', name); +} +exports.startGroup = startGroup; +/** + * End an output group. + */ +function endGroup() { + command_1.issue('endgroup'); +} +exports.endGroup = endGroup; +/** + * Wrap an asynchronous function call in a group. + * + * Returns the same type as the function itself. + * + * @param name The name of the group + * @param fn The function to wrap in the group + */ +function group(name, fn) { + return __awaiter(this, void 0, void 0, function* () { + startGroup(name); + let result; + try { + result = yield fn(); + } + finally { + endGroup(); + } + return result; + }); +} +exports.group = group; +//----------------------------------------------------------------------- +// Wrapper action state +//----------------------------------------------------------------------- +/** + * Saves state for current action, the state can only be retrieved by this action's post job execution. + * + * @param name name of the state to store + * @param value value to store. Non-string values will be converted to a string via JSON.stringify + */ +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function saveState(name, value) { + const filePath = process.env['GITHUB_STATE'] || ''; + if (filePath) { + return file_command_1.issueFileCommand('STATE', file_command_1.prepareKeyValueMessage(name, value)); + } + command_1.issueCommand('save-state', { name }, utils_1.toCommandValue(value)); +} +exports.saveState = saveState; +/** + * Gets the value of an state set by this action's main execution. + * + * @param name name of the state to get + * @returns string + */ +function getState(name) { + return process.env[`STATE_${name}`] || ''; +} +exports.getState = getState; +function getIDToken(aud) { + return __awaiter(this, void 0, void 0, function* () { + return yield oidc_utils_1.OidcClient.getIDToken(aud); + }); +} +exports.getIDToken = getIDToken; +/** + * Summary exports + */ +var summary_1 = __nccwpck_require__(1327); +Object.defineProperty(exports, "summary", ({ enumerable: true, get: function () { return summary_1.summary; } })); +/** + * @deprecated use core.summary + */ +var summary_2 = __nccwpck_require__(1327); +Object.defineProperty(exports, "markdownSummary", ({ enumerable: true, get: function () { return summary_2.markdownSummary; } })); +/** + * Path exports + */ +var path_utils_1 = __nccwpck_require__(2981); +Object.defineProperty(exports, "toPosixPath", ({ enumerable: true, get: function () { return path_utils_1.toPosixPath; } })); +Object.defineProperty(exports, "toWin32Path", ({ enumerable: true, get: function () { return path_utils_1.toWin32Path; } })); +Object.defineProperty(exports, "toPlatformPath", ({ enumerable: true, get: function () { return path_utils_1.toPlatformPath; } })); +//# sourceMappingURL=core.js.map + +/***/ }), + +/***/ 717: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +// For internal use, subject to change. +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.prepareKeyValueMessage = exports.issueFileCommand = void 0; +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +const fs = __importStar(__nccwpck_require__(7147)); +const os = __importStar(__nccwpck_require__(2037)); +const uuid_1 = __nccwpck_require__(5840); +const utils_1 = __nccwpck_require__(5278); +function issueFileCommand(command, message) { + const filePath = process.env[`GITHUB_${command}`]; + if (!filePath) { + throw new Error(`Unable to find environment variable for file command ${command}`); + } + if (!fs.existsSync(filePath)) { + throw new Error(`Missing file at path: ${filePath}`); + } + fs.appendFileSync(filePath, `${utils_1.toCommandValue(message)}${os.EOL}`, { + encoding: 'utf8' + }); +} +exports.issueFileCommand = issueFileCommand; +function prepareKeyValueMessage(key, value) { + const delimiter = `ghadelimiter_${uuid_1.v4()}`; + const convertedValue = utils_1.toCommandValue(value); + // These should realistically never happen, but just in case someone finds a + // way to exploit uuid generation let's not allow keys or values that contain + // the delimiter. + if (key.includes(delimiter)) { + throw new Error(`Unexpected input: name should not contain the delimiter "${delimiter}"`); + } + if (convertedValue.includes(delimiter)) { + throw new Error(`Unexpected input: value should not contain the delimiter "${delimiter}"`); + } + return `${key}<<${delimiter}${os.EOL}${convertedValue}${os.EOL}${delimiter}`; +} +exports.prepareKeyValueMessage = prepareKeyValueMessage; +//# sourceMappingURL=file-command.js.map + +/***/ }), + +/***/ 8041: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.OidcClient = void 0; +const http_client_1 = __nccwpck_require__(6255); +const auth_1 = __nccwpck_require__(5526); +const core_1 = __nccwpck_require__(2186); +class OidcClient { + static createHttpClient(allowRetry = true, maxRetry = 10) { + const requestOptions = { + allowRetries: allowRetry, + maxRetries: maxRetry + }; + return new http_client_1.HttpClient('actions/oidc-client', [new auth_1.BearerCredentialHandler(OidcClient.getRequestToken())], requestOptions); + } + static getRequestToken() { + const token = process.env['ACTIONS_ID_TOKEN_REQUEST_TOKEN']; + if (!token) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_TOKEN env variable'); + } + return token; + } + static getIDTokenUrl() { + const runtimeUrl = process.env['ACTIONS_ID_TOKEN_REQUEST_URL']; + if (!runtimeUrl) { + throw new Error('Unable to get ACTIONS_ID_TOKEN_REQUEST_URL env variable'); + } + return runtimeUrl; + } + static getCall(id_token_url) { + var _a; + return __awaiter(this, void 0, void 0, function* () { + const httpclient = OidcClient.createHttpClient(); + const res = yield httpclient + .getJson(id_token_url) + .catch(error => { + throw new Error(`Failed to get ID Token. \n + Error Code : ${error.statusCode}\n + Error Message: ${error.message}`); + }); + const id_token = (_a = res.result) === null || _a === void 0 ? void 0 : _a.value; + if (!id_token) { + throw new Error('Response json body do not have ID Token field'); + } + return id_token; + }); + } + static getIDToken(audience) { + return __awaiter(this, void 0, void 0, function* () { + try { + // New ID Token is requested from action service + let id_token_url = OidcClient.getIDTokenUrl(); + if (audience) { + const encodedAudience = encodeURIComponent(audience); + id_token_url = `${id_token_url}&audience=${encodedAudience}`; + } + core_1.debug(`ID token url is ${id_token_url}`); + const id_token = yield OidcClient.getCall(id_token_url); + core_1.setSecret(id_token); + return id_token; + } + catch (error) { + throw new Error(`Error message: ${error.message}`); + } + }); + } +} +exports.OidcClient = OidcClient; +//# sourceMappingURL=oidc-utils.js.map + +/***/ }), + +/***/ 2981: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toPlatformPath = exports.toWin32Path = exports.toPosixPath = void 0; +const path = __importStar(__nccwpck_require__(1017)); +/** + * toPosixPath converts the given path to the posix form. On Windows, \\ will be + * replaced with /. + * + * @param pth. Path to transform. + * @return string Posix path. + */ +function toPosixPath(pth) { + return pth.replace(/[\\]/g, '/'); +} +exports.toPosixPath = toPosixPath; +/** + * toWin32Path converts the given path to the win32 form. On Linux, / will be + * replaced with \\. + * + * @param pth. Path to transform. + * @return string Win32 path. + */ +function toWin32Path(pth) { + return pth.replace(/[/]/g, '\\'); +} +exports.toWin32Path = toWin32Path; +/** + * toPlatformPath converts the given path to a platform-specific path. It does + * this by replacing instances of / and \ with the platform-specific path + * separator. + * + * @param pth The path to platformize. + * @return string The platform-specific path. + */ +function toPlatformPath(pth) { + return pth.replace(/[/\\]/g, path.sep); +} +exports.toPlatformPath = toPlatformPath; +//# sourceMappingURL=path-utils.js.map + +/***/ }), + +/***/ 1327: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.summary = exports.markdownSummary = exports.SUMMARY_DOCS_URL = exports.SUMMARY_ENV_VAR = void 0; +const os_1 = __nccwpck_require__(2037); +const fs_1 = __nccwpck_require__(7147); +const { access, appendFile, writeFile } = fs_1.promises; +exports.SUMMARY_ENV_VAR = 'GITHUB_STEP_SUMMARY'; +exports.SUMMARY_DOCS_URL = 'https://docs.github.com/actions/using-workflows/workflow-commands-for-github-actions#adding-a-job-summary'; +class Summary { + constructor() { + this._buffer = ''; + } + /** + * Finds the summary file path from the environment, rejects if env var is not found or file does not exist + * Also checks r/w permissions. + * + * @returns step summary file path + */ + filePath() { + return __awaiter(this, void 0, void 0, function* () { + if (this._filePath) { + return this._filePath; + } + const pathFromEnv = process.env[exports.SUMMARY_ENV_VAR]; + if (!pathFromEnv) { + throw new Error(`Unable to find environment variable for $${exports.SUMMARY_ENV_VAR}. Check if your runtime environment supports job summaries.`); + } + try { + yield access(pathFromEnv, fs_1.constants.R_OK | fs_1.constants.W_OK); + } + catch (_a) { + throw new Error(`Unable to access summary file: '${pathFromEnv}'. Check if the file has correct read/write permissions.`); + } + this._filePath = pathFromEnv; + return this._filePath; + }); + } + /** + * Wraps content in an HTML tag, adding any HTML attributes + * + * @param {string} tag HTML tag to wrap + * @param {string | null} content content within the tag + * @param {[attribute: string]: string} attrs key-value list of HTML attributes to add + * + * @returns {string} content wrapped in HTML element + */ + wrap(tag, content, attrs = {}) { + const htmlAttrs = Object.entries(attrs) + .map(([key, value]) => ` ${key}="${value}"`) + .join(''); + if (!content) { + return `<${tag}${htmlAttrs}>`; + } + return `<${tag}${htmlAttrs}>${content}</${tag}>`; + } + /** + * Writes text in the buffer to the summary buffer file and empties buffer. Will append by default. + * + * @param {SummaryWriteOptions} [options] (optional) options for write operation + * + * @returns {Promise<Summary>} summary instance + */ + write(options) { + return __awaiter(this, void 0, void 0, function* () { + const overwrite = !!(options === null || options === void 0 ? void 0 : options.overwrite); + const filePath = yield this.filePath(); + const writeFunc = overwrite ? writeFile : appendFile; + yield writeFunc(filePath, this._buffer, { encoding: 'utf8' }); + return this.emptyBuffer(); + }); + } + /** + * Clears the summary buffer and wipes the summary file + * + * @returns {Summary} summary instance + */ + clear() { + return __awaiter(this, void 0, void 0, function* () { + return this.emptyBuffer().write({ overwrite: true }); + }); + } + /** + * Returns the current summary buffer as a string + * + * @returns {string} string of summary buffer + */ + stringify() { + return this._buffer; + } + /** + * If the summary buffer is empty + * + * @returns {boolen} true if the buffer is empty + */ + isEmptyBuffer() { + return this._buffer.length === 0; + } + /** + * Resets the summary buffer without writing to summary file + * + * @returns {Summary} summary instance + */ + emptyBuffer() { + this._buffer = ''; + return this; + } + /** + * Adds raw text to the summary buffer + * + * @param {string} text content to add + * @param {boolean} [addEOL=false] (optional) append an EOL to the raw text (default: false) + * + * @returns {Summary} summary instance + */ + addRaw(text, addEOL = false) { + this._buffer += text; + return addEOL ? this.addEOL() : this; + } + /** + * Adds the operating system-specific end-of-line marker to the buffer + * + * @returns {Summary} summary instance + */ + addEOL() { + return this.addRaw(os_1.EOL); + } + /** + * Adds an HTML codeblock to the summary buffer + * + * @param {string} code content to render within fenced code block + * @param {string} lang (optional) language to syntax highlight code + * + * @returns {Summary} summary instance + */ + addCodeBlock(code, lang) { + const attrs = Object.assign({}, (lang && { lang })); + const element = this.wrap('pre', this.wrap('code', code), attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML list to the summary buffer + * + * @param {string[]} items list of items to render + * @param {boolean} [ordered=false] (optional) if the rendered list should be ordered or not (default: false) + * + * @returns {Summary} summary instance + */ + addList(items, ordered = false) { + const tag = ordered ? 'ol' : 'ul'; + const listItems = items.map(item => this.wrap('li', item)).join(''); + const element = this.wrap(tag, listItems); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML table to the summary buffer + * + * @param {SummaryTableCell[]} rows table rows + * + * @returns {Summary} summary instance + */ + addTable(rows) { + const tableBody = rows + .map(row => { + const cells = row + .map(cell => { + if (typeof cell === 'string') { + return this.wrap('td', cell); + } + const { header, data, colspan, rowspan } = cell; + const tag = header ? 'th' : 'td'; + const attrs = Object.assign(Object.assign({}, (colspan && { colspan })), (rowspan && { rowspan })); + return this.wrap(tag, data, attrs); + }) + .join(''); + return this.wrap('tr', cells); + }) + .join(''); + const element = this.wrap('table', tableBody); + return this.addRaw(element).addEOL(); + } + /** + * Adds a collapsable HTML details element to the summary buffer + * + * @param {string} label text for the closed state + * @param {string} content collapsable content + * + * @returns {Summary} summary instance + */ + addDetails(label, content) { + const element = this.wrap('details', this.wrap('summary', label) + content); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML image tag to the summary buffer + * + * @param {string} src path to the image you to embed + * @param {string} alt text description of the image + * @param {SummaryImageOptions} options (optional) addition image attributes + * + * @returns {Summary} summary instance + */ + addImage(src, alt, options) { + const { width, height } = options || {}; + const attrs = Object.assign(Object.assign({}, (width && { width })), (height && { height })); + const element = this.wrap('img', null, Object.assign({ src, alt }, attrs)); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML section heading element + * + * @param {string} text heading text + * @param {number | string} [level=1] (optional) the heading level, default: 1 + * + * @returns {Summary} summary instance + */ + addHeading(text, level) { + const tag = `h${level}`; + const allowedTag = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'].includes(tag) + ? tag + : 'h1'; + const element = this.wrap(allowedTag, text); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML thematic break (<hr>) to the summary buffer + * + * @returns {Summary} summary instance + */ + addSeparator() { + const element = this.wrap('hr', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML line break (<br>) to the summary buffer + * + * @returns {Summary} summary instance + */ + addBreak() { + const element = this.wrap('br', null); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML blockquote to the summary buffer + * + * @param {string} text quote text + * @param {string} cite (optional) citation url + * + * @returns {Summary} summary instance + */ + addQuote(text, cite) { + const attrs = Object.assign({}, (cite && { cite })); + const element = this.wrap('blockquote', text, attrs); + return this.addRaw(element).addEOL(); + } + /** + * Adds an HTML anchor tag to the summary buffer + * + * @param {string} text link text/content + * @param {string} href hyperlink + * + * @returns {Summary} summary instance + */ + addLink(text, href) { + const element = this.wrap('a', text, { href }); + return this.addRaw(element).addEOL(); + } +} +const _summary = new Summary(); +/** + * @deprecated use `core.summary` + */ +exports.markdownSummary = _summary; +exports.summary = _summary; +//# sourceMappingURL=summary.js.map + +/***/ }), + +/***/ 5278: +/***/ ((__unused_webpack_module, exports) => { + + +// We use any as a valid input type +/* eslint-disable @typescript-eslint/no-explicit-any */ +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.toCommandProperties = exports.toCommandValue = void 0; +/** + * Sanitizes an input into a string so it can be passed into issueCommand safely + * @param input input to sanitize into a string + */ +function toCommandValue(input) { + if (input === null || input === undefined) { + return ''; + } + else if (typeof input === 'string' || input instanceof String) { + return input; + } + return JSON.stringify(input); +} +exports.toCommandValue = toCommandValue; +/** + * + * @param annotationProperties + * @returns The command properties to send with the actual annotation command + * See IssueCommandProperties: https://github.com/actions/runner/blob/main/src/Runner.Worker/ActionCommandManager.cs#L646 + */ +function toCommandProperties(annotationProperties) { + if (!Object.keys(annotationProperties).length) { + return {}; + } + return { + title: annotationProperties.title, + file: annotationProperties.file, + line: annotationProperties.startLine, + endLine: annotationProperties.endLine, + col: annotationProperties.startColumn, + endColumn: annotationProperties.endColumn + }; +} +exports.toCommandProperties = toCommandProperties; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 4087: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.Context = void 0; +const fs_1 = __nccwpck_require__(7147); +const os_1 = __nccwpck_require__(2037); +class Context { + /** + * Hydrate the context from the environment + */ + constructor() { + var _a, _b, _c; + this.payload = {}; + if (process.env.GITHUB_EVENT_PATH) { + if (fs_1.existsSync(process.env.GITHUB_EVENT_PATH)) { + this.payload = JSON.parse(fs_1.readFileSync(process.env.GITHUB_EVENT_PATH, { encoding: 'utf8' })); + } + else { + const path = process.env.GITHUB_EVENT_PATH; + process.stdout.write(`GITHUB_EVENT_PATH ${path} does not exist${os_1.EOL}`); + } + } + this.eventName = process.env.GITHUB_EVENT_NAME; + this.sha = process.env.GITHUB_SHA; + this.ref = process.env.GITHUB_REF; + this.workflow = process.env.GITHUB_WORKFLOW; + this.action = process.env.GITHUB_ACTION; + this.actor = process.env.GITHUB_ACTOR; + this.job = process.env.GITHUB_JOB; + this.runNumber = parseInt(process.env.GITHUB_RUN_NUMBER, 10); + this.runId = parseInt(process.env.GITHUB_RUN_ID, 10); + this.apiUrl = (_a = process.env.GITHUB_API_URL) !== null && _a !== void 0 ? _a : `https://api.github.com`; + this.serverUrl = (_b = process.env.GITHUB_SERVER_URL) !== null && _b !== void 0 ? _b : `https://github.com`; + this.graphqlUrl = (_c = process.env.GITHUB_GRAPHQL_URL) !== null && _c !== void 0 ? _c : `https://api.github.com/graphql`; + } + get issue() { + const payload = this.payload; + return Object.assign(Object.assign({}, this.repo), { number: (payload.issue || payload.pull_request || payload).number }); + } + get repo() { + if (process.env.GITHUB_REPOSITORY) { + const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/'); + return { owner, repo }; + } + if (this.payload.repository) { + return { + owner: this.payload.repository.owner.login, + repo: this.payload.repository.name + }; + } + throw new Error("context.repo requires a GITHUB_REPOSITORY environment variable like 'owner/repo'"); + } +} +exports.Context = Context; +//# sourceMappingURL=context.js.map + +/***/ }), + +/***/ 5438: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokit = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const utils_1 = __nccwpck_require__(3030); +exports.context = new Context.Context(); +/** + * Returns a hydrated octokit ready to use for GitHub Actions + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokit(token, options, ...additionalPlugins) { + const GitHubWithPlugins = utils_1.GitHub.plugin(...additionalPlugins); + return new GitHubWithPlugins(utils_1.getOctokitOptions(token, options)); +} +exports.getOctokit = getOctokit; +//# sourceMappingURL=github.js.map + +/***/ }), + +/***/ 7914: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getApiBaseUrl = exports.getProxyAgent = exports.getAuthString = void 0; +const httpClient = __importStar(__nccwpck_require__(6255)); +function getAuthString(token, options) { + if (!token && !options.auth) { + throw new Error('Parameter token or opts.auth is required'); + } + else if (token && options.auth) { + throw new Error('Parameters token and opts.auth may not both be specified'); + } + return typeof options.auth === 'string' ? options.auth : `token ${token}`; +} +exports.getAuthString = getAuthString; +function getProxyAgent(destinationUrl) { + const hc = new httpClient.HttpClient(); + return hc.getAgent(destinationUrl); +} +exports.getProxyAgent = getProxyAgent; +function getApiBaseUrl() { + return process.env['GITHUB_API_URL'] || 'https://api.github.com'; +} +exports.getApiBaseUrl = getApiBaseUrl; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 3030: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.getOctokitOptions = exports.GitHub = exports.defaults = exports.context = void 0; +const Context = __importStar(__nccwpck_require__(4087)); +const Utils = __importStar(__nccwpck_require__(7914)); +// octokit + plugins +const core_1 = __nccwpck_require__(6762); +const plugin_rest_endpoint_methods_1 = __nccwpck_require__(3044); +const plugin_paginate_rest_1 = __nccwpck_require__(4193); +exports.context = new Context.Context(); +const baseUrl = Utils.getApiBaseUrl(); +exports.defaults = { + baseUrl, + request: { + agent: Utils.getProxyAgent(baseUrl) + } +}; +exports.GitHub = core_1.Octokit.plugin(plugin_rest_endpoint_methods_1.restEndpointMethods, plugin_paginate_rest_1.paginateRest).defaults(exports.defaults); +/** + * Convience function to correctly format Octokit Options to pass into the constructor. + * + * @param token the repo PAT or GITHUB_TOKEN + * @param options other options to set + */ +function getOctokitOptions(token, options) { + const opts = Object.assign({}, options || {}); // Shallow clone - don't mutate the object provided by the caller + // Auth + const auth = Utils.getAuthString(token, opts); + if (auth) { + opts.auth = auth; + } + return opts; +} +exports.getOctokitOptions = getOctokitOptions; +//# sourceMappingURL=utils.js.map + +/***/ }), + +/***/ 5526: +/***/ (function(__unused_webpack_module, exports) { + + +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.PersonalAccessTokenCredentialHandler = exports.BearerCredentialHandler = exports.BasicCredentialHandler = void 0; +class BasicCredentialHandler { + constructor(username, password) { + this.username = username; + this.password = password; + } + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`${this.username}:${this.password}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BasicCredentialHandler = BasicCredentialHandler; +class BearerCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Bearer ${this.token}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.BearerCredentialHandler = BearerCredentialHandler; +class PersonalAccessTokenCredentialHandler { + constructor(token) { + this.token = token; + } + // currently implements pre-authorization + // TODO: support preAuth = false where it hooks on 401 + prepareRequest(options) { + if (!options.headers) { + throw Error('The request has no headers'); + } + options.headers['Authorization'] = `Basic ${Buffer.from(`PAT:${this.token}`).toString('base64')}`; + } + // This handler cannot handle 401 + canHandleAuthentication() { + return false; + } + handleAuthentication() { + return __awaiter(this, void 0, void 0, function* () { + throw new Error('not implemented'); + }); + } +} +exports.PersonalAccessTokenCredentialHandler = PersonalAccessTokenCredentialHandler; +//# sourceMappingURL=auth.js.map + +/***/ }), + +/***/ 6255: +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { + + +/* eslint-disable @typescript-eslint/no-explicit-any */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { + function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); +}; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.HttpClient = exports.isHttps = exports.HttpClientResponse = exports.HttpClientError = exports.getProxyUrl = exports.MediaTypes = exports.Headers = exports.HttpCodes = void 0; +const http = __importStar(__nccwpck_require__(3685)); +const https = __importStar(__nccwpck_require__(5687)); +const pm = __importStar(__nccwpck_require__(9835)); +const tunnel = __importStar(__nccwpck_require__(4294)); +var HttpCodes; +(function (HttpCodes) { + HttpCodes[HttpCodes["OK"] = 200] = "OK"; + HttpCodes[HttpCodes["MultipleChoices"] = 300] = "MultipleChoices"; + HttpCodes[HttpCodes["MovedPermanently"] = 301] = "MovedPermanently"; + HttpCodes[HttpCodes["ResourceMoved"] = 302] = "ResourceMoved"; + HttpCodes[HttpCodes["SeeOther"] = 303] = "SeeOther"; + HttpCodes[HttpCodes["NotModified"] = 304] = "NotModified"; + HttpCodes[HttpCodes["UseProxy"] = 305] = "UseProxy"; + HttpCodes[HttpCodes["SwitchProxy"] = 306] = "SwitchProxy"; + HttpCodes[HttpCodes["TemporaryRedirect"] = 307] = "TemporaryRedirect"; + HttpCodes[HttpCodes["PermanentRedirect"] = 308] = "PermanentRedirect"; + HttpCodes[HttpCodes["BadRequest"] = 400] = "BadRequest"; + HttpCodes[HttpCodes["Unauthorized"] = 401] = "Unauthorized"; + HttpCodes[HttpCodes["PaymentRequired"] = 402] = "PaymentRequired"; + HttpCodes[HttpCodes["Forbidden"] = 403] = "Forbidden"; + HttpCodes[HttpCodes["NotFound"] = 404] = "NotFound"; + HttpCodes[HttpCodes["MethodNotAllowed"] = 405] = "MethodNotAllowed"; + HttpCodes[HttpCodes["NotAcceptable"] = 406] = "NotAcceptable"; + HttpCodes[HttpCodes["ProxyAuthenticationRequired"] = 407] = "ProxyAuthenticationRequired"; + HttpCodes[HttpCodes["RequestTimeout"] = 408] = "RequestTimeout"; + HttpCodes[HttpCodes["Conflict"] = 409] = "Conflict"; + HttpCodes[HttpCodes["Gone"] = 410] = "Gone"; + HttpCodes[HttpCodes["TooManyRequests"] = 429] = "TooManyRequests"; + HttpCodes[HttpCodes["InternalServerError"] = 500] = "InternalServerError"; + HttpCodes[HttpCodes["NotImplemented"] = 501] = "NotImplemented"; + HttpCodes[HttpCodes["BadGateway"] = 502] = "BadGateway"; + HttpCodes[HttpCodes["ServiceUnavailable"] = 503] = "ServiceUnavailable"; + HttpCodes[HttpCodes["GatewayTimeout"] = 504] = "GatewayTimeout"; +})(HttpCodes = exports.HttpCodes || (exports.HttpCodes = {})); +var Headers; +(function (Headers) { + Headers["Accept"] = "accept"; + Headers["ContentType"] = "content-type"; +})(Headers = exports.Headers || (exports.Headers = {})); +var MediaTypes; +(function (MediaTypes) { + MediaTypes["ApplicationJson"] = "application/json"; +})(MediaTypes = exports.MediaTypes || (exports.MediaTypes = {})); +/** + * Returns the proxy URL, depending upon the supplied url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ +function getProxyUrl(serverUrl) { + const proxyUrl = pm.getProxyUrl(new URL(serverUrl)); + return proxyUrl ? proxyUrl.href : ''; +} +exports.getProxyUrl = getProxyUrl; +const HttpRedirectCodes = [ + HttpCodes.MovedPermanently, + HttpCodes.ResourceMoved, + HttpCodes.SeeOther, + HttpCodes.TemporaryRedirect, + HttpCodes.PermanentRedirect +]; +const HttpResponseRetryCodes = [ + HttpCodes.BadGateway, + HttpCodes.ServiceUnavailable, + HttpCodes.GatewayTimeout +]; +const RetryableHttpVerbs = ['OPTIONS', 'GET', 'DELETE', 'HEAD']; +const ExponentialBackoffCeiling = 10; +const ExponentialBackoffTimeSlice = 5; +class HttpClientError extends Error { + constructor(message, statusCode) { + super(message); + this.name = 'HttpClientError'; + this.statusCode = statusCode; + Object.setPrototypeOf(this, HttpClientError.prototype); + } +} +exports.HttpClientError = HttpClientError; +class HttpClientResponse { + constructor(message) { + this.message = message; + } + readBody() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + let output = Buffer.alloc(0); + this.message.on('data', (chunk) => { + output = Buffer.concat([output, chunk]); + }); + this.message.on('end', () => { + resolve(output.toString()); + }); + })); + }); + } + readBodyBuffer() { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve) => __awaiter(this, void 0, void 0, function* () { + const chunks = []; + this.message.on('data', (chunk) => { + chunks.push(chunk); + }); + this.message.on('end', () => { + resolve(Buffer.concat(chunks)); + }); + })); + }); + } +} +exports.HttpClientResponse = HttpClientResponse; +function isHttps(requestUrl) { + const parsedUrl = new URL(requestUrl); + return parsedUrl.protocol === 'https:'; +} +exports.isHttps = isHttps; +class HttpClient { + constructor(userAgent, handlers, requestOptions) { + this._ignoreSslError = false; + this._allowRedirects = true; + this._allowRedirectDowngrade = false; + this._maxRedirects = 50; + this._allowRetries = false; + this._maxRetries = 1; + this._keepAlive = false; + this._disposed = false; + this.userAgent = userAgent; + this.handlers = handlers || []; + this.requestOptions = requestOptions; + if (requestOptions) { + if (requestOptions.ignoreSslError != null) { + this._ignoreSslError = requestOptions.ignoreSslError; + } + this._socketTimeout = requestOptions.socketTimeout; + if (requestOptions.allowRedirects != null) { + this._allowRedirects = requestOptions.allowRedirects; + } + if (requestOptions.allowRedirectDowngrade != null) { + this._allowRedirectDowngrade = requestOptions.allowRedirectDowngrade; + } + if (requestOptions.maxRedirects != null) { + this._maxRedirects = Math.max(requestOptions.maxRedirects, 0); + } + if (requestOptions.keepAlive != null) { + this._keepAlive = requestOptions.keepAlive; + } + if (requestOptions.allowRetries != null) { + this._allowRetries = requestOptions.allowRetries; + } + if (requestOptions.maxRetries != null) { + this._maxRetries = requestOptions.maxRetries; + } + } + } + options(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('OPTIONS', requestUrl, null, additionalHeaders || {}); + }); + } + get(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('GET', requestUrl, null, additionalHeaders || {}); + }); + } + del(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('DELETE', requestUrl, null, additionalHeaders || {}); + }); + } + post(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('POST', requestUrl, data, additionalHeaders || {}); + }); + } + patch(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PATCH', requestUrl, data, additionalHeaders || {}); + }); + } + put(requestUrl, data, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('PUT', requestUrl, data, additionalHeaders || {}); + }); + } + head(requestUrl, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request('HEAD', requestUrl, null, additionalHeaders || {}); + }); + } + sendStream(verb, requestUrl, stream, additionalHeaders) { + return __awaiter(this, void 0, void 0, function* () { + return this.request(verb, requestUrl, stream, additionalHeaders); + }); + } + /** + * Gets a typed object from an endpoint + * Be aware that not found returns a null. Other errors (4xx, 5xx) reject the promise + */ + getJson(requestUrl, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + const res = yield this.get(requestUrl, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + postJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.post(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + putJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.put(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + patchJson(requestUrl, obj, additionalHeaders = {}) { + return __awaiter(this, void 0, void 0, function* () { + const data = JSON.stringify(obj, null, 2); + additionalHeaders[Headers.Accept] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.Accept, MediaTypes.ApplicationJson); + additionalHeaders[Headers.ContentType] = this._getExistingOrDefaultHeader(additionalHeaders, Headers.ContentType, MediaTypes.ApplicationJson); + const res = yield this.patch(requestUrl, data, additionalHeaders); + return this._processResponse(res, this.requestOptions); + }); + } + /** + * Makes a raw http request. + * All other methods such as get, post, patch, and request ultimately call this. + * Prefer get, del, post and patch + */ + request(verb, requestUrl, data, headers) { + return __awaiter(this, void 0, void 0, function* () { + if (this._disposed) { + throw new Error('Client has already been disposed.'); + } + const parsedUrl = new URL(requestUrl); + let info = this._prepareRequest(verb, parsedUrl, headers); + // Only perform retries on reads since writes may not be idempotent. + const maxTries = this._allowRetries && RetryableHttpVerbs.includes(verb) + ? this._maxRetries + 1 + : 1; + let numTries = 0; + let response; + do { + response = yield this.requestRaw(info, data); + // Check if it's an authentication challenge + if (response && + response.message && + response.message.statusCode === HttpCodes.Unauthorized) { + let authenticationHandler; + for (const handler of this.handlers) { + if (handler.canHandleAuthentication(response)) { + authenticationHandler = handler; + break; + } + } + if (authenticationHandler) { + return authenticationHandler.handleAuthentication(this, info, data); + } + else { + // We have received an unauthorized response but have no handlers to handle it. + // Let the response return to the caller. + return response; + } + } + let redirectsRemaining = this._maxRedirects; + while (response.message.statusCode && + HttpRedirectCodes.includes(response.message.statusCode) && + this._allowRedirects && + redirectsRemaining > 0) { + const redirectUrl = response.message.headers['location']; + if (!redirectUrl) { + // if there's no location to redirect to, we won't + break; + } + const parsedRedirectUrl = new URL(redirectUrl); + if (parsedUrl.protocol === 'https:' && + parsedUrl.protocol !== parsedRedirectUrl.protocol && + !this._allowRedirectDowngrade) { + throw new Error('Redirect from HTTPS to HTTP protocol. This downgrade is not allowed for security reasons. If you want to allow this behavior, set the allowRedirectDowngrade option to true.'); + } + // we need to finish reading the response before reassigning response + // which will leak the open socket. + yield response.readBody(); + // strip authorization header if redirected to a different hostname + if (parsedRedirectUrl.hostname !== parsedUrl.hostname) { + for (const header in headers) { + // header names are case insensitive + if (header.toLowerCase() === 'authorization') { + delete headers[header]; + } + } + } + // let's make the request with the new redirectUrl + info = this._prepareRequest(verb, parsedRedirectUrl, headers); + response = yield this.requestRaw(info, data); + redirectsRemaining--; + } + if (!response.message.statusCode || + !HttpResponseRetryCodes.includes(response.message.statusCode)) { + // If not a retry code, return immediately instead of retrying + return response; + } + numTries += 1; + if (numTries < maxTries) { + yield response.readBody(); + yield this._performExponentialBackoff(numTries); + } + } while (numTries < maxTries); + return response; + }); + } + /** + * Needs to be called if keepAlive is set to true in request options. + */ + dispose() { + if (this._agent) { + this._agent.destroy(); + } + this._disposed = true; + } + /** + * Raw request. + * @param info + * @param data + */ + requestRaw(info, data) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => { + function callbackForResult(err, res) { + if (err) { + reject(err); + } + else if (!res) { + // If `err` is not passed, then `res` must be passed. + reject(new Error('Unknown error')); + } + else { + resolve(res); + } + } + this.requestRawWithCallback(info, data, callbackForResult); + }); + }); + } + /** + * Raw request with callback. + * @param info + * @param data + * @param onResult + */ + requestRawWithCallback(info, data, onResult) { + if (typeof data === 'string') { + if (!info.options.headers) { + info.options.headers = {}; + } + info.options.headers['Content-Length'] = Buffer.byteLength(data, 'utf8'); + } + let callbackCalled = false; + function handleResult(err, res) { + if (!callbackCalled) { + callbackCalled = true; + onResult(err, res); + } + } + const req = info.httpModule.request(info.options, (msg) => { + const res = new HttpClientResponse(msg); + handleResult(undefined, res); + }); + let socket; + req.on('socket', sock => { + socket = sock; + }); + // If we ever get disconnected, we want the socket to timeout eventually + req.setTimeout(this._socketTimeout || 3 * 60000, () => { + if (socket) { + socket.end(); + } + handleResult(new Error(`Request timeout: ${info.options.path}`)); + }); + req.on('error', function (err) { + // err has statusCode property + // res should have headers + handleResult(err); + }); + if (data && typeof data === 'string') { + req.write(data, 'utf8'); + } + if (data && typeof data !== 'string') { + data.on('close', function () { + req.end(); + }); + data.pipe(req); + } + else { + req.end(); + } + } + /** + * Gets an http agent. This function is useful when you need an http agent that handles + * routing through a proxy server - depending upon the url and proxy environment variables. + * @param serverUrl The server URL where the request will be sent. For example, https://api.github.com + */ + getAgent(serverUrl) { + const parsedUrl = new URL(serverUrl); + return this._getAgent(parsedUrl); + } + _prepareRequest(method, requestUrl, headers) { + const info = {}; + info.parsedUrl = requestUrl; + const usingSsl = info.parsedUrl.protocol === 'https:'; + info.httpModule = usingSsl ? https : http; + const defaultPort = usingSsl ? 443 : 80; + info.options = {}; + info.options.host = info.parsedUrl.hostname; + info.options.port = info.parsedUrl.port + ? parseInt(info.parsedUrl.port) + : defaultPort; + info.options.path = + (info.parsedUrl.pathname || '') + (info.parsedUrl.search || ''); + info.options.method = method; + info.options.headers = this._mergeHeaders(headers); + if (this.userAgent != null) { + info.options.headers['user-agent'] = this.userAgent; + } + info.options.agent = this._getAgent(info.parsedUrl); + // gives handlers an opportunity to participate + if (this.handlers) { + for (const handler of this.handlers) { + handler.prepareRequest(info.options); + } + } + return info; + } + _mergeHeaders(headers) { + if (this.requestOptions && this.requestOptions.headers) { + return Object.assign({}, lowercaseKeys(this.requestOptions.headers), lowercaseKeys(headers || {})); + } + return lowercaseKeys(headers || {}); + } + _getExistingOrDefaultHeader(additionalHeaders, header, _default) { + let clientHeader; + if (this.requestOptions && this.requestOptions.headers) { + clientHeader = lowercaseKeys(this.requestOptions.headers)[header]; + } + return additionalHeaders[header] || clientHeader || _default; + } + _getAgent(parsedUrl) { + let agent; + const proxyUrl = pm.getProxyUrl(parsedUrl); + const useProxy = proxyUrl && proxyUrl.hostname; + if (this._keepAlive && useProxy) { + agent = this._proxyAgent; + } + if (this._keepAlive && !useProxy) { + agent = this._agent; + } + // if agent is already assigned use that agent. + if (agent) { + return agent; + } + const usingSsl = parsedUrl.protocol === 'https:'; + let maxSockets = 100; + if (this.requestOptions) { + maxSockets = this.requestOptions.maxSockets || http.globalAgent.maxSockets; + } + // This is `useProxy` again, but we need to check `proxyURl` directly for TypeScripts's flow analysis. + if (proxyUrl && proxyUrl.hostname) { + const agentOptions = { + maxSockets, + keepAlive: this._keepAlive, + proxy: Object.assign(Object.assign({}, ((proxyUrl.username || proxyUrl.password) && { + proxyAuth: `${proxyUrl.username}:${proxyUrl.password}` + })), { host: proxyUrl.hostname, port: proxyUrl.port }) + }; + let tunnelAgent; + const overHttps = proxyUrl.protocol === 'https:'; + if (usingSsl) { + tunnelAgent = overHttps ? tunnel.httpsOverHttps : tunnel.httpsOverHttp; + } + else { + tunnelAgent = overHttps ? tunnel.httpOverHttps : tunnel.httpOverHttp; + } + agent = tunnelAgent(agentOptions); + this._proxyAgent = agent; + } + // if reusing agent across request and tunneling agent isn't assigned create a new agent + if (this._keepAlive && !agent) { + const options = { keepAlive: this._keepAlive, maxSockets }; + agent = usingSsl ? new https.Agent(options) : new http.Agent(options); + this._agent = agent; + } + // if not using private agent and tunnel agent isn't setup then use global agent + if (!agent) { + agent = usingSsl ? https.globalAgent : http.globalAgent; + } + if (usingSsl && this._ignoreSslError) { + // we don't want to set NODE_TLS_REJECT_UNAUTHORIZED=0 since that will affect request for entire process + // http.RequestOptions doesn't expose a way to modify RequestOptions.agent.options + // we have to cast it to any and change it directly + agent.options = Object.assign(agent.options || {}, { + rejectUnauthorized: false + }); + } + return agent; + } + _performExponentialBackoff(retryNumber) { + return __awaiter(this, void 0, void 0, function* () { + retryNumber = Math.min(ExponentialBackoffCeiling, retryNumber); + const ms = ExponentialBackoffTimeSlice * Math.pow(2, retryNumber); + return new Promise(resolve => setTimeout(() => resolve(), ms)); + }); + } + _processResponse(res, options) { + return __awaiter(this, void 0, void 0, function* () { + return new Promise((resolve, reject) => __awaiter(this, void 0, void 0, function* () { + const statusCode = res.message.statusCode || 0; + const response = { + statusCode, + result: null, + headers: {} + }; + // not found leads to null obj returned + if (statusCode === HttpCodes.NotFound) { + resolve(response); + } + // get the result from the body + function dateTimeDeserializer(key, value) { + if (typeof value === 'string') { + const a = new Date(value); + if (!isNaN(a.valueOf())) { + return a; + } + } + return value; + } + let obj; + let contents; + try { + contents = yield res.readBody(); + if (contents && contents.length > 0) { + if (options && options.deserializeDates) { + obj = JSON.parse(contents, dateTimeDeserializer); + } + else { + obj = JSON.parse(contents); + } + response.result = obj; + } + response.headers = res.message.headers; + } + catch (err) { + // Invalid resource (contents not json); leaving result obj null + } + // note that 3xx redirects are handled by the http layer. + if (statusCode > 299) { + let msg; + // if exception/error in body, attempt to get better error + if (obj && obj.message) { + msg = obj.message; + } + else if (contents && contents.length > 0) { + // it may be the case that the exception is in the body message as string + msg = contents; + } + else { + msg = `Failed request: (${statusCode})`; + } + const err = new HttpClientError(msg, statusCode); + err.result = response.result; + reject(err); + } + else { + resolve(response); + } + })); + }); + } +} +exports.HttpClient = HttpClient; +const lowercaseKeys = (obj) => Object.keys(obj).reduce((c, k) => ((c[k.toLowerCase()] = obj[k]), c), {}); +//# sourceMappingURL=index.js.map + +/***/ }), + +/***/ 9835: +/***/ ((__unused_webpack_module, exports) => { + + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.checkBypass = exports.getProxyUrl = void 0; +function getProxyUrl(reqUrl) { + const usingSsl = reqUrl.protocol === 'https:'; + if (checkBypass(reqUrl)) { + return undefined; + } + const proxyVar = (() => { + if (usingSsl) { + return process.env['https_proxy'] || process.env['HTTPS_PROXY']; + } + else { + return process.env['http_proxy'] || process.env['HTTP_PROXY']; + } + })(); + if (proxyVar) { + try { + return new URL(proxyVar); + } + catch (_a) { + if (!proxyVar.startsWith('http://') && !proxyVar.startsWith('https://')) + return new URL(`http://${proxyVar}`); + } + } + else { + return undefined; + } +} +exports.getProxyUrl = getProxyUrl; +function checkBypass(reqUrl) { + if (!reqUrl.hostname) { + return false; + } + const reqHost = reqUrl.hostname; + if (isLoopbackAddress(reqHost)) { + return true; + } + const noProxy = process.env['no_proxy'] || process.env['NO_PROXY'] || ''; + if (!noProxy) { + return false; + } + // Determine the request port + let reqPort; + if (reqUrl.port) { + reqPort = Number(reqUrl.port); + } + else if (reqUrl.protocol === 'http:') { + reqPort = 80; + } + else if (reqUrl.protocol === 'https:') { + reqPort = 443; + } + // Format the request hostname and hostname with port + const upperReqHosts = [reqUrl.hostname.toUpperCase()]; + if (typeof reqPort === 'number') { + upperReqHosts.push(`${upperReqHosts[0]}:${reqPort}`); + } + // Compare request host against noproxy + for (const upperNoProxyItem of noProxy + .split(',') + .map(x => x.trim().toUpperCase()) + .filter(x => x)) { + if (upperNoProxyItem === '*' || + upperReqHosts.some(x => x === upperNoProxyItem || + x.endsWith(`.${upperNoProxyItem}`) || + (upperNoProxyItem.startsWith('.') && + x.endsWith(`${upperNoProxyItem}`)))) { + return true; + } + } + return false; +} +exports.checkBypass = checkBypass; +function isLoopbackAddress(host) { + const hostLower = host.toLowerCase(); + return (hostLower === 'localhost' || + hostLower.startsWith('127.') || + hostLower.startsWith('[::1]') || + hostLower.startsWith('[0:0:0:0:0:0:0:1]')); +} +//# sourceMappingURL=proxy.js.map + +/***/ }), + +/***/ 334: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +const REGEX_IS_INSTALLATION = /^ghs_/; +const REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token: token, + tokenType + }; +} + +/** + * Prefix token for usage in the Authorization header + * + * @param token OAuth token or JSON Web Token + */ +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + + return `token ${token}`; +} + +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge(route, parameters); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +const createTokenAuth = function createTokenAuth(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + + if (typeof token !== "string") { + throw new Error("[@octokit/auth-token] Token passed to createTokenAuth is not a string"); + } + + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; + +exports.createTokenAuth = createTokenAuth; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 6762: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var universalUserAgent = __nccwpck_require__(5030); +var beforeAfterHook = __nccwpck_require__(3682); +var request = __nccwpck_require__(6234); +var graphql = __nccwpck_require__(8467); +var authToken = __nccwpck_require__(334); + +function _objectWithoutPropertiesLoose(source, excluded) { + if (source == null) return {}; + var target = {}; + var sourceKeys = Object.keys(source); + var key, i; + + for (i = 0; i < sourceKeys.length; i++) { + key = sourceKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + target[key] = source[key]; + } + + return target; +} + +function _objectWithoutProperties(source, excluded) { + if (source == null) return {}; + + var target = _objectWithoutPropertiesLoose(source, excluded); + + var key, i; + + if (Object.getOwnPropertySymbols) { + var sourceSymbolKeys = Object.getOwnPropertySymbols(source); + + for (i = 0; i < sourceSymbolKeys.length; i++) { + key = sourceSymbolKeys[i]; + if (excluded.indexOf(key) >= 0) continue; + if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; + target[key] = source[key]; + } + } + + return target; +} + +const VERSION = "3.6.0"; + +const _excluded = ["authStrategy"]; +class Octokit { + constructor(options = {}) { + const hook = new beforeAfterHook.Collection(); + const requestDefaults = { + baseUrl: request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; // prepend default user agent with `options.userAgent` if set + + requestDefaults.headers["user-agent"] = [options.userAgent, `octokit-core.js/${VERSION} ${universalUserAgent.getUserAgent()}`].filter(Boolean).join(" "); + + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; + } + + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; + } + + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; + } + + this.request = request.request.defaults(requestDefaults); + this.graphql = graphql.withCustomRequest(this.request).defaults(requestDefaults); + this.log = Object.assign({ + debug: () => {}, + info: () => {}, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, options.log); + this.hook = hook; // (1) If neither `options.authStrategy` nor `options.auth` are set, the `octokit` instance + // is unauthenticated. The `this.auth()` method is a no-op and no request hook is registered. + // (2) If only `options.auth` is set, use the default token authentication strategy. + // (3) If `options.authStrategy` is set then use it and pass in `options.auth`. Always pass own request as many strategies accept a custom request instance. + // TODO: type `options.auth` based on `options.authStrategy`. + + if (!options.authStrategy) { + if (!options.auth) { + // (1) + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + // (2) + const auth = authToken.createTokenAuth(options.auth); // @ts-ignore ¯\_(ツ)_/¯ + + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { + authStrategy + } = options, + otherOptions = _objectWithoutProperties(options, _excluded); + + const auth = authStrategy(Object.assign({ + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, options.auth)); // @ts-ignore ¯\_(ツ)_/¯ + + hook.wrap("request", auth.hook); + this.auth = auth; + } // apply plugins + // https://stackoverflow.com/a/16345172 + + + const classConstructor = this.constructor; + classConstructor.plugins.forEach(plugin => { + Object.assign(this, plugin(this, options)); + }); + } + + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + + if (typeof defaults === "function") { + super(defaults(options)); + return; + } + + super(Object.assign({}, defaults, options, options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null)); + } + + }; + return OctokitWithDefaults; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ + + + static plugin(...newPlugins) { + var _a; + + const currentPlugins = this.plugins; + const NewOctokit = (_a = class extends this {}, _a.plugins = currentPlugins.concat(newPlugins.filter(plugin => !currentPlugins.includes(plugin))), _a); + return NewOctokit; + } + +} +Octokit.VERSION = VERSION; +Octokit.plugins = []; + +exports.Octokit = Octokit; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 9440: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var isPlainObject = __nccwpck_require__(3287); +var universalUserAgent = __nccwpck_require__(5030); + +function lowercaseKeys(object) { + if (!object) { + return {}; + } + + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); +} + +function mergeDeep(defaults, options) { + const result = Object.assign({}, defaults); + Object.keys(options).forEach(key => { + if (isPlainObject.isPlainObject(options[key])) { + if (!(key in defaults)) Object.assign(result, { + [key]: options[key] + });else result[key] = mergeDeep(defaults[key], options[key]); + } else { + Object.assign(result, { + [key]: options[key] + }); + } + }); + return result; +} + +function removeUndefinedProperties(obj) { + for (const key in obj) { + if (obj[key] === undefined) { + delete obj[key]; + } + } + + return obj; +} + +function merge(defaults, route, options) { + if (typeof route === "string") { + let [method, url] = route.split(" "); + options = Object.assign(url ? { + method, + url + } : { + url: method + }, options); + } else { + options = Object.assign({}, route); + } // lowercase header names before merging with defaults to avoid duplicates + + + options.headers = lowercaseKeys(options.headers); // remove properties with undefined values before merging + + removeUndefinedProperties(options); + removeUndefinedProperties(options.headers); + const mergedOptions = mergeDeep(defaults || {}, options); // mediaType.previews arrays are merged, instead of overwritten + + if (defaults && defaults.mediaType.previews.length) { + mergedOptions.mediaType.previews = defaults.mediaType.previews.filter(preview => !mergedOptions.mediaType.previews.includes(preview)).concat(mergedOptions.mediaType.previews); + } + + mergedOptions.mediaType.previews = mergedOptions.mediaType.previews.map(preview => preview.replace(/-preview/, "")); + return mergedOptions; +} + +function addQueryParameters(url, parameters) { + const separator = /\?/.test(url) ? "&" : "?"; + const names = Object.keys(parameters); + + if (names.length === 0) { + return url; + } + + return url + separator + names.map(name => { + if (name === "q") { + return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+"); + } + + return `${name}=${encodeURIComponent(parameters[name])}`; + }).join("&"); +} + +const urlVariableRegex = /\{[^}]+\}/g; + +function removeNonChars(variableName) { + return variableName.replace(/^\W+|\W+$/g, "").split(/,/); +} + +function extractUrlVariableNames(url) { + const matches = url.match(urlVariableRegex); + + if (!matches) { + return []; + } + + return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []); +} + +function omit(object, keysToOmit) { + return Object.keys(object).filter(option => !keysToOmit.includes(option)).reduce((obj, key) => { + obj[key] = object[key]; + return obj; + }, {}); +} + +// Based on https://github.com/bramstein/url-template, licensed under BSD +// TODO: create separate package. +// +// Copyright (c) 2012-2014, Bram Stein +// All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, +// INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +// BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +// EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +/* istanbul ignore file */ +function encodeReserved(str) { + return str.split(/(%[0-9A-Fa-f]{2})/g).map(function (part) { + if (!/%[0-9A-Fa-f]/.test(part)) { + part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); + } + + return part; + }).join(""); +} + +function encodeUnreserved(str) { + return encodeURIComponent(str).replace(/[!'()*]/g, function (c) { + return "%" + c.charCodeAt(0).toString(16).toUpperCase(); + }); +} + +function encodeValue(operator, value, key) { + value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); + + if (key) { + return encodeUnreserved(key) + "=" + value; + } else { + return value; + } +} + +function isDefined(value) { + return value !== undefined && value !== null; +} + +function isKeyOperator(operator) { + return operator === ";" || operator === "&" || operator === "?"; +} + +function getValues(context, operator, key, modifier) { + var value = context[key], + result = []; + + if (isDefined(value) && value !== "") { + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + value = value.toString(); + + if (modifier && modifier !== "*") { + value = value.substring(0, parseInt(modifier, 10)); + } + + result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); + } else { + if (modifier === "*") { + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function (value) { + result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : "")); + }); + } else { + Object.keys(value).forEach(function (k) { + if (isDefined(value[k])) { + result.push(encodeValue(operator, value[k], k)); + } + }); + } + } else { + const tmp = []; + + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function (value) { + tmp.push(encodeValue(operator, value)); + }); + } else { + Object.keys(value).forEach(function (k) { + if (isDefined(value[k])) { + tmp.push(encodeUnreserved(k)); + tmp.push(encodeValue(operator, value[k].toString())); + } + }); + } + + if (isKeyOperator(operator)) { + result.push(encodeUnreserved(key) + "=" + tmp.join(",")); + } else if (tmp.length !== 0) { + result.push(tmp.join(",")); + } + } + } + } else { + if (operator === ";") { + if (isDefined(value)) { + result.push(encodeUnreserved(key)); + } + } else if (value === "" && (operator === "&" || operator === "?")) { + result.push(encodeUnreserved(key) + "="); + } else if (value === "") { + result.push(""); + } + } + + return result; +} + +function parseUrl(template) { + return { + expand: expand.bind(null, template) + }; +} + +function expand(template, context) { + var operators = ["+", "#", ".", "/", ";", "?", "&"]; + return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function (_, expression, literal) { + if (expression) { + let operator = ""; + const values = []; + + if (operators.indexOf(expression.charAt(0)) !== -1) { + operator = expression.charAt(0); + expression = expression.substr(1); + } + + expression.split(/,/g).forEach(function (variable) { + var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); + values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); + }); + + if (operator && operator !== "+") { + var separator = ","; + + if (operator === "?") { + separator = "&"; + } else if (operator !== "#") { + separator = operator; + } + + return (values.length !== 0 ? operator : "") + values.join(separator); + } else { + return values.join(","); + } + } else { + return encodeReserved(literal); + } + }); +} + +function parse(options) { + // https://fetch.spec.whatwg.org/#methods + let method = options.method.toUpperCase(); // replace :varname with {varname} to make it RFC 6570 compatible + + let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); + let headers = Object.assign({}, options.headers); + let body; + let parameters = omit(options, ["method", "baseUrl", "url", "headers", "request", "mediaType"]); // extract variable names from URL to calculate remaining variables later + + const urlVariableNames = extractUrlVariableNames(url); + url = parseUrl(url).expand(parameters); + + if (!/^http/.test(url)) { + url = options.baseUrl + url; + } + + const omittedParameters = Object.keys(options).filter(option => urlVariableNames.includes(option)).concat("baseUrl"); + const remainingParameters = omit(parameters, omittedParameters); + const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); + + if (!isBinaryRequest) { + if (options.mediaType.format) { + // e.g. application/vnd.github.v3+json => application/vnd.github.v3.raw + headers.accept = headers.accept.split(/,/).map(preview => preview.replace(/application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, `application/vnd$1$2.${options.mediaType.format}`)).join(","); + } + + if (options.mediaType.previews.length) { + const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || []; + headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map(preview => { + const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; + return `application/vnd.github.${preview}-preview${format}`; + }).join(","); + } + } // for GET/HEAD requests, set URL query parameters from remaining parameters + // for PATCH/POST/PUT/DELETE requests, set request body from remaining parameters + + + if (["GET", "HEAD"].includes(method)) { + url = addQueryParameters(url, remainingParameters); + } else { + if ("data" in remainingParameters) { + body = remainingParameters.data; + } else { + if (Object.keys(remainingParameters).length) { + body = remainingParameters; + } else { + headers["content-length"] = 0; + } + } + } // default content-type for JSON if body is set + + + if (!headers["content-type"] && typeof body !== "undefined") { + headers["content-type"] = "application/json; charset=utf-8"; + } // GitHub expects 'content-length: 0' header for PUT/PATCH requests without body. + // fetch does not allow to set `content-length` header, but we can set body to an empty string + + + if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { + body = ""; + } // Only return body/request keys if present + + + return Object.assign({ + method, + url, + headers + }, typeof body !== "undefined" ? { + body + } : null, options.request ? { + request: options.request + } : null); +} + +function endpointWithDefaults(defaults, route, options) { + return parse(merge(defaults, route, options)); +} + +function withDefaults(oldDefaults, newDefaults) { + const DEFAULTS = merge(oldDefaults, newDefaults); + const endpoint = endpointWithDefaults.bind(null, DEFAULTS); + return Object.assign(endpoint, { + DEFAULTS, + defaults: withDefaults.bind(null, DEFAULTS), + merge: merge.bind(null, DEFAULTS), + parse + }); +} + +const VERSION = "6.0.12"; + +const userAgent = `octokit-endpoint.js/${VERSION} ${universalUserAgent.getUserAgent()}`; // DEFAULTS has all properties set that EndpointOptions has, except url. +// So we use RequestParameters and add method as additional required property. + +const DEFAULTS = { + method: "GET", + baseUrl: "https://api.github.com", + headers: { + accept: "application/vnd.github.v3+json", + "user-agent": userAgent + }, + mediaType: { + format: "", + previews: [] + } +}; + +const endpoint = withDefaults(null, DEFAULTS); + +exports.endpoint = endpoint; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 8467: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +var request = __nccwpck_require__(6234); +var universalUserAgent = __nccwpck_require__(5030); + +const VERSION = "4.8.0"; + +function _buildMessageForResponseErrors(data) { + return `Request failed due to following response errors:\n` + data.errors.map(e => ` - ${e.message}`).join("\n"); +} + +class GraphqlResponseError extends Error { + constructor(request, headers, response) { + super(_buildMessageForResponseErrors(response)); + this.request = request; + this.headers = headers; + this.response = response; + this.name = "GraphqlResponseError"; // Expose the errors and response data in their shorthand properties. + + this.errors = response.errors; + this.data = response.data; // Maintains proper stack trace (only available on V8) + + /* istanbul ignore next */ + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } + +} + +const NON_VARIABLE_OPTIONS = ["method", "baseUrl", "url", "headers", "request", "query", "mediaType"]; +const FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"]; +const GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/; +function graphql(request, query, options) { + if (options) { + if (typeof query === "string" && "query" in options) { + return Promise.reject(new Error(`[@octokit/graphql] "query" cannot be used as variable name`)); + } + + for (const key in options) { + if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) continue; + return Promise.reject(new Error(`[@octokit/graphql] "${key}" cannot be used as variable name`)); + } + } + + const parsedOptions = typeof query === "string" ? Object.assign({ + query + }, options) : query; + const requestOptions = Object.keys(parsedOptions).reduce((result, key) => { + if (NON_VARIABLE_OPTIONS.includes(key)) { + result[key] = parsedOptions[key]; + return result; + } + + if (!result.variables) { + result.variables = {}; + } + + result.variables[key] = parsedOptions[key]; + return result; + }, {}); // workaround for GitHub Enterprise baseUrl set with /api/v3 suffix + // https://github.com/octokit/auth-app.js/issues/111#issuecomment-657610451 + + const baseUrl = parsedOptions.baseUrl || request.endpoint.DEFAULTS.baseUrl; + + if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) { + requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql"); + } + + return request(requestOptions).then(response => { + if (response.data.errors) { + const headers = {}; + + for (const key of Object.keys(response.headers)) { + headers[key] = response.headers[key]; + } + + throw new GraphqlResponseError(requestOptions, headers, response.data); + } + + return response.data.data; + }); +} + +function withDefaults(request$1, newDefaults) { + const newRequest = request$1.defaults(newDefaults); + + const newApi = (query, options) => { + return graphql(newRequest, query, options); + }; + + return Object.assign(newApi, { + defaults: withDefaults.bind(null, newRequest), + endpoint: request.request.endpoint + }); +} + +const graphql$1 = withDefaults(request.request, { + headers: { + "user-agent": `octokit-graphql.js/${VERSION} ${universalUserAgent.getUserAgent()}` + }, + method: "POST", + url: "/graphql" +}); +function withCustomRequest(customRequest) { + return withDefaults(customRequest, { + method: "POST", + url: "/graphql" + }); +} + +exports.GraphqlResponseError = GraphqlResponseError; +exports.graphql = graphql$1; +exports.withCustomRequest = withCustomRequest; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 4193: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +const VERSION = "2.21.3"; + +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + enumerableOnly && (symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + })), keys.push.apply(keys, symbols); + } + + return keys; +} + +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = null != arguments[i] ? arguments[i] : {}; + i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { + _defineProperty(target, key, source[key]); + }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + + return target; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +/** + * Some “list” response that can be paginated have a different response structure + * + * They have a `total_count` key in the response (search also has `incomplete_results`, + * /installation/repositories also has `repository_selection`), as well as a key with + * the list of the items which name varies from endpoint to endpoint. + * + * Octokit normalizes these responses so that paginated results are always returned following + * the same structure. One challenge is that if the list response has only one page, no Link + * header is provided, so this header alone is not sufficient to check wether a response is + * paginated or not. + * + * We check if a "total_count" key is present in the response data, but also make sure that + * a "url" property is not, as the "Get the combined status for a specific ref" endpoint would + * otherwise match: https://developer.github.com/v3/repos/statuses/#get-the-combined-status-for-a-specific-ref + */ +function normalizePaginatedListResponse(response) { + // endpoints can respond with 204 if repository is empty + if (!response.data) { + return _objectSpread2(_objectSpread2({}, response), {}, { + data: [] + }); + } + + const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data); + if (!responseNeedsNormalization) return response; // keep the additional properties intact as there is currently no other way + // to retrieve the same information. + + const incompleteResults = response.data.incomplete_results; + const repositorySelection = response.data.repository_selection; + const totalCount = response.data.total_count; + delete response.data.incomplete_results; + delete response.data.repository_selection; + delete response.data.total_count; + const namespaceKey = Object.keys(response.data)[0]; + const data = response.data[namespaceKey]; + response.data = data; + + if (typeof incompleteResults !== "undefined") { + response.data.incomplete_results = incompleteResults; + } + + if (typeof repositorySelection !== "undefined") { + response.data.repository_selection = repositorySelection; + } + + response.data.total_count = totalCount; + return response; +} + +function iterator(octokit, route, parameters) { + const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters); + const requestMethod = typeof route === "function" ? route : octokit.request; + const method = options.method; + const headers = options.headers; + let url = options.url; + return { + [Symbol.asyncIterator]: () => ({ + async next() { + if (!url) return { + done: true + }; + + try { + const response = await requestMethod({ + method, + url, + headers + }); + const normalizedResponse = normalizePaginatedListResponse(response); // `response.headers.link` format: + // '<https://api.github.com/users/aseemk/followers?page=2>; rel="next", <https://api.github.com/users/aseemk/followers?page=2>; rel="last"' + // sets `url` to undefined if "next" URL is not present or `link` header is not set + + url = ((normalizedResponse.headers.link || "").match(/<([^>]+)>;\s*rel="next"/) || [])[1]; + return { + value: normalizedResponse + }; + } catch (error) { + if (error.status !== 409) throw error; + url = ""; + return { + value: { + status: 200, + headers: {}, + data: [] + } + }; + } + } + + }) + }; +} + +function paginate(octokit, route, parameters, mapFn) { + if (typeof parameters === "function") { + mapFn = parameters; + parameters = undefined; + } + + return gather(octokit, [], iterator(octokit, route, parameters)[Symbol.asyncIterator](), mapFn); +} + +function gather(octokit, results, iterator, mapFn) { + return iterator.next().then(result => { + if (result.done) { + return results; + } + + let earlyExit = false; + + function done() { + earlyExit = true; + } + + results = results.concat(mapFn ? mapFn(result.value, done) : result.value.data); + + if (earlyExit) { + return results; + } + + return gather(octokit, results, iterator, mapFn); + }); +} + +const composePaginateRest = Object.assign(paginate, { + iterator +}); + +const paginatingEndpoints = ["GET /app/hook/deliveries", "GET /app/installations", "GET /applications/grants", "GET /authorizations", "GET /enterprises/{enterprise}/actions/permissions/organizations", "GET /enterprises/{enterprise}/actions/runner-groups", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/organizations", "GET /enterprises/{enterprise}/actions/runner-groups/{runner_group_id}/runners", "GET /enterprises/{enterprise}/actions/runners", "GET /enterprises/{enterprise}/audit-log", "GET /enterprises/{enterprise}/secret-scanning/alerts", "GET /enterprises/{enterprise}/settings/billing/advanced-security", "GET /events", "GET /gists", "GET /gists/public", "GET /gists/starred", "GET /gists/{gist_id}/comments", "GET /gists/{gist_id}/commits", "GET /gists/{gist_id}/forks", "GET /installation/repositories", "GET /issues", "GET /licenses", "GET /marketplace_listing/plans", "GET /marketplace_listing/plans/{plan_id}/accounts", "GET /marketplace_listing/stubbed/plans", "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts", "GET /networks/{owner}/{repo}/events", "GET /notifications", "GET /organizations", "GET /orgs/{org}/actions/cache/usage-by-repository", "GET /orgs/{org}/actions/permissions/repositories", "GET /orgs/{org}/actions/runner-groups", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/repositories", "GET /orgs/{org}/actions/runner-groups/{runner_group_id}/runners", "GET /orgs/{org}/actions/runners", "GET /orgs/{org}/actions/secrets", "GET /orgs/{org}/actions/secrets/{secret_name}/repositories", "GET /orgs/{org}/audit-log", "GET /orgs/{org}/blocks", "GET /orgs/{org}/code-scanning/alerts", "GET /orgs/{org}/codespaces", "GET /orgs/{org}/credential-authorizations", "GET /orgs/{org}/dependabot/secrets", "GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories", "GET /orgs/{org}/events", "GET /orgs/{org}/external-groups", "GET /orgs/{org}/failed_invitations", "GET /orgs/{org}/hooks", "GET /orgs/{org}/hooks/{hook_id}/deliveries", "GET /orgs/{org}/installations", "GET /orgs/{org}/invitations", "GET /orgs/{org}/invitations/{invitation_id}/teams", "GET /orgs/{org}/issues", "GET /orgs/{org}/members", "GET /orgs/{org}/migrations", "GET /orgs/{org}/migrations/{migration_id}/repositories", "GET /orgs/{org}/outside_collaborators", "GET /orgs/{org}/packages", "GET /orgs/{org}/packages/{package_type}/{package_name}/versions", "GET /orgs/{org}/projects", "GET /orgs/{org}/public_members", "GET /orgs/{org}/repos", "GET /orgs/{org}/secret-scanning/alerts", "GET /orgs/{org}/settings/billing/advanced-security", "GET /orgs/{org}/team-sync/groups", "GET /orgs/{org}/teams", "GET /orgs/{org}/teams/{team_slug}/discussions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions", "GET /orgs/{org}/teams/{team_slug}/invitations", "GET /orgs/{org}/teams/{team_slug}/members", "GET /orgs/{org}/teams/{team_slug}/projects", "GET /orgs/{org}/teams/{team_slug}/repos", "GET /orgs/{org}/teams/{team_slug}/teams", "GET /projects/columns/{column_id}/cards", "GET /projects/{project_id}/collaborators", "GET /projects/{project_id}/columns", "GET /repos/{owner}/{repo}/actions/artifacts", "GET /repos/{owner}/{repo}/actions/caches", "GET /repos/{owner}/{repo}/actions/runners", "GET /repos/{owner}/{repo}/actions/runs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs", "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs", "GET /repos/{owner}/{repo}/actions/secrets", "GET /repos/{owner}/{repo}/actions/workflows", "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", "GET /repos/{owner}/{repo}/assignees", "GET /repos/{owner}/{repo}/branches", "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations", "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs", "GET /repos/{owner}/{repo}/code-scanning/alerts", "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", "GET /repos/{owner}/{repo}/code-scanning/analyses", "GET /repos/{owner}/{repo}/codespaces", "GET /repos/{owner}/{repo}/codespaces/devcontainers", "GET /repos/{owner}/{repo}/codespaces/secrets", "GET /repos/{owner}/{repo}/collaborators", "GET /repos/{owner}/{repo}/comments", "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/commits", "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments", "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls", "GET /repos/{owner}/{repo}/commits/{ref}/check-runs", "GET /repos/{owner}/{repo}/commits/{ref}/check-suites", "GET /repos/{owner}/{repo}/commits/{ref}/status", "GET /repos/{owner}/{repo}/commits/{ref}/statuses", "GET /repos/{owner}/{repo}/contributors", "GET /repos/{owner}/{repo}/dependabot/secrets", "GET /repos/{owner}/{repo}/deployments", "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses", "GET /repos/{owner}/{repo}/environments", "GET /repos/{owner}/{repo}/events", "GET /repos/{owner}/{repo}/forks", "GET /repos/{owner}/{repo}/git/matching-refs/{ref}", "GET /repos/{owner}/{repo}/hooks", "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", "GET /repos/{owner}/{repo}/invitations", "GET /repos/{owner}/{repo}/issues", "GET /repos/{owner}/{repo}/issues/comments", "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/issues/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/comments", "GET /repos/{owner}/{repo}/issues/{issue_number}/events", "GET /repos/{owner}/{repo}/issues/{issue_number}/labels", "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions", "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline", "GET /repos/{owner}/{repo}/keys", "GET /repos/{owner}/{repo}/labels", "GET /repos/{owner}/{repo}/milestones", "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels", "GET /repos/{owner}/{repo}/notifications", "GET /repos/{owner}/{repo}/pages/builds", "GET /repos/{owner}/{repo}/projects", "GET /repos/{owner}/{repo}/pulls", "GET /repos/{owner}/{repo}/pulls/comments", "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions", "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments", "GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews", "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments", "GET /repos/{owner}/{repo}/releases", "GET /repos/{owner}/{repo}/releases/{release_id}/assets", "GET /repos/{owner}/{repo}/releases/{release_id}/reactions", "GET /repos/{owner}/{repo}/secret-scanning/alerts", "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations", "GET /repos/{owner}/{repo}/stargazers", "GET /repos/{owner}/{repo}/subscribers", "GET /repos/{owner}/{repo}/tags", "GET /repos/{owner}/{repo}/teams", "GET /repos/{owner}/{repo}/topics", "GET /repositories", "GET /repositories/{repository_id}/environments/{environment_name}/secrets", "GET /search/code", "GET /search/commits", "GET /search/issues", "GET /search/labels", "GET /search/repositories", "GET /search/topics", "GET /search/users", "GET /teams/{team_id}/discussions", "GET /teams/{team_id}/discussions/{discussion_number}/comments", "GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions", "GET /teams/{team_id}/discussions/{discussion_number}/reactions", "GET /teams/{team_id}/invitations", "GET /teams/{team_id}/members", "GET /teams/{team_id}/projects", "GET /teams/{team_id}/repos", "GET /teams/{team_id}/teams", "GET /user/blocks", "GET /user/codespaces", "GET /user/codespaces/secrets", "GET /user/emails", "GET /user/followers", "GET /user/following", "GET /user/gpg_keys", "GET /user/installations", "GET /user/installations/{installation_id}/repositories", "GET /user/issues", "GET /user/keys", "GET /user/marketplace_purchases", "GET /user/marketplace_purchases/stubbed", "GET /user/memberships/orgs", "GET /user/migrations", "GET /user/migrations/{migration_id}/repositories", "GET /user/orgs", "GET /user/packages", "GET /user/packages/{package_type}/{package_name}/versions", "GET /user/public_emails", "GET /user/repos", "GET /user/repository_invitations", "GET /user/starred", "GET /user/subscriptions", "GET /user/teams", "GET /users", "GET /users/{username}/events", "GET /users/{username}/events/orgs/{org}", "GET /users/{username}/events/public", "GET /users/{username}/followers", "GET /users/{username}/following", "GET /users/{username}/gists", "GET /users/{username}/gpg_keys", "GET /users/{username}/keys", "GET /users/{username}/orgs", "GET /users/{username}/packages", "GET /users/{username}/projects", "GET /users/{username}/received_events", "GET /users/{username}/received_events/public", "GET /users/{username}/repos", "GET /users/{username}/starred", "GET /users/{username}/subscriptions"]; + +function isPaginatingEndpoint(arg) { + if (typeof arg === "string") { + return paginatingEndpoints.includes(arg); + } else { + return false; + } +} + +/** + * @param octokit Octokit instance + * @param options Options passed to Octokit constructor + */ + +function paginateRest(octokit) { + return { + paginate: Object.assign(paginate.bind(null, octokit), { + iterator: iterator.bind(null, octokit) + }) + }; +} +paginateRest.VERSION = VERSION; + +exports.composePaginateRest = composePaginateRest; +exports.isPaginatingEndpoint = isPaginatingEndpoint; +exports.paginateRest = paginateRest; +exports.paginatingEndpoints = paginatingEndpoints; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 3044: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function ownKeys(object, enumerableOnly) { + var keys = Object.keys(object); + + if (Object.getOwnPropertySymbols) { + var symbols = Object.getOwnPropertySymbols(object); + + if (enumerableOnly) { + symbols = symbols.filter(function (sym) { + return Object.getOwnPropertyDescriptor(object, sym).enumerable; + }); + } + + keys.push.apply(keys, symbols); + } + + return keys; +} + +function _objectSpread2(target) { + for (var i = 1; i < arguments.length; i++) { + var source = arguments[i] != null ? arguments[i] : {}; + + if (i % 2) { + ownKeys(Object(source), true).forEach(function (key) { + _defineProperty(target, key, source[key]); + }); + } else if (Object.getOwnPropertyDescriptors) { + Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); + } else { + ownKeys(Object(source)).forEach(function (key) { + Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); + }); + } + } + + return target; +} + +function _defineProperty(obj, key, value) { + if (key in obj) { + Object.defineProperty(obj, key, { + value: value, + enumerable: true, + configurable: true, + writable: true + }); + } else { + obj[key] = value; + } + + return obj; +} + +const Endpoints = { + actions: { + addCustomLabelsToSelfHostedRunnerForOrg: ["POST /orgs/{org}/actions/runners/{runner_id}/labels"], + addCustomLabelsToSelfHostedRunnerForRepo: ["POST /repos/{owner}/{repo}/actions/runners/{runner_id}/labels"], + addSelectedRepoToOrgSecret: ["PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}"], + approveWorkflowRun: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/approve"], + cancelWorkflowRun: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel"], + createOrUpdateEnvironmentSecret: ["PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}"], + createOrUpdateOrgSecret: ["PUT /orgs/{org}/actions/secrets/{secret_name}"], + createOrUpdateRepoSecret: ["PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}"], + createRegistrationTokenForOrg: ["POST /orgs/{org}/actions/runners/registration-token"], + createRegistrationTokenForRepo: ["POST /repos/{owner}/{repo}/actions/runners/registration-token"], + createRemoveTokenForOrg: ["POST /orgs/{org}/actions/runners/remove-token"], + createRemoveTokenForRepo: ["POST /repos/{owner}/{repo}/actions/runners/remove-token"], + createWorkflowDispatch: ["POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches"], + deleteActionsCacheById: ["DELETE /repos/{owner}/{repo}/actions/caches/{cache_id}"], + deleteActionsCacheByKey: ["DELETE /repos/{owner}/{repo}/actions/caches{?key,ref}"], + deleteArtifact: ["DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}"], + deleteEnvironmentSecret: ["DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}"], + deleteOrgSecret: ["DELETE /orgs/{org}/actions/secrets/{secret_name}"], + deleteRepoSecret: ["DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}"], + deleteSelfHostedRunnerFromOrg: ["DELETE /orgs/{org}/actions/runners/{runner_id}"], + deleteSelfHostedRunnerFromRepo: ["DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}"], + deleteWorkflowRun: ["DELETE /repos/{owner}/{repo}/actions/runs/{run_id}"], + deleteWorkflowRunLogs: ["DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs"], + disableSelectedRepositoryGithubActionsOrganization: ["DELETE /orgs/{org}/actions/permissions/repositories/{repository_id}"], + disableWorkflow: ["PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable"], + downloadArtifact: ["GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}"], + downloadJobLogsForWorkflowRun: ["GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs"], + downloadWorkflowRunAttemptLogs: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/logs"], + downloadWorkflowRunLogs: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs"], + enableSelectedRepositoryGithubActionsOrganization: ["PUT /orgs/{org}/actions/permissions/repositories/{repository_id}"], + enableWorkflow: ["PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable"], + getActionsCacheList: ["GET /repos/{owner}/{repo}/actions/caches"], + getActionsCacheUsage: ["GET /repos/{owner}/{repo}/actions/cache/usage"], + getActionsCacheUsageByRepoForOrg: ["GET /orgs/{org}/actions/cache/usage-by-repository"], + getActionsCacheUsageForEnterprise: ["GET /enterprises/{enterprise}/actions/cache/usage"], + getActionsCacheUsageForOrg: ["GET /orgs/{org}/actions/cache/usage"], + getAllowedActionsOrganization: ["GET /orgs/{org}/actions/permissions/selected-actions"], + getAllowedActionsRepository: ["GET /repos/{owner}/{repo}/actions/permissions/selected-actions"], + getArtifact: ["GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}"], + getEnvironmentPublicKey: ["GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key"], + getEnvironmentSecret: ["GET /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}"], + getGithubActionsDefaultWorkflowPermissionsEnterprise: ["GET /enterprises/{enterprise}/actions/permissions/workflow"], + getGithubActionsDefaultWorkflowPermissionsOrganization: ["GET /orgs/{org}/actions/permissions/workflow"], + getGithubActionsDefaultWorkflowPermissionsRepository: ["GET /repos/{owner}/{repo}/actions/permissions/workflow"], + getGithubActionsPermissionsOrganization: ["GET /orgs/{org}/actions/permissions"], + getGithubActionsPermissionsRepository: ["GET /repos/{owner}/{repo}/actions/permissions"], + getJobForWorkflowRun: ["GET /repos/{owner}/{repo}/actions/jobs/{job_id}"], + getOrgPublicKey: ["GET /orgs/{org}/actions/secrets/public-key"], + getOrgSecret: ["GET /orgs/{org}/actions/secrets/{secret_name}"], + getPendingDeploymentsForRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments"], + getRepoPermissions: ["GET /repos/{owner}/{repo}/actions/permissions", {}, { + renamed: ["actions", "getGithubActionsPermissionsRepository"] + }], + getRepoPublicKey: ["GET /repos/{owner}/{repo}/actions/secrets/public-key"], + getRepoSecret: ["GET /repos/{owner}/{repo}/actions/secrets/{secret_name}"], + getReviewsForRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/approvals"], + getSelfHostedRunnerForOrg: ["GET /orgs/{org}/actions/runners/{runner_id}"], + getSelfHostedRunnerForRepo: ["GET /repos/{owner}/{repo}/actions/runners/{runner_id}"], + getWorkflow: ["GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}"], + getWorkflowAccessToRepository: ["GET /repos/{owner}/{repo}/actions/permissions/access"], + getWorkflowRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}"], + getWorkflowRunAttempt: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}"], + getWorkflowRunUsage: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing"], + getWorkflowUsage: ["GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing"], + listArtifactsForRepo: ["GET /repos/{owner}/{repo}/actions/artifacts"], + listEnvironmentSecrets: ["GET /repositories/{repository_id}/environments/{environment_name}/secrets"], + listJobsForWorkflowRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs"], + listJobsForWorkflowRunAttempt: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs"], + listLabelsForSelfHostedRunnerForOrg: ["GET /orgs/{org}/actions/runners/{runner_id}/labels"], + listLabelsForSelfHostedRunnerForRepo: ["GET /repos/{owner}/{repo}/actions/runners/{runner_id}/labels"], + listOrgSecrets: ["GET /orgs/{org}/actions/secrets"], + listRepoSecrets: ["GET /repos/{owner}/{repo}/actions/secrets"], + listRepoWorkflows: ["GET /repos/{owner}/{repo}/actions/workflows"], + listRunnerApplicationsForOrg: ["GET /orgs/{org}/actions/runners/downloads"], + listRunnerApplicationsForRepo: ["GET /repos/{owner}/{repo}/actions/runners/downloads"], + listSelectedReposForOrgSecret: ["GET /orgs/{org}/actions/secrets/{secret_name}/repositories"], + listSelectedRepositoriesEnabledGithubActionsOrganization: ["GET /orgs/{org}/actions/permissions/repositories"], + listSelfHostedRunnersForOrg: ["GET /orgs/{org}/actions/runners"], + listSelfHostedRunnersForRepo: ["GET /repos/{owner}/{repo}/actions/runners"], + listWorkflowRunArtifacts: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts"], + listWorkflowRuns: ["GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs"], + listWorkflowRunsForRepo: ["GET /repos/{owner}/{repo}/actions/runs"], + reRunJobForWorkflowRun: ["POST /repos/{owner}/{repo}/actions/jobs/{job_id}/rerun"], + reRunWorkflow: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun"], + reRunWorkflowFailedJobs: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs"], + removeAllCustomLabelsFromSelfHostedRunnerForOrg: ["DELETE /orgs/{org}/actions/runners/{runner_id}/labels"], + removeAllCustomLabelsFromSelfHostedRunnerForRepo: ["DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels"], + removeCustomLabelFromSelfHostedRunnerForOrg: ["DELETE /orgs/{org}/actions/runners/{runner_id}/labels/{name}"], + removeCustomLabelFromSelfHostedRunnerForRepo: ["DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels/{name}"], + removeSelectedRepoFromOrgSecret: ["DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}"], + reviewPendingDeploymentsForRun: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments"], + setAllowedActionsOrganization: ["PUT /orgs/{org}/actions/permissions/selected-actions"], + setAllowedActionsRepository: ["PUT /repos/{owner}/{repo}/actions/permissions/selected-actions"], + setCustomLabelsForSelfHostedRunnerForOrg: ["PUT /orgs/{org}/actions/runners/{runner_id}/labels"], + setCustomLabelsForSelfHostedRunnerForRepo: ["PUT /repos/{owner}/{repo}/actions/runners/{runner_id}/labels"], + setGithubActionsDefaultWorkflowPermissionsEnterprise: ["PUT /enterprises/{enterprise}/actions/permissions/workflow"], + setGithubActionsDefaultWorkflowPermissionsOrganization: ["PUT /orgs/{org}/actions/permissions/workflow"], + setGithubActionsDefaultWorkflowPermissionsRepository: ["PUT /repos/{owner}/{repo}/actions/permissions/workflow"], + setGithubActionsPermissionsOrganization: ["PUT /orgs/{org}/actions/permissions"], + setGithubActionsPermissionsRepository: ["PUT /repos/{owner}/{repo}/actions/permissions"], + setSelectedReposForOrgSecret: ["PUT /orgs/{org}/actions/secrets/{secret_name}/repositories"], + setSelectedRepositoriesEnabledGithubActionsOrganization: ["PUT /orgs/{org}/actions/permissions/repositories"], + setWorkflowAccessToRepository: ["PUT /repos/{owner}/{repo}/actions/permissions/access"] + }, + activity: { + checkRepoIsStarredByAuthenticatedUser: ["GET /user/starred/{owner}/{repo}"], + deleteRepoSubscription: ["DELETE /repos/{owner}/{repo}/subscription"], + deleteThreadSubscription: ["DELETE /notifications/threads/{thread_id}/subscription"], + getFeeds: ["GET /feeds"], + getRepoSubscription: ["GET /repos/{owner}/{repo}/subscription"], + getThread: ["GET /notifications/threads/{thread_id}"], + getThreadSubscriptionForAuthenticatedUser: ["GET /notifications/threads/{thread_id}/subscription"], + listEventsForAuthenticatedUser: ["GET /users/{username}/events"], + listNotificationsForAuthenticatedUser: ["GET /notifications"], + listOrgEventsForAuthenticatedUser: ["GET /users/{username}/events/orgs/{org}"], + listPublicEvents: ["GET /events"], + listPublicEventsForRepoNetwork: ["GET /networks/{owner}/{repo}/events"], + listPublicEventsForUser: ["GET /users/{username}/events/public"], + listPublicOrgEvents: ["GET /orgs/{org}/events"], + listReceivedEventsForUser: ["GET /users/{username}/received_events"], + listReceivedPublicEventsForUser: ["GET /users/{username}/received_events/public"], + listRepoEvents: ["GET /repos/{owner}/{repo}/events"], + listRepoNotificationsForAuthenticatedUser: ["GET /repos/{owner}/{repo}/notifications"], + listReposStarredByAuthenticatedUser: ["GET /user/starred"], + listReposStarredByUser: ["GET /users/{username}/starred"], + listReposWatchedByUser: ["GET /users/{username}/subscriptions"], + listStargazersForRepo: ["GET /repos/{owner}/{repo}/stargazers"], + listWatchedReposForAuthenticatedUser: ["GET /user/subscriptions"], + listWatchersForRepo: ["GET /repos/{owner}/{repo}/subscribers"], + markNotificationsAsRead: ["PUT /notifications"], + markRepoNotificationsAsRead: ["PUT /repos/{owner}/{repo}/notifications"], + markThreadAsRead: ["PATCH /notifications/threads/{thread_id}"], + setRepoSubscription: ["PUT /repos/{owner}/{repo}/subscription"], + setThreadSubscription: ["PUT /notifications/threads/{thread_id}/subscription"], + starRepoForAuthenticatedUser: ["PUT /user/starred/{owner}/{repo}"], + unstarRepoForAuthenticatedUser: ["DELETE /user/starred/{owner}/{repo}"] + }, + apps: { + addRepoToInstallation: ["PUT /user/installations/{installation_id}/repositories/{repository_id}", {}, { + renamed: ["apps", "addRepoToInstallationForAuthenticatedUser"] + }], + addRepoToInstallationForAuthenticatedUser: ["PUT /user/installations/{installation_id}/repositories/{repository_id}"], + checkToken: ["POST /applications/{client_id}/token"], + createFromManifest: ["POST /app-manifests/{code}/conversions"], + createInstallationAccessToken: ["POST /app/installations/{installation_id}/access_tokens"], + deleteAuthorization: ["DELETE /applications/{client_id}/grant"], + deleteInstallation: ["DELETE /app/installations/{installation_id}"], + deleteToken: ["DELETE /applications/{client_id}/token"], + getAuthenticated: ["GET /app"], + getBySlug: ["GET /apps/{app_slug}"], + getInstallation: ["GET /app/installations/{installation_id}"], + getOrgInstallation: ["GET /orgs/{org}/installation"], + getRepoInstallation: ["GET /repos/{owner}/{repo}/installation"], + getSubscriptionPlanForAccount: ["GET /marketplace_listing/accounts/{account_id}"], + getSubscriptionPlanForAccountStubbed: ["GET /marketplace_listing/stubbed/accounts/{account_id}"], + getUserInstallation: ["GET /users/{username}/installation"], + getWebhookConfigForApp: ["GET /app/hook/config"], + getWebhookDelivery: ["GET /app/hook/deliveries/{delivery_id}"], + listAccountsForPlan: ["GET /marketplace_listing/plans/{plan_id}/accounts"], + listAccountsForPlanStubbed: ["GET /marketplace_listing/stubbed/plans/{plan_id}/accounts"], + listInstallationReposForAuthenticatedUser: ["GET /user/installations/{installation_id}/repositories"], + listInstallations: ["GET /app/installations"], + listInstallationsForAuthenticatedUser: ["GET /user/installations"], + listPlans: ["GET /marketplace_listing/plans"], + listPlansStubbed: ["GET /marketplace_listing/stubbed/plans"], + listReposAccessibleToInstallation: ["GET /installation/repositories"], + listSubscriptionsForAuthenticatedUser: ["GET /user/marketplace_purchases"], + listSubscriptionsForAuthenticatedUserStubbed: ["GET /user/marketplace_purchases/stubbed"], + listWebhookDeliveries: ["GET /app/hook/deliveries"], + redeliverWebhookDelivery: ["POST /app/hook/deliveries/{delivery_id}/attempts"], + removeRepoFromInstallation: ["DELETE /user/installations/{installation_id}/repositories/{repository_id}", {}, { + renamed: ["apps", "removeRepoFromInstallationForAuthenticatedUser"] + }], + removeRepoFromInstallationForAuthenticatedUser: ["DELETE /user/installations/{installation_id}/repositories/{repository_id}"], + resetToken: ["PATCH /applications/{client_id}/token"], + revokeInstallationAccessToken: ["DELETE /installation/token"], + scopeToken: ["POST /applications/{client_id}/token/scoped"], + suspendInstallation: ["PUT /app/installations/{installation_id}/suspended"], + unsuspendInstallation: ["DELETE /app/installations/{installation_id}/suspended"], + updateWebhookConfigForApp: ["PATCH /app/hook/config"] + }, + billing: { + getGithubActionsBillingOrg: ["GET /orgs/{org}/settings/billing/actions"], + getGithubActionsBillingUser: ["GET /users/{username}/settings/billing/actions"], + getGithubAdvancedSecurityBillingGhe: ["GET /enterprises/{enterprise}/settings/billing/advanced-security"], + getGithubAdvancedSecurityBillingOrg: ["GET /orgs/{org}/settings/billing/advanced-security"], + getGithubPackagesBillingOrg: ["GET /orgs/{org}/settings/billing/packages"], + getGithubPackagesBillingUser: ["GET /users/{username}/settings/billing/packages"], + getSharedStorageBillingOrg: ["GET /orgs/{org}/settings/billing/shared-storage"], + getSharedStorageBillingUser: ["GET /users/{username}/settings/billing/shared-storage"] + }, + checks: { + create: ["POST /repos/{owner}/{repo}/check-runs"], + createSuite: ["POST /repos/{owner}/{repo}/check-suites"], + get: ["GET /repos/{owner}/{repo}/check-runs/{check_run_id}"], + getSuite: ["GET /repos/{owner}/{repo}/check-suites/{check_suite_id}"], + listAnnotations: ["GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations"], + listForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/check-runs"], + listForSuite: ["GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs"], + listSuitesForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/check-suites"], + rerequestRun: ["POST /repos/{owner}/{repo}/check-runs/{check_run_id}/rerequest"], + rerequestSuite: ["POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest"], + setSuitesPreferences: ["PATCH /repos/{owner}/{repo}/check-suites/preferences"], + update: ["PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}"] + }, + codeScanning: { + deleteAnalysis: ["DELETE /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}{?confirm_delete}"], + getAlert: ["GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}", {}, { + renamedParameters: { + alert_id: "alert_number" + } + }], + getAnalysis: ["GET /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}"], + getSarif: ["GET /repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}"], + listAlertInstances: ["GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances"], + listAlertsForOrg: ["GET /orgs/{org}/code-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/code-scanning/alerts"], + listAlertsInstances: ["GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", {}, { + renamed: ["codeScanning", "listAlertInstances"] + }], + listRecentAnalyses: ["GET /repos/{owner}/{repo}/code-scanning/analyses"], + updateAlert: ["PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}"], + uploadSarif: ["POST /repos/{owner}/{repo}/code-scanning/sarifs"] + }, + codesOfConduct: { + getAllCodesOfConduct: ["GET /codes_of_conduct"], + getConductCode: ["GET /codes_of_conduct/{key}"] + }, + codespaces: { + addRepositoryForSecretForAuthenticatedUser: ["PUT /user/codespaces/secrets/{secret_name}/repositories/{repository_id}"], + codespaceMachinesForAuthenticatedUser: ["GET /user/codespaces/{codespace_name}/machines"], + createForAuthenticatedUser: ["POST /user/codespaces"], + createOrUpdateRepoSecret: ["PUT /repos/{owner}/{repo}/codespaces/secrets/{secret_name}"], + createOrUpdateSecretForAuthenticatedUser: ["PUT /user/codespaces/secrets/{secret_name}"], + createWithPrForAuthenticatedUser: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces"], + createWithRepoForAuthenticatedUser: ["POST /repos/{owner}/{repo}/codespaces"], + deleteForAuthenticatedUser: ["DELETE /user/codespaces/{codespace_name}"], + deleteFromOrganization: ["DELETE /orgs/{org}/members/{username}/codespaces/{codespace_name}"], + deleteRepoSecret: ["DELETE /repos/{owner}/{repo}/codespaces/secrets/{secret_name}"], + deleteSecretForAuthenticatedUser: ["DELETE /user/codespaces/secrets/{secret_name}"], + exportForAuthenticatedUser: ["POST /user/codespaces/{codespace_name}/exports"], + getExportDetailsForAuthenticatedUser: ["GET /user/codespaces/{codespace_name}/exports/{export_id}"], + getForAuthenticatedUser: ["GET /user/codespaces/{codespace_name}"], + getPublicKeyForAuthenticatedUser: ["GET /user/codespaces/secrets/public-key"], + getRepoPublicKey: ["GET /repos/{owner}/{repo}/codespaces/secrets/public-key"], + getRepoSecret: ["GET /repos/{owner}/{repo}/codespaces/secrets/{secret_name}"], + getSecretForAuthenticatedUser: ["GET /user/codespaces/secrets/{secret_name}"], + listDevcontainersInRepositoryForAuthenticatedUser: ["GET /repos/{owner}/{repo}/codespaces/devcontainers"], + listForAuthenticatedUser: ["GET /user/codespaces"], + listInOrganization: ["GET /orgs/{org}/codespaces", {}, { + renamedParameters: { + org_id: "org" + } + }], + listInRepositoryForAuthenticatedUser: ["GET /repos/{owner}/{repo}/codespaces"], + listRepoSecrets: ["GET /repos/{owner}/{repo}/codespaces/secrets"], + listRepositoriesForSecretForAuthenticatedUser: ["GET /user/codespaces/secrets/{secret_name}/repositories"], + listSecretsForAuthenticatedUser: ["GET /user/codespaces/secrets"], + removeRepositoryForSecretForAuthenticatedUser: ["DELETE /user/codespaces/secrets/{secret_name}/repositories/{repository_id}"], + repoMachinesForAuthenticatedUser: ["GET /repos/{owner}/{repo}/codespaces/machines"], + setRepositoriesForSecretForAuthenticatedUser: ["PUT /user/codespaces/secrets/{secret_name}/repositories"], + startForAuthenticatedUser: ["POST /user/codespaces/{codespace_name}/start"], + stopForAuthenticatedUser: ["POST /user/codespaces/{codespace_name}/stop"], + stopInOrganization: ["POST /orgs/{org}/members/{username}/codespaces/{codespace_name}/stop"], + updateForAuthenticatedUser: ["PATCH /user/codespaces/{codespace_name}"] + }, + dependabot: { + addSelectedRepoToOrgSecret: ["PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}"], + createOrUpdateOrgSecret: ["PUT /orgs/{org}/dependabot/secrets/{secret_name}"], + createOrUpdateRepoSecret: ["PUT /repos/{owner}/{repo}/dependabot/secrets/{secret_name}"], + deleteOrgSecret: ["DELETE /orgs/{org}/dependabot/secrets/{secret_name}"], + deleteRepoSecret: ["DELETE /repos/{owner}/{repo}/dependabot/secrets/{secret_name}"], + getOrgPublicKey: ["GET /orgs/{org}/dependabot/secrets/public-key"], + getOrgSecret: ["GET /orgs/{org}/dependabot/secrets/{secret_name}"], + getRepoPublicKey: ["GET /repos/{owner}/{repo}/dependabot/secrets/public-key"], + getRepoSecret: ["GET /repos/{owner}/{repo}/dependabot/secrets/{secret_name}"], + listOrgSecrets: ["GET /orgs/{org}/dependabot/secrets"], + listRepoSecrets: ["GET /repos/{owner}/{repo}/dependabot/secrets"], + listSelectedReposForOrgSecret: ["GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories"], + removeSelectedRepoFromOrgSecret: ["DELETE /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}"], + setSelectedReposForOrgSecret: ["PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories"] + }, + dependencyGraph: { + createRepositorySnapshot: ["POST /repos/{owner}/{repo}/dependency-graph/snapshots"], + diffRange: ["GET /repos/{owner}/{repo}/dependency-graph/compare/{basehead}"] + }, + emojis: { + get: ["GET /emojis"] + }, + enterpriseAdmin: { + addCustomLabelsToSelfHostedRunnerForEnterprise: ["POST /enterprises/{enterprise}/actions/runners/{runner_id}/labels"], + disableSelectedOrganizationGithubActionsEnterprise: ["DELETE /enterprises/{enterprise}/actions/permissions/organizations/{org_id}"], + enableSelectedOrganizationGithubActionsEnterprise: ["PUT /enterprises/{enterprise}/actions/permissions/organizations/{org_id}"], + getAllowedActionsEnterprise: ["GET /enterprises/{enterprise}/actions/permissions/selected-actions"], + getGithubActionsPermissionsEnterprise: ["GET /enterprises/{enterprise}/actions/permissions"], + getServerStatistics: ["GET /enterprise-installation/{enterprise_or_org}/server-statistics"], + listLabelsForSelfHostedRunnerForEnterprise: ["GET /enterprises/{enterprise}/actions/runners/{runner_id}/labels"], + listSelectedOrganizationsEnabledGithubActionsEnterprise: ["GET /enterprises/{enterprise}/actions/permissions/organizations"], + removeAllCustomLabelsFromSelfHostedRunnerForEnterprise: ["DELETE /enterprises/{enterprise}/actions/runners/{runner_id}/labels"], + removeCustomLabelFromSelfHostedRunnerForEnterprise: ["DELETE /enterprises/{enterprise}/actions/runners/{runner_id}/labels/{name}"], + setAllowedActionsEnterprise: ["PUT /enterprises/{enterprise}/actions/permissions/selected-actions"], + setCustomLabelsForSelfHostedRunnerForEnterprise: ["PUT /enterprises/{enterprise}/actions/runners/{runner_id}/labels"], + setGithubActionsPermissionsEnterprise: ["PUT /enterprises/{enterprise}/actions/permissions"], + setSelectedOrganizationsEnabledGithubActionsEnterprise: ["PUT /enterprises/{enterprise}/actions/permissions/organizations"] + }, + gists: { + checkIsStarred: ["GET /gists/{gist_id}/star"], + create: ["POST /gists"], + createComment: ["POST /gists/{gist_id}/comments"], + delete: ["DELETE /gists/{gist_id}"], + deleteComment: ["DELETE /gists/{gist_id}/comments/{comment_id}"], + fork: ["POST /gists/{gist_id}/forks"], + get: ["GET /gists/{gist_id}"], + getComment: ["GET /gists/{gist_id}/comments/{comment_id}"], + getRevision: ["GET /gists/{gist_id}/{sha}"], + list: ["GET /gists"], + listComments: ["GET /gists/{gist_id}/comments"], + listCommits: ["GET /gists/{gist_id}/commits"], + listForUser: ["GET /users/{username}/gists"], + listForks: ["GET /gists/{gist_id}/forks"], + listPublic: ["GET /gists/public"], + listStarred: ["GET /gists/starred"], + star: ["PUT /gists/{gist_id}/star"], + unstar: ["DELETE /gists/{gist_id}/star"], + update: ["PATCH /gists/{gist_id}"], + updateComment: ["PATCH /gists/{gist_id}/comments/{comment_id}"] + }, + git: { + createBlob: ["POST /repos/{owner}/{repo}/git/blobs"], + createCommit: ["POST /repos/{owner}/{repo}/git/commits"], + createRef: ["POST /repos/{owner}/{repo}/git/refs"], + createTag: ["POST /repos/{owner}/{repo}/git/tags"], + createTree: ["POST /repos/{owner}/{repo}/git/trees"], + deleteRef: ["DELETE /repos/{owner}/{repo}/git/refs/{ref}"], + getBlob: ["GET /repos/{owner}/{repo}/git/blobs/{file_sha}"], + getCommit: ["GET /repos/{owner}/{repo}/git/commits/{commit_sha}"], + getRef: ["GET /repos/{owner}/{repo}/git/ref/{ref}"], + getTag: ["GET /repos/{owner}/{repo}/git/tags/{tag_sha}"], + getTree: ["GET /repos/{owner}/{repo}/git/trees/{tree_sha}"], + listMatchingRefs: ["GET /repos/{owner}/{repo}/git/matching-refs/{ref}"], + updateRef: ["PATCH /repos/{owner}/{repo}/git/refs/{ref}"] + }, + gitignore: { + getAllTemplates: ["GET /gitignore/templates"], + getTemplate: ["GET /gitignore/templates/{name}"] + }, + interactions: { + getRestrictionsForAuthenticatedUser: ["GET /user/interaction-limits"], + getRestrictionsForOrg: ["GET /orgs/{org}/interaction-limits"], + getRestrictionsForRepo: ["GET /repos/{owner}/{repo}/interaction-limits"], + getRestrictionsForYourPublicRepos: ["GET /user/interaction-limits", {}, { + renamed: ["interactions", "getRestrictionsForAuthenticatedUser"] + }], + removeRestrictionsForAuthenticatedUser: ["DELETE /user/interaction-limits"], + removeRestrictionsForOrg: ["DELETE /orgs/{org}/interaction-limits"], + removeRestrictionsForRepo: ["DELETE /repos/{owner}/{repo}/interaction-limits"], + removeRestrictionsForYourPublicRepos: ["DELETE /user/interaction-limits", {}, { + renamed: ["interactions", "removeRestrictionsForAuthenticatedUser"] + }], + setRestrictionsForAuthenticatedUser: ["PUT /user/interaction-limits"], + setRestrictionsForOrg: ["PUT /orgs/{org}/interaction-limits"], + setRestrictionsForRepo: ["PUT /repos/{owner}/{repo}/interaction-limits"], + setRestrictionsForYourPublicRepos: ["PUT /user/interaction-limits", {}, { + renamed: ["interactions", "setRestrictionsForAuthenticatedUser"] + }] + }, + issues: { + addAssignees: ["POST /repos/{owner}/{repo}/issues/{issue_number}/assignees"], + addLabels: ["POST /repos/{owner}/{repo}/issues/{issue_number}/labels"], + checkUserCanBeAssigned: ["GET /repos/{owner}/{repo}/assignees/{assignee}"], + create: ["POST /repos/{owner}/{repo}/issues"], + createComment: ["POST /repos/{owner}/{repo}/issues/{issue_number}/comments"], + createLabel: ["POST /repos/{owner}/{repo}/labels"], + createMilestone: ["POST /repos/{owner}/{repo}/milestones"], + deleteComment: ["DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}"], + deleteLabel: ["DELETE /repos/{owner}/{repo}/labels/{name}"], + deleteMilestone: ["DELETE /repos/{owner}/{repo}/milestones/{milestone_number}"], + get: ["GET /repos/{owner}/{repo}/issues/{issue_number}"], + getComment: ["GET /repos/{owner}/{repo}/issues/comments/{comment_id}"], + getEvent: ["GET /repos/{owner}/{repo}/issues/events/{event_id}"], + getLabel: ["GET /repos/{owner}/{repo}/labels/{name}"], + getMilestone: ["GET /repos/{owner}/{repo}/milestones/{milestone_number}"], + list: ["GET /issues"], + listAssignees: ["GET /repos/{owner}/{repo}/assignees"], + listComments: ["GET /repos/{owner}/{repo}/issues/{issue_number}/comments"], + listCommentsForRepo: ["GET /repos/{owner}/{repo}/issues/comments"], + listEvents: ["GET /repos/{owner}/{repo}/issues/{issue_number}/events"], + listEventsForRepo: ["GET /repos/{owner}/{repo}/issues/events"], + listEventsForTimeline: ["GET /repos/{owner}/{repo}/issues/{issue_number}/timeline"], + listForAuthenticatedUser: ["GET /user/issues"], + listForOrg: ["GET /orgs/{org}/issues"], + listForRepo: ["GET /repos/{owner}/{repo}/issues"], + listLabelsForMilestone: ["GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels"], + listLabelsForRepo: ["GET /repos/{owner}/{repo}/labels"], + listLabelsOnIssue: ["GET /repos/{owner}/{repo}/issues/{issue_number}/labels"], + listMilestones: ["GET /repos/{owner}/{repo}/milestones"], + lock: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/lock"], + removeAllLabels: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels"], + removeAssignees: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees"], + removeLabel: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}"], + setLabels: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/labels"], + unlock: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock"], + update: ["PATCH /repos/{owner}/{repo}/issues/{issue_number}"], + updateComment: ["PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}"], + updateLabel: ["PATCH /repos/{owner}/{repo}/labels/{name}"], + updateMilestone: ["PATCH /repos/{owner}/{repo}/milestones/{milestone_number}"] + }, + licenses: { + get: ["GET /licenses/{license}"], + getAllCommonlyUsed: ["GET /licenses"], + getForRepo: ["GET /repos/{owner}/{repo}/license"] + }, + markdown: { + render: ["POST /markdown"], + renderRaw: ["POST /markdown/raw", { + headers: { + "content-type": "text/plain; charset=utf-8" + } + }] + }, + meta: { + get: ["GET /meta"], + getOctocat: ["GET /octocat"], + getZen: ["GET /zen"], + root: ["GET /"] + }, + migrations: { + cancelImport: ["DELETE /repos/{owner}/{repo}/import"], + deleteArchiveForAuthenticatedUser: ["DELETE /user/migrations/{migration_id}/archive"], + deleteArchiveForOrg: ["DELETE /orgs/{org}/migrations/{migration_id}/archive"], + downloadArchiveForOrg: ["GET /orgs/{org}/migrations/{migration_id}/archive"], + getArchiveForAuthenticatedUser: ["GET /user/migrations/{migration_id}/archive"], + getCommitAuthors: ["GET /repos/{owner}/{repo}/import/authors"], + getImportStatus: ["GET /repos/{owner}/{repo}/import"], + getLargeFiles: ["GET /repos/{owner}/{repo}/import/large_files"], + getStatusForAuthenticatedUser: ["GET /user/migrations/{migration_id}"], + getStatusForOrg: ["GET /orgs/{org}/migrations/{migration_id}"], + listForAuthenticatedUser: ["GET /user/migrations"], + listForOrg: ["GET /orgs/{org}/migrations"], + listReposForAuthenticatedUser: ["GET /user/migrations/{migration_id}/repositories"], + listReposForOrg: ["GET /orgs/{org}/migrations/{migration_id}/repositories"], + listReposForUser: ["GET /user/migrations/{migration_id}/repositories", {}, { + renamed: ["migrations", "listReposForAuthenticatedUser"] + }], + mapCommitAuthor: ["PATCH /repos/{owner}/{repo}/import/authors/{author_id}"], + setLfsPreference: ["PATCH /repos/{owner}/{repo}/import/lfs"], + startForAuthenticatedUser: ["POST /user/migrations"], + startForOrg: ["POST /orgs/{org}/migrations"], + startImport: ["PUT /repos/{owner}/{repo}/import"], + unlockRepoForAuthenticatedUser: ["DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock"], + unlockRepoForOrg: ["DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock"], + updateImport: ["PATCH /repos/{owner}/{repo}/import"] + }, + orgs: { + blockUser: ["PUT /orgs/{org}/blocks/{username}"], + cancelInvitation: ["DELETE /orgs/{org}/invitations/{invitation_id}"], + checkBlockedUser: ["GET /orgs/{org}/blocks/{username}"], + checkMembershipForUser: ["GET /orgs/{org}/members/{username}"], + checkPublicMembershipForUser: ["GET /orgs/{org}/public_members/{username}"], + convertMemberToOutsideCollaborator: ["PUT /orgs/{org}/outside_collaborators/{username}"], + createInvitation: ["POST /orgs/{org}/invitations"], + createWebhook: ["POST /orgs/{org}/hooks"], + deleteWebhook: ["DELETE /orgs/{org}/hooks/{hook_id}"], + get: ["GET /orgs/{org}"], + getMembershipForAuthenticatedUser: ["GET /user/memberships/orgs/{org}"], + getMembershipForUser: ["GET /orgs/{org}/memberships/{username}"], + getWebhook: ["GET /orgs/{org}/hooks/{hook_id}"], + getWebhookConfigForOrg: ["GET /orgs/{org}/hooks/{hook_id}/config"], + getWebhookDelivery: ["GET /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}"], + list: ["GET /organizations"], + listAppInstallations: ["GET /orgs/{org}/installations"], + listBlockedUsers: ["GET /orgs/{org}/blocks"], + listCustomRoles: ["GET /organizations/{organization_id}/custom_roles"], + listFailedInvitations: ["GET /orgs/{org}/failed_invitations"], + listForAuthenticatedUser: ["GET /user/orgs"], + listForUser: ["GET /users/{username}/orgs"], + listInvitationTeams: ["GET /orgs/{org}/invitations/{invitation_id}/teams"], + listMembers: ["GET /orgs/{org}/members"], + listMembershipsForAuthenticatedUser: ["GET /user/memberships/orgs"], + listOutsideCollaborators: ["GET /orgs/{org}/outside_collaborators"], + listPendingInvitations: ["GET /orgs/{org}/invitations"], + listPublicMembers: ["GET /orgs/{org}/public_members"], + listWebhookDeliveries: ["GET /orgs/{org}/hooks/{hook_id}/deliveries"], + listWebhooks: ["GET /orgs/{org}/hooks"], + pingWebhook: ["POST /orgs/{org}/hooks/{hook_id}/pings"], + redeliverWebhookDelivery: ["POST /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}/attempts"], + removeMember: ["DELETE /orgs/{org}/members/{username}"], + removeMembershipForUser: ["DELETE /orgs/{org}/memberships/{username}"], + removeOutsideCollaborator: ["DELETE /orgs/{org}/outside_collaborators/{username}"], + removePublicMembershipForAuthenticatedUser: ["DELETE /orgs/{org}/public_members/{username}"], + setMembershipForUser: ["PUT /orgs/{org}/memberships/{username}"], + setPublicMembershipForAuthenticatedUser: ["PUT /orgs/{org}/public_members/{username}"], + unblockUser: ["DELETE /orgs/{org}/blocks/{username}"], + update: ["PATCH /orgs/{org}"], + updateMembershipForAuthenticatedUser: ["PATCH /user/memberships/orgs/{org}"], + updateWebhook: ["PATCH /orgs/{org}/hooks/{hook_id}"], + updateWebhookConfigForOrg: ["PATCH /orgs/{org}/hooks/{hook_id}/config"] + }, + packages: { + deletePackageForAuthenticatedUser: ["DELETE /user/packages/{package_type}/{package_name}"], + deletePackageForOrg: ["DELETE /orgs/{org}/packages/{package_type}/{package_name}"], + deletePackageForUser: ["DELETE /users/{username}/packages/{package_type}/{package_name}"], + deletePackageVersionForAuthenticatedUser: ["DELETE /user/packages/{package_type}/{package_name}/versions/{package_version_id}"], + deletePackageVersionForOrg: ["DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}"], + deletePackageVersionForUser: ["DELETE /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}"], + getAllPackageVersionsForAPackageOwnedByAnOrg: ["GET /orgs/{org}/packages/{package_type}/{package_name}/versions", {}, { + renamed: ["packages", "getAllPackageVersionsForPackageOwnedByOrg"] + }], + getAllPackageVersionsForAPackageOwnedByTheAuthenticatedUser: ["GET /user/packages/{package_type}/{package_name}/versions", {}, { + renamed: ["packages", "getAllPackageVersionsForPackageOwnedByAuthenticatedUser"] + }], + getAllPackageVersionsForPackageOwnedByAuthenticatedUser: ["GET /user/packages/{package_type}/{package_name}/versions"], + getAllPackageVersionsForPackageOwnedByOrg: ["GET /orgs/{org}/packages/{package_type}/{package_name}/versions"], + getAllPackageVersionsForPackageOwnedByUser: ["GET /users/{username}/packages/{package_type}/{package_name}/versions"], + getPackageForAuthenticatedUser: ["GET /user/packages/{package_type}/{package_name}"], + getPackageForOrganization: ["GET /orgs/{org}/packages/{package_type}/{package_name}"], + getPackageForUser: ["GET /users/{username}/packages/{package_type}/{package_name}"], + getPackageVersionForAuthenticatedUser: ["GET /user/packages/{package_type}/{package_name}/versions/{package_version_id}"], + getPackageVersionForOrganization: ["GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}"], + getPackageVersionForUser: ["GET /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}"], + listPackagesForAuthenticatedUser: ["GET /user/packages"], + listPackagesForOrganization: ["GET /orgs/{org}/packages"], + listPackagesForUser: ["GET /users/{username}/packages"], + restorePackageForAuthenticatedUser: ["POST /user/packages/{package_type}/{package_name}/restore{?token}"], + restorePackageForOrg: ["POST /orgs/{org}/packages/{package_type}/{package_name}/restore{?token}"], + restorePackageForUser: ["POST /users/{username}/packages/{package_type}/{package_name}/restore{?token}"], + restorePackageVersionForAuthenticatedUser: ["POST /user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore"], + restorePackageVersionForOrg: ["POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore"], + restorePackageVersionForUser: ["POST /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore"] + }, + projects: { + addCollaborator: ["PUT /projects/{project_id}/collaborators/{username}"], + createCard: ["POST /projects/columns/{column_id}/cards"], + createColumn: ["POST /projects/{project_id}/columns"], + createForAuthenticatedUser: ["POST /user/projects"], + createForOrg: ["POST /orgs/{org}/projects"], + createForRepo: ["POST /repos/{owner}/{repo}/projects"], + delete: ["DELETE /projects/{project_id}"], + deleteCard: ["DELETE /projects/columns/cards/{card_id}"], + deleteColumn: ["DELETE /projects/columns/{column_id}"], + get: ["GET /projects/{project_id}"], + getCard: ["GET /projects/columns/cards/{card_id}"], + getColumn: ["GET /projects/columns/{column_id}"], + getPermissionForUser: ["GET /projects/{project_id}/collaborators/{username}/permission"], + listCards: ["GET /projects/columns/{column_id}/cards"], + listCollaborators: ["GET /projects/{project_id}/collaborators"], + listColumns: ["GET /projects/{project_id}/columns"], + listForOrg: ["GET /orgs/{org}/projects"], + listForRepo: ["GET /repos/{owner}/{repo}/projects"], + listForUser: ["GET /users/{username}/projects"], + moveCard: ["POST /projects/columns/cards/{card_id}/moves"], + moveColumn: ["POST /projects/columns/{column_id}/moves"], + removeCollaborator: ["DELETE /projects/{project_id}/collaborators/{username}"], + update: ["PATCH /projects/{project_id}"], + updateCard: ["PATCH /projects/columns/cards/{card_id}"], + updateColumn: ["PATCH /projects/columns/{column_id}"] + }, + pulls: { + checkIfMerged: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/merge"], + create: ["POST /repos/{owner}/{repo}/pulls"], + createReplyForReviewComment: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies"], + createReview: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews"], + createReviewComment: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/comments"], + deletePendingReview: ["DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}"], + deleteReviewComment: ["DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}"], + dismissReview: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals"], + get: ["GET /repos/{owner}/{repo}/pulls/{pull_number}"], + getReview: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}"], + getReviewComment: ["GET /repos/{owner}/{repo}/pulls/comments/{comment_id}"], + list: ["GET /repos/{owner}/{repo}/pulls"], + listCommentsForReview: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments"], + listCommits: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/commits"], + listFiles: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/files"], + listRequestedReviewers: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers"], + listReviewComments: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/comments"], + listReviewCommentsForRepo: ["GET /repos/{owner}/{repo}/pulls/comments"], + listReviews: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews"], + merge: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge"], + removeRequestedReviewers: ["DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers"], + requestReviewers: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers"], + submitReview: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events"], + update: ["PATCH /repos/{owner}/{repo}/pulls/{pull_number}"], + updateBranch: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch"], + updateReview: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}"], + updateReviewComment: ["PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}"] + }, + rateLimit: { + get: ["GET /rate_limit"] + }, + reactions: { + createForCommitComment: ["POST /repos/{owner}/{repo}/comments/{comment_id}/reactions"], + createForIssue: ["POST /repos/{owner}/{repo}/issues/{issue_number}/reactions"], + createForIssueComment: ["POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions"], + createForPullRequestReviewComment: ["POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions"], + createForRelease: ["POST /repos/{owner}/{repo}/releases/{release_id}/reactions"], + createForTeamDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions"], + createForTeamDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions"], + deleteForCommitComment: ["DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}"], + deleteForIssue: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}"], + deleteForIssueComment: ["DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}"], + deleteForPullRequestComment: ["DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}"], + deleteForRelease: ["DELETE /repos/{owner}/{repo}/releases/{release_id}/reactions/{reaction_id}"], + deleteForTeamDiscussion: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}"], + deleteForTeamDiscussionComment: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}"], + listForCommitComment: ["GET /repos/{owner}/{repo}/comments/{comment_id}/reactions"], + listForIssue: ["GET /repos/{owner}/{repo}/issues/{issue_number}/reactions"], + listForIssueComment: ["GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions"], + listForPullRequestReviewComment: ["GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions"], + listForRelease: ["GET /repos/{owner}/{repo}/releases/{release_id}/reactions"], + listForTeamDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions"], + listForTeamDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions"] + }, + repos: { + acceptInvitation: ["PATCH /user/repository_invitations/{invitation_id}", {}, { + renamed: ["repos", "acceptInvitationForAuthenticatedUser"] + }], + acceptInvitationForAuthenticatedUser: ["PATCH /user/repository_invitations/{invitation_id}"], + addAppAccessRestrictions: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + addCollaborator: ["PUT /repos/{owner}/{repo}/collaborators/{username}"], + addStatusCheckContexts: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + addTeamAccessRestrictions: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + addUserAccessRestrictions: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + checkCollaborator: ["GET /repos/{owner}/{repo}/collaborators/{username}"], + checkVulnerabilityAlerts: ["GET /repos/{owner}/{repo}/vulnerability-alerts"], + codeownersErrors: ["GET /repos/{owner}/{repo}/codeowners/errors"], + compareCommits: ["GET /repos/{owner}/{repo}/compare/{base}...{head}"], + compareCommitsWithBasehead: ["GET /repos/{owner}/{repo}/compare/{basehead}"], + createAutolink: ["POST /repos/{owner}/{repo}/autolinks"], + createCommitComment: ["POST /repos/{owner}/{repo}/commits/{commit_sha}/comments"], + createCommitSignatureProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures"], + createCommitStatus: ["POST /repos/{owner}/{repo}/statuses/{sha}"], + createDeployKey: ["POST /repos/{owner}/{repo}/keys"], + createDeployment: ["POST /repos/{owner}/{repo}/deployments"], + createDeploymentStatus: ["POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses"], + createDispatchEvent: ["POST /repos/{owner}/{repo}/dispatches"], + createForAuthenticatedUser: ["POST /user/repos"], + createFork: ["POST /repos/{owner}/{repo}/forks"], + createInOrg: ["POST /orgs/{org}/repos"], + createOrUpdateEnvironment: ["PUT /repos/{owner}/{repo}/environments/{environment_name}"], + createOrUpdateFileContents: ["PUT /repos/{owner}/{repo}/contents/{path}"], + createPagesSite: ["POST /repos/{owner}/{repo}/pages"], + createRelease: ["POST /repos/{owner}/{repo}/releases"], + createTagProtection: ["POST /repos/{owner}/{repo}/tags/protection"], + createUsingTemplate: ["POST /repos/{template_owner}/{template_repo}/generate"], + createWebhook: ["POST /repos/{owner}/{repo}/hooks"], + declineInvitation: ["DELETE /user/repository_invitations/{invitation_id}", {}, { + renamed: ["repos", "declineInvitationForAuthenticatedUser"] + }], + declineInvitationForAuthenticatedUser: ["DELETE /user/repository_invitations/{invitation_id}"], + delete: ["DELETE /repos/{owner}/{repo}"], + deleteAccessRestrictions: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions"], + deleteAdminBranchProtection: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + deleteAnEnvironment: ["DELETE /repos/{owner}/{repo}/environments/{environment_name}"], + deleteAutolink: ["DELETE /repos/{owner}/{repo}/autolinks/{autolink_id}"], + deleteBranchProtection: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection"], + deleteCommitComment: ["DELETE /repos/{owner}/{repo}/comments/{comment_id}"], + deleteCommitSignatureProtection: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures"], + deleteDeployKey: ["DELETE /repos/{owner}/{repo}/keys/{key_id}"], + deleteDeployment: ["DELETE /repos/{owner}/{repo}/deployments/{deployment_id}"], + deleteFile: ["DELETE /repos/{owner}/{repo}/contents/{path}"], + deleteInvitation: ["DELETE /repos/{owner}/{repo}/invitations/{invitation_id}"], + deletePagesSite: ["DELETE /repos/{owner}/{repo}/pages"], + deletePullRequestReviewProtection: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + deleteRelease: ["DELETE /repos/{owner}/{repo}/releases/{release_id}"], + deleteReleaseAsset: ["DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}"], + deleteTagProtection: ["DELETE /repos/{owner}/{repo}/tags/protection/{tag_protection_id}"], + deleteWebhook: ["DELETE /repos/{owner}/{repo}/hooks/{hook_id}"], + disableAutomatedSecurityFixes: ["DELETE /repos/{owner}/{repo}/automated-security-fixes"], + disableLfsForRepo: ["DELETE /repos/{owner}/{repo}/lfs"], + disableVulnerabilityAlerts: ["DELETE /repos/{owner}/{repo}/vulnerability-alerts"], + downloadArchive: ["GET /repos/{owner}/{repo}/zipball/{ref}", {}, { + renamed: ["repos", "downloadZipballArchive"] + }], + downloadTarballArchive: ["GET /repos/{owner}/{repo}/tarball/{ref}"], + downloadZipballArchive: ["GET /repos/{owner}/{repo}/zipball/{ref}"], + enableAutomatedSecurityFixes: ["PUT /repos/{owner}/{repo}/automated-security-fixes"], + enableLfsForRepo: ["PUT /repos/{owner}/{repo}/lfs"], + enableVulnerabilityAlerts: ["PUT /repos/{owner}/{repo}/vulnerability-alerts"], + generateReleaseNotes: ["POST /repos/{owner}/{repo}/releases/generate-notes"], + get: ["GET /repos/{owner}/{repo}"], + getAccessRestrictions: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions"], + getAdminBranchProtection: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + getAllEnvironments: ["GET /repos/{owner}/{repo}/environments"], + getAllStatusCheckContexts: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts"], + getAllTopics: ["GET /repos/{owner}/{repo}/topics"], + getAppsWithAccessToProtectedBranch: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps"], + getAutolink: ["GET /repos/{owner}/{repo}/autolinks/{autolink_id}"], + getBranch: ["GET /repos/{owner}/{repo}/branches/{branch}"], + getBranchProtection: ["GET /repos/{owner}/{repo}/branches/{branch}/protection"], + getClones: ["GET /repos/{owner}/{repo}/traffic/clones"], + getCodeFrequencyStats: ["GET /repos/{owner}/{repo}/stats/code_frequency"], + getCollaboratorPermissionLevel: ["GET /repos/{owner}/{repo}/collaborators/{username}/permission"], + getCombinedStatusForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/status"], + getCommit: ["GET /repos/{owner}/{repo}/commits/{ref}"], + getCommitActivityStats: ["GET /repos/{owner}/{repo}/stats/commit_activity"], + getCommitComment: ["GET /repos/{owner}/{repo}/comments/{comment_id}"], + getCommitSignatureProtection: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures"], + getCommunityProfileMetrics: ["GET /repos/{owner}/{repo}/community/profile"], + getContent: ["GET /repos/{owner}/{repo}/contents/{path}"], + getContributorsStats: ["GET /repos/{owner}/{repo}/stats/contributors"], + getDeployKey: ["GET /repos/{owner}/{repo}/keys/{key_id}"], + getDeployment: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}"], + getDeploymentStatus: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}"], + getEnvironment: ["GET /repos/{owner}/{repo}/environments/{environment_name}"], + getLatestPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/latest"], + getLatestRelease: ["GET /repos/{owner}/{repo}/releases/latest"], + getPages: ["GET /repos/{owner}/{repo}/pages"], + getPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/{build_id}"], + getPagesHealthCheck: ["GET /repos/{owner}/{repo}/pages/health"], + getParticipationStats: ["GET /repos/{owner}/{repo}/stats/participation"], + getPullRequestReviewProtection: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + getPunchCardStats: ["GET /repos/{owner}/{repo}/stats/punch_card"], + getReadme: ["GET /repos/{owner}/{repo}/readme"], + getReadmeInDirectory: ["GET /repos/{owner}/{repo}/readme/{dir}"], + getRelease: ["GET /repos/{owner}/{repo}/releases/{release_id}"], + getReleaseAsset: ["GET /repos/{owner}/{repo}/releases/assets/{asset_id}"], + getReleaseByTag: ["GET /repos/{owner}/{repo}/releases/tags/{tag}"], + getStatusChecksProtection: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + getTeamsWithAccessToProtectedBranch: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams"], + getTopPaths: ["GET /repos/{owner}/{repo}/traffic/popular/paths"], + getTopReferrers: ["GET /repos/{owner}/{repo}/traffic/popular/referrers"], + getUsersWithAccessToProtectedBranch: ["GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users"], + getViews: ["GET /repos/{owner}/{repo}/traffic/views"], + getWebhook: ["GET /repos/{owner}/{repo}/hooks/{hook_id}"], + getWebhookConfigForRepo: ["GET /repos/{owner}/{repo}/hooks/{hook_id}/config"], + getWebhookDelivery: ["GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}"], + listAutolinks: ["GET /repos/{owner}/{repo}/autolinks"], + listBranches: ["GET /repos/{owner}/{repo}/branches"], + listBranchesForHeadCommit: ["GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head"], + listCollaborators: ["GET /repos/{owner}/{repo}/collaborators"], + listCommentsForCommit: ["GET /repos/{owner}/{repo}/commits/{commit_sha}/comments"], + listCommitCommentsForRepo: ["GET /repos/{owner}/{repo}/comments"], + listCommitStatusesForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/statuses"], + listCommits: ["GET /repos/{owner}/{repo}/commits"], + listContributors: ["GET /repos/{owner}/{repo}/contributors"], + listDeployKeys: ["GET /repos/{owner}/{repo}/keys"], + listDeploymentStatuses: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses"], + listDeployments: ["GET /repos/{owner}/{repo}/deployments"], + listForAuthenticatedUser: ["GET /user/repos"], + listForOrg: ["GET /orgs/{org}/repos"], + listForUser: ["GET /users/{username}/repos"], + listForks: ["GET /repos/{owner}/{repo}/forks"], + listInvitations: ["GET /repos/{owner}/{repo}/invitations"], + listInvitationsForAuthenticatedUser: ["GET /user/repository_invitations"], + listLanguages: ["GET /repos/{owner}/{repo}/languages"], + listPagesBuilds: ["GET /repos/{owner}/{repo}/pages/builds"], + listPublic: ["GET /repositories"], + listPullRequestsAssociatedWithCommit: ["GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls"], + listReleaseAssets: ["GET /repos/{owner}/{repo}/releases/{release_id}/assets"], + listReleases: ["GET /repos/{owner}/{repo}/releases"], + listTagProtection: ["GET /repos/{owner}/{repo}/tags/protection"], + listTags: ["GET /repos/{owner}/{repo}/tags"], + listTeams: ["GET /repos/{owner}/{repo}/teams"], + listWebhookDeliveries: ["GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries"], + listWebhooks: ["GET /repos/{owner}/{repo}/hooks"], + merge: ["POST /repos/{owner}/{repo}/merges"], + mergeUpstream: ["POST /repos/{owner}/{repo}/merge-upstream"], + pingWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/pings"], + redeliverWebhookDelivery: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}/attempts"], + removeAppAccessRestrictions: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + removeCollaborator: ["DELETE /repos/{owner}/{repo}/collaborators/{username}"], + removeStatusCheckContexts: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + removeStatusCheckProtection: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + removeTeamAccessRestrictions: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + removeUserAccessRestrictions: ["DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], + replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: ["POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins"], + setAppAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", {}, { + mapToData: "apps" + }], + setStatusCheckContexts: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", {}, { + mapToData: "contexts" + }], + setTeamAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", {}, { + mapToData: "teams" + }], + setUserAccessRestrictions: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", {}, { + mapToData: "users" + }], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: ["PUT /repos/{owner}/{repo}/branches/{branch}/protection"], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: ["PATCH /repos/{owner}/{repo}/invitations/{invitation_id}"], + updatePullRequestReviewProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews"], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: ["PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}"], + updateStatusCheckPotection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", {}, { + renamed: ["repos", "updateStatusCheckProtection"] + }], + updateStatusCheckProtection: ["PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks"], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config"], + uploadReleaseAsset: ["POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", { + baseUrl: "https://uploads.github.com" + }] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"], + listAlertsForEnterprise: ["GET /enterprises/{enterprise}/secret-scanning/alerts"], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: ["GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations"], + updateAlert: ["PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}"] + }, + teams: { + addOrUpdateMembershipForUserInOrg: ["PUT /orgs/{org}/teams/{team_slug}/memberships/{username}"], + addOrUpdateProjectPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + addOrUpdateRepoPermissionsInOrg: ["PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + checkPermissionsForProjectInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + checkPermissionsForRepoInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + deleteDiscussionInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + getDiscussionInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + getMembershipForUserInOrg: ["GET /orgs/{org}/teams/{team_slug}/memberships/{username}"], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments"], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: ["GET /orgs/{org}/teams/{team_slug}/invitations"], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}"], + removeProjectInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}"], + removeRepoInOrg: ["DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}"], + updateDiscussionCommentInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}"], + updateDiscussionInOrg: ["PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}"], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: ["POST /user/emails", {}, { + renamed: ["users", "addEmailForAuthenticatedUser"] + }], + addEmailForAuthenticatedUser: ["POST /user/emails"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: ["POST /user/gpg_keys", {}, { + renamed: ["users", "createGpgKeyForAuthenticatedUser"] + }], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: ["POST /user/keys", {}, { + renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] + }], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + deleteEmailForAuthenticated: ["DELETE /user/emails", {}, { + renamed: ["users", "deleteEmailForAuthenticatedUser"] + }], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: ["DELETE /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] + }], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: ["DELETE /user/keys/{key_id}", {}, { + renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] + }], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: ["GET /user/gpg_keys/{gpg_key_id}", {}, { + renamed: ["users", "getGpgKeyForAuthenticatedUser"] + }], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: ["GET /user/keys/{key_id}", {}, { + renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] + }], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + list: ["GET /users"], + listBlockedByAuthenticated: ["GET /user/blocks", {}, { + renamed: ["users", "listBlockedByAuthenticatedUser"] + }], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: ["GET /user/emails", {}, { + renamed: ["users", "listEmailsForAuthenticatedUser"] + }], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: ["GET /user/following", {}, { + renamed: ["users", "listFollowedByAuthenticatedUser"] + }], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: ["GET /user/gpg_keys", {}, { + renamed: ["users", "listGpgKeysForAuthenticatedUser"] + }], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: ["GET /user/public_emails", {}, { + renamed: ["users", "listPublicEmailsForAuthenticatedUser"] + }], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: ["GET /user/keys", {}, { + renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] + }], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + setPrimaryEmailVisibilityForAuthenticated: ["PATCH /user/email/visibility", {}, { + renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] + }], + setPrimaryEmailVisibilityForAuthenticatedUser: ["PATCH /user/email/visibility"], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; + +const VERSION = "5.16.2"; + +function endpointsToMethods(octokit, endpointsMap) { + const newMethods = {}; + + for (const [scope, endpoints] of Object.entries(endpointsMap)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign({ + method, + url + }, defaults); + + if (!newMethods[scope]) { + newMethods[scope] = {}; + } + + const scopeMethods = newMethods[scope]; + + if (decorations) { + scopeMethods[methodName] = decorate(octokit, scope, methodName, endpointDefaults, decorations); + continue; + } + + scopeMethods[methodName] = octokit.request.defaults(endpointDefaults); + } + } + + return newMethods; +} + +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + /* istanbul ignore next */ + + function withDecorations(...args) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + let options = requestWithDefaults.endpoint.merge(...args); // There are currently no other decorations than `.mapToData` + + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: undefined + }); + return requestWithDefaults(options); + } + + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn(`octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()`); + } + + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } + + if (decorations.renamedParameters) { + // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + const options = requestWithDefaults.endpoint.merge(...args); + + for (const [name, alias] of Object.entries(decorations.renamedParameters)) { + if (name in options) { + octokit.log.warn(`"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead`); + + if (!(alias in options)) { + options[alias] = options[name]; + } + + delete options[name]; + } + } + + return requestWithDefaults(options); + } // @ts-ignore https://github.com/microsoft/TypeScript/issues/25488 + + + return requestWithDefaults(...args); + } + + return Object.assign(withDecorations, requestWithDefaults); +} + +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit, Endpoints); + return _objectSpread2(_objectSpread2({}, api), {}, { + rest: api + }); +} +legacyRestEndpointMethods.VERSION = VERSION; + +exports.legacyRestEndpointMethods = legacyRestEndpointMethods; +exports.restEndpointMethods = restEndpointMethods; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 537: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var deprecation = __nccwpck_require__(8932); +var once = _interopDefault(__nccwpck_require__(1223)); + +const logOnceCode = once(deprecation => console.warn(deprecation)); +const logOnceHeaders = once(deprecation => console.warn(deprecation)); +/** + * Error with extra properties to help with debugging + */ + +class RequestError extends Error { + constructor(message, statusCode, options) { + super(message); // Maintains proper stack trace (only available on V8) + + /* istanbul ignore next */ + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = "HttpError"; + this.status = statusCode; + let headers; + + if ("headers" in options && typeof options.headers !== "undefined") { + headers = options.headers; + } + + if ("response" in options) { + this.response = options.response; + headers = options.response.headers; + } // redact request credentials without mutating original request options + + + const requestCopy = Object.assign({}, options.request); + + if (options.request.headers.authorization) { + requestCopy.headers = Object.assign({}, options.request.headers, { + authorization: options.request.headers.authorization.replace(/ .*$/, " [REDACTED]") + }); + } + + requestCopy.url = requestCopy.url // client_id & client_secret can be passed as URL query parameters to increase rate limit + // see https://developer.github.com/v3/#increasing-the-unauthenticated-rate-limit-for-oauth-applications + .replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]") // OAuth tokens can be passed as URL query parameters, although it is not recommended + // see https://developer.github.com/v3/#oauth2-token-sent-in-a-header + .replace(/\baccess_token=\w+/g, "access_token=[REDACTED]"); + this.request = requestCopy; // deprecations + + Object.defineProperty(this, "code", { + get() { + logOnceCode(new deprecation.Deprecation("[@octokit/request-error] `error.code` is deprecated, use `error.status`.")); + return statusCode; + } + + }); + Object.defineProperty(this, "headers", { + get() { + logOnceHeaders(new deprecation.Deprecation("[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`.")); + return headers || {}; + } + + }); + } + +} + +exports.RequestError = RequestError; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 6234: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var endpoint = __nccwpck_require__(9440); +var universalUserAgent = __nccwpck_require__(5030); +var isPlainObject = __nccwpck_require__(3287); +var nodeFetch = _interopDefault(__nccwpck_require__(1768)); +var requestError = __nccwpck_require__(537); + +const VERSION = "5.6.3"; + +function getBufferResponse(response) { + return response.arrayBuffer(); +} + +function fetchWrapper(requestOptions) { + const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console; + + if (isPlainObject.isPlainObject(requestOptions.body) || Array.isArray(requestOptions.body)) { + requestOptions.body = JSON.stringify(requestOptions.body); + } + + let headers = {}; + let status; + let url; + const fetch = requestOptions.request && requestOptions.request.fetch || nodeFetch; + return fetch(requestOptions.url, Object.assign({ + method: requestOptions.method, + body: requestOptions.body, + headers: requestOptions.headers, + redirect: requestOptions.redirect + }, // `requestOptions.request.agent` type is incompatible + // see https://github.com/octokit/types.ts/pull/264 + requestOptions.request)).then(async response => { + url = response.url; + status = response.status; + + for (const keyAndValue of response.headers) { + headers[keyAndValue[0]] = keyAndValue[1]; + } + + if ("deprecation" in headers) { + const matches = headers.link && headers.link.match(/<([^>]+)>; rel="deprecation"/); + const deprecationLink = matches && matches.pop(); + log.warn(`[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}`); + } + + if (status === 204 || status === 205) { + return; + } // GitHub API returns 200 for HEAD requests + + + if (requestOptions.method === "HEAD") { + if (status < 400) { + return; + } + + throw new requestError.RequestError(response.statusText, status, { + response: { + url, + status, + headers, + data: undefined + }, + request: requestOptions + }); + } + + if (status === 304) { + throw new requestError.RequestError("Not modified", status, { + response: { + url, + status, + headers, + data: await getResponseData(response) + }, + request: requestOptions + }); + } + + if (status >= 400) { + const data = await getResponseData(response); + const error = new requestError.RequestError(toErrorMessage(data), status, { + response: { + url, + status, + headers, + data + }, + request: requestOptions + }); + throw error; + } + + return getResponseData(response); + }).then(data => { + return { + status, + url, + headers, + data + }; + }).catch(error => { + if (error instanceof requestError.RequestError) throw error; + throw new requestError.RequestError(error.message, 500, { + request: requestOptions + }); + }); +} + +async function getResponseData(response) { + const contentType = response.headers.get("content-type"); + + if (/application\/json/.test(contentType)) { + return response.json(); + } + + if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) { + return response.text(); + } + + return getBufferResponse(response); +} + +function toErrorMessage(data) { + if (typeof data === "string") return data; // istanbul ignore else - just in case + + if ("message" in data) { + if (Array.isArray(data.errors)) { + return `${data.message}: ${data.errors.map(JSON.stringify).join(", ")}`; + } + + return data.message; + } // istanbul ignore next - just in case + + + return `Unknown error: ${JSON.stringify(data)}`; +} + +function withDefaults(oldEndpoint, newDefaults) { + const endpoint = oldEndpoint.defaults(newDefaults); + + const newApi = function (route, parameters) { + const endpointOptions = endpoint.merge(route, parameters); + + if (!endpointOptions.request || !endpointOptions.request.hook) { + return fetchWrapper(endpoint.parse(endpointOptions)); + } + + const request = (route, parameters) => { + return fetchWrapper(endpoint.parse(endpoint.merge(route, parameters))); + }; + + Object.assign(request, { + endpoint, + defaults: withDefaults.bind(null, endpoint) + }); + return endpointOptions.request.hook(request, endpointOptions); + }; + + return Object.assign(newApi, { + endpoint, + defaults: withDefaults.bind(null, endpoint) + }); +} + +const request = withDefaults(endpoint.endpoint, { + headers: { + "user-agent": `octokit-request.js/${VERSION} ${universalUserAgent.getUserAgent()}` + } +}); + +exports.request = request; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 1768: +/***/ ((module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +var Stream = _interopDefault(__nccwpck_require__(2781)); +var http = _interopDefault(__nccwpck_require__(3685)); +var Url = _interopDefault(__nccwpck_require__(7310)); +var whatwgUrl = _interopDefault(__nccwpck_require__(8665)); +var https = _interopDefault(__nccwpck_require__(5687)); +var zlib = _interopDefault(__nccwpck_require__(9796)); + +// Based on https://github.com/tmpvar/jsdom/blob/aa85b2abf07766ff7bf5c1f6daafb3726f2f2db5/lib/jsdom/living/blob.js + +// fix for "Readable" isn't a named export issue +const Readable = Stream.Readable; + +const BUFFER = Symbol('buffer'); +const TYPE = Symbol('type'); + +class Blob { + constructor() { + this[TYPE] = ''; + + const blobParts = arguments[0]; + const options = arguments[1]; + + const buffers = []; + let size = 0; + + if (blobParts) { + const a = blobParts; + const length = Number(a.length); + for (let i = 0; i < length; i++) { + const element = a[i]; + let buffer; + if (element instanceof Buffer) { + buffer = element; + } else if (ArrayBuffer.isView(element)) { + buffer = Buffer.from(element.buffer, element.byteOffset, element.byteLength); + } else if (element instanceof ArrayBuffer) { + buffer = Buffer.from(element); + } else if (element instanceof Blob) { + buffer = element[BUFFER]; + } else { + buffer = Buffer.from(typeof element === 'string' ? element : String(element)); + } + size += buffer.length; + buffers.push(buffer); + } + } + + this[BUFFER] = Buffer.concat(buffers); + + let type = options && options.type !== undefined && String(options.type).toLowerCase(); + if (type && !/[^\u0020-\u007E]/.test(type)) { + this[TYPE] = type; + } + } + get size() { + return this[BUFFER].length; + } + get type() { + return this[TYPE]; + } + text() { + return Promise.resolve(this[BUFFER].toString()); + } + arrayBuffer() { + const buf = this[BUFFER]; + const ab = buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + return Promise.resolve(ab); + } + stream() { + const readable = new Readable(); + readable._read = function () {}; + readable.push(this[BUFFER]); + readable.push(null); + return readable; + } + toString() { + return '[object Blob]'; + } + slice() { + const size = this.size; + + const start = arguments[0]; + const end = arguments[1]; + let relativeStart, relativeEnd; + if (start === undefined) { + relativeStart = 0; + } else if (start < 0) { + relativeStart = Math.max(size + start, 0); + } else { + relativeStart = Math.min(start, size); + } + if (end === undefined) { + relativeEnd = size; + } else if (end < 0) { + relativeEnd = Math.max(size + end, 0); + } else { + relativeEnd = Math.min(end, size); + } + const span = Math.max(relativeEnd - relativeStart, 0); + + const buffer = this[BUFFER]; + const slicedBuffer = buffer.slice(relativeStart, relativeStart + span); + const blob = new Blob([], { type: arguments[2] }); + blob[BUFFER] = slicedBuffer; + return blob; + } +} + +Object.defineProperties(Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}); + +Object.defineProperty(Blob.prototype, Symbol.toStringTag, { + value: 'Blob', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * fetch-error.js + * + * FetchError interface for operational errors + */ + +/** + * Create FetchError instance + * + * @param String message Error message for human + * @param String type Error type for machine + * @param String systemError For Node.js system error + * @return FetchError + */ +function FetchError(message, type, systemError) { + Error.call(this, message); + + this.message = message; + this.type = type; + + // when err.type is `system`, err.code contains system error code + if (systemError) { + this.code = this.errno = systemError.code; + } + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +FetchError.prototype = Object.create(Error.prototype); +FetchError.prototype.constructor = FetchError; +FetchError.prototype.name = 'FetchError'; + +let convert; +try { + convert = (__nccwpck_require__(1635)/* .convert */ .O); +} catch (e) {} + +const INTERNALS = Symbol('Body internals'); + +// fix an issue where "PassThrough" isn't a named export for node <10 +const PassThrough = Stream.PassThrough; + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +function Body(body) { + var _this = this; + + var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}, + _ref$size = _ref.size; + + let size = _ref$size === undefined ? 0 : _ref$size; + var _ref$timeout = _ref.timeout; + let timeout = _ref$timeout === undefined ? 0 : _ref$timeout; + + if (body == null) { + // body is undefined or null + body = null; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + body = Buffer.from(body.toString()); + } else if (isBlob(body)) ; else if (Buffer.isBuffer(body)) ; else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + body = Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + body = Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof Stream) ; else { + // none of the above + // coerce to string then buffer + body = Buffer.from(String(body)); + } + this[INTERNALS] = { + body, + disturbed: false, + error: null + }; + this.size = size; + this.timeout = timeout; + + if (body instanceof Stream) { + body.on('error', function (err) { + const error = err.name === 'AbortError' ? err : new FetchError(`Invalid response body while trying to fetch ${_this.url}: ${err.message}`, 'system', err); + _this[INTERNALS].error = error; + }); + } +} + +Body.prototype = { + get body() { + return this[INTERNALS].body; + }, + + get bodyUsed() { + return this[INTERNALS].disturbed; + }, + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + arrayBuffer() { + return consumeBody.call(this).then(function (buf) { + return buf.buffer.slice(buf.byteOffset, buf.byteOffset + buf.byteLength); + }); + }, + + /** + * Return raw response as Blob + * + * @return Promise + */ + blob() { + let ct = this.headers && this.headers.get('content-type') || ''; + return consumeBody.call(this).then(function (buf) { + return Object.assign( + // Prevent copying + new Blob([], { + type: ct.toLowerCase() + }), { + [BUFFER]: buf + }); + }); + }, + + /** + * Decode response as json + * + * @return Promise + */ + json() { + var _this2 = this; + + return consumeBody.call(this).then(function (buffer) { + try { + return JSON.parse(buffer.toString()); + } catch (err) { + return Body.Promise.reject(new FetchError(`invalid json response body at ${_this2.url} reason: ${err.message}`, 'invalid-json')); + } + }); + }, + + /** + * Decode response as text + * + * @return Promise + */ + text() { + return consumeBody.call(this).then(function (buffer) { + return buffer.toString(); + }); + }, + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody.call(this); + }, + + /** + * Decode response as text, while automatically detecting the encoding and + * trying to decode to UTF-8 (non-spec api) + * + * @return Promise + */ + textConverted() { + var _this3 = this; + + return consumeBody.call(this).then(function (buffer) { + return convertBody(buffer, _this3.headers); + }); + } +}; + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: { enumerable: true }, + bodyUsed: { enumerable: true }, + arrayBuffer: { enumerable: true }, + blob: { enumerable: true }, + json: { enumerable: true }, + text: { enumerable: true } +}); + +Body.mixIn = function (proto) { + for (const name of Object.getOwnPropertyNames(Body.prototype)) { + // istanbul ignore else: future proof + if (!(name in proto)) { + const desc = Object.getOwnPropertyDescriptor(Body.prototype, name); + Object.defineProperty(proto, name, desc); + } + } +}; + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +function consumeBody() { + var _this4 = this; + + if (this[INTERNALS].disturbed) { + return Body.Promise.reject(new TypeError(`body used already for: ${this.url}`)); + } + + this[INTERNALS].disturbed = true; + + if (this[INTERNALS].error) { + return Body.Promise.reject(this[INTERNALS].error); + } + + let body = this.body; + + // body is null + if (body === null) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is blob + if (isBlob(body)) { + body = body.stream(); + } + + // body is buffer + if (Buffer.isBuffer(body)) { + return Body.Promise.resolve(body); + } + + // istanbul ignore if: should never happen + if (!(body instanceof Stream)) { + return Body.Promise.resolve(Buffer.alloc(0)); + } + + // body is stream + // get ready to actually consume the body + let accum = []; + let accumBytes = 0; + let abort = false; + + return new Body.Promise(function (resolve, reject) { + let resTimeout; + + // allow timeout on slow response body + if (_this4.timeout) { + resTimeout = setTimeout(function () { + abort = true; + reject(new FetchError(`Response timeout while trying to fetch ${_this4.url} (over ${_this4.timeout}ms)`, 'body-timeout')); + }, _this4.timeout); + } + + // handle stream errors + body.on('error', function (err) { + if (err.name === 'AbortError') { + // if the request was aborted, reject with this Error + abort = true; + reject(err); + } else { + // other errors, such as incorrect content-encoding + reject(new FetchError(`Invalid response body while trying to fetch ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + + body.on('data', function (chunk) { + if (abort || chunk === null) { + return; + } + + if (_this4.size && accumBytes + chunk.length > _this4.size) { + abort = true; + reject(new FetchError(`content size at ${_this4.url} over limit: ${_this4.size}`, 'max-size')); + return; + } + + accumBytes += chunk.length; + accum.push(chunk); + }); + + body.on('end', function () { + if (abort) { + return; + } + + clearTimeout(resTimeout); + + try { + resolve(Buffer.concat(accum, accumBytes)); + } catch (err) { + // handle streams that have accumulated too much data (issue #414) + reject(new FetchError(`Could not create Buffer from response body for ${_this4.url}: ${err.message}`, 'system', err)); + } + }); + }); +} + +/** + * Detect buffer encoding and convert to target encoding + * ref: http://www.w3.org/TR/2011/WD-html5-20110113/parsing.html#determining-the-character-encoding + * + * @param Buffer buffer Incoming buffer + * @param String encoding Target encoding + * @return String + */ +function convertBody(buffer, headers) { + if (typeof convert !== 'function') { + throw new Error('The package `encoding` must be installed to use the textConverted() function'); + } + + const ct = headers.get('content-type'); + let charset = 'utf-8'; + let res, str; + + // header + if (ct) { + res = /charset=([^;]*)/i.exec(ct); + } + + // no charset in content type, peek at response body for at most 1024 bytes + str = buffer.slice(0, 1024).toString(); + + // html5 + if (!res && str) { + res = /<meta.+?charset=(['"])(.+?)\1/i.exec(str); + } + + // html4 + if (!res && str) { + res = /<meta[\s]+?http-equiv=(['"])content-type\1[\s]+?content=(['"])(.+?)\2/i.exec(str); + if (!res) { + res = /<meta[\s]+?content=(['"])(.+?)\1[\s]+?http-equiv=(['"])content-type\3/i.exec(str); + if (res) { + res.pop(); // drop last quote + } + } + + if (res) { + res = /charset=(.*)/i.exec(res.pop()); + } + } + + // xml + if (!res && str) { + res = /<\?xml.+?encoding=(['"])(.+?)\1/i.exec(str); + } + + // found charset + if (res) { + charset = res.pop(); + + // prevent decode issues when sites use incorrect encoding + // ref: https://hsivonen.fi/encoding-menu/ + if (charset === 'gb2312' || charset === 'gbk') { + charset = 'gb18030'; + } + } + + // turn raw buffers into a single utf-8 buffer + return convert(buffer, 'UTF-8', charset).toString(); +} + +/** + * Detect a URLSearchParams object + * ref: https://github.com/bitinn/node-fetch/issues/296#issuecomment-307598143 + * + * @param Object obj Object to detect by type or brand + * @return String + */ +function isURLSearchParams(obj) { + // Duck-typing as a necessary condition. + if (typeof obj !== 'object' || typeof obj.append !== 'function' || typeof obj.delete !== 'function' || typeof obj.get !== 'function' || typeof obj.getAll !== 'function' || typeof obj.has !== 'function' || typeof obj.set !== 'function') { + return false; + } + + // Brand-checking and more duck-typing as optional condition. + return obj.constructor.name === 'URLSearchParams' || Object.prototype.toString.call(obj) === '[object URLSearchParams]' || typeof obj.sort === 'function'; +} + +/** + * Check if `obj` is a W3C `Blob` object (which `File` inherits from) + * @param {*} obj + * @return {boolean} + */ +function isBlob(obj) { + return typeof obj === 'object' && typeof obj.arrayBuffer === 'function' && typeof obj.type === 'string' && typeof obj.stream === 'function' && typeof obj.constructor === 'function' && typeof obj.constructor.name === 'string' && /^(Blob|File)$/.test(obj.constructor.name) && /^(Blob|File)$/.test(obj[Symbol.toStringTag]); +} + +/** + * Clone body given Res/Req instance + * + * @param Mixed instance Response or Request instance + * @return Mixed + */ +function clone(instance) { + let p1, p2; + let body = instance.body; + + // don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } + + // check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if (body instanceof Stream && typeof body.getBoundary !== 'function') { + // tee instance body + p1 = new PassThrough(); + p2 = new PassThrough(); + body.pipe(p1); + body.pipe(p2); + // set instance body to teed body and return the other teed body + instance[INTERNALS].body = p1; + body = p2; + } + + return body; +} + +/** + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. + * + * @param Mixed instance Any options.body input + */ +function extractContentType(body) { + if (body === null) { + // body is null + return null; + } else if (typeof body === 'string') { + // body is string + return 'text/plain;charset=UTF-8'; + } else if (isURLSearchParams(body)) { + // body is a URLSearchParams + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } else if (isBlob(body)) { + // body is blob + return body.type || null; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return null; + } else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') { + // body is ArrayBuffer + return null; + } else if (ArrayBuffer.isView(body)) { + // body is ArrayBufferView + return null; + } else if (typeof body.getBoundary === 'function') { + // detect form data input from form-data module + return `multipart/form-data;boundary=${body.getBoundary()}`; + } else if (body instanceof Stream) { + // body is stream + // can't really do much about this + return null; + } else { + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; + } +} + +/** + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes + * + * @param Body instance Instance of Body + * @return Number? Number of bytes, or null if not possible + */ +function getTotalBytes(instance) { + const body = instance.body; + + + if (body === null) { + // body is null + return 0; + } else if (isBlob(body)) { + return body.size; + } else if (Buffer.isBuffer(body)) { + // body is buffer + return body.length; + } else if (body && typeof body.getLengthSync === 'function') { + // detect form data input from form-data module + if (body._lengthRetrievers && body._lengthRetrievers.length == 0 || // 1.x + body.hasKnownLength && body.hasKnownLength()) { + // 2.x + return body.getLengthSync(); + } + return null; + } else { + // body is stream + return null; + } +} + +/** + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. + * + * @param Body instance Instance of Body + * @return Void + */ +function writeToStream(dest, instance) { + const body = instance.body; + + + if (body === null) { + // body is null + dest.end(); + } else if (isBlob(body)) { + body.stream().pipe(dest); + } else if (Buffer.isBuffer(body)) { + // body is buffer + dest.write(body); + dest.end(); + } else { + // body is stream + body.pipe(dest); + } +} + +// expose Promise +Body.Promise = global.Promise; + +/** + * headers.js + * + * Headers class offers convenient helpers + */ + +const invalidTokenRegex = /[^\^_`a-zA-Z\-0-9!#$%&'*+.|~]/; +const invalidHeaderCharRegex = /[^\t\x20-\x7e\x80-\xff]/; + +function validateName(name) { + name = `${name}`; + if (invalidTokenRegex.test(name) || name === '') { + throw new TypeError(`${name} is not a legal HTTP header name`); + } +} + +function validateValue(value) { + value = `${value}`; + if (invalidHeaderCharRegex.test(value)) { + throw new TypeError(`${value} is not a legal HTTP header value`); + } +} + +/** + * Find the key in the map object given a header name. + * + * Returns undefined if not found. + * + * @param String name Header name + * @return String|Undefined + */ +function find(map, name) { + name = name.toLowerCase(); + for (const key in map) { + if (key.toLowerCase() === name) { + return key; + } + } + return undefined; +} + +const MAP = Symbol('map'); +class Headers { + /** + * Headers class + * + * @param Object headers Response headers + * @return Void + */ + constructor() { + let init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : undefined; + + this[MAP] = Object.create(null); + + if (init instanceof Headers) { + const rawHeaders = init.raw(); + const headerNames = Object.keys(rawHeaders); + + for (const headerName of headerNames) { + for (const value of rawHeaders[headerName]) { + this.append(headerName, value); + } + } + + return; + } + + // We don't worry about converting prop to ByteString here as append() + // will handle it. + if (init == null) ; else if (typeof init === 'object') { + const method = init[Symbol.iterator]; + if (method != null) { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // sequence<sequence<ByteString>> + // Note: per spec we have to first exhaust the lists then process them + const pairs = []; + for (const pair of init) { + if (typeof pair !== 'object' || typeof pair[Symbol.iterator] !== 'function') { + throw new TypeError('Each header pair must be iterable'); + } + pairs.push(Array.from(pair)); + } + + for (const pair of pairs) { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + this.append(pair[0], pair[1]); + } + } else { + // record<ByteString, ByteString> + for (const key of Object.keys(init)) { + const value = init[key]; + this.append(key, value); + } + } + } else { + throw new TypeError('Provided initializer must be an object'); + } + } + + /** + * Return combined header value given name + * + * @param String name Header name + * @return Mixed + */ + get(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key === undefined) { + return null; + } + + return this[MAP][key].join(', '); + } + + /** + * Iterate over all headers + * + * @param Function callback Executed for each item with parameters (value, name, thisArg) + * @param Boolean thisArg `this` context for callback function + * @return Void + */ + forEach(callback) { + let thisArg = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined; + + let pairs = getHeaders(this); + let i = 0; + while (i < pairs.length) { + var _pairs$i = pairs[i]; + const name = _pairs$i[0], + value = _pairs$i[1]; + + callback.call(thisArg, value, name, this); + pairs = getHeaders(this); + i++; + } + } + + /** + * Overwrite header values given name + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + set(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + this[MAP][key !== undefined ? key : name] = [value]; + } + + /** + * Append a value onto existing header + * + * @param String name Header name + * @param String value Header value + * @return Void + */ + append(name, value) { + name = `${name}`; + value = `${value}`; + validateName(name); + validateValue(value); + const key = find(this[MAP], name); + if (key !== undefined) { + this[MAP][key].push(value); + } else { + this[MAP][name] = [value]; + } + } + + /** + * Check for header name existence + * + * @param String name Header name + * @return Boolean + */ + has(name) { + name = `${name}`; + validateName(name); + return find(this[MAP], name) !== undefined; + } + + /** + * Delete all header values given name + * + * @param String name Header name + * @return Void + */ + delete(name) { + name = `${name}`; + validateName(name); + const key = find(this[MAP], name); + if (key !== undefined) { + delete this[MAP][key]; + } + } + + /** + * Return raw headers (non-spec api) + * + * @return Object + */ + raw() { + return this[MAP]; + } + + /** + * Get an iterator on keys. + * + * @return Iterator + */ + keys() { + return createHeadersIterator(this, 'key'); + } + + /** + * Get an iterator on values. + * + * @return Iterator + */ + values() { + return createHeadersIterator(this, 'value'); + } + + /** + * Get an iterator on entries. + * + * This is the default iterator of the Headers object. + * + * @return Iterator + */ + [Symbol.iterator]() { + return createHeadersIterator(this, 'key+value'); + } +} +Headers.prototype.entries = Headers.prototype[Symbol.iterator]; + +Object.defineProperty(Headers.prototype, Symbol.toStringTag, { + value: 'Headers', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Headers.prototype, { + get: { enumerable: true }, + forEach: { enumerable: true }, + set: { enumerable: true }, + append: { enumerable: true }, + has: { enumerable: true }, + delete: { enumerable: true }, + keys: { enumerable: true }, + values: { enumerable: true }, + entries: { enumerable: true } +}); + +function getHeaders(headers) { + let kind = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'key+value'; + + const keys = Object.keys(headers[MAP]).sort(); + return keys.map(kind === 'key' ? function (k) { + return k.toLowerCase(); + } : kind === 'value' ? function (k) { + return headers[MAP][k].join(', '); + } : function (k) { + return [k.toLowerCase(), headers[MAP][k].join(', ')]; + }); +} + +const INTERNAL = Symbol('internal'); + +function createHeadersIterator(target, kind) { + const iterator = Object.create(HeadersIteratorPrototype); + iterator[INTERNAL] = { + target, + kind, + index: 0 + }; + return iterator; +} + +const HeadersIteratorPrototype = Object.setPrototypeOf({ + next() { + // istanbul ignore if + if (!this || Object.getPrototypeOf(this) !== HeadersIteratorPrototype) { + throw new TypeError('Value of `this` is not a HeadersIterator'); + } + + var _INTERNAL = this[INTERNAL]; + const target = _INTERNAL.target, + kind = _INTERNAL.kind, + index = _INTERNAL.index; + + const values = getHeaders(target, kind); + const len = values.length; + if (index >= len) { + return { + value: undefined, + done: true + }; + } + + this[INTERNAL].index = index + 1; + + return { + value: values[index], + done: false + }; + } +}, Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))); + +Object.defineProperty(HeadersIteratorPrototype, Symbol.toStringTag, { + value: 'HeadersIterator', + writable: false, + enumerable: false, + configurable: true +}); + +/** + * Export the Headers object in a form that Node.js can consume. + * + * @param Headers headers + * @return Object + */ +function exportNodeCompatibleHeaders(headers) { + const obj = Object.assign({ __proto__: null }, headers[MAP]); + + // http.request() only supports string as Host header. This hack makes + // specifying custom Host header possible. + const hostHeaderKey = find(headers[MAP], 'Host'); + if (hostHeaderKey !== undefined) { + obj[hostHeaderKey] = obj[hostHeaderKey][0]; + } + + return obj; +} + +/** + * Create a Headers object from an object of headers, ignoring those that do + * not conform to HTTP grammar productions. + * + * @param Object obj Object of headers + * @return Headers + */ +function createHeadersLenient(obj) { + const headers = new Headers(); + for (const name of Object.keys(obj)) { + if (invalidTokenRegex.test(name)) { + continue; + } + if (Array.isArray(obj[name])) { + for (const val of obj[name]) { + if (invalidHeaderCharRegex.test(val)) { + continue; + } + if (headers[MAP][name] === undefined) { + headers[MAP][name] = [val]; + } else { + headers[MAP][name].push(val); + } + } + } else if (!invalidHeaderCharRegex.test(obj[name])) { + headers[MAP][name] = [obj[name]]; + } + } + return headers; +} + +const INTERNALS$1 = Symbol('Response internals'); + +// fix an issue where "STATUS_CODES" aren't a named export for node <10 +const STATUS_CODES = http.STATUS_CODES; + +/** + * Response class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response { + constructor() { + let body = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : null; + let opts = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + Body.call(this, body, opts); + + const status = opts.status || 200; + const headers = new Headers(opts.headers); + + if (body != null && !headers.has('Content-Type')) { + const contentType = extractContentType(body); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[INTERNALS$1] = { + url: opts.url, + status, + statusText: opts.statusText || STATUS_CODES[status], + headers, + counter: opts.counter + }; + } + + get url() { + return this[INTERNALS$1].url || ''; + } + + get status() { + return this[INTERNALS$1].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[INTERNALS$1].status >= 200 && this[INTERNALS$1].status < 300; + } + + get redirected() { + return this[INTERNALS$1].counter > 0; + } + + get statusText() { + return this[INTERNALS$1].statusText; + } + + get headers() { + return this[INTERNALS$1].headers; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this), { + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected + }); + } +} + +Body.mixIn(Response.prototype); + +Object.defineProperties(Response.prototype, { + url: { enumerable: true }, + status: { enumerable: true }, + ok: { enumerable: true }, + redirected: { enumerable: true }, + statusText: { enumerable: true }, + headers: { enumerable: true }, + clone: { enumerable: true } +}); + +Object.defineProperty(Response.prototype, Symbol.toStringTag, { + value: 'Response', + writable: false, + enumerable: false, + configurable: true +}); + +const INTERNALS$2 = Symbol('Request internals'); +const URL = Url.URL || whatwgUrl.URL; + +// fix an issue where "format", "parse" aren't a named export for node <10 +const parse_url = Url.parse; +const format_url = Url.format; + +/** + * Wrapper around `new URL` to handle arbitrary URLs + * + * @param {string} urlStr + * @return {void} + */ +function parseURL(urlStr) { + /* + Check whether the URL is absolute or not + Scheme: https://tools.ietf.org/html/rfc3986#section-3.1 + Absolute URL: https://tools.ietf.org/html/rfc3986#section-4.3 + */ + if (/^[a-zA-Z][a-zA-Z\d+\-.]*:/.exec(urlStr)) { + urlStr = new URL(urlStr).toString(); + } + + // Fallback to old implementation for arbitrary URLs + return parse_url(urlStr); +} + +const streamDestructionSupported = 'destroy' in Stream.Readable.prototype; + +/** + * Check if a value is an instance of Request. + * + * @param Mixed input + * @return Boolean + */ +function isRequest(input) { + return typeof input === 'object' && typeof input[INTERNALS$2] === 'object'; +} + +function isAbortSignal(signal) { + const proto = signal && typeof signal === 'object' && Object.getPrototypeOf(signal); + return !!(proto && proto.constructor.name === 'AbortSignal'); +} + +/** + * Request class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request { + constructor(input) { + let init = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; + + let parsedURL; + + // normalize input + if (!isRequest(input)) { + if (input && input.href) { + // in order to support Node.js' Url objects; though WHATWG's URL objects + // will fall into this branch also (since their `toString()` will return + // `href` property anyway) + parsedURL = parseURL(input.href); + } else { + // coerce input to a string before attempting to parse + parsedURL = parseURL(`${input}`); + } + input = {}; + } else { + parsedURL = parseURL(input.url); + } + + let method = init.method || input.method || 'GET'; + method = method.toUpperCase(); + + if ((init.body != null || isRequest(input) && input.body !== null) && (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + let inputBody = init.body != null ? init.body : isRequest(input) && input.body !== null ? clone(input) : null; + + Body.call(this, inputBody, { + timeout: init.timeout || input.timeout || 0, + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody != null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? input.signal : null; + if ('signal' in init) signal = init.signal; + + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal'); + } + + this[INTERNALS$2] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal + }; + + // node-fetch-only options + this.follow = init.follow !== undefined ? init.follow : input.follow !== undefined ? input.follow : 20; + this.compress = init.compress !== undefined ? init.compress : input.compress !== undefined ? input.compress : true; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + } + + get method() { + return this[INTERNALS$2].method; + } + + get url() { + return format_url(this[INTERNALS$2].parsedURL); + } + + get headers() { + return this[INTERNALS$2].headers; + } + + get redirect() { + return this[INTERNALS$2].redirect; + } + + get signal() { + return this[INTERNALS$2].signal; + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } +} + +Body.mixIn(Request.prototype); + +Object.defineProperty(Request.prototype, Symbol.toStringTag, { + value: 'Request', + writable: false, + enumerable: false, + configurable: true +}); + +Object.defineProperties(Request.prototype, { + method: { enumerable: true }, + url: { enumerable: true }, + headers: { enumerable: true }, + redirect: { enumerable: true }, + clone: { enumerable: true }, + signal: { enumerable: true } +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param Request A Request instance + * @return Object The options object to be passed to http.request + */ +function getNodeRequestOptions(request) { + const parsedURL = request[INTERNALS$2].parsedURL; + const headers = new Headers(request[INTERNALS$2].headers); + + // fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // Basic fetch + if (!parsedURL.protocol || !parsedURL.hostname) { + throw new TypeError('Only absolute URLs are supported'); + } + + if (!/^https?:$/.test(parsedURL.protocol)) { + throw new TypeError('Only HTTP(S) protocols are supported'); + } + + if (request.signal && request.body instanceof Stream.Readable && !streamDestructionSupported) { + throw new Error('Cancellation of streamed requests with AbortSignal is not supported in node < 8'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body == null && /^(POST|PUT)$/i.test(request.method)) { + contentLengthValue = '0'; + } + if (request.body != null) { + const totalBytes = getTotalBytes(request); + if (typeof totalBytes === 'number') { + contentLengthValue = String(totalBytes); + } + } + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch/1.0 (+https://github.com/bitinn/node-fetch)'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip,deflate'); + } + + let agent = request.agent; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + return Object.assign({}, parsedURL, { + method: request.method, + headers: exportNodeCompatibleHeaders(headers), + agent + }); +} + +/** + * abort-error.js + * + * AbortError interface for cancelled requests + */ + +/** + * Create AbortError instance + * + * @param String message Error message for human + * @return AbortError + */ +function AbortError(message) { + Error.call(this, message); + + this.type = 'aborted'; + this.message = message; + + // hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); +} + +AbortError.prototype = Object.create(Error.prototype); +AbortError.prototype.constructor = AbortError; +AbortError.prototype.name = 'AbortError'; + +const URL$1 = Url.URL || whatwgUrl.URL; + +// fix an issue where "PassThrough", "resolve" aren't a named export for node <10 +const PassThrough$1 = Stream.PassThrough; + +const isDomainOrSubdomain = function isDomainOrSubdomain(destination, original) { + const orig = new URL$1(original).hostname; + const dest = new URL$1(destination).hostname; + + return orig === dest || orig[orig.length - dest.length - 1] === '.' && orig.endsWith(dest); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = function isSameProtocol(destination, original) { + const orig = new URL$1(original).protocol; + const dest = new URL$1(destination).protocol; + + return orig === dest; +}; + +/** + * Fetch function + * + * @param Mixed url Absolute url or Request instance + * @param Object opts Fetch options + * @return Promise + */ +function fetch(url, opts) { + + // allow custom promise + if (!fetch.Promise) { + throw new Error('native promise missing, set fetch.Promise to your favorite alternative'); + } + + Body.Promise = fetch.Promise; + + // wrap http.request into fetch + return new fetch.Promise(function (resolve, reject) { + // build request object + const request = new Request(url, opts); + const options = getNodeRequestOptions(request); + + const send = (options.protocol === 'https:' ? https : http).request; + const signal = request.signal; + + let response = null; + + const abort = function abort() { + let error = new AbortError('The user aborted a request.'); + reject(error); + if (request.body && request.body instanceof Stream.Readable) { + destroyStream(request.body, error); + } + if (!response || !response.body) return; + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = function abortAndFinalize() { + abort(); + finalize(); + }; + + // send request + const req = send(options); + let reqTimeout; + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + function finalize() { + req.abort(); + if (signal) signal.removeEventListener('abort', abortAndFinalize); + clearTimeout(reqTimeout); + } + + if (request.timeout) { + req.once('socket', function (socket) { + reqTimeout = setTimeout(function () { + reject(new FetchError(`network timeout at: ${request.url}`, 'request-timeout')); + finalize(); + }, request.timeout); + }); + } + + req.on('error', function (err) { + reject(new FetchError(`request to ${request.url} failed, reason: ${err.message}`, 'system', err)); + + if (response && response.body) { + destroyStream(response.body, err); + } + + finalize(); + }); + + fixResponseChunkedTransferBadEnding(req, function (err) { + if (signal && signal.aborted) { + return; + } + + if (response && response.body) { + destroyStream(response.body, err); + } + }); + + /* c8 ignore next 18 */ + if (parseInt(process.version.substring(1)) < 14) { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + req.on('socket', function (s) { + s.addListener('close', function (hadError) { + // if a data listener is still present we didn't end cleanly + const hasDataListener = s.listenerCount('data') > 0; + + // if end happened before close but the socket didn't emit an error, do it now + if (response && hasDataListener && !hadError && !(signal && signal.aborted)) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', err); + } + }); + }); + } + + req.on('response', function (res) { + clearTimeout(reqTimeout); + + const headers = createHeadersLenient(res.headers); + + // HTTP fetch step 5 + if (fetch.isRedirect(res.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL$1(location, request.url).toString(); + } catch (err) { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // node-fetch-specific step: make manual redirect a bit easier to use by setting the Location header value to the resolved URL. + if (locationURL !== null) { + // handle corrupted header + try { + headers.set('Location', locationURL); + } catch (err) { + // istanbul ignore next: nodejs server prevent invalid response headers, we can't test this through normal request + reject(err); + } + } + break; + case 'follow': + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOpts = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: request.body, + signal: request.signal, + timeout: request.timeout, + size: request.size + }; + + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOpts.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (res.statusCode !== 303 && request.body && getTotalBytes(request) === null) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (res.statusCode === 303 || (res.statusCode === 301 || res.statusCode === 302) && request.method === 'POST') { + requestOpts.method = 'GET'; + requestOpts.body = undefined; + requestOpts.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOpts))); + finalize(); + return; + } + } + + // prepare response + res.once('end', function () { + if (signal) signal.removeEventListener('abort', abortAndFinalize); + }); + let body = res.pipe(new PassThrough$1()); + + const response_options = { + url: request.url, + status: res.statusCode, + statusText: res.statusMessage, + headers: headers, + size: request.size, + timeout: request.timeout, + counter: request.counter + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || res.statusCode === 204 || res.statusCode === 304) { + response = new Response(body, response_options); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: zlib.Z_SYNC_FLUSH, + finishFlush: zlib.Z_SYNC_FLUSH + }; + + // for gzip + if (codings == 'gzip' || codings == 'x-gzip') { + body = body.pipe(zlib.createGunzip(zlibOptions)); + response = new Response(body, response_options); + resolve(response); + return; + } + + // for deflate + if (codings == 'deflate' || codings == 'x-deflate') { + // handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = res.pipe(new PassThrough$1()); + raw.once('data', function (chunk) { + // see http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = body.pipe(zlib.createInflate()); + } else { + body = body.pipe(zlib.createInflateRaw()); + } + response = new Response(body, response_options); + resolve(response); + }); + raw.on('end', function () { + // some old IIS servers return zero-length OK deflate responses, so 'data' is never emitted. + if (!response) { + response = new Response(body, response_options); + resolve(response); + } + }); + return; + } + + // for br + if (codings == 'br' && typeof zlib.createBrotliDecompress === 'function') { + body = body.pipe(zlib.createBrotliDecompress()); + response = new Response(body, response_options); + resolve(response); + return; + } + + // otherwise, use response as-is + response = new Response(body, response_options); + resolve(response); + }); + + writeToStream(req, request); + }); +} +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + let socket; + + request.on('socket', function (s) { + socket = s; + }); + + request.on('response', function (response) { + const headers = response.headers; + + if (headers['transfer-encoding'] === 'chunked' && !headers['content-length']) { + response.once('close', function (hadError) { + // tests for socket presence, as in some situations the + // the 'socket' event is not triggered for the request + // (happens in deno), avoids `TypeError` + // if a data listener is still present we didn't end cleanly + const hasDataListener = socket && socket.listenerCount('data') > 0; + + if (hasDataListener && !hadError) { + const err = new Error('Premature close'); + err.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(err); + } + }); + } + }); +} + +function destroyStream(stream, err) { + if (stream.destroy) { + stream.destroy(err); + } else { + // node < 8 + stream.emit('error', err); + stream.end(); + } +} + +/** + * Redirect code matching + * + * @param Number code Status code + * @return Boolean + */ +fetch.isRedirect = function (code) { + return code === 301 || code === 302 || code === 303 || code === 307 || code === 308; +}; + +// expose Promise +fetch.Promise = global.Promise; + +module.exports = exports = fetch; +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports["default"] = exports; +exports.Headers = Headers; +exports.Request = Request; +exports.Response = Response; +exports.FetchError = FetchError; +exports.AbortError = AbortError; + + +/***/ }), + +/***/ 5375: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + Octokit: () => Octokit +}); +module.exports = __toCommonJS(dist_src_exports); +var import_core = __nccwpck_require__(4952); +var import_plugin_request_log = __nccwpck_require__(748); +var import_plugin_paginate_rest = __nccwpck_require__(606); +var import_plugin_rest_endpoint_methods = __nccwpck_require__(4923); + +// pkg/dist-src/version.js +var VERSION = "20.0.2"; + +// pkg/dist-src/index.js +var Octokit = import_core.Octokit.plugin( + import_plugin_request_log.requestLog, + import_plugin_rest_endpoint_methods.legacyRestEndpointMethods, + import_plugin_paginate_rest.paginateRest +).defaults({ + userAgent: `octokit-rest.js/${VERSION}` +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 7633: +/***/ ((module) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + createTokenAuth: () => createTokenAuth +}); +module.exports = __toCommonJS(dist_src_exports); + +// pkg/dist-src/auth.js +var REGEX_IS_INSTALLATION_LEGACY = /^v1\./; +var REGEX_IS_INSTALLATION = /^ghs_/; +var REGEX_IS_USER_TO_SERVER = /^ghu_/; +async function auth(token) { + const isApp = token.split(/\./).length === 3; + const isInstallation = REGEX_IS_INSTALLATION_LEGACY.test(token) || REGEX_IS_INSTALLATION.test(token); + const isUserToServer = REGEX_IS_USER_TO_SERVER.test(token); + const tokenType = isApp ? "app" : isInstallation ? "installation" : isUserToServer ? "user-to-server" : "oauth"; + return { + type: "token", + token, + tokenType + }; +} + +// pkg/dist-src/with-authorization-prefix.js +function withAuthorizationPrefix(token) { + if (token.split(/\./).length === 3) { + return `bearer ${token}`; + } + return `token ${token}`; +} + +// pkg/dist-src/hook.js +async function hook(token, request, route, parameters) { + const endpoint = request.endpoint.merge( + route, + parameters + ); + endpoint.headers.authorization = withAuthorizationPrefix(token); + return request(endpoint); +} + +// pkg/dist-src/index.js +var createTokenAuth = function createTokenAuth2(token) { + if (!token) { + throw new Error("[@octokit/auth-token] No token passed to createTokenAuth"); + } + if (typeof token !== "string") { + throw new Error( + "[@octokit/auth-token] Token passed to createTokenAuth is not a string" + ); + } + token = token.replace(/^(token|bearer) +/i, ""); + return Object.assign(auth.bind(null, token), { + hook: hook.bind(null, token) + }); +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 4952: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + Octokit: () => Octokit +}); +module.exports = __toCommonJS(dist_src_exports); +var import_universal_user_agent = __nccwpck_require__(5030); +var import_before_after_hook = __nccwpck_require__(3682); +var import_request = __nccwpck_require__(6206); +var import_graphql = __nccwpck_require__(7461); +var import_auth_token = __nccwpck_require__(7633); + +// pkg/dist-src/version.js +var VERSION = "5.0.0"; + +// pkg/dist-src/index.js +var Octokit = class { + static { + this.VERSION = VERSION; + } + static defaults(defaults) { + const OctokitWithDefaults = class extends this { + constructor(...args) { + const options = args[0] || {}; + if (typeof defaults === "function") { + super(defaults(options)); + return; + } + super( + Object.assign( + {}, + defaults, + options, + options.userAgent && defaults.userAgent ? { + userAgent: `${options.userAgent} ${defaults.userAgent}` + } : null + ) + ); + } + }; + return OctokitWithDefaults; + } + static { + this.plugins = []; + } + /** + * Attach a plugin (or many) to your Octokit instance. + * + * @example + * const API = Octokit.plugin(plugin1, plugin2, plugin3, ...) + */ + static plugin(...newPlugins) { + const currentPlugins = this.plugins; + const NewOctokit = class extends this { + static { + this.plugins = currentPlugins.concat( + newPlugins.filter((plugin) => !currentPlugins.includes(plugin)) + ); + } + }; + return NewOctokit; + } + constructor(options = {}) { + const hook = new import_before_after_hook.Collection(); + const requestDefaults = { + baseUrl: import_request.request.endpoint.DEFAULTS.baseUrl, + headers: {}, + request: Object.assign({}, options.request, { + // @ts-ignore internal usage only, no need to type + hook: hook.bind(null, "request") + }), + mediaType: { + previews: [], + format: "" + } + }; + requestDefaults.headers["user-agent"] = [ + options.userAgent, + `octokit-core.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}` + ].filter(Boolean).join(" "); + if (options.baseUrl) { + requestDefaults.baseUrl = options.baseUrl; + } + if (options.previews) { + requestDefaults.mediaType.previews = options.previews; + } + if (options.timeZone) { + requestDefaults.headers["time-zone"] = options.timeZone; + } + this.request = import_request.request.defaults(requestDefaults); + this.graphql = (0, import_graphql.withCustomRequest)(this.request).defaults(requestDefaults); + this.log = Object.assign( + { + debug: () => { + }, + info: () => { + }, + warn: console.warn.bind(console), + error: console.error.bind(console) + }, + options.log + ); + this.hook = hook; + if (!options.authStrategy) { + if (!options.auth) { + this.auth = async () => ({ + type: "unauthenticated" + }); + } else { + const auth = (0, import_auth_token.createTokenAuth)(options.auth); + hook.wrap("request", auth.hook); + this.auth = auth; + } + } else { + const { authStrategy, ...otherOptions } = options; + const auth = authStrategy( + Object.assign( + { + request: this.request, + log: this.log, + // we pass the current octokit instance as well as its constructor options + // to allow for authentication strategies that return a new octokit instance + // that shares the same internal state as the current one. The original + // requirement for this was the "event-octokit" authentication strategy + // of https://github.com/probot/octokit-auth-probot. + octokit: this, + octokitOptions: otherOptions + }, + options.auth + ) + ); + hook.wrap("request", auth.hook); + this.auth = auth; + } + const classConstructor = this.constructor; + classConstructor.plugins.forEach((plugin) => { + Object.assign(this, plugin(this, options)); + }); + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 6065: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + endpoint: () => endpoint +}); +module.exports = __toCommonJS(dist_src_exports); + +// pkg/dist-src/defaults.js +var import_universal_user_agent = __nccwpck_require__(5030); + +// pkg/dist-src/version.js +var VERSION = "9.0.0"; + +// pkg/dist-src/defaults.js +var userAgent = `octokit-endpoint.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}`; +var DEFAULTS = { + method: "GET", + baseUrl: "https://api.github.com", + headers: { + accept: "application/vnd.github.v3+json", + "user-agent": userAgent + }, + mediaType: { + format: "" + } +}; + +// pkg/dist-src/util/lowercase-keys.js +function lowercaseKeys(object) { + if (!object) { + return {}; + } + return Object.keys(object).reduce((newObj, key) => { + newObj[key.toLowerCase()] = object[key]; + return newObj; + }, {}); +} + +// pkg/dist-src/util/merge-deep.js +var import_is_plain_object = __nccwpck_require__(3287); +function mergeDeep(defaults, options) { + const result = Object.assign({}, defaults); + Object.keys(options).forEach((key) => { + if ((0, import_is_plain_object.isPlainObject)(options[key])) { + if (!(key in defaults)) + Object.assign(result, { [key]: options[key] }); + else + result[key] = mergeDeep(defaults[key], options[key]); + } else { + Object.assign(result, { [key]: options[key] }); + } + }); + return result; +} + +// pkg/dist-src/util/remove-undefined-properties.js +function removeUndefinedProperties(obj) { + for (const key in obj) { + if (obj[key] === void 0) { + delete obj[key]; + } + } + return obj; +} + +// pkg/dist-src/merge.js +function merge(defaults, route, options) { + if (typeof route === "string") { + let [method, url] = route.split(" "); + options = Object.assign(url ? { method, url } : { url: method }, options); + } else { + options = Object.assign({}, route); + } + options.headers = lowercaseKeys(options.headers); + removeUndefinedProperties(options); + removeUndefinedProperties(options.headers); + const mergedOptions = mergeDeep(defaults || {}, options); + if (options.url === "/graphql") { + if (defaults && defaults.mediaType.previews?.length) { + mergedOptions.mediaType.previews = defaults.mediaType.previews.filter( + (preview) => !mergedOptions.mediaType.previews.includes(preview) + ).concat(mergedOptions.mediaType.previews); + } + mergedOptions.mediaType.previews = (mergedOptions.mediaType.previews || []).map((preview) => preview.replace(/-preview/, "")); + } + return mergedOptions; +} + +// pkg/dist-src/util/add-query-parameters.js +function addQueryParameters(url, parameters) { + const separator = /\?/.test(url) ? "&" : "?"; + const names = Object.keys(parameters); + if (names.length === 0) { + return url; + } + return url + separator + names.map((name) => { + if (name === "q") { + return "q=" + parameters.q.split("+").map(encodeURIComponent).join("+"); + } + return `${name}=${encodeURIComponent(parameters[name])}`; + }).join("&"); +} + +// pkg/dist-src/util/extract-url-variable-names.js +var urlVariableRegex = /\{[^}]+\}/g; +function removeNonChars(variableName) { + return variableName.replace(/^\W+|\W+$/g, "").split(/,/); +} +function extractUrlVariableNames(url) { + const matches = url.match(urlVariableRegex); + if (!matches) { + return []; + } + return matches.map(removeNonChars).reduce((a, b) => a.concat(b), []); +} + +// pkg/dist-src/util/omit.js +function omit(object, keysToOmit) { + return Object.keys(object).filter((option) => !keysToOmit.includes(option)).reduce((obj, key) => { + obj[key] = object[key]; + return obj; + }, {}); +} + +// pkg/dist-src/util/url-template.js +function encodeReserved(str) { + return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) { + if (!/%[0-9A-Fa-f]/.test(part)) { + part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]"); + } + return part; + }).join(""); +} +function encodeUnreserved(str) { + return encodeURIComponent(str).replace(/[!'()*]/g, function(c) { + return "%" + c.charCodeAt(0).toString(16).toUpperCase(); + }); +} +function encodeValue(operator, value, key) { + value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value); + if (key) { + return encodeUnreserved(key) + "=" + value; + } else { + return value; + } +} +function isDefined(value) { + return value !== void 0 && value !== null; +} +function isKeyOperator(operator) { + return operator === ";" || operator === "&" || operator === "?"; +} +function getValues(context, operator, key, modifier) { + var value = context[key], result = []; + if (isDefined(value) && value !== "") { + if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") { + value = value.toString(); + if (modifier && modifier !== "*") { + value = value.substring(0, parseInt(modifier, 10)); + } + result.push( + encodeValue(operator, value, isKeyOperator(operator) ? key : "") + ); + } else { + if (modifier === "*") { + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function(value2) { + result.push( + encodeValue(operator, value2, isKeyOperator(operator) ? key : "") + ); + }); + } else { + Object.keys(value).forEach(function(k) { + if (isDefined(value[k])) { + result.push(encodeValue(operator, value[k], k)); + } + }); + } + } else { + const tmp = []; + if (Array.isArray(value)) { + value.filter(isDefined).forEach(function(value2) { + tmp.push(encodeValue(operator, value2)); + }); + } else { + Object.keys(value).forEach(function(k) { + if (isDefined(value[k])) { + tmp.push(encodeUnreserved(k)); + tmp.push(encodeValue(operator, value[k].toString())); + } + }); + } + if (isKeyOperator(operator)) { + result.push(encodeUnreserved(key) + "=" + tmp.join(",")); + } else if (tmp.length !== 0) { + result.push(tmp.join(",")); + } + } + } + } else { + if (operator === ";") { + if (isDefined(value)) { + result.push(encodeUnreserved(key)); + } + } else if (value === "" && (operator === "&" || operator === "?")) { + result.push(encodeUnreserved(key) + "="); + } else if (value === "") { + result.push(""); + } + } + return result; +} +function parseUrl(template) { + return { + expand: expand.bind(null, template) + }; +} +function expand(template, context) { + var operators = ["+", "#", ".", "/", ";", "?", "&"]; + return template.replace( + /\{([^\{\}]+)\}|([^\{\}]+)/g, + function(_, expression, literal) { + if (expression) { + let operator = ""; + const values = []; + if (operators.indexOf(expression.charAt(0)) !== -1) { + operator = expression.charAt(0); + expression = expression.substr(1); + } + expression.split(/,/g).forEach(function(variable) { + var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable); + values.push(getValues(context, operator, tmp[1], tmp[2] || tmp[3])); + }); + if (operator && operator !== "+") { + var separator = ","; + if (operator === "?") { + separator = "&"; + } else if (operator !== "#") { + separator = operator; + } + return (values.length !== 0 ? operator : "") + values.join(separator); + } else { + return values.join(","); + } + } else { + return encodeReserved(literal); + } + } + ); +} + +// pkg/dist-src/parse.js +function parse(options) { + let method = options.method.toUpperCase(); + let url = (options.url || "/").replace(/:([a-z]\w+)/g, "{$1}"); + let headers = Object.assign({}, options.headers); + let body; + let parameters = omit(options, [ + "method", + "baseUrl", + "url", + "headers", + "request", + "mediaType" + ]); + const urlVariableNames = extractUrlVariableNames(url); + url = parseUrl(url).expand(parameters); + if (!/^http/.test(url)) { + url = options.baseUrl + url; + } + const omittedParameters = Object.keys(options).filter((option) => urlVariableNames.includes(option)).concat("baseUrl"); + const remainingParameters = omit(parameters, omittedParameters); + const isBinaryRequest = /application\/octet-stream/i.test(headers.accept); + if (!isBinaryRequest) { + if (options.mediaType.format) { + headers.accept = headers.accept.split(/,/).map( + (format) => format.replace( + /application\/vnd(\.\w+)(\.v3)?(\.\w+)?(\+json)?$/, + `application/vnd$1$2.${options.mediaType.format}` + ) + ).join(","); + } + if (url.endsWith("/graphql")) { + if (options.mediaType.previews?.length) { + const previewsFromAcceptHeader = headers.accept.match(/[\w-]+(?=-preview)/g) || []; + headers.accept = previewsFromAcceptHeader.concat(options.mediaType.previews).map((preview) => { + const format = options.mediaType.format ? `.${options.mediaType.format}` : "+json"; + return `application/vnd.github.${preview}-preview${format}`; + }).join(","); + } + } + } + if (["GET", "HEAD"].includes(method)) { + url = addQueryParameters(url, remainingParameters); + } else { + if ("data" in remainingParameters) { + body = remainingParameters.data; + } else { + if (Object.keys(remainingParameters).length) { + body = remainingParameters; + } + } + } + if (!headers["content-type"] && typeof body !== "undefined") { + headers["content-type"] = "application/json; charset=utf-8"; + } + if (["PATCH", "PUT"].includes(method) && typeof body === "undefined") { + body = ""; + } + return Object.assign( + { method, url, headers }, + typeof body !== "undefined" ? { body } : null, + options.request ? { request: options.request } : null + ); +} + +// pkg/dist-src/endpoint-with-defaults.js +function endpointWithDefaults(defaults, route, options) { + return parse(merge(defaults, route, options)); +} + +// pkg/dist-src/with-defaults.js +function withDefaults(oldDefaults, newDefaults) { + const DEFAULTS2 = merge(oldDefaults, newDefaults); + const endpoint2 = endpointWithDefaults.bind(null, DEFAULTS2); + return Object.assign(endpoint2, { + DEFAULTS: DEFAULTS2, + defaults: withDefaults.bind(null, DEFAULTS2), + merge: merge.bind(null, DEFAULTS2), + parse + }); +} + +// pkg/dist-src/index.js +var endpoint = withDefaults(null, DEFAULTS); +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 7461: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + GraphqlResponseError: () => GraphqlResponseError, + graphql: () => graphql2, + withCustomRequest: () => withCustomRequest +}); +module.exports = __toCommonJS(dist_src_exports); +var import_request3 = __nccwpck_require__(6206); +var import_universal_user_agent = __nccwpck_require__(5030); + +// pkg/dist-src/version.js +var VERSION = "7.0.1"; + +// pkg/dist-src/with-defaults.js +var import_request2 = __nccwpck_require__(6206); + +// pkg/dist-src/graphql.js +var import_request = __nccwpck_require__(6206); + +// pkg/dist-src/error.js +function _buildMessageForResponseErrors(data) { + return `Request failed due to following response errors: +` + data.errors.map((e) => ` - ${e.message}`).join("\n"); +} +var GraphqlResponseError = class extends Error { + constructor(request2, headers, response) { + super(_buildMessageForResponseErrors(response)); + this.request = request2; + this.headers = headers; + this.response = response; + this.name = "GraphqlResponseError"; + this.errors = response.errors; + this.data = response.data; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + } +}; + +// pkg/dist-src/graphql.js +var NON_VARIABLE_OPTIONS = [ + "method", + "baseUrl", + "url", + "headers", + "request", + "query", + "mediaType" +]; +var FORBIDDEN_VARIABLE_OPTIONS = ["query", "method", "url"]; +var GHES_V3_SUFFIX_REGEX = /\/api\/v3\/?$/; +function graphql(request2, query, options) { + if (options) { + if (typeof query === "string" && "query" in options) { + return Promise.reject( + new Error(`[@octokit/graphql] "query" cannot be used as variable name`) + ); + } + for (const key in options) { + if (!FORBIDDEN_VARIABLE_OPTIONS.includes(key)) + continue; + return Promise.reject( + new Error( + `[@octokit/graphql] "${key}" cannot be used as variable name` + ) + ); + } + } + const parsedOptions = typeof query === "string" ? Object.assign({ query }, options) : query; + const requestOptions = Object.keys( + parsedOptions + ).reduce((result, key) => { + if (NON_VARIABLE_OPTIONS.includes(key)) { + result[key] = parsedOptions[key]; + return result; + } + if (!result.variables) { + result.variables = {}; + } + result.variables[key] = parsedOptions[key]; + return result; + }, {}); + const baseUrl = parsedOptions.baseUrl || request2.endpoint.DEFAULTS.baseUrl; + if (GHES_V3_SUFFIX_REGEX.test(baseUrl)) { + requestOptions.url = baseUrl.replace(GHES_V3_SUFFIX_REGEX, "/api/graphql"); + } + return request2(requestOptions).then((response) => { + if (response.data.errors) { + const headers = {}; + for (const key of Object.keys(response.headers)) { + headers[key] = response.headers[key]; + } + throw new GraphqlResponseError( + requestOptions, + headers, + response.data + ); + } + return response.data.data; + }); +} + +// pkg/dist-src/with-defaults.js +function withDefaults(request2, newDefaults) { + const newRequest = request2.defaults(newDefaults); + const newApi = (query, options) => { + return graphql(newRequest, query, options); + }; + return Object.assign(newApi, { + defaults: withDefaults.bind(null, newRequest), + endpoint: newRequest.endpoint + }); +} + +// pkg/dist-src/index.js +var graphql2 = withDefaults(import_request3.request, { + headers: { + "user-agent": `octokit-graphql.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}` + }, + method: "POST", + url: "/graphql" +}); +function withCustomRequest(customRequest) { + return withDefaults(customRequest, { + method: "POST", + url: "/graphql" + }); +} +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 606: +/***/ ((module) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + composePaginateRest: () => composePaginateRest, + isPaginatingEndpoint: () => isPaginatingEndpoint, + paginateRest: () => paginateRest, + paginatingEndpoints: () => paginatingEndpoints +}); +module.exports = __toCommonJS(dist_src_exports); + +// pkg/dist-src/version.js +var VERSION = "9.2.1"; + +// pkg/dist-src/normalize-paginated-list-response.js +function normalizePaginatedListResponse(response) { + if (!response.data) { + return { + ...response, + data: [] + }; + } + const responseNeedsNormalization = "total_count" in response.data && !("url" in response.data); + if (!responseNeedsNormalization) + return response; + const incompleteResults = response.data.incomplete_results; + const repositorySelection = response.data.repository_selection; + const totalCount = response.data.total_count; + delete response.data.incomplete_results; + delete response.data.repository_selection; + delete response.data.total_count; + const namespaceKey = Object.keys(response.data)[0]; + const data = response.data[namespaceKey]; + response.data = data; + if (typeof incompleteResults !== "undefined") { + response.data.incomplete_results = incompleteResults; + } + if (typeof repositorySelection !== "undefined") { + response.data.repository_selection = repositorySelection; + } + response.data.total_count = totalCount; + return response; +} + +// pkg/dist-src/iterator.js +function iterator(octokit, route, parameters) { + const options = typeof route === "function" ? route.endpoint(parameters) : octokit.request.endpoint(route, parameters); + const requestMethod = typeof route === "function" ? route : octokit.request; + const method = options.method; + const headers = options.headers; + let url = options.url; + return { + [Symbol.asyncIterator]: () => ({ + async next() { + if (!url) + return { done: true }; + try { + const response = await requestMethod({ method, url, headers }); + const normalizedResponse = normalizePaginatedListResponse(response); + url = ((normalizedResponse.headers.link || "").match( + /<([^>]+)>;\s*rel="next"/ + ) || [])[1]; + return { value: normalizedResponse }; + } catch (error) { + if (error.status !== 409) + throw error; + url = ""; + return { + value: { + status: 200, + headers: {}, + data: [] + } + }; + } + } + }) + }; +} + +// pkg/dist-src/paginate.js +function paginate(octokit, route, parameters, mapFn) { + if (typeof parameters === "function") { + mapFn = parameters; + parameters = void 0; + } + return gather( + octokit, + [], + iterator(octokit, route, parameters)[Symbol.asyncIterator](), + mapFn + ); +} +function gather(octokit, results, iterator2, mapFn) { + return iterator2.next().then((result) => { + if (result.done) { + return results; + } + let earlyExit = false; + function done() { + earlyExit = true; + } + results = results.concat( + mapFn ? mapFn(result.value, done) : result.value.data + ); + if (earlyExit) { + return results; + } + return gather(octokit, results, iterator2, mapFn); + }); +} + +// pkg/dist-src/compose-paginate.js +var composePaginateRest = Object.assign(paginate, { + iterator +}); + +// pkg/dist-src/generated/paginating-endpoints.js +var paginatingEndpoints = [ + "GET /advisories", + "GET /app/hook/deliveries", + "GET /app/installation-requests", + "GET /app/installations", + "GET /assignments/{assignment_id}/accepted_assignments", + "GET /classrooms", + "GET /classrooms/{classroom_id}/assignments", + "GET /enterprises/{enterprise}/dependabot/alerts", + "GET /enterprises/{enterprise}/secret-scanning/alerts", + "GET /events", + "GET /gists", + "GET /gists/public", + "GET /gists/starred", + "GET /gists/{gist_id}/comments", + "GET /gists/{gist_id}/commits", + "GET /gists/{gist_id}/forks", + "GET /installation/repositories", + "GET /issues", + "GET /licenses", + "GET /marketplace_listing/plans", + "GET /marketplace_listing/plans/{plan_id}/accounts", + "GET /marketplace_listing/stubbed/plans", + "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts", + "GET /networks/{owner}/{repo}/events", + "GET /notifications", + "GET /organizations", + "GET /orgs/{org}/actions/cache/usage-by-repository", + "GET /orgs/{org}/actions/permissions/repositories", + "GET /orgs/{org}/actions/runners", + "GET /orgs/{org}/actions/secrets", + "GET /orgs/{org}/actions/secrets/{secret_name}/repositories", + "GET /orgs/{org}/actions/variables", + "GET /orgs/{org}/actions/variables/{name}/repositories", + "GET /orgs/{org}/blocks", + "GET /orgs/{org}/code-scanning/alerts", + "GET /orgs/{org}/codespaces", + "GET /orgs/{org}/codespaces/secrets", + "GET /orgs/{org}/codespaces/secrets/{secret_name}/repositories", + "GET /orgs/{org}/copilot/billing/seats", + "GET /orgs/{org}/dependabot/alerts", + "GET /orgs/{org}/dependabot/secrets", + "GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories", + "GET /orgs/{org}/events", + "GET /orgs/{org}/failed_invitations", + "GET /orgs/{org}/hooks", + "GET /orgs/{org}/hooks/{hook_id}/deliveries", + "GET /orgs/{org}/installations", + "GET /orgs/{org}/invitations", + "GET /orgs/{org}/invitations/{invitation_id}/teams", + "GET /orgs/{org}/issues", + "GET /orgs/{org}/members", + "GET /orgs/{org}/members/{username}/codespaces", + "GET /orgs/{org}/migrations", + "GET /orgs/{org}/migrations/{migration_id}/repositories", + "GET /orgs/{org}/organization-roles/{role_id}/teams", + "GET /orgs/{org}/organization-roles/{role_id}/users", + "GET /orgs/{org}/outside_collaborators", + "GET /orgs/{org}/packages", + "GET /orgs/{org}/packages/{package_type}/{package_name}/versions", + "GET /orgs/{org}/personal-access-token-requests", + "GET /orgs/{org}/personal-access-token-requests/{pat_request_id}/repositories", + "GET /orgs/{org}/personal-access-tokens", + "GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories", + "GET /orgs/{org}/projects", + "GET /orgs/{org}/properties/values", + "GET /orgs/{org}/public_members", + "GET /orgs/{org}/repos", + "GET /orgs/{org}/rulesets", + "GET /orgs/{org}/rulesets/rule-suites", + "GET /orgs/{org}/secret-scanning/alerts", + "GET /orgs/{org}/security-advisories", + "GET /orgs/{org}/teams", + "GET /orgs/{org}/teams/{team_slug}/discussions", + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments", + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions", + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions", + "GET /orgs/{org}/teams/{team_slug}/invitations", + "GET /orgs/{org}/teams/{team_slug}/members", + "GET /orgs/{org}/teams/{team_slug}/projects", + "GET /orgs/{org}/teams/{team_slug}/repos", + "GET /orgs/{org}/teams/{team_slug}/teams", + "GET /projects/columns/{column_id}/cards", + "GET /projects/{project_id}/collaborators", + "GET /projects/{project_id}/columns", + "GET /repos/{owner}/{repo}/actions/artifacts", + "GET /repos/{owner}/{repo}/actions/caches", + "GET /repos/{owner}/{repo}/actions/organization-secrets", + "GET /repos/{owner}/{repo}/actions/organization-variables", + "GET /repos/{owner}/{repo}/actions/runners", + "GET /repos/{owner}/{repo}/actions/runs", + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts", + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs", + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs", + "GET /repos/{owner}/{repo}/actions/secrets", + "GET /repos/{owner}/{repo}/actions/variables", + "GET /repos/{owner}/{repo}/actions/workflows", + "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs", + "GET /repos/{owner}/{repo}/activity", + "GET /repos/{owner}/{repo}/assignees", + "GET /repos/{owner}/{repo}/branches", + "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations", + "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs", + "GET /repos/{owner}/{repo}/code-scanning/alerts", + "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", + "GET /repos/{owner}/{repo}/code-scanning/analyses", + "GET /repos/{owner}/{repo}/codespaces", + "GET /repos/{owner}/{repo}/codespaces/devcontainers", + "GET /repos/{owner}/{repo}/codespaces/secrets", + "GET /repos/{owner}/{repo}/collaborators", + "GET /repos/{owner}/{repo}/comments", + "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions", + "GET /repos/{owner}/{repo}/commits", + "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments", + "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls", + "GET /repos/{owner}/{repo}/commits/{ref}/check-runs", + "GET /repos/{owner}/{repo}/commits/{ref}/check-suites", + "GET /repos/{owner}/{repo}/commits/{ref}/status", + "GET /repos/{owner}/{repo}/commits/{ref}/statuses", + "GET /repos/{owner}/{repo}/contributors", + "GET /repos/{owner}/{repo}/dependabot/alerts", + "GET /repos/{owner}/{repo}/dependabot/secrets", + "GET /repos/{owner}/{repo}/deployments", + "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses", + "GET /repos/{owner}/{repo}/environments", + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies", + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/apps", + "GET /repos/{owner}/{repo}/events", + "GET /repos/{owner}/{repo}/forks", + "GET /repos/{owner}/{repo}/hooks", + "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries", + "GET /repos/{owner}/{repo}/invitations", + "GET /repos/{owner}/{repo}/issues", + "GET /repos/{owner}/{repo}/issues/comments", + "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions", + "GET /repos/{owner}/{repo}/issues/events", + "GET /repos/{owner}/{repo}/issues/{issue_number}/comments", + "GET /repos/{owner}/{repo}/issues/{issue_number}/events", + "GET /repos/{owner}/{repo}/issues/{issue_number}/labels", + "GET /repos/{owner}/{repo}/issues/{issue_number}/reactions", + "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline", + "GET /repos/{owner}/{repo}/keys", + "GET /repos/{owner}/{repo}/labels", + "GET /repos/{owner}/{repo}/milestones", + "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels", + "GET /repos/{owner}/{repo}/notifications", + "GET /repos/{owner}/{repo}/pages/builds", + "GET /repos/{owner}/{repo}/projects", + "GET /repos/{owner}/{repo}/pulls", + "GET /repos/{owner}/{repo}/pulls/comments", + "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions", + "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments", + "GET /repos/{owner}/{repo}/pulls/{pull_number}/commits", + "GET /repos/{owner}/{repo}/pulls/{pull_number}/files", + "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews", + "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments", + "GET /repos/{owner}/{repo}/releases", + "GET /repos/{owner}/{repo}/releases/{release_id}/assets", + "GET /repos/{owner}/{repo}/releases/{release_id}/reactions", + "GET /repos/{owner}/{repo}/rules/branches/{branch}", + "GET /repos/{owner}/{repo}/rulesets", + "GET /repos/{owner}/{repo}/rulesets/rule-suites", + "GET /repos/{owner}/{repo}/secret-scanning/alerts", + "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations", + "GET /repos/{owner}/{repo}/security-advisories", + "GET /repos/{owner}/{repo}/stargazers", + "GET /repos/{owner}/{repo}/subscribers", + "GET /repos/{owner}/{repo}/tags", + "GET /repos/{owner}/{repo}/teams", + "GET /repos/{owner}/{repo}/topics", + "GET /repositories", + "GET /repositories/{repository_id}/environments/{environment_name}/secrets", + "GET /repositories/{repository_id}/environments/{environment_name}/variables", + "GET /search/code", + "GET /search/commits", + "GET /search/issues", + "GET /search/labels", + "GET /search/repositories", + "GET /search/topics", + "GET /search/users", + "GET /teams/{team_id}/discussions", + "GET /teams/{team_id}/discussions/{discussion_number}/comments", + "GET /teams/{team_id}/discussions/{discussion_number}/comments/{comment_number}/reactions", + "GET /teams/{team_id}/discussions/{discussion_number}/reactions", + "GET /teams/{team_id}/invitations", + "GET /teams/{team_id}/members", + "GET /teams/{team_id}/projects", + "GET /teams/{team_id}/repos", + "GET /teams/{team_id}/teams", + "GET /user/blocks", + "GET /user/codespaces", + "GET /user/codespaces/secrets", + "GET /user/emails", + "GET /user/followers", + "GET /user/following", + "GET /user/gpg_keys", + "GET /user/installations", + "GET /user/installations/{installation_id}/repositories", + "GET /user/issues", + "GET /user/keys", + "GET /user/marketplace_purchases", + "GET /user/marketplace_purchases/stubbed", + "GET /user/memberships/orgs", + "GET /user/migrations", + "GET /user/migrations/{migration_id}/repositories", + "GET /user/orgs", + "GET /user/packages", + "GET /user/packages/{package_type}/{package_name}/versions", + "GET /user/public_emails", + "GET /user/repos", + "GET /user/repository_invitations", + "GET /user/social_accounts", + "GET /user/ssh_signing_keys", + "GET /user/starred", + "GET /user/subscriptions", + "GET /user/teams", + "GET /users", + "GET /users/{username}/events", + "GET /users/{username}/events/orgs/{org}", + "GET /users/{username}/events/public", + "GET /users/{username}/followers", + "GET /users/{username}/following", + "GET /users/{username}/gists", + "GET /users/{username}/gpg_keys", + "GET /users/{username}/keys", + "GET /users/{username}/orgs", + "GET /users/{username}/packages", + "GET /users/{username}/projects", + "GET /users/{username}/received_events", + "GET /users/{username}/received_events/public", + "GET /users/{username}/repos", + "GET /users/{username}/social_accounts", + "GET /users/{username}/ssh_signing_keys", + "GET /users/{username}/starred", + "GET /users/{username}/subscriptions" +]; + +// pkg/dist-src/paginating-endpoints.js +function isPaginatingEndpoint(arg) { + if (typeof arg === "string") { + return paginatingEndpoints.includes(arg); + } else { + return false; + } +} + +// pkg/dist-src/index.js +function paginateRest(octokit) { + return { + paginate: Object.assign(paginate.bind(null, octokit), { + iterator: iterator.bind(null, octokit) + }) + }; +} +paginateRest.VERSION = VERSION; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 748: +/***/ ((module) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + requestLog: () => requestLog +}); +module.exports = __toCommonJS(dist_src_exports); + +// pkg/dist-src/version.js +var VERSION = "4.0.0"; + +// pkg/dist-src/index.js +function requestLog(octokit) { + octokit.hook.wrap("request", (request, options) => { + octokit.log.debug("request", options); + const start = Date.now(); + const requestOptions = octokit.request.endpoint.parse(options); + const path = requestOptions.url.replace(options.baseUrl, ""); + return request(options).then((response) => { + octokit.log.info( + `${requestOptions.method} ${path} - ${response.status} in ${Date.now() - start}ms` + ); + return response; + }).catch((error) => { + octokit.log.info( + `${requestOptions.method} ${path} - ${error.status} in ${Date.now() - start}ms` + ); + throw error; + }); + }); +} +requestLog.VERSION = VERSION; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 4923: +/***/ ((module) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + legacyRestEndpointMethods: () => legacyRestEndpointMethods, + restEndpointMethods: () => restEndpointMethods +}); +module.exports = __toCommonJS(dist_src_exports); + +// pkg/dist-src/version.js +var VERSION = "10.4.1"; + +// pkg/dist-src/generated/endpoints.js +var Endpoints = { + actions: { + addCustomLabelsToSelfHostedRunnerForOrg: [ + "POST /orgs/{org}/actions/runners/{runner_id}/labels" + ], + addCustomLabelsToSelfHostedRunnerForRepo: [ + "POST /repos/{owner}/{repo}/actions/runners/{runner_id}/labels" + ], + addSelectedRepoToOrgSecret: [ + "PUT /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}" + ], + addSelectedRepoToOrgVariable: [ + "PUT /orgs/{org}/actions/variables/{name}/repositories/{repository_id}" + ], + approveWorkflowRun: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/approve" + ], + cancelWorkflowRun: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/cancel" + ], + createEnvironmentVariable: [ + "POST /repositories/{repository_id}/environments/{environment_name}/variables" + ], + createOrUpdateEnvironmentSecret: [ + "PUT /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}" + ], + createOrUpdateOrgSecret: ["PUT /orgs/{org}/actions/secrets/{secret_name}"], + createOrUpdateRepoSecret: [ + "PUT /repos/{owner}/{repo}/actions/secrets/{secret_name}" + ], + createOrgVariable: ["POST /orgs/{org}/actions/variables"], + createRegistrationTokenForOrg: [ + "POST /orgs/{org}/actions/runners/registration-token" + ], + createRegistrationTokenForRepo: [ + "POST /repos/{owner}/{repo}/actions/runners/registration-token" + ], + createRemoveTokenForOrg: ["POST /orgs/{org}/actions/runners/remove-token"], + createRemoveTokenForRepo: [ + "POST /repos/{owner}/{repo}/actions/runners/remove-token" + ], + createRepoVariable: ["POST /repos/{owner}/{repo}/actions/variables"], + createWorkflowDispatch: [ + "POST /repos/{owner}/{repo}/actions/workflows/{workflow_id}/dispatches" + ], + deleteActionsCacheById: [ + "DELETE /repos/{owner}/{repo}/actions/caches/{cache_id}" + ], + deleteActionsCacheByKey: [ + "DELETE /repos/{owner}/{repo}/actions/caches{?key,ref}" + ], + deleteArtifact: [ + "DELETE /repos/{owner}/{repo}/actions/artifacts/{artifact_id}" + ], + deleteEnvironmentSecret: [ + "DELETE /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}" + ], + deleteEnvironmentVariable: [ + "DELETE /repositories/{repository_id}/environments/{environment_name}/variables/{name}" + ], + deleteOrgSecret: ["DELETE /orgs/{org}/actions/secrets/{secret_name}"], + deleteOrgVariable: ["DELETE /orgs/{org}/actions/variables/{name}"], + deleteRepoSecret: [ + "DELETE /repos/{owner}/{repo}/actions/secrets/{secret_name}" + ], + deleteRepoVariable: [ + "DELETE /repos/{owner}/{repo}/actions/variables/{name}" + ], + deleteSelfHostedRunnerFromOrg: [ + "DELETE /orgs/{org}/actions/runners/{runner_id}" + ], + deleteSelfHostedRunnerFromRepo: [ + "DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}" + ], + deleteWorkflowRun: ["DELETE /repos/{owner}/{repo}/actions/runs/{run_id}"], + deleteWorkflowRunLogs: [ + "DELETE /repos/{owner}/{repo}/actions/runs/{run_id}/logs" + ], + disableSelectedRepositoryGithubActionsOrganization: [ + "DELETE /orgs/{org}/actions/permissions/repositories/{repository_id}" + ], + disableWorkflow: [ + "PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/disable" + ], + downloadArtifact: [ + "GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}/{archive_format}" + ], + downloadJobLogsForWorkflowRun: [ + "GET /repos/{owner}/{repo}/actions/jobs/{job_id}/logs" + ], + downloadWorkflowRunAttemptLogs: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/logs" + ], + downloadWorkflowRunLogs: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/logs" + ], + enableSelectedRepositoryGithubActionsOrganization: [ + "PUT /orgs/{org}/actions/permissions/repositories/{repository_id}" + ], + enableWorkflow: [ + "PUT /repos/{owner}/{repo}/actions/workflows/{workflow_id}/enable" + ], + forceCancelWorkflowRun: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/force-cancel" + ], + generateRunnerJitconfigForOrg: [ + "POST /orgs/{org}/actions/runners/generate-jitconfig" + ], + generateRunnerJitconfigForRepo: [ + "POST /repos/{owner}/{repo}/actions/runners/generate-jitconfig" + ], + getActionsCacheList: ["GET /repos/{owner}/{repo}/actions/caches"], + getActionsCacheUsage: ["GET /repos/{owner}/{repo}/actions/cache/usage"], + getActionsCacheUsageByRepoForOrg: [ + "GET /orgs/{org}/actions/cache/usage-by-repository" + ], + getActionsCacheUsageForOrg: ["GET /orgs/{org}/actions/cache/usage"], + getAllowedActionsOrganization: [ + "GET /orgs/{org}/actions/permissions/selected-actions" + ], + getAllowedActionsRepository: [ + "GET /repos/{owner}/{repo}/actions/permissions/selected-actions" + ], + getArtifact: ["GET /repos/{owner}/{repo}/actions/artifacts/{artifact_id}"], + getCustomOidcSubClaimForRepo: [ + "GET /repos/{owner}/{repo}/actions/oidc/customization/sub" + ], + getEnvironmentPublicKey: [ + "GET /repositories/{repository_id}/environments/{environment_name}/secrets/public-key" + ], + getEnvironmentSecret: [ + "GET /repositories/{repository_id}/environments/{environment_name}/secrets/{secret_name}" + ], + getEnvironmentVariable: [ + "GET /repositories/{repository_id}/environments/{environment_name}/variables/{name}" + ], + getGithubActionsDefaultWorkflowPermissionsOrganization: [ + "GET /orgs/{org}/actions/permissions/workflow" + ], + getGithubActionsDefaultWorkflowPermissionsRepository: [ + "GET /repos/{owner}/{repo}/actions/permissions/workflow" + ], + getGithubActionsPermissionsOrganization: [ + "GET /orgs/{org}/actions/permissions" + ], + getGithubActionsPermissionsRepository: [ + "GET /repos/{owner}/{repo}/actions/permissions" + ], + getJobForWorkflowRun: ["GET /repos/{owner}/{repo}/actions/jobs/{job_id}"], + getOrgPublicKey: ["GET /orgs/{org}/actions/secrets/public-key"], + getOrgSecret: ["GET /orgs/{org}/actions/secrets/{secret_name}"], + getOrgVariable: ["GET /orgs/{org}/actions/variables/{name}"], + getPendingDeploymentsForRun: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments" + ], + getRepoPermissions: [ + "GET /repos/{owner}/{repo}/actions/permissions", + {}, + { renamed: ["actions", "getGithubActionsPermissionsRepository"] } + ], + getRepoPublicKey: ["GET /repos/{owner}/{repo}/actions/secrets/public-key"], + getRepoSecret: ["GET /repos/{owner}/{repo}/actions/secrets/{secret_name}"], + getRepoVariable: ["GET /repos/{owner}/{repo}/actions/variables/{name}"], + getReviewsForRun: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/approvals" + ], + getSelfHostedRunnerForOrg: ["GET /orgs/{org}/actions/runners/{runner_id}"], + getSelfHostedRunnerForRepo: [ + "GET /repos/{owner}/{repo}/actions/runners/{runner_id}" + ], + getWorkflow: ["GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}"], + getWorkflowAccessToRepository: [ + "GET /repos/{owner}/{repo}/actions/permissions/access" + ], + getWorkflowRun: ["GET /repos/{owner}/{repo}/actions/runs/{run_id}"], + getWorkflowRunAttempt: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}" + ], + getWorkflowRunUsage: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/timing" + ], + getWorkflowUsage: [ + "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/timing" + ], + listArtifactsForRepo: ["GET /repos/{owner}/{repo}/actions/artifacts"], + listEnvironmentSecrets: [ + "GET /repositories/{repository_id}/environments/{environment_name}/secrets" + ], + listEnvironmentVariables: [ + "GET /repositories/{repository_id}/environments/{environment_name}/variables" + ], + listJobsForWorkflowRun: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/jobs" + ], + listJobsForWorkflowRunAttempt: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/attempts/{attempt_number}/jobs" + ], + listLabelsForSelfHostedRunnerForOrg: [ + "GET /orgs/{org}/actions/runners/{runner_id}/labels" + ], + listLabelsForSelfHostedRunnerForRepo: [ + "GET /repos/{owner}/{repo}/actions/runners/{runner_id}/labels" + ], + listOrgSecrets: ["GET /orgs/{org}/actions/secrets"], + listOrgVariables: ["GET /orgs/{org}/actions/variables"], + listRepoOrganizationSecrets: [ + "GET /repos/{owner}/{repo}/actions/organization-secrets" + ], + listRepoOrganizationVariables: [ + "GET /repos/{owner}/{repo}/actions/organization-variables" + ], + listRepoSecrets: ["GET /repos/{owner}/{repo}/actions/secrets"], + listRepoVariables: ["GET /repos/{owner}/{repo}/actions/variables"], + listRepoWorkflows: ["GET /repos/{owner}/{repo}/actions/workflows"], + listRunnerApplicationsForOrg: ["GET /orgs/{org}/actions/runners/downloads"], + listRunnerApplicationsForRepo: [ + "GET /repos/{owner}/{repo}/actions/runners/downloads" + ], + listSelectedReposForOrgSecret: [ + "GET /orgs/{org}/actions/secrets/{secret_name}/repositories" + ], + listSelectedReposForOrgVariable: [ + "GET /orgs/{org}/actions/variables/{name}/repositories" + ], + listSelectedRepositoriesEnabledGithubActionsOrganization: [ + "GET /orgs/{org}/actions/permissions/repositories" + ], + listSelfHostedRunnersForOrg: ["GET /orgs/{org}/actions/runners"], + listSelfHostedRunnersForRepo: ["GET /repos/{owner}/{repo}/actions/runners"], + listWorkflowRunArtifacts: [ + "GET /repos/{owner}/{repo}/actions/runs/{run_id}/artifacts" + ], + listWorkflowRuns: [ + "GET /repos/{owner}/{repo}/actions/workflows/{workflow_id}/runs" + ], + listWorkflowRunsForRepo: ["GET /repos/{owner}/{repo}/actions/runs"], + reRunJobForWorkflowRun: [ + "POST /repos/{owner}/{repo}/actions/jobs/{job_id}/rerun" + ], + reRunWorkflow: ["POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun"], + reRunWorkflowFailedJobs: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/rerun-failed-jobs" + ], + removeAllCustomLabelsFromSelfHostedRunnerForOrg: [ + "DELETE /orgs/{org}/actions/runners/{runner_id}/labels" + ], + removeAllCustomLabelsFromSelfHostedRunnerForRepo: [ + "DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels" + ], + removeCustomLabelFromSelfHostedRunnerForOrg: [ + "DELETE /orgs/{org}/actions/runners/{runner_id}/labels/{name}" + ], + removeCustomLabelFromSelfHostedRunnerForRepo: [ + "DELETE /repos/{owner}/{repo}/actions/runners/{runner_id}/labels/{name}" + ], + removeSelectedRepoFromOrgSecret: [ + "DELETE /orgs/{org}/actions/secrets/{secret_name}/repositories/{repository_id}" + ], + removeSelectedRepoFromOrgVariable: [ + "DELETE /orgs/{org}/actions/variables/{name}/repositories/{repository_id}" + ], + reviewCustomGatesForRun: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/deployment_protection_rule" + ], + reviewPendingDeploymentsForRun: [ + "POST /repos/{owner}/{repo}/actions/runs/{run_id}/pending_deployments" + ], + setAllowedActionsOrganization: [ + "PUT /orgs/{org}/actions/permissions/selected-actions" + ], + setAllowedActionsRepository: [ + "PUT /repos/{owner}/{repo}/actions/permissions/selected-actions" + ], + setCustomLabelsForSelfHostedRunnerForOrg: [ + "PUT /orgs/{org}/actions/runners/{runner_id}/labels" + ], + setCustomLabelsForSelfHostedRunnerForRepo: [ + "PUT /repos/{owner}/{repo}/actions/runners/{runner_id}/labels" + ], + setCustomOidcSubClaimForRepo: [ + "PUT /repos/{owner}/{repo}/actions/oidc/customization/sub" + ], + setGithubActionsDefaultWorkflowPermissionsOrganization: [ + "PUT /orgs/{org}/actions/permissions/workflow" + ], + setGithubActionsDefaultWorkflowPermissionsRepository: [ + "PUT /repos/{owner}/{repo}/actions/permissions/workflow" + ], + setGithubActionsPermissionsOrganization: [ + "PUT /orgs/{org}/actions/permissions" + ], + setGithubActionsPermissionsRepository: [ + "PUT /repos/{owner}/{repo}/actions/permissions" + ], + setSelectedReposForOrgSecret: [ + "PUT /orgs/{org}/actions/secrets/{secret_name}/repositories" + ], + setSelectedReposForOrgVariable: [ + "PUT /orgs/{org}/actions/variables/{name}/repositories" + ], + setSelectedRepositoriesEnabledGithubActionsOrganization: [ + "PUT /orgs/{org}/actions/permissions/repositories" + ], + setWorkflowAccessToRepository: [ + "PUT /repos/{owner}/{repo}/actions/permissions/access" + ], + updateEnvironmentVariable: [ + "PATCH /repositories/{repository_id}/environments/{environment_name}/variables/{name}" + ], + updateOrgVariable: ["PATCH /orgs/{org}/actions/variables/{name}"], + updateRepoVariable: [ + "PATCH /repos/{owner}/{repo}/actions/variables/{name}" + ] + }, + activity: { + checkRepoIsStarredByAuthenticatedUser: ["GET /user/starred/{owner}/{repo}"], + deleteRepoSubscription: ["DELETE /repos/{owner}/{repo}/subscription"], + deleteThreadSubscription: [ + "DELETE /notifications/threads/{thread_id}/subscription" + ], + getFeeds: ["GET /feeds"], + getRepoSubscription: ["GET /repos/{owner}/{repo}/subscription"], + getThread: ["GET /notifications/threads/{thread_id}"], + getThreadSubscriptionForAuthenticatedUser: [ + "GET /notifications/threads/{thread_id}/subscription" + ], + listEventsForAuthenticatedUser: ["GET /users/{username}/events"], + listNotificationsForAuthenticatedUser: ["GET /notifications"], + listOrgEventsForAuthenticatedUser: [ + "GET /users/{username}/events/orgs/{org}" + ], + listPublicEvents: ["GET /events"], + listPublicEventsForRepoNetwork: ["GET /networks/{owner}/{repo}/events"], + listPublicEventsForUser: ["GET /users/{username}/events/public"], + listPublicOrgEvents: ["GET /orgs/{org}/events"], + listReceivedEventsForUser: ["GET /users/{username}/received_events"], + listReceivedPublicEventsForUser: [ + "GET /users/{username}/received_events/public" + ], + listRepoEvents: ["GET /repos/{owner}/{repo}/events"], + listRepoNotificationsForAuthenticatedUser: [ + "GET /repos/{owner}/{repo}/notifications" + ], + listReposStarredByAuthenticatedUser: ["GET /user/starred"], + listReposStarredByUser: ["GET /users/{username}/starred"], + listReposWatchedByUser: ["GET /users/{username}/subscriptions"], + listStargazersForRepo: ["GET /repos/{owner}/{repo}/stargazers"], + listWatchedReposForAuthenticatedUser: ["GET /user/subscriptions"], + listWatchersForRepo: ["GET /repos/{owner}/{repo}/subscribers"], + markNotificationsAsRead: ["PUT /notifications"], + markRepoNotificationsAsRead: ["PUT /repos/{owner}/{repo}/notifications"], + markThreadAsDone: ["DELETE /notifications/threads/{thread_id}"], + markThreadAsRead: ["PATCH /notifications/threads/{thread_id}"], + setRepoSubscription: ["PUT /repos/{owner}/{repo}/subscription"], + setThreadSubscription: [ + "PUT /notifications/threads/{thread_id}/subscription" + ], + starRepoForAuthenticatedUser: ["PUT /user/starred/{owner}/{repo}"], + unstarRepoForAuthenticatedUser: ["DELETE /user/starred/{owner}/{repo}"] + }, + apps: { + addRepoToInstallation: [ + "PUT /user/installations/{installation_id}/repositories/{repository_id}", + {}, + { renamed: ["apps", "addRepoToInstallationForAuthenticatedUser"] } + ], + addRepoToInstallationForAuthenticatedUser: [ + "PUT /user/installations/{installation_id}/repositories/{repository_id}" + ], + checkToken: ["POST /applications/{client_id}/token"], + createFromManifest: ["POST /app-manifests/{code}/conversions"], + createInstallationAccessToken: [ + "POST /app/installations/{installation_id}/access_tokens" + ], + deleteAuthorization: ["DELETE /applications/{client_id}/grant"], + deleteInstallation: ["DELETE /app/installations/{installation_id}"], + deleteToken: ["DELETE /applications/{client_id}/token"], + getAuthenticated: ["GET /app"], + getBySlug: ["GET /apps/{app_slug}"], + getInstallation: ["GET /app/installations/{installation_id}"], + getOrgInstallation: ["GET /orgs/{org}/installation"], + getRepoInstallation: ["GET /repos/{owner}/{repo}/installation"], + getSubscriptionPlanForAccount: [ + "GET /marketplace_listing/accounts/{account_id}" + ], + getSubscriptionPlanForAccountStubbed: [ + "GET /marketplace_listing/stubbed/accounts/{account_id}" + ], + getUserInstallation: ["GET /users/{username}/installation"], + getWebhookConfigForApp: ["GET /app/hook/config"], + getWebhookDelivery: ["GET /app/hook/deliveries/{delivery_id}"], + listAccountsForPlan: ["GET /marketplace_listing/plans/{plan_id}/accounts"], + listAccountsForPlanStubbed: [ + "GET /marketplace_listing/stubbed/plans/{plan_id}/accounts" + ], + listInstallationReposForAuthenticatedUser: [ + "GET /user/installations/{installation_id}/repositories" + ], + listInstallationRequestsForAuthenticatedApp: [ + "GET /app/installation-requests" + ], + listInstallations: ["GET /app/installations"], + listInstallationsForAuthenticatedUser: ["GET /user/installations"], + listPlans: ["GET /marketplace_listing/plans"], + listPlansStubbed: ["GET /marketplace_listing/stubbed/plans"], + listReposAccessibleToInstallation: ["GET /installation/repositories"], + listSubscriptionsForAuthenticatedUser: ["GET /user/marketplace_purchases"], + listSubscriptionsForAuthenticatedUserStubbed: [ + "GET /user/marketplace_purchases/stubbed" + ], + listWebhookDeliveries: ["GET /app/hook/deliveries"], + redeliverWebhookDelivery: [ + "POST /app/hook/deliveries/{delivery_id}/attempts" + ], + removeRepoFromInstallation: [ + "DELETE /user/installations/{installation_id}/repositories/{repository_id}", + {}, + { renamed: ["apps", "removeRepoFromInstallationForAuthenticatedUser"] } + ], + removeRepoFromInstallationForAuthenticatedUser: [ + "DELETE /user/installations/{installation_id}/repositories/{repository_id}" + ], + resetToken: ["PATCH /applications/{client_id}/token"], + revokeInstallationAccessToken: ["DELETE /installation/token"], + scopeToken: ["POST /applications/{client_id}/token/scoped"], + suspendInstallation: ["PUT /app/installations/{installation_id}/suspended"], + unsuspendInstallation: [ + "DELETE /app/installations/{installation_id}/suspended" + ], + updateWebhookConfigForApp: ["PATCH /app/hook/config"] + }, + billing: { + getGithubActionsBillingOrg: ["GET /orgs/{org}/settings/billing/actions"], + getGithubActionsBillingUser: [ + "GET /users/{username}/settings/billing/actions" + ], + getGithubPackagesBillingOrg: ["GET /orgs/{org}/settings/billing/packages"], + getGithubPackagesBillingUser: [ + "GET /users/{username}/settings/billing/packages" + ], + getSharedStorageBillingOrg: [ + "GET /orgs/{org}/settings/billing/shared-storage" + ], + getSharedStorageBillingUser: [ + "GET /users/{username}/settings/billing/shared-storage" + ] + }, + checks: { + create: ["POST /repos/{owner}/{repo}/check-runs"], + createSuite: ["POST /repos/{owner}/{repo}/check-suites"], + get: ["GET /repos/{owner}/{repo}/check-runs/{check_run_id}"], + getSuite: ["GET /repos/{owner}/{repo}/check-suites/{check_suite_id}"], + listAnnotations: [ + "GET /repos/{owner}/{repo}/check-runs/{check_run_id}/annotations" + ], + listForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/check-runs"], + listForSuite: [ + "GET /repos/{owner}/{repo}/check-suites/{check_suite_id}/check-runs" + ], + listSuitesForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/check-suites"], + rerequestRun: [ + "POST /repos/{owner}/{repo}/check-runs/{check_run_id}/rerequest" + ], + rerequestSuite: [ + "POST /repos/{owner}/{repo}/check-suites/{check_suite_id}/rerequest" + ], + setSuitesPreferences: [ + "PATCH /repos/{owner}/{repo}/check-suites/preferences" + ], + update: ["PATCH /repos/{owner}/{repo}/check-runs/{check_run_id}"] + }, + codeScanning: { + deleteAnalysis: [ + "DELETE /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}{?confirm_delete}" + ], + getAlert: [ + "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}", + {}, + { renamedParameters: { alert_id: "alert_number" } } + ], + getAnalysis: [ + "GET /repos/{owner}/{repo}/code-scanning/analyses/{analysis_id}" + ], + getCodeqlDatabase: [ + "GET /repos/{owner}/{repo}/code-scanning/codeql/databases/{language}" + ], + getDefaultSetup: ["GET /repos/{owner}/{repo}/code-scanning/default-setup"], + getSarif: ["GET /repos/{owner}/{repo}/code-scanning/sarifs/{sarif_id}"], + listAlertInstances: [ + "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances" + ], + listAlertsForOrg: ["GET /orgs/{org}/code-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/code-scanning/alerts"], + listAlertsInstances: [ + "GET /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}/instances", + {}, + { renamed: ["codeScanning", "listAlertInstances"] } + ], + listCodeqlDatabases: [ + "GET /repos/{owner}/{repo}/code-scanning/codeql/databases" + ], + listRecentAnalyses: ["GET /repos/{owner}/{repo}/code-scanning/analyses"], + updateAlert: [ + "PATCH /repos/{owner}/{repo}/code-scanning/alerts/{alert_number}" + ], + updateDefaultSetup: [ + "PATCH /repos/{owner}/{repo}/code-scanning/default-setup" + ], + uploadSarif: ["POST /repos/{owner}/{repo}/code-scanning/sarifs"] + }, + codesOfConduct: { + getAllCodesOfConduct: ["GET /codes_of_conduct"], + getConductCode: ["GET /codes_of_conduct/{key}"] + }, + codespaces: { + addRepositoryForSecretForAuthenticatedUser: [ + "PUT /user/codespaces/secrets/{secret_name}/repositories/{repository_id}" + ], + addSelectedRepoToOrgSecret: [ + "PUT /orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}" + ], + checkPermissionsForDevcontainer: [ + "GET /repos/{owner}/{repo}/codespaces/permissions_check" + ], + codespaceMachinesForAuthenticatedUser: [ + "GET /user/codespaces/{codespace_name}/machines" + ], + createForAuthenticatedUser: ["POST /user/codespaces"], + createOrUpdateOrgSecret: [ + "PUT /orgs/{org}/codespaces/secrets/{secret_name}" + ], + createOrUpdateRepoSecret: [ + "PUT /repos/{owner}/{repo}/codespaces/secrets/{secret_name}" + ], + createOrUpdateSecretForAuthenticatedUser: [ + "PUT /user/codespaces/secrets/{secret_name}" + ], + createWithPrForAuthenticatedUser: [ + "POST /repos/{owner}/{repo}/pulls/{pull_number}/codespaces" + ], + createWithRepoForAuthenticatedUser: [ + "POST /repos/{owner}/{repo}/codespaces" + ], + deleteForAuthenticatedUser: ["DELETE /user/codespaces/{codespace_name}"], + deleteFromOrganization: [ + "DELETE /orgs/{org}/members/{username}/codespaces/{codespace_name}" + ], + deleteOrgSecret: ["DELETE /orgs/{org}/codespaces/secrets/{secret_name}"], + deleteRepoSecret: [ + "DELETE /repos/{owner}/{repo}/codespaces/secrets/{secret_name}" + ], + deleteSecretForAuthenticatedUser: [ + "DELETE /user/codespaces/secrets/{secret_name}" + ], + exportForAuthenticatedUser: [ + "POST /user/codespaces/{codespace_name}/exports" + ], + getCodespacesForUserInOrg: [ + "GET /orgs/{org}/members/{username}/codespaces" + ], + getExportDetailsForAuthenticatedUser: [ + "GET /user/codespaces/{codespace_name}/exports/{export_id}" + ], + getForAuthenticatedUser: ["GET /user/codespaces/{codespace_name}"], + getOrgPublicKey: ["GET /orgs/{org}/codespaces/secrets/public-key"], + getOrgSecret: ["GET /orgs/{org}/codespaces/secrets/{secret_name}"], + getPublicKeyForAuthenticatedUser: [ + "GET /user/codespaces/secrets/public-key" + ], + getRepoPublicKey: [ + "GET /repos/{owner}/{repo}/codespaces/secrets/public-key" + ], + getRepoSecret: [ + "GET /repos/{owner}/{repo}/codespaces/secrets/{secret_name}" + ], + getSecretForAuthenticatedUser: [ + "GET /user/codespaces/secrets/{secret_name}" + ], + listDevcontainersInRepositoryForAuthenticatedUser: [ + "GET /repos/{owner}/{repo}/codespaces/devcontainers" + ], + listForAuthenticatedUser: ["GET /user/codespaces"], + listInOrganization: [ + "GET /orgs/{org}/codespaces", + {}, + { renamedParameters: { org_id: "org" } } + ], + listInRepositoryForAuthenticatedUser: [ + "GET /repos/{owner}/{repo}/codespaces" + ], + listOrgSecrets: ["GET /orgs/{org}/codespaces/secrets"], + listRepoSecrets: ["GET /repos/{owner}/{repo}/codespaces/secrets"], + listRepositoriesForSecretForAuthenticatedUser: [ + "GET /user/codespaces/secrets/{secret_name}/repositories" + ], + listSecretsForAuthenticatedUser: ["GET /user/codespaces/secrets"], + listSelectedReposForOrgSecret: [ + "GET /orgs/{org}/codespaces/secrets/{secret_name}/repositories" + ], + preFlightWithRepoForAuthenticatedUser: [ + "GET /repos/{owner}/{repo}/codespaces/new" + ], + publishForAuthenticatedUser: [ + "POST /user/codespaces/{codespace_name}/publish" + ], + removeRepositoryForSecretForAuthenticatedUser: [ + "DELETE /user/codespaces/secrets/{secret_name}/repositories/{repository_id}" + ], + removeSelectedRepoFromOrgSecret: [ + "DELETE /orgs/{org}/codespaces/secrets/{secret_name}/repositories/{repository_id}" + ], + repoMachinesForAuthenticatedUser: [ + "GET /repos/{owner}/{repo}/codespaces/machines" + ], + setRepositoriesForSecretForAuthenticatedUser: [ + "PUT /user/codespaces/secrets/{secret_name}/repositories" + ], + setSelectedReposForOrgSecret: [ + "PUT /orgs/{org}/codespaces/secrets/{secret_name}/repositories" + ], + startForAuthenticatedUser: ["POST /user/codespaces/{codespace_name}/start"], + stopForAuthenticatedUser: ["POST /user/codespaces/{codespace_name}/stop"], + stopInOrganization: [ + "POST /orgs/{org}/members/{username}/codespaces/{codespace_name}/stop" + ], + updateForAuthenticatedUser: ["PATCH /user/codespaces/{codespace_name}"] + }, + copilot: { + addCopilotSeatsForTeams: [ + "POST /orgs/{org}/copilot/billing/selected_teams" + ], + addCopilotSeatsForUsers: [ + "POST /orgs/{org}/copilot/billing/selected_users" + ], + cancelCopilotSeatAssignmentForTeams: [ + "DELETE /orgs/{org}/copilot/billing/selected_teams" + ], + cancelCopilotSeatAssignmentForUsers: [ + "DELETE /orgs/{org}/copilot/billing/selected_users" + ], + getCopilotOrganizationDetails: ["GET /orgs/{org}/copilot/billing"], + getCopilotSeatDetailsForUser: [ + "GET /orgs/{org}/members/{username}/copilot" + ], + listCopilotSeats: ["GET /orgs/{org}/copilot/billing/seats"] + }, + dependabot: { + addSelectedRepoToOrgSecret: [ + "PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}" + ], + createOrUpdateOrgSecret: [ + "PUT /orgs/{org}/dependabot/secrets/{secret_name}" + ], + createOrUpdateRepoSecret: [ + "PUT /repos/{owner}/{repo}/dependabot/secrets/{secret_name}" + ], + deleteOrgSecret: ["DELETE /orgs/{org}/dependabot/secrets/{secret_name}"], + deleteRepoSecret: [ + "DELETE /repos/{owner}/{repo}/dependabot/secrets/{secret_name}" + ], + getAlert: ["GET /repos/{owner}/{repo}/dependabot/alerts/{alert_number}"], + getOrgPublicKey: ["GET /orgs/{org}/dependabot/secrets/public-key"], + getOrgSecret: ["GET /orgs/{org}/dependabot/secrets/{secret_name}"], + getRepoPublicKey: [ + "GET /repos/{owner}/{repo}/dependabot/secrets/public-key" + ], + getRepoSecret: [ + "GET /repos/{owner}/{repo}/dependabot/secrets/{secret_name}" + ], + listAlertsForEnterprise: [ + "GET /enterprises/{enterprise}/dependabot/alerts" + ], + listAlertsForOrg: ["GET /orgs/{org}/dependabot/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/dependabot/alerts"], + listOrgSecrets: ["GET /orgs/{org}/dependabot/secrets"], + listRepoSecrets: ["GET /repos/{owner}/{repo}/dependabot/secrets"], + listSelectedReposForOrgSecret: [ + "GET /orgs/{org}/dependabot/secrets/{secret_name}/repositories" + ], + removeSelectedRepoFromOrgSecret: [ + "DELETE /orgs/{org}/dependabot/secrets/{secret_name}/repositories/{repository_id}" + ], + setSelectedReposForOrgSecret: [ + "PUT /orgs/{org}/dependabot/secrets/{secret_name}/repositories" + ], + updateAlert: [ + "PATCH /repos/{owner}/{repo}/dependabot/alerts/{alert_number}" + ] + }, + dependencyGraph: { + createRepositorySnapshot: [ + "POST /repos/{owner}/{repo}/dependency-graph/snapshots" + ], + diffRange: [ + "GET /repos/{owner}/{repo}/dependency-graph/compare/{basehead}" + ], + exportSbom: ["GET /repos/{owner}/{repo}/dependency-graph/sbom"] + }, + emojis: { get: ["GET /emojis"] }, + gists: { + checkIsStarred: ["GET /gists/{gist_id}/star"], + create: ["POST /gists"], + createComment: ["POST /gists/{gist_id}/comments"], + delete: ["DELETE /gists/{gist_id}"], + deleteComment: ["DELETE /gists/{gist_id}/comments/{comment_id}"], + fork: ["POST /gists/{gist_id}/forks"], + get: ["GET /gists/{gist_id}"], + getComment: ["GET /gists/{gist_id}/comments/{comment_id}"], + getRevision: ["GET /gists/{gist_id}/{sha}"], + list: ["GET /gists"], + listComments: ["GET /gists/{gist_id}/comments"], + listCommits: ["GET /gists/{gist_id}/commits"], + listForUser: ["GET /users/{username}/gists"], + listForks: ["GET /gists/{gist_id}/forks"], + listPublic: ["GET /gists/public"], + listStarred: ["GET /gists/starred"], + star: ["PUT /gists/{gist_id}/star"], + unstar: ["DELETE /gists/{gist_id}/star"], + update: ["PATCH /gists/{gist_id}"], + updateComment: ["PATCH /gists/{gist_id}/comments/{comment_id}"] + }, + git: { + createBlob: ["POST /repos/{owner}/{repo}/git/blobs"], + createCommit: ["POST /repos/{owner}/{repo}/git/commits"], + createRef: ["POST /repos/{owner}/{repo}/git/refs"], + createTag: ["POST /repos/{owner}/{repo}/git/tags"], + createTree: ["POST /repos/{owner}/{repo}/git/trees"], + deleteRef: ["DELETE /repos/{owner}/{repo}/git/refs/{ref}"], + getBlob: ["GET /repos/{owner}/{repo}/git/blobs/{file_sha}"], + getCommit: ["GET /repos/{owner}/{repo}/git/commits/{commit_sha}"], + getRef: ["GET /repos/{owner}/{repo}/git/ref/{ref}"], + getTag: ["GET /repos/{owner}/{repo}/git/tags/{tag_sha}"], + getTree: ["GET /repos/{owner}/{repo}/git/trees/{tree_sha}"], + listMatchingRefs: ["GET /repos/{owner}/{repo}/git/matching-refs/{ref}"], + updateRef: ["PATCH /repos/{owner}/{repo}/git/refs/{ref}"] + }, + gitignore: { + getAllTemplates: ["GET /gitignore/templates"], + getTemplate: ["GET /gitignore/templates/{name}"] + }, + interactions: { + getRestrictionsForAuthenticatedUser: ["GET /user/interaction-limits"], + getRestrictionsForOrg: ["GET /orgs/{org}/interaction-limits"], + getRestrictionsForRepo: ["GET /repos/{owner}/{repo}/interaction-limits"], + getRestrictionsForYourPublicRepos: [ + "GET /user/interaction-limits", + {}, + { renamed: ["interactions", "getRestrictionsForAuthenticatedUser"] } + ], + removeRestrictionsForAuthenticatedUser: ["DELETE /user/interaction-limits"], + removeRestrictionsForOrg: ["DELETE /orgs/{org}/interaction-limits"], + removeRestrictionsForRepo: [ + "DELETE /repos/{owner}/{repo}/interaction-limits" + ], + removeRestrictionsForYourPublicRepos: [ + "DELETE /user/interaction-limits", + {}, + { renamed: ["interactions", "removeRestrictionsForAuthenticatedUser"] } + ], + setRestrictionsForAuthenticatedUser: ["PUT /user/interaction-limits"], + setRestrictionsForOrg: ["PUT /orgs/{org}/interaction-limits"], + setRestrictionsForRepo: ["PUT /repos/{owner}/{repo}/interaction-limits"], + setRestrictionsForYourPublicRepos: [ + "PUT /user/interaction-limits", + {}, + { renamed: ["interactions", "setRestrictionsForAuthenticatedUser"] } + ] + }, + issues: { + addAssignees: [ + "POST /repos/{owner}/{repo}/issues/{issue_number}/assignees" + ], + addLabels: ["POST /repos/{owner}/{repo}/issues/{issue_number}/labels"], + checkUserCanBeAssigned: ["GET /repos/{owner}/{repo}/assignees/{assignee}"], + checkUserCanBeAssignedToIssue: [ + "GET /repos/{owner}/{repo}/issues/{issue_number}/assignees/{assignee}" + ], + create: ["POST /repos/{owner}/{repo}/issues"], + createComment: [ + "POST /repos/{owner}/{repo}/issues/{issue_number}/comments" + ], + createLabel: ["POST /repos/{owner}/{repo}/labels"], + createMilestone: ["POST /repos/{owner}/{repo}/milestones"], + deleteComment: [ + "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}" + ], + deleteLabel: ["DELETE /repos/{owner}/{repo}/labels/{name}"], + deleteMilestone: [ + "DELETE /repos/{owner}/{repo}/milestones/{milestone_number}" + ], + get: ["GET /repos/{owner}/{repo}/issues/{issue_number}"], + getComment: ["GET /repos/{owner}/{repo}/issues/comments/{comment_id}"], + getEvent: ["GET /repos/{owner}/{repo}/issues/events/{event_id}"], + getLabel: ["GET /repos/{owner}/{repo}/labels/{name}"], + getMilestone: ["GET /repos/{owner}/{repo}/milestones/{milestone_number}"], + list: ["GET /issues"], + listAssignees: ["GET /repos/{owner}/{repo}/assignees"], + listComments: ["GET /repos/{owner}/{repo}/issues/{issue_number}/comments"], + listCommentsForRepo: ["GET /repos/{owner}/{repo}/issues/comments"], + listEvents: ["GET /repos/{owner}/{repo}/issues/{issue_number}/events"], + listEventsForRepo: ["GET /repos/{owner}/{repo}/issues/events"], + listEventsForTimeline: [ + "GET /repos/{owner}/{repo}/issues/{issue_number}/timeline" + ], + listForAuthenticatedUser: ["GET /user/issues"], + listForOrg: ["GET /orgs/{org}/issues"], + listForRepo: ["GET /repos/{owner}/{repo}/issues"], + listLabelsForMilestone: [ + "GET /repos/{owner}/{repo}/milestones/{milestone_number}/labels" + ], + listLabelsForRepo: ["GET /repos/{owner}/{repo}/labels"], + listLabelsOnIssue: [ + "GET /repos/{owner}/{repo}/issues/{issue_number}/labels" + ], + listMilestones: ["GET /repos/{owner}/{repo}/milestones"], + lock: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/lock"], + removeAllLabels: [ + "DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels" + ], + removeAssignees: [ + "DELETE /repos/{owner}/{repo}/issues/{issue_number}/assignees" + ], + removeLabel: [ + "DELETE /repos/{owner}/{repo}/issues/{issue_number}/labels/{name}" + ], + setLabels: ["PUT /repos/{owner}/{repo}/issues/{issue_number}/labels"], + unlock: ["DELETE /repos/{owner}/{repo}/issues/{issue_number}/lock"], + update: ["PATCH /repos/{owner}/{repo}/issues/{issue_number}"], + updateComment: ["PATCH /repos/{owner}/{repo}/issues/comments/{comment_id}"], + updateLabel: ["PATCH /repos/{owner}/{repo}/labels/{name}"], + updateMilestone: [ + "PATCH /repos/{owner}/{repo}/milestones/{milestone_number}" + ] + }, + licenses: { + get: ["GET /licenses/{license}"], + getAllCommonlyUsed: ["GET /licenses"], + getForRepo: ["GET /repos/{owner}/{repo}/license"] + }, + markdown: { + render: ["POST /markdown"], + renderRaw: [ + "POST /markdown/raw", + { headers: { "content-type": "text/plain; charset=utf-8" } } + ] + }, + meta: { + get: ["GET /meta"], + getAllVersions: ["GET /versions"], + getOctocat: ["GET /octocat"], + getZen: ["GET /zen"], + root: ["GET /"] + }, + migrations: { + cancelImport: [ + "DELETE /repos/{owner}/{repo}/import", + {}, + { + deprecated: "octokit.rest.migrations.cancelImport() is deprecated, see https://docs.github.com/rest/migrations/source-imports#cancel-an-import" + } + ], + deleteArchiveForAuthenticatedUser: [ + "DELETE /user/migrations/{migration_id}/archive" + ], + deleteArchiveForOrg: [ + "DELETE /orgs/{org}/migrations/{migration_id}/archive" + ], + downloadArchiveForOrg: [ + "GET /orgs/{org}/migrations/{migration_id}/archive" + ], + getArchiveForAuthenticatedUser: [ + "GET /user/migrations/{migration_id}/archive" + ], + getCommitAuthors: [ + "GET /repos/{owner}/{repo}/import/authors", + {}, + { + deprecated: "octokit.rest.migrations.getCommitAuthors() is deprecated, see https://docs.github.com/rest/migrations/source-imports#get-commit-authors" + } + ], + getImportStatus: [ + "GET /repos/{owner}/{repo}/import", + {}, + { + deprecated: "octokit.rest.migrations.getImportStatus() is deprecated, see https://docs.github.com/rest/migrations/source-imports#get-an-import-status" + } + ], + getLargeFiles: [ + "GET /repos/{owner}/{repo}/import/large_files", + {}, + { + deprecated: "octokit.rest.migrations.getLargeFiles() is deprecated, see https://docs.github.com/rest/migrations/source-imports#get-large-files" + } + ], + getStatusForAuthenticatedUser: ["GET /user/migrations/{migration_id}"], + getStatusForOrg: ["GET /orgs/{org}/migrations/{migration_id}"], + listForAuthenticatedUser: ["GET /user/migrations"], + listForOrg: ["GET /orgs/{org}/migrations"], + listReposForAuthenticatedUser: [ + "GET /user/migrations/{migration_id}/repositories" + ], + listReposForOrg: ["GET /orgs/{org}/migrations/{migration_id}/repositories"], + listReposForUser: [ + "GET /user/migrations/{migration_id}/repositories", + {}, + { renamed: ["migrations", "listReposForAuthenticatedUser"] } + ], + mapCommitAuthor: [ + "PATCH /repos/{owner}/{repo}/import/authors/{author_id}", + {}, + { + deprecated: "octokit.rest.migrations.mapCommitAuthor() is deprecated, see https://docs.github.com/rest/migrations/source-imports#map-a-commit-author" + } + ], + setLfsPreference: [ + "PATCH /repos/{owner}/{repo}/import/lfs", + {}, + { + deprecated: "octokit.rest.migrations.setLfsPreference() is deprecated, see https://docs.github.com/rest/migrations/source-imports#update-git-lfs-preference" + } + ], + startForAuthenticatedUser: ["POST /user/migrations"], + startForOrg: ["POST /orgs/{org}/migrations"], + startImport: [ + "PUT /repos/{owner}/{repo}/import", + {}, + { + deprecated: "octokit.rest.migrations.startImport() is deprecated, see https://docs.github.com/rest/migrations/source-imports#start-an-import" + } + ], + unlockRepoForAuthenticatedUser: [ + "DELETE /user/migrations/{migration_id}/repos/{repo_name}/lock" + ], + unlockRepoForOrg: [ + "DELETE /orgs/{org}/migrations/{migration_id}/repos/{repo_name}/lock" + ], + updateImport: [ + "PATCH /repos/{owner}/{repo}/import", + {}, + { + deprecated: "octokit.rest.migrations.updateImport() is deprecated, see https://docs.github.com/rest/migrations/source-imports#update-an-import" + } + ] + }, + oidc: { + getOidcCustomSubTemplateForOrg: [ + "GET /orgs/{org}/actions/oidc/customization/sub" + ], + updateOidcCustomSubTemplateForOrg: [ + "PUT /orgs/{org}/actions/oidc/customization/sub" + ] + }, + orgs: { + addSecurityManagerTeam: [ + "PUT /orgs/{org}/security-managers/teams/{team_slug}" + ], + assignTeamToOrgRole: [ + "PUT /orgs/{org}/organization-roles/teams/{team_slug}/{role_id}" + ], + assignUserToOrgRole: [ + "PUT /orgs/{org}/organization-roles/users/{username}/{role_id}" + ], + blockUser: ["PUT /orgs/{org}/blocks/{username}"], + cancelInvitation: ["DELETE /orgs/{org}/invitations/{invitation_id}"], + checkBlockedUser: ["GET /orgs/{org}/blocks/{username}"], + checkMembershipForUser: ["GET /orgs/{org}/members/{username}"], + checkPublicMembershipForUser: ["GET /orgs/{org}/public_members/{username}"], + convertMemberToOutsideCollaborator: [ + "PUT /orgs/{org}/outside_collaborators/{username}" + ], + createCustomOrganizationRole: ["POST /orgs/{org}/organization-roles"], + createInvitation: ["POST /orgs/{org}/invitations"], + createOrUpdateCustomProperties: ["PATCH /orgs/{org}/properties/schema"], + createOrUpdateCustomPropertiesValuesForRepos: [ + "PATCH /orgs/{org}/properties/values" + ], + createOrUpdateCustomProperty: [ + "PUT /orgs/{org}/properties/schema/{custom_property_name}" + ], + createWebhook: ["POST /orgs/{org}/hooks"], + delete: ["DELETE /orgs/{org}"], + deleteCustomOrganizationRole: [ + "DELETE /orgs/{org}/organization-roles/{role_id}" + ], + deleteWebhook: ["DELETE /orgs/{org}/hooks/{hook_id}"], + enableOrDisableSecurityProductOnAllOrgRepos: [ + "POST /orgs/{org}/{security_product}/{enablement}" + ], + get: ["GET /orgs/{org}"], + getAllCustomProperties: ["GET /orgs/{org}/properties/schema"], + getCustomProperty: [ + "GET /orgs/{org}/properties/schema/{custom_property_name}" + ], + getMembershipForAuthenticatedUser: ["GET /user/memberships/orgs/{org}"], + getMembershipForUser: ["GET /orgs/{org}/memberships/{username}"], + getOrgRole: ["GET /orgs/{org}/organization-roles/{role_id}"], + getWebhook: ["GET /orgs/{org}/hooks/{hook_id}"], + getWebhookConfigForOrg: ["GET /orgs/{org}/hooks/{hook_id}/config"], + getWebhookDelivery: [ + "GET /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}" + ], + list: ["GET /organizations"], + listAppInstallations: ["GET /orgs/{org}/installations"], + listBlockedUsers: ["GET /orgs/{org}/blocks"], + listCustomPropertiesValuesForRepos: ["GET /orgs/{org}/properties/values"], + listFailedInvitations: ["GET /orgs/{org}/failed_invitations"], + listForAuthenticatedUser: ["GET /user/orgs"], + listForUser: ["GET /users/{username}/orgs"], + listInvitationTeams: ["GET /orgs/{org}/invitations/{invitation_id}/teams"], + listMembers: ["GET /orgs/{org}/members"], + listMembershipsForAuthenticatedUser: ["GET /user/memberships/orgs"], + listOrgRoleTeams: ["GET /orgs/{org}/organization-roles/{role_id}/teams"], + listOrgRoleUsers: ["GET /orgs/{org}/organization-roles/{role_id}/users"], + listOrgRoles: ["GET /orgs/{org}/organization-roles"], + listOrganizationFineGrainedPermissions: [ + "GET /orgs/{org}/organization-fine-grained-permissions" + ], + listOutsideCollaborators: ["GET /orgs/{org}/outside_collaborators"], + listPatGrantRepositories: [ + "GET /orgs/{org}/personal-access-tokens/{pat_id}/repositories" + ], + listPatGrantRequestRepositories: [ + "GET /orgs/{org}/personal-access-token-requests/{pat_request_id}/repositories" + ], + listPatGrantRequests: ["GET /orgs/{org}/personal-access-token-requests"], + listPatGrants: ["GET /orgs/{org}/personal-access-tokens"], + listPendingInvitations: ["GET /orgs/{org}/invitations"], + listPublicMembers: ["GET /orgs/{org}/public_members"], + listSecurityManagerTeams: ["GET /orgs/{org}/security-managers"], + listWebhookDeliveries: ["GET /orgs/{org}/hooks/{hook_id}/deliveries"], + listWebhooks: ["GET /orgs/{org}/hooks"], + patchCustomOrganizationRole: [ + "PATCH /orgs/{org}/organization-roles/{role_id}" + ], + pingWebhook: ["POST /orgs/{org}/hooks/{hook_id}/pings"], + redeliverWebhookDelivery: [ + "POST /orgs/{org}/hooks/{hook_id}/deliveries/{delivery_id}/attempts" + ], + removeCustomProperty: [ + "DELETE /orgs/{org}/properties/schema/{custom_property_name}" + ], + removeMember: ["DELETE /orgs/{org}/members/{username}"], + removeMembershipForUser: ["DELETE /orgs/{org}/memberships/{username}"], + removeOutsideCollaborator: [ + "DELETE /orgs/{org}/outside_collaborators/{username}" + ], + removePublicMembershipForAuthenticatedUser: [ + "DELETE /orgs/{org}/public_members/{username}" + ], + removeSecurityManagerTeam: [ + "DELETE /orgs/{org}/security-managers/teams/{team_slug}" + ], + reviewPatGrantRequest: [ + "POST /orgs/{org}/personal-access-token-requests/{pat_request_id}" + ], + reviewPatGrantRequestsInBulk: [ + "POST /orgs/{org}/personal-access-token-requests" + ], + revokeAllOrgRolesTeam: [ + "DELETE /orgs/{org}/organization-roles/teams/{team_slug}" + ], + revokeAllOrgRolesUser: [ + "DELETE /orgs/{org}/organization-roles/users/{username}" + ], + revokeOrgRoleTeam: [ + "DELETE /orgs/{org}/organization-roles/teams/{team_slug}/{role_id}" + ], + revokeOrgRoleUser: [ + "DELETE /orgs/{org}/organization-roles/users/{username}/{role_id}" + ], + setMembershipForUser: ["PUT /orgs/{org}/memberships/{username}"], + setPublicMembershipForAuthenticatedUser: [ + "PUT /orgs/{org}/public_members/{username}" + ], + unblockUser: ["DELETE /orgs/{org}/blocks/{username}"], + update: ["PATCH /orgs/{org}"], + updateMembershipForAuthenticatedUser: [ + "PATCH /user/memberships/orgs/{org}" + ], + updatePatAccess: ["POST /orgs/{org}/personal-access-tokens/{pat_id}"], + updatePatAccesses: ["POST /orgs/{org}/personal-access-tokens"], + updateWebhook: ["PATCH /orgs/{org}/hooks/{hook_id}"], + updateWebhookConfigForOrg: ["PATCH /orgs/{org}/hooks/{hook_id}/config"] + }, + packages: { + deletePackageForAuthenticatedUser: [ + "DELETE /user/packages/{package_type}/{package_name}" + ], + deletePackageForOrg: [ + "DELETE /orgs/{org}/packages/{package_type}/{package_name}" + ], + deletePackageForUser: [ + "DELETE /users/{username}/packages/{package_type}/{package_name}" + ], + deletePackageVersionForAuthenticatedUser: [ + "DELETE /user/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + deletePackageVersionForOrg: [ + "DELETE /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + deletePackageVersionForUser: [ + "DELETE /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + getAllPackageVersionsForAPackageOwnedByAnOrg: [ + "GET /orgs/{org}/packages/{package_type}/{package_name}/versions", + {}, + { renamed: ["packages", "getAllPackageVersionsForPackageOwnedByOrg"] } + ], + getAllPackageVersionsForAPackageOwnedByTheAuthenticatedUser: [ + "GET /user/packages/{package_type}/{package_name}/versions", + {}, + { + renamed: [ + "packages", + "getAllPackageVersionsForPackageOwnedByAuthenticatedUser" + ] + } + ], + getAllPackageVersionsForPackageOwnedByAuthenticatedUser: [ + "GET /user/packages/{package_type}/{package_name}/versions" + ], + getAllPackageVersionsForPackageOwnedByOrg: [ + "GET /orgs/{org}/packages/{package_type}/{package_name}/versions" + ], + getAllPackageVersionsForPackageOwnedByUser: [ + "GET /users/{username}/packages/{package_type}/{package_name}/versions" + ], + getPackageForAuthenticatedUser: [ + "GET /user/packages/{package_type}/{package_name}" + ], + getPackageForOrganization: [ + "GET /orgs/{org}/packages/{package_type}/{package_name}" + ], + getPackageForUser: [ + "GET /users/{username}/packages/{package_type}/{package_name}" + ], + getPackageVersionForAuthenticatedUser: [ + "GET /user/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + getPackageVersionForOrganization: [ + "GET /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + getPackageVersionForUser: [ + "GET /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}" + ], + listDockerMigrationConflictingPackagesForAuthenticatedUser: [ + "GET /user/docker/conflicts" + ], + listDockerMigrationConflictingPackagesForOrganization: [ + "GET /orgs/{org}/docker/conflicts" + ], + listDockerMigrationConflictingPackagesForUser: [ + "GET /users/{username}/docker/conflicts" + ], + listPackagesForAuthenticatedUser: ["GET /user/packages"], + listPackagesForOrganization: ["GET /orgs/{org}/packages"], + listPackagesForUser: ["GET /users/{username}/packages"], + restorePackageForAuthenticatedUser: [ + "POST /user/packages/{package_type}/{package_name}/restore{?token}" + ], + restorePackageForOrg: [ + "POST /orgs/{org}/packages/{package_type}/{package_name}/restore{?token}" + ], + restorePackageForUser: [ + "POST /users/{username}/packages/{package_type}/{package_name}/restore{?token}" + ], + restorePackageVersionForAuthenticatedUser: [ + "POST /user/packages/{package_type}/{package_name}/versions/{package_version_id}/restore" + ], + restorePackageVersionForOrg: [ + "POST /orgs/{org}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore" + ], + restorePackageVersionForUser: [ + "POST /users/{username}/packages/{package_type}/{package_name}/versions/{package_version_id}/restore" + ] + }, + projects: { + addCollaborator: ["PUT /projects/{project_id}/collaborators/{username}"], + createCard: ["POST /projects/columns/{column_id}/cards"], + createColumn: ["POST /projects/{project_id}/columns"], + createForAuthenticatedUser: ["POST /user/projects"], + createForOrg: ["POST /orgs/{org}/projects"], + createForRepo: ["POST /repos/{owner}/{repo}/projects"], + delete: ["DELETE /projects/{project_id}"], + deleteCard: ["DELETE /projects/columns/cards/{card_id}"], + deleteColumn: ["DELETE /projects/columns/{column_id}"], + get: ["GET /projects/{project_id}"], + getCard: ["GET /projects/columns/cards/{card_id}"], + getColumn: ["GET /projects/columns/{column_id}"], + getPermissionForUser: [ + "GET /projects/{project_id}/collaborators/{username}/permission" + ], + listCards: ["GET /projects/columns/{column_id}/cards"], + listCollaborators: ["GET /projects/{project_id}/collaborators"], + listColumns: ["GET /projects/{project_id}/columns"], + listForOrg: ["GET /orgs/{org}/projects"], + listForRepo: ["GET /repos/{owner}/{repo}/projects"], + listForUser: ["GET /users/{username}/projects"], + moveCard: ["POST /projects/columns/cards/{card_id}/moves"], + moveColumn: ["POST /projects/columns/{column_id}/moves"], + removeCollaborator: [ + "DELETE /projects/{project_id}/collaborators/{username}" + ], + update: ["PATCH /projects/{project_id}"], + updateCard: ["PATCH /projects/columns/cards/{card_id}"], + updateColumn: ["PATCH /projects/columns/{column_id}"] + }, + pulls: { + checkIfMerged: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/merge"], + create: ["POST /repos/{owner}/{repo}/pulls"], + createReplyForReviewComment: [ + "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments/{comment_id}/replies" + ], + createReview: ["POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews"], + createReviewComment: [ + "POST /repos/{owner}/{repo}/pulls/{pull_number}/comments" + ], + deletePendingReview: [ + "DELETE /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}" + ], + deleteReviewComment: [ + "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}" + ], + dismissReview: [ + "PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/dismissals" + ], + get: ["GET /repos/{owner}/{repo}/pulls/{pull_number}"], + getReview: [ + "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}" + ], + getReviewComment: ["GET /repos/{owner}/{repo}/pulls/comments/{comment_id}"], + list: ["GET /repos/{owner}/{repo}/pulls"], + listCommentsForReview: [ + "GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/comments" + ], + listCommits: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/commits"], + listFiles: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/files"], + listRequestedReviewers: [ + "GET /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers" + ], + listReviewComments: [ + "GET /repos/{owner}/{repo}/pulls/{pull_number}/comments" + ], + listReviewCommentsForRepo: ["GET /repos/{owner}/{repo}/pulls/comments"], + listReviews: ["GET /repos/{owner}/{repo}/pulls/{pull_number}/reviews"], + merge: ["PUT /repos/{owner}/{repo}/pulls/{pull_number}/merge"], + removeRequestedReviewers: [ + "DELETE /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers" + ], + requestReviewers: [ + "POST /repos/{owner}/{repo}/pulls/{pull_number}/requested_reviewers" + ], + submitReview: [ + "POST /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}/events" + ], + update: ["PATCH /repos/{owner}/{repo}/pulls/{pull_number}"], + updateBranch: [ + "PUT /repos/{owner}/{repo}/pulls/{pull_number}/update-branch" + ], + updateReview: [ + "PUT /repos/{owner}/{repo}/pulls/{pull_number}/reviews/{review_id}" + ], + updateReviewComment: [ + "PATCH /repos/{owner}/{repo}/pulls/comments/{comment_id}" + ] + }, + rateLimit: { get: ["GET /rate_limit"] }, + reactions: { + createForCommitComment: [ + "POST /repos/{owner}/{repo}/comments/{comment_id}/reactions" + ], + createForIssue: [ + "POST /repos/{owner}/{repo}/issues/{issue_number}/reactions" + ], + createForIssueComment: [ + "POST /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions" + ], + createForPullRequestReviewComment: [ + "POST /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions" + ], + createForRelease: [ + "POST /repos/{owner}/{repo}/releases/{release_id}/reactions" + ], + createForTeamDiscussionCommentInOrg: [ + "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions" + ], + createForTeamDiscussionInOrg: [ + "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions" + ], + deleteForCommitComment: [ + "DELETE /repos/{owner}/{repo}/comments/{comment_id}/reactions/{reaction_id}" + ], + deleteForIssue: [ + "DELETE /repos/{owner}/{repo}/issues/{issue_number}/reactions/{reaction_id}" + ], + deleteForIssueComment: [ + "DELETE /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions/{reaction_id}" + ], + deleteForPullRequestComment: [ + "DELETE /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions/{reaction_id}" + ], + deleteForRelease: [ + "DELETE /repos/{owner}/{repo}/releases/{release_id}/reactions/{reaction_id}" + ], + deleteForTeamDiscussion: [ + "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions/{reaction_id}" + ], + deleteForTeamDiscussionComment: [ + "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions/{reaction_id}" + ], + listForCommitComment: [ + "GET /repos/{owner}/{repo}/comments/{comment_id}/reactions" + ], + listForIssue: ["GET /repos/{owner}/{repo}/issues/{issue_number}/reactions"], + listForIssueComment: [ + "GET /repos/{owner}/{repo}/issues/comments/{comment_id}/reactions" + ], + listForPullRequestReviewComment: [ + "GET /repos/{owner}/{repo}/pulls/comments/{comment_id}/reactions" + ], + listForRelease: [ + "GET /repos/{owner}/{repo}/releases/{release_id}/reactions" + ], + listForTeamDiscussionCommentInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}/reactions" + ], + listForTeamDiscussionInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/reactions" + ] + }, + repos: { + acceptInvitation: [ + "PATCH /user/repository_invitations/{invitation_id}", + {}, + { renamed: ["repos", "acceptInvitationForAuthenticatedUser"] } + ], + acceptInvitationForAuthenticatedUser: [ + "PATCH /user/repository_invitations/{invitation_id}" + ], + addAppAccessRestrictions: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", + {}, + { mapToData: "apps" } + ], + addCollaborator: ["PUT /repos/{owner}/{repo}/collaborators/{username}"], + addStatusCheckContexts: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", + {}, + { mapToData: "contexts" } + ], + addTeamAccessRestrictions: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", + {}, + { mapToData: "teams" } + ], + addUserAccessRestrictions: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", + {}, + { mapToData: "users" } + ], + cancelPagesDeployment: [ + "POST /repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}/cancel" + ], + checkAutomatedSecurityFixes: [ + "GET /repos/{owner}/{repo}/automated-security-fixes" + ], + checkCollaborator: ["GET /repos/{owner}/{repo}/collaborators/{username}"], + checkVulnerabilityAlerts: [ + "GET /repos/{owner}/{repo}/vulnerability-alerts" + ], + codeownersErrors: ["GET /repos/{owner}/{repo}/codeowners/errors"], + compareCommits: ["GET /repos/{owner}/{repo}/compare/{base}...{head}"], + compareCommitsWithBasehead: [ + "GET /repos/{owner}/{repo}/compare/{basehead}" + ], + createAutolink: ["POST /repos/{owner}/{repo}/autolinks"], + createCommitComment: [ + "POST /repos/{owner}/{repo}/commits/{commit_sha}/comments" + ], + createCommitSignatureProtection: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures" + ], + createCommitStatus: ["POST /repos/{owner}/{repo}/statuses/{sha}"], + createDeployKey: ["POST /repos/{owner}/{repo}/keys"], + createDeployment: ["POST /repos/{owner}/{repo}/deployments"], + createDeploymentBranchPolicy: [ + "POST /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies" + ], + createDeploymentProtectionRule: [ + "POST /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules" + ], + createDeploymentStatus: [ + "POST /repos/{owner}/{repo}/deployments/{deployment_id}/statuses" + ], + createDispatchEvent: ["POST /repos/{owner}/{repo}/dispatches"], + createForAuthenticatedUser: ["POST /user/repos"], + createFork: ["POST /repos/{owner}/{repo}/forks"], + createInOrg: ["POST /orgs/{org}/repos"], + createOrUpdateCustomPropertiesValues: [ + "PATCH /repos/{owner}/{repo}/properties/values" + ], + createOrUpdateEnvironment: [ + "PUT /repos/{owner}/{repo}/environments/{environment_name}" + ], + createOrUpdateFileContents: ["PUT /repos/{owner}/{repo}/contents/{path}"], + createOrgRuleset: ["POST /orgs/{org}/rulesets"], + createPagesDeployment: ["POST /repos/{owner}/{repo}/pages/deployments"], + createPagesSite: ["POST /repos/{owner}/{repo}/pages"], + createRelease: ["POST /repos/{owner}/{repo}/releases"], + createRepoRuleset: ["POST /repos/{owner}/{repo}/rulesets"], + createTagProtection: ["POST /repos/{owner}/{repo}/tags/protection"], + createUsingTemplate: [ + "POST /repos/{template_owner}/{template_repo}/generate" + ], + createWebhook: ["POST /repos/{owner}/{repo}/hooks"], + declineInvitation: [ + "DELETE /user/repository_invitations/{invitation_id}", + {}, + { renamed: ["repos", "declineInvitationForAuthenticatedUser"] } + ], + declineInvitationForAuthenticatedUser: [ + "DELETE /user/repository_invitations/{invitation_id}" + ], + delete: ["DELETE /repos/{owner}/{repo}"], + deleteAccessRestrictions: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions" + ], + deleteAdminBranchProtection: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins" + ], + deleteAnEnvironment: [ + "DELETE /repos/{owner}/{repo}/environments/{environment_name}" + ], + deleteAutolink: ["DELETE /repos/{owner}/{repo}/autolinks/{autolink_id}"], + deleteBranchProtection: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection" + ], + deleteCommitComment: ["DELETE /repos/{owner}/{repo}/comments/{comment_id}"], + deleteCommitSignatureProtection: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures" + ], + deleteDeployKey: ["DELETE /repos/{owner}/{repo}/keys/{key_id}"], + deleteDeployment: [ + "DELETE /repos/{owner}/{repo}/deployments/{deployment_id}" + ], + deleteDeploymentBranchPolicy: [ + "DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}" + ], + deleteFile: ["DELETE /repos/{owner}/{repo}/contents/{path}"], + deleteInvitation: [ + "DELETE /repos/{owner}/{repo}/invitations/{invitation_id}" + ], + deleteOrgRuleset: ["DELETE /orgs/{org}/rulesets/{ruleset_id}"], + deletePagesSite: ["DELETE /repos/{owner}/{repo}/pages"], + deletePullRequestReviewProtection: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews" + ], + deleteRelease: ["DELETE /repos/{owner}/{repo}/releases/{release_id}"], + deleteReleaseAsset: [ + "DELETE /repos/{owner}/{repo}/releases/assets/{asset_id}" + ], + deleteRepoRuleset: ["DELETE /repos/{owner}/{repo}/rulesets/{ruleset_id}"], + deleteTagProtection: [ + "DELETE /repos/{owner}/{repo}/tags/protection/{tag_protection_id}" + ], + deleteWebhook: ["DELETE /repos/{owner}/{repo}/hooks/{hook_id}"], + disableAutomatedSecurityFixes: [ + "DELETE /repos/{owner}/{repo}/automated-security-fixes" + ], + disableDeploymentProtectionRule: [ + "DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}" + ], + disablePrivateVulnerabilityReporting: [ + "DELETE /repos/{owner}/{repo}/private-vulnerability-reporting" + ], + disableVulnerabilityAlerts: [ + "DELETE /repos/{owner}/{repo}/vulnerability-alerts" + ], + downloadArchive: [ + "GET /repos/{owner}/{repo}/zipball/{ref}", + {}, + { renamed: ["repos", "downloadZipballArchive"] } + ], + downloadTarballArchive: ["GET /repos/{owner}/{repo}/tarball/{ref}"], + downloadZipballArchive: ["GET /repos/{owner}/{repo}/zipball/{ref}"], + enableAutomatedSecurityFixes: [ + "PUT /repos/{owner}/{repo}/automated-security-fixes" + ], + enablePrivateVulnerabilityReporting: [ + "PUT /repos/{owner}/{repo}/private-vulnerability-reporting" + ], + enableVulnerabilityAlerts: [ + "PUT /repos/{owner}/{repo}/vulnerability-alerts" + ], + generateReleaseNotes: [ + "POST /repos/{owner}/{repo}/releases/generate-notes" + ], + get: ["GET /repos/{owner}/{repo}"], + getAccessRestrictions: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions" + ], + getAdminBranchProtection: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins" + ], + getAllDeploymentProtectionRules: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules" + ], + getAllEnvironments: ["GET /repos/{owner}/{repo}/environments"], + getAllStatusCheckContexts: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts" + ], + getAllTopics: ["GET /repos/{owner}/{repo}/topics"], + getAppsWithAccessToProtectedBranch: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps" + ], + getAutolink: ["GET /repos/{owner}/{repo}/autolinks/{autolink_id}"], + getBranch: ["GET /repos/{owner}/{repo}/branches/{branch}"], + getBranchProtection: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection" + ], + getBranchRules: ["GET /repos/{owner}/{repo}/rules/branches/{branch}"], + getClones: ["GET /repos/{owner}/{repo}/traffic/clones"], + getCodeFrequencyStats: ["GET /repos/{owner}/{repo}/stats/code_frequency"], + getCollaboratorPermissionLevel: [ + "GET /repos/{owner}/{repo}/collaborators/{username}/permission" + ], + getCombinedStatusForRef: ["GET /repos/{owner}/{repo}/commits/{ref}/status"], + getCommit: ["GET /repos/{owner}/{repo}/commits/{ref}"], + getCommitActivityStats: ["GET /repos/{owner}/{repo}/stats/commit_activity"], + getCommitComment: ["GET /repos/{owner}/{repo}/comments/{comment_id}"], + getCommitSignatureProtection: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_signatures" + ], + getCommunityProfileMetrics: ["GET /repos/{owner}/{repo}/community/profile"], + getContent: ["GET /repos/{owner}/{repo}/contents/{path}"], + getContributorsStats: ["GET /repos/{owner}/{repo}/stats/contributors"], + getCustomDeploymentProtectionRule: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/{protection_rule_id}" + ], + getCustomPropertiesValues: ["GET /repos/{owner}/{repo}/properties/values"], + getDeployKey: ["GET /repos/{owner}/{repo}/keys/{key_id}"], + getDeployment: ["GET /repos/{owner}/{repo}/deployments/{deployment_id}"], + getDeploymentBranchPolicy: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}" + ], + getDeploymentStatus: [ + "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses/{status_id}" + ], + getEnvironment: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}" + ], + getLatestPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/latest"], + getLatestRelease: ["GET /repos/{owner}/{repo}/releases/latest"], + getOrgRuleSuite: ["GET /orgs/{org}/rulesets/rule-suites/{rule_suite_id}"], + getOrgRuleSuites: ["GET /orgs/{org}/rulesets/rule-suites"], + getOrgRuleset: ["GET /orgs/{org}/rulesets/{ruleset_id}"], + getOrgRulesets: ["GET /orgs/{org}/rulesets"], + getPages: ["GET /repos/{owner}/{repo}/pages"], + getPagesBuild: ["GET /repos/{owner}/{repo}/pages/builds/{build_id}"], + getPagesDeployment: [ + "GET /repos/{owner}/{repo}/pages/deployments/{pages_deployment_id}" + ], + getPagesHealthCheck: ["GET /repos/{owner}/{repo}/pages/health"], + getParticipationStats: ["GET /repos/{owner}/{repo}/stats/participation"], + getPullRequestReviewProtection: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews" + ], + getPunchCardStats: ["GET /repos/{owner}/{repo}/stats/punch_card"], + getReadme: ["GET /repos/{owner}/{repo}/readme"], + getReadmeInDirectory: ["GET /repos/{owner}/{repo}/readme/{dir}"], + getRelease: ["GET /repos/{owner}/{repo}/releases/{release_id}"], + getReleaseAsset: ["GET /repos/{owner}/{repo}/releases/assets/{asset_id}"], + getReleaseByTag: ["GET /repos/{owner}/{repo}/releases/tags/{tag}"], + getRepoRuleSuite: [ + "GET /repos/{owner}/{repo}/rulesets/rule-suites/{rule_suite_id}" + ], + getRepoRuleSuites: ["GET /repos/{owner}/{repo}/rulesets/rule-suites"], + getRepoRuleset: ["GET /repos/{owner}/{repo}/rulesets/{ruleset_id}"], + getRepoRulesets: ["GET /repos/{owner}/{repo}/rulesets"], + getStatusChecksProtection: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks" + ], + getTeamsWithAccessToProtectedBranch: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams" + ], + getTopPaths: ["GET /repos/{owner}/{repo}/traffic/popular/paths"], + getTopReferrers: ["GET /repos/{owner}/{repo}/traffic/popular/referrers"], + getUsersWithAccessToProtectedBranch: [ + "GET /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users" + ], + getViews: ["GET /repos/{owner}/{repo}/traffic/views"], + getWebhook: ["GET /repos/{owner}/{repo}/hooks/{hook_id}"], + getWebhookConfigForRepo: [ + "GET /repos/{owner}/{repo}/hooks/{hook_id}/config" + ], + getWebhookDelivery: [ + "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}" + ], + listActivities: ["GET /repos/{owner}/{repo}/activity"], + listAutolinks: ["GET /repos/{owner}/{repo}/autolinks"], + listBranches: ["GET /repos/{owner}/{repo}/branches"], + listBranchesForHeadCommit: [ + "GET /repos/{owner}/{repo}/commits/{commit_sha}/branches-where-head" + ], + listCollaborators: ["GET /repos/{owner}/{repo}/collaborators"], + listCommentsForCommit: [ + "GET /repos/{owner}/{repo}/commits/{commit_sha}/comments" + ], + listCommitCommentsForRepo: ["GET /repos/{owner}/{repo}/comments"], + listCommitStatusesForRef: [ + "GET /repos/{owner}/{repo}/commits/{ref}/statuses" + ], + listCommits: ["GET /repos/{owner}/{repo}/commits"], + listContributors: ["GET /repos/{owner}/{repo}/contributors"], + listCustomDeploymentRuleIntegrations: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment_protection_rules/apps" + ], + listDeployKeys: ["GET /repos/{owner}/{repo}/keys"], + listDeploymentBranchPolicies: [ + "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies" + ], + listDeploymentStatuses: [ + "GET /repos/{owner}/{repo}/deployments/{deployment_id}/statuses" + ], + listDeployments: ["GET /repos/{owner}/{repo}/deployments"], + listForAuthenticatedUser: ["GET /user/repos"], + listForOrg: ["GET /orgs/{org}/repos"], + listForUser: ["GET /users/{username}/repos"], + listForks: ["GET /repos/{owner}/{repo}/forks"], + listInvitations: ["GET /repos/{owner}/{repo}/invitations"], + listInvitationsForAuthenticatedUser: ["GET /user/repository_invitations"], + listLanguages: ["GET /repos/{owner}/{repo}/languages"], + listPagesBuilds: ["GET /repos/{owner}/{repo}/pages/builds"], + listPublic: ["GET /repositories"], + listPullRequestsAssociatedWithCommit: [ + "GET /repos/{owner}/{repo}/commits/{commit_sha}/pulls" + ], + listReleaseAssets: [ + "GET /repos/{owner}/{repo}/releases/{release_id}/assets" + ], + listReleases: ["GET /repos/{owner}/{repo}/releases"], + listTagProtection: ["GET /repos/{owner}/{repo}/tags/protection"], + listTags: ["GET /repos/{owner}/{repo}/tags"], + listTeams: ["GET /repos/{owner}/{repo}/teams"], + listWebhookDeliveries: [ + "GET /repos/{owner}/{repo}/hooks/{hook_id}/deliveries" + ], + listWebhooks: ["GET /repos/{owner}/{repo}/hooks"], + merge: ["POST /repos/{owner}/{repo}/merges"], + mergeUpstream: ["POST /repos/{owner}/{repo}/merge-upstream"], + pingWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/pings"], + redeliverWebhookDelivery: [ + "POST /repos/{owner}/{repo}/hooks/{hook_id}/deliveries/{delivery_id}/attempts" + ], + removeAppAccessRestrictions: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", + {}, + { mapToData: "apps" } + ], + removeCollaborator: [ + "DELETE /repos/{owner}/{repo}/collaborators/{username}" + ], + removeStatusCheckContexts: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", + {}, + { mapToData: "contexts" } + ], + removeStatusCheckProtection: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks" + ], + removeTeamAccessRestrictions: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", + {}, + { mapToData: "teams" } + ], + removeUserAccessRestrictions: [ + "DELETE /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", + {}, + { mapToData: "users" } + ], + renameBranch: ["POST /repos/{owner}/{repo}/branches/{branch}/rename"], + replaceAllTopics: ["PUT /repos/{owner}/{repo}/topics"], + requestPagesBuild: ["POST /repos/{owner}/{repo}/pages/builds"], + setAdminBranchProtection: [ + "POST /repos/{owner}/{repo}/branches/{branch}/protection/enforce_admins" + ], + setAppAccessRestrictions: [ + "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/apps", + {}, + { mapToData: "apps" } + ], + setStatusCheckContexts: [ + "PUT /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks/contexts", + {}, + { mapToData: "contexts" } + ], + setTeamAccessRestrictions: [ + "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/teams", + {}, + { mapToData: "teams" } + ], + setUserAccessRestrictions: [ + "PUT /repos/{owner}/{repo}/branches/{branch}/protection/restrictions/users", + {}, + { mapToData: "users" } + ], + testPushWebhook: ["POST /repos/{owner}/{repo}/hooks/{hook_id}/tests"], + transfer: ["POST /repos/{owner}/{repo}/transfer"], + update: ["PATCH /repos/{owner}/{repo}"], + updateBranchProtection: [ + "PUT /repos/{owner}/{repo}/branches/{branch}/protection" + ], + updateCommitComment: ["PATCH /repos/{owner}/{repo}/comments/{comment_id}"], + updateDeploymentBranchPolicy: [ + "PUT /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}" + ], + updateInformationAboutPagesSite: ["PUT /repos/{owner}/{repo}/pages"], + updateInvitation: [ + "PATCH /repos/{owner}/{repo}/invitations/{invitation_id}" + ], + updateOrgRuleset: ["PUT /orgs/{org}/rulesets/{ruleset_id}"], + updatePullRequestReviewProtection: [ + "PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_pull_request_reviews" + ], + updateRelease: ["PATCH /repos/{owner}/{repo}/releases/{release_id}"], + updateReleaseAsset: [ + "PATCH /repos/{owner}/{repo}/releases/assets/{asset_id}" + ], + updateRepoRuleset: ["PUT /repos/{owner}/{repo}/rulesets/{ruleset_id}"], + updateStatusCheckPotection: [ + "PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks", + {}, + { renamed: ["repos", "updateStatusCheckProtection"] } + ], + updateStatusCheckProtection: [ + "PATCH /repos/{owner}/{repo}/branches/{branch}/protection/required_status_checks" + ], + updateWebhook: ["PATCH /repos/{owner}/{repo}/hooks/{hook_id}"], + updateWebhookConfigForRepo: [ + "PATCH /repos/{owner}/{repo}/hooks/{hook_id}/config" + ], + uploadReleaseAsset: [ + "POST /repos/{owner}/{repo}/releases/{release_id}/assets{?name,label}", + { baseUrl: "https://uploads.github.com" } + ] + }, + search: { + code: ["GET /search/code"], + commits: ["GET /search/commits"], + issuesAndPullRequests: ["GET /search/issues"], + labels: ["GET /search/labels"], + repos: ["GET /search/repositories"], + topics: ["GET /search/topics"], + users: ["GET /search/users"] + }, + secretScanning: { + getAlert: [ + "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}" + ], + listAlertsForEnterprise: [ + "GET /enterprises/{enterprise}/secret-scanning/alerts" + ], + listAlertsForOrg: ["GET /orgs/{org}/secret-scanning/alerts"], + listAlertsForRepo: ["GET /repos/{owner}/{repo}/secret-scanning/alerts"], + listLocationsForAlert: [ + "GET /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}/locations" + ], + updateAlert: [ + "PATCH /repos/{owner}/{repo}/secret-scanning/alerts/{alert_number}" + ] + }, + securityAdvisories: { + createFork: [ + "POST /repos/{owner}/{repo}/security-advisories/{ghsa_id}/forks" + ], + createPrivateVulnerabilityReport: [ + "POST /repos/{owner}/{repo}/security-advisories/reports" + ], + createRepositoryAdvisory: [ + "POST /repos/{owner}/{repo}/security-advisories" + ], + createRepositoryAdvisoryCveRequest: [ + "POST /repos/{owner}/{repo}/security-advisories/{ghsa_id}/cve" + ], + getGlobalAdvisory: ["GET /advisories/{ghsa_id}"], + getRepositoryAdvisory: [ + "GET /repos/{owner}/{repo}/security-advisories/{ghsa_id}" + ], + listGlobalAdvisories: ["GET /advisories"], + listOrgRepositoryAdvisories: ["GET /orgs/{org}/security-advisories"], + listRepositoryAdvisories: ["GET /repos/{owner}/{repo}/security-advisories"], + updateRepositoryAdvisory: [ + "PATCH /repos/{owner}/{repo}/security-advisories/{ghsa_id}" + ] + }, + teams: { + addOrUpdateMembershipForUserInOrg: [ + "PUT /orgs/{org}/teams/{team_slug}/memberships/{username}" + ], + addOrUpdateProjectPermissionsInOrg: [ + "PUT /orgs/{org}/teams/{team_slug}/projects/{project_id}" + ], + addOrUpdateRepoPermissionsInOrg: [ + "PUT /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" + ], + checkPermissionsForProjectInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/projects/{project_id}" + ], + checkPermissionsForRepoInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" + ], + create: ["POST /orgs/{org}/teams"], + createDiscussionCommentInOrg: [ + "POST /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments" + ], + createDiscussionInOrg: ["POST /orgs/{org}/teams/{team_slug}/discussions"], + deleteDiscussionCommentInOrg: [ + "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}" + ], + deleteDiscussionInOrg: [ + "DELETE /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}" + ], + deleteInOrg: ["DELETE /orgs/{org}/teams/{team_slug}"], + getByName: ["GET /orgs/{org}/teams/{team_slug}"], + getDiscussionCommentInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}" + ], + getDiscussionInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}" + ], + getMembershipForUserInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/memberships/{username}" + ], + list: ["GET /orgs/{org}/teams"], + listChildInOrg: ["GET /orgs/{org}/teams/{team_slug}/teams"], + listDiscussionCommentsInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments" + ], + listDiscussionsInOrg: ["GET /orgs/{org}/teams/{team_slug}/discussions"], + listForAuthenticatedUser: ["GET /user/teams"], + listMembersInOrg: ["GET /orgs/{org}/teams/{team_slug}/members"], + listPendingInvitationsInOrg: [ + "GET /orgs/{org}/teams/{team_slug}/invitations" + ], + listProjectsInOrg: ["GET /orgs/{org}/teams/{team_slug}/projects"], + listReposInOrg: ["GET /orgs/{org}/teams/{team_slug}/repos"], + removeMembershipForUserInOrg: [ + "DELETE /orgs/{org}/teams/{team_slug}/memberships/{username}" + ], + removeProjectInOrg: [ + "DELETE /orgs/{org}/teams/{team_slug}/projects/{project_id}" + ], + removeRepoInOrg: [ + "DELETE /orgs/{org}/teams/{team_slug}/repos/{owner}/{repo}" + ], + updateDiscussionCommentInOrg: [ + "PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}/comments/{comment_number}" + ], + updateDiscussionInOrg: [ + "PATCH /orgs/{org}/teams/{team_slug}/discussions/{discussion_number}" + ], + updateInOrg: ["PATCH /orgs/{org}/teams/{team_slug}"] + }, + users: { + addEmailForAuthenticated: [ + "POST /user/emails", + {}, + { renamed: ["users", "addEmailForAuthenticatedUser"] } + ], + addEmailForAuthenticatedUser: ["POST /user/emails"], + addSocialAccountForAuthenticatedUser: ["POST /user/social_accounts"], + block: ["PUT /user/blocks/{username}"], + checkBlocked: ["GET /user/blocks/{username}"], + checkFollowingForUser: ["GET /users/{username}/following/{target_user}"], + checkPersonIsFollowedByAuthenticated: ["GET /user/following/{username}"], + createGpgKeyForAuthenticated: [ + "POST /user/gpg_keys", + {}, + { renamed: ["users", "createGpgKeyForAuthenticatedUser"] } + ], + createGpgKeyForAuthenticatedUser: ["POST /user/gpg_keys"], + createPublicSshKeyForAuthenticated: [ + "POST /user/keys", + {}, + { renamed: ["users", "createPublicSshKeyForAuthenticatedUser"] } + ], + createPublicSshKeyForAuthenticatedUser: ["POST /user/keys"], + createSshSigningKeyForAuthenticatedUser: ["POST /user/ssh_signing_keys"], + deleteEmailForAuthenticated: [ + "DELETE /user/emails", + {}, + { renamed: ["users", "deleteEmailForAuthenticatedUser"] } + ], + deleteEmailForAuthenticatedUser: ["DELETE /user/emails"], + deleteGpgKeyForAuthenticated: [ + "DELETE /user/gpg_keys/{gpg_key_id}", + {}, + { renamed: ["users", "deleteGpgKeyForAuthenticatedUser"] } + ], + deleteGpgKeyForAuthenticatedUser: ["DELETE /user/gpg_keys/{gpg_key_id}"], + deletePublicSshKeyForAuthenticated: [ + "DELETE /user/keys/{key_id}", + {}, + { renamed: ["users", "deletePublicSshKeyForAuthenticatedUser"] } + ], + deletePublicSshKeyForAuthenticatedUser: ["DELETE /user/keys/{key_id}"], + deleteSocialAccountForAuthenticatedUser: ["DELETE /user/social_accounts"], + deleteSshSigningKeyForAuthenticatedUser: [ + "DELETE /user/ssh_signing_keys/{ssh_signing_key_id}" + ], + follow: ["PUT /user/following/{username}"], + getAuthenticated: ["GET /user"], + getByUsername: ["GET /users/{username}"], + getContextForUser: ["GET /users/{username}/hovercard"], + getGpgKeyForAuthenticated: [ + "GET /user/gpg_keys/{gpg_key_id}", + {}, + { renamed: ["users", "getGpgKeyForAuthenticatedUser"] } + ], + getGpgKeyForAuthenticatedUser: ["GET /user/gpg_keys/{gpg_key_id}"], + getPublicSshKeyForAuthenticated: [ + "GET /user/keys/{key_id}", + {}, + { renamed: ["users", "getPublicSshKeyForAuthenticatedUser"] } + ], + getPublicSshKeyForAuthenticatedUser: ["GET /user/keys/{key_id}"], + getSshSigningKeyForAuthenticatedUser: [ + "GET /user/ssh_signing_keys/{ssh_signing_key_id}" + ], + list: ["GET /users"], + listBlockedByAuthenticated: [ + "GET /user/blocks", + {}, + { renamed: ["users", "listBlockedByAuthenticatedUser"] } + ], + listBlockedByAuthenticatedUser: ["GET /user/blocks"], + listEmailsForAuthenticated: [ + "GET /user/emails", + {}, + { renamed: ["users", "listEmailsForAuthenticatedUser"] } + ], + listEmailsForAuthenticatedUser: ["GET /user/emails"], + listFollowedByAuthenticated: [ + "GET /user/following", + {}, + { renamed: ["users", "listFollowedByAuthenticatedUser"] } + ], + listFollowedByAuthenticatedUser: ["GET /user/following"], + listFollowersForAuthenticatedUser: ["GET /user/followers"], + listFollowersForUser: ["GET /users/{username}/followers"], + listFollowingForUser: ["GET /users/{username}/following"], + listGpgKeysForAuthenticated: [ + "GET /user/gpg_keys", + {}, + { renamed: ["users", "listGpgKeysForAuthenticatedUser"] } + ], + listGpgKeysForAuthenticatedUser: ["GET /user/gpg_keys"], + listGpgKeysForUser: ["GET /users/{username}/gpg_keys"], + listPublicEmailsForAuthenticated: [ + "GET /user/public_emails", + {}, + { renamed: ["users", "listPublicEmailsForAuthenticatedUser"] } + ], + listPublicEmailsForAuthenticatedUser: ["GET /user/public_emails"], + listPublicKeysForUser: ["GET /users/{username}/keys"], + listPublicSshKeysForAuthenticated: [ + "GET /user/keys", + {}, + { renamed: ["users", "listPublicSshKeysForAuthenticatedUser"] } + ], + listPublicSshKeysForAuthenticatedUser: ["GET /user/keys"], + listSocialAccountsForAuthenticatedUser: ["GET /user/social_accounts"], + listSocialAccountsForUser: ["GET /users/{username}/social_accounts"], + listSshSigningKeysForAuthenticatedUser: ["GET /user/ssh_signing_keys"], + listSshSigningKeysForUser: ["GET /users/{username}/ssh_signing_keys"], + setPrimaryEmailVisibilityForAuthenticated: [ + "PATCH /user/email/visibility", + {}, + { renamed: ["users", "setPrimaryEmailVisibilityForAuthenticatedUser"] } + ], + setPrimaryEmailVisibilityForAuthenticatedUser: [ + "PATCH /user/email/visibility" + ], + unblock: ["DELETE /user/blocks/{username}"], + unfollow: ["DELETE /user/following/{username}"], + updateAuthenticated: ["PATCH /user"] + } +}; +var endpoints_default = Endpoints; + +// pkg/dist-src/endpoints-to-methods.js +var endpointMethodsMap = /* @__PURE__ */ new Map(); +for (const [scope, endpoints] of Object.entries(endpoints_default)) { + for (const [methodName, endpoint] of Object.entries(endpoints)) { + const [route, defaults, decorations] = endpoint; + const [method, url] = route.split(/ /); + const endpointDefaults = Object.assign( + { + method, + url + }, + defaults + ); + if (!endpointMethodsMap.has(scope)) { + endpointMethodsMap.set(scope, /* @__PURE__ */ new Map()); + } + endpointMethodsMap.get(scope).set(methodName, { + scope, + methodName, + endpointDefaults, + decorations + }); + } +} +var handler = { + has({ scope }, methodName) { + return endpointMethodsMap.get(scope).has(methodName); + }, + getOwnPropertyDescriptor(target, methodName) { + return { + value: this.get(target, methodName), + // ensures method is in the cache + configurable: true, + writable: true, + enumerable: true + }; + }, + defineProperty(target, methodName, descriptor) { + Object.defineProperty(target.cache, methodName, descriptor); + return true; + }, + deleteProperty(target, methodName) { + delete target.cache[methodName]; + return true; + }, + ownKeys({ scope }) { + return [...endpointMethodsMap.get(scope).keys()]; + }, + set(target, methodName, value) { + return target.cache[methodName] = value; + }, + get({ octokit, scope, cache }, methodName) { + if (cache[methodName]) { + return cache[methodName]; + } + const method = endpointMethodsMap.get(scope).get(methodName); + if (!method) { + return void 0; + } + const { endpointDefaults, decorations } = method; + if (decorations) { + cache[methodName] = decorate( + octokit, + scope, + methodName, + endpointDefaults, + decorations + ); + } else { + cache[methodName] = octokit.request.defaults(endpointDefaults); + } + return cache[methodName]; + } +}; +function endpointsToMethods(octokit) { + const newMethods = {}; + for (const scope of endpointMethodsMap.keys()) { + newMethods[scope] = new Proxy({ octokit, scope, cache: {} }, handler); + } + return newMethods; +} +function decorate(octokit, scope, methodName, defaults, decorations) { + const requestWithDefaults = octokit.request.defaults(defaults); + function withDecorations(...args) { + let options = requestWithDefaults.endpoint.merge(...args); + if (decorations.mapToData) { + options = Object.assign({}, options, { + data: options[decorations.mapToData], + [decorations.mapToData]: void 0 + }); + return requestWithDefaults(options); + } + if (decorations.renamed) { + const [newScope, newMethodName] = decorations.renamed; + octokit.log.warn( + `octokit.${scope}.${methodName}() has been renamed to octokit.${newScope}.${newMethodName}()` + ); + } + if (decorations.deprecated) { + octokit.log.warn(decorations.deprecated); + } + if (decorations.renamedParameters) { + const options2 = requestWithDefaults.endpoint.merge(...args); + for (const [name, alias] of Object.entries( + decorations.renamedParameters + )) { + if (name in options2) { + octokit.log.warn( + `"${name}" parameter is deprecated for "octokit.${scope}.${methodName}()". Use "${alias}" instead` + ); + if (!(alias in options2)) { + options2[alias] = options2[name]; + } + delete options2[name]; + } + } + return requestWithDefaults(options2); + } + return requestWithDefaults(...args); + } + return Object.assign(withDecorations, requestWithDefaults); +} + +// pkg/dist-src/index.js +function restEndpointMethods(octokit) { + const api = endpointsToMethods(octokit); + return { + rest: api + }; +} +restEndpointMethods.VERSION = VERSION; +function legacyRestEndpointMethods(octokit) { + const api = endpointsToMethods(octokit); + return { + ...api, + rest: api + }; +} +legacyRestEndpointMethods.VERSION = VERSION; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 6239: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __create = Object.create; +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __getProtoOf = Object.getPrototypeOf; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( + // If the importer is in node compatibility mode or this is not an ESM + // file that has been converted to a CommonJS file using a Babel- + // compatible transform (i.e. "__esModule" has not been set), then set + // "default" to the CommonJS "module.exports" for node compatibility. + isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, + mod +)); +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + RequestError: () => RequestError +}); +module.exports = __toCommonJS(dist_src_exports); +var import_deprecation = __nccwpck_require__(8932); +var import_once = __toESM(__nccwpck_require__(1223)); +var logOnceCode = (0, import_once.default)((deprecation) => console.warn(deprecation)); +var logOnceHeaders = (0, import_once.default)((deprecation) => console.warn(deprecation)); +var RequestError = class extends Error { + constructor(message, statusCode, options) { + super(message); + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + this.name = "HttpError"; + this.status = statusCode; + let headers; + if ("headers" in options && typeof options.headers !== "undefined") { + headers = options.headers; + } + if ("response" in options) { + this.response = options.response; + headers = options.response.headers; + } + const requestCopy = Object.assign({}, options.request); + if (options.request.headers.authorization) { + requestCopy.headers = Object.assign({}, options.request.headers, { + authorization: options.request.headers.authorization.replace( + / .*$/, + " [REDACTED]" + ) + }); + } + requestCopy.url = requestCopy.url.replace(/\bclient_secret=\w+/g, "client_secret=[REDACTED]").replace(/\baccess_token=\w+/g, "access_token=[REDACTED]"); + this.request = requestCopy; + Object.defineProperty(this, "code", { + get() { + logOnceCode( + new import_deprecation.Deprecation( + "[@octokit/request-error] `error.code` is deprecated, use `error.status`." + ) + ); + return statusCode; + } + }); + Object.defineProperty(this, "headers", { + get() { + logOnceHeaders( + new import_deprecation.Deprecation( + "[@octokit/request-error] `error.headers` is deprecated, use `error.response.headers`." + ) + ); + return headers || {}; + } + }); + } +}; +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 6206: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var __defProp = Object.defineProperty; +var __getOwnPropDesc = Object.getOwnPropertyDescriptor; +var __getOwnPropNames = Object.getOwnPropertyNames; +var __hasOwnProp = Object.prototype.hasOwnProperty; +var __export = (target, all) => { + for (var name in all) + __defProp(target, name, { get: all[name], enumerable: true }); +}; +var __copyProps = (to, from, except, desc) => { + if (from && typeof from === "object" || typeof from === "function") { + for (let key of __getOwnPropNames(from)) + if (!__hasOwnProp.call(to, key) && key !== except) + __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); + } + return to; +}; +var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); + +// pkg/dist-src/index.js +var dist_src_exports = {}; +__export(dist_src_exports, { + request: () => request +}); +module.exports = __toCommonJS(dist_src_exports); +var import_endpoint = __nccwpck_require__(6065); +var import_universal_user_agent = __nccwpck_require__(5030); + +// pkg/dist-src/version.js +var VERSION = "8.1.1"; + +// pkg/dist-src/fetch-wrapper.js +var import_is_plain_object = __nccwpck_require__(3287); +var import_request_error = __nccwpck_require__(6239); + +// pkg/dist-src/get-buffer-response.js +function getBufferResponse(response) { + return response.arrayBuffer(); +} + +// pkg/dist-src/fetch-wrapper.js +function fetchWrapper(requestOptions) { + var _a, _b, _c; + const log = requestOptions.request && requestOptions.request.log ? requestOptions.request.log : console; + const parseSuccessResponseBody = ((_a = requestOptions.request) == null ? void 0 : _a.parseSuccessResponseBody) !== false; + if ((0, import_is_plain_object.isPlainObject)(requestOptions.body) || Array.isArray(requestOptions.body)) { + requestOptions.body = JSON.stringify(requestOptions.body); + } + let headers = {}; + let status; + let url; + let { fetch } = globalThis; + if ((_b = requestOptions.request) == null ? void 0 : _b.fetch) { + fetch = requestOptions.request.fetch; + } + if (!fetch) { + throw new Error( + "fetch is not set. Please pass a fetch implementation as new Octokit({ request: { fetch }}). Learn more at https://github.com/octokit/octokit.js/#fetch-missing" + ); + } + return fetch(requestOptions.url, { + method: requestOptions.method, + body: requestOptions.body, + headers: requestOptions.headers, + signal: (_c = requestOptions.request) == null ? void 0 : _c.signal, + // duplex must be set if request.body is ReadableStream or Async Iterables. + // See https://fetch.spec.whatwg.org/#dom-requestinit-duplex. + ...requestOptions.body && { duplex: "half" } + }).then(async (response) => { + url = response.url; + status = response.status; + for (const keyAndValue of response.headers) { + headers[keyAndValue[0]] = keyAndValue[1]; + } + if ("deprecation" in headers) { + const matches = headers.link && headers.link.match(/<([^>]+)>; rel="deprecation"/); + const deprecationLink = matches && matches.pop(); + log.warn( + `[@octokit/request] "${requestOptions.method} ${requestOptions.url}" is deprecated. It is scheduled to be removed on ${headers.sunset}${deprecationLink ? `. See ${deprecationLink}` : ""}` + ); + } + if (status === 204 || status === 205) { + return; + } + if (requestOptions.method === "HEAD") { + if (status < 400) { + return; + } + throw new import_request_error.RequestError(response.statusText, status, { + response: { + url, + status, + headers, + data: void 0 + }, + request: requestOptions + }); + } + if (status === 304) { + throw new import_request_error.RequestError("Not modified", status, { + response: { + url, + status, + headers, + data: await getResponseData(response) + }, + request: requestOptions + }); + } + if (status >= 400) { + const data = await getResponseData(response); + const error = new import_request_error.RequestError(toErrorMessage(data), status, { + response: { + url, + status, + headers, + data + }, + request: requestOptions + }); + throw error; + } + return parseSuccessResponseBody ? await getResponseData(response) : response.body; + }).then((data) => { + return { + status, + url, + headers, + data + }; + }).catch((error) => { + if (error instanceof import_request_error.RequestError) + throw error; + else if (error.name === "AbortError") + throw error; + throw new import_request_error.RequestError(error.message, 500, { + request: requestOptions + }); + }); +} +async function getResponseData(response) { + const contentType = response.headers.get("content-type"); + if (/application\/json/.test(contentType)) { + return response.json(); + } + if (!contentType || /^text\/|charset=utf-8$/.test(contentType)) { + return response.text(); + } + return getBufferResponse(response); +} +function toErrorMessage(data) { + if (typeof data === "string") + return data; + if ("message" in data) { + if (Array.isArray(data.errors)) { + return `${data.message}: ${data.errors.map(JSON.stringify).join(", ")}`; + } + return data.message; + } + return `Unknown error: ${JSON.stringify(data)}`; +} + +// pkg/dist-src/with-defaults.js +function withDefaults(oldEndpoint, newDefaults) { + const endpoint2 = oldEndpoint.defaults(newDefaults); + const newApi = function(route, parameters) { + const endpointOptions = endpoint2.merge(route, parameters); + if (!endpointOptions.request || !endpointOptions.request.hook) { + return fetchWrapper(endpoint2.parse(endpointOptions)); + } + const request2 = (route2, parameters2) => { + return fetchWrapper( + endpoint2.parse(endpoint2.merge(route2, parameters2)) + ); + }; + Object.assign(request2, { + endpoint: endpoint2, + defaults: withDefaults.bind(null, endpoint2) + }); + return endpointOptions.request.hook(request2, endpointOptions); + }; + return Object.assign(newApi, { + endpoint: endpoint2, + defaults: withDefaults.bind(null, endpoint2) + }); +} + +// pkg/dist-src/index.js +var request = withDefaults(import_endpoint.endpoint, { + headers: { + "user-agent": `octokit-request.js/${VERSION} ${(0, import_universal_user_agent.getUserAgent)()}` + } +}); +// Annotate the CommonJS export names for ESM import in node: +0 && (0); + + +/***/ }), + +/***/ 3682: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var register = __nccwpck_require__(4670); +var addHook = __nccwpck_require__(5549); +var removeHook = __nccwpck_require__(6819); + +// bind with array of arguments: https://stackoverflow.com/a/21792913 +var bind = Function.bind; +var bindable = bind.bind(bind); + +function bindApi(hook, state, name) { + var removeHookRef = bindable(removeHook, null).apply( + null, + name ? [state, name] : [state] + ); + hook.api = { remove: removeHookRef }; + hook.remove = removeHookRef; + ["before", "error", "after", "wrap"].forEach(function (kind) { + var args = name ? [state, kind, name] : [state, kind]; + hook[kind] = hook.api[kind] = bindable(addHook, null).apply(null, args); + }); +} + +function HookSingular() { + var singularHookName = "h"; + var singularHookState = { + registry: {}, + }; + var singularHook = register.bind(null, singularHookState, singularHookName); + bindApi(singularHook, singularHookState, singularHookName); + return singularHook; +} + +function HookCollection() { + var state = { + registry: {}, + }; + + var hook = register.bind(null, state); + bindApi(hook, state); + + return hook; +} + +var collectionHookDeprecationMessageDisplayed = false; +function Hook() { + if (!collectionHookDeprecationMessageDisplayed) { + console.warn( + '[before-after-hook]: "Hook()" repurposing warning, use "Hook.Collection()". Read more: https://git.io/upgrade-before-after-hook-to-1.4' + ); + collectionHookDeprecationMessageDisplayed = true; + } + return HookCollection(); +} + +Hook.Singular = HookSingular.bind(); +Hook.Collection = HookCollection.bind(); + +module.exports = Hook; +// expose constructors as a named property for TypeScript +module.exports.Hook = Hook; +module.exports.Singular = Hook.Singular; +module.exports.Collection = Hook.Collection; + + +/***/ }), + +/***/ 5549: +/***/ ((module) => { + +module.exports = addHook; + +function addHook(state, kind, name, hook) { + var orig = hook; + if (!state.registry[name]) { + state.registry[name] = []; + } + + if (kind === "before") { + hook = function (method, options) { + return Promise.resolve() + .then(orig.bind(null, options)) + .then(method.bind(null, options)); + }; + } + + if (kind === "after") { + hook = function (method, options) { + var result; + return Promise.resolve() + .then(method.bind(null, options)) + .then(function (result_) { + result = result_; + return orig(result, options); + }) + .then(function () { + return result; + }); + }; + } + + if (kind === "error") { + hook = function (method, options) { + return Promise.resolve() + .then(method.bind(null, options)) + .catch(function (error) { + return orig(error, options); + }); + }; + } + + state.registry[name].push({ + hook: hook, + orig: orig, + }); +} + + +/***/ }), + +/***/ 4670: +/***/ ((module) => { + +module.exports = register; + +function register(state, name, method, options) { + if (typeof method !== "function") { + throw new Error("method for before hook must be a function"); + } + + if (!options) { + options = {}; + } + + if (Array.isArray(name)) { + return name.reverse().reduce(function (callback, name) { + return register.bind(null, state, name, callback, options); + }, method)(); + } + + return Promise.resolve().then(function () { + if (!state.registry[name]) { + return method(options); + } + + return state.registry[name].reduce(function (method, registered) { + return registered.hook.bind(null, method, options); + }, method)(); + }); +} + + +/***/ }), + +/***/ 6819: +/***/ ((module) => { + +module.exports = removeHook; + +function removeHook(state, name, method) { + if (!state.registry[name]) { + return; + } + + var index = state.registry[name] + .map(function (registered) { + return registered.orig; + }) + .indexOf(method); + + if (index === -1) { + return; + } + + state.registry[name].splice(index, 1); +} + + +/***/ }), + +/***/ 8932: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +class Deprecation extends Error { + constructor(message) { + super(message); // Maintains proper stack trace (only available on V8) + + /* istanbul ignore next */ + + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + + this.name = 'Deprecation'; + } + +} + +exports.Deprecation = Deprecation; + + +/***/ }), + +/***/ 4933: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +const fs = __nccwpck_require__(7147); +const path = __nccwpck_require__(1017); +const crypto = __nccwpck_require__(6113); +const isStream = __nccwpck_require__(1554); + +const {Worker} = (() => { + try { + return __nccwpck_require__(1267); + } catch (_) { + return {}; + } +})(); + +let worker; // Lazy +let taskIdCounter = 0; +const tasks = new Map(); + +const recreateWorkerError = sourceError => { + const error = new Error(sourceError.message); + + for (const [key, value] of Object.entries(sourceError)) { + if (key !== 'message') { + error[key] = value; + } + } + + return error; +}; + +const createWorker = () => { + worker = new Worker(__nccwpck_require__.ab + "thread.js"); + + worker.on('message', message => { + const task = tasks.get(message.id); + tasks.delete(message.id); + + if (tasks.size === 0) { + worker.unref(); + } + + if (message.error === undefined) { + task.resolve(message.value); + } else { + task.reject(recreateWorkerError(message.error)); + } + }); + + worker.on('error', error => { + // Any error here is effectively an equivalent of segfault, and have no scope, so we just throw it on callback level + throw error; + }); +}; + +const taskWorker = (method, args, transferList) => new Promise((resolve, reject) => { + const id = taskIdCounter++; + tasks.set(id, {resolve, reject}); + + if (worker === undefined) { + createWorker(); + } + + worker.ref(); + worker.postMessage({id, method, args}, transferList); +}); + +const hasha = (input, options = {}) => { + let outputEncoding = options.encoding || 'hex'; + + if (outputEncoding === 'buffer') { + outputEncoding = undefined; + } + + const hash = crypto.createHash(options.algorithm || 'sha512'); + + const update = buffer => { + const inputEncoding = typeof buffer === 'string' ? 'utf8' : undefined; + hash.update(buffer, inputEncoding); + }; + + if (Array.isArray(input)) { + input.forEach(update); + } else { + update(input); + } + + return hash.digest(outputEncoding); +}; + +hasha.stream = (options = {}) => { + let outputEncoding = options.encoding || 'hex'; + + if (outputEncoding === 'buffer') { + outputEncoding = undefined; + } + + const stream = crypto.createHash(options.algorithm || 'sha512'); + stream.setEncoding(outputEncoding); + return stream; +}; + +hasha.fromStream = async (stream, options = {}) => { + if (!isStream(stream)) { + throw new TypeError('Expected a stream'); + } + + return new Promise((resolve, reject) => { + // TODO: Use `stream.pipeline` and `stream.finished` when targeting Node.js 10 + stream + .on('error', reject) + .pipe(hasha.stream(options)) + .on('error', reject) + .on('finish', function () { + resolve(this.read()); + }); + }); +}; + +if (Worker === undefined) { + hasha.fromFile = async (filePath, options) => hasha.fromStream(fs.createReadStream(filePath), options); + hasha.async = async (input, options) => hasha(input, options); +} else { + hasha.fromFile = async (filePath, {algorithm = 'sha512', encoding = 'hex'} = {}) => { + const hash = await taskWorker('hashFile', [algorithm, filePath]); + + if (encoding === 'buffer') { + return Buffer.from(hash); + } + + return Buffer.from(hash).toString(encoding); + }; + + hasha.async = async (input, {algorithm = 'sha512', encoding = 'hex'} = {}) => { + if (encoding === 'buffer') { + encoding = undefined; + } + + const hash = await taskWorker('hash', [algorithm, input]); + + if (encoding === undefined) { + return Buffer.from(hash); + } + + return Buffer.from(hash).toString(encoding); + }; +} + +hasha.fromFileSync = (filePath, options) => hasha(fs.readFileSync(filePath), options); + +module.exports = hasha; + + +/***/ }), + +/***/ 3287: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +/*! + * is-plain-object <https://github.com/jonschlinkert/is-plain-object> + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ + +function isObject(o) { + return Object.prototype.toString.call(o) === '[object Object]'; +} + +function isPlainObject(o) { + var ctor,prot; + + if (isObject(o) === false) return false; + + // If has modified constructor + ctor = o.constructor; + if (ctor === undefined) return true; + + // If has modified prototype + prot = ctor.prototype; + if (isObject(prot) === false) return false; + + // If constructor does not have an Object-specific method + if (prot.hasOwnProperty('isPrototypeOf') === false) { + return false; + } + + // Most likely a plain Object + return true; +} + +exports.isPlainObject = isPlainObject; + + +/***/ }), + +/***/ 1554: +/***/ ((module) => { + + + +const isStream = stream => + stream !== null && + typeof stream === 'object' && + typeof stream.pipe === 'function'; + +isStream.writable = stream => + isStream(stream) && + stream.writable !== false && + typeof stream._write === 'function' && + typeof stream._writableState === 'object'; + +isStream.readable = stream => + isStream(stream) && + stream.readable !== false && + typeof stream._read === 'function' && + typeof stream._readableState === 'object'; + +isStream.duplex = stream => + isStream.writable(stream) && + isStream.readable(stream); + +isStream.transform = stream => + isStream.duplex(stream) && + typeof stream._transform === 'function'; + +module.exports = isStream; + + +/***/ }), + +/***/ 7760: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +/*! node-domexception. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ + +if (!globalThis.DOMException) { + try { + const { MessageChannel } = __nccwpck_require__(1267), + port = new MessageChannel().port1, + ab = new ArrayBuffer() + port.postMessage(ab, [ab, ab]) + } catch (err) { + err.constructor.name === 'DOMException' && ( + globalThis.DOMException = err.constructor + ) + } +} + +module.exports = globalThis.DOMException + + +/***/ }), + +/***/ 1223: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +var wrappy = __nccwpck_require__(2940) +module.exports = wrappy(once) +module.exports.strict = wrappy(onceStrict) + +once.proto = once(function () { + Object.defineProperty(Function.prototype, 'once', { + value: function () { + return once(this) + }, + configurable: true + }) + + Object.defineProperty(Function.prototype, 'onceStrict', { + value: function () { + return onceStrict(this) + }, + configurable: true + }) +}) + +function once (fn) { + var f = function () { + if (f.called) return f.value + f.called = true + return f.value = fn.apply(this, arguments) + } + f.called = false + return f +} + +function onceStrict (fn) { + var f = function () { + if (f.called) + throw new Error(f.onceError) + f.called = true + return f.value = fn.apply(this, arguments) + } + var name = fn.name || 'Function wrapped with `once`' + f.onceError = name + " shouldn't be called more than once" + f.called = false + return f +} + + +/***/ }), + +/***/ 4256: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var punycode = __nccwpck_require__(5477); +var mappingTable = __nccwpck_require__(2020); + +var PROCESSING_OPTIONS = { + TRANSITIONAL: 0, + NONTRANSITIONAL: 1 +}; + +function normalize(str) { // fix bug in v8 + return str.split('\u0000').map(function (s) { return s.normalize('NFC'); }).join('\u0000'); +} + +function findStatus(val) { + var start = 0; + var end = mappingTable.length - 1; + + while (start <= end) { + var mid = Math.floor((start + end) / 2); + + var target = mappingTable[mid]; + if (target[0][0] <= val && target[0][1] >= val) { + return target; + } else if (target[0][0] > val) { + end = mid - 1; + } else { + start = mid + 1; + } + } + + return null; +} + +var regexAstralSymbols = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + +function countSymbols(string) { + return string + // replace every surrogate pair with a BMP symbol + .replace(regexAstralSymbols, '_') + // then get the length + .length; +} + +function mapChars(domain_name, useSTD3, processing_option) { + var hasError = false; + var processed = ""; + + var len = countSymbols(domain_name); + for (var i = 0; i < len; ++i) { + var codePoint = domain_name.codePointAt(i); + var status = findStatus(codePoint); + + switch (status[1]) { + case "disallowed": + hasError = true; + processed += String.fromCodePoint(codePoint); + break; + case "ignored": + break; + case "mapped": + processed += String.fromCodePoint.apply(String, status[2]); + break; + case "deviation": + if (processing_option === PROCESSING_OPTIONS.TRANSITIONAL) { + processed += String.fromCodePoint.apply(String, status[2]); + } else { + processed += String.fromCodePoint(codePoint); + } + break; + case "valid": + processed += String.fromCodePoint(codePoint); + break; + case "disallowed_STD3_mapped": + if (useSTD3) { + hasError = true; + processed += String.fromCodePoint(codePoint); + } else { + processed += String.fromCodePoint.apply(String, status[2]); + } + break; + case "disallowed_STD3_valid": + if (useSTD3) { + hasError = true; + } + + processed += String.fromCodePoint(codePoint); + break; + } + } + + return { + string: processed, + error: hasError + }; +} + +var combiningMarksRegex = /[\u0300-\u036F\u0483-\u0489\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08E4-\u0903\u093A-\u093C\u093E-\u094F\u0951-\u0957\u0962\u0963\u0981-\u0983\u09BC\u09BE-\u09C4\u09C7\u09C8\u09CB-\u09CD\u09D7\u09E2\u09E3\u0A01-\u0A03\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A70\u0A71\u0A75\u0A81-\u0A83\u0ABC\u0ABE-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AE2\u0AE3\u0B01-\u0B03\u0B3C\u0B3E-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B62\u0B63\u0B82\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD7\u0C00-\u0C03\u0C3E-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C62\u0C63\u0C81-\u0C83\u0CBC\u0CBE-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CE2\u0CE3\u0D01-\u0D03\u0D3E-\u0D44\u0D46-\u0D48\u0D4A-\u0D4D\u0D57\u0D62\u0D63\u0D82\u0D83\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DF2\u0DF3\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB\u0EBC\u0EC8-\u0ECD\u0F18\u0F19\u0F35\u0F37\u0F39\u0F3E\u0F3F\u0F71-\u0F84\u0F86\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102B-\u103E\u1056-\u1059\u105E-\u1060\u1062-\u1064\u1067-\u106D\u1071-\u1074\u1082-\u108D\u108F\u109A-\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17B4-\u17D3\u17DD\u180B-\u180D\u18A9\u1920-\u192B\u1930-\u193B\u19B0-\u19C0\u19C8\u19C9\u1A17-\u1A1B\u1A55-\u1A5E\u1A60-\u1A7C\u1A7F\u1AB0-\u1ABE\u1B00-\u1B04\u1B34-\u1B44\u1B6B-\u1B73\u1B80-\u1B82\u1BA1-\u1BAD\u1BE6-\u1BF3\u1C24-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE8\u1CED\u1CF2-\u1CF4\u1CF8\u1CF9\u1DC0-\u1DF5\u1DFC-\u1DFF\u20D0-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302F\u3099\u309A\uA66F-\uA672\uA674-\uA67D\uA69F\uA6F0\uA6F1\uA802\uA806\uA80B\uA823-\uA827\uA880\uA881\uA8B4-\uA8C4\uA8E0-\uA8F1\uA926-\uA92D\uA947-\uA953\uA980-\uA983\uA9B3-\uA9C0\uA9E5\uAA29-\uAA36\uAA43\uAA4C\uAA4D\uAA7B-\uAA7D\uAAB0\uAAB2-\uAAB4\uAAB7\uAAB8\uAABE\uAABF\uAAC1\uAAEB-\uAAEF\uAAF5\uAAF6\uABE3-\uABEA\uABEC\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2D]|\uD800[\uDDFD\uDEE0\uDF76-\uDF7A]|\uD802[\uDE01-\uDE03\uDE05\uDE06\uDE0C-\uDE0F\uDE38-\uDE3A\uDE3F\uDEE5\uDEE6]|\uD804[\uDC00-\uDC02\uDC38-\uDC46\uDC7F-\uDC82\uDCB0-\uDCBA\uDD00-\uDD02\uDD27-\uDD34\uDD73\uDD80-\uDD82\uDDB3-\uDDC0\uDE2C-\uDE37\uDEDF-\uDEEA\uDF01-\uDF03\uDF3C\uDF3E-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF57\uDF62\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDCB0-\uDCC3\uDDAF-\uDDB5\uDDB8-\uDDC0\uDE30-\uDE40\uDEAB-\uDEB7]|\uD81A[\uDEF0-\uDEF4\uDF30-\uDF36]|\uD81B[\uDF51-\uDF7E\uDF8F-\uDF92]|\uD82F[\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD83A[\uDCD0-\uDCD6]|\uDB40[\uDD00-\uDDEF]/; + +function validateLabel(label, processing_option) { + if (label.substr(0, 4) === "xn--") { + label = punycode.toUnicode(label); + processing_option = PROCESSING_OPTIONS.NONTRANSITIONAL; + } + + var error = false; + + if (normalize(label) !== label || + (label[3] === "-" && label[4] === "-") || + label[0] === "-" || label[label.length - 1] === "-" || + label.indexOf(".") !== -1 || + label.search(combiningMarksRegex) === 0) { + error = true; + } + + var len = countSymbols(label); + for (var i = 0; i < len; ++i) { + var status = findStatus(label.codePointAt(i)); + if ((processing === PROCESSING_OPTIONS.TRANSITIONAL && status[1] !== "valid") || + (processing === PROCESSING_OPTIONS.NONTRANSITIONAL && + status[1] !== "valid" && status[1] !== "deviation")) { + error = true; + break; + } + } + + return { + label: label, + error: error + }; +} + +function processing(domain_name, useSTD3, processing_option) { + var result = mapChars(domain_name, useSTD3, processing_option); + result.string = normalize(result.string); + + var labels = result.string.split("."); + for (var i = 0; i < labels.length; ++i) { + try { + var validation = validateLabel(labels[i]); + labels[i] = validation.label; + result.error = result.error || validation.error; + } catch(e) { + result.error = true; + } + } + + return { + string: labels.join("."), + error: result.error + }; +} + +module.exports.toASCII = function(domain_name, useSTD3, processing_option, verifyDnsLength) { + var result = processing(domain_name, useSTD3, processing_option); + var labels = result.string.split("."); + labels = labels.map(function(l) { + try { + return punycode.toASCII(l); + } catch(e) { + result.error = true; + return l; + } + }); + + if (verifyDnsLength) { + var total = labels.slice(0, labels.length - 1).join(".").length; + if (total.length > 253 || total.length === 0) { + result.error = true; + } + + for (var i=0; i < labels.length; ++i) { + if (labels.length > 63 || labels.length === 0) { + result.error = true; + break; + } + } + } + + if (result.error) return null; + return labels.join("."); +}; + +module.exports.toUnicode = function(domain_name, useSTD3) { + var result = processing(domain_name, useSTD3, PROCESSING_OPTIONS.NONTRANSITIONAL); + + return { + domain: result.string, + error: result.error + }; +}; + +module.exports.PROCESSING_OPTIONS = PROCESSING_OPTIONS; + + +/***/ }), + +/***/ 4294: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +module.exports = __nccwpck_require__(4219); + + +/***/ }), + +/***/ 4219: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +var net = __nccwpck_require__(1808); +var tls = __nccwpck_require__(4404); +var http = __nccwpck_require__(3685); +var https = __nccwpck_require__(5687); +var events = __nccwpck_require__(2361); +var assert = __nccwpck_require__(9491); +var util = __nccwpck_require__(3837); + + +exports.httpOverHttp = httpOverHttp; +exports.httpsOverHttp = httpsOverHttp; +exports.httpOverHttps = httpOverHttps; +exports.httpsOverHttps = httpsOverHttps; + + +function httpOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + return agent; +} + +function httpsOverHttp(options) { + var agent = new TunnelingAgent(options); + agent.request = http.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + +function httpOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + return agent; +} + +function httpsOverHttps(options) { + var agent = new TunnelingAgent(options); + agent.request = https.request; + agent.createSocket = createSecureSocket; + agent.defaultPort = 443; + return agent; +} + + +function TunnelingAgent(options) { + var self = this; + self.options = options || {}; + self.proxyOptions = self.options.proxy || {}; + self.maxSockets = self.options.maxSockets || http.Agent.defaultMaxSockets; + self.requests = []; + self.sockets = []; + + self.on('free', function onFree(socket, host, port, localAddress) { + var options = toOptions(host, port, localAddress); + for (var i = 0, len = self.requests.length; i < len; ++i) { + var pending = self.requests[i]; + if (pending.host === options.host && pending.port === options.port) { + // Detect the request to connect same origin server, + // reuse the connection. + self.requests.splice(i, 1); + pending.request.onSocket(socket); + return; + } + } + socket.destroy(); + self.removeSocket(socket); + }); +} +util.inherits(TunnelingAgent, events.EventEmitter); + +TunnelingAgent.prototype.addRequest = function addRequest(req, host, port, localAddress) { + var self = this; + var options = mergeOptions({request: req}, self.options, toOptions(host, port, localAddress)); + + if (self.sockets.length >= this.maxSockets) { + // We are over limit so we'll add it to the queue. + self.requests.push(options); + return; + } + + // If we are under maxSockets create a new one. + self.createSocket(options, function(socket) { + socket.on('free', onFree); + socket.on('close', onCloseOrRemove); + socket.on('agentRemove', onCloseOrRemove); + req.onSocket(socket); + + function onFree() { + self.emit('free', socket, options); + } + + function onCloseOrRemove(err) { + self.removeSocket(socket); + socket.removeListener('free', onFree); + socket.removeListener('close', onCloseOrRemove); + socket.removeListener('agentRemove', onCloseOrRemove); + } + }); +}; + +TunnelingAgent.prototype.createSocket = function createSocket(options, cb) { + var self = this; + var placeholder = {}; + self.sockets.push(placeholder); + + var connectOptions = mergeOptions({}, self.proxyOptions, { + method: 'CONNECT', + path: options.host + ':' + options.port, + agent: false, + headers: { + host: options.host + ':' + options.port + } + }); + if (options.localAddress) { + connectOptions.localAddress = options.localAddress; + } + if (connectOptions.proxyAuth) { + connectOptions.headers = connectOptions.headers || {}; + connectOptions.headers['Proxy-Authorization'] = 'Basic ' + + new Buffer(connectOptions.proxyAuth).toString('base64'); + } + + debug('making CONNECT request'); + var connectReq = self.request(connectOptions); + connectReq.useChunkedEncodingByDefault = false; // for v0.6 + connectReq.once('response', onResponse); // for v0.6 + connectReq.once('upgrade', onUpgrade); // for v0.6 + connectReq.once('connect', onConnect); // for v0.7 or later + connectReq.once('error', onError); + connectReq.end(); + + function onResponse(res) { + // Very hacky. This is necessary to avoid http-parser leaks. + res.upgrade = true; + } + + function onUpgrade(res, socket, head) { + // Hacky. + process.nextTick(function() { + onConnect(res, socket, head); + }); + } + + function onConnect(res, socket, head) { + connectReq.removeAllListeners(); + socket.removeAllListeners(); + + if (res.statusCode !== 200) { + debug('tunneling socket could not be established, statusCode=%d', + res.statusCode); + socket.destroy(); + var error = new Error('tunneling socket could not be established, ' + + 'statusCode=' + res.statusCode); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + if (head.length > 0) { + debug('got illegal response body from proxy'); + socket.destroy(); + var error = new Error('got illegal response body from proxy'); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + return; + } + debug('tunneling connection has established'); + self.sockets[self.sockets.indexOf(placeholder)] = socket; + return cb(socket); + } + + function onError(cause) { + connectReq.removeAllListeners(); + + debug('tunneling socket could not be established, cause=%s\n', + cause.message, cause.stack); + var error = new Error('tunneling socket could not be established, ' + + 'cause=' + cause.message); + error.code = 'ECONNRESET'; + options.request.emit('error', error); + self.removeSocket(placeholder); + } +}; + +TunnelingAgent.prototype.removeSocket = function removeSocket(socket) { + var pos = this.sockets.indexOf(socket) + if (pos === -1) { + return; + } + this.sockets.splice(pos, 1); + + var pending = this.requests.shift(); + if (pending) { + // If we have pending requests and a socket gets closed a new one + // needs to be created to take over in the pool for the one that closed. + this.createSocket(pending, function(socket) { + pending.request.onSocket(socket); + }); + } +}; + +function createSecureSocket(options, cb) { + var self = this; + TunnelingAgent.prototype.createSocket.call(self, options, function(socket) { + var hostHeader = options.request.getHeader('host'); + var tlsOptions = mergeOptions({}, self.options, { + socket: socket, + servername: hostHeader ? hostHeader.replace(/:.*$/, '') : options.host + }); + + // 0 is dummy port for v0.6 + var secureSocket = tls.connect(0, tlsOptions); + self.sockets[self.sockets.indexOf(socket)] = secureSocket; + cb(secureSocket); + }); +} + + +function toOptions(host, port, localAddress) { + if (typeof host === 'string') { // since v0.10 + return { + host: host, + port: port, + localAddress: localAddress + }; + } + return host; // for v0.11 or later +} + +function mergeOptions(target) { + for (var i = 1, len = arguments.length; i < len; ++i) { + var overrides = arguments[i]; + if (typeof overrides === 'object') { + var keys = Object.keys(overrides); + for (var j = 0, keyLen = keys.length; j < keyLen; ++j) { + var k = keys[j]; + if (overrides[k] !== undefined) { + target[k] = overrides[k]; + } + } + } + } + return target; +} + + +var debug; +if (process.env.NODE_DEBUG && /\btunnel\b/.test(process.env.NODE_DEBUG)) { + debug = function() { + var args = Array.prototype.slice.call(arguments); + if (typeof args[0] === 'string') { + args[0] = 'TUNNEL: ' + args[0]; + } else { + args.unshift('TUNNEL:'); + } + console.error.apply(console, args); + } +} else { + debug = function() {}; +} +exports.debug = debug; // for test + + +/***/ }), + +/***/ 5030: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ value: true })); + +function getUserAgent() { + if (typeof navigator === "object" && "userAgent" in navigator) { + return navigator.userAgent; + } + + if (typeof process === "object" && "version" in process) { + return `Node.js/${process.version.substr(1)} (${process.platform}; ${process.arch})`; + } + + return "<environment undetectable>"; +} + +exports.getUserAgent = getUserAgent; +//# sourceMappingURL=index.js.map + + +/***/ }), + +/***/ 5840: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +Object.defineProperty(exports, "v1", ({ + enumerable: true, + get: function () { + return _v.default; + } +})); +Object.defineProperty(exports, "v3", ({ + enumerable: true, + get: function () { + return _v2.default; + } +})); +Object.defineProperty(exports, "v4", ({ + enumerable: true, + get: function () { + return _v3.default; + } +})); +Object.defineProperty(exports, "v5", ({ + enumerable: true, + get: function () { + return _v4.default; + } +})); +Object.defineProperty(exports, "NIL", ({ + enumerable: true, + get: function () { + return _nil.default; + } +})); +Object.defineProperty(exports, "version", ({ + enumerable: true, + get: function () { + return _version.default; + } +})); +Object.defineProperty(exports, "validate", ({ + enumerable: true, + get: function () { + return _validate.default; + } +})); +Object.defineProperty(exports, "stringify", ({ + enumerable: true, + get: function () { + return _stringify.default; + } +})); +Object.defineProperty(exports, "parse", ({ + enumerable: true, + get: function () { + return _parse.default; + } +})); + +var _v = _interopRequireDefault(__nccwpck_require__(8628)); + +var _v2 = _interopRequireDefault(__nccwpck_require__(6409)); + +var _v3 = _interopRequireDefault(__nccwpck_require__(5122)); + +var _v4 = _interopRequireDefault(__nccwpck_require__(9120)); + +var _nil = _interopRequireDefault(__nccwpck_require__(5332)); + +var _version = _interopRequireDefault(__nccwpck_require__(1595)); + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/***/ }), + +/***/ 4569: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function md5(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('md5').update(bytes).digest(); +} + +var _default = md5; +exports["default"] = _default; + +/***/ }), + +/***/ 5332: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = '00000000-0000-0000-0000-000000000000'; +exports["default"] = _default; + +/***/ }), + +/***/ 2746: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function parse(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + let v; + const arr = new Uint8Array(16); // Parse ########-....-....-....-............ + + arr[0] = (v = parseInt(uuid.slice(0, 8), 16)) >>> 24; + arr[1] = v >>> 16 & 0xff; + arr[2] = v >>> 8 & 0xff; + arr[3] = v & 0xff; // Parse ........-####-....-....-............ + + arr[4] = (v = parseInt(uuid.slice(9, 13), 16)) >>> 8; + arr[5] = v & 0xff; // Parse ........-....-####-....-............ + + arr[6] = (v = parseInt(uuid.slice(14, 18), 16)) >>> 8; + arr[7] = v & 0xff; // Parse ........-....-....-####-............ + + arr[8] = (v = parseInt(uuid.slice(19, 23), 16)) >>> 8; + arr[9] = v & 0xff; // Parse ........-....-....-....-############ + // (Use "/" to avoid 32-bit truncation when bit-shifting high-order bytes) + + arr[10] = (v = parseInt(uuid.slice(24, 36), 16)) / 0x10000000000 & 0xff; + arr[11] = v / 0x100000000 & 0xff; + arr[12] = v >>> 24 & 0xff; + arr[13] = v >>> 16 & 0xff; + arr[14] = v >>> 8 & 0xff; + arr[15] = v & 0xff; + return arr; +} + +var _default = parse; +exports["default"] = _default; + +/***/ }), + +/***/ 814: +/***/ ((__unused_webpack_module, exports) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; +var _default = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i; +exports["default"] = _default; + +/***/ }), + +/***/ 807: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = rng; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const rnds8Pool = new Uint8Array(256); // # of random values to pre-allocate + +let poolPtr = rnds8Pool.length; + +function rng() { + if (poolPtr > rnds8Pool.length - 16) { + _crypto.default.randomFillSync(rnds8Pool); + + poolPtr = 0; + } + + return rnds8Pool.slice(poolPtr, poolPtr += 16); +} + +/***/ }), + +/***/ 5274: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _crypto = _interopRequireDefault(__nccwpck_require__(6113)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function sha1(bytes) { + if (Array.isArray(bytes)) { + bytes = Buffer.from(bytes); + } else if (typeof bytes === 'string') { + bytes = Buffer.from(bytes, 'utf8'); + } + + return _crypto.default.createHash('sha1').update(bytes).digest(); +} + +var _default = sha1; +exports["default"] = _default; + +/***/ }), + +/***/ 8950: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +/** + * Convert array of 16 byte values to UUID string format of the form: + * XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ +const byteToHex = []; + +for (let i = 0; i < 256; ++i) { + byteToHex.push((i + 0x100).toString(16).substr(1)); +} + +function stringify(arr, offset = 0) { + // Note: Be careful editing this code! It's been tuned for performance + // and works in ways you may not expect. See https://github.com/uuidjs/uuid/pull/434 + const uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + '-' + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + '-' + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + '-' + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + '-' + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase(); // Consistency check for valid UUID. If this throws, it's likely due to one + // of the following: + // - One or more input array values don't map to a hex octet (leading to + // "undefined" in the uuid) + // - Invalid input values for the RFC `version` or `variant` fields + + if (!(0, _validate.default)(uuid)) { + throw TypeError('Stringified UUID is invalid'); + } + + return uuid; +} + +var _default = stringify; +exports["default"] = _default; + +/***/ }), + +/***/ 8628: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +// **`v1()` - Generate time-based UUID** +// +// Inspired by https://github.com/LiosK/UUID.js +// and http://docs.python.org/library/uuid.html +let _nodeId; + +let _clockseq; // Previous uuid creation time + + +let _lastMSecs = 0; +let _lastNSecs = 0; // See https://github.com/uuidjs/uuid for API details + +function v1(options, buf, offset) { + let i = buf && offset || 0; + const b = buf || new Array(16); + options = options || {}; + let node = options.node || _nodeId; + let clockseq = options.clockseq !== undefined ? options.clockseq : _clockseq; // node and clockseq need to be initialized to random values if they're not + // specified. We do this lazily to minimize issues related to insufficient + // system entropy. See #189 + + if (node == null || clockseq == null) { + const seedBytes = options.random || (options.rng || _rng.default)(); + + if (node == null) { + // Per 4.5, create and 48-bit node id, (47 random bits + multicast bit = 1) + node = _nodeId = [seedBytes[0] | 0x01, seedBytes[1], seedBytes[2], seedBytes[3], seedBytes[4], seedBytes[5]]; + } + + if (clockseq == null) { + // Per 4.2.2, randomize (14 bit) clockseq + clockseq = _clockseq = (seedBytes[6] << 8 | seedBytes[7]) & 0x3fff; + } + } // UUID timestamps are 100 nano-second units since the Gregorian epoch, + // (1582-10-15 00:00). JSNumbers aren't precise enough for this, so + // time is handled internally as 'msecs' (integer milliseconds) and 'nsecs' + // (100-nanoseconds offset from msecs) since unix epoch, 1970-01-01 00:00. + + + let msecs = options.msecs !== undefined ? options.msecs : Date.now(); // Per 4.2.1.2, use count of uuid's generated during the current clock + // cycle to simulate higher resolution clock + + let nsecs = options.nsecs !== undefined ? options.nsecs : _lastNSecs + 1; // Time since last uuid creation (in msecs) + + const dt = msecs - _lastMSecs + (nsecs - _lastNSecs) / 10000; // Per 4.2.1.2, Bump clockseq on clock regression + + if (dt < 0 && options.clockseq === undefined) { + clockseq = clockseq + 1 & 0x3fff; + } // Reset nsecs if clock regresses (new clockseq) or we've moved onto a new + // time interval + + + if ((dt < 0 || msecs > _lastMSecs) && options.nsecs === undefined) { + nsecs = 0; + } // Per 4.2.1.2 Throw error if too many uuids are requested + + + if (nsecs >= 10000) { + throw new Error("uuid.v1(): Can't create more than 10M uuids/sec"); + } + + _lastMSecs = msecs; + _lastNSecs = nsecs; + _clockseq = clockseq; // Per 4.1.4 - Convert from unix epoch to Gregorian epoch + + msecs += 12219292800000; // `time_low` + + const tl = ((msecs & 0xfffffff) * 10000 + nsecs) % 0x100000000; + b[i++] = tl >>> 24 & 0xff; + b[i++] = tl >>> 16 & 0xff; + b[i++] = tl >>> 8 & 0xff; + b[i++] = tl & 0xff; // `time_mid` + + const tmh = msecs / 0x100000000 * 10000 & 0xfffffff; + b[i++] = tmh >>> 8 & 0xff; + b[i++] = tmh & 0xff; // `time_high_and_version` + + b[i++] = tmh >>> 24 & 0xf | 0x10; // include version + + b[i++] = tmh >>> 16 & 0xff; // `clock_seq_hi_and_reserved` (Per 4.2.2 - include variant) + + b[i++] = clockseq >>> 8 | 0x80; // `clock_seq_low` + + b[i++] = clockseq & 0xff; // `node` + + for (let n = 0; n < 6; ++n) { + b[i + n] = node[n]; + } + + return buf || (0, _stringify.default)(b); +} + +var _default = v1; +exports["default"] = _default; + +/***/ }), + +/***/ 6409: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _md = _interopRequireDefault(__nccwpck_require__(4569)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v3 = (0, _v.default)('v3', 0x30, _md.default); +var _default = v3; +exports["default"] = _default; + +/***/ }), + +/***/ 5998: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = _default; +exports.URL = exports.DNS = void 0; + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +var _parse = _interopRequireDefault(__nccwpck_require__(2746)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function stringToBytes(str) { + str = unescape(encodeURIComponent(str)); // UTF8 escape + + const bytes = []; + + for (let i = 0; i < str.length; ++i) { + bytes.push(str.charCodeAt(i)); + } + + return bytes; +} + +const DNS = '6ba7b810-9dad-11d1-80b4-00c04fd430c8'; +exports.DNS = DNS; +const URL = '6ba7b811-9dad-11d1-80b4-00c04fd430c8'; +exports.URL = URL; + +function _default(name, version, hashfunc) { + function generateUUID(value, namespace, buf, offset) { + if (typeof value === 'string') { + value = stringToBytes(value); + } + + if (typeof namespace === 'string') { + namespace = (0, _parse.default)(namespace); + } + + if (namespace.length !== 16) { + throw TypeError('Namespace must be array-like (16 iterable integer values, 0-255)'); + } // Compute hash of namespace and value, Per 4.3 + // Future: Use spread syntax when supported on all platforms, e.g. `bytes = + // hashfunc([...namespace, ... value])` + + + let bytes = new Uint8Array(16 + value.length); + bytes.set(namespace); + bytes.set(value, namespace.length); + bytes = hashfunc(bytes); + bytes[6] = bytes[6] & 0x0f | version; + bytes[8] = bytes[8] & 0x3f | 0x80; + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = bytes[i]; + } + + return buf; + } + + return (0, _stringify.default)(bytes); + } // Function#name is not settable on some platforms (#270) + + + try { + generateUUID.name = name; // eslint-disable-next-line no-empty + } catch (err) {} // For CommonJS default export support + + + generateUUID.DNS = DNS; + generateUUID.URL = URL; + return generateUUID; +} + +/***/ }), + +/***/ 5122: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _rng = _interopRequireDefault(__nccwpck_require__(807)); + +var _stringify = _interopRequireDefault(__nccwpck_require__(8950)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function v4(options, buf, offset) { + options = options || {}; + + const rnds = options.random || (options.rng || _rng.default)(); // Per 4.4, set bits for version and `clock_seq_hi_and_reserved` + + + rnds[6] = rnds[6] & 0x0f | 0x40; + rnds[8] = rnds[8] & 0x3f | 0x80; // Copy bytes to buffer, if provided + + if (buf) { + offset = offset || 0; + + for (let i = 0; i < 16; ++i) { + buf[offset + i] = rnds[i]; + } + + return buf; + } + + return (0, _stringify.default)(rnds); +} + +var _default = v4; +exports["default"] = _default; + +/***/ }), + +/***/ 9120: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _v = _interopRequireDefault(__nccwpck_require__(5998)); + +var _sha = _interopRequireDefault(__nccwpck_require__(5274)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +const v5 = (0, _v.default)('v5', 0x50, _sha.default); +var _default = v5; +exports["default"] = _default; + +/***/ }), + +/***/ 6900: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _regex = _interopRequireDefault(__nccwpck_require__(814)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function validate(uuid) { + return typeof uuid === 'string' && _regex.default.test(uuid); +} + +var _default = validate; +exports["default"] = _default; + +/***/ }), + +/***/ 1595: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +Object.defineProperty(exports, "__esModule", ({ + value: true +})); +exports["default"] = void 0; + +var _validate = _interopRequireDefault(__nccwpck_require__(6900)); + +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } + +function version(uuid) { + if (!(0, _validate.default)(uuid)) { + throw TypeError('Invalid UUID'); + } + + return parseInt(uuid.substr(14, 1), 16); +} + +var _default = version; +exports["default"] = _default; + +/***/ }), + +/***/ 1452: +/***/ (function(__unused_webpack_module, exports) { + +/** + * web-streams-polyfill v3.2.1 + */ +(function (global, factory) { + true ? factory(exports) : + 0; +}(this, (function (exports) { 'use strict'; + + /// <reference lib="es2015.symbol" /> + const SymbolPolyfill = typeof Symbol === 'function' && typeof Symbol.iterator === 'symbol' ? + Symbol : + description => `Symbol(${description})`; + + /// <reference lib="dom" /> + function noop() { + return undefined; + } + function getGlobals() { + if (typeof self !== 'undefined') { + return self; + } + else if (typeof window !== 'undefined') { + return window; + } + else if (typeof global !== 'undefined') { + return global; + } + return undefined; + } + const globals = getGlobals(); + + function typeIsObject(x) { + return (typeof x === 'object' && x !== null) || typeof x === 'function'; + } + const rethrowAssertionErrorRejection = noop; + + const originalPromise = Promise; + const originalPromiseThen = Promise.prototype.then; + const originalPromiseResolve = Promise.resolve.bind(originalPromise); + const originalPromiseReject = Promise.reject.bind(originalPromise); + function newPromise(executor) { + return new originalPromise(executor); + } + function promiseResolvedWith(value) { + return originalPromiseResolve(value); + } + function promiseRejectedWith(reason) { + return originalPromiseReject(reason); + } + function PerformPromiseThen(promise, onFulfilled, onRejected) { + // There doesn't appear to be any way to correctly emulate the behaviour from JavaScript, so this is just an + // approximation. + return originalPromiseThen.call(promise, onFulfilled, onRejected); + } + function uponPromise(promise, onFulfilled, onRejected) { + PerformPromiseThen(PerformPromiseThen(promise, onFulfilled, onRejected), undefined, rethrowAssertionErrorRejection); + } + function uponFulfillment(promise, onFulfilled) { + uponPromise(promise, onFulfilled); + } + function uponRejection(promise, onRejected) { + uponPromise(promise, undefined, onRejected); + } + function transformPromiseWith(promise, fulfillmentHandler, rejectionHandler) { + return PerformPromiseThen(promise, fulfillmentHandler, rejectionHandler); + } + function setPromiseIsHandledToTrue(promise) { + PerformPromiseThen(promise, undefined, rethrowAssertionErrorRejection); + } + const queueMicrotask = (() => { + const globalQueueMicrotask = globals && globals.queueMicrotask; + if (typeof globalQueueMicrotask === 'function') { + return globalQueueMicrotask; + } + const resolvedPromise = promiseResolvedWith(undefined); + return (fn) => PerformPromiseThen(resolvedPromise, fn); + })(); + function reflectCall(F, V, args) { + if (typeof F !== 'function') { + throw new TypeError('Argument is not a function'); + } + return Function.prototype.apply.call(F, V, args); + } + function promiseCall(F, V, args) { + try { + return promiseResolvedWith(reflectCall(F, V, args)); + } + catch (value) { + return promiseRejectedWith(value); + } + } + + // Original from Chromium + // https://chromium.googlesource.com/chromium/src/+/0aee4434a4dba42a42abaea9bfbc0cd196a63bc1/third_party/blink/renderer/core/streams/SimpleQueue.js + const QUEUE_MAX_ARRAY_SIZE = 16384; + /** + * Simple queue structure. + * + * Avoids scalability issues with using a packed array directly by using + * multiple arrays in a linked list and keeping the array size bounded. + */ + class SimpleQueue { + constructor() { + this._cursor = 0; + this._size = 0; + // _front and _back are always defined. + this._front = { + _elements: [], + _next: undefined + }; + this._back = this._front; + // The cursor is used to avoid calling Array.shift(). + // It contains the index of the front element of the array inside the + // front-most node. It is always in the range [0, QUEUE_MAX_ARRAY_SIZE). + this._cursor = 0; + // When there is only one node, size === elements.length - cursor. + this._size = 0; + } + get length() { + return this._size; + } + // For exception safety, this method is structured in order: + // 1. Read state + // 2. Calculate required state mutations + // 3. Perform state mutations + push(element) { + const oldBack = this._back; + let newBack = oldBack; + if (oldBack._elements.length === QUEUE_MAX_ARRAY_SIZE - 1) { + newBack = { + _elements: [], + _next: undefined + }; + } + // push() is the mutation most likely to throw an exception, so it + // goes first. + oldBack._elements.push(element); + if (newBack !== oldBack) { + this._back = newBack; + oldBack._next = newBack; + } + ++this._size; + } + // Like push(), shift() follows the read -> calculate -> mutate pattern for + // exception safety. + shift() { // must not be called on an empty queue + const oldFront = this._front; + let newFront = oldFront; + const oldCursor = this._cursor; + let newCursor = oldCursor + 1; + const elements = oldFront._elements; + const element = elements[oldCursor]; + if (newCursor === QUEUE_MAX_ARRAY_SIZE) { + newFront = oldFront._next; + newCursor = 0; + } + // No mutations before this point. + --this._size; + this._cursor = newCursor; + if (oldFront !== newFront) { + this._front = newFront; + } + // Permit shifted element to be garbage collected. + elements[oldCursor] = undefined; + return element; + } + // The tricky thing about forEach() is that it can be called + // re-entrantly. The queue may be mutated inside the callback. It is easy to + // see that push() within the callback has no negative effects since the end + // of the queue is checked for on every iteration. If shift() is called + // repeatedly within the callback then the next iteration may return an + // element that has been removed. In this case the callback will be called + // with undefined values until we either "catch up" with elements that still + // exist or reach the back of the queue. + forEach(callback) { + let i = this._cursor; + let node = this._front; + let elements = node._elements; + while (i !== elements.length || node._next !== undefined) { + if (i === elements.length) { + node = node._next; + elements = node._elements; + i = 0; + if (elements.length === 0) { + break; + } + } + callback(elements[i]); + ++i; + } + } + // Return the element that would be returned if shift() was called now, + // without modifying the queue. + peek() { // must not be called on an empty queue + const front = this._front; + const cursor = this._cursor; + return front._elements[cursor]; + } + } + + function ReadableStreamReaderGenericInitialize(reader, stream) { + reader._ownerReadableStream = stream; + stream._reader = reader; + if (stream._state === 'readable') { + defaultReaderClosedPromiseInitialize(reader); + } + else if (stream._state === 'closed') { + defaultReaderClosedPromiseInitializeAsResolved(reader); + } + else { + defaultReaderClosedPromiseInitializeAsRejected(reader, stream._storedError); + } + } + // A client of ReadableStreamDefaultReader and ReadableStreamBYOBReader may use these functions directly to bypass state + // check. + function ReadableStreamReaderGenericCancel(reader, reason) { + const stream = reader._ownerReadableStream; + return ReadableStreamCancel(stream, reason); + } + function ReadableStreamReaderGenericRelease(reader) { + if (reader._ownerReadableStream._state === 'readable') { + defaultReaderClosedPromiseReject(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`)); + } + else { + defaultReaderClosedPromiseResetToRejected(reader, new TypeError(`Reader was released and can no longer be used to monitor the stream's closedness`)); + } + reader._ownerReadableStream._reader = undefined; + reader._ownerReadableStream = undefined; + } + // Helper functions for the readers. + function readerLockException(name) { + return new TypeError('Cannot ' + name + ' a stream using a released reader'); + } + // Helper functions for the ReadableStreamDefaultReader. + function defaultReaderClosedPromiseInitialize(reader) { + reader._closedPromise = newPromise((resolve, reject) => { + reader._closedPromise_resolve = resolve; + reader._closedPromise_reject = reject; + }); + } + function defaultReaderClosedPromiseInitializeAsRejected(reader, reason) { + defaultReaderClosedPromiseInitialize(reader); + defaultReaderClosedPromiseReject(reader, reason); + } + function defaultReaderClosedPromiseInitializeAsResolved(reader) { + defaultReaderClosedPromiseInitialize(reader); + defaultReaderClosedPromiseResolve(reader); + } + function defaultReaderClosedPromiseReject(reader, reason) { + if (reader._closedPromise_reject === undefined) { + return; + } + setPromiseIsHandledToTrue(reader._closedPromise); + reader._closedPromise_reject(reason); + reader._closedPromise_resolve = undefined; + reader._closedPromise_reject = undefined; + } + function defaultReaderClosedPromiseResetToRejected(reader, reason) { + defaultReaderClosedPromiseInitializeAsRejected(reader, reason); + } + function defaultReaderClosedPromiseResolve(reader) { + if (reader._closedPromise_resolve === undefined) { + return; + } + reader._closedPromise_resolve(undefined); + reader._closedPromise_resolve = undefined; + reader._closedPromise_reject = undefined; + } + + const AbortSteps = SymbolPolyfill('[[AbortSteps]]'); + const ErrorSteps = SymbolPolyfill('[[ErrorSteps]]'); + const CancelSteps = SymbolPolyfill('[[CancelSteps]]'); + const PullSteps = SymbolPolyfill('[[PullSteps]]'); + + /// <reference lib="es2015.core" /> + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite#Polyfill + const NumberIsFinite = Number.isFinite || function (x) { + return typeof x === 'number' && isFinite(x); + }; + + /// <reference lib="es2015.core" /> + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/trunc#Polyfill + const MathTrunc = Math.trunc || function (v) { + return v < 0 ? Math.ceil(v) : Math.floor(v); + }; + + // https://heycam.github.io/webidl/#idl-dictionaries + function isDictionary(x) { + return typeof x === 'object' || typeof x === 'function'; + } + function assertDictionary(obj, context) { + if (obj !== undefined && !isDictionary(obj)) { + throw new TypeError(`${context} is not an object.`); + } + } + // https://heycam.github.io/webidl/#idl-callback-functions + function assertFunction(x, context) { + if (typeof x !== 'function') { + throw new TypeError(`${context} is not a function.`); + } + } + // https://heycam.github.io/webidl/#idl-object + function isObject(x) { + return (typeof x === 'object' && x !== null) || typeof x === 'function'; + } + function assertObject(x, context) { + if (!isObject(x)) { + throw new TypeError(`${context} is not an object.`); + } + } + function assertRequiredArgument(x, position, context) { + if (x === undefined) { + throw new TypeError(`Parameter ${position} is required in '${context}'.`); + } + } + function assertRequiredField(x, field, context) { + if (x === undefined) { + throw new TypeError(`${field} is required in '${context}'.`); + } + } + // https://heycam.github.io/webidl/#idl-unrestricted-double + function convertUnrestrictedDouble(value) { + return Number(value); + } + function censorNegativeZero(x) { + return x === 0 ? 0 : x; + } + function integerPart(x) { + return censorNegativeZero(MathTrunc(x)); + } + // https://heycam.github.io/webidl/#idl-unsigned-long-long + function convertUnsignedLongLongWithEnforceRange(value, context) { + const lowerBound = 0; + const upperBound = Number.MAX_SAFE_INTEGER; + let x = Number(value); + x = censorNegativeZero(x); + if (!NumberIsFinite(x)) { + throw new TypeError(`${context} is not a finite number`); + } + x = integerPart(x); + if (x < lowerBound || x > upperBound) { + throw new TypeError(`${context} is outside the accepted range of ${lowerBound} to ${upperBound}, inclusive`); + } + if (!NumberIsFinite(x) || x === 0) { + return 0; + } + // TODO Use BigInt if supported? + // let xBigInt = BigInt(integerPart(x)); + // xBigInt = BigInt.asUintN(64, xBigInt); + // return Number(xBigInt); + return x; + } + + function assertReadableStream(x, context) { + if (!IsReadableStream(x)) { + throw new TypeError(`${context} is not a ReadableStream.`); + } + } + + // Abstract operations for the ReadableStream. + function AcquireReadableStreamDefaultReader(stream) { + return new ReadableStreamDefaultReader(stream); + } + // ReadableStream API exposed for controllers. + function ReadableStreamAddReadRequest(stream, readRequest) { + stream._reader._readRequests.push(readRequest); + } + function ReadableStreamFulfillReadRequest(stream, chunk, done) { + const reader = stream._reader; + const readRequest = reader._readRequests.shift(); + if (done) { + readRequest._closeSteps(); + } + else { + readRequest._chunkSteps(chunk); + } + } + function ReadableStreamGetNumReadRequests(stream) { + return stream._reader._readRequests.length; + } + function ReadableStreamHasDefaultReader(stream) { + const reader = stream._reader; + if (reader === undefined) { + return false; + } + if (!IsReadableStreamDefaultReader(reader)) { + return false; + } + return true; + } + /** + * A default reader vended by a {@link ReadableStream}. + * + * @public + */ + class ReadableStreamDefaultReader { + constructor(stream) { + assertRequiredArgument(stream, 1, 'ReadableStreamDefaultReader'); + assertReadableStream(stream, 'First parameter'); + if (IsReadableStreamLocked(stream)) { + throw new TypeError('This stream has already been locked for exclusive reading by another reader'); + } + ReadableStreamReaderGenericInitialize(this, stream); + this._readRequests = new SimpleQueue(); + } + /** + * Returns a promise that will be fulfilled when the stream becomes closed, + * or rejected if the stream ever errors or the reader's lock is released before the stream finishes closing. + */ + get closed() { + if (!IsReadableStreamDefaultReader(this)) { + return promiseRejectedWith(defaultReaderBrandCheckException('closed')); + } + return this._closedPromise; + } + /** + * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}. + */ + cancel(reason = undefined) { + if (!IsReadableStreamDefaultReader(this)) { + return promiseRejectedWith(defaultReaderBrandCheckException('cancel')); + } + if (this._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('cancel')); + } + return ReadableStreamReaderGenericCancel(this, reason); + } + /** + * Returns a promise that allows access to the next chunk from the stream's internal queue, if available. + * + * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source. + */ + read() { + if (!IsReadableStreamDefaultReader(this)) { + return promiseRejectedWith(defaultReaderBrandCheckException('read')); + } + if (this._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('read from')); + } + let resolvePromise; + let rejectPromise; + const promise = newPromise((resolve, reject) => { + resolvePromise = resolve; + rejectPromise = reject; + }); + const readRequest = { + _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }), + _closeSteps: () => resolvePromise({ value: undefined, done: true }), + _errorSteps: e => rejectPromise(e) + }; + ReadableStreamDefaultReaderRead(this, readRequest); + return promise; + } + /** + * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active. + * If the associated stream is errored when the lock is released, the reader will appear errored in the same way + * from now on; otherwise, the reader will appear closed. + * + * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by + * the reader's {@link ReadableStreamDefaultReader.read | read()} method has not yet been settled. Attempting to + * do so will throw a `TypeError` and leave the reader locked to the stream. + */ + releaseLock() { + if (!IsReadableStreamDefaultReader(this)) { + throw defaultReaderBrandCheckException('releaseLock'); + } + if (this._ownerReadableStream === undefined) { + return; + } + if (this._readRequests.length > 0) { + throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled'); + } + ReadableStreamReaderGenericRelease(this); + } + } + Object.defineProperties(ReadableStreamDefaultReader.prototype, { + cancel: { enumerable: true }, + read: { enumerable: true }, + releaseLock: { enumerable: true }, + closed: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableStreamDefaultReader.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableStreamDefaultReader', + configurable: true + }); + } + // Abstract operations for the readers. + function IsReadableStreamDefaultReader(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_readRequests')) { + return false; + } + return x instanceof ReadableStreamDefaultReader; + } + function ReadableStreamDefaultReaderRead(reader, readRequest) { + const stream = reader._ownerReadableStream; + stream._disturbed = true; + if (stream._state === 'closed') { + readRequest._closeSteps(); + } + else if (stream._state === 'errored') { + readRequest._errorSteps(stream._storedError); + } + else { + stream._readableStreamController[PullSteps](readRequest); + } + } + // Helper functions for the ReadableStreamDefaultReader. + function defaultReaderBrandCheckException(name) { + return new TypeError(`ReadableStreamDefaultReader.prototype.${name} can only be used on a ReadableStreamDefaultReader`); + } + + /// <reference lib="es2018.asynciterable" /> + /* eslint-disable @typescript-eslint/no-empty-function */ + const AsyncIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf(async function* () { }).prototype); + + /// <reference lib="es2018.asynciterable" /> + class ReadableStreamAsyncIteratorImpl { + constructor(reader, preventCancel) { + this._ongoingPromise = undefined; + this._isFinished = false; + this._reader = reader; + this._preventCancel = preventCancel; + } + next() { + const nextSteps = () => this._nextSteps(); + this._ongoingPromise = this._ongoingPromise ? + transformPromiseWith(this._ongoingPromise, nextSteps, nextSteps) : + nextSteps(); + return this._ongoingPromise; + } + return(value) { + const returnSteps = () => this._returnSteps(value); + return this._ongoingPromise ? + transformPromiseWith(this._ongoingPromise, returnSteps, returnSteps) : + returnSteps(); + } + _nextSteps() { + if (this._isFinished) { + return Promise.resolve({ value: undefined, done: true }); + } + const reader = this._reader; + if (reader._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('iterate')); + } + let resolvePromise; + let rejectPromise; + const promise = newPromise((resolve, reject) => { + resolvePromise = resolve; + rejectPromise = reject; + }); + const readRequest = { + _chunkSteps: chunk => { + this._ongoingPromise = undefined; + // This needs to be delayed by one microtask, otherwise we stop pulling too early which breaks a test. + // FIXME Is this a bug in the specification, or in the test? + queueMicrotask(() => resolvePromise({ value: chunk, done: false })); + }, + _closeSteps: () => { + this._ongoingPromise = undefined; + this._isFinished = true; + ReadableStreamReaderGenericRelease(reader); + resolvePromise({ value: undefined, done: true }); + }, + _errorSteps: reason => { + this._ongoingPromise = undefined; + this._isFinished = true; + ReadableStreamReaderGenericRelease(reader); + rejectPromise(reason); + } + }; + ReadableStreamDefaultReaderRead(reader, readRequest); + return promise; + } + _returnSteps(value) { + if (this._isFinished) { + return Promise.resolve({ value, done: true }); + } + this._isFinished = true; + const reader = this._reader; + if (reader._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('finish iterating')); + } + if (!this._preventCancel) { + const result = ReadableStreamReaderGenericCancel(reader, value); + ReadableStreamReaderGenericRelease(reader); + return transformPromiseWith(result, () => ({ value, done: true })); + } + ReadableStreamReaderGenericRelease(reader); + return promiseResolvedWith({ value, done: true }); + } + } + const ReadableStreamAsyncIteratorPrototype = { + next() { + if (!IsReadableStreamAsyncIterator(this)) { + return promiseRejectedWith(streamAsyncIteratorBrandCheckException('next')); + } + return this._asyncIteratorImpl.next(); + }, + return(value) { + if (!IsReadableStreamAsyncIterator(this)) { + return promiseRejectedWith(streamAsyncIteratorBrandCheckException('return')); + } + return this._asyncIteratorImpl.return(value); + } + }; + if (AsyncIteratorPrototype !== undefined) { + Object.setPrototypeOf(ReadableStreamAsyncIteratorPrototype, AsyncIteratorPrototype); + } + // Abstract operations for the ReadableStream. + function AcquireReadableStreamAsyncIterator(stream, preventCancel) { + const reader = AcquireReadableStreamDefaultReader(stream); + const impl = new ReadableStreamAsyncIteratorImpl(reader, preventCancel); + const iterator = Object.create(ReadableStreamAsyncIteratorPrototype); + iterator._asyncIteratorImpl = impl; + return iterator; + } + function IsReadableStreamAsyncIterator(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_asyncIteratorImpl')) { + return false; + } + try { + // noinspection SuspiciousTypeOfGuard + return x._asyncIteratorImpl instanceof + ReadableStreamAsyncIteratorImpl; + } + catch (_a) { + return false; + } + } + // Helper functions for the ReadableStream. + function streamAsyncIteratorBrandCheckException(name) { + return new TypeError(`ReadableStreamAsyncIterator.${name} can only be used on a ReadableSteamAsyncIterator`); + } + + /// <reference lib="es2015.core" /> + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN#Polyfill + const NumberIsNaN = Number.isNaN || function (x) { + // eslint-disable-next-line no-self-compare + return x !== x; + }; + + function CreateArrayFromList(elements) { + // We use arrays to represent lists, so this is basically a no-op. + // Do a slice though just in case we happen to depend on the unique-ness. + return elements.slice(); + } + function CopyDataBlockBytes(dest, destOffset, src, srcOffset, n) { + new Uint8Array(dest).set(new Uint8Array(src, srcOffset, n), destOffset); + } + // Not implemented correctly + function TransferArrayBuffer(O) { + return O; + } + // Not implemented correctly + // eslint-disable-next-line @typescript-eslint/no-unused-vars + function IsDetachedBuffer(O) { + return false; + } + function ArrayBufferSlice(buffer, begin, end) { + // ArrayBuffer.prototype.slice is not available on IE10 + // https://www.caniuse.com/mdn-javascript_builtins_arraybuffer_slice + if (buffer.slice) { + return buffer.slice(begin, end); + } + const length = end - begin; + const slice = new ArrayBuffer(length); + CopyDataBlockBytes(slice, 0, buffer, begin, length); + return slice; + } + + function IsNonNegativeNumber(v) { + if (typeof v !== 'number') { + return false; + } + if (NumberIsNaN(v)) { + return false; + } + if (v < 0) { + return false; + } + return true; + } + function CloneAsUint8Array(O) { + const buffer = ArrayBufferSlice(O.buffer, O.byteOffset, O.byteOffset + O.byteLength); + return new Uint8Array(buffer); + } + + function DequeueValue(container) { + const pair = container._queue.shift(); + container._queueTotalSize -= pair.size; + if (container._queueTotalSize < 0) { + container._queueTotalSize = 0; + } + return pair.value; + } + function EnqueueValueWithSize(container, value, size) { + if (!IsNonNegativeNumber(size) || size === Infinity) { + throw new RangeError('Size must be a finite, non-NaN, non-negative number.'); + } + container._queue.push({ value, size }); + container._queueTotalSize += size; + } + function PeekQueueValue(container) { + const pair = container._queue.peek(); + return pair.value; + } + function ResetQueue(container) { + container._queue = new SimpleQueue(); + container._queueTotalSize = 0; + } + + /** + * A pull-into request in a {@link ReadableByteStreamController}. + * + * @public + */ + class ReadableStreamBYOBRequest { + constructor() { + throw new TypeError('Illegal constructor'); + } + /** + * Returns the view for writing in to, or `null` if the BYOB request has already been responded to. + */ + get view() { + if (!IsReadableStreamBYOBRequest(this)) { + throw byobRequestBrandCheckException('view'); + } + return this._view; + } + respond(bytesWritten) { + if (!IsReadableStreamBYOBRequest(this)) { + throw byobRequestBrandCheckException('respond'); + } + assertRequiredArgument(bytesWritten, 1, 'respond'); + bytesWritten = convertUnsignedLongLongWithEnforceRange(bytesWritten, 'First parameter'); + if (this._associatedReadableByteStreamController === undefined) { + throw new TypeError('This BYOB request has been invalidated'); + } + if (IsDetachedBuffer(this._view.buffer)) ; + ReadableByteStreamControllerRespond(this._associatedReadableByteStreamController, bytesWritten); + } + respondWithNewView(view) { + if (!IsReadableStreamBYOBRequest(this)) { + throw byobRequestBrandCheckException('respondWithNewView'); + } + assertRequiredArgument(view, 1, 'respondWithNewView'); + if (!ArrayBuffer.isView(view)) { + throw new TypeError('You can only respond with array buffer views'); + } + if (this._associatedReadableByteStreamController === undefined) { + throw new TypeError('This BYOB request has been invalidated'); + } + if (IsDetachedBuffer(view.buffer)) ; + ReadableByteStreamControllerRespondWithNewView(this._associatedReadableByteStreamController, view); + } + } + Object.defineProperties(ReadableStreamBYOBRequest.prototype, { + respond: { enumerable: true }, + respondWithNewView: { enumerable: true }, + view: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableStreamBYOBRequest.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableStreamBYOBRequest', + configurable: true + }); + } + /** + * Allows control of a {@link ReadableStream | readable byte stream}'s state and internal queue. + * + * @public + */ + class ReadableByteStreamController { + constructor() { + throw new TypeError('Illegal constructor'); + } + /** + * Returns the current BYOB pull request, or `null` if there isn't one. + */ + get byobRequest() { + if (!IsReadableByteStreamController(this)) { + throw byteStreamControllerBrandCheckException('byobRequest'); + } + return ReadableByteStreamControllerGetBYOBRequest(this); + } + /** + * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is + * over-full. An underlying byte source ought to use this information to determine when and how to apply backpressure. + */ + get desiredSize() { + if (!IsReadableByteStreamController(this)) { + throw byteStreamControllerBrandCheckException('desiredSize'); + } + return ReadableByteStreamControllerGetDesiredSize(this); + } + /** + * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from + * the stream, but once those are read, the stream will become closed. + */ + close() { + if (!IsReadableByteStreamController(this)) { + throw byteStreamControllerBrandCheckException('close'); + } + if (this._closeRequested) { + throw new TypeError('The stream has already been closed; do not close it again!'); + } + const state = this._controlledReadableByteStream._state; + if (state !== 'readable') { + throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be closed`); + } + ReadableByteStreamControllerClose(this); + } + enqueue(chunk) { + if (!IsReadableByteStreamController(this)) { + throw byteStreamControllerBrandCheckException('enqueue'); + } + assertRequiredArgument(chunk, 1, 'enqueue'); + if (!ArrayBuffer.isView(chunk)) { + throw new TypeError('chunk must be an array buffer view'); + } + if (chunk.byteLength === 0) { + throw new TypeError('chunk must have non-zero byteLength'); + } + if (chunk.buffer.byteLength === 0) { + throw new TypeError(`chunk's buffer must have non-zero byteLength`); + } + if (this._closeRequested) { + throw new TypeError('stream is closed or draining'); + } + const state = this._controlledReadableByteStream._state; + if (state !== 'readable') { + throw new TypeError(`The stream (in ${state} state) is not in the readable state and cannot be enqueued to`); + } + ReadableByteStreamControllerEnqueue(this, chunk); + } + /** + * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`. + */ + error(e = undefined) { + if (!IsReadableByteStreamController(this)) { + throw byteStreamControllerBrandCheckException('error'); + } + ReadableByteStreamControllerError(this, e); + } + /** @internal */ + [CancelSteps](reason) { + ReadableByteStreamControllerClearPendingPullIntos(this); + ResetQueue(this); + const result = this._cancelAlgorithm(reason); + ReadableByteStreamControllerClearAlgorithms(this); + return result; + } + /** @internal */ + [PullSteps](readRequest) { + const stream = this._controlledReadableByteStream; + if (this._queueTotalSize > 0) { + const entry = this._queue.shift(); + this._queueTotalSize -= entry.byteLength; + ReadableByteStreamControllerHandleQueueDrain(this); + const view = new Uint8Array(entry.buffer, entry.byteOffset, entry.byteLength); + readRequest._chunkSteps(view); + return; + } + const autoAllocateChunkSize = this._autoAllocateChunkSize; + if (autoAllocateChunkSize !== undefined) { + let buffer; + try { + buffer = new ArrayBuffer(autoAllocateChunkSize); + } + catch (bufferE) { + readRequest._errorSteps(bufferE); + return; + } + const pullIntoDescriptor = { + buffer, + bufferByteLength: autoAllocateChunkSize, + byteOffset: 0, + byteLength: autoAllocateChunkSize, + bytesFilled: 0, + elementSize: 1, + viewConstructor: Uint8Array, + readerType: 'default' + }; + this._pendingPullIntos.push(pullIntoDescriptor); + } + ReadableStreamAddReadRequest(stream, readRequest); + ReadableByteStreamControllerCallPullIfNeeded(this); + } + } + Object.defineProperties(ReadableByteStreamController.prototype, { + close: { enumerable: true }, + enqueue: { enumerable: true }, + error: { enumerable: true }, + byobRequest: { enumerable: true }, + desiredSize: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableByteStreamController.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableByteStreamController', + configurable: true + }); + } + // Abstract operations for the ReadableByteStreamController. + function IsReadableByteStreamController(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableByteStream')) { + return false; + } + return x instanceof ReadableByteStreamController; + } + function IsReadableStreamBYOBRequest(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_associatedReadableByteStreamController')) { + return false; + } + return x instanceof ReadableStreamBYOBRequest; + } + function ReadableByteStreamControllerCallPullIfNeeded(controller) { + const shouldPull = ReadableByteStreamControllerShouldCallPull(controller); + if (!shouldPull) { + return; + } + if (controller._pulling) { + controller._pullAgain = true; + return; + } + controller._pulling = true; + // TODO: Test controller argument + const pullPromise = controller._pullAlgorithm(); + uponPromise(pullPromise, () => { + controller._pulling = false; + if (controller._pullAgain) { + controller._pullAgain = false; + ReadableByteStreamControllerCallPullIfNeeded(controller); + } + }, e => { + ReadableByteStreamControllerError(controller, e); + }); + } + function ReadableByteStreamControllerClearPendingPullIntos(controller) { + ReadableByteStreamControllerInvalidateBYOBRequest(controller); + controller._pendingPullIntos = new SimpleQueue(); + } + function ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor) { + let done = false; + if (stream._state === 'closed') { + done = true; + } + const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor); + if (pullIntoDescriptor.readerType === 'default') { + ReadableStreamFulfillReadRequest(stream, filledView, done); + } + else { + ReadableStreamFulfillReadIntoRequest(stream, filledView, done); + } + } + function ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor) { + const bytesFilled = pullIntoDescriptor.bytesFilled; + const elementSize = pullIntoDescriptor.elementSize; + return new pullIntoDescriptor.viewConstructor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, bytesFilled / elementSize); + } + function ReadableByteStreamControllerEnqueueChunkToQueue(controller, buffer, byteOffset, byteLength) { + controller._queue.push({ buffer, byteOffset, byteLength }); + controller._queueTotalSize += byteLength; + } + function ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor) { + const elementSize = pullIntoDescriptor.elementSize; + const currentAlignedBytes = pullIntoDescriptor.bytesFilled - pullIntoDescriptor.bytesFilled % elementSize; + const maxBytesToCopy = Math.min(controller._queueTotalSize, pullIntoDescriptor.byteLength - pullIntoDescriptor.bytesFilled); + const maxBytesFilled = pullIntoDescriptor.bytesFilled + maxBytesToCopy; + const maxAlignedBytes = maxBytesFilled - maxBytesFilled % elementSize; + let totalBytesToCopyRemaining = maxBytesToCopy; + let ready = false; + if (maxAlignedBytes > currentAlignedBytes) { + totalBytesToCopyRemaining = maxAlignedBytes - pullIntoDescriptor.bytesFilled; + ready = true; + } + const queue = controller._queue; + while (totalBytesToCopyRemaining > 0) { + const headOfQueue = queue.peek(); + const bytesToCopy = Math.min(totalBytesToCopyRemaining, headOfQueue.byteLength); + const destStart = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled; + CopyDataBlockBytes(pullIntoDescriptor.buffer, destStart, headOfQueue.buffer, headOfQueue.byteOffset, bytesToCopy); + if (headOfQueue.byteLength === bytesToCopy) { + queue.shift(); + } + else { + headOfQueue.byteOffset += bytesToCopy; + headOfQueue.byteLength -= bytesToCopy; + } + controller._queueTotalSize -= bytesToCopy; + ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesToCopy, pullIntoDescriptor); + totalBytesToCopyRemaining -= bytesToCopy; + } + return ready; + } + function ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, size, pullIntoDescriptor) { + pullIntoDescriptor.bytesFilled += size; + } + function ReadableByteStreamControllerHandleQueueDrain(controller) { + if (controller._queueTotalSize === 0 && controller._closeRequested) { + ReadableByteStreamControllerClearAlgorithms(controller); + ReadableStreamClose(controller._controlledReadableByteStream); + } + else { + ReadableByteStreamControllerCallPullIfNeeded(controller); + } + } + function ReadableByteStreamControllerInvalidateBYOBRequest(controller) { + if (controller._byobRequest === null) { + return; + } + controller._byobRequest._associatedReadableByteStreamController = undefined; + controller._byobRequest._view = null; + controller._byobRequest = null; + } + function ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller) { + while (controller._pendingPullIntos.length > 0) { + if (controller._queueTotalSize === 0) { + return; + } + const pullIntoDescriptor = controller._pendingPullIntos.peek(); + if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) { + ReadableByteStreamControllerShiftPendingPullInto(controller); + ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor); + } + } + } + function ReadableByteStreamControllerPullInto(controller, view, readIntoRequest) { + const stream = controller._controlledReadableByteStream; + let elementSize = 1; + if (view.constructor !== DataView) { + elementSize = view.constructor.BYTES_PER_ELEMENT; + } + const ctor = view.constructor; + // try { + const buffer = TransferArrayBuffer(view.buffer); + // } catch (e) { + // readIntoRequest._errorSteps(e); + // return; + // } + const pullIntoDescriptor = { + buffer, + bufferByteLength: buffer.byteLength, + byteOffset: view.byteOffset, + byteLength: view.byteLength, + bytesFilled: 0, + elementSize, + viewConstructor: ctor, + readerType: 'byob' + }; + if (controller._pendingPullIntos.length > 0) { + controller._pendingPullIntos.push(pullIntoDescriptor); + // No ReadableByteStreamControllerCallPullIfNeeded() call since: + // - No change happens on desiredSize + // - The source has already been notified of that there's at least 1 pending read(view) + ReadableStreamAddReadIntoRequest(stream, readIntoRequest); + return; + } + if (stream._state === 'closed') { + const emptyView = new ctor(pullIntoDescriptor.buffer, pullIntoDescriptor.byteOffset, 0); + readIntoRequest._closeSteps(emptyView); + return; + } + if (controller._queueTotalSize > 0) { + if (ReadableByteStreamControllerFillPullIntoDescriptorFromQueue(controller, pullIntoDescriptor)) { + const filledView = ReadableByteStreamControllerConvertPullIntoDescriptor(pullIntoDescriptor); + ReadableByteStreamControllerHandleQueueDrain(controller); + readIntoRequest._chunkSteps(filledView); + return; + } + if (controller._closeRequested) { + const e = new TypeError('Insufficient bytes to fill elements in the given buffer'); + ReadableByteStreamControllerError(controller, e); + readIntoRequest._errorSteps(e); + return; + } + } + controller._pendingPullIntos.push(pullIntoDescriptor); + ReadableStreamAddReadIntoRequest(stream, readIntoRequest); + ReadableByteStreamControllerCallPullIfNeeded(controller); + } + function ReadableByteStreamControllerRespondInClosedState(controller, firstDescriptor) { + const stream = controller._controlledReadableByteStream; + if (ReadableStreamHasBYOBReader(stream)) { + while (ReadableStreamGetNumReadIntoRequests(stream) > 0) { + const pullIntoDescriptor = ReadableByteStreamControllerShiftPendingPullInto(controller); + ReadableByteStreamControllerCommitPullIntoDescriptor(stream, pullIntoDescriptor); + } + } + } + function ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, pullIntoDescriptor) { + ReadableByteStreamControllerFillHeadPullIntoDescriptor(controller, bytesWritten, pullIntoDescriptor); + if (pullIntoDescriptor.bytesFilled < pullIntoDescriptor.elementSize) { + return; + } + ReadableByteStreamControllerShiftPendingPullInto(controller); + const remainderSize = pullIntoDescriptor.bytesFilled % pullIntoDescriptor.elementSize; + if (remainderSize > 0) { + const end = pullIntoDescriptor.byteOffset + pullIntoDescriptor.bytesFilled; + const remainder = ArrayBufferSlice(pullIntoDescriptor.buffer, end - remainderSize, end); + ReadableByteStreamControllerEnqueueChunkToQueue(controller, remainder, 0, remainder.byteLength); + } + pullIntoDescriptor.bytesFilled -= remainderSize; + ReadableByteStreamControllerCommitPullIntoDescriptor(controller._controlledReadableByteStream, pullIntoDescriptor); + ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller); + } + function ReadableByteStreamControllerRespondInternal(controller, bytesWritten) { + const firstDescriptor = controller._pendingPullIntos.peek(); + ReadableByteStreamControllerInvalidateBYOBRequest(controller); + const state = controller._controlledReadableByteStream._state; + if (state === 'closed') { + ReadableByteStreamControllerRespondInClosedState(controller); + } + else { + ReadableByteStreamControllerRespondInReadableState(controller, bytesWritten, firstDescriptor); + } + ReadableByteStreamControllerCallPullIfNeeded(controller); + } + function ReadableByteStreamControllerShiftPendingPullInto(controller) { + const descriptor = controller._pendingPullIntos.shift(); + return descriptor; + } + function ReadableByteStreamControllerShouldCallPull(controller) { + const stream = controller._controlledReadableByteStream; + if (stream._state !== 'readable') { + return false; + } + if (controller._closeRequested) { + return false; + } + if (!controller._started) { + return false; + } + if (ReadableStreamHasDefaultReader(stream) && ReadableStreamGetNumReadRequests(stream) > 0) { + return true; + } + if (ReadableStreamHasBYOBReader(stream) && ReadableStreamGetNumReadIntoRequests(stream) > 0) { + return true; + } + const desiredSize = ReadableByteStreamControllerGetDesiredSize(controller); + if (desiredSize > 0) { + return true; + } + return false; + } + function ReadableByteStreamControllerClearAlgorithms(controller) { + controller._pullAlgorithm = undefined; + controller._cancelAlgorithm = undefined; + } + // A client of ReadableByteStreamController may use these functions directly to bypass state check. + function ReadableByteStreamControllerClose(controller) { + const stream = controller._controlledReadableByteStream; + if (controller._closeRequested || stream._state !== 'readable') { + return; + } + if (controller._queueTotalSize > 0) { + controller._closeRequested = true; + return; + } + if (controller._pendingPullIntos.length > 0) { + const firstPendingPullInto = controller._pendingPullIntos.peek(); + if (firstPendingPullInto.bytesFilled > 0) { + const e = new TypeError('Insufficient bytes to fill elements in the given buffer'); + ReadableByteStreamControllerError(controller, e); + throw e; + } + } + ReadableByteStreamControllerClearAlgorithms(controller); + ReadableStreamClose(stream); + } + function ReadableByteStreamControllerEnqueue(controller, chunk) { + const stream = controller._controlledReadableByteStream; + if (controller._closeRequested || stream._state !== 'readable') { + return; + } + const buffer = chunk.buffer; + const byteOffset = chunk.byteOffset; + const byteLength = chunk.byteLength; + const transferredBuffer = TransferArrayBuffer(buffer); + if (controller._pendingPullIntos.length > 0) { + const firstPendingPullInto = controller._pendingPullIntos.peek(); + if (IsDetachedBuffer(firstPendingPullInto.buffer)) ; + firstPendingPullInto.buffer = TransferArrayBuffer(firstPendingPullInto.buffer); + } + ReadableByteStreamControllerInvalidateBYOBRequest(controller); + if (ReadableStreamHasDefaultReader(stream)) { + if (ReadableStreamGetNumReadRequests(stream) === 0) { + ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength); + } + else { + if (controller._pendingPullIntos.length > 0) { + ReadableByteStreamControllerShiftPendingPullInto(controller); + } + const transferredView = new Uint8Array(transferredBuffer, byteOffset, byteLength); + ReadableStreamFulfillReadRequest(stream, transferredView, false); + } + } + else if (ReadableStreamHasBYOBReader(stream)) { + // TODO: Ideally in this branch detaching should happen only if the buffer is not consumed fully. + ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength); + ReadableByteStreamControllerProcessPullIntoDescriptorsUsingQueue(controller); + } + else { + ReadableByteStreamControllerEnqueueChunkToQueue(controller, transferredBuffer, byteOffset, byteLength); + } + ReadableByteStreamControllerCallPullIfNeeded(controller); + } + function ReadableByteStreamControllerError(controller, e) { + const stream = controller._controlledReadableByteStream; + if (stream._state !== 'readable') { + return; + } + ReadableByteStreamControllerClearPendingPullIntos(controller); + ResetQueue(controller); + ReadableByteStreamControllerClearAlgorithms(controller); + ReadableStreamError(stream, e); + } + function ReadableByteStreamControllerGetBYOBRequest(controller) { + if (controller._byobRequest === null && controller._pendingPullIntos.length > 0) { + const firstDescriptor = controller._pendingPullIntos.peek(); + const view = new Uint8Array(firstDescriptor.buffer, firstDescriptor.byteOffset + firstDescriptor.bytesFilled, firstDescriptor.byteLength - firstDescriptor.bytesFilled); + const byobRequest = Object.create(ReadableStreamBYOBRequest.prototype); + SetUpReadableStreamBYOBRequest(byobRequest, controller, view); + controller._byobRequest = byobRequest; + } + return controller._byobRequest; + } + function ReadableByteStreamControllerGetDesiredSize(controller) { + const state = controller._controlledReadableByteStream._state; + if (state === 'errored') { + return null; + } + if (state === 'closed') { + return 0; + } + return controller._strategyHWM - controller._queueTotalSize; + } + function ReadableByteStreamControllerRespond(controller, bytesWritten) { + const firstDescriptor = controller._pendingPullIntos.peek(); + const state = controller._controlledReadableByteStream._state; + if (state === 'closed') { + if (bytesWritten !== 0) { + throw new TypeError('bytesWritten must be 0 when calling respond() on a closed stream'); + } + } + else { + if (bytesWritten === 0) { + throw new TypeError('bytesWritten must be greater than 0 when calling respond() on a readable stream'); + } + if (firstDescriptor.bytesFilled + bytesWritten > firstDescriptor.byteLength) { + throw new RangeError('bytesWritten out of range'); + } + } + firstDescriptor.buffer = TransferArrayBuffer(firstDescriptor.buffer); + ReadableByteStreamControllerRespondInternal(controller, bytesWritten); + } + function ReadableByteStreamControllerRespondWithNewView(controller, view) { + const firstDescriptor = controller._pendingPullIntos.peek(); + const state = controller._controlledReadableByteStream._state; + if (state === 'closed') { + if (view.byteLength !== 0) { + throw new TypeError('The view\'s length must be 0 when calling respondWithNewView() on a closed stream'); + } + } + else { + if (view.byteLength === 0) { + throw new TypeError('The view\'s length must be greater than 0 when calling respondWithNewView() on a readable stream'); + } + } + if (firstDescriptor.byteOffset + firstDescriptor.bytesFilled !== view.byteOffset) { + throw new RangeError('The region specified by view does not match byobRequest'); + } + if (firstDescriptor.bufferByteLength !== view.buffer.byteLength) { + throw new RangeError('The buffer of view has different capacity than byobRequest'); + } + if (firstDescriptor.bytesFilled + view.byteLength > firstDescriptor.byteLength) { + throw new RangeError('The region specified by view is larger than byobRequest'); + } + const viewByteLength = view.byteLength; + firstDescriptor.buffer = TransferArrayBuffer(view.buffer); + ReadableByteStreamControllerRespondInternal(controller, viewByteLength); + } + function SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize) { + controller._controlledReadableByteStream = stream; + controller._pullAgain = false; + controller._pulling = false; + controller._byobRequest = null; + // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly. + controller._queue = controller._queueTotalSize = undefined; + ResetQueue(controller); + controller._closeRequested = false; + controller._started = false; + controller._strategyHWM = highWaterMark; + controller._pullAlgorithm = pullAlgorithm; + controller._cancelAlgorithm = cancelAlgorithm; + controller._autoAllocateChunkSize = autoAllocateChunkSize; + controller._pendingPullIntos = new SimpleQueue(); + stream._readableStreamController = controller; + const startResult = startAlgorithm(); + uponPromise(promiseResolvedWith(startResult), () => { + controller._started = true; + ReadableByteStreamControllerCallPullIfNeeded(controller); + }, r => { + ReadableByteStreamControllerError(controller, r); + }); + } + function SetUpReadableByteStreamControllerFromUnderlyingSource(stream, underlyingByteSource, highWaterMark) { + const controller = Object.create(ReadableByteStreamController.prototype); + let startAlgorithm = () => undefined; + let pullAlgorithm = () => promiseResolvedWith(undefined); + let cancelAlgorithm = () => promiseResolvedWith(undefined); + if (underlyingByteSource.start !== undefined) { + startAlgorithm = () => underlyingByteSource.start(controller); + } + if (underlyingByteSource.pull !== undefined) { + pullAlgorithm = () => underlyingByteSource.pull(controller); + } + if (underlyingByteSource.cancel !== undefined) { + cancelAlgorithm = reason => underlyingByteSource.cancel(reason); + } + const autoAllocateChunkSize = underlyingByteSource.autoAllocateChunkSize; + if (autoAllocateChunkSize === 0) { + throw new TypeError('autoAllocateChunkSize must be greater than 0'); + } + SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, autoAllocateChunkSize); + } + function SetUpReadableStreamBYOBRequest(request, controller, view) { + request._associatedReadableByteStreamController = controller; + request._view = view; + } + // Helper functions for the ReadableStreamBYOBRequest. + function byobRequestBrandCheckException(name) { + return new TypeError(`ReadableStreamBYOBRequest.prototype.${name} can only be used on a ReadableStreamBYOBRequest`); + } + // Helper functions for the ReadableByteStreamController. + function byteStreamControllerBrandCheckException(name) { + return new TypeError(`ReadableByteStreamController.prototype.${name} can only be used on a ReadableByteStreamController`); + } + + // Abstract operations for the ReadableStream. + function AcquireReadableStreamBYOBReader(stream) { + return new ReadableStreamBYOBReader(stream); + } + // ReadableStream API exposed for controllers. + function ReadableStreamAddReadIntoRequest(stream, readIntoRequest) { + stream._reader._readIntoRequests.push(readIntoRequest); + } + function ReadableStreamFulfillReadIntoRequest(stream, chunk, done) { + const reader = stream._reader; + const readIntoRequest = reader._readIntoRequests.shift(); + if (done) { + readIntoRequest._closeSteps(chunk); + } + else { + readIntoRequest._chunkSteps(chunk); + } + } + function ReadableStreamGetNumReadIntoRequests(stream) { + return stream._reader._readIntoRequests.length; + } + function ReadableStreamHasBYOBReader(stream) { + const reader = stream._reader; + if (reader === undefined) { + return false; + } + if (!IsReadableStreamBYOBReader(reader)) { + return false; + } + return true; + } + /** + * A BYOB reader vended by a {@link ReadableStream}. + * + * @public + */ + class ReadableStreamBYOBReader { + constructor(stream) { + assertRequiredArgument(stream, 1, 'ReadableStreamBYOBReader'); + assertReadableStream(stream, 'First parameter'); + if (IsReadableStreamLocked(stream)) { + throw new TypeError('This stream has already been locked for exclusive reading by another reader'); + } + if (!IsReadableByteStreamController(stream._readableStreamController)) { + throw new TypeError('Cannot construct a ReadableStreamBYOBReader for a stream not constructed with a byte ' + + 'source'); + } + ReadableStreamReaderGenericInitialize(this, stream); + this._readIntoRequests = new SimpleQueue(); + } + /** + * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or + * the reader's lock is released before the stream finishes closing. + */ + get closed() { + if (!IsReadableStreamBYOBReader(this)) { + return promiseRejectedWith(byobReaderBrandCheckException('closed')); + } + return this._closedPromise; + } + /** + * If the reader is active, behaves the same as {@link ReadableStream.cancel | stream.cancel(reason)}. + */ + cancel(reason = undefined) { + if (!IsReadableStreamBYOBReader(this)) { + return promiseRejectedWith(byobReaderBrandCheckException('cancel')); + } + if (this._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('cancel')); + } + return ReadableStreamReaderGenericCancel(this, reason); + } + /** + * Attempts to reads bytes into view, and returns a promise resolved with the result. + * + * If reading a chunk causes the queue to become empty, more data will be pulled from the underlying source. + */ + read(view) { + if (!IsReadableStreamBYOBReader(this)) { + return promiseRejectedWith(byobReaderBrandCheckException('read')); + } + if (!ArrayBuffer.isView(view)) { + return promiseRejectedWith(new TypeError('view must be an array buffer view')); + } + if (view.byteLength === 0) { + return promiseRejectedWith(new TypeError('view must have non-zero byteLength')); + } + if (view.buffer.byteLength === 0) { + return promiseRejectedWith(new TypeError(`view's buffer must have non-zero byteLength`)); + } + if (IsDetachedBuffer(view.buffer)) ; + if (this._ownerReadableStream === undefined) { + return promiseRejectedWith(readerLockException('read from')); + } + let resolvePromise; + let rejectPromise; + const promise = newPromise((resolve, reject) => { + resolvePromise = resolve; + rejectPromise = reject; + }); + const readIntoRequest = { + _chunkSteps: chunk => resolvePromise({ value: chunk, done: false }), + _closeSteps: chunk => resolvePromise({ value: chunk, done: true }), + _errorSteps: e => rejectPromise(e) + }; + ReadableStreamBYOBReaderRead(this, view, readIntoRequest); + return promise; + } + /** + * Releases the reader's lock on the corresponding stream. After the lock is released, the reader is no longer active. + * If the associated stream is errored when the lock is released, the reader will appear errored in the same way + * from now on; otherwise, the reader will appear closed. + * + * A reader's lock cannot be released while it still has a pending read request, i.e., if a promise returned by + * the reader's {@link ReadableStreamBYOBReader.read | read()} method has not yet been settled. Attempting to + * do so will throw a `TypeError` and leave the reader locked to the stream. + */ + releaseLock() { + if (!IsReadableStreamBYOBReader(this)) { + throw byobReaderBrandCheckException('releaseLock'); + } + if (this._ownerReadableStream === undefined) { + return; + } + if (this._readIntoRequests.length > 0) { + throw new TypeError('Tried to release a reader lock when that reader has pending read() calls un-settled'); + } + ReadableStreamReaderGenericRelease(this); + } + } + Object.defineProperties(ReadableStreamBYOBReader.prototype, { + cancel: { enumerable: true }, + read: { enumerable: true }, + releaseLock: { enumerable: true }, + closed: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableStreamBYOBReader.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableStreamBYOBReader', + configurable: true + }); + } + // Abstract operations for the readers. + function IsReadableStreamBYOBReader(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_readIntoRequests')) { + return false; + } + return x instanceof ReadableStreamBYOBReader; + } + function ReadableStreamBYOBReaderRead(reader, view, readIntoRequest) { + const stream = reader._ownerReadableStream; + stream._disturbed = true; + if (stream._state === 'errored') { + readIntoRequest._errorSteps(stream._storedError); + } + else { + ReadableByteStreamControllerPullInto(stream._readableStreamController, view, readIntoRequest); + } + } + // Helper functions for the ReadableStreamBYOBReader. + function byobReaderBrandCheckException(name) { + return new TypeError(`ReadableStreamBYOBReader.prototype.${name} can only be used on a ReadableStreamBYOBReader`); + } + + function ExtractHighWaterMark(strategy, defaultHWM) { + const { highWaterMark } = strategy; + if (highWaterMark === undefined) { + return defaultHWM; + } + if (NumberIsNaN(highWaterMark) || highWaterMark < 0) { + throw new RangeError('Invalid highWaterMark'); + } + return highWaterMark; + } + function ExtractSizeAlgorithm(strategy) { + const { size } = strategy; + if (!size) { + return () => 1; + } + return size; + } + + function convertQueuingStrategy(init, context) { + assertDictionary(init, context); + const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark; + const size = init === null || init === void 0 ? void 0 : init.size; + return { + highWaterMark: highWaterMark === undefined ? undefined : convertUnrestrictedDouble(highWaterMark), + size: size === undefined ? undefined : convertQueuingStrategySize(size, `${context} has member 'size' that`) + }; + } + function convertQueuingStrategySize(fn, context) { + assertFunction(fn, context); + return chunk => convertUnrestrictedDouble(fn(chunk)); + } + + function convertUnderlyingSink(original, context) { + assertDictionary(original, context); + const abort = original === null || original === void 0 ? void 0 : original.abort; + const close = original === null || original === void 0 ? void 0 : original.close; + const start = original === null || original === void 0 ? void 0 : original.start; + const type = original === null || original === void 0 ? void 0 : original.type; + const write = original === null || original === void 0 ? void 0 : original.write; + return { + abort: abort === undefined ? + undefined : + convertUnderlyingSinkAbortCallback(abort, original, `${context} has member 'abort' that`), + close: close === undefined ? + undefined : + convertUnderlyingSinkCloseCallback(close, original, `${context} has member 'close' that`), + start: start === undefined ? + undefined : + convertUnderlyingSinkStartCallback(start, original, `${context} has member 'start' that`), + write: write === undefined ? + undefined : + convertUnderlyingSinkWriteCallback(write, original, `${context} has member 'write' that`), + type + }; + } + function convertUnderlyingSinkAbortCallback(fn, original, context) { + assertFunction(fn, context); + return (reason) => promiseCall(fn, original, [reason]); + } + function convertUnderlyingSinkCloseCallback(fn, original, context) { + assertFunction(fn, context); + return () => promiseCall(fn, original, []); + } + function convertUnderlyingSinkStartCallback(fn, original, context) { + assertFunction(fn, context); + return (controller) => reflectCall(fn, original, [controller]); + } + function convertUnderlyingSinkWriteCallback(fn, original, context) { + assertFunction(fn, context); + return (chunk, controller) => promiseCall(fn, original, [chunk, controller]); + } + + function assertWritableStream(x, context) { + if (!IsWritableStream(x)) { + throw new TypeError(`${context} is not a WritableStream.`); + } + } + + function isAbortSignal(value) { + if (typeof value !== 'object' || value === null) { + return false; + } + try { + return typeof value.aborted === 'boolean'; + } + catch (_a) { + // AbortSignal.prototype.aborted throws if its brand check fails + return false; + } + } + const supportsAbortController = typeof AbortController === 'function'; + /** + * Construct a new AbortController, if supported by the platform. + * + * @internal + */ + function createAbortController() { + if (supportsAbortController) { + return new AbortController(); + } + return undefined; + } + + /** + * A writable stream represents a destination for data, into which you can write. + * + * @public + */ + class WritableStream { + constructor(rawUnderlyingSink = {}, rawStrategy = {}) { + if (rawUnderlyingSink === undefined) { + rawUnderlyingSink = null; + } + else { + assertObject(rawUnderlyingSink, 'First parameter'); + } + const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter'); + const underlyingSink = convertUnderlyingSink(rawUnderlyingSink, 'First parameter'); + InitializeWritableStream(this); + const type = underlyingSink.type; + if (type !== undefined) { + throw new RangeError('Invalid type is specified'); + } + const sizeAlgorithm = ExtractSizeAlgorithm(strategy); + const highWaterMark = ExtractHighWaterMark(strategy, 1); + SetUpWritableStreamDefaultControllerFromUnderlyingSink(this, underlyingSink, highWaterMark, sizeAlgorithm); + } + /** + * Returns whether or not the writable stream is locked to a writer. + */ + get locked() { + if (!IsWritableStream(this)) { + throw streamBrandCheckException$2('locked'); + } + return IsWritableStreamLocked(this); + } + /** + * Aborts the stream, signaling that the producer can no longer successfully write to the stream and it is to be + * immediately moved to an errored state, with any queued-up writes discarded. This will also execute any abort + * mechanism of the underlying sink. + * + * The returned promise will fulfill if the stream shuts down successfully, or reject if the underlying sink signaled + * that there was an error doing so. Additionally, it will reject with a `TypeError` (without attempting to cancel + * the stream) if the stream is currently locked. + */ + abort(reason = undefined) { + if (!IsWritableStream(this)) { + return promiseRejectedWith(streamBrandCheckException$2('abort')); + } + if (IsWritableStreamLocked(this)) { + return promiseRejectedWith(new TypeError('Cannot abort a stream that already has a writer')); + } + return WritableStreamAbort(this, reason); + } + /** + * Closes the stream. The underlying sink will finish processing any previously-written chunks, before invoking its + * close behavior. During this time any further attempts to write will fail (without erroring the stream). + * + * The method returns a promise that will fulfill if all remaining chunks are successfully written and the stream + * successfully closes, or rejects if an error is encountered during this process. Additionally, it will reject with + * a `TypeError` (without attempting to cancel the stream) if the stream is currently locked. + */ + close() { + if (!IsWritableStream(this)) { + return promiseRejectedWith(streamBrandCheckException$2('close')); + } + if (IsWritableStreamLocked(this)) { + return promiseRejectedWith(new TypeError('Cannot close a stream that already has a writer')); + } + if (WritableStreamCloseQueuedOrInFlight(this)) { + return promiseRejectedWith(new TypeError('Cannot close an already-closing stream')); + } + return WritableStreamClose(this); + } + /** + * Creates a {@link WritableStreamDefaultWriter | writer} and locks the stream to the new writer. While the stream + * is locked, no other writer can be acquired until this one is released. + * + * This functionality is especially useful for creating abstractions that desire the ability to write to a stream + * without interruption or interleaving. By getting a writer for the stream, you can ensure nobody else can write at + * the same time, which would cause the resulting written data to be unpredictable and probably useless. + */ + getWriter() { + if (!IsWritableStream(this)) { + throw streamBrandCheckException$2('getWriter'); + } + return AcquireWritableStreamDefaultWriter(this); + } + } + Object.defineProperties(WritableStream.prototype, { + abort: { enumerable: true }, + close: { enumerable: true }, + getWriter: { enumerable: true }, + locked: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(WritableStream.prototype, SymbolPolyfill.toStringTag, { + value: 'WritableStream', + configurable: true + }); + } + // Abstract operations for the WritableStream. + function AcquireWritableStreamDefaultWriter(stream) { + return new WritableStreamDefaultWriter(stream); + } + // Throws if and only if startAlgorithm throws. + function CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) { + const stream = Object.create(WritableStream.prototype); + InitializeWritableStream(stream); + const controller = Object.create(WritableStreamDefaultController.prototype); + SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm); + return stream; + } + function InitializeWritableStream(stream) { + stream._state = 'writable'; + // The error that will be reported by new method calls once the state becomes errored. Only set when [[state]] is + // 'erroring' or 'errored'. May be set to an undefined value. + stream._storedError = undefined; + stream._writer = undefined; + // Initialize to undefined first because the constructor of the controller checks this + // variable to validate the caller. + stream._writableStreamController = undefined; + // This queue is placed here instead of the writer class in order to allow for passing a writer to the next data + // producer without waiting for the queued writes to finish. + stream._writeRequests = new SimpleQueue(); + // Write requests are removed from _writeRequests when write() is called on the underlying sink. This prevents + // them from being erroneously rejected on error. If a write() call is in-flight, the request is stored here. + stream._inFlightWriteRequest = undefined; + // The promise that was returned from writer.close(). Stored here because it may be fulfilled after the writer + // has been detached. + stream._closeRequest = undefined; + // Close request is removed from _closeRequest when close() is called on the underlying sink. This prevents it + // from being erroneously rejected on error. If a close() call is in-flight, the request is stored here. + stream._inFlightCloseRequest = undefined; + // The promise that was returned from writer.abort(). This may also be fulfilled after the writer has detached. + stream._pendingAbortRequest = undefined; + // The backpressure signal set by the controller. + stream._backpressure = false; + } + function IsWritableStream(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_writableStreamController')) { + return false; + } + return x instanceof WritableStream; + } + function IsWritableStreamLocked(stream) { + if (stream._writer === undefined) { + return false; + } + return true; + } + function WritableStreamAbort(stream, reason) { + var _a; + if (stream._state === 'closed' || stream._state === 'errored') { + return promiseResolvedWith(undefined); + } + stream._writableStreamController._abortReason = reason; + (_a = stream._writableStreamController._abortController) === null || _a === void 0 ? void 0 : _a.abort(); + // TypeScript narrows the type of `stream._state` down to 'writable' | 'erroring', + // but it doesn't know that signaling abort runs author code that might have changed the state. + // Widen the type again by casting to WritableStreamState. + const state = stream._state; + if (state === 'closed' || state === 'errored') { + return promiseResolvedWith(undefined); + } + if (stream._pendingAbortRequest !== undefined) { + return stream._pendingAbortRequest._promise; + } + let wasAlreadyErroring = false; + if (state === 'erroring') { + wasAlreadyErroring = true; + // reason will not be used, so don't keep a reference to it. + reason = undefined; + } + const promise = newPromise((resolve, reject) => { + stream._pendingAbortRequest = { + _promise: undefined, + _resolve: resolve, + _reject: reject, + _reason: reason, + _wasAlreadyErroring: wasAlreadyErroring + }; + }); + stream._pendingAbortRequest._promise = promise; + if (!wasAlreadyErroring) { + WritableStreamStartErroring(stream, reason); + } + return promise; + } + function WritableStreamClose(stream) { + const state = stream._state; + if (state === 'closed' || state === 'errored') { + return promiseRejectedWith(new TypeError(`The stream (in ${state} state) is not in the writable state and cannot be closed`)); + } + const promise = newPromise((resolve, reject) => { + const closeRequest = { + _resolve: resolve, + _reject: reject + }; + stream._closeRequest = closeRequest; + }); + const writer = stream._writer; + if (writer !== undefined && stream._backpressure && state === 'writable') { + defaultWriterReadyPromiseResolve(writer); + } + WritableStreamDefaultControllerClose(stream._writableStreamController); + return promise; + } + // WritableStream API exposed for controllers. + function WritableStreamAddWriteRequest(stream) { + const promise = newPromise((resolve, reject) => { + const writeRequest = { + _resolve: resolve, + _reject: reject + }; + stream._writeRequests.push(writeRequest); + }); + return promise; + } + function WritableStreamDealWithRejection(stream, error) { + const state = stream._state; + if (state === 'writable') { + WritableStreamStartErroring(stream, error); + return; + } + WritableStreamFinishErroring(stream); + } + function WritableStreamStartErroring(stream, reason) { + const controller = stream._writableStreamController; + stream._state = 'erroring'; + stream._storedError = reason; + const writer = stream._writer; + if (writer !== undefined) { + WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, reason); + } + if (!WritableStreamHasOperationMarkedInFlight(stream) && controller._started) { + WritableStreamFinishErroring(stream); + } + } + function WritableStreamFinishErroring(stream) { + stream._state = 'errored'; + stream._writableStreamController[ErrorSteps](); + const storedError = stream._storedError; + stream._writeRequests.forEach(writeRequest => { + writeRequest._reject(storedError); + }); + stream._writeRequests = new SimpleQueue(); + if (stream._pendingAbortRequest === undefined) { + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + return; + } + const abortRequest = stream._pendingAbortRequest; + stream._pendingAbortRequest = undefined; + if (abortRequest._wasAlreadyErroring) { + abortRequest._reject(storedError); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + return; + } + const promise = stream._writableStreamController[AbortSteps](abortRequest._reason); + uponPromise(promise, () => { + abortRequest._resolve(); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + }, (reason) => { + abortRequest._reject(reason); + WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream); + }); + } + function WritableStreamFinishInFlightWrite(stream) { + stream._inFlightWriteRequest._resolve(undefined); + stream._inFlightWriteRequest = undefined; + } + function WritableStreamFinishInFlightWriteWithError(stream, error) { + stream._inFlightWriteRequest._reject(error); + stream._inFlightWriteRequest = undefined; + WritableStreamDealWithRejection(stream, error); + } + function WritableStreamFinishInFlightClose(stream) { + stream._inFlightCloseRequest._resolve(undefined); + stream._inFlightCloseRequest = undefined; + const state = stream._state; + if (state === 'erroring') { + // The error was too late to do anything, so it is ignored. + stream._storedError = undefined; + if (stream._pendingAbortRequest !== undefined) { + stream._pendingAbortRequest._resolve(); + stream._pendingAbortRequest = undefined; + } + } + stream._state = 'closed'; + const writer = stream._writer; + if (writer !== undefined) { + defaultWriterClosedPromiseResolve(writer); + } + } + function WritableStreamFinishInFlightCloseWithError(stream, error) { + stream._inFlightCloseRequest._reject(error); + stream._inFlightCloseRequest = undefined; + // Never execute sink abort() after sink close(). + if (stream._pendingAbortRequest !== undefined) { + stream._pendingAbortRequest._reject(error); + stream._pendingAbortRequest = undefined; + } + WritableStreamDealWithRejection(stream, error); + } + // TODO(ricea): Fix alphabetical order. + function WritableStreamCloseQueuedOrInFlight(stream) { + if (stream._closeRequest === undefined && stream._inFlightCloseRequest === undefined) { + return false; + } + return true; + } + function WritableStreamHasOperationMarkedInFlight(stream) { + if (stream._inFlightWriteRequest === undefined && stream._inFlightCloseRequest === undefined) { + return false; + } + return true; + } + function WritableStreamMarkCloseRequestInFlight(stream) { + stream._inFlightCloseRequest = stream._closeRequest; + stream._closeRequest = undefined; + } + function WritableStreamMarkFirstWriteRequestInFlight(stream) { + stream._inFlightWriteRequest = stream._writeRequests.shift(); + } + function WritableStreamRejectCloseAndClosedPromiseIfNeeded(stream) { + if (stream._closeRequest !== undefined) { + stream._closeRequest._reject(stream._storedError); + stream._closeRequest = undefined; + } + const writer = stream._writer; + if (writer !== undefined) { + defaultWriterClosedPromiseReject(writer, stream._storedError); + } + } + function WritableStreamUpdateBackpressure(stream, backpressure) { + const writer = stream._writer; + if (writer !== undefined && backpressure !== stream._backpressure) { + if (backpressure) { + defaultWriterReadyPromiseReset(writer); + } + else { + defaultWriterReadyPromiseResolve(writer); + } + } + stream._backpressure = backpressure; + } + /** + * A default writer vended by a {@link WritableStream}. + * + * @public + */ + class WritableStreamDefaultWriter { + constructor(stream) { + assertRequiredArgument(stream, 1, 'WritableStreamDefaultWriter'); + assertWritableStream(stream, 'First parameter'); + if (IsWritableStreamLocked(stream)) { + throw new TypeError('This stream has already been locked for exclusive writing by another writer'); + } + this._ownerWritableStream = stream; + stream._writer = this; + const state = stream._state; + if (state === 'writable') { + if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._backpressure) { + defaultWriterReadyPromiseInitialize(this); + } + else { + defaultWriterReadyPromiseInitializeAsResolved(this); + } + defaultWriterClosedPromiseInitialize(this); + } + else if (state === 'erroring') { + defaultWriterReadyPromiseInitializeAsRejected(this, stream._storedError); + defaultWriterClosedPromiseInitialize(this); + } + else if (state === 'closed') { + defaultWriterReadyPromiseInitializeAsResolved(this); + defaultWriterClosedPromiseInitializeAsResolved(this); + } + else { + const storedError = stream._storedError; + defaultWriterReadyPromiseInitializeAsRejected(this, storedError); + defaultWriterClosedPromiseInitializeAsRejected(this, storedError); + } + } + /** + * Returns a promise that will be fulfilled when the stream becomes closed, or rejected if the stream ever errors or + * the writer’s lock is released before the stream finishes closing. + */ + get closed() { + if (!IsWritableStreamDefaultWriter(this)) { + return promiseRejectedWith(defaultWriterBrandCheckException('closed')); + } + return this._closedPromise; + } + /** + * Returns the desired size to fill the stream’s internal queue. It can be negative, if the queue is over-full. + * A producer can use this information to determine the right amount of data to write. + * + * It will be `null` if the stream cannot be successfully written to (due to either being errored, or having an abort + * queued up). It will return zero if the stream is closed. And the getter will throw an exception if invoked when + * the writer’s lock is released. + */ + get desiredSize() { + if (!IsWritableStreamDefaultWriter(this)) { + throw defaultWriterBrandCheckException('desiredSize'); + } + if (this._ownerWritableStream === undefined) { + throw defaultWriterLockException('desiredSize'); + } + return WritableStreamDefaultWriterGetDesiredSize(this); + } + /** + * Returns a promise that will be fulfilled when the desired size to fill the stream’s internal queue transitions + * from non-positive to positive, signaling that it is no longer applying backpressure. Once the desired size dips + * back to zero or below, the getter will return a new promise that stays pending until the next transition. + * + * If the stream becomes errored or aborted, or the writer’s lock is released, the returned promise will become + * rejected. + */ + get ready() { + if (!IsWritableStreamDefaultWriter(this)) { + return promiseRejectedWith(defaultWriterBrandCheckException('ready')); + } + return this._readyPromise; + } + /** + * If the reader is active, behaves the same as {@link WritableStream.abort | stream.abort(reason)}. + */ + abort(reason = undefined) { + if (!IsWritableStreamDefaultWriter(this)) { + return promiseRejectedWith(defaultWriterBrandCheckException('abort')); + } + if (this._ownerWritableStream === undefined) { + return promiseRejectedWith(defaultWriterLockException('abort')); + } + return WritableStreamDefaultWriterAbort(this, reason); + } + /** + * If the reader is active, behaves the same as {@link WritableStream.close | stream.close()}. + */ + close() { + if (!IsWritableStreamDefaultWriter(this)) { + return promiseRejectedWith(defaultWriterBrandCheckException('close')); + } + const stream = this._ownerWritableStream; + if (stream === undefined) { + return promiseRejectedWith(defaultWriterLockException('close')); + } + if (WritableStreamCloseQueuedOrInFlight(stream)) { + return promiseRejectedWith(new TypeError('Cannot close an already-closing stream')); + } + return WritableStreamDefaultWriterClose(this); + } + /** + * Releases the writer’s lock on the corresponding stream. After the lock is released, the writer is no longer active. + * If the associated stream is errored when the lock is released, the writer will appear errored in the same way from + * now on; otherwise, the writer will appear closed. + * + * Note that the lock can still be released even if some ongoing writes have not yet finished (i.e. even if the + * promises returned from previous calls to {@link WritableStreamDefaultWriter.write | write()} have not yet settled). + * It’s not necessary to hold the lock on the writer for the duration of the write; the lock instead simply prevents + * other producers from writing in an interleaved manner. + */ + releaseLock() { + if (!IsWritableStreamDefaultWriter(this)) { + throw defaultWriterBrandCheckException('releaseLock'); + } + const stream = this._ownerWritableStream; + if (stream === undefined) { + return; + } + WritableStreamDefaultWriterRelease(this); + } + write(chunk = undefined) { + if (!IsWritableStreamDefaultWriter(this)) { + return promiseRejectedWith(defaultWriterBrandCheckException('write')); + } + if (this._ownerWritableStream === undefined) { + return promiseRejectedWith(defaultWriterLockException('write to')); + } + return WritableStreamDefaultWriterWrite(this, chunk); + } + } + Object.defineProperties(WritableStreamDefaultWriter.prototype, { + abort: { enumerable: true }, + close: { enumerable: true }, + releaseLock: { enumerable: true }, + write: { enumerable: true }, + closed: { enumerable: true }, + desiredSize: { enumerable: true }, + ready: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(WritableStreamDefaultWriter.prototype, SymbolPolyfill.toStringTag, { + value: 'WritableStreamDefaultWriter', + configurable: true + }); + } + // Abstract operations for the WritableStreamDefaultWriter. + function IsWritableStreamDefaultWriter(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_ownerWritableStream')) { + return false; + } + return x instanceof WritableStreamDefaultWriter; + } + // A client of WritableStreamDefaultWriter may use these functions directly to bypass state check. + function WritableStreamDefaultWriterAbort(writer, reason) { + const stream = writer._ownerWritableStream; + return WritableStreamAbort(stream, reason); + } + function WritableStreamDefaultWriterClose(writer) { + const stream = writer._ownerWritableStream; + return WritableStreamClose(stream); + } + function WritableStreamDefaultWriterCloseWithErrorPropagation(writer) { + const stream = writer._ownerWritableStream; + const state = stream._state; + if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') { + return promiseResolvedWith(undefined); + } + if (state === 'errored') { + return promiseRejectedWith(stream._storedError); + } + return WritableStreamDefaultWriterClose(writer); + } + function WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, error) { + if (writer._closedPromiseState === 'pending') { + defaultWriterClosedPromiseReject(writer, error); + } + else { + defaultWriterClosedPromiseResetToRejected(writer, error); + } + } + function WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, error) { + if (writer._readyPromiseState === 'pending') { + defaultWriterReadyPromiseReject(writer, error); + } + else { + defaultWriterReadyPromiseResetToRejected(writer, error); + } + } + function WritableStreamDefaultWriterGetDesiredSize(writer) { + const stream = writer._ownerWritableStream; + const state = stream._state; + if (state === 'errored' || state === 'erroring') { + return null; + } + if (state === 'closed') { + return 0; + } + return WritableStreamDefaultControllerGetDesiredSize(stream._writableStreamController); + } + function WritableStreamDefaultWriterRelease(writer) { + const stream = writer._ownerWritableStream; + const releasedError = new TypeError(`Writer was released and can no longer be used to monitor the stream's closedness`); + WritableStreamDefaultWriterEnsureReadyPromiseRejected(writer, releasedError); + // The state transitions to "errored" before the sink abort() method runs, but the writer.closed promise is not + // rejected until afterwards. This means that simply testing state will not work. + WritableStreamDefaultWriterEnsureClosedPromiseRejected(writer, releasedError); + stream._writer = undefined; + writer._ownerWritableStream = undefined; + } + function WritableStreamDefaultWriterWrite(writer, chunk) { + const stream = writer._ownerWritableStream; + const controller = stream._writableStreamController; + const chunkSize = WritableStreamDefaultControllerGetChunkSize(controller, chunk); + if (stream !== writer._ownerWritableStream) { + return promiseRejectedWith(defaultWriterLockException('write to')); + } + const state = stream._state; + if (state === 'errored') { + return promiseRejectedWith(stream._storedError); + } + if (WritableStreamCloseQueuedOrInFlight(stream) || state === 'closed') { + return promiseRejectedWith(new TypeError('The stream is closing or closed and cannot be written to')); + } + if (state === 'erroring') { + return promiseRejectedWith(stream._storedError); + } + const promise = WritableStreamAddWriteRequest(stream); + WritableStreamDefaultControllerWrite(controller, chunk, chunkSize); + return promise; + } + const closeSentinel = {}; + /** + * Allows control of a {@link WritableStream | writable stream}'s state and internal queue. + * + * @public + */ + class WritableStreamDefaultController { + constructor() { + throw new TypeError('Illegal constructor'); + } + /** + * The reason which was passed to `WritableStream.abort(reason)` when the stream was aborted. + * + * @deprecated + * This property has been removed from the specification, see https://github.com/whatwg/streams/pull/1177. + * Use {@link WritableStreamDefaultController.signal}'s `reason` instead. + */ + get abortReason() { + if (!IsWritableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$2('abortReason'); + } + return this._abortReason; + } + /** + * An `AbortSignal` that can be used to abort the pending write or close operation when the stream is aborted. + */ + get signal() { + if (!IsWritableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$2('signal'); + } + if (this._abortController === undefined) { + // Older browsers or older Node versions may not support `AbortController` or `AbortSignal`. + // We don't want to bundle and ship an `AbortController` polyfill together with our polyfill, + // so instead we only implement support for `signal` if we find a global `AbortController` constructor. + throw new TypeError('WritableStreamDefaultController.prototype.signal is not supported'); + } + return this._abortController.signal; + } + /** + * Closes the controlled writable stream, making all future interactions with it fail with the given error `e`. + * + * This method is rarely used, since usually it suffices to return a rejected promise from one of the underlying + * sink's methods. However, it can be useful for suddenly shutting down a stream in response to an event outside the + * normal lifecycle of interactions with the underlying sink. + */ + error(e = undefined) { + if (!IsWritableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$2('error'); + } + const state = this._controlledWritableStream._state; + if (state !== 'writable') { + // The stream is closed, errored or will be soon. The sink can't do anything useful if it gets an error here, so + // just treat it as a no-op. + return; + } + WritableStreamDefaultControllerError(this, e); + } + /** @internal */ + [AbortSteps](reason) { + const result = this._abortAlgorithm(reason); + WritableStreamDefaultControllerClearAlgorithms(this); + return result; + } + /** @internal */ + [ErrorSteps]() { + ResetQueue(this); + } + } + Object.defineProperties(WritableStreamDefaultController.prototype, { + abortReason: { enumerable: true }, + signal: { enumerable: true }, + error: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(WritableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, { + value: 'WritableStreamDefaultController', + configurable: true + }); + } + // Abstract operations implementing interface required by the WritableStream. + function IsWritableStreamDefaultController(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_controlledWritableStream')) { + return false; + } + return x instanceof WritableStreamDefaultController; + } + function SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm) { + controller._controlledWritableStream = stream; + stream._writableStreamController = controller; + // Need to set the slots so that the assert doesn't fire. In the spec the slots already exist implicitly. + controller._queue = undefined; + controller._queueTotalSize = undefined; + ResetQueue(controller); + controller._abortReason = undefined; + controller._abortController = createAbortController(); + controller._started = false; + controller._strategySizeAlgorithm = sizeAlgorithm; + controller._strategyHWM = highWaterMark; + controller._writeAlgorithm = writeAlgorithm; + controller._closeAlgorithm = closeAlgorithm; + controller._abortAlgorithm = abortAlgorithm; + const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); + WritableStreamUpdateBackpressure(stream, backpressure); + const startResult = startAlgorithm(); + const startPromise = promiseResolvedWith(startResult); + uponPromise(startPromise, () => { + controller._started = true; + WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); + }, r => { + controller._started = true; + WritableStreamDealWithRejection(stream, r); + }); + } + function SetUpWritableStreamDefaultControllerFromUnderlyingSink(stream, underlyingSink, highWaterMark, sizeAlgorithm) { + const controller = Object.create(WritableStreamDefaultController.prototype); + let startAlgorithm = () => undefined; + let writeAlgorithm = () => promiseResolvedWith(undefined); + let closeAlgorithm = () => promiseResolvedWith(undefined); + let abortAlgorithm = () => promiseResolvedWith(undefined); + if (underlyingSink.start !== undefined) { + startAlgorithm = () => underlyingSink.start(controller); + } + if (underlyingSink.write !== undefined) { + writeAlgorithm = chunk => underlyingSink.write(chunk, controller); + } + if (underlyingSink.close !== undefined) { + closeAlgorithm = () => underlyingSink.close(); + } + if (underlyingSink.abort !== undefined) { + abortAlgorithm = reason => underlyingSink.abort(reason); + } + SetUpWritableStreamDefaultController(stream, controller, startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, highWaterMark, sizeAlgorithm); + } + // ClearAlgorithms may be called twice. Erroring the same stream in multiple ways will often result in redundant calls. + function WritableStreamDefaultControllerClearAlgorithms(controller) { + controller._writeAlgorithm = undefined; + controller._closeAlgorithm = undefined; + controller._abortAlgorithm = undefined; + controller._strategySizeAlgorithm = undefined; + } + function WritableStreamDefaultControllerClose(controller) { + EnqueueValueWithSize(controller, closeSentinel, 0); + WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); + } + function WritableStreamDefaultControllerGetChunkSize(controller, chunk) { + try { + return controller._strategySizeAlgorithm(chunk); + } + catch (chunkSizeE) { + WritableStreamDefaultControllerErrorIfNeeded(controller, chunkSizeE); + return 1; + } + } + function WritableStreamDefaultControllerGetDesiredSize(controller) { + return controller._strategyHWM - controller._queueTotalSize; + } + function WritableStreamDefaultControllerWrite(controller, chunk, chunkSize) { + try { + EnqueueValueWithSize(controller, chunk, chunkSize); + } + catch (enqueueE) { + WritableStreamDefaultControllerErrorIfNeeded(controller, enqueueE); + return; + } + const stream = controller._controlledWritableStream; + if (!WritableStreamCloseQueuedOrInFlight(stream) && stream._state === 'writable') { + const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); + WritableStreamUpdateBackpressure(stream, backpressure); + } + WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); + } + // Abstract operations for the WritableStreamDefaultController. + function WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller) { + const stream = controller._controlledWritableStream; + if (!controller._started) { + return; + } + if (stream._inFlightWriteRequest !== undefined) { + return; + } + const state = stream._state; + if (state === 'erroring') { + WritableStreamFinishErroring(stream); + return; + } + if (controller._queue.length === 0) { + return; + } + const value = PeekQueueValue(controller); + if (value === closeSentinel) { + WritableStreamDefaultControllerProcessClose(controller); + } + else { + WritableStreamDefaultControllerProcessWrite(controller, value); + } + } + function WritableStreamDefaultControllerErrorIfNeeded(controller, error) { + if (controller._controlledWritableStream._state === 'writable') { + WritableStreamDefaultControllerError(controller, error); + } + } + function WritableStreamDefaultControllerProcessClose(controller) { + const stream = controller._controlledWritableStream; + WritableStreamMarkCloseRequestInFlight(stream); + DequeueValue(controller); + const sinkClosePromise = controller._closeAlgorithm(); + WritableStreamDefaultControllerClearAlgorithms(controller); + uponPromise(sinkClosePromise, () => { + WritableStreamFinishInFlightClose(stream); + }, reason => { + WritableStreamFinishInFlightCloseWithError(stream, reason); + }); + } + function WritableStreamDefaultControllerProcessWrite(controller, chunk) { + const stream = controller._controlledWritableStream; + WritableStreamMarkFirstWriteRequestInFlight(stream); + const sinkWritePromise = controller._writeAlgorithm(chunk); + uponPromise(sinkWritePromise, () => { + WritableStreamFinishInFlightWrite(stream); + const state = stream._state; + DequeueValue(controller); + if (!WritableStreamCloseQueuedOrInFlight(stream) && state === 'writable') { + const backpressure = WritableStreamDefaultControllerGetBackpressure(controller); + WritableStreamUpdateBackpressure(stream, backpressure); + } + WritableStreamDefaultControllerAdvanceQueueIfNeeded(controller); + }, reason => { + if (stream._state === 'writable') { + WritableStreamDefaultControllerClearAlgorithms(controller); + } + WritableStreamFinishInFlightWriteWithError(stream, reason); + }); + } + function WritableStreamDefaultControllerGetBackpressure(controller) { + const desiredSize = WritableStreamDefaultControllerGetDesiredSize(controller); + return desiredSize <= 0; + } + // A client of WritableStreamDefaultController may use these functions directly to bypass state check. + function WritableStreamDefaultControllerError(controller, error) { + const stream = controller._controlledWritableStream; + WritableStreamDefaultControllerClearAlgorithms(controller); + WritableStreamStartErroring(stream, error); + } + // Helper functions for the WritableStream. + function streamBrandCheckException$2(name) { + return new TypeError(`WritableStream.prototype.${name} can only be used on a WritableStream`); + } + // Helper functions for the WritableStreamDefaultController. + function defaultControllerBrandCheckException$2(name) { + return new TypeError(`WritableStreamDefaultController.prototype.${name} can only be used on a WritableStreamDefaultController`); + } + // Helper functions for the WritableStreamDefaultWriter. + function defaultWriterBrandCheckException(name) { + return new TypeError(`WritableStreamDefaultWriter.prototype.${name} can only be used on a WritableStreamDefaultWriter`); + } + function defaultWriterLockException(name) { + return new TypeError('Cannot ' + name + ' a stream using a released writer'); + } + function defaultWriterClosedPromiseInitialize(writer) { + writer._closedPromise = newPromise((resolve, reject) => { + writer._closedPromise_resolve = resolve; + writer._closedPromise_reject = reject; + writer._closedPromiseState = 'pending'; + }); + } + function defaultWriterClosedPromiseInitializeAsRejected(writer, reason) { + defaultWriterClosedPromiseInitialize(writer); + defaultWriterClosedPromiseReject(writer, reason); + } + function defaultWriterClosedPromiseInitializeAsResolved(writer) { + defaultWriterClosedPromiseInitialize(writer); + defaultWriterClosedPromiseResolve(writer); + } + function defaultWriterClosedPromiseReject(writer, reason) { + if (writer._closedPromise_reject === undefined) { + return; + } + setPromiseIsHandledToTrue(writer._closedPromise); + writer._closedPromise_reject(reason); + writer._closedPromise_resolve = undefined; + writer._closedPromise_reject = undefined; + writer._closedPromiseState = 'rejected'; + } + function defaultWriterClosedPromiseResetToRejected(writer, reason) { + defaultWriterClosedPromiseInitializeAsRejected(writer, reason); + } + function defaultWriterClosedPromiseResolve(writer) { + if (writer._closedPromise_resolve === undefined) { + return; + } + writer._closedPromise_resolve(undefined); + writer._closedPromise_resolve = undefined; + writer._closedPromise_reject = undefined; + writer._closedPromiseState = 'resolved'; + } + function defaultWriterReadyPromiseInitialize(writer) { + writer._readyPromise = newPromise((resolve, reject) => { + writer._readyPromise_resolve = resolve; + writer._readyPromise_reject = reject; + }); + writer._readyPromiseState = 'pending'; + } + function defaultWriterReadyPromiseInitializeAsRejected(writer, reason) { + defaultWriterReadyPromiseInitialize(writer); + defaultWriterReadyPromiseReject(writer, reason); + } + function defaultWriterReadyPromiseInitializeAsResolved(writer) { + defaultWriterReadyPromiseInitialize(writer); + defaultWriterReadyPromiseResolve(writer); + } + function defaultWriterReadyPromiseReject(writer, reason) { + if (writer._readyPromise_reject === undefined) { + return; + } + setPromiseIsHandledToTrue(writer._readyPromise); + writer._readyPromise_reject(reason); + writer._readyPromise_resolve = undefined; + writer._readyPromise_reject = undefined; + writer._readyPromiseState = 'rejected'; + } + function defaultWriterReadyPromiseReset(writer) { + defaultWriterReadyPromiseInitialize(writer); + } + function defaultWriterReadyPromiseResetToRejected(writer, reason) { + defaultWriterReadyPromiseInitializeAsRejected(writer, reason); + } + function defaultWriterReadyPromiseResolve(writer) { + if (writer._readyPromise_resolve === undefined) { + return; + } + writer._readyPromise_resolve(undefined); + writer._readyPromise_resolve = undefined; + writer._readyPromise_reject = undefined; + writer._readyPromiseState = 'fulfilled'; + } + + /// <reference lib="dom" /> + const NativeDOMException = typeof DOMException !== 'undefined' ? DOMException : undefined; + + /// <reference types="node" /> + function isDOMExceptionConstructor(ctor) { + if (!(typeof ctor === 'function' || typeof ctor === 'object')) { + return false; + } + try { + new ctor(); + return true; + } + catch (_a) { + return false; + } + } + function createDOMExceptionPolyfill() { + // eslint-disable-next-line no-shadow + const ctor = function DOMException(message, name) { + this.message = message || ''; + this.name = name || 'Error'; + if (Error.captureStackTrace) { + Error.captureStackTrace(this, this.constructor); + } + }; + ctor.prototype = Object.create(Error.prototype); + Object.defineProperty(ctor.prototype, 'constructor', { value: ctor, writable: true, configurable: true }); + return ctor; + } + // eslint-disable-next-line no-redeclare + const DOMException$1 = isDOMExceptionConstructor(NativeDOMException) ? NativeDOMException : createDOMExceptionPolyfill(); + + function ReadableStreamPipeTo(source, dest, preventClose, preventAbort, preventCancel, signal) { + const reader = AcquireReadableStreamDefaultReader(source); + const writer = AcquireWritableStreamDefaultWriter(dest); + source._disturbed = true; + let shuttingDown = false; + // This is used to keep track of the spec's requirement that we wait for ongoing writes during shutdown. + let currentWrite = promiseResolvedWith(undefined); + return newPromise((resolve, reject) => { + let abortAlgorithm; + if (signal !== undefined) { + abortAlgorithm = () => { + const error = new DOMException$1('Aborted', 'AbortError'); + const actions = []; + if (!preventAbort) { + actions.push(() => { + if (dest._state === 'writable') { + return WritableStreamAbort(dest, error); + } + return promiseResolvedWith(undefined); + }); + } + if (!preventCancel) { + actions.push(() => { + if (source._state === 'readable') { + return ReadableStreamCancel(source, error); + } + return promiseResolvedWith(undefined); + }); + } + shutdownWithAction(() => Promise.all(actions.map(action => action())), true, error); + }; + if (signal.aborted) { + abortAlgorithm(); + return; + } + signal.addEventListener('abort', abortAlgorithm); + } + // Using reader and writer, read all chunks from this and write them to dest + // - Backpressure must be enforced + // - Shutdown must stop all activity + function pipeLoop() { + return newPromise((resolveLoop, rejectLoop) => { + function next(done) { + if (done) { + resolveLoop(); + } + else { + // Use `PerformPromiseThen` instead of `uponPromise` to avoid + // adding unnecessary `.catch(rethrowAssertionErrorRejection)` handlers + PerformPromiseThen(pipeStep(), next, rejectLoop); + } + } + next(false); + }); + } + function pipeStep() { + if (shuttingDown) { + return promiseResolvedWith(true); + } + return PerformPromiseThen(writer._readyPromise, () => { + return newPromise((resolveRead, rejectRead) => { + ReadableStreamDefaultReaderRead(reader, { + _chunkSteps: chunk => { + currentWrite = PerformPromiseThen(WritableStreamDefaultWriterWrite(writer, chunk), undefined, noop); + resolveRead(false); + }, + _closeSteps: () => resolveRead(true), + _errorSteps: rejectRead + }); + }); + }); + } + // Errors must be propagated forward + isOrBecomesErrored(source, reader._closedPromise, storedError => { + if (!preventAbort) { + shutdownWithAction(() => WritableStreamAbort(dest, storedError), true, storedError); + } + else { + shutdown(true, storedError); + } + }); + // Errors must be propagated backward + isOrBecomesErrored(dest, writer._closedPromise, storedError => { + if (!preventCancel) { + shutdownWithAction(() => ReadableStreamCancel(source, storedError), true, storedError); + } + else { + shutdown(true, storedError); + } + }); + // Closing must be propagated forward + isOrBecomesClosed(source, reader._closedPromise, () => { + if (!preventClose) { + shutdownWithAction(() => WritableStreamDefaultWriterCloseWithErrorPropagation(writer)); + } + else { + shutdown(); + } + }); + // Closing must be propagated backward + if (WritableStreamCloseQueuedOrInFlight(dest) || dest._state === 'closed') { + const destClosed = new TypeError('the destination writable stream closed before all data could be piped to it'); + if (!preventCancel) { + shutdownWithAction(() => ReadableStreamCancel(source, destClosed), true, destClosed); + } + else { + shutdown(true, destClosed); + } + } + setPromiseIsHandledToTrue(pipeLoop()); + function waitForWritesToFinish() { + // Another write may have started while we were waiting on this currentWrite, so we have to be sure to wait + // for that too. + const oldCurrentWrite = currentWrite; + return PerformPromiseThen(currentWrite, () => oldCurrentWrite !== currentWrite ? waitForWritesToFinish() : undefined); + } + function isOrBecomesErrored(stream, promise, action) { + if (stream._state === 'errored') { + action(stream._storedError); + } + else { + uponRejection(promise, action); + } + } + function isOrBecomesClosed(stream, promise, action) { + if (stream._state === 'closed') { + action(); + } + else { + uponFulfillment(promise, action); + } + } + function shutdownWithAction(action, originalIsError, originalError) { + if (shuttingDown) { + return; + } + shuttingDown = true; + if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) { + uponFulfillment(waitForWritesToFinish(), doTheRest); + } + else { + doTheRest(); + } + function doTheRest() { + uponPromise(action(), () => finalize(originalIsError, originalError), newError => finalize(true, newError)); + } + } + function shutdown(isError, error) { + if (shuttingDown) { + return; + } + shuttingDown = true; + if (dest._state === 'writable' && !WritableStreamCloseQueuedOrInFlight(dest)) { + uponFulfillment(waitForWritesToFinish(), () => finalize(isError, error)); + } + else { + finalize(isError, error); + } + } + function finalize(isError, error) { + WritableStreamDefaultWriterRelease(writer); + ReadableStreamReaderGenericRelease(reader); + if (signal !== undefined) { + signal.removeEventListener('abort', abortAlgorithm); + } + if (isError) { + reject(error); + } + else { + resolve(undefined); + } + } + }); + } + + /** + * Allows control of a {@link ReadableStream | readable stream}'s state and internal queue. + * + * @public + */ + class ReadableStreamDefaultController { + constructor() { + throw new TypeError('Illegal constructor'); + } + /** + * Returns the desired size to fill the controlled stream's internal queue. It can be negative, if the queue is + * over-full. An underlying source ought to use this information to determine when and how to apply backpressure. + */ + get desiredSize() { + if (!IsReadableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$1('desiredSize'); + } + return ReadableStreamDefaultControllerGetDesiredSize(this); + } + /** + * Closes the controlled readable stream. Consumers will still be able to read any previously-enqueued chunks from + * the stream, but once those are read, the stream will become closed. + */ + close() { + if (!IsReadableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$1('close'); + } + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) { + throw new TypeError('The stream is not in a state that permits close'); + } + ReadableStreamDefaultControllerClose(this); + } + enqueue(chunk = undefined) { + if (!IsReadableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$1('enqueue'); + } + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(this)) { + throw new TypeError('The stream is not in a state that permits enqueue'); + } + return ReadableStreamDefaultControllerEnqueue(this, chunk); + } + /** + * Errors the controlled readable stream, making all future interactions with it fail with the given error `e`. + */ + error(e = undefined) { + if (!IsReadableStreamDefaultController(this)) { + throw defaultControllerBrandCheckException$1('error'); + } + ReadableStreamDefaultControllerError(this, e); + } + /** @internal */ + [CancelSteps](reason) { + ResetQueue(this); + const result = this._cancelAlgorithm(reason); + ReadableStreamDefaultControllerClearAlgorithms(this); + return result; + } + /** @internal */ + [PullSteps](readRequest) { + const stream = this._controlledReadableStream; + if (this._queue.length > 0) { + const chunk = DequeueValue(this); + if (this._closeRequested && this._queue.length === 0) { + ReadableStreamDefaultControllerClearAlgorithms(this); + ReadableStreamClose(stream); + } + else { + ReadableStreamDefaultControllerCallPullIfNeeded(this); + } + readRequest._chunkSteps(chunk); + } + else { + ReadableStreamAddReadRequest(stream, readRequest); + ReadableStreamDefaultControllerCallPullIfNeeded(this); + } + } + } + Object.defineProperties(ReadableStreamDefaultController.prototype, { + close: { enumerable: true }, + enqueue: { enumerable: true }, + error: { enumerable: true }, + desiredSize: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableStreamDefaultController.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableStreamDefaultController', + configurable: true + }); + } + // Abstract operations for the ReadableStreamDefaultController. + function IsReadableStreamDefaultController(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_controlledReadableStream')) { + return false; + } + return x instanceof ReadableStreamDefaultController; + } + function ReadableStreamDefaultControllerCallPullIfNeeded(controller) { + const shouldPull = ReadableStreamDefaultControllerShouldCallPull(controller); + if (!shouldPull) { + return; + } + if (controller._pulling) { + controller._pullAgain = true; + return; + } + controller._pulling = true; + const pullPromise = controller._pullAlgorithm(); + uponPromise(pullPromise, () => { + controller._pulling = false; + if (controller._pullAgain) { + controller._pullAgain = false; + ReadableStreamDefaultControllerCallPullIfNeeded(controller); + } + }, e => { + ReadableStreamDefaultControllerError(controller, e); + }); + } + function ReadableStreamDefaultControllerShouldCallPull(controller) { + const stream = controller._controlledReadableStream; + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { + return false; + } + if (!controller._started) { + return false; + } + if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) { + return true; + } + const desiredSize = ReadableStreamDefaultControllerGetDesiredSize(controller); + if (desiredSize > 0) { + return true; + } + return false; + } + function ReadableStreamDefaultControllerClearAlgorithms(controller) { + controller._pullAlgorithm = undefined; + controller._cancelAlgorithm = undefined; + controller._strategySizeAlgorithm = undefined; + } + // A client of ReadableStreamDefaultController may use these functions directly to bypass state check. + function ReadableStreamDefaultControllerClose(controller) { + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { + return; + } + const stream = controller._controlledReadableStream; + controller._closeRequested = true; + if (controller._queue.length === 0) { + ReadableStreamDefaultControllerClearAlgorithms(controller); + ReadableStreamClose(stream); + } + } + function ReadableStreamDefaultControllerEnqueue(controller, chunk) { + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(controller)) { + return; + } + const stream = controller._controlledReadableStream; + if (IsReadableStreamLocked(stream) && ReadableStreamGetNumReadRequests(stream) > 0) { + ReadableStreamFulfillReadRequest(stream, chunk, false); + } + else { + let chunkSize; + try { + chunkSize = controller._strategySizeAlgorithm(chunk); + } + catch (chunkSizeE) { + ReadableStreamDefaultControllerError(controller, chunkSizeE); + throw chunkSizeE; + } + try { + EnqueueValueWithSize(controller, chunk, chunkSize); + } + catch (enqueueE) { + ReadableStreamDefaultControllerError(controller, enqueueE); + throw enqueueE; + } + } + ReadableStreamDefaultControllerCallPullIfNeeded(controller); + } + function ReadableStreamDefaultControllerError(controller, e) { + const stream = controller._controlledReadableStream; + if (stream._state !== 'readable') { + return; + } + ResetQueue(controller); + ReadableStreamDefaultControllerClearAlgorithms(controller); + ReadableStreamError(stream, e); + } + function ReadableStreamDefaultControllerGetDesiredSize(controller) { + const state = controller._controlledReadableStream._state; + if (state === 'errored') { + return null; + } + if (state === 'closed') { + return 0; + } + return controller._strategyHWM - controller._queueTotalSize; + } + // This is used in the implementation of TransformStream. + function ReadableStreamDefaultControllerHasBackpressure(controller) { + if (ReadableStreamDefaultControllerShouldCallPull(controller)) { + return false; + } + return true; + } + function ReadableStreamDefaultControllerCanCloseOrEnqueue(controller) { + const state = controller._controlledReadableStream._state; + if (!controller._closeRequested && state === 'readable') { + return true; + } + return false; + } + function SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm) { + controller._controlledReadableStream = stream; + controller._queue = undefined; + controller._queueTotalSize = undefined; + ResetQueue(controller); + controller._started = false; + controller._closeRequested = false; + controller._pullAgain = false; + controller._pulling = false; + controller._strategySizeAlgorithm = sizeAlgorithm; + controller._strategyHWM = highWaterMark; + controller._pullAlgorithm = pullAlgorithm; + controller._cancelAlgorithm = cancelAlgorithm; + stream._readableStreamController = controller; + const startResult = startAlgorithm(); + uponPromise(promiseResolvedWith(startResult), () => { + controller._started = true; + ReadableStreamDefaultControllerCallPullIfNeeded(controller); + }, r => { + ReadableStreamDefaultControllerError(controller, r); + }); + } + function SetUpReadableStreamDefaultControllerFromUnderlyingSource(stream, underlyingSource, highWaterMark, sizeAlgorithm) { + const controller = Object.create(ReadableStreamDefaultController.prototype); + let startAlgorithm = () => undefined; + let pullAlgorithm = () => promiseResolvedWith(undefined); + let cancelAlgorithm = () => promiseResolvedWith(undefined); + if (underlyingSource.start !== undefined) { + startAlgorithm = () => underlyingSource.start(controller); + } + if (underlyingSource.pull !== undefined) { + pullAlgorithm = () => underlyingSource.pull(controller); + } + if (underlyingSource.cancel !== undefined) { + cancelAlgorithm = reason => underlyingSource.cancel(reason); + } + SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm); + } + // Helper functions for the ReadableStreamDefaultController. + function defaultControllerBrandCheckException$1(name) { + return new TypeError(`ReadableStreamDefaultController.prototype.${name} can only be used on a ReadableStreamDefaultController`); + } + + function ReadableStreamTee(stream, cloneForBranch2) { + if (IsReadableByteStreamController(stream._readableStreamController)) { + return ReadableByteStreamTee(stream); + } + return ReadableStreamDefaultTee(stream); + } + function ReadableStreamDefaultTee(stream, cloneForBranch2) { + const reader = AcquireReadableStreamDefaultReader(stream); + let reading = false; + let readAgain = false; + let canceled1 = false; + let canceled2 = false; + let reason1; + let reason2; + let branch1; + let branch2; + let resolveCancelPromise; + const cancelPromise = newPromise(resolve => { + resolveCancelPromise = resolve; + }); + function pullAlgorithm() { + if (reading) { + readAgain = true; + return promiseResolvedWith(undefined); + } + reading = true; + const readRequest = { + _chunkSteps: chunk => { + // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using + // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let + // successful synchronously-available reads get ahead of asynchronously-available errors. + queueMicrotask(() => { + readAgain = false; + const chunk1 = chunk; + const chunk2 = chunk; + // There is no way to access the cloning code right now in the reference implementation. + // If we add one then we'll need an implementation for serializable objects. + // if (!canceled2 && cloneForBranch2) { + // chunk2 = StructuredDeserialize(StructuredSerialize(chunk2)); + // } + if (!canceled1) { + ReadableStreamDefaultControllerEnqueue(branch1._readableStreamController, chunk1); + } + if (!canceled2) { + ReadableStreamDefaultControllerEnqueue(branch2._readableStreamController, chunk2); + } + reading = false; + if (readAgain) { + pullAlgorithm(); + } + }); + }, + _closeSteps: () => { + reading = false; + if (!canceled1) { + ReadableStreamDefaultControllerClose(branch1._readableStreamController); + } + if (!canceled2) { + ReadableStreamDefaultControllerClose(branch2._readableStreamController); + } + if (!canceled1 || !canceled2) { + resolveCancelPromise(undefined); + } + }, + _errorSteps: () => { + reading = false; + } + }; + ReadableStreamDefaultReaderRead(reader, readRequest); + return promiseResolvedWith(undefined); + } + function cancel1Algorithm(reason) { + canceled1 = true; + reason1 = reason; + if (canceled2) { + const compositeReason = CreateArrayFromList([reason1, reason2]); + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolveCancelPromise(cancelResult); + } + return cancelPromise; + } + function cancel2Algorithm(reason) { + canceled2 = true; + reason2 = reason; + if (canceled1) { + const compositeReason = CreateArrayFromList([reason1, reason2]); + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolveCancelPromise(cancelResult); + } + return cancelPromise; + } + function startAlgorithm() { + // do nothing + } + branch1 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel1Algorithm); + branch2 = CreateReadableStream(startAlgorithm, pullAlgorithm, cancel2Algorithm); + uponRejection(reader._closedPromise, (r) => { + ReadableStreamDefaultControllerError(branch1._readableStreamController, r); + ReadableStreamDefaultControllerError(branch2._readableStreamController, r); + if (!canceled1 || !canceled2) { + resolveCancelPromise(undefined); + } + }); + return [branch1, branch2]; + } + function ReadableByteStreamTee(stream) { + let reader = AcquireReadableStreamDefaultReader(stream); + let reading = false; + let readAgainForBranch1 = false; + let readAgainForBranch2 = false; + let canceled1 = false; + let canceled2 = false; + let reason1; + let reason2; + let branch1; + let branch2; + let resolveCancelPromise; + const cancelPromise = newPromise(resolve => { + resolveCancelPromise = resolve; + }); + function forwardReaderError(thisReader) { + uponRejection(thisReader._closedPromise, r => { + if (thisReader !== reader) { + return; + } + ReadableByteStreamControllerError(branch1._readableStreamController, r); + ReadableByteStreamControllerError(branch2._readableStreamController, r); + if (!canceled1 || !canceled2) { + resolveCancelPromise(undefined); + } + }); + } + function pullWithDefaultReader() { + if (IsReadableStreamBYOBReader(reader)) { + ReadableStreamReaderGenericRelease(reader); + reader = AcquireReadableStreamDefaultReader(stream); + forwardReaderError(reader); + } + const readRequest = { + _chunkSteps: chunk => { + // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using + // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let + // successful synchronously-available reads get ahead of asynchronously-available errors. + queueMicrotask(() => { + readAgainForBranch1 = false; + readAgainForBranch2 = false; + const chunk1 = chunk; + let chunk2 = chunk; + if (!canceled1 && !canceled2) { + try { + chunk2 = CloneAsUint8Array(chunk); + } + catch (cloneE) { + ReadableByteStreamControllerError(branch1._readableStreamController, cloneE); + ReadableByteStreamControllerError(branch2._readableStreamController, cloneE); + resolveCancelPromise(ReadableStreamCancel(stream, cloneE)); + return; + } + } + if (!canceled1) { + ReadableByteStreamControllerEnqueue(branch1._readableStreamController, chunk1); + } + if (!canceled2) { + ReadableByteStreamControllerEnqueue(branch2._readableStreamController, chunk2); + } + reading = false; + if (readAgainForBranch1) { + pull1Algorithm(); + } + else if (readAgainForBranch2) { + pull2Algorithm(); + } + }); + }, + _closeSteps: () => { + reading = false; + if (!canceled1) { + ReadableByteStreamControllerClose(branch1._readableStreamController); + } + if (!canceled2) { + ReadableByteStreamControllerClose(branch2._readableStreamController); + } + if (branch1._readableStreamController._pendingPullIntos.length > 0) { + ReadableByteStreamControllerRespond(branch1._readableStreamController, 0); + } + if (branch2._readableStreamController._pendingPullIntos.length > 0) { + ReadableByteStreamControllerRespond(branch2._readableStreamController, 0); + } + if (!canceled1 || !canceled2) { + resolveCancelPromise(undefined); + } + }, + _errorSteps: () => { + reading = false; + } + }; + ReadableStreamDefaultReaderRead(reader, readRequest); + } + function pullWithBYOBReader(view, forBranch2) { + if (IsReadableStreamDefaultReader(reader)) { + ReadableStreamReaderGenericRelease(reader); + reader = AcquireReadableStreamBYOBReader(stream); + forwardReaderError(reader); + } + const byobBranch = forBranch2 ? branch2 : branch1; + const otherBranch = forBranch2 ? branch1 : branch2; + const readIntoRequest = { + _chunkSteps: chunk => { + // This needs to be delayed a microtask because it takes at least a microtask to detect errors (using + // reader._closedPromise below), and we want errors in stream to error both branches immediately. We cannot let + // successful synchronously-available reads get ahead of asynchronously-available errors. + queueMicrotask(() => { + readAgainForBranch1 = false; + readAgainForBranch2 = false; + const byobCanceled = forBranch2 ? canceled2 : canceled1; + const otherCanceled = forBranch2 ? canceled1 : canceled2; + if (!otherCanceled) { + let clonedChunk; + try { + clonedChunk = CloneAsUint8Array(chunk); + } + catch (cloneE) { + ReadableByteStreamControllerError(byobBranch._readableStreamController, cloneE); + ReadableByteStreamControllerError(otherBranch._readableStreamController, cloneE); + resolveCancelPromise(ReadableStreamCancel(stream, cloneE)); + return; + } + if (!byobCanceled) { + ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk); + } + ReadableByteStreamControllerEnqueue(otherBranch._readableStreamController, clonedChunk); + } + else if (!byobCanceled) { + ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk); + } + reading = false; + if (readAgainForBranch1) { + pull1Algorithm(); + } + else if (readAgainForBranch2) { + pull2Algorithm(); + } + }); + }, + _closeSteps: chunk => { + reading = false; + const byobCanceled = forBranch2 ? canceled2 : canceled1; + const otherCanceled = forBranch2 ? canceled1 : canceled2; + if (!byobCanceled) { + ReadableByteStreamControllerClose(byobBranch._readableStreamController); + } + if (!otherCanceled) { + ReadableByteStreamControllerClose(otherBranch._readableStreamController); + } + if (chunk !== undefined) { + if (!byobCanceled) { + ReadableByteStreamControllerRespondWithNewView(byobBranch._readableStreamController, chunk); + } + if (!otherCanceled && otherBranch._readableStreamController._pendingPullIntos.length > 0) { + ReadableByteStreamControllerRespond(otherBranch._readableStreamController, 0); + } + } + if (!byobCanceled || !otherCanceled) { + resolveCancelPromise(undefined); + } + }, + _errorSteps: () => { + reading = false; + } + }; + ReadableStreamBYOBReaderRead(reader, view, readIntoRequest); + } + function pull1Algorithm() { + if (reading) { + readAgainForBranch1 = true; + return promiseResolvedWith(undefined); + } + reading = true; + const byobRequest = ReadableByteStreamControllerGetBYOBRequest(branch1._readableStreamController); + if (byobRequest === null) { + pullWithDefaultReader(); + } + else { + pullWithBYOBReader(byobRequest._view, false); + } + return promiseResolvedWith(undefined); + } + function pull2Algorithm() { + if (reading) { + readAgainForBranch2 = true; + return promiseResolvedWith(undefined); + } + reading = true; + const byobRequest = ReadableByteStreamControllerGetBYOBRequest(branch2._readableStreamController); + if (byobRequest === null) { + pullWithDefaultReader(); + } + else { + pullWithBYOBReader(byobRequest._view, true); + } + return promiseResolvedWith(undefined); + } + function cancel1Algorithm(reason) { + canceled1 = true; + reason1 = reason; + if (canceled2) { + const compositeReason = CreateArrayFromList([reason1, reason2]); + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolveCancelPromise(cancelResult); + } + return cancelPromise; + } + function cancel2Algorithm(reason) { + canceled2 = true; + reason2 = reason; + if (canceled1) { + const compositeReason = CreateArrayFromList([reason1, reason2]); + const cancelResult = ReadableStreamCancel(stream, compositeReason); + resolveCancelPromise(cancelResult); + } + return cancelPromise; + } + function startAlgorithm() { + return; + } + branch1 = CreateReadableByteStream(startAlgorithm, pull1Algorithm, cancel1Algorithm); + branch2 = CreateReadableByteStream(startAlgorithm, pull2Algorithm, cancel2Algorithm); + forwardReaderError(reader); + return [branch1, branch2]; + } + + function convertUnderlyingDefaultOrByteSource(source, context) { + assertDictionary(source, context); + const original = source; + const autoAllocateChunkSize = original === null || original === void 0 ? void 0 : original.autoAllocateChunkSize; + const cancel = original === null || original === void 0 ? void 0 : original.cancel; + const pull = original === null || original === void 0 ? void 0 : original.pull; + const start = original === null || original === void 0 ? void 0 : original.start; + const type = original === null || original === void 0 ? void 0 : original.type; + return { + autoAllocateChunkSize: autoAllocateChunkSize === undefined ? + undefined : + convertUnsignedLongLongWithEnforceRange(autoAllocateChunkSize, `${context} has member 'autoAllocateChunkSize' that`), + cancel: cancel === undefined ? + undefined : + convertUnderlyingSourceCancelCallback(cancel, original, `${context} has member 'cancel' that`), + pull: pull === undefined ? + undefined : + convertUnderlyingSourcePullCallback(pull, original, `${context} has member 'pull' that`), + start: start === undefined ? + undefined : + convertUnderlyingSourceStartCallback(start, original, `${context} has member 'start' that`), + type: type === undefined ? undefined : convertReadableStreamType(type, `${context} has member 'type' that`) + }; + } + function convertUnderlyingSourceCancelCallback(fn, original, context) { + assertFunction(fn, context); + return (reason) => promiseCall(fn, original, [reason]); + } + function convertUnderlyingSourcePullCallback(fn, original, context) { + assertFunction(fn, context); + return (controller) => promiseCall(fn, original, [controller]); + } + function convertUnderlyingSourceStartCallback(fn, original, context) { + assertFunction(fn, context); + return (controller) => reflectCall(fn, original, [controller]); + } + function convertReadableStreamType(type, context) { + type = `${type}`; + if (type !== 'bytes') { + throw new TypeError(`${context} '${type}' is not a valid enumeration value for ReadableStreamType`); + } + return type; + } + + function convertReaderOptions(options, context) { + assertDictionary(options, context); + const mode = options === null || options === void 0 ? void 0 : options.mode; + return { + mode: mode === undefined ? undefined : convertReadableStreamReaderMode(mode, `${context} has member 'mode' that`) + }; + } + function convertReadableStreamReaderMode(mode, context) { + mode = `${mode}`; + if (mode !== 'byob') { + throw new TypeError(`${context} '${mode}' is not a valid enumeration value for ReadableStreamReaderMode`); + } + return mode; + } + + function convertIteratorOptions(options, context) { + assertDictionary(options, context); + const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel; + return { preventCancel: Boolean(preventCancel) }; + } + + function convertPipeOptions(options, context) { + assertDictionary(options, context); + const preventAbort = options === null || options === void 0 ? void 0 : options.preventAbort; + const preventCancel = options === null || options === void 0 ? void 0 : options.preventCancel; + const preventClose = options === null || options === void 0 ? void 0 : options.preventClose; + const signal = options === null || options === void 0 ? void 0 : options.signal; + if (signal !== undefined) { + assertAbortSignal(signal, `${context} has member 'signal' that`); + } + return { + preventAbort: Boolean(preventAbort), + preventCancel: Boolean(preventCancel), + preventClose: Boolean(preventClose), + signal + }; + } + function assertAbortSignal(signal, context) { + if (!isAbortSignal(signal)) { + throw new TypeError(`${context} is not an AbortSignal.`); + } + } + + function convertReadableWritablePair(pair, context) { + assertDictionary(pair, context); + const readable = pair === null || pair === void 0 ? void 0 : pair.readable; + assertRequiredField(readable, 'readable', 'ReadableWritablePair'); + assertReadableStream(readable, `${context} has member 'readable' that`); + const writable = pair === null || pair === void 0 ? void 0 : pair.writable; + assertRequiredField(writable, 'writable', 'ReadableWritablePair'); + assertWritableStream(writable, `${context} has member 'writable' that`); + return { readable, writable }; + } + + /** + * A readable stream represents a source of data, from which you can read. + * + * @public + */ + class ReadableStream { + constructor(rawUnderlyingSource = {}, rawStrategy = {}) { + if (rawUnderlyingSource === undefined) { + rawUnderlyingSource = null; + } + else { + assertObject(rawUnderlyingSource, 'First parameter'); + } + const strategy = convertQueuingStrategy(rawStrategy, 'Second parameter'); + const underlyingSource = convertUnderlyingDefaultOrByteSource(rawUnderlyingSource, 'First parameter'); + InitializeReadableStream(this); + if (underlyingSource.type === 'bytes') { + if (strategy.size !== undefined) { + throw new RangeError('The strategy for a byte stream cannot have a size function'); + } + const highWaterMark = ExtractHighWaterMark(strategy, 0); + SetUpReadableByteStreamControllerFromUnderlyingSource(this, underlyingSource, highWaterMark); + } + else { + const sizeAlgorithm = ExtractSizeAlgorithm(strategy); + const highWaterMark = ExtractHighWaterMark(strategy, 1); + SetUpReadableStreamDefaultControllerFromUnderlyingSource(this, underlyingSource, highWaterMark, sizeAlgorithm); + } + } + /** + * Whether or not the readable stream is locked to a {@link ReadableStreamDefaultReader | reader}. + */ + get locked() { + if (!IsReadableStream(this)) { + throw streamBrandCheckException$1('locked'); + } + return IsReadableStreamLocked(this); + } + /** + * Cancels the stream, signaling a loss of interest in the stream by a consumer. + * + * The supplied `reason` argument will be given to the underlying source's {@link UnderlyingSource.cancel | cancel()} + * method, which might or might not use it. + */ + cancel(reason = undefined) { + if (!IsReadableStream(this)) { + return promiseRejectedWith(streamBrandCheckException$1('cancel')); + } + if (IsReadableStreamLocked(this)) { + return promiseRejectedWith(new TypeError('Cannot cancel a stream that already has a reader')); + } + return ReadableStreamCancel(this, reason); + } + getReader(rawOptions = undefined) { + if (!IsReadableStream(this)) { + throw streamBrandCheckException$1('getReader'); + } + const options = convertReaderOptions(rawOptions, 'First parameter'); + if (options.mode === undefined) { + return AcquireReadableStreamDefaultReader(this); + } + return AcquireReadableStreamBYOBReader(this); + } + pipeThrough(rawTransform, rawOptions = {}) { + if (!IsReadableStream(this)) { + throw streamBrandCheckException$1('pipeThrough'); + } + assertRequiredArgument(rawTransform, 1, 'pipeThrough'); + const transform = convertReadableWritablePair(rawTransform, 'First parameter'); + const options = convertPipeOptions(rawOptions, 'Second parameter'); + if (IsReadableStreamLocked(this)) { + throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked ReadableStream'); + } + if (IsWritableStreamLocked(transform.writable)) { + throw new TypeError('ReadableStream.prototype.pipeThrough cannot be used on a locked WritableStream'); + } + const promise = ReadableStreamPipeTo(this, transform.writable, options.preventClose, options.preventAbort, options.preventCancel, options.signal); + setPromiseIsHandledToTrue(promise); + return transform.readable; + } + pipeTo(destination, rawOptions = {}) { + if (!IsReadableStream(this)) { + return promiseRejectedWith(streamBrandCheckException$1('pipeTo')); + } + if (destination === undefined) { + return promiseRejectedWith(`Parameter 1 is required in 'pipeTo'.`); + } + if (!IsWritableStream(destination)) { + return promiseRejectedWith(new TypeError(`ReadableStream.prototype.pipeTo's first argument must be a WritableStream`)); + } + let options; + try { + options = convertPipeOptions(rawOptions, 'Second parameter'); + } + catch (e) { + return promiseRejectedWith(e); + } + if (IsReadableStreamLocked(this)) { + return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked ReadableStream')); + } + if (IsWritableStreamLocked(destination)) { + return promiseRejectedWith(new TypeError('ReadableStream.prototype.pipeTo cannot be used on a locked WritableStream')); + } + return ReadableStreamPipeTo(this, destination, options.preventClose, options.preventAbort, options.preventCancel, options.signal); + } + /** + * Tees this readable stream, returning a two-element array containing the two resulting branches as + * new {@link ReadableStream} instances. + * + * Teeing a stream will lock it, preventing any other consumer from acquiring a reader. + * To cancel the stream, cancel both of the resulting branches; a composite cancellation reason will then be + * propagated to the stream's underlying source. + * + * Note that the chunks seen in each branch will be the same object. If the chunks are not immutable, + * this could allow interference between the two branches. + */ + tee() { + if (!IsReadableStream(this)) { + throw streamBrandCheckException$1('tee'); + } + const branches = ReadableStreamTee(this); + return CreateArrayFromList(branches); + } + values(rawOptions = undefined) { + if (!IsReadableStream(this)) { + throw streamBrandCheckException$1('values'); + } + const options = convertIteratorOptions(rawOptions, 'First parameter'); + return AcquireReadableStreamAsyncIterator(this, options.preventCancel); + } + } + Object.defineProperties(ReadableStream.prototype, { + cancel: { enumerable: true }, + getReader: { enumerable: true }, + pipeThrough: { enumerable: true }, + pipeTo: { enumerable: true }, + tee: { enumerable: true }, + values: { enumerable: true }, + locked: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.toStringTag, { + value: 'ReadableStream', + configurable: true + }); + } + if (typeof SymbolPolyfill.asyncIterator === 'symbol') { + Object.defineProperty(ReadableStream.prototype, SymbolPolyfill.asyncIterator, { + value: ReadableStream.prototype.values, + writable: true, + configurable: true + }); + } + // Abstract operations for the ReadableStream. + // Throws if and only if startAlgorithm throws. + function CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark = 1, sizeAlgorithm = () => 1) { + const stream = Object.create(ReadableStream.prototype); + InitializeReadableStream(stream); + const controller = Object.create(ReadableStreamDefaultController.prototype); + SetUpReadableStreamDefaultController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, highWaterMark, sizeAlgorithm); + return stream; + } + // Throws if and only if startAlgorithm throws. + function CreateReadableByteStream(startAlgorithm, pullAlgorithm, cancelAlgorithm) { + const stream = Object.create(ReadableStream.prototype); + InitializeReadableStream(stream); + const controller = Object.create(ReadableByteStreamController.prototype); + SetUpReadableByteStreamController(stream, controller, startAlgorithm, pullAlgorithm, cancelAlgorithm, 0, undefined); + return stream; + } + function InitializeReadableStream(stream) { + stream._state = 'readable'; + stream._reader = undefined; + stream._storedError = undefined; + stream._disturbed = false; + } + function IsReadableStream(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_readableStreamController')) { + return false; + } + return x instanceof ReadableStream; + } + function IsReadableStreamLocked(stream) { + if (stream._reader === undefined) { + return false; + } + return true; + } + // ReadableStream API exposed for controllers. + function ReadableStreamCancel(stream, reason) { + stream._disturbed = true; + if (stream._state === 'closed') { + return promiseResolvedWith(undefined); + } + if (stream._state === 'errored') { + return promiseRejectedWith(stream._storedError); + } + ReadableStreamClose(stream); + const reader = stream._reader; + if (reader !== undefined && IsReadableStreamBYOBReader(reader)) { + reader._readIntoRequests.forEach(readIntoRequest => { + readIntoRequest._closeSteps(undefined); + }); + reader._readIntoRequests = new SimpleQueue(); + } + const sourceCancelPromise = stream._readableStreamController[CancelSteps](reason); + return transformPromiseWith(sourceCancelPromise, noop); + } + function ReadableStreamClose(stream) { + stream._state = 'closed'; + const reader = stream._reader; + if (reader === undefined) { + return; + } + defaultReaderClosedPromiseResolve(reader); + if (IsReadableStreamDefaultReader(reader)) { + reader._readRequests.forEach(readRequest => { + readRequest._closeSteps(); + }); + reader._readRequests = new SimpleQueue(); + } + } + function ReadableStreamError(stream, e) { + stream._state = 'errored'; + stream._storedError = e; + const reader = stream._reader; + if (reader === undefined) { + return; + } + defaultReaderClosedPromiseReject(reader, e); + if (IsReadableStreamDefaultReader(reader)) { + reader._readRequests.forEach(readRequest => { + readRequest._errorSteps(e); + }); + reader._readRequests = new SimpleQueue(); + } + else { + reader._readIntoRequests.forEach(readIntoRequest => { + readIntoRequest._errorSteps(e); + }); + reader._readIntoRequests = new SimpleQueue(); + } + } + // Helper functions for the ReadableStream. + function streamBrandCheckException$1(name) { + return new TypeError(`ReadableStream.prototype.${name} can only be used on a ReadableStream`); + } + + function convertQueuingStrategyInit(init, context) { + assertDictionary(init, context); + const highWaterMark = init === null || init === void 0 ? void 0 : init.highWaterMark; + assertRequiredField(highWaterMark, 'highWaterMark', 'QueuingStrategyInit'); + return { + highWaterMark: convertUnrestrictedDouble(highWaterMark) + }; + } + + // The size function must not have a prototype property nor be a constructor + const byteLengthSizeFunction = (chunk) => { + return chunk.byteLength; + }; + try { + Object.defineProperty(byteLengthSizeFunction, 'name', { + value: 'size', + configurable: true + }); + } + catch (_a) { + // This property is non-configurable in older browsers, so ignore if this throws. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#browser_compatibility + } + /** + * A queuing strategy that counts the number of bytes in each chunk. + * + * @public + */ + class ByteLengthQueuingStrategy { + constructor(options) { + assertRequiredArgument(options, 1, 'ByteLengthQueuingStrategy'); + options = convertQueuingStrategyInit(options, 'First parameter'); + this._byteLengthQueuingStrategyHighWaterMark = options.highWaterMark; + } + /** + * Returns the high water mark provided to the constructor. + */ + get highWaterMark() { + if (!IsByteLengthQueuingStrategy(this)) { + throw byteLengthBrandCheckException('highWaterMark'); + } + return this._byteLengthQueuingStrategyHighWaterMark; + } + /** + * Measures the size of `chunk` by returning the value of its `byteLength` property. + */ + get size() { + if (!IsByteLengthQueuingStrategy(this)) { + throw byteLengthBrandCheckException('size'); + } + return byteLengthSizeFunction; + } + } + Object.defineProperties(ByteLengthQueuingStrategy.prototype, { + highWaterMark: { enumerable: true }, + size: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(ByteLengthQueuingStrategy.prototype, SymbolPolyfill.toStringTag, { + value: 'ByteLengthQueuingStrategy', + configurable: true + }); + } + // Helper functions for the ByteLengthQueuingStrategy. + function byteLengthBrandCheckException(name) { + return new TypeError(`ByteLengthQueuingStrategy.prototype.${name} can only be used on a ByteLengthQueuingStrategy`); + } + function IsByteLengthQueuingStrategy(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_byteLengthQueuingStrategyHighWaterMark')) { + return false; + } + return x instanceof ByteLengthQueuingStrategy; + } + + // The size function must not have a prototype property nor be a constructor + const countSizeFunction = () => { + return 1; + }; + try { + Object.defineProperty(countSizeFunction, 'name', { + value: 'size', + configurable: true + }); + } + catch (_a) { + // This property is non-configurable in older browsers, so ignore if this throws. + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name#browser_compatibility + } + /** + * A queuing strategy that counts the number of chunks. + * + * @public + */ + class CountQueuingStrategy { + constructor(options) { + assertRequiredArgument(options, 1, 'CountQueuingStrategy'); + options = convertQueuingStrategyInit(options, 'First parameter'); + this._countQueuingStrategyHighWaterMark = options.highWaterMark; + } + /** + * Returns the high water mark provided to the constructor. + */ + get highWaterMark() { + if (!IsCountQueuingStrategy(this)) { + throw countBrandCheckException('highWaterMark'); + } + return this._countQueuingStrategyHighWaterMark; + } + /** + * Measures the size of `chunk` by always returning 1. + * This ensures that the total queue size is a count of the number of chunks in the queue. + */ + get size() { + if (!IsCountQueuingStrategy(this)) { + throw countBrandCheckException('size'); + } + return countSizeFunction; + } + } + Object.defineProperties(CountQueuingStrategy.prototype, { + highWaterMark: { enumerable: true }, + size: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(CountQueuingStrategy.prototype, SymbolPolyfill.toStringTag, { + value: 'CountQueuingStrategy', + configurable: true + }); + } + // Helper functions for the CountQueuingStrategy. + function countBrandCheckException(name) { + return new TypeError(`CountQueuingStrategy.prototype.${name} can only be used on a CountQueuingStrategy`); + } + function IsCountQueuingStrategy(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_countQueuingStrategyHighWaterMark')) { + return false; + } + return x instanceof CountQueuingStrategy; + } + + function convertTransformer(original, context) { + assertDictionary(original, context); + const flush = original === null || original === void 0 ? void 0 : original.flush; + const readableType = original === null || original === void 0 ? void 0 : original.readableType; + const start = original === null || original === void 0 ? void 0 : original.start; + const transform = original === null || original === void 0 ? void 0 : original.transform; + const writableType = original === null || original === void 0 ? void 0 : original.writableType; + return { + flush: flush === undefined ? + undefined : + convertTransformerFlushCallback(flush, original, `${context} has member 'flush' that`), + readableType, + start: start === undefined ? + undefined : + convertTransformerStartCallback(start, original, `${context} has member 'start' that`), + transform: transform === undefined ? + undefined : + convertTransformerTransformCallback(transform, original, `${context} has member 'transform' that`), + writableType + }; + } + function convertTransformerFlushCallback(fn, original, context) { + assertFunction(fn, context); + return (controller) => promiseCall(fn, original, [controller]); + } + function convertTransformerStartCallback(fn, original, context) { + assertFunction(fn, context); + return (controller) => reflectCall(fn, original, [controller]); + } + function convertTransformerTransformCallback(fn, original, context) { + assertFunction(fn, context); + return (chunk, controller) => promiseCall(fn, original, [chunk, controller]); + } + + // Class TransformStream + /** + * A transform stream consists of a pair of streams: a {@link WritableStream | writable stream}, + * known as its writable side, and a {@link ReadableStream | readable stream}, known as its readable side. + * In a manner specific to the transform stream in question, writes to the writable side result in new data being + * made available for reading from the readable side. + * + * @public + */ + class TransformStream { + constructor(rawTransformer = {}, rawWritableStrategy = {}, rawReadableStrategy = {}) { + if (rawTransformer === undefined) { + rawTransformer = null; + } + const writableStrategy = convertQueuingStrategy(rawWritableStrategy, 'Second parameter'); + const readableStrategy = convertQueuingStrategy(rawReadableStrategy, 'Third parameter'); + const transformer = convertTransformer(rawTransformer, 'First parameter'); + if (transformer.readableType !== undefined) { + throw new RangeError('Invalid readableType specified'); + } + if (transformer.writableType !== undefined) { + throw new RangeError('Invalid writableType specified'); + } + const readableHighWaterMark = ExtractHighWaterMark(readableStrategy, 0); + const readableSizeAlgorithm = ExtractSizeAlgorithm(readableStrategy); + const writableHighWaterMark = ExtractHighWaterMark(writableStrategy, 1); + const writableSizeAlgorithm = ExtractSizeAlgorithm(writableStrategy); + let startPromise_resolve; + const startPromise = newPromise(resolve => { + startPromise_resolve = resolve; + }); + InitializeTransformStream(this, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm); + SetUpTransformStreamDefaultControllerFromTransformer(this, transformer); + if (transformer.start !== undefined) { + startPromise_resolve(transformer.start(this._transformStreamController)); + } + else { + startPromise_resolve(undefined); + } + } + /** + * The readable side of the transform stream. + */ + get readable() { + if (!IsTransformStream(this)) { + throw streamBrandCheckException('readable'); + } + return this._readable; + } + /** + * The writable side of the transform stream. + */ + get writable() { + if (!IsTransformStream(this)) { + throw streamBrandCheckException('writable'); + } + return this._writable; + } + } + Object.defineProperties(TransformStream.prototype, { + readable: { enumerable: true }, + writable: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(TransformStream.prototype, SymbolPolyfill.toStringTag, { + value: 'TransformStream', + configurable: true + }); + } + function InitializeTransformStream(stream, startPromise, writableHighWaterMark, writableSizeAlgorithm, readableHighWaterMark, readableSizeAlgorithm) { + function startAlgorithm() { + return startPromise; + } + function writeAlgorithm(chunk) { + return TransformStreamDefaultSinkWriteAlgorithm(stream, chunk); + } + function abortAlgorithm(reason) { + return TransformStreamDefaultSinkAbortAlgorithm(stream, reason); + } + function closeAlgorithm() { + return TransformStreamDefaultSinkCloseAlgorithm(stream); + } + stream._writable = CreateWritableStream(startAlgorithm, writeAlgorithm, closeAlgorithm, abortAlgorithm, writableHighWaterMark, writableSizeAlgorithm); + function pullAlgorithm() { + return TransformStreamDefaultSourcePullAlgorithm(stream); + } + function cancelAlgorithm(reason) { + TransformStreamErrorWritableAndUnblockWrite(stream, reason); + return promiseResolvedWith(undefined); + } + stream._readable = CreateReadableStream(startAlgorithm, pullAlgorithm, cancelAlgorithm, readableHighWaterMark, readableSizeAlgorithm); + // The [[backpressure]] slot is set to undefined so that it can be initialised by TransformStreamSetBackpressure. + stream._backpressure = undefined; + stream._backpressureChangePromise = undefined; + stream._backpressureChangePromise_resolve = undefined; + TransformStreamSetBackpressure(stream, true); + stream._transformStreamController = undefined; + } + function IsTransformStream(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_transformStreamController')) { + return false; + } + return x instanceof TransformStream; + } + // This is a no-op if both sides are already errored. + function TransformStreamError(stream, e) { + ReadableStreamDefaultControllerError(stream._readable._readableStreamController, e); + TransformStreamErrorWritableAndUnblockWrite(stream, e); + } + function TransformStreamErrorWritableAndUnblockWrite(stream, e) { + TransformStreamDefaultControllerClearAlgorithms(stream._transformStreamController); + WritableStreamDefaultControllerErrorIfNeeded(stream._writable._writableStreamController, e); + if (stream._backpressure) { + // Pretend that pull() was called to permit any pending write() calls to complete. TransformStreamSetBackpressure() + // cannot be called from enqueue() or pull() once the ReadableStream is errored, so this will will be the final time + // _backpressure is set. + TransformStreamSetBackpressure(stream, false); + } + } + function TransformStreamSetBackpressure(stream, backpressure) { + // Passes also when called during construction. + if (stream._backpressureChangePromise !== undefined) { + stream._backpressureChangePromise_resolve(); + } + stream._backpressureChangePromise = newPromise(resolve => { + stream._backpressureChangePromise_resolve = resolve; + }); + stream._backpressure = backpressure; + } + // Class TransformStreamDefaultController + /** + * Allows control of the {@link ReadableStream} and {@link WritableStream} of the associated {@link TransformStream}. + * + * @public + */ + class TransformStreamDefaultController { + constructor() { + throw new TypeError('Illegal constructor'); + } + /** + * Returns the desired size to fill the readable side’s internal queue. It can be negative, if the queue is over-full. + */ + get desiredSize() { + if (!IsTransformStreamDefaultController(this)) { + throw defaultControllerBrandCheckException('desiredSize'); + } + const readableController = this._controlledTransformStream._readable._readableStreamController; + return ReadableStreamDefaultControllerGetDesiredSize(readableController); + } + enqueue(chunk = undefined) { + if (!IsTransformStreamDefaultController(this)) { + throw defaultControllerBrandCheckException('enqueue'); + } + TransformStreamDefaultControllerEnqueue(this, chunk); + } + /** + * Errors both the readable side and the writable side of the controlled transform stream, making all future + * interactions with it fail with the given error `e`. Any chunks queued for transformation will be discarded. + */ + error(reason = undefined) { + if (!IsTransformStreamDefaultController(this)) { + throw defaultControllerBrandCheckException('error'); + } + TransformStreamDefaultControllerError(this, reason); + } + /** + * Closes the readable side and errors the writable side of the controlled transform stream. This is useful when the + * transformer only needs to consume a portion of the chunks written to the writable side. + */ + terminate() { + if (!IsTransformStreamDefaultController(this)) { + throw defaultControllerBrandCheckException('terminate'); + } + TransformStreamDefaultControllerTerminate(this); + } + } + Object.defineProperties(TransformStreamDefaultController.prototype, { + enqueue: { enumerable: true }, + error: { enumerable: true }, + terminate: { enumerable: true }, + desiredSize: { enumerable: true } + }); + if (typeof SymbolPolyfill.toStringTag === 'symbol') { + Object.defineProperty(TransformStreamDefaultController.prototype, SymbolPolyfill.toStringTag, { + value: 'TransformStreamDefaultController', + configurable: true + }); + } + // Transform Stream Default Controller Abstract Operations + function IsTransformStreamDefaultController(x) { + if (!typeIsObject(x)) { + return false; + } + if (!Object.prototype.hasOwnProperty.call(x, '_controlledTransformStream')) { + return false; + } + return x instanceof TransformStreamDefaultController; + } + function SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm) { + controller._controlledTransformStream = stream; + stream._transformStreamController = controller; + controller._transformAlgorithm = transformAlgorithm; + controller._flushAlgorithm = flushAlgorithm; + } + function SetUpTransformStreamDefaultControllerFromTransformer(stream, transformer) { + const controller = Object.create(TransformStreamDefaultController.prototype); + let transformAlgorithm = (chunk) => { + try { + TransformStreamDefaultControllerEnqueue(controller, chunk); + return promiseResolvedWith(undefined); + } + catch (transformResultE) { + return promiseRejectedWith(transformResultE); + } + }; + let flushAlgorithm = () => promiseResolvedWith(undefined); + if (transformer.transform !== undefined) { + transformAlgorithm = chunk => transformer.transform(chunk, controller); + } + if (transformer.flush !== undefined) { + flushAlgorithm = () => transformer.flush(controller); + } + SetUpTransformStreamDefaultController(stream, controller, transformAlgorithm, flushAlgorithm); + } + function TransformStreamDefaultControllerClearAlgorithms(controller) { + controller._transformAlgorithm = undefined; + controller._flushAlgorithm = undefined; + } + function TransformStreamDefaultControllerEnqueue(controller, chunk) { + const stream = controller._controlledTransformStream; + const readableController = stream._readable._readableStreamController; + if (!ReadableStreamDefaultControllerCanCloseOrEnqueue(readableController)) { + throw new TypeError('Readable side is not in a state that permits enqueue'); + } + // We throttle transform invocations based on the backpressure of the ReadableStream, but we still + // accept TransformStreamDefaultControllerEnqueue() calls. + try { + ReadableStreamDefaultControllerEnqueue(readableController, chunk); + } + catch (e) { + // This happens when readableStrategy.size() throws. + TransformStreamErrorWritableAndUnblockWrite(stream, e); + throw stream._readable._storedError; + } + const backpressure = ReadableStreamDefaultControllerHasBackpressure(readableController); + if (backpressure !== stream._backpressure) { + TransformStreamSetBackpressure(stream, true); + } + } + function TransformStreamDefaultControllerError(controller, e) { + TransformStreamError(controller._controlledTransformStream, e); + } + function TransformStreamDefaultControllerPerformTransform(controller, chunk) { + const transformPromise = controller._transformAlgorithm(chunk); + return transformPromiseWith(transformPromise, undefined, r => { + TransformStreamError(controller._controlledTransformStream, r); + throw r; + }); + } + function TransformStreamDefaultControllerTerminate(controller) { + const stream = controller._controlledTransformStream; + const readableController = stream._readable._readableStreamController; + ReadableStreamDefaultControllerClose(readableController); + const error = new TypeError('TransformStream terminated'); + TransformStreamErrorWritableAndUnblockWrite(stream, error); + } + // TransformStreamDefaultSink Algorithms + function TransformStreamDefaultSinkWriteAlgorithm(stream, chunk) { + const controller = stream._transformStreamController; + if (stream._backpressure) { + const backpressureChangePromise = stream._backpressureChangePromise; + return transformPromiseWith(backpressureChangePromise, () => { + const writable = stream._writable; + const state = writable._state; + if (state === 'erroring') { + throw writable._storedError; + } + return TransformStreamDefaultControllerPerformTransform(controller, chunk); + }); + } + return TransformStreamDefaultControllerPerformTransform(controller, chunk); + } + function TransformStreamDefaultSinkAbortAlgorithm(stream, reason) { + // abort() is not called synchronously, so it is possible for abort() to be called when the stream is already + // errored. + TransformStreamError(stream, reason); + return promiseResolvedWith(undefined); + } + function TransformStreamDefaultSinkCloseAlgorithm(stream) { + // stream._readable cannot change after construction, so caching it across a call to user code is safe. + const readable = stream._readable; + const controller = stream._transformStreamController; + const flushPromise = controller._flushAlgorithm(); + TransformStreamDefaultControllerClearAlgorithms(controller); + // Return a promise that is fulfilled with undefined on success. + return transformPromiseWith(flushPromise, () => { + if (readable._state === 'errored') { + throw readable._storedError; + } + ReadableStreamDefaultControllerClose(readable._readableStreamController); + }, r => { + TransformStreamError(stream, r); + throw readable._storedError; + }); + } + // TransformStreamDefaultSource Algorithms + function TransformStreamDefaultSourcePullAlgorithm(stream) { + // Invariant. Enforced by the promises returned by start() and pull(). + TransformStreamSetBackpressure(stream, false); + // Prevent the next pull() call until there is backpressure. + return stream._backpressureChangePromise; + } + // Helper functions for the TransformStreamDefaultController. + function defaultControllerBrandCheckException(name) { + return new TypeError(`TransformStreamDefaultController.prototype.${name} can only be used on a TransformStreamDefaultController`); + } + // Helper functions for the TransformStream. + function streamBrandCheckException(name) { + return new TypeError(`TransformStream.prototype.${name} can only be used on a TransformStream`); + } + + exports.ByteLengthQueuingStrategy = ByteLengthQueuingStrategy; + exports.CountQueuingStrategy = CountQueuingStrategy; + exports.ReadableByteStreamController = ReadableByteStreamController; + exports.ReadableStream = ReadableStream; + exports.ReadableStreamBYOBReader = ReadableStreamBYOBReader; + exports.ReadableStreamBYOBRequest = ReadableStreamBYOBRequest; + exports.ReadableStreamDefaultController = ReadableStreamDefaultController; + exports.ReadableStreamDefaultReader = ReadableStreamDefaultReader; + exports.TransformStream = TransformStream; + exports.TransformStreamDefaultController = TransformStreamDefaultController; + exports.WritableStream = WritableStream; + exports.WritableStreamDefaultController = WritableStreamDefaultController; + exports.WritableStreamDefaultWriter = WritableStreamDefaultWriter; + + Object.defineProperty(exports, '__esModule', { value: true }); + +}))); +//# sourceMappingURL=ponyfill.es2018.js.map + + +/***/ }), + +/***/ 4886: +/***/ ((module) => { + + + +var conversions = {}; +module.exports = conversions; + +function sign(x) { + return x < 0 ? -1 : 1; +} + +function evenRound(x) { + // Round x to the nearest integer, choosing the even integer if it lies halfway between two. + if ((x % 1) === 0.5 && (x & 1) === 0) { // [even number].5; round down (i.e. floor) + return Math.floor(x); + } else { + return Math.round(x); + } +} + +function createNumberConversion(bitLength, typeOpts) { + if (!typeOpts.unsigned) { + --bitLength; + } + const lowerBound = typeOpts.unsigned ? 0 : -Math.pow(2, bitLength); + const upperBound = Math.pow(2, bitLength) - 1; + + const moduloVal = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength) : Math.pow(2, bitLength); + const moduloBound = typeOpts.moduloBitLength ? Math.pow(2, typeOpts.moduloBitLength - 1) : Math.pow(2, bitLength - 1); + + return function(V, opts) { + if (!opts) opts = {}; + + let x = +V; + + if (opts.enforceRange) { + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite number"); + } + + x = sign(x) * Math.floor(Math.abs(x)); + if (x < lowerBound || x > upperBound) { + throw new TypeError("Argument is not in byte range"); + } + + return x; + } + + if (!isNaN(x) && opts.clamp) { + x = evenRound(x); + + if (x < lowerBound) x = lowerBound; + if (x > upperBound) x = upperBound; + return x; + } + + if (!Number.isFinite(x) || x === 0) { + return 0; + } + + x = sign(x) * Math.floor(Math.abs(x)); + x = x % moduloVal; + + if (!typeOpts.unsigned && x >= moduloBound) { + return x - moduloVal; + } else if (typeOpts.unsigned) { + if (x < 0) { + x += moduloVal; + } else if (x === -0) { // don't return negative zero + return 0; + } + } + + return x; + } +} + +conversions["void"] = function () { + return undefined; +}; + +conversions["boolean"] = function (val) { + return !!val; +}; + +conversions["byte"] = createNumberConversion(8, { unsigned: false }); +conversions["octet"] = createNumberConversion(8, { unsigned: true }); + +conversions["short"] = createNumberConversion(16, { unsigned: false }); +conversions["unsigned short"] = createNumberConversion(16, { unsigned: true }); + +conversions["long"] = createNumberConversion(32, { unsigned: false }); +conversions["unsigned long"] = createNumberConversion(32, { unsigned: true }); + +conversions["long long"] = createNumberConversion(32, { unsigned: false, moduloBitLength: 64 }); +conversions["unsigned long long"] = createNumberConversion(32, { unsigned: true, moduloBitLength: 64 }); + +conversions["double"] = function (V) { + const x = +V; + + if (!Number.isFinite(x)) { + throw new TypeError("Argument is not a finite floating-point value"); + } + + return x; +}; + +conversions["unrestricted double"] = function (V) { + const x = +V; + + if (isNaN(x)) { + throw new TypeError("Argument is NaN"); + } + + return x; +}; + +// not quite valid, but good enough for JS +conversions["float"] = conversions["double"]; +conversions["unrestricted float"] = conversions["unrestricted double"]; + +conversions["DOMString"] = function (V, opts) { + if (!opts) opts = {}; + + if (opts.treatNullAsEmptyString && V === null) { + return ""; + } + + return String(V); +}; + +conversions["ByteString"] = function (V, opts) { + const x = String(V); + let c = undefined; + for (let i = 0; (c = x.codePointAt(i)) !== undefined; ++i) { + if (c > 255) { + throw new TypeError("Argument is not a valid bytestring"); + } + } + + return x; +}; + +conversions["USVString"] = function (V) { + const S = String(V); + const n = S.length; + const U = []; + for (let i = 0; i < n; ++i) { + const c = S.charCodeAt(i); + if (c < 0xD800 || c > 0xDFFF) { + U.push(String.fromCodePoint(c)); + } else if (0xDC00 <= c && c <= 0xDFFF) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + if (i === n - 1) { + U.push(String.fromCodePoint(0xFFFD)); + } else { + const d = S.charCodeAt(i + 1); + if (0xDC00 <= d && d <= 0xDFFF) { + const a = c & 0x3FF; + const b = d & 0x3FF; + U.push(String.fromCodePoint((2 << 15) + (2 << 9) * a + b)); + ++i; + } else { + U.push(String.fromCodePoint(0xFFFD)); + } + } + } + } + + return U.join(''); +}; + +conversions["Date"] = function (V, opts) { + if (!(V instanceof Date)) { + throw new TypeError("Argument is not a Date object"); + } + if (isNaN(V)) { + return undefined; + } + + return V; +}; + +conversions["RegExp"] = function (V, opts) { + if (!(V instanceof RegExp)) { + V = new RegExp(V); + } + + return V; +}; + + +/***/ }), + +/***/ 7537: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +const usm = __nccwpck_require__(2158); + +exports.implementation = class URLImpl { + constructor(constructorArgs) { + const url = constructorArgs[0]; + const base = constructorArgs[1]; + + let parsedBase = null; + if (base !== undefined) { + parsedBase = usm.basicURLParse(base); + if (parsedBase === "failure") { + throw new TypeError("Invalid base URL"); + } + } + + const parsedURL = usm.basicURLParse(url, { baseURL: parsedBase }); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + + this._url = parsedURL; + + // TODO: query stuff + } + + get href() { + return usm.serializeURL(this._url); + } + + set href(v) { + const parsedURL = usm.basicURLParse(v); + if (parsedURL === "failure") { + throw new TypeError("Invalid URL"); + } + + this._url = parsedURL; + } + + get origin() { + return usm.serializeURLOrigin(this._url); + } + + get protocol() { + return this._url.scheme + ":"; + } + + set protocol(v) { + usm.basicURLParse(v + ":", { url: this._url, stateOverride: "scheme start" }); + } + + get username() { + return this._url.username; + } + + set username(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + + usm.setTheUsername(this._url, v); + } + + get password() { + return this._url.password; + } + + set password(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + + usm.setThePassword(this._url, v); + } + + get host() { + const url = this._url; + + if (url.host === null) { + return ""; + } + + if (url.port === null) { + return usm.serializeHost(url.host); + } + + return usm.serializeHost(url.host) + ":" + usm.serializeInteger(url.port); + } + + set host(v) { + if (this._url.cannotBeABaseURL) { + return; + } + + usm.basicURLParse(v, { url: this._url, stateOverride: "host" }); + } + + get hostname() { + if (this._url.host === null) { + return ""; + } + + return usm.serializeHost(this._url.host); + } + + set hostname(v) { + if (this._url.cannotBeABaseURL) { + return; + } + + usm.basicURLParse(v, { url: this._url, stateOverride: "hostname" }); + } + + get port() { + if (this._url.port === null) { + return ""; + } + + return usm.serializeInteger(this._url.port); + } + + set port(v) { + if (usm.cannotHaveAUsernamePasswordPort(this._url)) { + return; + } + + if (v === "") { + this._url.port = null; + } else { + usm.basicURLParse(v, { url: this._url, stateOverride: "port" }); + } + } + + get pathname() { + if (this._url.cannotBeABaseURL) { + return this._url.path[0]; + } + + if (this._url.path.length === 0) { + return ""; + } + + return "/" + this._url.path.join("/"); + } + + set pathname(v) { + if (this._url.cannotBeABaseURL) { + return; + } + + this._url.path = []; + usm.basicURLParse(v, { url: this._url, stateOverride: "path start" }); + } + + get search() { + if (this._url.query === null || this._url.query === "") { + return ""; + } + + return "?" + this._url.query; + } + + set search(v) { + // TODO: query stuff + + const url = this._url; + + if (v === "") { + url.query = null; + return; + } + + const input = v[0] === "?" ? v.substring(1) : v; + url.query = ""; + usm.basicURLParse(input, { url, stateOverride: "query" }); + } + + get hash() { + if (this._url.fragment === null || this._url.fragment === "") { + return ""; + } + + return "#" + this._url.fragment; + } + + set hash(v) { + if (v === "") { + this._url.fragment = null; + return; + } + + const input = v[0] === "#" ? v.substring(1) : v; + this._url.fragment = ""; + usm.basicURLParse(input, { url: this._url, stateOverride: "fragment" }); + } + + toJSON() { + return this.href; + } +}; + + +/***/ }), + +/***/ 3394: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +const conversions = __nccwpck_require__(4886); +const utils = __nccwpck_require__(3185); +const Impl = __nccwpck_require__(7537); + +const impl = utils.implSymbol; + +function URL(url) { + if (!this || this[impl] || !(this instanceof URL)) { + throw new TypeError("Failed to construct 'URL': Please use the 'new' operator, this DOM object constructor cannot be called as a function."); + } + if (arguments.length < 1) { + throw new TypeError("Failed to construct 'URL': 1 argument required, but only " + arguments.length + " present."); + } + const args = []; + for (let i = 0; i < arguments.length && i < 2; ++i) { + args[i] = arguments[i]; + } + args[0] = conversions["USVString"](args[0]); + if (args[1] !== undefined) { + args[1] = conversions["USVString"](args[1]); + } + + module.exports.setup(this, args); +} + +URL.prototype.toJSON = function toJSON() { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + const args = []; + for (let i = 0; i < arguments.length && i < 0; ++i) { + args[i] = arguments[i]; + } + return this[impl].toJSON.apply(this[impl], args); +}; +Object.defineProperty(URL.prototype, "href", { + get() { + return this[impl].href; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].href = V; + }, + enumerable: true, + configurable: true +}); + +URL.prototype.toString = function () { + if (!this || !module.exports.is(this)) { + throw new TypeError("Illegal invocation"); + } + return this.href; +}; + +Object.defineProperty(URL.prototype, "origin", { + get() { + return this[impl].origin; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "protocol", { + get() { + return this[impl].protocol; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].protocol = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "username", { + get() { + return this[impl].username; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].username = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "password", { + get() { + return this[impl].password; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].password = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "host", { + get() { + return this[impl].host; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].host = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "hostname", { + get() { + return this[impl].hostname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hostname = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "port", { + get() { + return this[impl].port; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].port = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "pathname", { + get() { + return this[impl].pathname; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].pathname = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "search", { + get() { + return this[impl].search; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].search = V; + }, + enumerable: true, + configurable: true +}); + +Object.defineProperty(URL.prototype, "hash", { + get() { + return this[impl].hash; + }, + set(V) { + V = conversions["USVString"](V); + this[impl].hash = V; + }, + enumerable: true, + configurable: true +}); + + +module.exports = { + is(obj) { + return !!obj && obj[impl] instanceof Impl.implementation; + }, + create(constructorArgs, privateData) { + let obj = Object.create(URL.prototype); + this.setup(obj, constructorArgs, privateData); + return obj; + }, + setup(obj, constructorArgs, privateData) { + if (!privateData) privateData = {}; + privateData.wrapper = obj; + + obj[impl] = new Impl.implementation(constructorArgs, privateData); + obj[impl][utils.wrapperSymbol] = obj; + }, + interface: URL, + expose: { + Window: { URL: URL }, + Worker: { URL: URL } + } +}; + + + +/***/ }), + +/***/ 8665: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +exports.URL = __nccwpck_require__(3394)["interface"]; +exports.serializeURL = __nccwpck_require__(2158).serializeURL; +exports.serializeURLOrigin = __nccwpck_require__(2158).serializeURLOrigin; +exports.basicURLParse = __nccwpck_require__(2158).basicURLParse; +exports.setTheUsername = __nccwpck_require__(2158).setTheUsername; +exports.setThePassword = __nccwpck_require__(2158).setThePassword; +exports.serializeHost = __nccwpck_require__(2158).serializeHost; +exports.serializeInteger = __nccwpck_require__(2158).serializeInteger; +exports.parseURL = __nccwpck_require__(2158).parseURL; + + +/***/ }), + +/***/ 2158: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +const punycode = __nccwpck_require__(5477); +const tr46 = __nccwpck_require__(4256); + +const specialSchemes = { + ftp: 21, + file: null, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443 +}; + +const failure = Symbol("failure"); + +function countSymbols(str) { + return punycode.ucs2.decode(str).length; +} + +function at(input, idx) { + const c = input[idx]; + return isNaN(c) ? undefined : String.fromCodePoint(c); +} + +function isASCIIDigit(c) { + return c >= 0x30 && c <= 0x39; +} + +function isASCIIAlpha(c) { + return (c >= 0x41 && c <= 0x5A) || (c >= 0x61 && c <= 0x7A); +} + +function isASCIIAlphanumeric(c) { + return isASCIIAlpha(c) || isASCIIDigit(c); +} + +function isASCIIHex(c) { + return isASCIIDigit(c) || (c >= 0x41 && c <= 0x46) || (c >= 0x61 && c <= 0x66); +} + +function isSingleDot(buffer) { + return buffer === "." || buffer.toLowerCase() === "%2e"; +} + +function isDoubleDot(buffer) { + buffer = buffer.toLowerCase(); + return buffer === ".." || buffer === "%2e." || buffer === ".%2e" || buffer === "%2e%2e"; +} + +function isWindowsDriveLetterCodePoints(cp1, cp2) { + return isASCIIAlpha(cp1) && (cp2 === 58 || cp2 === 124); +} + +function isWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && (string[1] === ":" || string[1] === "|"); +} + +function isNormalizedWindowsDriveLetterString(string) { + return string.length === 2 && isASCIIAlpha(string.codePointAt(0)) && string[1] === ":"; +} + +function containsForbiddenHostCodePoint(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|%|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function containsForbiddenHostCodePointExcludingPercent(string) { + return string.search(/\u0000|\u0009|\u000A|\u000D|\u0020|#|\/|:|\?|@|\[|\\|\]/) !== -1; +} + +function isSpecialScheme(scheme) { + return specialSchemes[scheme] !== undefined; +} + +function isSpecial(url) { + return isSpecialScheme(url.scheme); +} + +function defaultPort(scheme) { + return specialSchemes[scheme]; +} + +function percentEncode(c) { + let hex = c.toString(16).toUpperCase(); + if (hex.length === 1) { + hex = "0" + hex; + } + + return "%" + hex; +} + +function utf8PercentEncode(c) { + const buf = new Buffer(c); + + let str = ""; + + for (let i = 0; i < buf.length; ++i) { + str += percentEncode(buf[i]); + } + + return str; +} + +function utf8PercentDecode(str) { + const input = new Buffer(str); + const output = []; + for (let i = 0; i < input.length; ++i) { + if (input[i] !== 37) { + output.push(input[i]); + } else if (input[i] === 37 && isASCIIHex(input[i + 1]) && isASCIIHex(input[i + 2])) { + output.push(parseInt(input.slice(i + 1, i + 3).toString(), 16)); + i += 2; + } else { + output.push(input[i]); + } + } + return new Buffer(output).toString(); +} + +function isC0ControlPercentEncode(c) { + return c <= 0x1F || c > 0x7E; +} + +const extraPathPercentEncodeSet = new Set([32, 34, 35, 60, 62, 63, 96, 123, 125]); +function isPathPercentEncode(c) { + return isC0ControlPercentEncode(c) || extraPathPercentEncodeSet.has(c); +} + +const extraUserinfoPercentEncodeSet = + new Set([47, 58, 59, 61, 64, 91, 92, 93, 94, 124]); +function isUserinfoPercentEncode(c) { + return isPathPercentEncode(c) || extraUserinfoPercentEncodeSet.has(c); +} + +function percentEncodeChar(c, encodeSetPredicate) { + const cStr = String.fromCodePoint(c); + + if (encodeSetPredicate(c)) { + return utf8PercentEncode(cStr); + } + + return cStr; +} + +function parseIPv4Number(input) { + let R = 10; + + if (input.length >= 2 && input.charAt(0) === "0" && input.charAt(1).toLowerCase() === "x") { + input = input.substring(2); + R = 16; + } else if (input.length >= 2 && input.charAt(0) === "0") { + input = input.substring(1); + R = 8; + } + + if (input === "") { + return 0; + } + + const regex = R === 10 ? /[^0-9]/ : (R === 16 ? /[^0-9A-Fa-f]/ : /[^0-7]/); + if (regex.test(input)) { + return failure; + } + + return parseInt(input, R); +} + +function parseIPv4(input) { + const parts = input.split("."); + if (parts[parts.length - 1] === "") { + if (parts.length > 1) { + parts.pop(); + } + } + + if (parts.length > 4) { + return input; + } + + const numbers = []; + for (const part of parts) { + if (part === "") { + return input; + } + const n = parseIPv4Number(part); + if (n === failure) { + return input; + } + + numbers.push(n); + } + + for (let i = 0; i < numbers.length - 1; ++i) { + if (numbers[i] > 255) { + return failure; + } + } + if (numbers[numbers.length - 1] >= Math.pow(256, 5 - numbers.length)) { + return failure; + } + + let ipv4 = numbers.pop(); + let counter = 0; + + for (const n of numbers) { + ipv4 += n * Math.pow(256, 3 - counter); + ++counter; + } + + return ipv4; +} + +function serializeIPv4(address) { + let output = ""; + let n = address; + + for (let i = 1; i <= 4; ++i) { + output = String(n % 256) + output; + if (i !== 4) { + output = "." + output; + } + n = Math.floor(n / 256); + } + + return output; +} + +function parseIPv6(input) { + const address = [0, 0, 0, 0, 0, 0, 0, 0]; + let pieceIndex = 0; + let compress = null; + let pointer = 0; + + input = punycode.ucs2.decode(input); + + if (input[pointer] === 58) { + if (input[pointer + 1] !== 58) { + return failure; + } + + pointer += 2; + ++pieceIndex; + compress = pieceIndex; + } + + while (pointer < input.length) { + if (pieceIndex === 8) { + return failure; + } + + if (input[pointer] === 58) { + if (compress !== null) { + return failure; + } + ++pointer; + ++pieceIndex; + compress = pieceIndex; + continue; + } + + let value = 0; + let length = 0; + + while (length < 4 && isASCIIHex(input[pointer])) { + value = value * 0x10 + parseInt(at(input, pointer), 16); + ++pointer; + ++length; + } + + if (input[pointer] === 46) { + if (length === 0) { + return failure; + } + + pointer -= length; + + if (pieceIndex > 6) { + return failure; + } + + let numbersSeen = 0; + + while (input[pointer] !== undefined) { + let ipv4Piece = null; + + if (numbersSeen > 0) { + if (input[pointer] === 46 && numbersSeen < 4) { + ++pointer; + } else { + return failure; + } + } + + if (!isASCIIDigit(input[pointer])) { + return failure; + } + + while (isASCIIDigit(input[pointer])) { + const number = parseInt(at(input, pointer)); + if (ipv4Piece === null) { + ipv4Piece = number; + } else if (ipv4Piece === 0) { + return failure; + } else { + ipv4Piece = ipv4Piece * 10 + number; + } + if (ipv4Piece > 255) { + return failure; + } + ++pointer; + } + + address[pieceIndex] = address[pieceIndex] * 0x100 + ipv4Piece; + + ++numbersSeen; + + if (numbersSeen === 2 || numbersSeen === 4) { + ++pieceIndex; + } + } + + if (numbersSeen !== 4) { + return failure; + } + + break; + } else if (input[pointer] === 58) { + ++pointer; + if (input[pointer] === undefined) { + return failure; + } + } else if (input[pointer] !== undefined) { + return failure; + } + + address[pieceIndex] = value; + ++pieceIndex; + } + + if (compress !== null) { + let swaps = pieceIndex - compress; + pieceIndex = 7; + while (pieceIndex !== 0 && swaps > 0) { + const temp = address[compress + swaps - 1]; + address[compress + swaps - 1] = address[pieceIndex]; + address[pieceIndex] = temp; + --pieceIndex; + --swaps; + } + } else if (compress === null && pieceIndex !== 8) { + return failure; + } + + return address; +} + +function serializeIPv6(address) { + let output = ""; + const seqResult = findLongestZeroSequence(address); + const compress = seqResult.idx; + let ignore0 = false; + + for (let pieceIndex = 0; pieceIndex <= 7; ++pieceIndex) { + if (ignore0 && address[pieceIndex] === 0) { + continue; + } else if (ignore0) { + ignore0 = false; + } + + if (compress === pieceIndex) { + const separator = pieceIndex === 0 ? "::" : ":"; + output += separator; + ignore0 = true; + continue; + } + + output += address[pieceIndex].toString(16); + + if (pieceIndex !== 7) { + output += ":"; + } + } + + return output; +} + +function parseHost(input, isSpecialArg) { + if (input[0] === "[") { + if (input[input.length - 1] !== "]") { + return failure; + } + + return parseIPv6(input.substring(1, input.length - 1)); + } + + if (!isSpecialArg) { + return parseOpaqueHost(input); + } + + const domain = utf8PercentDecode(input); + const asciiDomain = tr46.toASCII(domain, false, tr46.PROCESSING_OPTIONS.NONTRANSITIONAL, false); + if (asciiDomain === null) { + return failure; + } + + if (containsForbiddenHostCodePoint(asciiDomain)) { + return failure; + } + + const ipv4Host = parseIPv4(asciiDomain); + if (typeof ipv4Host === "number" || ipv4Host === failure) { + return ipv4Host; + } + + return asciiDomain; +} + +function parseOpaqueHost(input) { + if (containsForbiddenHostCodePointExcludingPercent(input)) { + return failure; + } + + let output = ""; + const decoded = punycode.ucs2.decode(input); + for (let i = 0; i < decoded.length; ++i) { + output += percentEncodeChar(decoded[i], isC0ControlPercentEncode); + } + return output; +} + +function findLongestZeroSequence(arr) { + let maxIdx = null; + let maxLen = 1; // only find elements > 1 + let currStart = null; + let currLen = 0; + + for (let i = 0; i < arr.length; ++i) { + if (arr[i] !== 0) { + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + currStart = null; + currLen = 0; + } else { + if (currStart === null) { + currStart = i; + } + ++currLen; + } + } + + // if trailing zeros + if (currLen > maxLen) { + maxIdx = currStart; + maxLen = currLen; + } + + return { + idx: maxIdx, + len: maxLen + }; +} + +function serializeHost(host) { + if (typeof host === "number") { + return serializeIPv4(host); + } + + // IPv6 serializer + if (host instanceof Array) { + return "[" + serializeIPv6(host) + "]"; + } + + return host; +} + +function trimControlChars(url) { + return url.replace(/^[\u0000-\u001F\u0020]+|[\u0000-\u001F\u0020]+$/g, ""); +} + +function trimTabAndNewline(url) { + return url.replace(/\u0009|\u000A|\u000D/g, ""); +} + +function shortenPath(url) { + const path = url.path; + if (path.length === 0) { + return; + } + if (url.scheme === "file" && path.length === 1 && isNormalizedWindowsDriveLetter(path[0])) { + return; + } + + path.pop(); +} + +function includesCredentials(url) { + return url.username !== "" || url.password !== ""; +} + +function cannotHaveAUsernamePasswordPort(url) { + return url.host === null || url.host === "" || url.cannotBeABaseURL || url.scheme === "file"; +} + +function isNormalizedWindowsDriveLetter(string) { + return /^[A-Za-z]:$/.test(string); +} + +function URLStateMachine(input, base, encodingOverride, url, stateOverride) { + this.pointer = 0; + this.input = input; + this.base = base || null; + this.encodingOverride = encodingOverride || "utf-8"; + this.stateOverride = stateOverride; + this.url = url; + this.failure = false; + this.parseError = false; + + if (!this.url) { + this.url = { + scheme: "", + username: "", + password: "", + host: null, + port: null, + path: [], + query: null, + fragment: null, + + cannotBeABaseURL: false + }; + + const res = trimControlChars(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + } + + const res = trimTabAndNewline(this.input); + if (res !== this.input) { + this.parseError = true; + } + this.input = res; + + this.state = stateOverride || "scheme start"; + + this.buffer = ""; + this.atFlag = false; + this.arrFlag = false; + this.passwordTokenSeenFlag = false; + + this.input = punycode.ucs2.decode(this.input); + + for (; this.pointer <= this.input.length; ++this.pointer) { + const c = this.input[this.pointer]; + const cStr = isNaN(c) ? undefined : String.fromCodePoint(c); + + // exec state machine + const ret = this["parse " + this.state](c, cStr); + if (!ret) { + break; // terminate algorithm + } else if (ret === failure) { + this.failure = true; + break; + } + } +} + +URLStateMachine.prototype["parse scheme start"] = function parseSchemeStart(c, cStr) { + if (isASCIIAlpha(c)) { + this.buffer += cStr.toLowerCase(); + this.state = "scheme"; + } else if (!this.stateOverride) { + this.state = "no scheme"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse scheme"] = function parseScheme(c, cStr) { + if (isASCIIAlphanumeric(c) || c === 43 || c === 45 || c === 46) { + this.buffer += cStr.toLowerCase(); + } else if (c === 58) { + if (this.stateOverride) { + if (isSpecial(this.url) && !isSpecialScheme(this.buffer)) { + return false; + } + + if (!isSpecial(this.url) && isSpecialScheme(this.buffer)) { + return false; + } + + if ((includesCredentials(this.url) || this.url.port !== null) && this.buffer === "file") { + return false; + } + + if (this.url.scheme === "file" && (this.url.host === "" || this.url.host === null)) { + return false; + } + } + this.url.scheme = this.buffer; + this.buffer = ""; + if (this.stateOverride) { + return false; + } + if (this.url.scheme === "file") { + if (this.input[this.pointer + 1] !== 47 || this.input[this.pointer + 2] !== 47) { + this.parseError = true; + } + this.state = "file"; + } else if (isSpecial(this.url) && this.base !== null && this.base.scheme === this.url.scheme) { + this.state = "special relative or authority"; + } else if (isSpecial(this.url)) { + this.state = "special authority slashes"; + } else if (this.input[this.pointer + 1] === 47) { + this.state = "path or authority"; + ++this.pointer; + } else { + this.url.cannotBeABaseURL = true; + this.url.path.push(""); + this.state = "cannot-be-a-base-URL path"; + } + } else if (!this.stateOverride) { + this.buffer = ""; + this.state = "no scheme"; + this.pointer = -1; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +URLStateMachine.prototype["parse no scheme"] = function parseNoScheme(c) { + if (this.base === null || (this.base.cannotBeABaseURL && c !== 35)) { + return failure; + } else if (this.base.cannotBeABaseURL && c === 35) { + this.url.scheme = this.base.scheme; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.url.cannotBeABaseURL = true; + this.state = "fragment"; + } else if (this.base.scheme === "file") { + this.state = "file"; + --this.pointer; + } else { + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special relative or authority"] = function parseSpecialRelativeOrAuthority(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "relative"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse path or authority"] = function parsePathOrAuthority(c) { + if (c === 47) { + this.state = "authority"; + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative"] = function parseRelative(c) { + this.url.scheme = this.base.scheme; + if (isNaN(c)) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 47) { + this.state = "relative slash"; + } else if (c === 63) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else if (isSpecial(this.url) && c === 92) { + this.parseError = true; + this.state = "relative slash"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.url.path = this.base.path.slice(0, this.base.path.length - 1); + + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse relative slash"] = function parseRelativeSlash(c) { + if (isSpecial(this.url) && (c === 47 || c === 92)) { + if (c === 92) { + this.parseError = true; + } + this.state = "special authority ignore slashes"; + } else if (c === 47) { + this.state = "authority"; + } else { + this.url.username = this.base.username; + this.url.password = this.base.password; + this.url.host = this.base.host; + this.url.port = this.base.port; + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority slashes"] = function parseSpecialAuthoritySlashes(c) { + if (c === 47 && this.input[this.pointer + 1] === 47) { + this.state = "special authority ignore slashes"; + ++this.pointer; + } else { + this.parseError = true; + this.state = "special authority ignore slashes"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse special authority ignore slashes"] = function parseSpecialAuthorityIgnoreSlashes(c) { + if (c !== 47 && c !== 92) { + this.state = "authority"; + --this.pointer; + } else { + this.parseError = true; + } + + return true; +}; + +URLStateMachine.prototype["parse authority"] = function parseAuthority(c, cStr) { + if (c === 64) { + this.parseError = true; + if (this.atFlag) { + this.buffer = "%40" + this.buffer; + } + this.atFlag = true; + + // careful, this is based on buffer and has its own pointer (this.pointer != pointer) and inner chars + const len = countSymbols(this.buffer); + for (let pointer = 0; pointer < len; ++pointer) { + const codePoint = this.buffer.codePointAt(pointer); + + if (codePoint === 58 && !this.passwordTokenSeenFlag) { + this.passwordTokenSeenFlag = true; + continue; + } + const encodedCodePoints = percentEncodeChar(codePoint, isUserinfoPercentEncode); + if (this.passwordTokenSeenFlag) { + this.url.password += encodedCodePoints; + } else { + this.url.username += encodedCodePoints; + } + } + this.buffer = ""; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + if (this.atFlag && this.buffer === "") { + this.parseError = true; + return failure; + } + this.pointer -= countSymbols(this.buffer) + 1; + this.buffer = ""; + this.state = "host"; + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse hostname"] = +URLStateMachine.prototype["parse host"] = function parseHostName(c, cStr) { + if (this.stateOverride && this.url.scheme === "file") { + --this.pointer; + this.state = "file host"; + } else if (c === 58 && !this.arrFlag) { + if (this.buffer === "") { + this.parseError = true; + return failure; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "port"; + if (this.stateOverride === "hostname") { + return false; + } + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92)) { + --this.pointer; + if (isSpecial(this.url) && this.buffer === "") { + this.parseError = true; + return failure; + } else if (this.stateOverride && this.buffer === "" && + (includesCredentials(this.url) || this.url.port !== null)) { + this.parseError = true; + return false; + } + + const host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + + this.url.host = host; + this.buffer = ""; + this.state = "path start"; + if (this.stateOverride) { + return false; + } + } else { + if (c === 91) { + this.arrFlag = true; + } else if (c === 93) { + this.arrFlag = false; + } + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse port"] = function parsePort(c, cStr) { + if (isASCIIDigit(c)) { + this.buffer += cStr; + } else if (isNaN(c) || c === 47 || c === 63 || c === 35 || + (isSpecial(this.url) && c === 92) || + this.stateOverride) { + if (this.buffer !== "") { + const port = parseInt(this.buffer); + if (port > Math.pow(2, 16) - 1) { + this.parseError = true; + return failure; + } + this.url.port = port === defaultPort(this.url.scheme) ? null : port; + this.buffer = ""; + } + if (this.stateOverride) { + return false; + } + this.state = "path start"; + --this.pointer; + } else { + this.parseError = true; + return failure; + } + + return true; +}; + +const fileOtherwiseCodePoints = new Set([47, 92, 63, 35]); + +URLStateMachine.prototype["parse file"] = function parseFile(c) { + this.url.scheme = "file"; + + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file slash"; + } else if (this.base !== null && this.base.scheme === "file") { + if (isNaN(c)) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + } else if (c === 63) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + this.url.query = this.base.query; + this.url.fragment = ""; + this.state = "fragment"; + } else { + if (this.input.length - this.pointer - 1 === 0 || // remaining consists of 0 code points + !isWindowsDriveLetterCodePoints(c, this.input[this.pointer + 1]) || + (this.input.length - this.pointer - 1 >= 2 && // remaining has at least 2 code points + !fileOtherwiseCodePoints.has(this.input[this.pointer + 2]))) { + this.url.host = this.base.host; + this.url.path = this.base.path.slice(); + shortenPath(this.url); + } else { + this.parseError = true; + } + + this.state = "path"; + --this.pointer; + } + } else { + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file slash"] = function parseFileSlash(c) { + if (c === 47 || c === 92) { + if (c === 92) { + this.parseError = true; + } + this.state = "file host"; + } else { + if (this.base !== null && this.base.scheme === "file") { + if (isNormalizedWindowsDriveLetterString(this.base.path[0])) { + this.url.path.push(this.base.path[0]); + } else { + this.url.host = this.base.host; + } + } + this.state = "path"; + --this.pointer; + } + + return true; +}; + +URLStateMachine.prototype["parse file host"] = function parseFileHost(c, cStr) { + if (isNaN(c) || c === 47 || c === 92 || c === 63 || c === 35) { + --this.pointer; + if (!this.stateOverride && isWindowsDriveLetterString(this.buffer)) { + this.parseError = true; + this.state = "path"; + } else if (this.buffer === "") { + this.url.host = ""; + if (this.stateOverride) { + return false; + } + this.state = "path start"; + } else { + let host = parseHost(this.buffer, isSpecial(this.url)); + if (host === failure) { + return failure; + } + if (host === "localhost") { + host = ""; + } + this.url.host = host; + + if (this.stateOverride) { + return false; + } + + this.buffer = ""; + this.state = "path start"; + } + } else { + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse path start"] = function parsePathStart(c) { + if (isSpecial(this.url)) { + if (c === 92) { + this.parseError = true; + } + this.state = "path"; + + if (c !== 47 && c !== 92) { + --this.pointer; + } + } else if (!this.stateOverride && c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (!this.stateOverride && c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else if (c !== undefined) { + this.state = "path"; + if (c !== 47) { + --this.pointer; + } + } + + return true; +}; + +URLStateMachine.prototype["parse path"] = function parsePath(c) { + if (isNaN(c) || c === 47 || (isSpecial(this.url) && c === 92) || + (!this.stateOverride && (c === 63 || c === 35))) { + if (isSpecial(this.url) && c === 92) { + this.parseError = true; + } + + if (isDoubleDot(this.buffer)) { + shortenPath(this.url); + if (c !== 47 && !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } + } else if (isSingleDot(this.buffer) && c !== 47 && + !(isSpecial(this.url) && c === 92)) { + this.url.path.push(""); + } else if (!isSingleDot(this.buffer)) { + if (this.url.scheme === "file" && this.url.path.length === 0 && isWindowsDriveLetterString(this.buffer)) { + if (this.url.host !== "" && this.url.host !== null) { + this.parseError = true; + this.url.host = ""; + } + this.buffer = this.buffer[0] + ":"; + } + this.url.path.push(this.buffer); + } + this.buffer = ""; + if (this.url.scheme === "file" && (c === undefined || c === 63 || c === 35)) { + while (this.url.path.length > 1 && this.url.path[0] === "") { + this.parseError = true; + this.url.path.shift(); + } + } + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += percentEncodeChar(c, isPathPercentEncode); + } + + return true; +}; + +URLStateMachine.prototype["parse cannot-be-a-base-URL path"] = function parseCannotBeABaseURLPath(c) { + if (c === 63) { + this.url.query = ""; + this.state = "query"; + } else if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } else { + // TODO: Add: not a URL code point + if (!isNaN(c) && c !== 37) { + this.parseError = true; + } + + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + if (!isNaN(c)) { + this.url.path[0] = this.url.path[0] + percentEncodeChar(c, isC0ControlPercentEncode); + } + } + + return true; +}; + +URLStateMachine.prototype["parse query"] = function parseQuery(c, cStr) { + if (isNaN(c) || (!this.stateOverride && c === 35)) { + if (!isSpecial(this.url) || this.url.scheme === "ws" || this.url.scheme === "wss") { + this.encodingOverride = "utf-8"; + } + + const buffer = new Buffer(this.buffer); // TODO: Use encoding override instead + for (let i = 0; i < buffer.length; ++i) { + if (buffer[i] < 0x21 || buffer[i] > 0x7E || buffer[i] === 0x22 || buffer[i] === 0x23 || + buffer[i] === 0x3C || buffer[i] === 0x3E) { + this.url.query += percentEncode(buffer[i]); + } else { + this.url.query += String.fromCodePoint(buffer[i]); + } + } + + this.buffer = ""; + if (c === 35) { + this.url.fragment = ""; + this.state = "fragment"; + } + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.buffer += cStr; + } + + return true; +}; + +URLStateMachine.prototype["parse fragment"] = function parseFragment(c) { + if (isNaN(c)) { // do nothing + } else if (c === 0x0) { + this.parseError = true; + } else { + // TODO: If c is not a URL code point and not "%", parse error. + if (c === 37 && + (!isASCIIHex(this.input[this.pointer + 1]) || + !isASCIIHex(this.input[this.pointer + 2]))) { + this.parseError = true; + } + + this.url.fragment += percentEncodeChar(c, isC0ControlPercentEncode); + } + + return true; +}; + +function serializeURL(url, excludeFragment) { + let output = url.scheme + ":"; + if (url.host !== null) { + output += "//"; + + if (url.username !== "" || url.password !== "") { + output += url.username; + if (url.password !== "") { + output += ":" + url.password; + } + output += "@"; + } + + output += serializeHost(url.host); + + if (url.port !== null) { + output += ":" + url.port; + } + } else if (url.host === null && url.scheme === "file") { + output += "//"; + } + + if (url.cannotBeABaseURL) { + output += url.path[0]; + } else { + for (const string of url.path) { + output += "/" + string; + } + } + + if (url.query !== null) { + output += "?" + url.query; + } + + if (!excludeFragment && url.fragment !== null) { + output += "#" + url.fragment; + } + + return output; +} + +function serializeOrigin(tuple) { + let result = tuple.scheme + "://"; + result += serializeHost(tuple.host); + + if (tuple.port !== null) { + result += ":" + tuple.port; + } + + return result; +} + +module.exports.serializeURL = serializeURL; + +module.exports.serializeURLOrigin = function (url) { + // https://url.spec.whatwg.org/#concept-url-origin + switch (url.scheme) { + case "blob": + try { + return module.exports.serializeURLOrigin(module.exports.parseURL(url.path[0])); + } catch (e) { + // serializing an opaque origin returns "null" + return "null"; + } + case "ftp": + case "gopher": + case "http": + case "https": + case "ws": + case "wss": + return serializeOrigin({ + scheme: url.scheme, + host: url.host, + port: url.port + }); + case "file": + // spec says "exercise to the reader", chrome says "file://" + return "file://"; + default: + // serializing an opaque origin returns "null" + return "null"; + } +}; + +module.exports.basicURLParse = function (input, options) { + if (options === undefined) { + options = {}; + } + + const usm = new URLStateMachine(input, options.baseURL, options.encodingOverride, options.url, options.stateOverride); + if (usm.failure) { + return "failure"; + } + + return usm.url; +}; + +module.exports.setTheUsername = function (url, username) { + url.username = ""; + const decoded = punycode.ucs2.decode(username); + for (let i = 0; i < decoded.length; ++i) { + url.username += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.setThePassword = function (url, password) { + url.password = ""; + const decoded = punycode.ucs2.decode(password); + for (let i = 0; i < decoded.length; ++i) { + url.password += percentEncodeChar(decoded[i], isUserinfoPercentEncode); + } +}; + +module.exports.serializeHost = serializeHost; + +module.exports.cannotHaveAUsernamePasswordPort = cannotHaveAUsernamePasswordPort; + +module.exports.serializeInteger = function (integer) { + return String(integer); +}; + +module.exports.parseURL = function (input, options) { + if (options === undefined) { + options = {}; + } + + // We don't handle blobs, so this just delegates: + return module.exports.basicURLParse(input, { baseURL: options.baseURL, encodingOverride: options.encodingOverride }); +}; + + +/***/ }), + +/***/ 3185: +/***/ ((module) => { + + + +module.exports.mixin = function mixin(target, source) { + const keys = Object.getOwnPropertyNames(source); + for (let i = 0; i < keys.length; ++i) { + Object.defineProperty(target, keys[i], Object.getOwnPropertyDescriptor(source, keys[i])); + } +}; + +module.exports.wrapperSymbol = Symbol("wrapper"); +module.exports.implSymbol = Symbol("impl"); + +module.exports.wrapperForImpl = function (impl) { + return impl[module.exports.wrapperSymbol]; +}; + +module.exports.implForWrapper = function (wrapper) { + return wrapper[module.exports.implSymbol]; +}; + + + +/***/ }), + +/***/ 2940: +/***/ ((module) => { + +// Returns a wrapper function that returns a wrapped callback +// The wrapper function should do some stuff, and return a +// presumably different callback function. +// This makes sure that own properties are retained, so that +// decorations and such are not lost along the way. +module.exports = wrappy +function wrappy (fn, cb) { + if (fn && cb) return wrappy(fn)(cb) + + if (typeof fn !== 'function') + throw new TypeError('need wrapper function') + + Object.keys(fn).forEach(function (k) { + wrapper[k] = fn[k] + }) + + return wrapper + + function wrapper() { + var args = new Array(arguments.length) + for (var i = 0; i < args.length; i++) { + args[i] = arguments[i] + } + var ret = fn.apply(this, args) + var cb = args[args.length-1] + if (typeof ret === 'function' && ret !== cb) { + Object.keys(cb).forEach(function (k) { + ret[k] = cb[k] + }) + } + return ret + } +} + + +/***/ }), + +/***/ 1635: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var iconvLite = __nccwpck_require__(3225); + +// Expose to the world +module.exports.O = convert; + +/** + * Convert encoding of an UTF-8 string or a buffer + * + * @param {String|Buffer} str String to be converted + * @param {String} to Encoding to be converted to + * @param {String} [from='UTF-8'] Encoding to be converted from + * @return {Buffer} Encoded string + */ +function convert(str, to, from) { + from = checkEncoding(from || 'UTF-8'); + to = checkEncoding(to || 'UTF-8'); + str = str || ''; + + var result; + + if (from !== 'UTF-8' && typeof str === 'string') { + str = Buffer.from(str, 'binary'); + } + + if (from === to) { + if (typeof str === 'string') { + result = Buffer.from(str); + } else { + result = str; + } + } else { + try { + result = convertIconvLite(str, to, from); + } catch (E) { + console.error(E); + result = str; + } + } + + if (typeof result === 'string') { + result = Buffer.from(result, 'utf-8'); + } + + return result; +} + +/** + * Convert encoding of astring with iconv-lite + * + * @param {String|Buffer} str String to be converted + * @param {String} to Encoding to be converted to + * @param {String} [from='UTF-8'] Encoding to be converted from + * @return {Buffer} Encoded string + */ +function convertIconvLite(str, to, from) { + if (to === 'UTF-8') { + return iconvLite.decode(str, from); + } else if (from === 'UTF-8') { + return iconvLite.encode(str, to); + } else { + return iconvLite.encode(iconvLite.decode(str, from), to); + } +} + +/** + * Converts charset name if needed + * + * @param {String} name Character set + * @return {String} Character set name + */ +function checkEncoding(name) { + return (name || '') + .toString() + .trim() + .replace(/^latin[\-_]?(\d+)$/i, 'ISO-8859-$1') + .replace(/^win(?:dows)?[\-_]?(\d+)$/i, 'WINDOWS-$1') + .replace(/^utf[\-_]?(\d+)$/i, 'UTF-$1') + .replace(/^ks_c_5601\-1987$/i, 'CP949') + .replace(/^us[\-_]?ascii$/i, 'ASCII') + .toUpperCase(); +} + + +/***/ }), + +/***/ 2507: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// Multibyte codec. In this scheme, a character is represented by 1 or more bytes. +// Our codec supports UTF-16 surrogates, extensions for GB18030 and unicode sequences. +// To save memory and loading time, we read table files only when requested. + +exports._dbcs = DBCSCodec; + +var UNASSIGNED = -1, + GB18030_CODE = -2, + SEQ_START = -10, + NODE_START = -1000, + UNASSIGNED_NODE = new Array(0x100), + DEF_CHAR = -1; + +for (var i = 0; i < 0x100; i++) + UNASSIGNED_NODE[i] = UNASSIGNED; + + +// Class DBCSCodec reads and initializes mapping tables. +function DBCSCodec(codecOptions, iconv) { + this.encodingName = codecOptions.encodingName; + if (!codecOptions) + throw new Error("DBCS codec is called without the data.") + if (!codecOptions.table) + throw new Error("Encoding '" + this.encodingName + "' has no data."); + + // Load tables. + var mappingTable = codecOptions.table(); + + + // Decode tables: MBCS -> Unicode. + + // decodeTables is a trie, encoded as an array of arrays of integers. Internal arrays are trie nodes and all have len = 256. + // Trie root is decodeTables[0]. + // Values: >= 0 -> unicode character code. can be > 0xFFFF + // == UNASSIGNED -> unknown/unassigned sequence. + // == GB18030_CODE -> this is the end of a GB18030 4-byte sequence. + // <= NODE_START -> index of the next node in our trie to process next byte. + // <= SEQ_START -> index of the start of a character code sequence, in decodeTableSeq. + this.decodeTables = []; + this.decodeTables[0] = UNASSIGNED_NODE.slice(0); // Create root node. + + // Sometimes a MBCS char corresponds to a sequence of unicode chars. We store them as arrays of integers here. + this.decodeTableSeq = []; + + // Actual mapping tables consist of chunks. Use them to fill up decode tables. + for (var i = 0; i < mappingTable.length; i++) + this._addDecodeChunk(mappingTable[i]); + + // Load & create GB18030 tables when needed. + if (typeof codecOptions.gb18030 === 'function') { + this.gb18030 = codecOptions.gb18030(); // Load GB18030 ranges. + + // Add GB18030 common decode nodes. + var commonThirdByteNodeIdx = this.decodeTables.length; + this.decodeTables.push(UNASSIGNED_NODE.slice(0)); + + var commonFourthByteNodeIdx = this.decodeTables.length; + this.decodeTables.push(UNASSIGNED_NODE.slice(0)); + + // Fill out the tree + var firstByteNode = this.decodeTables[0]; + for (var i = 0x81; i <= 0xFE; i++) { + var secondByteNode = this.decodeTables[NODE_START - firstByteNode[i]]; + for (var j = 0x30; j <= 0x39; j++) { + if (secondByteNode[j] === UNASSIGNED) { + secondByteNode[j] = NODE_START - commonThirdByteNodeIdx; + } else if (secondByteNode[j] > NODE_START) { + throw new Error("gb18030 decode tables conflict at byte 2"); + } + + var thirdByteNode = this.decodeTables[NODE_START - secondByteNode[j]]; + for (var k = 0x81; k <= 0xFE; k++) { + if (thirdByteNode[k] === UNASSIGNED) { + thirdByteNode[k] = NODE_START - commonFourthByteNodeIdx; + } else if (thirdByteNode[k] === NODE_START - commonFourthByteNodeIdx) { + continue; + } else if (thirdByteNode[k] > NODE_START) { + throw new Error("gb18030 decode tables conflict at byte 3"); + } + + var fourthByteNode = this.decodeTables[NODE_START - thirdByteNode[k]]; + for (var l = 0x30; l <= 0x39; l++) { + if (fourthByteNode[l] === UNASSIGNED) + fourthByteNode[l] = GB18030_CODE; + } + } + } + } + } + + this.defaultCharUnicode = iconv.defaultCharUnicode; + + + // Encode tables: Unicode -> DBCS. + + // `encodeTable` is array mapping from unicode char to encoded char. All its values are integers for performance. + // Because it can be sparse, it is represented as array of buckets by 256 chars each. Bucket can be null. + // Values: >= 0 -> it is a normal char. Write the value (if <=256 then 1 byte, if <=65536 then 2 bytes, etc.). + // == UNASSIGNED -> no conversion found. Output a default char. + // <= SEQ_START -> it's an index in encodeTableSeq, see below. The character starts a sequence. + this.encodeTable = []; + + // `encodeTableSeq` is used when a sequence of unicode characters is encoded as a single code. We use a tree of + // objects where keys correspond to characters in sequence and leafs are the encoded dbcs values. A special DEF_CHAR key + // means end of sequence (needed when one sequence is a strict subsequence of another). + // Objects are kept separately from encodeTable to increase performance. + this.encodeTableSeq = []; + + // Some chars can be decoded, but need not be encoded. + var skipEncodeChars = {}; + if (codecOptions.encodeSkipVals) + for (var i = 0; i < codecOptions.encodeSkipVals.length; i++) { + var val = codecOptions.encodeSkipVals[i]; + if (typeof val === 'number') + skipEncodeChars[val] = true; + else + for (var j = val.from; j <= val.to; j++) + skipEncodeChars[j] = true; + } + + // Use decode trie to recursively fill out encode tables. + this._fillEncodeTable(0, 0, skipEncodeChars); + + // Add more encoding pairs when needed. + if (codecOptions.encodeAdd) { + for (var uChar in codecOptions.encodeAdd) + if (Object.prototype.hasOwnProperty.call(codecOptions.encodeAdd, uChar)) + this._setEncodeChar(uChar.charCodeAt(0), codecOptions.encodeAdd[uChar]); + } + + this.defCharSB = this.encodeTable[0][iconv.defaultCharSingleByte.charCodeAt(0)]; + if (this.defCharSB === UNASSIGNED) this.defCharSB = this.encodeTable[0]['?']; + if (this.defCharSB === UNASSIGNED) this.defCharSB = "?".charCodeAt(0); +} + +DBCSCodec.prototype.encoder = DBCSEncoder; +DBCSCodec.prototype.decoder = DBCSDecoder; + +// Decoder helpers +DBCSCodec.prototype._getDecodeTrieNode = function(addr) { + var bytes = []; + for (; addr > 0; addr >>>= 8) + bytes.push(addr & 0xFF); + if (bytes.length == 0) + bytes.push(0); + + var node = this.decodeTables[0]; + for (var i = bytes.length-1; i > 0; i--) { // Traverse nodes deeper into the trie. + var val = node[bytes[i]]; + + if (val == UNASSIGNED) { // Create new node. + node[bytes[i]] = NODE_START - this.decodeTables.length; + this.decodeTables.push(node = UNASSIGNED_NODE.slice(0)); + } + else if (val <= NODE_START) { // Existing node. + node = this.decodeTables[NODE_START - val]; + } + else + throw new Error("Overwrite byte in " + this.encodingName + ", addr: " + addr.toString(16)); + } + return node; +} + + +DBCSCodec.prototype._addDecodeChunk = function(chunk) { + // First element of chunk is the hex mbcs code where we start. + var curAddr = parseInt(chunk[0], 16); + + // Choose the decoding node where we'll write our chars. + var writeTable = this._getDecodeTrieNode(curAddr); + curAddr = curAddr & 0xFF; + + // Write all other elements of the chunk to the table. + for (var k = 1; k < chunk.length; k++) { + var part = chunk[k]; + if (typeof part === "string") { // String, write as-is. + for (var l = 0; l < part.length;) { + var code = part.charCodeAt(l++); + if (0xD800 <= code && code < 0xDC00) { // Decode surrogate + var codeTrail = part.charCodeAt(l++); + if (0xDC00 <= codeTrail && codeTrail < 0xE000) + writeTable[curAddr++] = 0x10000 + (code - 0xD800) * 0x400 + (codeTrail - 0xDC00); + else + throw new Error("Incorrect surrogate pair in " + this.encodingName + " at chunk " + chunk[0]); + } + else if (0x0FF0 < code && code <= 0x0FFF) { // Character sequence (our own encoding used) + var len = 0xFFF - code + 2; + var seq = []; + for (var m = 0; m < len; m++) + seq.push(part.charCodeAt(l++)); // Simple variation: don't support surrogates or subsequences in seq. + + writeTable[curAddr++] = SEQ_START - this.decodeTableSeq.length; + this.decodeTableSeq.push(seq); + } + else + writeTable[curAddr++] = code; // Basic char + } + } + else if (typeof part === "number") { // Integer, meaning increasing sequence starting with prev character. + var charCode = writeTable[curAddr - 1] + 1; + for (var l = 0; l < part; l++) + writeTable[curAddr++] = charCode++; + } + else + throw new Error("Incorrect type '" + typeof part + "' given in " + this.encodingName + " at chunk " + chunk[0]); + } + if (curAddr > 0xFF) + throw new Error("Incorrect chunk in " + this.encodingName + " at addr " + chunk[0] + ": too long" + curAddr); +} + +// Encoder helpers +DBCSCodec.prototype._getEncodeBucket = function(uCode) { + var high = uCode >> 8; // This could be > 0xFF because of astral characters. + if (this.encodeTable[high] === undefined) + this.encodeTable[high] = UNASSIGNED_NODE.slice(0); // Create bucket on demand. + return this.encodeTable[high]; +} + +DBCSCodec.prototype._setEncodeChar = function(uCode, dbcsCode) { + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; + if (bucket[low] <= SEQ_START) + this.encodeTableSeq[SEQ_START-bucket[low]][DEF_CHAR] = dbcsCode; // There's already a sequence, set a single-char subsequence of it. + else if (bucket[low] == UNASSIGNED) + bucket[low] = dbcsCode; +} + +DBCSCodec.prototype._setEncodeSequence = function(seq, dbcsCode) { + + // Get the root of character tree according to first character of the sequence. + var uCode = seq[0]; + var bucket = this._getEncodeBucket(uCode); + var low = uCode & 0xFF; + + var node; + if (bucket[low] <= SEQ_START) { + // There's already a sequence with - use it. + node = this.encodeTableSeq[SEQ_START-bucket[low]]; + } + else { + // There was no sequence object - allocate a new one. + node = {}; + if (bucket[low] !== UNASSIGNED) node[DEF_CHAR] = bucket[low]; // If a char was set before - make it a single-char subsequence. + bucket[low] = SEQ_START - this.encodeTableSeq.length; + this.encodeTableSeq.push(node); + } + + // Traverse the character tree, allocating new nodes as needed. + for (var j = 1; j < seq.length-1; j++) { + var oldVal = node[uCode]; + if (typeof oldVal === 'object') + node = oldVal; + else { + node = node[uCode] = {} + if (oldVal !== undefined) + node[DEF_CHAR] = oldVal + } + } + + // Set the leaf to given dbcsCode. + uCode = seq[seq.length-1]; + node[uCode] = dbcsCode; +} + +DBCSCodec.prototype._fillEncodeTable = function(nodeIdx, prefix, skipEncodeChars) { + var node = this.decodeTables[nodeIdx]; + var hasValues = false; + var subNodeEmpty = {}; + for (var i = 0; i < 0x100; i++) { + var uCode = node[i]; + var mbCode = prefix + i; + if (skipEncodeChars[mbCode]) + continue; + + if (uCode >= 0) { + this._setEncodeChar(uCode, mbCode); + hasValues = true; + } else if (uCode <= NODE_START) { + var subNodeIdx = NODE_START - uCode; + if (!subNodeEmpty[subNodeIdx]) { // Skip empty subtrees (they are too large in gb18030). + var newPrefix = (mbCode << 8) >>> 0; // NOTE: '>>> 0' keeps 32-bit num positive. + if (this._fillEncodeTable(subNodeIdx, newPrefix, skipEncodeChars)) + hasValues = true; + else + subNodeEmpty[subNodeIdx] = true; + } + } else if (uCode <= SEQ_START) { + this._setEncodeSequence(this.decodeTableSeq[SEQ_START - uCode], mbCode); + hasValues = true; + } + } + return hasValues; +} + + + +// == Encoder ================================================================== + +function DBCSEncoder(options, codec) { + // Encoder state + this.leadSurrogate = -1; + this.seqObj = undefined; + + // Static data + this.encodeTable = codec.encodeTable; + this.encodeTableSeq = codec.encodeTableSeq; + this.defaultCharSingleByte = codec.defCharSB; + this.gb18030 = codec.gb18030; +} + +DBCSEncoder.prototype.write = function(str) { + var newBuf = Buffer.alloc(str.length * (this.gb18030 ? 4 : 3)), + leadSurrogate = this.leadSurrogate, + seqObj = this.seqObj, nextChar = -1, + i = 0, j = 0; + + while (true) { + // 0. Get next character. + if (nextChar === -1) { + if (i == str.length) break; + var uCode = str.charCodeAt(i++); + } + else { + var uCode = nextChar; + nextChar = -1; + } + + // 1. Handle surrogates. + if (0xD800 <= uCode && uCode < 0xE000) { // Char is one of surrogates. + if (uCode < 0xDC00) { // We've got lead surrogate. + if (leadSurrogate === -1) { + leadSurrogate = uCode; + continue; + } else { + leadSurrogate = uCode; + // Double lead surrogate found. + uCode = UNASSIGNED; + } + } else { // We've got trail surrogate. + if (leadSurrogate !== -1) { + uCode = 0x10000 + (leadSurrogate - 0xD800) * 0x400 + (uCode - 0xDC00); + leadSurrogate = -1; + } else { + // Incomplete surrogate pair - only trail surrogate found. + uCode = UNASSIGNED; + } + + } + } + else if (leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + nextChar = uCode; uCode = UNASSIGNED; // Write an error, then current char. + leadSurrogate = -1; + } + + // 2. Convert uCode character. + var dbcsCode = UNASSIGNED; + if (seqObj !== undefined && uCode != UNASSIGNED) { // We are in the middle of the sequence + var resCode = seqObj[uCode]; + if (typeof resCode === 'object') { // Sequence continues. + seqObj = resCode; + continue; + + } else if (typeof resCode == 'number') { // Sequence finished. Write it. + dbcsCode = resCode; + + } else if (resCode == undefined) { // Current character is not part of the sequence. + + // Try default character for this sequence + resCode = seqObj[DEF_CHAR]; + if (resCode !== undefined) { + dbcsCode = resCode; // Found. Write it. + nextChar = uCode; // Current character will be written too in the next iteration. + + } else { + // TODO: What if we have no default? (resCode == undefined) + // Then, we should write first char of the sequence as-is and try the rest recursively. + // Didn't do it for now because no encoding has this situation yet. + // Currently, just skip the sequence and write current char. + } + } + seqObj = undefined; + } + else if (uCode >= 0) { // Regular character + var subtable = this.encodeTable[uCode >> 8]; + if (subtable !== undefined) + dbcsCode = subtable[uCode & 0xFF]; + + if (dbcsCode <= SEQ_START) { // Sequence start + seqObj = this.encodeTableSeq[SEQ_START-dbcsCode]; + continue; + } + + if (dbcsCode == UNASSIGNED && this.gb18030) { + // Use GB18030 algorithm to find character(s) to write. + var idx = findIdx(this.gb18030.uChars, uCode); + if (idx != -1) { + var dbcsCode = this.gb18030.gbChars[idx] + (uCode - this.gb18030.uChars[idx]); + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 12600); dbcsCode = dbcsCode % 12600; + newBuf[j++] = 0x30 + Math.floor(dbcsCode / 1260); dbcsCode = dbcsCode % 1260; + newBuf[j++] = 0x81 + Math.floor(dbcsCode / 10); dbcsCode = dbcsCode % 10; + newBuf[j++] = 0x30 + dbcsCode; + continue; + } + } + } + + // 3. Write dbcsCode character. + if (dbcsCode === UNASSIGNED) + dbcsCode = this.defaultCharSingleByte; + + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } + else if (dbcsCode < 0x10000) { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } + else if (dbcsCode < 0x1000000) { + newBuf[j++] = dbcsCode >> 16; + newBuf[j++] = (dbcsCode >> 8) & 0xFF; + newBuf[j++] = dbcsCode & 0xFF; + } else { + newBuf[j++] = dbcsCode >>> 24; + newBuf[j++] = (dbcsCode >>> 16) & 0xFF; + newBuf[j++] = (dbcsCode >>> 8) & 0xFF; + newBuf[j++] = dbcsCode & 0xFF; + } + } + + this.seqObj = seqObj; + this.leadSurrogate = leadSurrogate; + return newBuf.slice(0, j); +} + +DBCSEncoder.prototype.end = function() { + if (this.leadSurrogate === -1 && this.seqObj === undefined) + return; // All clean. Most often case. + + var newBuf = Buffer.alloc(10), j = 0; + + if (this.seqObj) { // We're in the sequence. + var dbcsCode = this.seqObj[DEF_CHAR]; + if (dbcsCode !== undefined) { // Write beginning of the sequence. + if (dbcsCode < 0x100) { + newBuf[j++] = dbcsCode; + } + else { + newBuf[j++] = dbcsCode >> 8; // high byte + newBuf[j++] = dbcsCode & 0xFF; // low byte + } + } else { + // See todo above. + } + this.seqObj = undefined; + } + + if (this.leadSurrogate !== -1) { + // Incomplete surrogate pair - only lead surrogate found. + newBuf[j++] = this.defaultCharSingleByte; + this.leadSurrogate = -1; + } + + return newBuf.slice(0, j); +} + +// Export for testing +DBCSEncoder.prototype.findIdx = findIdx; + + +// == Decoder ================================================================== + +function DBCSDecoder(options, codec) { + // Decoder state + this.nodeIdx = 0; + this.prevBytes = []; + + // Static data + this.decodeTables = codec.decodeTables; + this.decodeTableSeq = codec.decodeTableSeq; + this.defaultCharUnicode = codec.defaultCharUnicode; + this.gb18030 = codec.gb18030; +} + +DBCSDecoder.prototype.write = function(buf) { + var newBuf = Buffer.alloc(buf.length*2), + nodeIdx = this.nodeIdx, + prevBytes = this.prevBytes, prevOffset = this.prevBytes.length, + seqStart = -this.prevBytes.length, // idx of the start of current parsed sequence. + uCode; + + for (var i = 0, j = 0; i < buf.length; i++) { + var curByte = (i >= 0) ? buf[i] : prevBytes[i + prevOffset]; + + // Lookup in current trie node. + var uCode = this.decodeTables[nodeIdx][curByte]; + + if (uCode >= 0) { + // Normal character, just use it. + } + else if (uCode === UNASSIGNED) { // Unknown char. + // TODO: Callback with seq. + uCode = this.defaultCharUnicode.charCodeAt(0); + i = seqStart; // Skip one byte ('i' will be incremented by the for loop) and try to parse again. + } + else if (uCode === GB18030_CODE) { + if (i >= 3) { + var ptr = (buf[i-3]-0x81)*12600 + (buf[i-2]-0x30)*1260 + (buf[i-1]-0x81)*10 + (curByte-0x30); + } else { + var ptr = (prevBytes[i-3+prevOffset]-0x81)*12600 + + (((i-2 >= 0) ? buf[i-2] : prevBytes[i-2+prevOffset])-0x30)*1260 + + (((i-1 >= 0) ? buf[i-1] : prevBytes[i-1+prevOffset])-0x81)*10 + + (curByte-0x30); + } + var idx = findIdx(this.gb18030.gbChars, ptr); + uCode = this.gb18030.uChars[idx] + ptr - this.gb18030.gbChars[idx]; + } + else if (uCode <= NODE_START) { // Go to next trie node. + nodeIdx = NODE_START - uCode; + continue; + } + else if (uCode <= SEQ_START) { // Output a sequence of chars. + var seq = this.decodeTableSeq[SEQ_START - uCode]; + for (var k = 0; k < seq.length - 1; k++) { + uCode = seq[k]; + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; + } + uCode = seq[seq.length-1]; + } + else + throw new Error("iconv-lite internal error: invalid decoding table value " + uCode + " at " + nodeIdx + "/" + curByte); + + // Write the character to buffer, handling higher planes using surrogate pair. + if (uCode >= 0x10000) { + uCode -= 0x10000; + var uCodeLead = 0xD800 | (uCode >> 10); + newBuf[j++] = uCodeLead & 0xFF; + newBuf[j++] = uCodeLead >> 8; + + uCode = 0xDC00 | (uCode & 0x3FF); + } + newBuf[j++] = uCode & 0xFF; + newBuf[j++] = uCode >> 8; + + // Reset trie node. + nodeIdx = 0; seqStart = i+1; + } + + this.nodeIdx = nodeIdx; + this.prevBytes = (seqStart >= 0) + ? Array.prototype.slice.call(buf, seqStart) + : prevBytes.slice(seqStart + prevOffset).concat(Array.prototype.slice.call(buf)); + + return newBuf.slice(0, j).toString('ucs2'); +} + +DBCSDecoder.prototype.end = function() { + var ret = ''; + + // Try to parse all remaining chars. + while (this.prevBytes.length > 0) { + // Skip 1 character in the buffer. + ret += this.defaultCharUnicode; + var bytesArr = this.prevBytes.slice(1); + + // Parse remaining as usual. + this.prevBytes = []; + this.nodeIdx = 0; + if (bytesArr.length > 0) + ret += this.write(bytesArr); + } + + this.prevBytes = []; + this.nodeIdx = 0; + return ret; +} + +// Binary search for GB18030. Returns largest i such that table[i] <= val. +function findIdx(table, val) { + if (table[0] > val) + return -1; + + var l = 0, r = table.length; + while (l < r-1) { // always table[l] <= val < table[r] + var mid = l + ((r-l+1) >> 1); + if (table[mid] <= val) + l = mid; + else + r = mid; + } + return l; +} + + + +/***/ }), + +/***/ 5520: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +// Description of supported double byte encodings and aliases. +// Tables are not require()-d until they are needed to speed up library load. +// require()-s are direct to support Browserify. + +module.exports = { + + // == Japanese/ShiftJIS ==================================================== + // All japanese encodings are based on JIS X set of standards: + // JIS X 0201 - Single-byte encoding of ASCII + ¥ + Kana chars at 0xA1-0xDF. + // JIS X 0208 - Main set of 6879 characters, placed in 94x94 plane, to be encoded by 2 bytes. + // Has several variations in 1978, 1983, 1990 and 1997. + // JIS X 0212 - Supplementary plane of 6067 chars in 94x94 plane. 1990. Effectively dead. + // JIS X 0213 - Extension and modern replacement of 0208 and 0212. Total chars: 11233. + // 2 planes, first is superset of 0208, second - revised 0212. + // Introduced in 2000, revised 2004. Some characters are in Unicode Plane 2 (0x2xxxx) + + // Byte encodings are: + // * Shift_JIS: Compatible with 0201, uses not defined chars in top half as lead bytes for double-byte + // encoding of 0208. Lead byte ranges: 0x81-0x9F, 0xE0-0xEF; Trail byte ranges: 0x40-0x7E, 0x80-0x9E, 0x9F-0xFC. + // Windows CP932 is a superset of Shift_JIS. Some companies added more chars, notably KDDI. + // * EUC-JP: Up to 3 bytes per character. Used mostly on *nixes. + // 0x00-0x7F - lower part of 0201 + // 0x8E, 0xA1-0xDF - upper part of 0201 + // (0xA1-0xFE)x2 - 0208 plane (94x94). + // 0x8F, (0xA1-0xFE)x2 - 0212 plane (94x94). + // * JIS X 208: 7-bit, direct encoding of 0208. Byte ranges: 0x21-0x7E (94 values). Uncommon. + // Used as-is in ISO2022 family. + // * ISO2022-JP: Stateful encoding, with escape sequences to switch between ASCII, + // 0201-1976 Roman, 0208-1978, 0208-1983. + // * ISO2022-JP-1: Adds esc seq for 0212-1990. + // * ISO2022-JP-2: Adds esc seq for GB2313-1980, KSX1001-1992, ISO8859-1, ISO8859-7. + // * ISO2022-JP-3: Adds esc seq for 0201-1976 Kana set, 0213-2000 Planes 1, 2. + // * ISO2022-JP-2004: Adds 0213-2004 Plane 1. + // + // After JIS X 0213 appeared, Shift_JIS-2004, EUC-JISX0213 and ISO2022-JP-2004 followed, with just changing the planes. + // + // Overall, it seems that it's a mess :( http://www8.plala.or.jp/tkubota1/unicode-symbols-map2.html + + 'shiftjis': { + type: '_dbcs', + table: function() { return __nccwpck_require__(2348) }, + encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, + encodeSkipVals: [{from: 0xED40, to: 0xF940}], + }, + 'csshiftjis': 'shiftjis', + 'mskanji': 'shiftjis', + 'sjis': 'shiftjis', + 'windows31j': 'shiftjis', + 'ms31j': 'shiftjis', + 'xsjis': 'shiftjis', + 'windows932': 'shiftjis', + 'ms932': 'shiftjis', + '932': 'shiftjis', + 'cp932': 'shiftjis', + + 'eucjp': { + type: '_dbcs', + table: function() { return __nccwpck_require__(3078) }, + encodeAdd: {'\u00a5': 0x5C, '\u203E': 0x7E}, + }, + + // TODO: KDDI extension to Shift_JIS + // TODO: IBM CCSID 942 = CP932, but F0-F9 custom chars and other char changes. + // TODO: IBM CCSID 943 = Shift_JIS = CP932 with original Shift_JIS lower 128 chars. + + + // == Chinese/GBK ========================================================== + // http://en.wikipedia.org/wiki/GBK + // We mostly implement W3C recommendation: https://www.w3.org/TR/encoding/#gbk-encoder + + // Oldest GB2312 (1981, ~7600 chars) is a subset of CP936 + 'gb2312': 'cp936', + 'gb231280': 'cp936', + 'gb23121980': 'cp936', + 'csgb2312': 'cp936', + 'csiso58gb231280': 'cp936', + 'euccn': 'cp936', + + // Microsoft's CP936 is a subset and approximation of GBK. + 'windows936': 'cp936', + 'ms936': 'cp936', + '936': 'cp936', + 'cp936': { + type: '_dbcs', + table: function() { return __nccwpck_require__(4847) }, + }, + + // GBK (~22000 chars) is an extension of CP936 that added user-mapped chars and some other. + 'gbk': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(4847).concat)(__nccwpck_require__(7235)) }, + }, + 'xgbk': 'gbk', + 'isoir58': 'gbk', + + // GB18030 is an algorithmic extension of GBK. + // Main source: https://www.w3.org/TR/encoding/#gbk-encoder + // http://icu-project.org/docs/papers/gb18030.html + // http://source.icu-project.org/repos/icu/data/trunk/charset/data/xml/gb-18030-2000.xml + // http://www.khngai.com/chinese/charmap/tblgbk.php?page=0 + 'gb18030': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(4847).concat)(__nccwpck_require__(7235)) }, + gb18030: function() { return __nccwpck_require__(3567) }, + encodeSkipVals: [0x80], + encodeAdd: {'€': 0xA2E3}, + }, + + 'chinese': 'gb18030', + + + // == Korean =============================================================== + // EUC-KR, KS_C_5601 and KS X 1001 are exactly the same. + 'windows949': 'cp949', + 'ms949': 'cp949', + '949': 'cp949', + 'cp949': { + type: '_dbcs', + table: function() { return __nccwpck_require__(2683) }, + }, + + 'cseuckr': 'cp949', + 'csksc56011987': 'cp949', + 'euckr': 'cp949', + 'isoir149': 'cp949', + 'korean': 'cp949', + 'ksc56011987': 'cp949', + 'ksc56011989': 'cp949', + 'ksc5601': 'cp949', + + + // == Big5/Taiwan/Hong Kong ================================================ + // There are lots of tables for Big5 and cp950. Please see the following links for history: + // http://moztw.org/docs/big5/ http://www.haible.de/bruno/charsets/conversion-tables/Big5.html + // Variations, in roughly number of defined chars: + // * Windows CP 950: Microsoft variant of Big5. Canonical: http://www.unicode.org/Public/MAPPINGS/VENDORS/MICSFT/WINDOWS/CP950.TXT + // * Windows CP 951: Microsoft variant of Big5-HKSCS-2001. Seems to be never public. http://me.abelcheung.org/articles/research/what-is-cp951/ + // * Big5-2003 (Taiwan standard) almost superset of cp950. + // * Unicode-at-on (UAO) / Mozilla 1.8. Falling out of use on the Web. Not supported by other browsers. + // * Big5-HKSCS (-2001, -2004, -2008). Hong Kong standard. + // many unicode code points moved from PUA to Supplementary plane (U+2XXXX) over the years. + // Plus, it has 4 combining sequences. + // Seems that Mozilla refused to support it for 10 yrs. https://bugzilla.mozilla.org/show_bug.cgi?id=162431 https://bugzilla.mozilla.org/show_bug.cgi?id=310299 + // because big5-hkscs is the only encoding to include astral characters in non-algorithmic way. + // Implementations are not consistent within browsers; sometimes labeled as just big5. + // MS Internet Explorer switches from big5 to big5-hkscs when a patch applied. + // Great discussion & recap of what's going on https://bugzilla.mozilla.org/show_bug.cgi?id=912470#c31 + // In the encoder, it might make sense to support encoding old PUA mappings to Big5 bytes seq-s. + // Official spec: http://www.ogcio.gov.hk/en/business/tech_promotion/ccli/terms/doc/2003cmp_2008.txt + // http://www.ogcio.gov.hk/tc/business/tech_promotion/ccli/terms/doc/hkscs-2008-big5-iso.txt + // + // Current understanding of how to deal with Big5(-HKSCS) is in the Encoding Standard, http://encoding.spec.whatwg.org/#big5-encoder + // Unicode mapping (http://www.unicode.org/Public/MAPPINGS/OBSOLETE/EASTASIA/OTHER/BIG5.TXT) is said to be wrong. + + 'windows950': 'cp950', + 'ms950': 'cp950', + '950': 'cp950', + 'cp950': { + type: '_dbcs', + table: function() { return __nccwpck_require__(8867) }, + }, + + // Big5 has many variations and is an extension of cp950. We use Encoding Standard's as a consensus. + 'big5': 'big5hkscs', + 'big5hkscs': { + type: '_dbcs', + table: function() { return (__nccwpck_require__(8867).concat)(__nccwpck_require__(6086)) }, + encodeSkipVals: [ + // Although Encoding Standard says we should avoid encoding to HKSCS area (See Step 1 of + // https://encoding.spec.whatwg.org/#index-big5-pointer), we still do it to increase compatibility with ICU. + // But if a single unicode point can be encoded both as HKSCS and regular Big5, we prefer the latter. + 0x8e69, 0x8e6f, 0x8e7e, 0x8eab, 0x8eb4, 0x8ecd, 0x8ed0, 0x8f57, 0x8f69, 0x8f6e, 0x8fcb, 0x8ffe, + 0x906d, 0x907a, 0x90c4, 0x90dc, 0x90f1, 0x91bf, 0x92af, 0x92b0, 0x92b1, 0x92b2, 0x92d1, 0x9447, 0x94ca, + 0x95d9, 0x96fc, 0x9975, 0x9b76, 0x9b78, 0x9b7b, 0x9bc6, 0x9bde, 0x9bec, 0x9bf6, 0x9c42, 0x9c53, 0x9c62, + 0x9c68, 0x9c6b, 0x9c77, 0x9cbc, 0x9cbd, 0x9cd0, 0x9d57, 0x9d5a, 0x9dc4, 0x9def, 0x9dfb, 0x9ea9, 0x9eef, + 0x9efd, 0x9f60, 0x9fcb, 0xa077, 0xa0dc, 0xa0df, 0x8fcc, 0x92c8, 0x9644, 0x96ed, + + // Step 2 of https://encoding.spec.whatwg.org/#index-big5-pointer: Use last pointer for U+2550, U+255E, U+2561, U+256A, U+5341, or U+5345 + 0xa2a4, 0xa2a5, 0xa2a7, 0xa2a6, 0xa2cc, 0xa2ce, + ], + }, + + 'cnbig5': 'big5hkscs', + 'csbig5': 'big5hkscs', + 'xxbig5': 'big5hkscs', +}; + + +/***/ }), + +/***/ 1446: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +// Update this array if you add/rename/remove files in this directory. +// We support Browserify by skipping automatic module discovery and requiring modules directly. +var modules = [ + __nccwpck_require__(5005), + __nccwpck_require__(3141), + __nccwpck_require__(7485), + __nccwpck_require__(6185), + __nccwpck_require__(9566), + __nccwpck_require__(3430), + __nccwpck_require__(854), + __nccwpck_require__(2507), + __nccwpck_require__(5520), +]; + +// Put all encoding/alias/codec definitions to single object and export it. +for (var i = 0; i < modules.length; i++) { + var module = modules[i]; + for (var enc in module) + if (Object.prototype.hasOwnProperty.call(module, enc)) + exports[enc] = module[enc]; +} + + +/***/ }), + +/***/ 5005: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// Export Node.js internal encodings. + +module.exports = { + // Encodings + utf8: { type: "_internal", bomAware: true}, + cesu8: { type: "_internal", bomAware: true}, + unicode11utf8: "utf8", + + ucs2: { type: "_internal", bomAware: true}, + utf16le: "ucs2", + + binary: { type: "_internal" }, + base64: { type: "_internal" }, + hex: { type: "_internal" }, + + // Codec. + _internal: InternalCodec, +}; + +//------------------------------------------------------------------------------ + +function InternalCodec(codecOptions, iconv) { + this.enc = codecOptions.encodingName; + this.bomAware = codecOptions.bomAware; + + if (this.enc === "base64") + this.encoder = InternalEncoderBase64; + else if (this.enc === "cesu8") { + this.enc = "utf8"; // Use utf8 for decoding. + this.encoder = InternalEncoderCesu8; + + // Add decoder for versions of Node not supporting CESU-8 + if (Buffer.from('eda0bdedb2a9', 'hex').toString() !== '💩') { + this.decoder = InternalDecoderCesu8; + this.defaultCharUnicode = iconv.defaultCharUnicode; + } + } +} + +InternalCodec.prototype.encoder = InternalEncoder; +InternalCodec.prototype.decoder = InternalDecoder; + +//------------------------------------------------------------------------------ + +// We use node.js internal decoder. Its signature is the same as ours. +var StringDecoder = (__nccwpck_require__(1576).StringDecoder); + +if (!StringDecoder.prototype.end) // Node v0.8 doesn't have this method. + StringDecoder.prototype.end = function() {}; + + +function InternalDecoder(options, codec) { + this.decoder = new StringDecoder(codec.enc); +} + +InternalDecoder.prototype.write = function(buf) { + if (!Buffer.isBuffer(buf)) { + buf = Buffer.from(buf); + } + + return this.decoder.write(buf); +} + +InternalDecoder.prototype.end = function() { + return this.decoder.end(); +} + + +//------------------------------------------------------------------------------ +// Encoder is mostly trivial + +function InternalEncoder(options, codec) { + this.enc = codec.enc; +} + +InternalEncoder.prototype.write = function(str) { + return Buffer.from(str, this.enc); +} + +InternalEncoder.prototype.end = function() { +} + + +//------------------------------------------------------------------------------ +// Except base64 encoder, which must keep its state. + +function InternalEncoderBase64(options, codec) { + this.prevStr = ''; +} + +InternalEncoderBase64.prototype.write = function(str) { + str = this.prevStr + str; + var completeQuads = str.length - (str.length % 4); + this.prevStr = str.slice(completeQuads); + str = str.slice(0, completeQuads); + + return Buffer.from(str, "base64"); +} + +InternalEncoderBase64.prototype.end = function() { + return Buffer.from(this.prevStr, "base64"); +} + + +//------------------------------------------------------------------------------ +// CESU-8 encoder is also special. + +function InternalEncoderCesu8(options, codec) { +} + +InternalEncoderCesu8.prototype.write = function(str) { + var buf = Buffer.alloc(str.length * 3), bufIdx = 0; + for (var i = 0; i < str.length; i++) { + var charCode = str.charCodeAt(i); + // Naive implementation, but it works because CESU-8 is especially easy + // to convert from UTF-16 (which all JS strings are encoded in). + if (charCode < 0x80) + buf[bufIdx++] = charCode; + else if (charCode < 0x800) { + buf[bufIdx++] = 0xC0 + (charCode >>> 6); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } + else { // charCode will always be < 0x10000 in javascript. + buf[bufIdx++] = 0xE0 + (charCode >>> 12); + buf[bufIdx++] = 0x80 + ((charCode >>> 6) & 0x3f); + buf[bufIdx++] = 0x80 + (charCode & 0x3f); + } + } + return buf.slice(0, bufIdx); +} + +InternalEncoderCesu8.prototype.end = function() { +} + +//------------------------------------------------------------------------------ +// CESU-8 decoder is not implemented in Node v4.0+ + +function InternalDecoderCesu8(options, codec) { + this.acc = 0; + this.contBytes = 0; + this.accBytes = 0; + this.defaultCharUnicode = codec.defaultCharUnicode; +} + +InternalDecoderCesu8.prototype.write = function(buf) { + var acc = this.acc, contBytes = this.contBytes, accBytes = this.accBytes, + res = ''; + for (var i = 0; i < buf.length; i++) { + var curByte = buf[i]; + if ((curByte & 0xC0) !== 0x80) { // Leading byte + if (contBytes > 0) { // Previous code is invalid + res += this.defaultCharUnicode; + contBytes = 0; + } + + if (curByte < 0x80) { // Single-byte code + res += String.fromCharCode(curByte); + } else if (curByte < 0xE0) { // Two-byte code + acc = curByte & 0x1F; + contBytes = 1; accBytes = 1; + } else if (curByte < 0xF0) { // Three-byte code + acc = curByte & 0x0F; + contBytes = 2; accBytes = 1; + } else { // Four or more are not supported for CESU-8. + res += this.defaultCharUnicode; + } + } else { // Continuation byte + if (contBytes > 0) { // We're waiting for it. + acc = (acc << 6) | (curByte & 0x3f); + contBytes--; accBytes++; + if (contBytes === 0) { + // Check for overlong encoding, but support Modified UTF-8 (encoding NULL as C0 80) + if (accBytes === 2 && acc < 0x80 && acc > 0) + res += this.defaultCharUnicode; + else if (accBytes === 3 && acc < 0x800) + res += this.defaultCharUnicode; + else + // Actually add character. + res += String.fromCharCode(acc); + } + } else { // Unexpected continuation byte + res += this.defaultCharUnicode; + } + } + } + this.acc = acc; this.contBytes = contBytes; this.accBytes = accBytes; + return res; +} + +InternalDecoderCesu8.prototype.end = function() { + var res = 0; + if (this.contBytes > 0) + res += this.defaultCharUnicode; + return res; +} + + +/***/ }), + +/***/ 9566: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// Single-byte codec. Needs a 'chars' string parameter that contains 256 or 128 chars that +// correspond to encoded bytes (if 128 - then lower half is ASCII). + +exports._sbcs = SBCSCodec; +function SBCSCodec(codecOptions, iconv) { + if (!codecOptions) + throw new Error("SBCS codec is called without the data.") + + // Prepare char buffer for decoding. + if (!codecOptions.chars || (codecOptions.chars.length !== 128 && codecOptions.chars.length !== 256)) + throw new Error("Encoding '"+codecOptions.type+"' has incorrect 'chars' (must be of len 128 or 256)"); + + if (codecOptions.chars.length === 128) { + var asciiString = ""; + for (var i = 0; i < 128; i++) + asciiString += String.fromCharCode(i); + codecOptions.chars = asciiString + codecOptions.chars; + } + + this.decodeBuf = Buffer.from(codecOptions.chars, 'ucs2'); + + // Encoding buffer. + var encodeBuf = Buffer.alloc(65536, iconv.defaultCharSingleByte.charCodeAt(0)); + + for (var i = 0; i < codecOptions.chars.length; i++) + encodeBuf[codecOptions.chars.charCodeAt(i)] = i; + + this.encodeBuf = encodeBuf; +} + +SBCSCodec.prototype.encoder = SBCSEncoder; +SBCSCodec.prototype.decoder = SBCSDecoder; + + +function SBCSEncoder(options, codec) { + this.encodeBuf = codec.encodeBuf; +} + +SBCSEncoder.prototype.write = function(str) { + var buf = Buffer.alloc(str.length); + for (var i = 0; i < str.length; i++) + buf[i] = this.encodeBuf[str.charCodeAt(i)]; + + return buf; +} + +SBCSEncoder.prototype.end = function() { +} + + +function SBCSDecoder(options, codec) { + this.decodeBuf = codec.decodeBuf; +} + +SBCSDecoder.prototype.write = function(buf) { + // Strings are immutable in JS -> we use ucs2 buffer to speed up computations. + var decodeBuf = this.decodeBuf; + var newBuf = Buffer.alloc(buf.length*2); + var idx1 = 0, idx2 = 0; + for (var i = 0; i < buf.length; i++) { + idx1 = buf[i]*2; idx2 = i*2; + newBuf[idx2] = decodeBuf[idx1]; + newBuf[idx2+1] = decodeBuf[idx1+1]; + } + return newBuf.toString('ucs2'); +} + +SBCSDecoder.prototype.end = function() { +} + + +/***/ }), + +/***/ 854: +/***/ ((module) => { + + + +// Generated data for sbcs codec. Don't edit manually. Regenerate using generation/gen-sbcs.js script. +module.exports = { + "437": "cp437", + "737": "cp737", + "775": "cp775", + "850": "cp850", + "852": "cp852", + "855": "cp855", + "856": "cp856", + "857": "cp857", + "858": "cp858", + "860": "cp860", + "861": "cp861", + "862": "cp862", + "863": "cp863", + "864": "cp864", + "865": "cp865", + "866": "cp866", + "869": "cp869", + "874": "windows874", + "922": "cp922", + "1046": "cp1046", + "1124": "cp1124", + "1125": "cp1125", + "1129": "cp1129", + "1133": "cp1133", + "1161": "cp1161", + "1162": "cp1162", + "1163": "cp1163", + "1250": "windows1250", + "1251": "windows1251", + "1252": "windows1252", + "1253": "windows1253", + "1254": "windows1254", + "1255": "windows1255", + "1256": "windows1256", + "1257": "windows1257", + "1258": "windows1258", + "28591": "iso88591", + "28592": "iso88592", + "28593": "iso88593", + "28594": "iso88594", + "28595": "iso88595", + "28596": "iso88596", + "28597": "iso88597", + "28598": "iso88598", + "28599": "iso88599", + "28600": "iso885910", + "28601": "iso885911", + "28603": "iso885913", + "28604": "iso885914", + "28605": "iso885915", + "28606": "iso885916", + "windows874": { + "type": "_sbcs", + "chars": "€����…�����������‘’“”•–—�������� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "win874": "windows874", + "cp874": "windows874", + "windows1250": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰Š‹ŚŤŽŹ�‘’“”•–—�™š›śťžź ˇ˘Ł¤Ą¦§¨©Ş«¬­®Ż°±˛ł´µ¶·¸ąş»Ľ˝ľżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "win1250": "windows1250", + "cp1250": "windows1250", + "windows1251": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊЌЋЏђ‘’“”•–—�™љ›њќћџ ЎўЈ¤Ґ¦§Ё©Є«¬­®Ї°±Ііґµ¶·ё№є»јЅѕїАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "win1251": "windows1251", + "cp1251": "windows1251", + "windows1252": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ�Ž��‘’“”•–—˜™š›œ�žŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "win1252": "windows1252", + "cp1252": "windows1252", + "windows1253": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡�‰�‹�����‘’“”•–—�™�›���� ΅Ά£¤¥¦§¨©�«¬­®―°±²³΄µ¶·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "win1253": "windows1253", + "cp1253": "windows1253", + "windows1254": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰Š‹Œ����‘’“”•–—˜™š›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "win1254": "windows1254", + "cp1254": "windows1254", + "windows1255": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹�����‘’“”•–—˜™�›���� ¡¢£₪¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾¿ְֱֲֳִֵֶַָֹֺֻּֽ־ֿ׀ׁׂ׃װױײ׳״�������אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "win1255": "windows1255", + "cp1255": "windows1255", + "windows1256": { + "type": "_sbcs", + "chars": "€پ‚ƒ„…†‡ˆ‰ٹ‹Œچژڈگ‘’“”•–—ک™ڑ›œ‌‍ں ،¢£¤¥¦§¨©ھ«¬­®¯°±²³´µ¶·¸¹؛»¼½¾؟ہءآأؤإئابةتثجحخدذرزسشصض×طظعغـفقكàلâمنهوçèéêëىيîïًٌٍَôُِ÷ّùْûü‎‏ے" + }, + "win1256": "windows1256", + "cp1256": "windows1256", + "windows1257": { + "type": "_sbcs", + "chars": "€�‚�„…†‡�‰�‹�¨ˇ¸�‘’“”•–—�™�›�¯˛� �¢£¤�¦§Ø©Ŗ«¬­®Æ°±²³´µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž˙" + }, + "win1257": "windows1257", + "cp1257": "windows1257", + "windows1258": { + "type": "_sbcs", + "chars": "€�‚ƒ„…†‡ˆ‰�‹Œ����‘’“”•–—˜™�›œ��Ÿ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "win1258": "windows1258", + "cp1258": "windows1258", + "iso88591": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28591": "iso88591", + "iso88592": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ą˘Ł¤ĽŚ§¨ŠŞŤŹ­ŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙" + }, + "cp28592": "iso88592", + "iso88593": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ħ˘£¤�Ĥ§¨İŞĞĴ­�ݰħ²³´µĥ·¸ışğĵ½�żÀÁÂ�ÄĊĈÇÈÉÊËÌÍÎÏ�ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ�äċĉçèéêëìíîï�ñòóôġö÷ĝùúûüŭŝ˙" + }, + "cp28593": "iso88593", + "iso88594": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĸŖ¤Ĩϧ¨ŠĒĢŦ­Ž¯°ą˛ŗ´ĩšēģŧŊžŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎĪĐŅŌĶÔÕÖרŲÚÛÜŨŪßāáâãäåæįčéęëėíîīđņōķôõö÷øųúûüũū˙" + }, + "cp28594": "iso88594", + "iso88595": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂЃЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђѓєѕіїјљњћќ§ўџ" + }, + "cp28595": "iso88595", + "iso88596": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ���¤�������،­�������������؛���؟�ءآأؤإئابةتثجحخدذرزسشصضطظعغ�����ـفقكلمنهوىيًٌٍَُِّْ�������������" + }, + "cp28596": "iso88596", + "iso88597": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ‘’£€₯¦§¨©ͺ«¬­�―°±²³΄΅Ά·ΈΉΊ»Ό½ΎΏΐΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡ�ΣΤΥΦΧΨΩΪΫάέήίΰαβγδεζηθικλμνξοπρςστυφχψωϊϋόύώ�" + }, + "cp28597": "iso88597", + "iso88598": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �¢£¤¥¦§¨©×«¬­®¯°±²³´µ¶·¸¹÷»¼½¾��������������������������������‗אבגדהוזחטיךכלםמןנסעףפץצקרשת��‎‏�" + }, + "cp28598": "iso88598", + "iso88599": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏĞÑÒÓÔÕÖרÙÚÛÜİŞßàáâãäåæçèéêëìíîïğñòóôõö÷øùúûüışÿ" + }, + "cp28599": "iso88599", + "iso885910": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄĒĢĪĨͧĻĐŠŦŽ­ŪŊ°ąēģīĩķ·ļđšŧž―ūŋĀÁÂÃÄÅÆĮČÉĘËĖÍÎÏÐŅŌÓÔÕÖŨØŲÚÛÜÝÞßāáâãäåæįčéęëėíîïðņōóôõöũøųúûüýþĸ" + }, + "cp28600": "iso885910", + "iso885911": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "cp28601": "iso885911", + "iso885913": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ”¢£¤„¦§Ø©Ŗ«¬­®Æ°±²³“µ¶·ø¹ŗ»¼½¾æĄĮĀĆÄÅĘĒČÉŹĖĢĶĪĻŠŃŅÓŌÕÖ×ŲŁŚŪÜŻŽßąįāćäåęēčéźėģķīļšńņóōõö÷ųłśūüżž’" + }, + "cp28603": "iso885913", + "iso885914": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ Ḃḃ£ĊċḊ§Ẁ©ẂḋỲ­®ŸḞḟĠġṀṁ¶ṖẁṗẃṠỳẄẅṡÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŴÑÒÓÔÕÖṪØÙÚÛÜÝŶßàáâãäåæçèéêëìíîïŵñòóôõöṫøùúûüýŷÿ" + }, + "cp28604": "iso885914", + "iso885915": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥Š§š©ª«¬­®¯°±²³Žµ¶·ž¹º»ŒœŸ¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "cp28605": "iso885915", + "iso885916": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ĄąŁ€„Чš©Ș«Ź­źŻ°±ČłŽ”¶·žčș»ŒœŸżÀÁÂĂÄĆÆÇÈÉÊËÌÍÎÏĐŃÒÓÔŐÖŚŰÙÚÛÜĘȚßàáâăäćæçèéêëìíîïđńòóôőöśűùúûüęțÿ" + }, + "cp28606": "iso885916", + "cp437": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜ¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm437": "cp437", + "csibm437": "cp437", + "cp737": { + "type": "_sbcs", + "chars": "ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρσςτυφχψ░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ωάέήϊίόύϋώΆΈΉΊΌΎΏ±≥≤ΪΫ÷≈°∙·√ⁿ²■ " + }, + "ibm737": "cp737", + "csibm737": "cp737", + "cp775": { + "type": "_sbcs", + "chars": "ĆüéāäģåćłēŖŗīŹÄÅÉæÆōöĢ¢ŚśÖÜø£Ø×¤ĀĪóŻżź”¦©®¬½¼Ł«»░▒▓│┤ĄČĘĖ╣║╗╝ĮŠ┐└┴┬├─┼ŲŪ╚╔╩╦╠═╬Žąčęėįšųūž┘┌█▄▌▐▀ÓßŌŃõÕµńĶķĻļņĒŅ’­±“¾¶§÷„°∙·¹³²■ " + }, + "ibm775": "cp775", + "csibm775": "cp775", + "cp850": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈıÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm850": "cp850", + "csibm850": "cp850", + "cp852": { + "type": "_sbcs", + "chars": "ÇüéâäůćçłëŐőîŹÄĆÉĹĺôöĽľŚśÖÜŤťŁ×čáíóúĄąŽžĘ꬟Ⱥ«»░▒▓│┤ÁÂĚŞ╣║╗╝Żż┐└┴┬├─┼Ăă╚╔╩╦╠═╬¤đĐĎËďŇÍÎě┘┌█▄ŢŮ▀ÓßÔŃńňŠšŔÚŕŰýÝţ´­˝˛ˇ˘§÷¸°¨˙űŘř■ " + }, + "ibm852": "cp852", + "csibm852": "cp852", + "cp855": { + "type": "_sbcs", + "chars": "ђЂѓЃёЁєЄѕЅіІїЇјЈљЉњЊћЋќЌўЎџЏюЮъЪаАбБцЦдДеЕфФгГ«»░▒▓│┤хХиИ╣║╗╝йЙ┐└┴┬├─┼кК╚╔╩╦╠═╬¤лЛмМнНоОп┘┌█▄Пя▀ЯрРсСтТуУжЖвВьЬ№­ыЫзЗшШэЭщЩчЧ§■ " + }, + "ibm855": "cp855", + "csibm855": "cp855", + "cp856": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת�£�×����������®¬½¼�«»░▒▓│┤���©╣║╗╝¢¥┐└┴┬├─┼��╚╔╩╦╠═╬¤���������┘┌█▄¦�▀������µ�������¯´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm856": "cp856", + "csibm856": "cp856", + "cp857": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîıÄÅÉæÆôöòûùİÖÜø£ØŞşáíóúñÑĞ𿮬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ºªÊËÈ�ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµ�×ÚÛÙìÿ¯´­±�¾¶§÷¸°¨·¹³²■ " + }, + "ibm857": "cp857", + "csibm857": "cp857", + "cp858": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø×ƒáíóúñѪº¿®¬½¼¡«»░▒▓│┤ÁÂÀ©╣║╗╝¢¥┐└┴┬├─┼ãÃ╚╔╩╦╠═╬¤ðÐÊËÈ€ÍÎÏ┘┌█▄¦Ì▀ÓßÔÒõÕµþÞÚÛÙýݯ´­±‗¾¶§÷¸°¨·¹³²■ " + }, + "ibm858": "cp858", + "csibm858": "cp858", + "cp860": { + "type": "_sbcs", + "chars": "ÇüéâãàÁçêÊèÍÔìÃÂÉÀÈôõòÚùÌÕÜ¢£Ù₧ÓáíóúñѪº¿Ò¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm860": "cp860", + "csibm860": "cp860", + "cp861": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèÐðÞÄÅÉæÆôöþûÝýÖÜø£Ø₧ƒáíóúÁÍÓÚ¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm861": "cp861", + "csibm861": "cp861", + "cp862": { + "type": "_sbcs", + "chars": "אבגדהוזחטיךכלםמןנסעףפץצקרשת¢£¥₧ƒáíóúñѪº¿⌐¬½¼¡«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm862": "cp862", + "csibm862": "cp862", + "cp863": { + "type": "_sbcs", + "chars": "ÇüéâÂà¶çêëèïî‗À§ÉÈÊôËÏûù¤ÔÜ¢£ÙÛƒ¦´óú¨¸³¯Î⌐¬½¼¾«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm863": "cp863", + "csibm863": "cp863", + "cp864": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$٪&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~°·∙√▒─│┼┤┬├┴┐┌└┘β∞φ±½¼≈«»ﻷﻸ��ﻻﻼ� ­ﺂ£¤ﺄ��ﺎﺏﺕﺙ،ﺝﺡﺥ٠١٢٣٤٥٦٧٨٩ﻑ؛ﺱﺵﺹ؟¢ﺀﺁﺃﺅﻊﺋﺍﺑﺓﺗﺛﺟﺣﺧﺩﺫﺭﺯﺳﺷﺻﺿﻁﻅﻋﻏ¦¬÷×ﻉـﻓﻗﻛﻟﻣﻧﻫﻭﻯﻳﺽﻌﻎﻍﻡﹽّﻥﻩﻬﻰﻲﻐﻕﻵﻶﻝﻙﻱ■�" + }, + "ibm864": "cp864", + "csibm864": "cp864", + "cp865": { + "type": "_sbcs", + "chars": "ÇüéâäàåçêëèïîìÄÅÉæÆôöòûùÿÖÜø£Ø₧ƒáíóúñѪº¿⌐¬½¼¡«¤░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + "ibm865": "cp865", + "csibm865": "cp865", + "cp866": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№¤■ " + }, + "ibm866": "cp866", + "csibm866": "cp866", + "cp869": { + "type": "_sbcs", + "chars": "������Ά�·¬¦‘’Έ―ΉΊΪΌ��ΎΫ©Ώ²³ά£έήίϊΐόύΑΒΓΔΕΖΗ½ΘΙ«»░▒▓│┤ΚΛΜΝ╣║╗╝ΞΟ┐└┴┬├─┼ΠΡ╚╔╩╦╠═╬ΣΤΥΦΧΨΩαβγ┘┌█▄δε▀ζηθικλμνξοπρσςτ΄­±υφχ§ψ΅°¨ωϋΰώ■ " + }, + "ibm869": "cp869", + "csibm869": "cp869", + "cp922": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®‾°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏŠÑÒÓÔÕÖרÙÚÛÜÝŽßàáâãäåæçèéêëìíîïšñòóôõö÷øùúûüýžÿ" + }, + "ibm922": "cp922", + "csibm922": "cp922", + "cp1046": { + "type": "_sbcs", + "chars": "ﺈ×÷ﹱˆ■│─┐┌└┘ﹹﹻﹽﹿﹷﺊﻰﻳﻲﻎﻏﻐﻶﻸﻺﻼ ¤ﺋﺑﺗﺛﺟﺣ،­ﺧﺳ٠١٢٣٤٥٦٧٨٩ﺷ؛ﺻﺿﻊ؟ﻋءآأؤإئابةتثجحخدذرزسشصضطﻇعغﻌﺂﺄﺎﻓـفقكلمنهوىيًٌٍَُِّْﻗﻛﻟﻵﻷﻹﻻﻣﻧﻬﻩ�" + }, + "ibm1046": "cp1046", + "csibm1046": "cp1046", + "cp1124": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ЁЂҐЄЅІЇЈЉЊЋЌ­ЎЏАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя№ёђґєѕіїјљњћќ§ўџ" + }, + "ibm1124": "cp1124", + "csibm1124": "cp1124", + "cp1125": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёҐґЄєІіЇї·√№¤■ " + }, + "ibm1125": "cp1125", + "csibm1125": "cp1125", + "cp1129": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1129": "cp1129", + "csibm1129": "cp1129", + "cp1133": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ກຂຄງຈສຊຍດຕຖທນບປຜຝພຟມຢຣລວຫອຮ���ຯະາຳິີຶືຸູຼັົຽ���ເແໂໃໄ່້໊໋໌ໍໆ�ໜໝ₭����������������໐໑໒໓໔໕໖໗໘໙��¢¬¦�" + }, + "ibm1133": "cp1133", + "csibm1133": "cp1133", + "cp1161": { + "type": "_sbcs", + "chars": "��������������������������������่กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู้๊๋€฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛¢¬¦ " + }, + "ibm1161": "cp1161", + "csibm1161": "cp1161", + "cp1162": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + }, + "ibm1162": "cp1162", + "csibm1162": "cp1162", + "cp1163": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£€¥¦§œ©ª«¬­®¯°±²³Ÿµ¶·Œ¹º»¼½¾¿ÀÁÂĂÄÅÆÇÈÉÊË̀ÍÎÏĐÑ̉ÓÔƠÖרÙÚÛÜỮßàáâăäåæçèéêë́íîïđṇ̃óôơö÷øùúûüư₫ÿ" + }, + "ibm1163": "cp1163", + "csibm1163": "cp1163", + "maccroatian": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®Š™´¨≠ŽØ∞±≤≥∆µ∂∑∏š∫ªºΩžø¿¡¬√ƒ≈ƫȅ ÀÃÕŒœĐ—“”‘’÷◊�©⁄¤‹›Æ»–·‚„‰ÂćÁčÈÍÎÏÌÓÔđÒÚÛÙıˆ˜¯πË˚¸Êæˇ" + }, + "maccyrillic": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°¢£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµ∂ЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "macgreek": { + "type": "_sbcs", + "chars": "Ĺ²É³ÖÜ΅àâä΄¨çéèê룙î‰ôö¦­ùûü†ΓΔΘΛΞΠß®©ΣΪ§≠°·Α±≤≥¥ΒΕΖΗΙΚΜΦΫΨΩάΝ¬ΟΡ≈Τ«»… ΥΧΆΈœ–―“”‘’÷ΉΊΌΎέήίόΏύαβψδεφγηιξκλμνοπώρστθωςχυζϊϋΐΰ�" + }, + "maciceland": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûüݰ¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤ÐðÞþý·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macroman": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macromania": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ĂŞ∞±≤≥¥µ∂∑∏π∫ªºΩăş¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›Ţţ‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macthai": { + "type": "_sbcs", + "chars": "«»…“”�•‘’� กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู​–—฿เแโใไๅๆ็่้๊๋์ํ™๏๐๑๒๓๔๕๖๗๘๙®©����" + }, + "macturkish": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸĞğİıŞş‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙ�ˆ˜¯˘˙˚¸˝˛ˇ" + }, + "macukraine": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ†°Ґ£§•¶І®©™Ђђ≠Ѓѓ∞±≤≥іµґЈЄєЇїЉљЊњјЅ¬√ƒ≈∆«»… ЋћЌќѕ–—“”‘’÷„ЎўЏџ№Ёёяабвгдежзийклмнопрстуфхцчшщъыьэю¤" + }, + "koi8r": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ё╓╔╕╖╗╘╙╚╛╜╝╞╟╠╡Ё╢╣╤╥╦╧╨╩╪╫╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8u": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґ╝╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪Ґ╬©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8ru": { + "type": "_sbcs", + "chars": "─│┌┐└┘├┤┬┴┼▀▄█▌▐░▒▓⌠■∙√≈≤≥ ⌡°²·÷═║╒ёє╔ії╗╘╙╚╛ґў╞╟╠╡ЁЄ╣ІЇ╦╧╨╩╪ҐЎ©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "koi8t": { + "type": "_sbcs", + "chars": "қғ‚Ғ„…†‡�‰ҳ‹ҲҷҶ�Қ‘’“”•–—�™�›�����ӯӮё¤ӣ¦§���«¬­®�°±²Ё�Ӣ¶·�№�»���©юабцдефгхийклмнопярстужвьызшэщчъЮАБЦДЕФГХИЙКЛМНОПЯРСТУЖВЬЫЗШЭЩЧЪ" + }, + "armscii8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ �և։)(»«—.՝,-֊…՜՛՞ԱաԲբԳգԴդԵեԶզԷէԸըԹթԺժԻիԼլԽխԾծԿկՀհՁձՂղՃճՄմՅյՆնՇշՈոՉչՊպՋջՌռՍսՎվՏտՐրՑցՒւՓփՔքՕօՖֆ՚�" + }, + "rk1048": { + "type": "_sbcs", + "chars": "ЂЃ‚ѓ„…†‡€‰Љ‹ЊҚҺЏђ‘’“”•–—�™љ›њқһџ ҰұӘ¤Ө¦§Ё©Ғ«¬­®Ү°±Ііөµ¶·ё№ғ»әҢңүАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "tcvn": { + "type": "_sbcs", + "chars": "\u0000ÚỤ\u0003ỪỬỮ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010ỨỰỲỶỸÝỴ\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ÀẢÃÁẠẶẬÈẺẼÉẸỆÌỈĨÍỊÒỎÕÓỌỘỜỞỠỚỢÙỦŨ ĂÂÊÔƠƯĐăâêôơưđẶ̀̀̉̃́àảãáạẲằẳẵắẴẮẦẨẪẤỀặầẩẫấậèỂẻẽéẹềểễếệìỉỄẾỒĩíịòỔỏõóọồổỗốộờởỡớợùỖủũúụừửữứựỳỷỹýỵỐ" + }, + "georgianacademy": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზთიკლმნოპჟრსტუფქღყშჩცძწჭხჯჰჱჲჳჴჵჶçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "georgianps": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿აბგდევზჱთიკლმნჲოპჟრსტჳუფქღყშჩცძწჭხჴჯჰჵæçèéêëìíîïðñòóôõö÷øùúûüýþÿ" + }, + "pt154": { + "type": "_sbcs", + "chars": "ҖҒӮғ„…ҶҮҲүҠӢҢҚҺҸҗ‘’“”•–—ҳҷҡӣңқһҹ ЎўЈӨҘҰ§Ё©Ә«¬ӯ®Ҝ°ұІіҙө¶·ё№ә»јҪҫҝАБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя" + }, + "viscii": { + "type": "_sbcs", + "chars": "\u0000\u0001Ẳ\u0003\u0004ẴẪ\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013Ỷ\u0015\u0016\u0017\u0018Ỹ\u001a\u001b\u001c\u001dỴ\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ẠẮẰẶẤẦẨẬẼẸẾỀỂỄỆỐỒỔỖỘỢỚỜỞỊỎỌỈỦŨỤỲÕắằặấầẩậẽẹếềểễệốồổỗỠƠộờởịỰỨỪỬơớƯÀÁÂÃẢĂẳẵÈÉÊẺÌÍĨỳĐứÒÓÔạỷừửÙÚỹỵÝỡưàáâãảăữẫèéêẻìíĩỉđựòóôõỏọụùúũủýợỮ" + }, + "iso646cn": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#¥%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" + }, + "iso646jp": { + "type": "_sbcs", + "chars": "\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[¥]^_`abcdefghijklmnopqrstuvwxyz{|}‾��������������������������������������������������������������������������������������������������������������������������������" + }, + "hproman8": { + "type": "_sbcs", + "chars": "€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ÀÂÈÊËÎÏ´ˋˆ¨˜ÙÛ₤¯Ýý°ÇçÑñ¡¿¤£¥§ƒ¢âêôûáéóúàèòùäëöüÅîØÆåíøæÄìÖÜÉïßÔÁÃãÐðÍÌÓÒÕõŠšÚŸÿÞþ·µ¶¾—¼½ªº«■»±�" + }, + "macintosh": { + "type": "_sbcs", + "chars": "ÄÅÇÉÑÖÜáàâäãåçéèêëíìîïñóòôöõúùûü†°¢£§•¶ß®©™´¨≠ÆØ∞±≤≥¥µ∂∑∏π∫ªºΩæø¿¡¬√ƒ≈∆«»… ÀÃÕŒœ–—“”‘’÷◊ÿŸ⁄¤‹›fifl‡·‚„‰ÂÊÁËÈÍÎÏÌÓÔ�ÒÚÛÙıˆ˜¯˘˙˚¸˝˛ˇ" + }, + "ascii": { + "type": "_sbcs", + "chars": "��������������������������������������������������������������������������������������������������������������������������������" + }, + "tis620": { + "type": "_sbcs", + "chars": "���������������������������������กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรฤลฦวศษสหฬอฮฯะัาำิีึืฺุู����฿เแโใไๅๆ็่้๊๋์ํ๎๏๐๑๒๓๔๕๖๗๘๙๚๛����" + } +} + +/***/ }), + +/***/ 3430: +/***/ ((module) => { + + + +// Manually added data to be used by sbcs codec in addition to generated one. + +module.exports = { + // Not supported by iconv, not sure why. + "10029": "maccenteuro", + "maccenteuro": { + "type": "_sbcs", + "chars": "ÄĀāÉĄÖÜáąČäčĆć鏟ĎíďĒēĖóėôöõúĚěü†°Ę£§•¶ß®©™ę¨≠ģĮįĪ≤≥īĶ∂∑łĻļĽľĹĺŅņѬ√ńŇ∆«»… ňŐÕőŌ–—“”‘’÷◊ōŔŕŘ‹›řŖŗŠ‚„šŚśÁŤťÍŽžŪÓÔūŮÚůŰűŲųÝýķŻŁżĢˇ" + }, + + "808": "cp808", + "ibm808": "cp808", + "cp808": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмноп░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀рстуфхцчшщъыьэюяЁёЄєЇїЎў°∙·√№€■ " + }, + + "mik": { + "type": "_sbcs", + "chars": "АБВГДЕЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдежзийклмнопрстуфхцчшщъыьэюя└┴┬├─┼╣║╚╔╩╦╠═╬┐░▒▓│┤№§╗╝┘┌█▄▌▐▀αßΓπΣσµτΦΘΩδ∞φε∩≡±≥≤⌠⌡÷≈°∙·√ⁿ²■ " + }, + + "cp720": { + "type": "_sbcs", + "chars": "\x80\x81éâ\x84à\x86çêëèïî\x8d\x8e\x8f\x90\u0651\u0652ô¤ـûùءآأؤ£إئابةتثجحخدذرزسشص«»░▒▓│┤╡╢╖╕╣║╗╝╜╛┐└┴┬├─┼╞╟╚╔╩╦╠═╬╧╨╤╥╙╘╒╓╫╪┘┌█▄▌▐▀ضطظعغفµقكلمنهوىي≡\u064b\u064c\u064d\u064e\u064f\u0650≈°∙·√ⁿ²■\u00a0" + }, + + // Aliases of generated encodings. + "ascii8bit": "ascii", + "usascii": "ascii", + "ansix34": "ascii", + "ansix341968": "ascii", + "ansix341986": "ascii", + "csascii": "ascii", + "cp367": "ascii", + "ibm367": "ascii", + "isoir6": "ascii", + "iso646us": "ascii", + "iso646irv": "ascii", + "us": "ascii", + + "latin1": "iso88591", + "latin2": "iso88592", + "latin3": "iso88593", + "latin4": "iso88594", + "latin5": "iso88599", + "latin6": "iso885910", + "latin7": "iso885913", + "latin8": "iso885914", + "latin9": "iso885915", + "latin10": "iso885916", + + "csisolatin1": "iso88591", + "csisolatin2": "iso88592", + "csisolatin3": "iso88593", + "csisolatin4": "iso88594", + "csisolatincyrillic": "iso88595", + "csisolatinarabic": "iso88596", + "csisolatingreek" : "iso88597", + "csisolatinhebrew": "iso88598", + "csisolatin5": "iso88599", + "csisolatin6": "iso885910", + + "l1": "iso88591", + "l2": "iso88592", + "l3": "iso88593", + "l4": "iso88594", + "l5": "iso88599", + "l6": "iso885910", + "l7": "iso885913", + "l8": "iso885914", + "l9": "iso885915", + "l10": "iso885916", + + "isoir14": "iso646jp", + "isoir57": "iso646cn", + "isoir100": "iso88591", + "isoir101": "iso88592", + "isoir109": "iso88593", + "isoir110": "iso88594", + "isoir144": "iso88595", + "isoir127": "iso88596", + "isoir126": "iso88597", + "isoir138": "iso88598", + "isoir148": "iso88599", + "isoir157": "iso885910", + "isoir166": "tis620", + "isoir179": "iso885913", + "isoir199": "iso885914", + "isoir203": "iso885915", + "isoir226": "iso885916", + + "cp819": "iso88591", + "ibm819": "iso88591", + + "cyrillic": "iso88595", + + "arabic": "iso88596", + "arabic8": "iso88596", + "ecma114": "iso88596", + "asmo708": "iso88596", + + "greek" : "iso88597", + "greek8" : "iso88597", + "ecma118" : "iso88597", + "elot928" : "iso88597", + + "hebrew": "iso88598", + "hebrew8": "iso88598", + + "turkish": "iso88599", + "turkish8": "iso88599", + + "thai": "iso885911", + "thai8": "iso885911", + + "celtic": "iso885914", + "celtic8": "iso885914", + "isoceltic": "iso885914", + + "tis6200": "tis620", + "tis62025291": "tis620", + "tis62025330": "tis620", + + "10000": "macroman", + "10006": "macgreek", + "10007": "maccyrillic", + "10079": "maciceland", + "10081": "macturkish", + + "cspc8codepage437": "cp437", + "cspc775baltic": "cp775", + "cspc850multilingual": "cp850", + "cspcp852": "cp852", + "cspc862latinhebrew": "cp862", + "cpgr": "cp869", + + "msee": "cp1250", + "mscyrl": "cp1251", + "msansi": "cp1252", + "msgreek": "cp1253", + "msturk": "cp1254", + "mshebr": "cp1255", + "msarab": "cp1256", + "winbaltrim": "cp1257", + + "cp20866": "koi8r", + "20866": "koi8r", + "ibm878": "koi8r", + "cskoi8r": "koi8r", + + "cp21866": "koi8u", + "21866": "koi8u", + "ibm1168": "koi8u", + + "strk10482002": "rk1048", + + "tcvn5712": "tcvn", + "tcvn57121": "tcvn", + + "gb198880": "iso646cn", + "cn": "iso646cn", + + "csiso14jisc6220ro": "iso646jp", + "jisc62201969ro": "iso646jp", + "jp": "iso646jp", + + "cshproman8": "hproman8", + "r8": "hproman8", + "roman8": "hproman8", + "xroman8": "hproman8", + "ibm1051": "hproman8", + + "mac": "macintosh", + "csmacintosh": "macintosh", +}; + + + +/***/ }), + +/***/ 7485: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// Note: UTF16-LE (or UCS2) codec is Node.js native. See encodings/internal.js + +// == UTF16-BE codec. ========================================================== + +exports.utf16be = Utf16BECodec; +function Utf16BECodec() { +} + +Utf16BECodec.prototype.encoder = Utf16BEEncoder; +Utf16BECodec.prototype.decoder = Utf16BEDecoder; +Utf16BECodec.prototype.bomAware = true; + + +// -- Encoding + +function Utf16BEEncoder() { +} + +Utf16BEEncoder.prototype.write = function(str) { + var buf = Buffer.from(str, 'ucs2'); + for (var i = 0; i < buf.length; i += 2) { + var tmp = buf[i]; buf[i] = buf[i+1]; buf[i+1] = tmp; + } + return buf; +} + +Utf16BEEncoder.prototype.end = function() { +} + + +// -- Decoding + +function Utf16BEDecoder() { + this.overflowByte = -1; +} + +Utf16BEDecoder.prototype.write = function(buf) { + if (buf.length == 0) + return ''; + + var buf2 = Buffer.alloc(buf.length + 1), + i = 0, j = 0; + + if (this.overflowByte !== -1) { + buf2[0] = buf[0]; + buf2[1] = this.overflowByte; + i = 1; j = 2; + } + + for (; i < buf.length-1; i += 2, j+= 2) { + buf2[j] = buf[i+1]; + buf2[j+1] = buf[i]; + } + + this.overflowByte = (i == buf.length-1) ? buf[buf.length-1] : -1; + + return buf2.slice(0, j).toString('ucs2'); +} + +Utf16BEDecoder.prototype.end = function() { + this.overflowByte = -1; +} + + +// == UTF-16 codec ============================================================= +// Decoder chooses automatically from UTF-16LE and UTF-16BE using BOM and space-based heuristic. +// Defaults to UTF-16LE, as it's prevalent and default in Node. +// http://en.wikipedia.org/wiki/UTF-16 and http://encoding.spec.whatwg.org/#utf-16le +// Decoder default can be changed: iconv.decode(buf, 'utf16', {defaultEncoding: 'utf-16be'}); + +// Encoder uses UTF-16LE and prepends BOM (which can be overridden with addBOM: false). + +exports.utf16 = Utf16Codec; +function Utf16Codec(codecOptions, iconv) { + this.iconv = iconv; +} + +Utf16Codec.prototype.encoder = Utf16Encoder; +Utf16Codec.prototype.decoder = Utf16Decoder; + + +// -- Encoding (pass-through) + +function Utf16Encoder(options, codec) { + options = options || {}; + if (options.addBOM === undefined) + options.addBOM = true; + this.encoder = codec.iconv.getEncoder('utf-16le', options); +} + +Utf16Encoder.prototype.write = function(str) { + return this.encoder.write(str); +} + +Utf16Encoder.prototype.end = function() { + return this.encoder.end(); +} + + +// -- Decoding + +function Utf16Decoder(options, codec) { + this.decoder = null; + this.initialBufs = []; + this.initialBufsLen = 0; + + this.options = options || {}; + this.iconv = codec.iconv; +} + +Utf16Decoder.prototype.write = function(buf) { + if (!this.decoder) { + // Codec is not chosen yet. Accumulate initial bytes. + this.initialBufs.push(buf); + this.initialBufsLen += buf.length; + + if (this.initialBufsLen < 16) // We need more bytes to use space heuristic (see below) + return ''; + + // We have enough bytes -> detect endianness. + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); + + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; + } + + return this.decoder.write(buf); +} + +Utf16Decoder.prototype.end = function() { + if (!this.decoder) { + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); + + var trail = this.decoder.end(); + if (trail) + resStr += trail; + + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; + } + return this.decoder.end(); +} + +function detectEncoding(bufs, defaultEncoding) { + var b = []; + var charsProcessed = 0; + var asciiCharsLE = 0, asciiCharsBE = 0; // Number of ASCII chars when decoded as LE or BE. + + outer_loop: + for (var i = 0; i < bufs.length; i++) { + var buf = bufs[i]; + for (var j = 0; j < buf.length; j++) { + b.push(buf[j]); + if (b.length === 2) { + if (charsProcessed === 0) { + // Check BOM first. + if (b[0] === 0xFF && b[1] === 0xFE) return 'utf-16le'; + if (b[0] === 0xFE && b[1] === 0xFF) return 'utf-16be'; + } + + if (b[0] === 0 && b[1] !== 0) asciiCharsBE++; + if (b[0] !== 0 && b[1] === 0) asciiCharsLE++; + + b.length = 0; + charsProcessed++; + + if (charsProcessed >= 100) { + break outer_loop; + } + } + } + } + + // Make decisions. + // Most of the time, the content has ASCII chars (U+00**), but the opposite (U+**00) is uncommon. + // So, we count ASCII as if it was LE or BE, and decide from that. + if (asciiCharsBE > asciiCharsLE) return 'utf-16be'; + if (asciiCharsBE < asciiCharsLE) return 'utf-16le'; + + // Couldn't decide (likely all zeros or not enough data). + return defaultEncoding || 'utf-16le'; +} + + + + +/***/ }), + +/***/ 3141: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// == UTF32-LE/BE codec. ========================================================== + +exports._utf32 = Utf32Codec; + +function Utf32Codec(codecOptions, iconv) { + this.iconv = iconv; + this.bomAware = true; + this.isLE = codecOptions.isLE; +} + +exports.utf32le = { type: '_utf32', isLE: true }; +exports.utf32be = { type: '_utf32', isLE: false }; + +// Aliases +exports.ucs4le = 'utf32le'; +exports.ucs4be = 'utf32be'; + +Utf32Codec.prototype.encoder = Utf32Encoder; +Utf32Codec.prototype.decoder = Utf32Decoder; + +// -- Encoding + +function Utf32Encoder(options, codec) { + this.isLE = codec.isLE; + this.highSurrogate = 0; +} + +Utf32Encoder.prototype.write = function(str) { + var src = Buffer.from(str, 'ucs2'); + var dst = Buffer.alloc(src.length * 2); + var write32 = this.isLE ? dst.writeUInt32LE : dst.writeUInt32BE; + var offset = 0; + + for (var i = 0; i < src.length; i += 2) { + var code = src.readUInt16LE(i); + var isHighSurrogate = (0xD800 <= code && code < 0xDC00); + var isLowSurrogate = (0xDC00 <= code && code < 0xE000); + + if (this.highSurrogate) { + if (isHighSurrogate || !isLowSurrogate) { + // There shouldn't be two high surrogates in a row, nor a high surrogate which isn't followed by a low + // surrogate. If this happens, keep the pending high surrogate as a stand-alone semi-invalid character + // (technically wrong, but expected by some applications, like Windows file names). + write32.call(dst, this.highSurrogate, offset); + offset += 4; + } + else { + // Create 32-bit value from high and low surrogates; + var codepoint = (((this.highSurrogate - 0xD800) << 10) | (code - 0xDC00)) + 0x10000; + + write32.call(dst, codepoint, offset); + offset += 4; + this.highSurrogate = 0; + + continue; + } + } + + if (isHighSurrogate) + this.highSurrogate = code; + else { + // Even if the current character is a low surrogate, with no previous high surrogate, we'll + // encode it as a semi-invalid stand-alone character for the same reasons expressed above for + // unpaired high surrogates. + write32.call(dst, code, offset); + offset += 4; + this.highSurrogate = 0; + } + } + + if (offset < dst.length) + dst = dst.slice(0, offset); + + return dst; +}; + +Utf32Encoder.prototype.end = function() { + // Treat any leftover high surrogate as a semi-valid independent character. + if (!this.highSurrogate) + return; + + var buf = Buffer.alloc(4); + + if (this.isLE) + buf.writeUInt32LE(this.highSurrogate, 0); + else + buf.writeUInt32BE(this.highSurrogate, 0); + + this.highSurrogate = 0; + + return buf; +}; + +// -- Decoding + +function Utf32Decoder(options, codec) { + this.isLE = codec.isLE; + this.badChar = codec.iconv.defaultCharUnicode.charCodeAt(0); + this.overflow = []; +} + +Utf32Decoder.prototype.write = function(src) { + if (src.length === 0) + return ''; + + var i = 0; + var codepoint = 0; + var dst = Buffer.alloc(src.length + 4); + var offset = 0; + var isLE = this.isLE; + var overflow = this.overflow; + var badChar = this.badChar; + + if (overflow.length > 0) { + for (; i < src.length && overflow.length < 4; i++) + overflow.push(src[i]); + + if (overflow.length === 4) { + // NOTE: codepoint is a signed int32 and can be negative. + // NOTE: We copied this block from below to help V8 optimize it (it works with array, not buffer). + if (isLE) { + codepoint = overflow[i] | (overflow[i+1] << 8) | (overflow[i+2] << 16) | (overflow[i+3] << 24); + } else { + codepoint = overflow[i+3] | (overflow[i+2] << 8) | (overflow[i+1] << 16) | (overflow[i] << 24); + } + overflow.length = 0; + + offset = _writeCodepoint(dst, offset, codepoint, badChar); + } + } + + // Main loop. Should be as optimized as possible. + for (; i < src.length - 3; i += 4) { + // NOTE: codepoint is a signed int32 and can be negative. + if (isLE) { + codepoint = src[i] | (src[i+1] << 8) | (src[i+2] << 16) | (src[i+3] << 24); + } else { + codepoint = src[i+3] | (src[i+2] << 8) | (src[i+1] << 16) | (src[i] << 24); + } + offset = _writeCodepoint(dst, offset, codepoint, badChar); + } + + // Keep overflowing bytes. + for (; i < src.length; i++) { + overflow.push(src[i]); + } + + return dst.slice(0, offset).toString('ucs2'); +}; + +function _writeCodepoint(dst, offset, codepoint, badChar) { + // NOTE: codepoint is signed int32 and can be negative. We keep it that way to help V8 with optimizations. + if (codepoint < 0 || codepoint > 0x10FFFF) { + // Not a valid Unicode codepoint + codepoint = badChar; + } + + // Ephemeral Planes: Write high surrogate. + if (codepoint >= 0x10000) { + codepoint -= 0x10000; + + var high = 0xD800 | (codepoint >> 10); + dst[offset++] = high & 0xff; + dst[offset++] = high >> 8; + + // Low surrogate is written below. + var codepoint = 0xDC00 | (codepoint & 0x3FF); + } + + // Write BMP char or low surrogate. + dst[offset++] = codepoint & 0xff; + dst[offset++] = codepoint >> 8; + + return offset; +}; + +Utf32Decoder.prototype.end = function() { + this.overflow.length = 0; +}; + +// == UTF-32 Auto codec ============================================================= +// Decoder chooses automatically from UTF-32LE and UTF-32BE using BOM and space-based heuristic. +// Defaults to UTF-32LE. http://en.wikipedia.org/wiki/UTF-32 +// Encoder/decoder default can be changed: iconv.decode(buf, 'utf32', {defaultEncoding: 'utf-32be'}); + +// Encoder prepends BOM (which can be overridden with (addBOM: false}). + +exports.utf32 = Utf32AutoCodec; +exports.ucs4 = 'utf32'; + +function Utf32AutoCodec(options, iconv) { + this.iconv = iconv; +} + +Utf32AutoCodec.prototype.encoder = Utf32AutoEncoder; +Utf32AutoCodec.prototype.decoder = Utf32AutoDecoder; + +// -- Encoding + +function Utf32AutoEncoder(options, codec) { + options = options || {}; + + if (options.addBOM === undefined) + options.addBOM = true; + + this.encoder = codec.iconv.getEncoder(options.defaultEncoding || 'utf-32le', options); +} + +Utf32AutoEncoder.prototype.write = function(str) { + return this.encoder.write(str); +}; + +Utf32AutoEncoder.prototype.end = function() { + return this.encoder.end(); +}; + +// -- Decoding + +function Utf32AutoDecoder(options, codec) { + this.decoder = null; + this.initialBufs = []; + this.initialBufsLen = 0; + this.options = options || {}; + this.iconv = codec.iconv; +} + +Utf32AutoDecoder.prototype.write = function(buf) { + if (!this.decoder) { + // Codec is not chosen yet. Accumulate initial bytes. + this.initialBufs.push(buf); + this.initialBufsLen += buf.length; + + if (this.initialBufsLen < 32) // We need more bytes to use space heuristic (see below) + return ''; + + // We have enough bytes -> detect endianness. + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); + + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; + } + + return this.decoder.write(buf); +}; + +Utf32AutoDecoder.prototype.end = function() { + if (!this.decoder) { + var encoding = detectEncoding(this.initialBufs, this.options.defaultEncoding); + this.decoder = this.iconv.getDecoder(encoding, this.options); + + var resStr = ''; + for (var i = 0; i < this.initialBufs.length; i++) + resStr += this.decoder.write(this.initialBufs[i]); + + var trail = this.decoder.end(); + if (trail) + resStr += trail; + + this.initialBufs.length = this.initialBufsLen = 0; + return resStr; + } + + return this.decoder.end(); +}; + +function detectEncoding(bufs, defaultEncoding) { + var b = []; + var charsProcessed = 0; + var invalidLE = 0, invalidBE = 0; // Number of invalid chars when decoded as LE or BE. + var bmpCharsLE = 0, bmpCharsBE = 0; // Number of BMP chars when decoded as LE or BE. + + outer_loop: + for (var i = 0; i < bufs.length; i++) { + var buf = bufs[i]; + for (var j = 0; j < buf.length; j++) { + b.push(buf[j]); + if (b.length === 4) { + if (charsProcessed === 0) { + // Check BOM first. + if (b[0] === 0xFF && b[1] === 0xFE && b[2] === 0 && b[3] === 0) { + return 'utf-32le'; + } + if (b[0] === 0 && b[1] === 0 && b[2] === 0xFE && b[3] === 0xFF) { + return 'utf-32be'; + } + } + + if (b[0] !== 0 || b[1] > 0x10) invalidBE++; + if (b[3] !== 0 || b[2] > 0x10) invalidLE++; + + if (b[0] === 0 && b[1] === 0 && (b[2] !== 0 || b[3] !== 0)) bmpCharsBE++; + if ((b[0] !== 0 || b[1] !== 0) && b[2] === 0 && b[3] === 0) bmpCharsLE++; + + b.length = 0; + charsProcessed++; + + if (charsProcessed >= 100) { + break outer_loop; + } + } + } + } + + // Make decisions. + if (bmpCharsBE - invalidBE > bmpCharsLE - invalidLE) return 'utf-32be'; + if (bmpCharsBE - invalidBE < bmpCharsLE - invalidLE) return 'utf-32le'; + + // Couldn't decide (likely all zeros or not enough data). + return defaultEncoding || 'utf-32le'; +} + + +/***/ }), + +/***/ 6185: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// UTF-7 codec, according to https://tools.ietf.org/html/rfc2152 +// See also below a UTF-7-IMAP codec, according to http://tools.ietf.org/html/rfc3501#section-5.1.3 + +exports.utf7 = Utf7Codec; +exports.unicode11utf7 = 'utf7'; // Alias UNICODE-1-1-UTF-7 +function Utf7Codec(codecOptions, iconv) { + this.iconv = iconv; +}; + +Utf7Codec.prototype.encoder = Utf7Encoder; +Utf7Codec.prototype.decoder = Utf7Decoder; +Utf7Codec.prototype.bomAware = true; + + +// -- Encoding + +var nonDirectChars = /[^A-Za-z0-9'\(\),-\.\/:\? \n\r\t]+/g; + +function Utf7Encoder(options, codec) { + this.iconv = codec.iconv; +} + +Utf7Encoder.prototype.write = function(str) { + // Naive implementation. + // Non-direct chars are encoded as "+<base64>-"; single "+" char is encoded as "+-". + return Buffer.from(str.replace(nonDirectChars, function(chunk) { + return "+" + (chunk === '+' ? '' : + this.iconv.encode(chunk, 'utf16-be').toString('base64').replace(/=+$/, '')) + + "-"; + }.bind(this))); +} + +Utf7Encoder.prototype.end = function() { +} + + +// -- Decoding + +function Utf7Decoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; +} + +var base64Regex = /[A-Za-z0-9\/+]/; +var base64Chars = []; +for (var i = 0; i < 256; i++) + base64Chars[i] = base64Regex.test(String.fromCharCode(i)); + +var plusChar = '+'.charCodeAt(0), + minusChar = '-'.charCodeAt(0), + andChar = '&'.charCodeAt(0); + +Utf7Decoder.prototype.write = function(buf) { + var res = "", lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; + + // The decoder is more involved as we must handle chunks in stream. + + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { // We're in direct mode. + // Write direct chars until '+' + if (buf[i] == plusChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i+1; + inBase64 = true; + } + } else { // We decode base64. + if (!base64Chars[buf[i]]) { // Base64 ended. + if (i == lastI && buf[i] == minusChar) {// "+-" -> "+" + res += "+"; + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii"); + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } + + if (buf[i] != minusChar) // Minus is absorbed after base64. + i--; + + lastI = i+1; + inBase64 = false; + base64Accum = ''; + } + } + } + + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii"); + + var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); + + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } + + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + + return res; +} + +Utf7Decoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); + + this.inBase64 = false; + this.base64Accum = ''; + return res; +} + + +// UTF-7-IMAP codec. +// RFC3501 Sec. 5.1.3 Modified UTF-7 (http://tools.ietf.org/html/rfc3501#section-5.1.3) +// Differences: +// * Base64 part is started by "&" instead of "+" +// * Direct characters are 0x20-0x7E, except "&" (0x26) +// * In Base64, "," is used instead of "/" +// * Base64 must not be used to represent direct characters. +// * No implicit shift back from Base64 (should always end with '-') +// * String must end in non-shifted position. +// * "-&" while in base64 is not allowed. + + +exports.utf7imap = Utf7IMAPCodec; +function Utf7IMAPCodec(codecOptions, iconv) { + this.iconv = iconv; +}; + +Utf7IMAPCodec.prototype.encoder = Utf7IMAPEncoder; +Utf7IMAPCodec.prototype.decoder = Utf7IMAPDecoder; +Utf7IMAPCodec.prototype.bomAware = true; + + +// -- Encoding + +function Utf7IMAPEncoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = Buffer.alloc(6); + this.base64AccumIdx = 0; +} + +Utf7IMAPEncoder.prototype.write = function(str) { + var inBase64 = this.inBase64, + base64Accum = this.base64Accum, + base64AccumIdx = this.base64AccumIdx, + buf = Buffer.alloc(str.length*5 + 10), bufIdx = 0; + + for (var i = 0; i < str.length; i++) { + var uChar = str.charCodeAt(i); + if (0x20 <= uChar && uChar <= 0x7E) { // Direct character or '&'. + if (inBase64) { + if (base64AccumIdx > 0) { + bufIdx += buf.write(base64Accum.slice(0, base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + base64AccumIdx = 0; + } + + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + inBase64 = false; + } + + if (!inBase64) { + buf[bufIdx++] = uChar; // Write direct character + + if (uChar === andChar) // Ampersand -> '&-' + buf[bufIdx++] = minusChar; + } + + } else { // Non-direct character + if (!inBase64) { + buf[bufIdx++] = andChar; // Write '&', then go to base64 mode. + inBase64 = true; + } + if (inBase64) { + base64Accum[base64AccumIdx++] = uChar >> 8; + base64Accum[base64AccumIdx++] = uChar & 0xFF; + + if (base64AccumIdx == base64Accum.length) { + bufIdx += buf.write(base64Accum.toString('base64').replace(/\//g, ','), bufIdx); + base64AccumIdx = 0; + } + } + } + } + + this.inBase64 = inBase64; + this.base64AccumIdx = base64AccumIdx; + + return buf.slice(0, bufIdx); +} + +Utf7IMAPEncoder.prototype.end = function() { + var buf = Buffer.alloc(10), bufIdx = 0; + if (this.inBase64) { + if (this.base64AccumIdx > 0) { + bufIdx += buf.write(this.base64Accum.slice(0, this.base64AccumIdx).toString('base64').replace(/\//g, ',').replace(/=+$/, ''), bufIdx); + this.base64AccumIdx = 0; + } + + buf[bufIdx++] = minusChar; // Write '-', then go to direct mode. + this.inBase64 = false; + } + + return buf.slice(0, bufIdx); +} + + +// -- Decoding + +function Utf7IMAPDecoder(options, codec) { + this.iconv = codec.iconv; + this.inBase64 = false; + this.base64Accum = ''; +} + +var base64IMAPChars = base64Chars.slice(); +base64IMAPChars[','.charCodeAt(0)] = true; + +Utf7IMAPDecoder.prototype.write = function(buf) { + var res = "", lastI = 0, + inBase64 = this.inBase64, + base64Accum = this.base64Accum; + + // The decoder is more involved as we must handle chunks in stream. + // It is forgiving, closer to standard UTF-7 (for example, '-' is optional at the end). + + for (var i = 0; i < buf.length; i++) { + if (!inBase64) { // We're in direct mode. + // Write direct chars until '&' + if (buf[i] == andChar) { + res += this.iconv.decode(buf.slice(lastI, i), "ascii"); // Write direct chars. + lastI = i+1; + inBase64 = true; + } + } else { // We decode base64. + if (!base64IMAPChars[buf[i]]) { // Base64 ended. + if (i == lastI && buf[i] == minusChar) { // "&-" -> "&" + res += "&"; + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI, i), "ascii").replace(/,/g, '/'); + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } + + if (buf[i] != minusChar) // Minus may be absorbed after base64. + i--; + + lastI = i+1; + inBase64 = false; + base64Accum = ''; + } + } + } + + if (!inBase64) { + res += this.iconv.decode(buf.slice(lastI), "ascii"); // Write direct chars. + } else { + var b64str = base64Accum + this.iconv.decode(buf.slice(lastI), "ascii").replace(/,/g, '/'); + + var canBeDecoded = b64str.length - (b64str.length % 8); // Minimal chunk: 2 quads -> 2x3 bytes -> 3 chars. + base64Accum = b64str.slice(canBeDecoded); // The rest will be decoded in future. + b64str = b64str.slice(0, canBeDecoded); + + res += this.iconv.decode(Buffer.from(b64str, 'base64'), "utf16-be"); + } + + this.inBase64 = inBase64; + this.base64Accum = base64Accum; + + return res; +} + +Utf7IMAPDecoder.prototype.end = function() { + var res = ""; + if (this.inBase64 && this.base64Accum.length > 0) + res = this.iconv.decode(Buffer.from(this.base64Accum, 'base64'), "utf16-be"); + + this.inBase64 = false; + this.base64Accum = ''; + return res; +} + + + + +/***/ }), + +/***/ 7318: +/***/ ((__unused_webpack_module, exports) => { + + + +var BOMChar = '\uFEFF'; + +exports.PrependBOM = PrependBOMWrapper +function PrependBOMWrapper(encoder, options) { + this.encoder = encoder; + this.addBOM = true; +} + +PrependBOMWrapper.prototype.write = function(str) { + if (this.addBOM) { + str = BOMChar + str; + this.addBOM = false; + } + + return this.encoder.write(str); +} + +PrependBOMWrapper.prototype.end = function() { + return this.encoder.end(); +} + + +//------------------------------------------------------------------------------ + +exports.StripBOM = StripBOMWrapper; +function StripBOMWrapper(decoder, options) { + this.decoder = decoder; + this.pass = false; + this.options = options || {}; +} + +StripBOMWrapper.prototype.write = function(buf) { + var res = this.decoder.write(buf); + if (this.pass || !res) + return res; + + if (res[0] === BOMChar) { + res = res.slice(1); + if (typeof this.options.stripBOM === 'function') + this.options.stripBOM(); + } + + this.pass = true; + return res; +} + +StripBOMWrapper.prototype.end = function() { + return this.decoder.end(); +} + + + +/***/ }), + +/***/ 3225: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +var bomHandling = __nccwpck_require__(7318), + iconv = module.exports; + +// All codecs and aliases are kept here, keyed by encoding name/alias. +// They are lazy loaded in `iconv.getCodec` from `encodings/index.js`. +iconv.encodings = null; + +// Characters emitted in case of error. +iconv.defaultCharUnicode = '�'; +iconv.defaultCharSingleByte = '?'; + +// Public API. +iconv.encode = function encode(str, encoding, options) { + str = "" + (str || ""); // Ensure string. + + var encoder = iconv.getEncoder(encoding, options); + + var res = encoder.write(str); + var trail = encoder.end(); + + return (trail && trail.length > 0) ? Buffer.concat([res, trail]) : res; +} + +iconv.decode = function decode(buf, encoding, options) { + if (typeof buf === 'string') { + if (!iconv.skipDecodeWarning) { + console.error('Iconv-lite warning: decode()-ing strings is deprecated. Refer to https://github.com/ashtuchkin/iconv-lite/wiki/Use-Buffers-when-decoding'); + iconv.skipDecodeWarning = true; + } + + buf = Buffer.from("" + (buf || ""), "binary"); // Ensure buffer. + } + + var decoder = iconv.getDecoder(encoding, options); + + var res = decoder.write(buf); + var trail = decoder.end(); + + return trail ? (res + trail) : res; +} + +iconv.encodingExists = function encodingExists(enc) { + try { + iconv.getCodec(enc); + return true; + } catch (e) { + return false; + } +} + +// Legacy aliases to convert functions +iconv.toEncoding = iconv.encode; +iconv.fromEncoding = iconv.decode; + +// Search for a codec in iconv.encodings. Cache codec data in iconv._codecDataCache. +iconv._codecDataCache = {}; +iconv.getCodec = function getCodec(encoding) { + if (!iconv.encodings) + iconv.encodings = __nccwpck_require__(1446); // Lazy load all encoding definitions. + + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. + var enc = iconv._canonicalizeEncoding(encoding); + + // Traverse iconv.encodings to find actual codec. + var codecOptions = {}; + while (true) { + var codec = iconv._codecDataCache[enc]; + if (codec) + return codec; + + var codecDef = iconv.encodings[enc]; + + switch (typeof codecDef) { + case "string": // Direct alias to other encoding. + enc = codecDef; + break; + + case "object": // Alias with options. Can be layered. + for (var key in codecDef) + codecOptions[key] = codecDef[key]; + + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; + + enc = codecDef.type; + break; + + case "function": // Codec itself. + if (!codecOptions.encodingName) + codecOptions.encodingName = enc; + + // The codec function must load all tables and return object with .encoder and .decoder methods. + // It'll be called only once (for each different options object). + codec = new codecDef(codecOptions, iconv); + + iconv._codecDataCache[codecOptions.encodingName] = codec; // Save it to be reused later. + return codec; + + default: + throw new Error("Encoding not recognized: '" + encoding + "' (searched as: '"+enc+"')"); + } + } +} + +iconv._canonicalizeEncoding = function(encoding) { + // Canonicalize encoding name: strip all non-alphanumeric chars and appended year. + return (''+encoding).toLowerCase().replace(/:\d{4}$|[^0-9a-z]/g, ""); +} + +iconv.getEncoder = function getEncoder(encoding, options) { + var codec = iconv.getCodec(encoding), + encoder = new codec.encoder(options, codec); + + if (codec.bomAware && options && options.addBOM) + encoder = new bomHandling.PrependBOM(encoder, options); + + return encoder; +} + +iconv.getDecoder = function getDecoder(encoding, options) { + var codec = iconv.getCodec(encoding), + decoder = new codec.decoder(options, codec); + + if (codec.bomAware && !(options && options.stripBOM === false)) + decoder = new bomHandling.StripBOM(decoder, options); + + return decoder; +} + +// Streaming API +// NOTE: Streaming API naturally depends on 'stream' module from Node.js. Unfortunately in browser environments this module can add +// up to 100Kb to the output bundle. To avoid unnecessary code bloat, we don't enable Streaming API in browser by default. +// If you would like to enable it explicitly, please add the following code to your app: +// > iconv.enableStreamingAPI(require('stream')); +iconv.enableStreamingAPI = function enableStreamingAPI(stream_module) { + if (iconv.supportsStreams) + return; + + // Dependency-inject stream module to create IconvLite stream classes. + var streams = __nccwpck_require__(4966)(stream_module); + + // Not public API yet, but expose the stream classes. + iconv.IconvLiteEncoderStream = streams.IconvLiteEncoderStream; + iconv.IconvLiteDecoderStream = streams.IconvLiteDecoderStream; + + // Streaming API. + iconv.encodeStream = function encodeStream(encoding, options) { + return new iconv.IconvLiteEncoderStream(iconv.getEncoder(encoding, options), options); + } + + iconv.decodeStream = function decodeStream(encoding, options) { + return new iconv.IconvLiteDecoderStream(iconv.getDecoder(encoding, options), options); + } + + iconv.supportsStreams = true; +} + +// Enable Streaming API automatically if 'stream' module is available and non-empty (the majority of environments). +var stream_module; +try { + stream_module = __nccwpck_require__(2781); +} catch (e) {} + +if (stream_module && stream_module.Transform) { + iconv.enableStreamingAPI(stream_module); + +} else { + // In rare cases where 'stream' module is not available by default, throw a helpful exception. + iconv.encodeStream = iconv.decodeStream = function() { + throw new Error("iconv-lite Streaming API is not enabled. Use iconv.enableStreamingAPI(require('stream')); to enable it."); + }; +} + +if (false) {} + + +/***/ }), + +/***/ 4966: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + + + +var Buffer = (__nccwpck_require__(8772).Buffer); + +// NOTE: Due to 'stream' module being pretty large (~100Kb, significant in browser environments), +// we opt to dependency-inject it instead of creating a hard dependency. +module.exports = function(stream_module) { + var Transform = stream_module.Transform; + + // == Encoder stream ======================================================= + + function IconvLiteEncoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.decodeStrings = false; // We accept only strings, so we don't need to decode them. + Transform.call(this, options); + } + + IconvLiteEncoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteEncoderStream } + }); + + IconvLiteEncoderStream.prototype._transform = function(chunk, encoding, done) { + if (typeof chunk != 'string') + return done(new Error("Iconv encoding stream needs strings as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res); + done(); + } + catch (e) { + done(e); + } + } + + IconvLiteEncoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res); + done(); + } + catch (e) { + done(e); + } + } + + IconvLiteEncoderStream.prototype.collect = function(cb) { + var chunks = []; + this.on('error', cb); + this.on('data', function(chunk) { chunks.push(chunk); }); + this.on('end', function() { + cb(null, Buffer.concat(chunks)); + }); + return this; + } + + + // == Decoder stream ======================================================= + + function IconvLiteDecoderStream(conv, options) { + this.conv = conv; + options = options || {}; + options.encoding = this.encoding = 'utf8'; // We output strings. + Transform.call(this, options); + } + + IconvLiteDecoderStream.prototype = Object.create(Transform.prototype, { + constructor: { value: IconvLiteDecoderStream } + }); + + IconvLiteDecoderStream.prototype._transform = function(chunk, encoding, done) { + if (!Buffer.isBuffer(chunk) && !(chunk instanceof Uint8Array)) + return done(new Error("Iconv decoding stream needs buffers as its input.")); + try { + var res = this.conv.write(chunk); + if (res && res.length) this.push(res, this.encoding); + done(); + } + catch (e) { + done(e); + } + } + + IconvLiteDecoderStream.prototype._flush = function(done) { + try { + var res = this.conv.end(); + if (res && res.length) this.push(res, this.encoding); + done(); + } + catch (e) { + done(e); + } + } + + IconvLiteDecoderStream.prototype.collect = function(cb) { + var res = ''; + this.on('error', cb); + this.on('data', function(chunk) { res += chunk; }); + this.on('end', function() { + cb(null, res); + }); + return this; + } + + return { + IconvLiteEncoderStream: IconvLiteEncoderStream, + IconvLiteDecoderStream: IconvLiteDecoderStream, + }; +}; + + +/***/ }), + +/***/ 8772: +/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { + +/* eslint-disable node/no-deprecated-api */ + + + +var buffer = __nccwpck_require__(4300) +var Buffer = buffer.Buffer + +var safer = {} + +var key + +for (key in buffer) { + if (!buffer.hasOwnProperty(key)) continue + if (key === 'SlowBuffer' || key === 'Buffer') continue + safer[key] = buffer[key] +} + +var Safer = safer.Buffer = {} +for (key in Buffer) { + if (!Buffer.hasOwnProperty(key)) continue + if (key === 'allocUnsafe' || key === 'allocUnsafeSlow') continue + Safer[key] = Buffer[key] +} + +safer.Buffer.prototype = Buffer.prototype + +if (!Safer.from || Safer.from === Uint8Array.from) { + Safer.from = function (value, encodingOrOffset, length) { + if (typeof value === 'number') { + throw new TypeError('The "value" argument must not be of type number. Received type ' + typeof value) + } + if (value && typeof value.length === 'undefined') { + throw new TypeError('The first argument must be one of type string, Buffer, ArrayBuffer, Array, or Array-like Object. Received type ' + typeof value) + } + return Buffer(value, encodingOrOffset, length) + } +} + +if (!Safer.alloc) { + Safer.alloc = function (size, fill, encoding) { + if (typeof size !== 'number') { + throw new TypeError('The "size" argument must be of type number. Received type ' + typeof size) + } + if (size < 0 || size >= 2 * (1 << 30)) { + throw new RangeError('The value "' + size + '" is invalid for option "size"') + } + var buf = Buffer(size) + if (!fill || fill.length === 0) { + buf.fill(0) + } else if (typeof encoding === 'string') { + buf.fill(fill, encoding) + } else { + buf.fill(fill) + } + return buf + } +} + +if (!safer.kStringMaxLength) { + try { + safer.kStringMaxLength = process.binding('buffer').kStringMaxLength + } catch (e) { + // we can't determine kStringMaxLength in environments where process.binding + // is unsupported, so let's not set it + } +} + +if (!safer.constants) { + safer.constants = { + MAX_LENGTH: safer.kMaxLength + } + if (safer.kStringMaxLength) { + safer.constants.MAX_STRING_LENGTH = safer.kStringMaxLength + } +} + +module.exports = safer + + +/***/ }), + +/***/ 9491: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("assert"); + +/***/ }), + +/***/ 4300: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("buffer"); + +/***/ }), + +/***/ 6113: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("crypto"); + +/***/ }), + +/***/ 2361: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("events"); + +/***/ }), + +/***/ 7147: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("fs"); + +/***/ }), + +/***/ 3685: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("http"); + +/***/ }), + +/***/ 5687: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("https"); + +/***/ }), + +/***/ 1808: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("net"); + +/***/ }), + +/***/ 7742: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:process"); + +/***/ }), + +/***/ 2477: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:stream/web"); + +/***/ }), + +/***/ 2037: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("os"); + +/***/ }), + +/***/ 1017: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("path"); + +/***/ }), + +/***/ 5477: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("punycode"); + +/***/ }), + +/***/ 2781: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("stream"); + +/***/ }), + +/***/ 1576: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("string_decoder"); + +/***/ }), + +/***/ 4404: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("tls"); + +/***/ }), + +/***/ 7310: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("url"); + +/***/ }), + +/***/ 3837: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("util"); + +/***/ }), + +/***/ 1267: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("worker_threads"); + +/***/ }), + +/***/ 9796: +/***/ ((module) => { + +module.exports = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("zlib"); + +/***/ }), + +/***/ 8572: +/***/ ((__unused_webpack_module, __unused_webpack_exports, __nccwpck_require__) => { + +/* c8 ignore start */ +// 64 KiB (same size chrome slice theirs blob into Uint8array's) +const POOL_SIZE = 65536 + +if (!globalThis.ReadableStream) { + // `node:stream/web` got introduced in v16.5.0 as experimental + // and it's preferred over the polyfilled version. So we also + // suppress the warning that gets emitted by NodeJS for using it. + try { + const process = __nccwpck_require__(7742) + const { emitWarning } = process + try { + process.emitWarning = () => {} + Object.assign(globalThis, __nccwpck_require__(2477)) + process.emitWarning = emitWarning + } catch (error) { + process.emitWarning = emitWarning + throw error + } + } catch (error) { + // fallback to polyfill implementation + Object.assign(globalThis, __nccwpck_require__(1452)) + } +} + +try { + // Don't use node: prefix for this, require+node: is not supported until node v14.14 + // Only `import()` can use prefix in 12.20 and later + const { Blob } = __nccwpck_require__(4300) + if (Blob && !Blob.prototype.stream) { + Blob.prototype.stream = function name (params) { + let position = 0 + const blob = this + + return new ReadableStream({ + type: 'bytes', + async pull (ctrl) { + const chunk = blob.slice(position, Math.min(blob.size, position + POOL_SIZE)) + const buffer = await chunk.arrayBuffer() + position += buffer.byteLength + ctrl.enqueue(new Uint8Array(buffer)) + + if (position === blob.size) { + ctrl.close() + } + } + }) + } + } +} catch (error) {} +/* c8 ignore end */ + + +/***/ }), + +/***/ 3213: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { + +/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* unused harmony export File */ +/* harmony import */ var _index_js__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(1410); + + +const _File = class File extends _index_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z { + #lastModified = 0 + #name = '' + + /** + * @param {*[]} fileBits + * @param {string} fileName + * @param {{lastModified?: number, type?: string}} options + */// @ts-ignore + constructor (fileBits, fileName, options = {}) { + if (arguments.length < 2) { + throw new TypeError(`Failed to construct 'File': 2 arguments required, but only ${arguments.length} present.`) + } + super(fileBits, options) + + if (options === null) options = {} + + // Simulate WebIDL type casting for NaN value in lastModified option. + const lastModified = options.lastModified === undefined ? Date.now() : Number(options.lastModified) + if (!Number.isNaN(lastModified)) { + this.#lastModified = lastModified + } + + this.#name = String(fileName) + } + + get name () { + return this.#name + } + + get lastModified () { + return this.#lastModified + } + + get [Symbol.toStringTag] () { + return 'File' + } + + static [Symbol.hasInstance] (object) { + return !!object && object instanceof _index_js__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z && + /^(File)$/.test(object[Symbol.toStringTag]) + } +} + +/** @type {typeof globalThis.File} */// @ts-ignore +const File = _File +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (File); + + +/***/ }), + +/***/ 2777: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { + + +// EXPORTS +__nccwpck_require__.d(__webpack_exports__, { + "$B": () => (/* reexport */ file/* default */.Z) +}); + +// UNUSED EXPORTS: Blob, blobFrom, blobFromSync, default, fileFrom, fileFromSync + +;// CONCATENATED MODULE: external "node:fs" +const external_node_fs_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:fs"); +;// CONCATENATED MODULE: external "node:path" +const external_node_path_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:path"); +// EXTERNAL MODULE: ./node_modules/node-domexception/index.js +var node_domexception = __nccwpck_require__(7760); +// EXTERNAL MODULE: ./node_modules/fetch-blob/file.js +var file = __nccwpck_require__(3213); +// EXTERNAL MODULE: ./node_modules/fetch-blob/index.js +var fetch_blob = __nccwpck_require__(1410); +;// CONCATENATED MODULE: ./node_modules/fetch-blob/from.js + + + + + + + +const { stat } = external_node_fs_namespaceObject.promises + +/** + * @param {string} path filepath on the disk + * @param {string} [type] mimetype to use + */ +const blobFromSync = (path, type) => fromBlob(statSync(path), path, type) + +/** + * @param {string} path filepath on the disk + * @param {string} [type] mimetype to use + * @returns {Promise<Blob>} + */ +const blobFrom = (path, type) => stat(path).then(stat => fromBlob(stat, path, type)) + +/** + * @param {string} path filepath on the disk + * @param {string} [type] mimetype to use + * @returns {Promise<File>} + */ +const fileFrom = (path, type) => stat(path).then(stat => fromFile(stat, path, type)) + +/** + * @param {string} path filepath on the disk + * @param {string} [type] mimetype to use + */ +const fileFromSync = (path, type) => fromFile(statSync(path), path, type) + +// @ts-ignore +const fromBlob = (stat, path, type = '') => new Blob([new BlobDataItem({ + path, + size: stat.size, + lastModified: stat.mtimeMs, + start: 0 +})], { type }) + +// @ts-ignore +const fromFile = (stat, path, type = '') => new File([new BlobDataItem({ + path, + size: stat.size, + lastModified: stat.mtimeMs, + start: 0 +})], basename(path), { type, lastModified: stat.mtimeMs }) + +/** + * This is a blob backed up by a file on the disk + * with minium requirement. Its wrapped around a Blob as a blobPart + * so you have no direct access to this. + * + * @private + */ +class BlobDataItem { + #path + #start + + constructor (options) { + this.#path = options.path + this.#start = options.start + this.size = options.size + this.lastModified = options.lastModified + } + + /** + * Slicing arguments is first validated and formatted + * to not be out of range by Blob.prototype.slice + */ + slice (start, end) { + return new BlobDataItem({ + path: this.#path, + lastModified: this.lastModified, + size: end - start, + start: this.#start + start + }) + } + + async * stream () { + const { mtimeMs } = await stat(this.#path) + if (mtimeMs > this.lastModified) { + throw new DOMException('The requested file could not be read, typically due to permission problems that have occurred after a reference to a file was acquired.', 'NotReadableError') + } + yield * createReadStream(this.#path, { + start: this.#start, + end: this.#start + this.size - 1 + }) + } + + get [Symbol.toStringTag] () { + return 'Blob' + } +} + +/* harmony default export */ const from = ((/* unused pure expression or super */ null && (blobFromSync))); + + + +/***/ }), + +/***/ 1410: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { + +/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { +/* harmony export */ "Z": () => (__WEBPACK_DEFAULT_EXPORT__) +/* harmony export */ }); +/* unused harmony export Blob */ +/* harmony import */ var _streams_cjs__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(8572); +/*! fetch-blob. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ + +// TODO (jimmywarting): in the feature use conditional loading with top level await (requires 14.x) +// Node has recently added whatwg stream into core + + + +// 64 KiB (same size chrome slice theirs blob into Uint8array's) +const POOL_SIZE = 65536 + +/** @param {(Blob | Uint8Array)[]} parts */ +async function * toIterator (parts, clone = true) { + for (const part of parts) { + if ('stream' in part) { + yield * (/** @type {AsyncIterableIterator<Uint8Array>} */ (part.stream())) + } else if (ArrayBuffer.isView(part)) { + if (clone) { + let position = part.byteOffset + const end = part.byteOffset + part.byteLength + while (position !== end) { + const size = Math.min(end - position, POOL_SIZE) + const chunk = part.buffer.slice(position, position + size) + position += chunk.byteLength + yield new Uint8Array(chunk) + } + } else { + yield part + } + /* c8 ignore next 10 */ + } else { + // For blobs that have arrayBuffer but no stream method (nodes buffer.Blob) + let position = 0, b = (/** @type {Blob} */ (part)) + while (position !== b.size) { + const chunk = b.slice(position, Math.min(b.size, position + POOL_SIZE)) + const buffer = await chunk.arrayBuffer() + position += buffer.byteLength + yield new Uint8Array(buffer) + } + } + } +} + +const _Blob = class Blob { + /** @type {Array.<(Blob|Uint8Array)>} */ + #parts = [] + #type = '' + #size = 0 + #endings = 'transparent' + + /** + * The Blob() constructor returns a new Blob object. The content + * of the blob consists of the concatenation of the values given + * in the parameter array. + * + * @param {*} blobParts + * @param {{ type?: string, endings?: string }} [options] + */ + constructor (blobParts = [], options = {}) { + if (typeof blobParts !== 'object' || blobParts === null) { + throw new TypeError('Failed to construct \'Blob\': The provided value cannot be converted to a sequence.') + } + + if (typeof blobParts[Symbol.iterator] !== 'function') { + throw new TypeError('Failed to construct \'Blob\': The object must have a callable @@iterator property.') + } + + if (typeof options !== 'object' && typeof options !== 'function') { + throw new TypeError('Failed to construct \'Blob\': parameter 2 cannot convert to dictionary.') + } + + if (options === null) options = {} + + const encoder = new TextEncoder() + for (const element of blobParts) { + let part + if (ArrayBuffer.isView(element)) { + part = new Uint8Array(element.buffer.slice(element.byteOffset, element.byteOffset + element.byteLength)) + } else if (element instanceof ArrayBuffer) { + part = new Uint8Array(element.slice(0)) + } else if (element instanceof Blob) { + part = element + } else { + part = encoder.encode(`${element}`) + } + + this.#size += ArrayBuffer.isView(part) ? part.byteLength : part.size + this.#parts.push(part) + } + + this.#endings = `${options.endings === undefined ? 'transparent' : options.endings}` + const type = options.type === undefined ? '' : String(options.type) + this.#type = /^[\x20-\x7E]*$/.test(type) ? type : '' + } + + /** + * The Blob interface's size property returns the + * size of the Blob in bytes. + */ + get size () { + return this.#size + } + + /** + * The type property of a Blob object returns the MIME type of the file. + */ + get type () { + return this.#type + } + + /** + * The text() method in the Blob interface returns a Promise + * that resolves with a string containing the contents of + * the blob, interpreted as UTF-8. + * + * @return {Promise<string>} + */ + async text () { + // More optimized than using this.arrayBuffer() + // that requires twice as much ram + const decoder = new TextDecoder() + let str = '' + for await (const part of toIterator(this.#parts, false)) { + str += decoder.decode(part, { stream: true }) + } + // Remaining + str += decoder.decode() + return str + } + + /** + * The arrayBuffer() method in the Blob interface returns a + * Promise that resolves with the contents of the blob as + * binary data contained in an ArrayBuffer. + * + * @return {Promise<ArrayBuffer>} + */ + async arrayBuffer () { + // Easier way... Just a unnecessary overhead + // const view = new Uint8Array(this.size); + // await this.stream().getReader({mode: 'byob'}).read(view); + // return view.buffer; + + const data = new Uint8Array(this.size) + let offset = 0 + for await (const chunk of toIterator(this.#parts, false)) { + data.set(chunk, offset) + offset += chunk.length + } + + return data.buffer + } + + stream () { + const it = toIterator(this.#parts, true) + + return new globalThis.ReadableStream({ + // @ts-ignore + type: 'bytes', + async pull (ctrl) { + const chunk = await it.next() + chunk.done ? ctrl.close() : ctrl.enqueue(chunk.value) + }, + + async cancel () { + await it.return() + } + }) + } + + /** + * The Blob interface's slice() method creates and returns a + * new Blob object which contains data from a subset of the + * blob on which it's called. + * + * @param {number} [start] + * @param {number} [end] + * @param {string} [type] + */ + slice (start = 0, end = this.size, type = '') { + const { size } = this + + let relativeStart = start < 0 ? Math.max(size + start, 0) : Math.min(start, size) + let relativeEnd = end < 0 ? Math.max(size + end, 0) : Math.min(end, size) + + const span = Math.max(relativeEnd - relativeStart, 0) + const parts = this.#parts + const blobParts = [] + let added = 0 + + for (const part of parts) { + // don't add the overflow to new blobParts + if (added >= span) { + break + } + + const size = ArrayBuffer.isView(part) ? part.byteLength : part.size + if (relativeStart && size <= relativeStart) { + // Skip the beginning and change the relative + // start & end position as we skip the unwanted parts + relativeStart -= size + relativeEnd -= size + } else { + let chunk + if (ArrayBuffer.isView(part)) { + chunk = part.subarray(relativeStart, Math.min(size, relativeEnd)) + added += chunk.byteLength + } else { + chunk = part.slice(relativeStart, Math.min(size, relativeEnd)) + added += chunk.size + } + relativeEnd -= size + blobParts.push(chunk) + relativeStart = 0 // All next sequential parts should start at 0 + } + } + + const blob = new Blob([], { type: String(type).toLowerCase() }) + blob.#size = span + blob.#parts = blobParts + + return blob + } + + get [Symbol.toStringTag] () { + return 'Blob' + } + + static [Symbol.hasInstance] (object) { + return ( + object && + typeof object === 'object' && + typeof object.constructor === 'function' && + ( + typeof object.stream === 'function' || + typeof object.arrayBuffer === 'function' + ) && + /^(Blob|File)$/.test(object[Symbol.toStringTag]) + ) + } +} + +Object.defineProperties(_Blob.prototype, { + size: { enumerable: true }, + type: { enumerable: true }, + slice: { enumerable: true } +}) + +/** @type {typeof globalThis.Blob} */ +const Blob = _Blob +/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (Blob); + + +/***/ }), + +/***/ 8010: +/***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => { + +/* harmony export */ __nccwpck_require__.d(__webpack_exports__, { +/* harmony export */ "Ct": () => (/* binding */ FormData), +/* harmony export */ "au": () => (/* binding */ formDataToBlob) +/* harmony export */ }); +/* unused harmony export File */ +/* harmony import */ var fetch_blob__WEBPACK_IMPORTED_MODULE_0__ = __nccwpck_require__(1410); +/* harmony import */ var fetch_blob_file_js__WEBPACK_IMPORTED_MODULE_1__ = __nccwpck_require__(3213); +/*! formdata-polyfill. MIT License. Jimmy Wärting <https://jimmy.warting.se/opensource> */ + + + + +var {toStringTag:t,iterator:i,hasInstance:h}=Symbol, +r=Math.random, +m='append,set,get,getAll,delete,keys,values,entries,forEach,constructor'.split(','), +f=(a,b,c)=>(a+='',/^(Blob|File)$/.test(b && b[t])?[(c=c!==void 0?c+'':b[t]=='File'?b.name:'blob',a),b.name!==c||b[t]=='blob'?new fetch_blob_file_js__WEBPACK_IMPORTED_MODULE_1__/* ["default"] */ .Z([b],c,b):b]:[a,b+'']), +e=(c,f)=>(f?c:c.replace(/\r?\n|\r/g,'\r\n')).replace(/\n/g,'%0A').replace(/\r/g,'%0D').replace(/"/g,'%22'), +x=(n, a, e)=>{if(a.length<e){throw new TypeError(`Failed to execute '${n}' on 'FormData': ${e} arguments required, but only ${a.length} present.`)}} + +const File = (/* unused pure expression or super */ null && (F)) + +/** @type {typeof globalThis.FormData} */ +const FormData = class FormData { +#d=[]; +constructor(...a){if(a.length)throw new TypeError(`Failed to construct 'FormData': parameter 1 is not of type 'HTMLFormElement'.`)} +get [t]() {return 'FormData'} +[i](){return this.entries()} +static [h](o) {return o&&typeof o==='object'&&o[t]==='FormData'&&!m.some(m=>typeof o[m]!='function')} +append(...a){x('append',arguments,2);this.#d.push(f(...a))} +delete(a){x('delete',arguments,1);a+='';this.#d=this.#d.filter(([b])=>b!==a)} +get(a){x('get',arguments,1);a+='';for(var b=this.#d,l=b.length,c=0;c<l;c++)if(b[c][0]===a)return b[c][1];return null} +getAll(a,b){x('getAll',arguments,1);b=[];a+='';this.#d.forEach(c=>c[0]===a&&b.push(c[1]));return b} +has(a){x('has',arguments,1);a+='';return this.#d.some(b=>b[0]===a)} +forEach(a,b){x('forEach',arguments,1);for(var [c,d]of this)a.call(b,d,c,this)} +set(...a){x('set',arguments,2);var b=[],c=!0;a=f(...a);this.#d.forEach(d=>{d[0]===a[0]?c&&(c=!b.push(a)):b.push(d)});c&&b.push(a);this.#d=b} +*entries(){yield*this.#d} +*keys(){for(var[a]of this)yield a} +*values(){for(var[,a]of this)yield a}} + +/** @param {FormData} F */ +function formDataToBlob (F,B=fetch_blob__WEBPACK_IMPORTED_MODULE_0__/* ["default"] */ .Z){ +var b=`${r()}${r()}`.replace(/\./g, '').slice(-28).padStart(32, '-'),c=[],p=`--${b}\r\nContent-Disposition: form-data; name="` +F.forEach((v,n)=>typeof v=='string' +?c.push(p+e(n)+`"\r\n\r\n${v.replace(/\r(?!\n)|(?<!\r)\n/g, '\r\n')}\r\n`) +:c.push(p+e(n)+`"; filename="${e(v.name, 1)}"\r\nContent-Type: ${v.type||"application/octet-stream"}\r\n\r\n`, v, '\r\n')) +c.push(`--${b}--`) +return new B(c,{type:"multipart/form-data; boundary="+b})} + + +/***/ }), + +/***/ 2020: +/***/ ((module) => { + +module.exports = JSON.parse('[[[0,44],"disallowed_STD3_valid"],[[45,46],"valid"],[[47,47],"disallowed_STD3_valid"],[[48,57],"valid"],[[58,64],"disallowed_STD3_valid"],[[65,65],"mapped",[97]],[[66,66],"mapped",[98]],[[67,67],"mapped",[99]],[[68,68],"mapped",[100]],[[69,69],"mapped",[101]],[[70,70],"mapped",[102]],[[71,71],"mapped",[103]],[[72,72],"mapped",[104]],[[73,73],"mapped",[105]],[[74,74],"mapped",[106]],[[75,75],"mapped",[107]],[[76,76],"mapped",[108]],[[77,77],"mapped",[109]],[[78,78],"mapped",[110]],[[79,79],"mapped",[111]],[[80,80],"mapped",[112]],[[81,81],"mapped",[113]],[[82,82],"mapped",[114]],[[83,83],"mapped",[115]],[[84,84],"mapped",[116]],[[85,85],"mapped",[117]],[[86,86],"mapped",[118]],[[87,87],"mapped",[119]],[[88,88],"mapped",[120]],[[89,89],"mapped",[121]],[[90,90],"mapped",[122]],[[91,96],"disallowed_STD3_valid"],[[97,122],"valid"],[[123,127],"disallowed_STD3_valid"],[[128,159],"disallowed"],[[160,160],"disallowed_STD3_mapped",[32]],[[161,167],"valid",[],"NV8"],[[168,168],"disallowed_STD3_mapped",[32,776]],[[169,169],"valid",[],"NV8"],[[170,170],"mapped",[97]],[[171,172],"valid",[],"NV8"],[[173,173],"ignored"],[[174,174],"valid",[],"NV8"],[[175,175],"disallowed_STD3_mapped",[32,772]],[[176,177],"valid",[],"NV8"],[[178,178],"mapped",[50]],[[179,179],"mapped",[51]],[[180,180],"disallowed_STD3_mapped",[32,769]],[[181,181],"mapped",[956]],[[182,182],"valid",[],"NV8"],[[183,183],"valid"],[[184,184],"disallowed_STD3_mapped",[32,807]],[[185,185],"mapped",[49]],[[186,186],"mapped",[111]],[[187,187],"valid",[],"NV8"],[[188,188],"mapped",[49,8260,52]],[[189,189],"mapped",[49,8260,50]],[[190,190],"mapped",[51,8260,52]],[[191,191],"valid",[],"NV8"],[[192,192],"mapped",[224]],[[193,193],"mapped",[225]],[[194,194],"mapped",[226]],[[195,195],"mapped",[227]],[[196,196],"mapped",[228]],[[197,197],"mapped",[229]],[[198,198],"mapped",[230]],[[199,199],"mapped",[231]],[[200,200],"mapped",[232]],[[201,201],"mapped",[233]],[[202,202],"mapped",[234]],[[203,203],"mapped",[235]],[[204,204],"mapped",[236]],[[205,205],"mapped",[237]],[[206,206],"mapped",[238]],[[207,207],"mapped",[239]],[[208,208],"mapped",[240]],[[209,209],"mapped",[241]],[[210,210],"mapped",[242]],[[211,211],"mapped",[243]],[[212,212],"mapped",[244]],[[213,213],"mapped",[245]],[[214,214],"mapped",[246]],[[215,215],"valid",[],"NV8"],[[216,216],"mapped",[248]],[[217,217],"mapped",[249]],[[218,218],"mapped",[250]],[[219,219],"mapped",[251]],[[220,220],"mapped",[252]],[[221,221],"mapped",[253]],[[222,222],"mapped",[254]],[[223,223],"deviation",[115,115]],[[224,246],"valid"],[[247,247],"valid",[],"NV8"],[[248,255],"valid"],[[256,256],"mapped",[257]],[[257,257],"valid"],[[258,258],"mapped",[259]],[[259,259],"valid"],[[260,260],"mapped",[261]],[[261,261],"valid"],[[262,262],"mapped",[263]],[[263,263],"valid"],[[264,264],"mapped",[265]],[[265,265],"valid"],[[266,266],"mapped",[267]],[[267,267],"valid"],[[268,268],"mapped",[269]],[[269,269],"valid"],[[270,270],"mapped",[271]],[[271,271],"valid"],[[272,272],"mapped",[273]],[[273,273],"valid"],[[274,274],"mapped",[275]],[[275,275],"valid"],[[276,276],"mapped",[277]],[[277,277],"valid"],[[278,278],"mapped",[279]],[[279,279],"valid"],[[280,280],"mapped",[281]],[[281,281],"valid"],[[282,282],"mapped",[283]],[[283,283],"valid"],[[284,284],"mapped",[285]],[[285,285],"valid"],[[286,286],"mapped",[287]],[[287,287],"valid"],[[288,288],"mapped",[289]],[[289,289],"valid"],[[290,290],"mapped",[291]],[[291,291],"valid"],[[292,292],"mapped",[293]],[[293,293],"valid"],[[294,294],"mapped",[295]],[[295,295],"valid"],[[296,296],"mapped",[297]],[[297,297],"valid"],[[298,298],"mapped",[299]],[[299,299],"valid"],[[300,300],"mapped",[301]],[[301,301],"valid"],[[302,302],"mapped",[303]],[[303,303],"valid"],[[304,304],"mapped",[105,775]],[[305,305],"valid"],[[306,307],"mapped",[105,106]],[[308,308],"mapped",[309]],[[309,309],"valid"],[[310,310],"mapped",[311]],[[311,312],"valid"],[[313,313],"mapped",[314]],[[314,314],"valid"],[[315,315],"mapped",[316]],[[316,316],"valid"],[[317,317],"mapped",[318]],[[318,318],"valid"],[[319,320],"mapped",[108,183]],[[321,321],"mapped",[322]],[[322,322],"valid"],[[323,323],"mapped",[324]],[[324,324],"valid"],[[325,325],"mapped",[326]],[[326,326],"valid"],[[327,327],"mapped",[328]],[[328,328],"valid"],[[329,329],"mapped",[700,110]],[[330,330],"mapped",[331]],[[331,331],"valid"],[[332,332],"mapped",[333]],[[333,333],"valid"],[[334,334],"mapped",[335]],[[335,335],"valid"],[[336,336],"mapped",[337]],[[337,337],"valid"],[[338,338],"mapped",[339]],[[339,339],"valid"],[[340,340],"mapped",[341]],[[341,341],"valid"],[[342,342],"mapped",[343]],[[343,343],"valid"],[[344,344],"mapped",[345]],[[345,345],"valid"],[[346,346],"mapped",[347]],[[347,347],"valid"],[[348,348],"mapped",[349]],[[349,349],"valid"],[[350,350],"mapped",[351]],[[351,351],"valid"],[[352,352],"mapped",[353]],[[353,353],"valid"],[[354,354],"mapped",[355]],[[355,355],"valid"],[[356,356],"mapped",[357]],[[357,357],"valid"],[[358,358],"mapped",[359]],[[359,359],"valid"],[[360,360],"mapped",[361]],[[361,361],"valid"],[[362,362],"mapped",[363]],[[363,363],"valid"],[[364,364],"mapped",[365]],[[365,365],"valid"],[[366,366],"mapped",[367]],[[367,367],"valid"],[[368,368],"mapped",[369]],[[369,369],"valid"],[[370,370],"mapped",[371]],[[371,371],"valid"],[[372,372],"mapped",[373]],[[373,373],"valid"],[[374,374],"mapped",[375]],[[375,375],"valid"],[[376,376],"mapped",[255]],[[377,377],"mapped",[378]],[[378,378],"valid"],[[379,379],"mapped",[380]],[[380,380],"valid"],[[381,381],"mapped",[382]],[[382,382],"valid"],[[383,383],"mapped",[115]],[[384,384],"valid"],[[385,385],"mapped",[595]],[[386,386],"mapped",[387]],[[387,387],"valid"],[[388,388],"mapped",[389]],[[389,389],"valid"],[[390,390],"mapped",[596]],[[391,391],"mapped",[392]],[[392,392],"valid"],[[393,393],"mapped",[598]],[[394,394],"mapped",[599]],[[395,395],"mapped",[396]],[[396,397],"valid"],[[398,398],"mapped",[477]],[[399,399],"mapped",[601]],[[400,400],"mapped",[603]],[[401,401],"mapped",[402]],[[402,402],"valid"],[[403,403],"mapped",[608]],[[404,404],"mapped",[611]],[[405,405],"valid"],[[406,406],"mapped",[617]],[[407,407],"mapped",[616]],[[408,408],"mapped",[409]],[[409,411],"valid"],[[412,412],"mapped",[623]],[[413,413],"mapped",[626]],[[414,414],"valid"],[[415,415],"mapped",[629]],[[416,416],"mapped",[417]],[[417,417],"valid"],[[418,418],"mapped",[419]],[[419,419],"valid"],[[420,420],"mapped",[421]],[[421,421],"valid"],[[422,422],"mapped",[640]],[[423,423],"mapped",[424]],[[424,424],"valid"],[[425,425],"mapped",[643]],[[426,427],"valid"],[[428,428],"mapped",[429]],[[429,429],"valid"],[[430,430],"mapped",[648]],[[431,431],"mapped",[432]],[[432,432],"valid"],[[433,433],"mapped",[650]],[[434,434],"mapped",[651]],[[435,435],"mapped",[436]],[[436,436],"valid"],[[437,437],"mapped",[438]],[[438,438],"valid"],[[439,439],"mapped",[658]],[[440,440],"mapped",[441]],[[441,443],"valid"],[[444,444],"mapped",[445]],[[445,451],"valid"],[[452,454],"mapped",[100,382]],[[455,457],"mapped",[108,106]],[[458,460],"mapped",[110,106]],[[461,461],"mapped",[462]],[[462,462],"valid"],[[463,463],"mapped",[464]],[[464,464],"valid"],[[465,465],"mapped",[466]],[[466,466],"valid"],[[467,467],"mapped",[468]],[[468,468],"valid"],[[469,469],"mapped",[470]],[[470,470],"valid"],[[471,471],"mapped",[472]],[[472,472],"valid"],[[473,473],"mapped",[474]],[[474,474],"valid"],[[475,475],"mapped",[476]],[[476,477],"valid"],[[478,478],"mapped",[479]],[[479,479],"valid"],[[480,480],"mapped",[481]],[[481,481],"valid"],[[482,482],"mapped",[483]],[[483,483],"valid"],[[484,484],"mapped",[485]],[[485,485],"valid"],[[486,486],"mapped",[487]],[[487,487],"valid"],[[488,488],"mapped",[489]],[[489,489],"valid"],[[490,490],"mapped",[491]],[[491,491],"valid"],[[492,492],"mapped",[493]],[[493,493],"valid"],[[494,494],"mapped",[495]],[[495,496],"valid"],[[497,499],"mapped",[100,122]],[[500,500],"mapped",[501]],[[501,501],"valid"],[[502,502],"mapped",[405]],[[503,503],"mapped",[447]],[[504,504],"mapped",[505]],[[505,505],"valid"],[[506,506],"mapped",[507]],[[507,507],"valid"],[[508,508],"mapped",[509]],[[509,509],"valid"],[[510,510],"mapped",[511]],[[511,511],"valid"],[[512,512],"mapped",[513]],[[513,513],"valid"],[[514,514],"mapped",[515]],[[515,515],"valid"],[[516,516],"mapped",[517]],[[517,517],"valid"],[[518,518],"mapped",[519]],[[519,519],"valid"],[[520,520],"mapped",[521]],[[521,521],"valid"],[[522,522],"mapped",[523]],[[523,523],"valid"],[[524,524],"mapped",[525]],[[525,525],"valid"],[[526,526],"mapped",[527]],[[527,527],"valid"],[[528,528],"mapped",[529]],[[529,529],"valid"],[[530,530],"mapped",[531]],[[531,531],"valid"],[[532,532],"mapped",[533]],[[533,533],"valid"],[[534,534],"mapped",[535]],[[535,535],"valid"],[[536,536],"mapped",[537]],[[537,537],"valid"],[[538,538],"mapped",[539]],[[539,539],"valid"],[[540,540],"mapped",[541]],[[541,541],"valid"],[[542,542],"mapped",[543]],[[543,543],"valid"],[[544,544],"mapped",[414]],[[545,545],"valid"],[[546,546],"mapped",[547]],[[547,547],"valid"],[[548,548],"mapped",[549]],[[549,549],"valid"],[[550,550],"mapped",[551]],[[551,551],"valid"],[[552,552],"mapped",[553]],[[553,553],"valid"],[[554,554],"mapped",[555]],[[555,555],"valid"],[[556,556],"mapped",[557]],[[557,557],"valid"],[[558,558],"mapped",[559]],[[559,559],"valid"],[[560,560],"mapped",[561]],[[561,561],"valid"],[[562,562],"mapped",[563]],[[563,563],"valid"],[[564,566],"valid"],[[567,569],"valid"],[[570,570],"mapped",[11365]],[[571,571],"mapped",[572]],[[572,572],"valid"],[[573,573],"mapped",[410]],[[574,574],"mapped",[11366]],[[575,576],"valid"],[[577,577],"mapped",[578]],[[578,578],"valid"],[[579,579],"mapped",[384]],[[580,580],"mapped",[649]],[[581,581],"mapped",[652]],[[582,582],"mapped",[583]],[[583,583],"valid"],[[584,584],"mapped",[585]],[[585,585],"valid"],[[586,586],"mapped",[587]],[[587,587],"valid"],[[588,588],"mapped",[589]],[[589,589],"valid"],[[590,590],"mapped",[591]],[[591,591],"valid"],[[592,680],"valid"],[[681,685],"valid"],[[686,687],"valid"],[[688,688],"mapped",[104]],[[689,689],"mapped",[614]],[[690,690],"mapped",[106]],[[691,691],"mapped",[114]],[[692,692],"mapped",[633]],[[693,693],"mapped",[635]],[[694,694],"mapped",[641]],[[695,695],"mapped",[119]],[[696,696],"mapped",[121]],[[697,705],"valid"],[[706,709],"valid",[],"NV8"],[[710,721],"valid"],[[722,727],"valid",[],"NV8"],[[728,728],"disallowed_STD3_mapped",[32,774]],[[729,729],"disallowed_STD3_mapped",[32,775]],[[730,730],"disallowed_STD3_mapped",[32,778]],[[731,731],"disallowed_STD3_mapped",[32,808]],[[732,732],"disallowed_STD3_mapped",[32,771]],[[733,733],"disallowed_STD3_mapped",[32,779]],[[734,734],"valid",[],"NV8"],[[735,735],"valid",[],"NV8"],[[736,736],"mapped",[611]],[[737,737],"mapped",[108]],[[738,738],"mapped",[115]],[[739,739],"mapped",[120]],[[740,740],"mapped",[661]],[[741,745],"valid",[],"NV8"],[[746,747],"valid",[],"NV8"],[[748,748],"valid"],[[749,749],"valid",[],"NV8"],[[750,750],"valid"],[[751,767],"valid",[],"NV8"],[[768,831],"valid"],[[832,832],"mapped",[768]],[[833,833],"mapped",[769]],[[834,834],"valid"],[[835,835],"mapped",[787]],[[836,836],"mapped",[776,769]],[[837,837],"mapped",[953]],[[838,846],"valid"],[[847,847],"ignored"],[[848,855],"valid"],[[856,860],"valid"],[[861,863],"valid"],[[864,865],"valid"],[[866,866],"valid"],[[867,879],"valid"],[[880,880],"mapped",[881]],[[881,881],"valid"],[[882,882],"mapped",[883]],[[883,883],"valid"],[[884,884],"mapped",[697]],[[885,885],"valid"],[[886,886],"mapped",[887]],[[887,887],"valid"],[[888,889],"disallowed"],[[890,890],"disallowed_STD3_mapped",[32,953]],[[891,893],"valid"],[[894,894],"disallowed_STD3_mapped",[59]],[[895,895],"mapped",[1011]],[[896,899],"disallowed"],[[900,900],"disallowed_STD3_mapped",[32,769]],[[901,901],"disallowed_STD3_mapped",[32,776,769]],[[902,902],"mapped",[940]],[[903,903],"mapped",[183]],[[904,904],"mapped",[941]],[[905,905],"mapped",[942]],[[906,906],"mapped",[943]],[[907,907],"disallowed"],[[908,908],"mapped",[972]],[[909,909],"disallowed"],[[910,910],"mapped",[973]],[[911,911],"mapped",[974]],[[912,912],"valid"],[[913,913],"mapped",[945]],[[914,914],"mapped",[946]],[[915,915],"mapped",[947]],[[916,916],"mapped",[948]],[[917,917],"mapped",[949]],[[918,918],"mapped",[950]],[[919,919],"mapped",[951]],[[920,920],"mapped",[952]],[[921,921],"mapped",[953]],[[922,922],"mapped",[954]],[[923,923],"mapped",[955]],[[924,924],"mapped",[956]],[[925,925],"mapped",[957]],[[926,926],"mapped",[958]],[[927,927],"mapped",[959]],[[928,928],"mapped",[960]],[[929,929],"mapped",[961]],[[930,930],"disallowed"],[[931,931],"mapped",[963]],[[932,932],"mapped",[964]],[[933,933],"mapped",[965]],[[934,934],"mapped",[966]],[[935,935],"mapped",[967]],[[936,936],"mapped",[968]],[[937,937],"mapped",[969]],[[938,938],"mapped",[970]],[[939,939],"mapped",[971]],[[940,961],"valid"],[[962,962],"deviation",[963]],[[963,974],"valid"],[[975,975],"mapped",[983]],[[976,976],"mapped",[946]],[[977,977],"mapped",[952]],[[978,978],"mapped",[965]],[[979,979],"mapped",[973]],[[980,980],"mapped",[971]],[[981,981],"mapped",[966]],[[982,982],"mapped",[960]],[[983,983],"valid"],[[984,984],"mapped",[985]],[[985,985],"valid"],[[986,986],"mapped",[987]],[[987,987],"valid"],[[988,988],"mapped",[989]],[[989,989],"valid"],[[990,990],"mapped",[991]],[[991,991],"valid"],[[992,992],"mapped",[993]],[[993,993],"valid"],[[994,994],"mapped",[995]],[[995,995],"valid"],[[996,996],"mapped",[997]],[[997,997],"valid"],[[998,998],"mapped",[999]],[[999,999],"valid"],[[1000,1000],"mapped",[1001]],[[1001,1001],"valid"],[[1002,1002],"mapped",[1003]],[[1003,1003],"valid"],[[1004,1004],"mapped",[1005]],[[1005,1005],"valid"],[[1006,1006],"mapped",[1007]],[[1007,1007],"valid"],[[1008,1008],"mapped",[954]],[[1009,1009],"mapped",[961]],[[1010,1010],"mapped",[963]],[[1011,1011],"valid"],[[1012,1012],"mapped",[952]],[[1013,1013],"mapped",[949]],[[1014,1014],"valid",[],"NV8"],[[1015,1015],"mapped",[1016]],[[1016,1016],"valid"],[[1017,1017],"mapped",[963]],[[1018,1018],"mapped",[1019]],[[1019,1019],"valid"],[[1020,1020],"valid"],[[1021,1021],"mapped",[891]],[[1022,1022],"mapped",[892]],[[1023,1023],"mapped",[893]],[[1024,1024],"mapped",[1104]],[[1025,1025],"mapped",[1105]],[[1026,1026],"mapped",[1106]],[[1027,1027],"mapped",[1107]],[[1028,1028],"mapped",[1108]],[[1029,1029],"mapped",[1109]],[[1030,1030],"mapped",[1110]],[[1031,1031],"mapped",[1111]],[[1032,1032],"mapped",[1112]],[[1033,1033],"mapped",[1113]],[[1034,1034],"mapped",[1114]],[[1035,1035],"mapped",[1115]],[[1036,1036],"mapped",[1116]],[[1037,1037],"mapped",[1117]],[[1038,1038],"mapped",[1118]],[[1039,1039],"mapped",[1119]],[[1040,1040],"mapped",[1072]],[[1041,1041],"mapped",[1073]],[[1042,1042],"mapped",[1074]],[[1043,1043],"mapped",[1075]],[[1044,1044],"mapped",[1076]],[[1045,1045],"mapped",[1077]],[[1046,1046],"mapped",[1078]],[[1047,1047],"mapped",[1079]],[[1048,1048],"mapped",[1080]],[[1049,1049],"mapped",[1081]],[[1050,1050],"mapped",[1082]],[[1051,1051],"mapped",[1083]],[[1052,1052],"mapped",[1084]],[[1053,1053],"mapped",[1085]],[[1054,1054],"mapped",[1086]],[[1055,1055],"mapped",[1087]],[[1056,1056],"mapped",[1088]],[[1057,1057],"mapped",[1089]],[[1058,1058],"mapped",[1090]],[[1059,1059],"mapped",[1091]],[[1060,1060],"mapped",[1092]],[[1061,1061],"mapped",[1093]],[[1062,1062],"mapped",[1094]],[[1063,1063],"mapped",[1095]],[[1064,1064],"mapped",[1096]],[[1065,1065],"mapped",[1097]],[[1066,1066],"mapped",[1098]],[[1067,1067],"mapped",[1099]],[[1068,1068],"mapped",[1100]],[[1069,1069],"mapped",[1101]],[[1070,1070],"mapped",[1102]],[[1071,1071],"mapped",[1103]],[[1072,1103],"valid"],[[1104,1104],"valid"],[[1105,1116],"valid"],[[1117,1117],"valid"],[[1118,1119],"valid"],[[1120,1120],"mapped",[1121]],[[1121,1121],"valid"],[[1122,1122],"mapped",[1123]],[[1123,1123],"valid"],[[1124,1124],"mapped",[1125]],[[1125,1125],"valid"],[[1126,1126],"mapped",[1127]],[[1127,1127],"valid"],[[1128,1128],"mapped",[1129]],[[1129,1129],"valid"],[[1130,1130],"mapped",[1131]],[[1131,1131],"valid"],[[1132,1132],"mapped",[1133]],[[1133,1133],"valid"],[[1134,1134],"mapped",[1135]],[[1135,1135],"valid"],[[1136,1136],"mapped",[1137]],[[1137,1137],"valid"],[[1138,1138],"mapped",[1139]],[[1139,1139],"valid"],[[1140,1140],"mapped",[1141]],[[1141,1141],"valid"],[[1142,1142],"mapped",[1143]],[[1143,1143],"valid"],[[1144,1144],"mapped",[1145]],[[1145,1145],"valid"],[[1146,1146],"mapped",[1147]],[[1147,1147],"valid"],[[1148,1148],"mapped",[1149]],[[1149,1149],"valid"],[[1150,1150],"mapped",[1151]],[[1151,1151],"valid"],[[1152,1152],"mapped",[1153]],[[1153,1153],"valid"],[[1154,1154],"valid",[],"NV8"],[[1155,1158],"valid"],[[1159,1159],"valid"],[[1160,1161],"valid",[],"NV8"],[[1162,1162],"mapped",[1163]],[[1163,1163],"valid"],[[1164,1164],"mapped",[1165]],[[1165,1165],"valid"],[[1166,1166],"mapped",[1167]],[[1167,1167],"valid"],[[1168,1168],"mapped",[1169]],[[1169,1169],"valid"],[[1170,1170],"mapped",[1171]],[[1171,1171],"valid"],[[1172,1172],"mapped",[1173]],[[1173,1173],"valid"],[[1174,1174],"mapped",[1175]],[[1175,1175],"valid"],[[1176,1176],"mapped",[1177]],[[1177,1177],"valid"],[[1178,1178],"mapped",[1179]],[[1179,1179],"valid"],[[1180,1180],"mapped",[1181]],[[1181,1181],"valid"],[[1182,1182],"mapped",[1183]],[[1183,1183],"valid"],[[1184,1184],"mapped",[1185]],[[1185,1185],"valid"],[[1186,1186],"mapped",[1187]],[[1187,1187],"valid"],[[1188,1188],"mapped",[1189]],[[1189,1189],"valid"],[[1190,1190],"mapped",[1191]],[[1191,1191],"valid"],[[1192,1192],"mapped",[1193]],[[1193,1193],"valid"],[[1194,1194],"mapped",[1195]],[[1195,1195],"valid"],[[1196,1196],"mapped",[1197]],[[1197,1197],"valid"],[[1198,1198],"mapped",[1199]],[[1199,1199],"valid"],[[1200,1200],"mapped",[1201]],[[1201,1201],"valid"],[[1202,1202],"mapped",[1203]],[[1203,1203],"valid"],[[1204,1204],"mapped",[1205]],[[1205,1205],"valid"],[[1206,1206],"mapped",[1207]],[[1207,1207],"valid"],[[1208,1208],"mapped",[1209]],[[1209,1209],"valid"],[[1210,1210],"mapped",[1211]],[[1211,1211],"valid"],[[1212,1212],"mapped",[1213]],[[1213,1213],"valid"],[[1214,1214],"mapped",[1215]],[[1215,1215],"valid"],[[1216,1216],"disallowed"],[[1217,1217],"mapped",[1218]],[[1218,1218],"valid"],[[1219,1219],"mapped",[1220]],[[1220,1220],"valid"],[[1221,1221],"mapped",[1222]],[[1222,1222],"valid"],[[1223,1223],"mapped",[1224]],[[1224,1224],"valid"],[[1225,1225],"mapped",[1226]],[[1226,1226],"valid"],[[1227,1227],"mapped",[1228]],[[1228,1228],"valid"],[[1229,1229],"mapped",[1230]],[[1230,1230],"valid"],[[1231,1231],"valid"],[[1232,1232],"mapped",[1233]],[[1233,1233],"valid"],[[1234,1234],"mapped",[1235]],[[1235,1235],"valid"],[[1236,1236],"mapped",[1237]],[[1237,1237],"valid"],[[1238,1238],"mapped",[1239]],[[1239,1239],"valid"],[[1240,1240],"mapped",[1241]],[[1241,1241],"valid"],[[1242,1242],"mapped",[1243]],[[1243,1243],"valid"],[[1244,1244],"mapped",[1245]],[[1245,1245],"valid"],[[1246,1246],"mapped",[1247]],[[1247,1247],"valid"],[[1248,1248],"mapped",[1249]],[[1249,1249],"valid"],[[1250,1250],"mapped",[1251]],[[1251,1251],"valid"],[[1252,1252],"mapped",[1253]],[[1253,1253],"valid"],[[1254,1254],"mapped",[1255]],[[1255,1255],"valid"],[[1256,1256],"mapped",[1257]],[[1257,1257],"valid"],[[1258,1258],"mapped",[1259]],[[1259,1259],"valid"],[[1260,1260],"mapped",[1261]],[[1261,1261],"valid"],[[1262,1262],"mapped",[1263]],[[1263,1263],"valid"],[[1264,1264],"mapped",[1265]],[[1265,1265],"valid"],[[1266,1266],"mapped",[1267]],[[1267,1267],"valid"],[[1268,1268],"mapped",[1269]],[[1269,1269],"valid"],[[1270,1270],"mapped",[1271]],[[1271,1271],"valid"],[[1272,1272],"mapped",[1273]],[[1273,1273],"valid"],[[1274,1274],"mapped",[1275]],[[1275,1275],"valid"],[[1276,1276],"mapped",[1277]],[[1277,1277],"valid"],[[1278,1278],"mapped",[1279]],[[1279,1279],"valid"],[[1280,1280],"mapped",[1281]],[[1281,1281],"valid"],[[1282,1282],"mapped",[1283]],[[1283,1283],"valid"],[[1284,1284],"mapped",[1285]],[[1285,1285],"valid"],[[1286,1286],"mapped",[1287]],[[1287,1287],"valid"],[[1288,1288],"mapped",[1289]],[[1289,1289],"valid"],[[1290,1290],"mapped",[1291]],[[1291,1291],"valid"],[[1292,1292],"mapped",[1293]],[[1293,1293],"valid"],[[1294,1294],"mapped",[1295]],[[1295,1295],"valid"],[[1296,1296],"mapped",[1297]],[[1297,1297],"valid"],[[1298,1298],"mapped",[1299]],[[1299,1299],"valid"],[[1300,1300],"mapped",[1301]],[[1301,1301],"valid"],[[1302,1302],"mapped",[1303]],[[1303,1303],"valid"],[[1304,1304],"mapped",[1305]],[[1305,1305],"valid"],[[1306,1306],"mapped",[1307]],[[1307,1307],"valid"],[[1308,1308],"mapped",[1309]],[[1309,1309],"valid"],[[1310,1310],"mapped",[1311]],[[1311,1311],"valid"],[[1312,1312],"mapped",[1313]],[[1313,1313],"valid"],[[1314,1314],"mapped",[1315]],[[1315,1315],"valid"],[[1316,1316],"mapped",[1317]],[[1317,1317],"valid"],[[1318,1318],"mapped",[1319]],[[1319,1319],"valid"],[[1320,1320],"mapped",[1321]],[[1321,1321],"valid"],[[1322,1322],"mapped",[1323]],[[1323,1323],"valid"],[[1324,1324],"mapped",[1325]],[[1325,1325],"valid"],[[1326,1326],"mapped",[1327]],[[1327,1327],"valid"],[[1328,1328],"disallowed"],[[1329,1329],"mapped",[1377]],[[1330,1330],"mapped",[1378]],[[1331,1331],"mapped",[1379]],[[1332,1332],"mapped",[1380]],[[1333,1333],"mapped",[1381]],[[1334,1334],"mapped",[1382]],[[1335,1335],"mapped",[1383]],[[1336,1336],"mapped",[1384]],[[1337,1337],"mapped",[1385]],[[1338,1338],"mapped",[1386]],[[1339,1339],"mapped",[1387]],[[1340,1340],"mapped",[1388]],[[1341,1341],"mapped",[1389]],[[1342,1342],"mapped",[1390]],[[1343,1343],"mapped",[1391]],[[1344,1344],"mapped",[1392]],[[1345,1345],"mapped",[1393]],[[1346,1346],"mapped",[1394]],[[1347,1347],"mapped",[1395]],[[1348,1348],"mapped",[1396]],[[1349,1349],"mapped",[1397]],[[1350,1350],"mapped",[1398]],[[1351,1351],"mapped",[1399]],[[1352,1352],"mapped",[1400]],[[1353,1353],"mapped",[1401]],[[1354,1354],"mapped",[1402]],[[1355,1355],"mapped",[1403]],[[1356,1356],"mapped",[1404]],[[1357,1357],"mapped",[1405]],[[1358,1358],"mapped",[1406]],[[1359,1359],"mapped",[1407]],[[1360,1360],"mapped",[1408]],[[1361,1361],"mapped",[1409]],[[1362,1362],"mapped",[1410]],[[1363,1363],"mapped",[1411]],[[1364,1364],"mapped",[1412]],[[1365,1365],"mapped",[1413]],[[1366,1366],"mapped",[1414]],[[1367,1368],"disallowed"],[[1369,1369],"valid"],[[1370,1375],"valid",[],"NV8"],[[1376,1376],"disallowed"],[[1377,1414],"valid"],[[1415,1415],"mapped",[1381,1410]],[[1416,1416],"disallowed"],[[1417,1417],"valid",[],"NV8"],[[1418,1418],"valid",[],"NV8"],[[1419,1420],"disallowed"],[[1421,1422],"valid",[],"NV8"],[[1423,1423],"valid",[],"NV8"],[[1424,1424],"disallowed"],[[1425,1441],"valid"],[[1442,1442],"valid"],[[1443,1455],"valid"],[[1456,1465],"valid"],[[1466,1466],"valid"],[[1467,1469],"valid"],[[1470,1470],"valid",[],"NV8"],[[1471,1471],"valid"],[[1472,1472],"valid",[],"NV8"],[[1473,1474],"valid"],[[1475,1475],"valid",[],"NV8"],[[1476,1476],"valid"],[[1477,1477],"valid"],[[1478,1478],"valid",[],"NV8"],[[1479,1479],"valid"],[[1480,1487],"disallowed"],[[1488,1514],"valid"],[[1515,1519],"disallowed"],[[1520,1524],"valid"],[[1525,1535],"disallowed"],[[1536,1539],"disallowed"],[[1540,1540],"disallowed"],[[1541,1541],"disallowed"],[[1542,1546],"valid",[],"NV8"],[[1547,1547],"valid",[],"NV8"],[[1548,1548],"valid",[],"NV8"],[[1549,1551],"valid",[],"NV8"],[[1552,1557],"valid"],[[1558,1562],"valid"],[[1563,1563],"valid",[],"NV8"],[[1564,1564],"disallowed"],[[1565,1565],"disallowed"],[[1566,1566],"valid",[],"NV8"],[[1567,1567],"valid",[],"NV8"],[[1568,1568],"valid"],[[1569,1594],"valid"],[[1595,1599],"valid"],[[1600,1600],"valid",[],"NV8"],[[1601,1618],"valid"],[[1619,1621],"valid"],[[1622,1624],"valid"],[[1625,1630],"valid"],[[1631,1631],"valid"],[[1632,1641],"valid"],[[1642,1645],"valid",[],"NV8"],[[1646,1647],"valid"],[[1648,1652],"valid"],[[1653,1653],"mapped",[1575,1652]],[[1654,1654],"mapped",[1608,1652]],[[1655,1655],"mapped",[1735,1652]],[[1656,1656],"mapped",[1610,1652]],[[1657,1719],"valid"],[[1720,1721],"valid"],[[1722,1726],"valid"],[[1727,1727],"valid"],[[1728,1742],"valid"],[[1743,1743],"valid"],[[1744,1747],"valid"],[[1748,1748],"valid",[],"NV8"],[[1749,1756],"valid"],[[1757,1757],"disallowed"],[[1758,1758],"valid",[],"NV8"],[[1759,1768],"valid"],[[1769,1769],"valid",[],"NV8"],[[1770,1773],"valid"],[[1774,1775],"valid"],[[1776,1785],"valid"],[[1786,1790],"valid"],[[1791,1791],"valid"],[[1792,1805],"valid",[],"NV8"],[[1806,1806],"disallowed"],[[1807,1807],"disallowed"],[[1808,1836],"valid"],[[1837,1839],"valid"],[[1840,1866],"valid"],[[1867,1868],"disallowed"],[[1869,1871],"valid"],[[1872,1901],"valid"],[[1902,1919],"valid"],[[1920,1968],"valid"],[[1969,1969],"valid"],[[1970,1983],"disallowed"],[[1984,2037],"valid"],[[2038,2042],"valid",[],"NV8"],[[2043,2047],"disallowed"],[[2048,2093],"valid"],[[2094,2095],"disallowed"],[[2096,2110],"valid",[],"NV8"],[[2111,2111],"disallowed"],[[2112,2139],"valid"],[[2140,2141],"disallowed"],[[2142,2142],"valid",[],"NV8"],[[2143,2207],"disallowed"],[[2208,2208],"valid"],[[2209,2209],"valid"],[[2210,2220],"valid"],[[2221,2226],"valid"],[[2227,2228],"valid"],[[2229,2274],"disallowed"],[[2275,2275],"valid"],[[2276,2302],"valid"],[[2303,2303],"valid"],[[2304,2304],"valid"],[[2305,2307],"valid"],[[2308,2308],"valid"],[[2309,2361],"valid"],[[2362,2363],"valid"],[[2364,2381],"valid"],[[2382,2382],"valid"],[[2383,2383],"valid"],[[2384,2388],"valid"],[[2389,2389],"valid"],[[2390,2391],"valid"],[[2392,2392],"mapped",[2325,2364]],[[2393,2393],"mapped",[2326,2364]],[[2394,2394],"mapped",[2327,2364]],[[2395,2395],"mapped",[2332,2364]],[[2396,2396],"mapped",[2337,2364]],[[2397,2397],"mapped",[2338,2364]],[[2398,2398],"mapped",[2347,2364]],[[2399,2399],"mapped",[2351,2364]],[[2400,2403],"valid"],[[2404,2405],"valid",[],"NV8"],[[2406,2415],"valid"],[[2416,2416],"valid",[],"NV8"],[[2417,2418],"valid"],[[2419,2423],"valid"],[[2424,2424],"valid"],[[2425,2426],"valid"],[[2427,2428],"valid"],[[2429,2429],"valid"],[[2430,2431],"valid"],[[2432,2432],"valid"],[[2433,2435],"valid"],[[2436,2436],"disallowed"],[[2437,2444],"valid"],[[2445,2446],"disallowed"],[[2447,2448],"valid"],[[2449,2450],"disallowed"],[[2451,2472],"valid"],[[2473,2473],"disallowed"],[[2474,2480],"valid"],[[2481,2481],"disallowed"],[[2482,2482],"valid"],[[2483,2485],"disallowed"],[[2486,2489],"valid"],[[2490,2491],"disallowed"],[[2492,2492],"valid"],[[2493,2493],"valid"],[[2494,2500],"valid"],[[2501,2502],"disallowed"],[[2503,2504],"valid"],[[2505,2506],"disallowed"],[[2507,2509],"valid"],[[2510,2510],"valid"],[[2511,2518],"disallowed"],[[2519,2519],"valid"],[[2520,2523],"disallowed"],[[2524,2524],"mapped",[2465,2492]],[[2525,2525],"mapped",[2466,2492]],[[2526,2526],"disallowed"],[[2527,2527],"mapped",[2479,2492]],[[2528,2531],"valid"],[[2532,2533],"disallowed"],[[2534,2545],"valid"],[[2546,2554],"valid",[],"NV8"],[[2555,2555],"valid",[],"NV8"],[[2556,2560],"disallowed"],[[2561,2561],"valid"],[[2562,2562],"valid"],[[2563,2563],"valid"],[[2564,2564],"disallowed"],[[2565,2570],"valid"],[[2571,2574],"disallowed"],[[2575,2576],"valid"],[[2577,2578],"disallowed"],[[2579,2600],"valid"],[[2601,2601],"disallowed"],[[2602,2608],"valid"],[[2609,2609],"disallowed"],[[2610,2610],"valid"],[[2611,2611],"mapped",[2610,2620]],[[2612,2612],"disallowed"],[[2613,2613],"valid"],[[2614,2614],"mapped",[2616,2620]],[[2615,2615],"disallowed"],[[2616,2617],"valid"],[[2618,2619],"disallowed"],[[2620,2620],"valid"],[[2621,2621],"disallowed"],[[2622,2626],"valid"],[[2627,2630],"disallowed"],[[2631,2632],"valid"],[[2633,2634],"disallowed"],[[2635,2637],"valid"],[[2638,2640],"disallowed"],[[2641,2641],"valid"],[[2642,2648],"disallowed"],[[2649,2649],"mapped",[2582,2620]],[[2650,2650],"mapped",[2583,2620]],[[2651,2651],"mapped",[2588,2620]],[[2652,2652],"valid"],[[2653,2653],"disallowed"],[[2654,2654],"mapped",[2603,2620]],[[2655,2661],"disallowed"],[[2662,2676],"valid"],[[2677,2677],"valid"],[[2678,2688],"disallowed"],[[2689,2691],"valid"],[[2692,2692],"disallowed"],[[2693,2699],"valid"],[[2700,2700],"valid"],[[2701,2701],"valid"],[[2702,2702],"disallowed"],[[2703,2705],"valid"],[[2706,2706],"disallowed"],[[2707,2728],"valid"],[[2729,2729],"disallowed"],[[2730,2736],"valid"],[[2737,2737],"disallowed"],[[2738,2739],"valid"],[[2740,2740],"disallowed"],[[2741,2745],"valid"],[[2746,2747],"disallowed"],[[2748,2757],"valid"],[[2758,2758],"disallowed"],[[2759,2761],"valid"],[[2762,2762],"disallowed"],[[2763,2765],"valid"],[[2766,2767],"disallowed"],[[2768,2768],"valid"],[[2769,2783],"disallowed"],[[2784,2784],"valid"],[[2785,2787],"valid"],[[2788,2789],"disallowed"],[[2790,2799],"valid"],[[2800,2800],"valid",[],"NV8"],[[2801,2801],"valid",[],"NV8"],[[2802,2808],"disallowed"],[[2809,2809],"valid"],[[2810,2816],"disallowed"],[[2817,2819],"valid"],[[2820,2820],"disallowed"],[[2821,2828],"valid"],[[2829,2830],"disallowed"],[[2831,2832],"valid"],[[2833,2834],"disallowed"],[[2835,2856],"valid"],[[2857,2857],"disallowed"],[[2858,2864],"valid"],[[2865,2865],"disallowed"],[[2866,2867],"valid"],[[2868,2868],"disallowed"],[[2869,2869],"valid"],[[2870,2873],"valid"],[[2874,2875],"disallowed"],[[2876,2883],"valid"],[[2884,2884],"valid"],[[2885,2886],"disallowed"],[[2887,2888],"valid"],[[2889,2890],"disallowed"],[[2891,2893],"valid"],[[2894,2901],"disallowed"],[[2902,2903],"valid"],[[2904,2907],"disallowed"],[[2908,2908],"mapped",[2849,2876]],[[2909,2909],"mapped",[2850,2876]],[[2910,2910],"disallowed"],[[2911,2913],"valid"],[[2914,2915],"valid"],[[2916,2917],"disallowed"],[[2918,2927],"valid"],[[2928,2928],"valid",[],"NV8"],[[2929,2929],"valid"],[[2930,2935],"valid",[],"NV8"],[[2936,2945],"disallowed"],[[2946,2947],"valid"],[[2948,2948],"disallowed"],[[2949,2954],"valid"],[[2955,2957],"disallowed"],[[2958,2960],"valid"],[[2961,2961],"disallowed"],[[2962,2965],"valid"],[[2966,2968],"disallowed"],[[2969,2970],"valid"],[[2971,2971],"disallowed"],[[2972,2972],"valid"],[[2973,2973],"disallowed"],[[2974,2975],"valid"],[[2976,2978],"disallowed"],[[2979,2980],"valid"],[[2981,2983],"disallowed"],[[2984,2986],"valid"],[[2987,2989],"disallowed"],[[2990,2997],"valid"],[[2998,2998],"valid"],[[2999,3001],"valid"],[[3002,3005],"disallowed"],[[3006,3010],"valid"],[[3011,3013],"disallowed"],[[3014,3016],"valid"],[[3017,3017],"disallowed"],[[3018,3021],"valid"],[[3022,3023],"disallowed"],[[3024,3024],"valid"],[[3025,3030],"disallowed"],[[3031,3031],"valid"],[[3032,3045],"disallowed"],[[3046,3046],"valid"],[[3047,3055],"valid"],[[3056,3058],"valid",[],"NV8"],[[3059,3066],"valid",[],"NV8"],[[3067,3071],"disallowed"],[[3072,3072],"valid"],[[3073,3075],"valid"],[[3076,3076],"disallowed"],[[3077,3084],"valid"],[[3085,3085],"disallowed"],[[3086,3088],"valid"],[[3089,3089],"disallowed"],[[3090,3112],"valid"],[[3113,3113],"disallowed"],[[3114,3123],"valid"],[[3124,3124],"valid"],[[3125,3129],"valid"],[[3130,3132],"disallowed"],[[3133,3133],"valid"],[[3134,3140],"valid"],[[3141,3141],"disallowed"],[[3142,3144],"valid"],[[3145,3145],"disallowed"],[[3146,3149],"valid"],[[3150,3156],"disallowed"],[[3157,3158],"valid"],[[3159,3159],"disallowed"],[[3160,3161],"valid"],[[3162,3162],"valid"],[[3163,3167],"disallowed"],[[3168,3169],"valid"],[[3170,3171],"valid"],[[3172,3173],"disallowed"],[[3174,3183],"valid"],[[3184,3191],"disallowed"],[[3192,3199],"valid",[],"NV8"],[[3200,3200],"disallowed"],[[3201,3201],"valid"],[[3202,3203],"valid"],[[3204,3204],"disallowed"],[[3205,3212],"valid"],[[3213,3213],"disallowed"],[[3214,3216],"valid"],[[3217,3217],"disallowed"],[[3218,3240],"valid"],[[3241,3241],"disallowed"],[[3242,3251],"valid"],[[3252,3252],"disallowed"],[[3253,3257],"valid"],[[3258,3259],"disallowed"],[[3260,3261],"valid"],[[3262,3268],"valid"],[[3269,3269],"disallowed"],[[3270,3272],"valid"],[[3273,3273],"disallowed"],[[3274,3277],"valid"],[[3278,3284],"disallowed"],[[3285,3286],"valid"],[[3287,3293],"disallowed"],[[3294,3294],"valid"],[[3295,3295],"disallowed"],[[3296,3297],"valid"],[[3298,3299],"valid"],[[3300,3301],"disallowed"],[[3302,3311],"valid"],[[3312,3312],"disallowed"],[[3313,3314],"valid"],[[3315,3328],"disallowed"],[[3329,3329],"valid"],[[3330,3331],"valid"],[[3332,3332],"disallowed"],[[3333,3340],"valid"],[[3341,3341],"disallowed"],[[3342,3344],"valid"],[[3345,3345],"disallowed"],[[3346,3368],"valid"],[[3369,3369],"valid"],[[3370,3385],"valid"],[[3386,3386],"valid"],[[3387,3388],"disallowed"],[[3389,3389],"valid"],[[3390,3395],"valid"],[[3396,3396],"valid"],[[3397,3397],"disallowed"],[[3398,3400],"valid"],[[3401,3401],"disallowed"],[[3402,3405],"valid"],[[3406,3406],"valid"],[[3407,3414],"disallowed"],[[3415,3415],"valid"],[[3416,3422],"disallowed"],[[3423,3423],"valid"],[[3424,3425],"valid"],[[3426,3427],"valid"],[[3428,3429],"disallowed"],[[3430,3439],"valid"],[[3440,3445],"valid",[],"NV8"],[[3446,3448],"disallowed"],[[3449,3449],"valid",[],"NV8"],[[3450,3455],"valid"],[[3456,3457],"disallowed"],[[3458,3459],"valid"],[[3460,3460],"disallowed"],[[3461,3478],"valid"],[[3479,3481],"disallowed"],[[3482,3505],"valid"],[[3506,3506],"disallowed"],[[3507,3515],"valid"],[[3516,3516],"disallowed"],[[3517,3517],"valid"],[[3518,3519],"disallowed"],[[3520,3526],"valid"],[[3527,3529],"disallowed"],[[3530,3530],"valid"],[[3531,3534],"disallowed"],[[3535,3540],"valid"],[[3541,3541],"disallowed"],[[3542,3542],"valid"],[[3543,3543],"disallowed"],[[3544,3551],"valid"],[[3552,3557],"disallowed"],[[3558,3567],"valid"],[[3568,3569],"disallowed"],[[3570,3571],"valid"],[[3572,3572],"valid",[],"NV8"],[[3573,3584],"disallowed"],[[3585,3634],"valid"],[[3635,3635],"mapped",[3661,3634]],[[3636,3642],"valid"],[[3643,3646],"disallowed"],[[3647,3647],"valid",[],"NV8"],[[3648,3662],"valid"],[[3663,3663],"valid",[],"NV8"],[[3664,3673],"valid"],[[3674,3675],"valid",[],"NV8"],[[3676,3712],"disallowed"],[[3713,3714],"valid"],[[3715,3715],"disallowed"],[[3716,3716],"valid"],[[3717,3718],"disallowed"],[[3719,3720],"valid"],[[3721,3721],"disallowed"],[[3722,3722],"valid"],[[3723,3724],"disallowed"],[[3725,3725],"valid"],[[3726,3731],"disallowed"],[[3732,3735],"valid"],[[3736,3736],"disallowed"],[[3737,3743],"valid"],[[3744,3744],"disallowed"],[[3745,3747],"valid"],[[3748,3748],"disallowed"],[[3749,3749],"valid"],[[3750,3750],"disallowed"],[[3751,3751],"valid"],[[3752,3753],"disallowed"],[[3754,3755],"valid"],[[3756,3756],"disallowed"],[[3757,3762],"valid"],[[3763,3763],"mapped",[3789,3762]],[[3764,3769],"valid"],[[3770,3770],"disallowed"],[[3771,3773],"valid"],[[3774,3775],"disallowed"],[[3776,3780],"valid"],[[3781,3781],"disallowed"],[[3782,3782],"valid"],[[3783,3783],"disallowed"],[[3784,3789],"valid"],[[3790,3791],"disallowed"],[[3792,3801],"valid"],[[3802,3803],"disallowed"],[[3804,3804],"mapped",[3755,3737]],[[3805,3805],"mapped",[3755,3745]],[[3806,3807],"valid"],[[3808,3839],"disallowed"],[[3840,3840],"valid"],[[3841,3850],"valid",[],"NV8"],[[3851,3851],"valid"],[[3852,3852],"mapped",[3851]],[[3853,3863],"valid",[],"NV8"],[[3864,3865],"valid"],[[3866,3871],"valid",[],"NV8"],[[3872,3881],"valid"],[[3882,3892],"valid",[],"NV8"],[[3893,3893],"valid"],[[3894,3894],"valid",[],"NV8"],[[3895,3895],"valid"],[[3896,3896],"valid",[],"NV8"],[[3897,3897],"valid"],[[3898,3901],"valid",[],"NV8"],[[3902,3906],"valid"],[[3907,3907],"mapped",[3906,4023]],[[3908,3911],"valid"],[[3912,3912],"disallowed"],[[3913,3916],"valid"],[[3917,3917],"mapped",[3916,4023]],[[3918,3921],"valid"],[[3922,3922],"mapped",[3921,4023]],[[3923,3926],"valid"],[[3927,3927],"mapped",[3926,4023]],[[3928,3931],"valid"],[[3932,3932],"mapped",[3931,4023]],[[3933,3944],"valid"],[[3945,3945],"mapped",[3904,4021]],[[3946,3946],"valid"],[[3947,3948],"valid"],[[3949,3952],"disallowed"],[[3953,3954],"valid"],[[3955,3955],"mapped",[3953,3954]],[[3956,3956],"valid"],[[3957,3957],"mapped",[3953,3956]],[[3958,3958],"mapped",[4018,3968]],[[3959,3959],"mapped",[4018,3953,3968]],[[3960,3960],"mapped",[4019,3968]],[[3961,3961],"mapped",[4019,3953,3968]],[[3962,3968],"valid"],[[3969,3969],"mapped",[3953,3968]],[[3970,3972],"valid"],[[3973,3973],"valid",[],"NV8"],[[3974,3979],"valid"],[[3980,3983],"valid"],[[3984,3986],"valid"],[[3987,3987],"mapped",[3986,4023]],[[3988,3989],"valid"],[[3990,3990],"valid"],[[3991,3991],"valid"],[[3992,3992],"disallowed"],[[3993,3996],"valid"],[[3997,3997],"mapped",[3996,4023]],[[3998,4001],"valid"],[[4002,4002],"mapped",[4001,4023]],[[4003,4006],"valid"],[[4007,4007],"mapped",[4006,4023]],[[4008,4011],"valid"],[[4012,4012],"mapped",[4011,4023]],[[4013,4013],"valid"],[[4014,4016],"valid"],[[4017,4023],"valid"],[[4024,4024],"valid"],[[4025,4025],"mapped",[3984,4021]],[[4026,4028],"valid"],[[4029,4029],"disallowed"],[[4030,4037],"valid",[],"NV8"],[[4038,4038],"valid"],[[4039,4044],"valid",[],"NV8"],[[4045,4045],"disallowed"],[[4046,4046],"valid",[],"NV8"],[[4047,4047],"valid",[],"NV8"],[[4048,4049],"valid",[],"NV8"],[[4050,4052],"valid",[],"NV8"],[[4053,4056],"valid",[],"NV8"],[[4057,4058],"valid",[],"NV8"],[[4059,4095],"disallowed"],[[4096,4129],"valid"],[[4130,4130],"valid"],[[4131,4135],"valid"],[[4136,4136],"valid"],[[4137,4138],"valid"],[[4139,4139],"valid"],[[4140,4146],"valid"],[[4147,4149],"valid"],[[4150,4153],"valid"],[[4154,4159],"valid"],[[4160,4169],"valid"],[[4170,4175],"valid",[],"NV8"],[[4176,4185],"valid"],[[4186,4249],"valid"],[[4250,4253],"valid"],[[4254,4255],"valid",[],"NV8"],[[4256,4293],"disallowed"],[[4294,4294],"disallowed"],[[4295,4295],"mapped",[11559]],[[4296,4300],"disallowed"],[[4301,4301],"mapped",[11565]],[[4302,4303],"disallowed"],[[4304,4342],"valid"],[[4343,4344],"valid"],[[4345,4346],"valid"],[[4347,4347],"valid",[],"NV8"],[[4348,4348],"mapped",[4316]],[[4349,4351],"valid"],[[4352,4441],"valid",[],"NV8"],[[4442,4446],"valid",[],"NV8"],[[4447,4448],"disallowed"],[[4449,4514],"valid",[],"NV8"],[[4515,4519],"valid",[],"NV8"],[[4520,4601],"valid",[],"NV8"],[[4602,4607],"valid",[],"NV8"],[[4608,4614],"valid"],[[4615,4615],"valid"],[[4616,4678],"valid"],[[4679,4679],"valid"],[[4680,4680],"valid"],[[4681,4681],"disallowed"],[[4682,4685],"valid"],[[4686,4687],"disallowed"],[[4688,4694],"valid"],[[4695,4695],"disallowed"],[[4696,4696],"valid"],[[4697,4697],"disallowed"],[[4698,4701],"valid"],[[4702,4703],"disallowed"],[[4704,4742],"valid"],[[4743,4743],"valid"],[[4744,4744],"valid"],[[4745,4745],"disallowed"],[[4746,4749],"valid"],[[4750,4751],"disallowed"],[[4752,4782],"valid"],[[4783,4783],"valid"],[[4784,4784],"valid"],[[4785,4785],"disallowed"],[[4786,4789],"valid"],[[4790,4791],"disallowed"],[[4792,4798],"valid"],[[4799,4799],"disallowed"],[[4800,4800],"valid"],[[4801,4801],"disallowed"],[[4802,4805],"valid"],[[4806,4807],"disallowed"],[[4808,4814],"valid"],[[4815,4815],"valid"],[[4816,4822],"valid"],[[4823,4823],"disallowed"],[[4824,4846],"valid"],[[4847,4847],"valid"],[[4848,4878],"valid"],[[4879,4879],"valid"],[[4880,4880],"valid"],[[4881,4881],"disallowed"],[[4882,4885],"valid"],[[4886,4887],"disallowed"],[[4888,4894],"valid"],[[4895,4895],"valid"],[[4896,4934],"valid"],[[4935,4935],"valid"],[[4936,4954],"valid"],[[4955,4956],"disallowed"],[[4957,4958],"valid"],[[4959,4959],"valid"],[[4960,4960],"valid",[],"NV8"],[[4961,4988],"valid",[],"NV8"],[[4989,4991],"disallowed"],[[4992,5007],"valid"],[[5008,5017],"valid",[],"NV8"],[[5018,5023],"disallowed"],[[5024,5108],"valid"],[[5109,5109],"valid"],[[5110,5111],"disallowed"],[[5112,5112],"mapped",[5104]],[[5113,5113],"mapped",[5105]],[[5114,5114],"mapped",[5106]],[[5115,5115],"mapped",[5107]],[[5116,5116],"mapped",[5108]],[[5117,5117],"mapped",[5109]],[[5118,5119],"disallowed"],[[5120,5120],"valid",[],"NV8"],[[5121,5740],"valid"],[[5741,5742],"valid",[],"NV8"],[[5743,5750],"valid"],[[5751,5759],"valid"],[[5760,5760],"disallowed"],[[5761,5786],"valid"],[[5787,5788],"valid",[],"NV8"],[[5789,5791],"disallowed"],[[5792,5866],"valid"],[[5867,5872],"valid",[],"NV8"],[[5873,5880],"valid"],[[5881,5887],"disallowed"],[[5888,5900],"valid"],[[5901,5901],"disallowed"],[[5902,5908],"valid"],[[5909,5919],"disallowed"],[[5920,5940],"valid"],[[5941,5942],"valid",[],"NV8"],[[5943,5951],"disallowed"],[[5952,5971],"valid"],[[5972,5983],"disallowed"],[[5984,5996],"valid"],[[5997,5997],"disallowed"],[[5998,6000],"valid"],[[6001,6001],"disallowed"],[[6002,6003],"valid"],[[6004,6015],"disallowed"],[[6016,6067],"valid"],[[6068,6069],"disallowed"],[[6070,6099],"valid"],[[6100,6102],"valid",[],"NV8"],[[6103,6103],"valid"],[[6104,6107],"valid",[],"NV8"],[[6108,6108],"valid"],[[6109,6109],"valid"],[[6110,6111],"disallowed"],[[6112,6121],"valid"],[[6122,6127],"disallowed"],[[6128,6137],"valid",[],"NV8"],[[6138,6143],"disallowed"],[[6144,6149],"valid",[],"NV8"],[[6150,6150],"disallowed"],[[6151,6154],"valid",[],"NV8"],[[6155,6157],"ignored"],[[6158,6158],"disallowed"],[[6159,6159],"disallowed"],[[6160,6169],"valid"],[[6170,6175],"disallowed"],[[6176,6263],"valid"],[[6264,6271],"disallowed"],[[6272,6313],"valid"],[[6314,6314],"valid"],[[6315,6319],"disallowed"],[[6320,6389],"valid"],[[6390,6399],"disallowed"],[[6400,6428],"valid"],[[6429,6430],"valid"],[[6431,6431],"disallowed"],[[6432,6443],"valid"],[[6444,6447],"disallowed"],[[6448,6459],"valid"],[[6460,6463],"disallowed"],[[6464,6464],"valid",[],"NV8"],[[6465,6467],"disallowed"],[[6468,6469],"valid",[],"NV8"],[[6470,6509],"valid"],[[6510,6511],"disallowed"],[[6512,6516],"valid"],[[6517,6527],"disallowed"],[[6528,6569],"valid"],[[6570,6571],"valid"],[[6572,6575],"disallowed"],[[6576,6601],"valid"],[[6602,6607],"disallowed"],[[6608,6617],"valid"],[[6618,6618],"valid",[],"XV8"],[[6619,6621],"disallowed"],[[6622,6623],"valid",[],"NV8"],[[6624,6655],"valid",[],"NV8"],[[6656,6683],"valid"],[[6684,6685],"disallowed"],[[6686,6687],"valid",[],"NV8"],[[6688,6750],"valid"],[[6751,6751],"disallowed"],[[6752,6780],"valid"],[[6781,6782],"disallowed"],[[6783,6793],"valid"],[[6794,6799],"disallowed"],[[6800,6809],"valid"],[[6810,6815],"disallowed"],[[6816,6822],"valid",[],"NV8"],[[6823,6823],"valid"],[[6824,6829],"valid",[],"NV8"],[[6830,6831],"disallowed"],[[6832,6845],"valid"],[[6846,6846],"valid",[],"NV8"],[[6847,6911],"disallowed"],[[6912,6987],"valid"],[[6988,6991],"disallowed"],[[6992,7001],"valid"],[[7002,7018],"valid",[],"NV8"],[[7019,7027],"valid"],[[7028,7036],"valid",[],"NV8"],[[7037,7039],"disallowed"],[[7040,7082],"valid"],[[7083,7085],"valid"],[[7086,7097],"valid"],[[7098,7103],"valid"],[[7104,7155],"valid"],[[7156,7163],"disallowed"],[[7164,7167],"valid",[],"NV8"],[[7168,7223],"valid"],[[7224,7226],"disallowed"],[[7227,7231],"valid",[],"NV8"],[[7232,7241],"valid"],[[7242,7244],"disallowed"],[[7245,7293],"valid"],[[7294,7295],"valid",[],"NV8"],[[7296,7359],"disallowed"],[[7360,7367],"valid",[],"NV8"],[[7368,7375],"disallowed"],[[7376,7378],"valid"],[[7379,7379],"valid",[],"NV8"],[[7380,7410],"valid"],[[7411,7414],"valid"],[[7415,7415],"disallowed"],[[7416,7417],"valid"],[[7418,7423],"disallowed"],[[7424,7467],"valid"],[[7468,7468],"mapped",[97]],[[7469,7469],"mapped",[230]],[[7470,7470],"mapped",[98]],[[7471,7471],"valid"],[[7472,7472],"mapped",[100]],[[7473,7473],"mapped",[101]],[[7474,7474],"mapped",[477]],[[7475,7475],"mapped",[103]],[[7476,7476],"mapped",[104]],[[7477,7477],"mapped",[105]],[[7478,7478],"mapped",[106]],[[7479,7479],"mapped",[107]],[[7480,7480],"mapped",[108]],[[7481,7481],"mapped",[109]],[[7482,7482],"mapped",[110]],[[7483,7483],"valid"],[[7484,7484],"mapped",[111]],[[7485,7485],"mapped",[547]],[[7486,7486],"mapped",[112]],[[7487,7487],"mapped",[114]],[[7488,7488],"mapped",[116]],[[7489,7489],"mapped",[117]],[[7490,7490],"mapped",[119]],[[7491,7491],"mapped",[97]],[[7492,7492],"mapped",[592]],[[7493,7493],"mapped",[593]],[[7494,7494],"mapped",[7426]],[[7495,7495],"mapped",[98]],[[7496,7496],"mapped",[100]],[[7497,7497],"mapped",[101]],[[7498,7498],"mapped",[601]],[[7499,7499],"mapped",[603]],[[7500,7500],"mapped",[604]],[[7501,7501],"mapped",[103]],[[7502,7502],"valid"],[[7503,7503],"mapped",[107]],[[7504,7504],"mapped",[109]],[[7505,7505],"mapped",[331]],[[7506,7506],"mapped",[111]],[[7507,7507],"mapped",[596]],[[7508,7508],"mapped",[7446]],[[7509,7509],"mapped",[7447]],[[7510,7510],"mapped",[112]],[[7511,7511],"mapped",[116]],[[7512,7512],"mapped",[117]],[[7513,7513],"mapped",[7453]],[[7514,7514],"mapped",[623]],[[7515,7515],"mapped",[118]],[[7516,7516],"mapped",[7461]],[[7517,7517],"mapped",[946]],[[7518,7518],"mapped",[947]],[[7519,7519],"mapped",[948]],[[7520,7520],"mapped",[966]],[[7521,7521],"mapped",[967]],[[7522,7522],"mapped",[105]],[[7523,7523],"mapped",[114]],[[7524,7524],"mapped",[117]],[[7525,7525],"mapped",[118]],[[7526,7526],"mapped",[946]],[[7527,7527],"mapped",[947]],[[7528,7528],"mapped",[961]],[[7529,7529],"mapped",[966]],[[7530,7530],"mapped",[967]],[[7531,7531],"valid"],[[7532,7543],"valid"],[[7544,7544],"mapped",[1085]],[[7545,7578],"valid"],[[7579,7579],"mapped",[594]],[[7580,7580],"mapped",[99]],[[7581,7581],"mapped",[597]],[[7582,7582],"mapped",[240]],[[7583,7583],"mapped",[604]],[[7584,7584],"mapped",[102]],[[7585,7585],"mapped",[607]],[[7586,7586],"mapped",[609]],[[7587,7587],"mapped",[613]],[[7588,7588],"mapped",[616]],[[7589,7589],"mapped",[617]],[[7590,7590],"mapped",[618]],[[7591,7591],"mapped",[7547]],[[7592,7592],"mapped",[669]],[[7593,7593],"mapped",[621]],[[7594,7594],"mapped",[7557]],[[7595,7595],"mapped",[671]],[[7596,7596],"mapped",[625]],[[7597,7597],"mapped",[624]],[[7598,7598],"mapped",[626]],[[7599,7599],"mapped",[627]],[[7600,7600],"mapped",[628]],[[7601,7601],"mapped",[629]],[[7602,7602],"mapped",[632]],[[7603,7603],"mapped",[642]],[[7604,7604],"mapped",[643]],[[7605,7605],"mapped",[427]],[[7606,7606],"mapped",[649]],[[7607,7607],"mapped",[650]],[[7608,7608],"mapped",[7452]],[[7609,7609],"mapped",[651]],[[7610,7610],"mapped",[652]],[[7611,7611],"mapped",[122]],[[7612,7612],"mapped",[656]],[[7613,7613],"mapped",[657]],[[7614,7614],"mapped",[658]],[[7615,7615],"mapped",[952]],[[7616,7619],"valid"],[[7620,7626],"valid"],[[7627,7654],"valid"],[[7655,7669],"valid"],[[7670,7675],"disallowed"],[[7676,7676],"valid"],[[7677,7677],"valid"],[[7678,7679],"valid"],[[7680,7680],"mapped",[7681]],[[7681,7681],"valid"],[[7682,7682],"mapped",[7683]],[[7683,7683],"valid"],[[7684,7684],"mapped",[7685]],[[7685,7685],"valid"],[[7686,7686],"mapped",[7687]],[[7687,7687],"valid"],[[7688,7688],"mapped",[7689]],[[7689,7689],"valid"],[[7690,7690],"mapped",[7691]],[[7691,7691],"valid"],[[7692,7692],"mapped",[7693]],[[7693,7693],"valid"],[[7694,7694],"mapped",[7695]],[[7695,7695],"valid"],[[7696,7696],"mapped",[7697]],[[7697,7697],"valid"],[[7698,7698],"mapped",[7699]],[[7699,7699],"valid"],[[7700,7700],"mapped",[7701]],[[7701,7701],"valid"],[[7702,7702],"mapped",[7703]],[[7703,7703],"valid"],[[7704,7704],"mapped",[7705]],[[7705,7705],"valid"],[[7706,7706],"mapped",[7707]],[[7707,7707],"valid"],[[7708,7708],"mapped",[7709]],[[7709,7709],"valid"],[[7710,7710],"mapped",[7711]],[[7711,7711],"valid"],[[7712,7712],"mapped",[7713]],[[7713,7713],"valid"],[[7714,7714],"mapped",[7715]],[[7715,7715],"valid"],[[7716,7716],"mapped",[7717]],[[7717,7717],"valid"],[[7718,7718],"mapped",[7719]],[[7719,7719],"valid"],[[7720,7720],"mapped",[7721]],[[7721,7721],"valid"],[[7722,7722],"mapped",[7723]],[[7723,7723],"valid"],[[7724,7724],"mapped",[7725]],[[7725,7725],"valid"],[[7726,7726],"mapped",[7727]],[[7727,7727],"valid"],[[7728,7728],"mapped",[7729]],[[7729,7729],"valid"],[[7730,7730],"mapped",[7731]],[[7731,7731],"valid"],[[7732,7732],"mapped",[7733]],[[7733,7733],"valid"],[[7734,7734],"mapped",[7735]],[[7735,7735],"valid"],[[7736,7736],"mapped",[7737]],[[7737,7737],"valid"],[[7738,7738],"mapped",[7739]],[[7739,7739],"valid"],[[7740,7740],"mapped",[7741]],[[7741,7741],"valid"],[[7742,7742],"mapped",[7743]],[[7743,7743],"valid"],[[7744,7744],"mapped",[7745]],[[7745,7745],"valid"],[[7746,7746],"mapped",[7747]],[[7747,7747],"valid"],[[7748,7748],"mapped",[7749]],[[7749,7749],"valid"],[[7750,7750],"mapped",[7751]],[[7751,7751],"valid"],[[7752,7752],"mapped",[7753]],[[7753,7753],"valid"],[[7754,7754],"mapped",[7755]],[[7755,7755],"valid"],[[7756,7756],"mapped",[7757]],[[7757,7757],"valid"],[[7758,7758],"mapped",[7759]],[[7759,7759],"valid"],[[7760,7760],"mapped",[7761]],[[7761,7761],"valid"],[[7762,7762],"mapped",[7763]],[[7763,7763],"valid"],[[7764,7764],"mapped",[7765]],[[7765,7765],"valid"],[[7766,7766],"mapped",[7767]],[[7767,7767],"valid"],[[7768,7768],"mapped",[7769]],[[7769,7769],"valid"],[[7770,7770],"mapped",[7771]],[[7771,7771],"valid"],[[7772,7772],"mapped",[7773]],[[7773,7773],"valid"],[[7774,7774],"mapped",[7775]],[[7775,7775],"valid"],[[7776,7776],"mapped",[7777]],[[7777,7777],"valid"],[[7778,7778],"mapped",[7779]],[[7779,7779],"valid"],[[7780,7780],"mapped",[7781]],[[7781,7781],"valid"],[[7782,7782],"mapped",[7783]],[[7783,7783],"valid"],[[7784,7784],"mapped",[7785]],[[7785,7785],"valid"],[[7786,7786],"mapped",[7787]],[[7787,7787],"valid"],[[7788,7788],"mapped",[7789]],[[7789,7789],"valid"],[[7790,7790],"mapped",[7791]],[[7791,7791],"valid"],[[7792,7792],"mapped",[7793]],[[7793,7793],"valid"],[[7794,7794],"mapped",[7795]],[[7795,7795],"valid"],[[7796,7796],"mapped",[7797]],[[7797,7797],"valid"],[[7798,7798],"mapped",[7799]],[[7799,7799],"valid"],[[7800,7800],"mapped",[7801]],[[7801,7801],"valid"],[[7802,7802],"mapped",[7803]],[[7803,7803],"valid"],[[7804,7804],"mapped",[7805]],[[7805,7805],"valid"],[[7806,7806],"mapped",[7807]],[[7807,7807],"valid"],[[7808,7808],"mapped",[7809]],[[7809,7809],"valid"],[[7810,7810],"mapped",[7811]],[[7811,7811],"valid"],[[7812,7812],"mapped",[7813]],[[7813,7813],"valid"],[[7814,7814],"mapped",[7815]],[[7815,7815],"valid"],[[7816,7816],"mapped",[7817]],[[7817,7817],"valid"],[[7818,7818],"mapped",[7819]],[[7819,7819],"valid"],[[7820,7820],"mapped",[7821]],[[7821,7821],"valid"],[[7822,7822],"mapped",[7823]],[[7823,7823],"valid"],[[7824,7824],"mapped",[7825]],[[7825,7825],"valid"],[[7826,7826],"mapped",[7827]],[[7827,7827],"valid"],[[7828,7828],"mapped",[7829]],[[7829,7833],"valid"],[[7834,7834],"mapped",[97,702]],[[7835,7835],"mapped",[7777]],[[7836,7837],"valid"],[[7838,7838],"mapped",[115,115]],[[7839,7839],"valid"],[[7840,7840],"mapped",[7841]],[[7841,7841],"valid"],[[7842,7842],"mapped",[7843]],[[7843,7843],"valid"],[[7844,7844],"mapped",[7845]],[[7845,7845],"valid"],[[7846,7846],"mapped",[7847]],[[7847,7847],"valid"],[[7848,7848],"mapped",[7849]],[[7849,7849],"valid"],[[7850,7850],"mapped",[7851]],[[7851,7851],"valid"],[[7852,7852],"mapped",[7853]],[[7853,7853],"valid"],[[7854,7854],"mapped",[7855]],[[7855,7855],"valid"],[[7856,7856],"mapped",[7857]],[[7857,7857],"valid"],[[7858,7858],"mapped",[7859]],[[7859,7859],"valid"],[[7860,7860],"mapped",[7861]],[[7861,7861],"valid"],[[7862,7862],"mapped",[7863]],[[7863,7863],"valid"],[[7864,7864],"mapped",[7865]],[[7865,7865],"valid"],[[7866,7866],"mapped",[7867]],[[7867,7867],"valid"],[[7868,7868],"mapped",[7869]],[[7869,7869],"valid"],[[7870,7870],"mapped",[7871]],[[7871,7871],"valid"],[[7872,7872],"mapped",[7873]],[[7873,7873],"valid"],[[7874,7874],"mapped",[7875]],[[7875,7875],"valid"],[[7876,7876],"mapped",[7877]],[[7877,7877],"valid"],[[7878,7878],"mapped",[7879]],[[7879,7879],"valid"],[[7880,7880],"mapped",[7881]],[[7881,7881],"valid"],[[7882,7882],"mapped",[7883]],[[7883,7883],"valid"],[[7884,7884],"mapped",[7885]],[[7885,7885],"valid"],[[7886,7886],"mapped",[7887]],[[7887,7887],"valid"],[[7888,7888],"mapped",[7889]],[[7889,7889],"valid"],[[7890,7890],"mapped",[7891]],[[7891,7891],"valid"],[[7892,7892],"mapped",[7893]],[[7893,7893],"valid"],[[7894,7894],"mapped",[7895]],[[7895,7895],"valid"],[[7896,7896],"mapped",[7897]],[[7897,7897],"valid"],[[7898,7898],"mapped",[7899]],[[7899,7899],"valid"],[[7900,7900],"mapped",[7901]],[[7901,7901],"valid"],[[7902,7902],"mapped",[7903]],[[7903,7903],"valid"],[[7904,7904],"mapped",[7905]],[[7905,7905],"valid"],[[7906,7906],"mapped",[7907]],[[7907,7907],"valid"],[[7908,7908],"mapped",[7909]],[[7909,7909],"valid"],[[7910,7910],"mapped",[7911]],[[7911,7911],"valid"],[[7912,7912],"mapped",[7913]],[[7913,7913],"valid"],[[7914,7914],"mapped",[7915]],[[7915,7915],"valid"],[[7916,7916],"mapped",[7917]],[[7917,7917],"valid"],[[7918,7918],"mapped",[7919]],[[7919,7919],"valid"],[[7920,7920],"mapped",[7921]],[[7921,7921],"valid"],[[7922,7922],"mapped",[7923]],[[7923,7923],"valid"],[[7924,7924],"mapped",[7925]],[[7925,7925],"valid"],[[7926,7926],"mapped",[7927]],[[7927,7927],"valid"],[[7928,7928],"mapped",[7929]],[[7929,7929],"valid"],[[7930,7930],"mapped",[7931]],[[7931,7931],"valid"],[[7932,7932],"mapped",[7933]],[[7933,7933],"valid"],[[7934,7934],"mapped",[7935]],[[7935,7935],"valid"],[[7936,7943],"valid"],[[7944,7944],"mapped",[7936]],[[7945,7945],"mapped",[7937]],[[7946,7946],"mapped",[7938]],[[7947,7947],"mapped",[7939]],[[7948,7948],"mapped",[7940]],[[7949,7949],"mapped",[7941]],[[7950,7950],"mapped",[7942]],[[7951,7951],"mapped",[7943]],[[7952,7957],"valid"],[[7958,7959],"disallowed"],[[7960,7960],"mapped",[7952]],[[7961,7961],"mapped",[7953]],[[7962,7962],"mapped",[7954]],[[7963,7963],"mapped",[7955]],[[7964,7964],"mapped",[7956]],[[7965,7965],"mapped",[7957]],[[7966,7967],"disallowed"],[[7968,7975],"valid"],[[7976,7976],"mapped",[7968]],[[7977,7977],"mapped",[7969]],[[7978,7978],"mapped",[7970]],[[7979,7979],"mapped",[7971]],[[7980,7980],"mapped",[7972]],[[7981,7981],"mapped",[7973]],[[7982,7982],"mapped",[7974]],[[7983,7983],"mapped",[7975]],[[7984,7991],"valid"],[[7992,7992],"mapped",[7984]],[[7993,7993],"mapped",[7985]],[[7994,7994],"mapped",[7986]],[[7995,7995],"mapped",[7987]],[[7996,7996],"mapped",[7988]],[[7997,7997],"mapped",[7989]],[[7998,7998],"mapped",[7990]],[[7999,7999],"mapped",[7991]],[[8000,8005],"valid"],[[8006,8007],"disallowed"],[[8008,8008],"mapped",[8000]],[[8009,8009],"mapped",[8001]],[[8010,8010],"mapped",[8002]],[[8011,8011],"mapped",[8003]],[[8012,8012],"mapped",[8004]],[[8013,8013],"mapped",[8005]],[[8014,8015],"disallowed"],[[8016,8023],"valid"],[[8024,8024],"disallowed"],[[8025,8025],"mapped",[8017]],[[8026,8026],"disallowed"],[[8027,8027],"mapped",[8019]],[[8028,8028],"disallowed"],[[8029,8029],"mapped",[8021]],[[8030,8030],"disallowed"],[[8031,8031],"mapped",[8023]],[[8032,8039],"valid"],[[8040,8040],"mapped",[8032]],[[8041,8041],"mapped",[8033]],[[8042,8042],"mapped",[8034]],[[8043,8043],"mapped",[8035]],[[8044,8044],"mapped",[8036]],[[8045,8045],"mapped",[8037]],[[8046,8046],"mapped",[8038]],[[8047,8047],"mapped",[8039]],[[8048,8048],"valid"],[[8049,8049],"mapped",[940]],[[8050,8050],"valid"],[[8051,8051],"mapped",[941]],[[8052,8052],"valid"],[[8053,8053],"mapped",[942]],[[8054,8054],"valid"],[[8055,8055],"mapped",[943]],[[8056,8056],"valid"],[[8057,8057],"mapped",[972]],[[8058,8058],"valid"],[[8059,8059],"mapped",[973]],[[8060,8060],"valid"],[[8061,8061],"mapped",[974]],[[8062,8063],"disallowed"],[[8064,8064],"mapped",[7936,953]],[[8065,8065],"mapped",[7937,953]],[[8066,8066],"mapped",[7938,953]],[[8067,8067],"mapped",[7939,953]],[[8068,8068],"mapped",[7940,953]],[[8069,8069],"mapped",[7941,953]],[[8070,8070],"mapped",[7942,953]],[[8071,8071],"mapped",[7943,953]],[[8072,8072],"mapped",[7936,953]],[[8073,8073],"mapped",[7937,953]],[[8074,8074],"mapped",[7938,953]],[[8075,8075],"mapped",[7939,953]],[[8076,8076],"mapped",[7940,953]],[[8077,8077],"mapped",[7941,953]],[[8078,8078],"mapped",[7942,953]],[[8079,8079],"mapped",[7943,953]],[[8080,8080],"mapped",[7968,953]],[[8081,8081],"mapped",[7969,953]],[[8082,8082],"mapped",[7970,953]],[[8083,8083],"mapped",[7971,953]],[[8084,8084],"mapped",[7972,953]],[[8085,8085],"mapped",[7973,953]],[[8086,8086],"mapped",[7974,953]],[[8087,8087],"mapped",[7975,953]],[[8088,8088],"mapped",[7968,953]],[[8089,8089],"mapped",[7969,953]],[[8090,8090],"mapped",[7970,953]],[[8091,8091],"mapped",[7971,953]],[[8092,8092],"mapped",[7972,953]],[[8093,8093],"mapped",[7973,953]],[[8094,8094],"mapped",[7974,953]],[[8095,8095],"mapped",[7975,953]],[[8096,8096],"mapped",[8032,953]],[[8097,8097],"mapped",[8033,953]],[[8098,8098],"mapped",[8034,953]],[[8099,8099],"mapped",[8035,953]],[[8100,8100],"mapped",[8036,953]],[[8101,8101],"mapped",[8037,953]],[[8102,8102],"mapped",[8038,953]],[[8103,8103],"mapped",[8039,953]],[[8104,8104],"mapped",[8032,953]],[[8105,8105],"mapped",[8033,953]],[[8106,8106],"mapped",[8034,953]],[[8107,8107],"mapped",[8035,953]],[[8108,8108],"mapped",[8036,953]],[[8109,8109],"mapped",[8037,953]],[[8110,8110],"mapped",[8038,953]],[[8111,8111],"mapped",[8039,953]],[[8112,8113],"valid"],[[8114,8114],"mapped",[8048,953]],[[8115,8115],"mapped",[945,953]],[[8116,8116],"mapped",[940,953]],[[8117,8117],"disallowed"],[[8118,8118],"valid"],[[8119,8119],"mapped",[8118,953]],[[8120,8120],"mapped",[8112]],[[8121,8121],"mapped",[8113]],[[8122,8122],"mapped",[8048]],[[8123,8123],"mapped",[940]],[[8124,8124],"mapped",[945,953]],[[8125,8125],"disallowed_STD3_mapped",[32,787]],[[8126,8126],"mapped",[953]],[[8127,8127],"disallowed_STD3_mapped",[32,787]],[[8128,8128],"disallowed_STD3_mapped",[32,834]],[[8129,8129],"disallowed_STD3_mapped",[32,776,834]],[[8130,8130],"mapped",[8052,953]],[[8131,8131],"mapped",[951,953]],[[8132,8132],"mapped",[942,953]],[[8133,8133],"disallowed"],[[8134,8134],"valid"],[[8135,8135],"mapped",[8134,953]],[[8136,8136],"mapped",[8050]],[[8137,8137],"mapped",[941]],[[8138,8138],"mapped",[8052]],[[8139,8139],"mapped",[942]],[[8140,8140],"mapped",[951,953]],[[8141,8141],"disallowed_STD3_mapped",[32,787,768]],[[8142,8142],"disallowed_STD3_mapped",[32,787,769]],[[8143,8143],"disallowed_STD3_mapped",[32,787,834]],[[8144,8146],"valid"],[[8147,8147],"mapped",[912]],[[8148,8149],"disallowed"],[[8150,8151],"valid"],[[8152,8152],"mapped",[8144]],[[8153,8153],"mapped",[8145]],[[8154,8154],"mapped",[8054]],[[8155,8155],"mapped",[943]],[[8156,8156],"disallowed"],[[8157,8157],"disallowed_STD3_mapped",[32,788,768]],[[8158,8158],"disallowed_STD3_mapped",[32,788,769]],[[8159,8159],"disallowed_STD3_mapped",[32,788,834]],[[8160,8162],"valid"],[[8163,8163],"mapped",[944]],[[8164,8167],"valid"],[[8168,8168],"mapped",[8160]],[[8169,8169],"mapped",[8161]],[[8170,8170],"mapped",[8058]],[[8171,8171],"mapped",[973]],[[8172,8172],"mapped",[8165]],[[8173,8173],"disallowed_STD3_mapped",[32,776,768]],[[8174,8174],"disallowed_STD3_mapped",[32,776,769]],[[8175,8175],"disallowed_STD3_mapped",[96]],[[8176,8177],"disallowed"],[[8178,8178],"mapped",[8060,953]],[[8179,8179],"mapped",[969,953]],[[8180,8180],"mapped",[974,953]],[[8181,8181],"disallowed"],[[8182,8182],"valid"],[[8183,8183],"mapped",[8182,953]],[[8184,8184],"mapped",[8056]],[[8185,8185],"mapped",[972]],[[8186,8186],"mapped",[8060]],[[8187,8187],"mapped",[974]],[[8188,8188],"mapped",[969,953]],[[8189,8189],"disallowed_STD3_mapped",[32,769]],[[8190,8190],"disallowed_STD3_mapped",[32,788]],[[8191,8191],"disallowed"],[[8192,8202],"disallowed_STD3_mapped",[32]],[[8203,8203],"ignored"],[[8204,8205],"deviation",[]],[[8206,8207],"disallowed"],[[8208,8208],"valid",[],"NV8"],[[8209,8209],"mapped",[8208]],[[8210,8214],"valid",[],"NV8"],[[8215,8215],"disallowed_STD3_mapped",[32,819]],[[8216,8227],"valid",[],"NV8"],[[8228,8230],"disallowed"],[[8231,8231],"valid",[],"NV8"],[[8232,8238],"disallowed"],[[8239,8239],"disallowed_STD3_mapped",[32]],[[8240,8242],"valid",[],"NV8"],[[8243,8243],"mapped",[8242,8242]],[[8244,8244],"mapped",[8242,8242,8242]],[[8245,8245],"valid",[],"NV8"],[[8246,8246],"mapped",[8245,8245]],[[8247,8247],"mapped",[8245,8245,8245]],[[8248,8251],"valid",[],"NV8"],[[8252,8252],"disallowed_STD3_mapped",[33,33]],[[8253,8253],"valid",[],"NV8"],[[8254,8254],"disallowed_STD3_mapped",[32,773]],[[8255,8262],"valid",[],"NV8"],[[8263,8263],"disallowed_STD3_mapped",[63,63]],[[8264,8264],"disallowed_STD3_mapped",[63,33]],[[8265,8265],"disallowed_STD3_mapped",[33,63]],[[8266,8269],"valid",[],"NV8"],[[8270,8274],"valid",[],"NV8"],[[8275,8276],"valid",[],"NV8"],[[8277,8278],"valid",[],"NV8"],[[8279,8279],"mapped",[8242,8242,8242,8242]],[[8280,8286],"valid",[],"NV8"],[[8287,8287],"disallowed_STD3_mapped",[32]],[[8288,8288],"ignored"],[[8289,8291],"disallowed"],[[8292,8292],"ignored"],[[8293,8293],"disallowed"],[[8294,8297],"disallowed"],[[8298,8303],"disallowed"],[[8304,8304],"mapped",[48]],[[8305,8305],"mapped",[105]],[[8306,8307],"disallowed"],[[8308,8308],"mapped",[52]],[[8309,8309],"mapped",[53]],[[8310,8310],"mapped",[54]],[[8311,8311],"mapped",[55]],[[8312,8312],"mapped",[56]],[[8313,8313],"mapped",[57]],[[8314,8314],"disallowed_STD3_mapped",[43]],[[8315,8315],"mapped",[8722]],[[8316,8316],"disallowed_STD3_mapped",[61]],[[8317,8317],"disallowed_STD3_mapped",[40]],[[8318,8318],"disallowed_STD3_mapped",[41]],[[8319,8319],"mapped",[110]],[[8320,8320],"mapped",[48]],[[8321,8321],"mapped",[49]],[[8322,8322],"mapped",[50]],[[8323,8323],"mapped",[51]],[[8324,8324],"mapped",[52]],[[8325,8325],"mapped",[53]],[[8326,8326],"mapped",[54]],[[8327,8327],"mapped",[55]],[[8328,8328],"mapped",[56]],[[8329,8329],"mapped",[57]],[[8330,8330],"disallowed_STD3_mapped",[43]],[[8331,8331],"mapped",[8722]],[[8332,8332],"disallowed_STD3_mapped",[61]],[[8333,8333],"disallowed_STD3_mapped",[40]],[[8334,8334],"disallowed_STD3_mapped",[41]],[[8335,8335],"disallowed"],[[8336,8336],"mapped",[97]],[[8337,8337],"mapped",[101]],[[8338,8338],"mapped",[111]],[[8339,8339],"mapped",[120]],[[8340,8340],"mapped",[601]],[[8341,8341],"mapped",[104]],[[8342,8342],"mapped",[107]],[[8343,8343],"mapped",[108]],[[8344,8344],"mapped",[109]],[[8345,8345],"mapped",[110]],[[8346,8346],"mapped",[112]],[[8347,8347],"mapped",[115]],[[8348,8348],"mapped",[116]],[[8349,8351],"disallowed"],[[8352,8359],"valid",[],"NV8"],[[8360,8360],"mapped",[114,115]],[[8361,8362],"valid",[],"NV8"],[[8363,8363],"valid",[],"NV8"],[[8364,8364],"valid",[],"NV8"],[[8365,8367],"valid",[],"NV8"],[[8368,8369],"valid",[],"NV8"],[[8370,8373],"valid",[],"NV8"],[[8374,8376],"valid",[],"NV8"],[[8377,8377],"valid",[],"NV8"],[[8378,8378],"valid",[],"NV8"],[[8379,8381],"valid",[],"NV8"],[[8382,8382],"valid",[],"NV8"],[[8383,8399],"disallowed"],[[8400,8417],"valid",[],"NV8"],[[8418,8419],"valid",[],"NV8"],[[8420,8426],"valid",[],"NV8"],[[8427,8427],"valid",[],"NV8"],[[8428,8431],"valid",[],"NV8"],[[8432,8432],"valid",[],"NV8"],[[8433,8447],"disallowed"],[[8448,8448],"disallowed_STD3_mapped",[97,47,99]],[[8449,8449],"disallowed_STD3_mapped",[97,47,115]],[[8450,8450],"mapped",[99]],[[8451,8451],"mapped",[176,99]],[[8452,8452],"valid",[],"NV8"],[[8453,8453],"disallowed_STD3_mapped",[99,47,111]],[[8454,8454],"disallowed_STD3_mapped",[99,47,117]],[[8455,8455],"mapped",[603]],[[8456,8456],"valid",[],"NV8"],[[8457,8457],"mapped",[176,102]],[[8458,8458],"mapped",[103]],[[8459,8462],"mapped",[104]],[[8463,8463],"mapped",[295]],[[8464,8465],"mapped",[105]],[[8466,8467],"mapped",[108]],[[8468,8468],"valid",[],"NV8"],[[8469,8469],"mapped",[110]],[[8470,8470],"mapped",[110,111]],[[8471,8472],"valid",[],"NV8"],[[8473,8473],"mapped",[112]],[[8474,8474],"mapped",[113]],[[8475,8477],"mapped",[114]],[[8478,8479],"valid",[],"NV8"],[[8480,8480],"mapped",[115,109]],[[8481,8481],"mapped",[116,101,108]],[[8482,8482],"mapped",[116,109]],[[8483,8483],"valid",[],"NV8"],[[8484,8484],"mapped",[122]],[[8485,8485],"valid",[],"NV8"],[[8486,8486],"mapped",[969]],[[8487,8487],"valid",[],"NV8"],[[8488,8488],"mapped",[122]],[[8489,8489],"valid",[],"NV8"],[[8490,8490],"mapped",[107]],[[8491,8491],"mapped",[229]],[[8492,8492],"mapped",[98]],[[8493,8493],"mapped",[99]],[[8494,8494],"valid",[],"NV8"],[[8495,8496],"mapped",[101]],[[8497,8497],"mapped",[102]],[[8498,8498],"disallowed"],[[8499,8499],"mapped",[109]],[[8500,8500],"mapped",[111]],[[8501,8501],"mapped",[1488]],[[8502,8502],"mapped",[1489]],[[8503,8503],"mapped",[1490]],[[8504,8504],"mapped",[1491]],[[8505,8505],"mapped",[105]],[[8506,8506],"valid",[],"NV8"],[[8507,8507],"mapped",[102,97,120]],[[8508,8508],"mapped",[960]],[[8509,8510],"mapped",[947]],[[8511,8511],"mapped",[960]],[[8512,8512],"mapped",[8721]],[[8513,8516],"valid",[],"NV8"],[[8517,8518],"mapped",[100]],[[8519,8519],"mapped",[101]],[[8520,8520],"mapped",[105]],[[8521,8521],"mapped",[106]],[[8522,8523],"valid",[],"NV8"],[[8524,8524],"valid",[],"NV8"],[[8525,8525],"valid",[],"NV8"],[[8526,8526],"valid"],[[8527,8527],"valid",[],"NV8"],[[8528,8528],"mapped",[49,8260,55]],[[8529,8529],"mapped",[49,8260,57]],[[8530,8530],"mapped",[49,8260,49,48]],[[8531,8531],"mapped",[49,8260,51]],[[8532,8532],"mapped",[50,8260,51]],[[8533,8533],"mapped",[49,8260,53]],[[8534,8534],"mapped",[50,8260,53]],[[8535,8535],"mapped",[51,8260,53]],[[8536,8536],"mapped",[52,8260,53]],[[8537,8537],"mapped",[49,8260,54]],[[8538,8538],"mapped",[53,8260,54]],[[8539,8539],"mapped",[49,8260,56]],[[8540,8540],"mapped",[51,8260,56]],[[8541,8541],"mapped",[53,8260,56]],[[8542,8542],"mapped",[55,8260,56]],[[8543,8543],"mapped",[49,8260]],[[8544,8544],"mapped",[105]],[[8545,8545],"mapped",[105,105]],[[8546,8546],"mapped",[105,105,105]],[[8547,8547],"mapped",[105,118]],[[8548,8548],"mapped",[118]],[[8549,8549],"mapped",[118,105]],[[8550,8550],"mapped",[118,105,105]],[[8551,8551],"mapped",[118,105,105,105]],[[8552,8552],"mapped",[105,120]],[[8553,8553],"mapped",[120]],[[8554,8554],"mapped",[120,105]],[[8555,8555],"mapped",[120,105,105]],[[8556,8556],"mapped",[108]],[[8557,8557],"mapped",[99]],[[8558,8558],"mapped",[100]],[[8559,8559],"mapped",[109]],[[8560,8560],"mapped",[105]],[[8561,8561],"mapped",[105,105]],[[8562,8562],"mapped",[105,105,105]],[[8563,8563],"mapped",[105,118]],[[8564,8564],"mapped",[118]],[[8565,8565],"mapped",[118,105]],[[8566,8566],"mapped",[118,105,105]],[[8567,8567],"mapped",[118,105,105,105]],[[8568,8568],"mapped",[105,120]],[[8569,8569],"mapped",[120]],[[8570,8570],"mapped",[120,105]],[[8571,8571],"mapped",[120,105,105]],[[8572,8572],"mapped",[108]],[[8573,8573],"mapped",[99]],[[8574,8574],"mapped",[100]],[[8575,8575],"mapped",[109]],[[8576,8578],"valid",[],"NV8"],[[8579,8579],"disallowed"],[[8580,8580],"valid"],[[8581,8584],"valid",[],"NV8"],[[8585,8585],"mapped",[48,8260,51]],[[8586,8587],"valid",[],"NV8"],[[8588,8591],"disallowed"],[[8592,8682],"valid",[],"NV8"],[[8683,8691],"valid",[],"NV8"],[[8692,8703],"valid",[],"NV8"],[[8704,8747],"valid",[],"NV8"],[[8748,8748],"mapped",[8747,8747]],[[8749,8749],"mapped",[8747,8747,8747]],[[8750,8750],"valid",[],"NV8"],[[8751,8751],"mapped",[8750,8750]],[[8752,8752],"mapped",[8750,8750,8750]],[[8753,8799],"valid",[],"NV8"],[[8800,8800],"disallowed_STD3_valid"],[[8801,8813],"valid",[],"NV8"],[[8814,8815],"disallowed_STD3_valid"],[[8816,8945],"valid",[],"NV8"],[[8946,8959],"valid",[],"NV8"],[[8960,8960],"valid",[],"NV8"],[[8961,8961],"valid",[],"NV8"],[[8962,9000],"valid",[],"NV8"],[[9001,9001],"mapped",[12296]],[[9002,9002],"mapped",[12297]],[[9003,9082],"valid",[],"NV8"],[[9083,9083],"valid",[],"NV8"],[[9084,9084],"valid",[],"NV8"],[[9085,9114],"valid",[],"NV8"],[[9115,9166],"valid",[],"NV8"],[[9167,9168],"valid",[],"NV8"],[[9169,9179],"valid",[],"NV8"],[[9180,9191],"valid",[],"NV8"],[[9192,9192],"valid",[],"NV8"],[[9193,9203],"valid",[],"NV8"],[[9204,9210],"valid",[],"NV8"],[[9211,9215],"disallowed"],[[9216,9252],"valid",[],"NV8"],[[9253,9254],"valid",[],"NV8"],[[9255,9279],"disallowed"],[[9280,9290],"valid",[],"NV8"],[[9291,9311],"disallowed"],[[9312,9312],"mapped",[49]],[[9313,9313],"mapped",[50]],[[9314,9314],"mapped",[51]],[[9315,9315],"mapped",[52]],[[9316,9316],"mapped",[53]],[[9317,9317],"mapped",[54]],[[9318,9318],"mapped",[55]],[[9319,9319],"mapped",[56]],[[9320,9320],"mapped",[57]],[[9321,9321],"mapped",[49,48]],[[9322,9322],"mapped",[49,49]],[[9323,9323],"mapped",[49,50]],[[9324,9324],"mapped",[49,51]],[[9325,9325],"mapped",[49,52]],[[9326,9326],"mapped",[49,53]],[[9327,9327],"mapped",[49,54]],[[9328,9328],"mapped",[49,55]],[[9329,9329],"mapped",[49,56]],[[9330,9330],"mapped",[49,57]],[[9331,9331],"mapped",[50,48]],[[9332,9332],"disallowed_STD3_mapped",[40,49,41]],[[9333,9333],"disallowed_STD3_mapped",[40,50,41]],[[9334,9334],"disallowed_STD3_mapped",[40,51,41]],[[9335,9335],"disallowed_STD3_mapped",[40,52,41]],[[9336,9336],"disallowed_STD3_mapped",[40,53,41]],[[9337,9337],"disallowed_STD3_mapped",[40,54,41]],[[9338,9338],"disallowed_STD3_mapped",[40,55,41]],[[9339,9339],"disallowed_STD3_mapped",[40,56,41]],[[9340,9340],"disallowed_STD3_mapped",[40,57,41]],[[9341,9341],"disallowed_STD3_mapped",[40,49,48,41]],[[9342,9342],"disallowed_STD3_mapped",[40,49,49,41]],[[9343,9343],"disallowed_STD3_mapped",[40,49,50,41]],[[9344,9344],"disallowed_STD3_mapped",[40,49,51,41]],[[9345,9345],"disallowed_STD3_mapped",[40,49,52,41]],[[9346,9346],"disallowed_STD3_mapped",[40,49,53,41]],[[9347,9347],"disallowed_STD3_mapped",[40,49,54,41]],[[9348,9348],"disallowed_STD3_mapped",[40,49,55,41]],[[9349,9349],"disallowed_STD3_mapped",[40,49,56,41]],[[9350,9350],"disallowed_STD3_mapped",[40,49,57,41]],[[9351,9351],"disallowed_STD3_mapped",[40,50,48,41]],[[9352,9371],"disallowed"],[[9372,9372],"disallowed_STD3_mapped",[40,97,41]],[[9373,9373],"disallowed_STD3_mapped",[40,98,41]],[[9374,9374],"disallowed_STD3_mapped",[40,99,41]],[[9375,9375],"disallowed_STD3_mapped",[40,100,41]],[[9376,9376],"disallowed_STD3_mapped",[40,101,41]],[[9377,9377],"disallowed_STD3_mapped",[40,102,41]],[[9378,9378],"disallowed_STD3_mapped",[40,103,41]],[[9379,9379],"disallowed_STD3_mapped",[40,104,41]],[[9380,9380],"disallowed_STD3_mapped",[40,105,41]],[[9381,9381],"disallowed_STD3_mapped",[40,106,41]],[[9382,9382],"disallowed_STD3_mapped",[40,107,41]],[[9383,9383],"disallowed_STD3_mapped",[40,108,41]],[[9384,9384],"disallowed_STD3_mapped",[40,109,41]],[[9385,9385],"disallowed_STD3_mapped",[40,110,41]],[[9386,9386],"disallowed_STD3_mapped",[40,111,41]],[[9387,9387],"disallowed_STD3_mapped",[40,112,41]],[[9388,9388],"disallowed_STD3_mapped",[40,113,41]],[[9389,9389],"disallowed_STD3_mapped",[40,114,41]],[[9390,9390],"disallowed_STD3_mapped",[40,115,41]],[[9391,9391],"disallowed_STD3_mapped",[40,116,41]],[[9392,9392],"disallowed_STD3_mapped",[40,117,41]],[[9393,9393],"disallowed_STD3_mapped",[40,118,41]],[[9394,9394],"disallowed_STD3_mapped",[40,119,41]],[[9395,9395],"disallowed_STD3_mapped",[40,120,41]],[[9396,9396],"disallowed_STD3_mapped",[40,121,41]],[[9397,9397],"disallowed_STD3_mapped",[40,122,41]],[[9398,9398],"mapped",[97]],[[9399,9399],"mapped",[98]],[[9400,9400],"mapped",[99]],[[9401,9401],"mapped",[100]],[[9402,9402],"mapped",[101]],[[9403,9403],"mapped",[102]],[[9404,9404],"mapped",[103]],[[9405,9405],"mapped",[104]],[[9406,9406],"mapped",[105]],[[9407,9407],"mapped",[106]],[[9408,9408],"mapped",[107]],[[9409,9409],"mapped",[108]],[[9410,9410],"mapped",[109]],[[9411,9411],"mapped",[110]],[[9412,9412],"mapped",[111]],[[9413,9413],"mapped",[112]],[[9414,9414],"mapped",[113]],[[9415,9415],"mapped",[114]],[[9416,9416],"mapped",[115]],[[9417,9417],"mapped",[116]],[[9418,9418],"mapped",[117]],[[9419,9419],"mapped",[118]],[[9420,9420],"mapped",[119]],[[9421,9421],"mapped",[120]],[[9422,9422],"mapped",[121]],[[9423,9423],"mapped",[122]],[[9424,9424],"mapped",[97]],[[9425,9425],"mapped",[98]],[[9426,9426],"mapped",[99]],[[9427,9427],"mapped",[100]],[[9428,9428],"mapped",[101]],[[9429,9429],"mapped",[102]],[[9430,9430],"mapped",[103]],[[9431,9431],"mapped",[104]],[[9432,9432],"mapped",[105]],[[9433,9433],"mapped",[106]],[[9434,9434],"mapped",[107]],[[9435,9435],"mapped",[108]],[[9436,9436],"mapped",[109]],[[9437,9437],"mapped",[110]],[[9438,9438],"mapped",[111]],[[9439,9439],"mapped",[112]],[[9440,9440],"mapped",[113]],[[9441,9441],"mapped",[114]],[[9442,9442],"mapped",[115]],[[9443,9443],"mapped",[116]],[[9444,9444],"mapped",[117]],[[9445,9445],"mapped",[118]],[[9446,9446],"mapped",[119]],[[9447,9447],"mapped",[120]],[[9448,9448],"mapped",[121]],[[9449,9449],"mapped",[122]],[[9450,9450],"mapped",[48]],[[9451,9470],"valid",[],"NV8"],[[9471,9471],"valid",[],"NV8"],[[9472,9621],"valid",[],"NV8"],[[9622,9631],"valid",[],"NV8"],[[9632,9711],"valid",[],"NV8"],[[9712,9719],"valid",[],"NV8"],[[9720,9727],"valid",[],"NV8"],[[9728,9747],"valid",[],"NV8"],[[9748,9749],"valid",[],"NV8"],[[9750,9751],"valid",[],"NV8"],[[9752,9752],"valid",[],"NV8"],[[9753,9753],"valid",[],"NV8"],[[9754,9839],"valid",[],"NV8"],[[9840,9841],"valid",[],"NV8"],[[9842,9853],"valid",[],"NV8"],[[9854,9855],"valid",[],"NV8"],[[9856,9865],"valid",[],"NV8"],[[9866,9873],"valid",[],"NV8"],[[9874,9884],"valid",[],"NV8"],[[9885,9885],"valid",[],"NV8"],[[9886,9887],"valid",[],"NV8"],[[9888,9889],"valid",[],"NV8"],[[9890,9905],"valid",[],"NV8"],[[9906,9906],"valid",[],"NV8"],[[9907,9916],"valid",[],"NV8"],[[9917,9919],"valid",[],"NV8"],[[9920,9923],"valid",[],"NV8"],[[9924,9933],"valid",[],"NV8"],[[9934,9934],"valid",[],"NV8"],[[9935,9953],"valid",[],"NV8"],[[9954,9954],"valid",[],"NV8"],[[9955,9955],"valid",[],"NV8"],[[9956,9959],"valid",[],"NV8"],[[9960,9983],"valid",[],"NV8"],[[9984,9984],"valid",[],"NV8"],[[9985,9988],"valid",[],"NV8"],[[9989,9989],"valid",[],"NV8"],[[9990,9993],"valid",[],"NV8"],[[9994,9995],"valid",[],"NV8"],[[9996,10023],"valid",[],"NV8"],[[10024,10024],"valid",[],"NV8"],[[10025,10059],"valid",[],"NV8"],[[10060,10060],"valid",[],"NV8"],[[10061,10061],"valid",[],"NV8"],[[10062,10062],"valid",[],"NV8"],[[10063,10066],"valid",[],"NV8"],[[10067,10069],"valid",[],"NV8"],[[10070,10070],"valid",[],"NV8"],[[10071,10071],"valid",[],"NV8"],[[10072,10078],"valid",[],"NV8"],[[10079,10080],"valid",[],"NV8"],[[10081,10087],"valid",[],"NV8"],[[10088,10101],"valid",[],"NV8"],[[10102,10132],"valid",[],"NV8"],[[10133,10135],"valid",[],"NV8"],[[10136,10159],"valid",[],"NV8"],[[10160,10160],"valid",[],"NV8"],[[10161,10174],"valid",[],"NV8"],[[10175,10175],"valid",[],"NV8"],[[10176,10182],"valid",[],"NV8"],[[10183,10186],"valid",[],"NV8"],[[10187,10187],"valid",[],"NV8"],[[10188,10188],"valid",[],"NV8"],[[10189,10189],"valid",[],"NV8"],[[10190,10191],"valid",[],"NV8"],[[10192,10219],"valid",[],"NV8"],[[10220,10223],"valid",[],"NV8"],[[10224,10239],"valid",[],"NV8"],[[10240,10495],"valid",[],"NV8"],[[10496,10763],"valid",[],"NV8"],[[10764,10764],"mapped",[8747,8747,8747,8747]],[[10765,10867],"valid",[],"NV8"],[[10868,10868],"disallowed_STD3_mapped",[58,58,61]],[[10869,10869],"disallowed_STD3_mapped",[61,61]],[[10870,10870],"disallowed_STD3_mapped",[61,61,61]],[[10871,10971],"valid",[],"NV8"],[[10972,10972],"mapped",[10973,824]],[[10973,11007],"valid",[],"NV8"],[[11008,11021],"valid",[],"NV8"],[[11022,11027],"valid",[],"NV8"],[[11028,11034],"valid",[],"NV8"],[[11035,11039],"valid",[],"NV8"],[[11040,11043],"valid",[],"NV8"],[[11044,11084],"valid",[],"NV8"],[[11085,11087],"valid",[],"NV8"],[[11088,11092],"valid",[],"NV8"],[[11093,11097],"valid",[],"NV8"],[[11098,11123],"valid",[],"NV8"],[[11124,11125],"disallowed"],[[11126,11157],"valid",[],"NV8"],[[11158,11159],"disallowed"],[[11160,11193],"valid",[],"NV8"],[[11194,11196],"disallowed"],[[11197,11208],"valid",[],"NV8"],[[11209,11209],"disallowed"],[[11210,11217],"valid",[],"NV8"],[[11218,11243],"disallowed"],[[11244,11247],"valid",[],"NV8"],[[11248,11263],"disallowed"],[[11264,11264],"mapped",[11312]],[[11265,11265],"mapped",[11313]],[[11266,11266],"mapped",[11314]],[[11267,11267],"mapped",[11315]],[[11268,11268],"mapped",[11316]],[[11269,11269],"mapped",[11317]],[[11270,11270],"mapped",[11318]],[[11271,11271],"mapped",[11319]],[[11272,11272],"mapped",[11320]],[[11273,11273],"mapped",[11321]],[[11274,11274],"mapped",[11322]],[[11275,11275],"mapped",[11323]],[[11276,11276],"mapped",[11324]],[[11277,11277],"mapped",[11325]],[[11278,11278],"mapped",[11326]],[[11279,11279],"mapped",[11327]],[[11280,11280],"mapped",[11328]],[[11281,11281],"mapped",[11329]],[[11282,11282],"mapped",[11330]],[[11283,11283],"mapped",[11331]],[[11284,11284],"mapped",[11332]],[[11285,11285],"mapped",[11333]],[[11286,11286],"mapped",[11334]],[[11287,11287],"mapped",[11335]],[[11288,11288],"mapped",[11336]],[[11289,11289],"mapped",[11337]],[[11290,11290],"mapped",[11338]],[[11291,11291],"mapped",[11339]],[[11292,11292],"mapped",[11340]],[[11293,11293],"mapped",[11341]],[[11294,11294],"mapped",[11342]],[[11295,11295],"mapped",[11343]],[[11296,11296],"mapped",[11344]],[[11297,11297],"mapped",[11345]],[[11298,11298],"mapped",[11346]],[[11299,11299],"mapped",[11347]],[[11300,11300],"mapped",[11348]],[[11301,11301],"mapped",[11349]],[[11302,11302],"mapped",[11350]],[[11303,11303],"mapped",[11351]],[[11304,11304],"mapped",[11352]],[[11305,11305],"mapped",[11353]],[[11306,11306],"mapped",[11354]],[[11307,11307],"mapped",[11355]],[[11308,11308],"mapped",[11356]],[[11309,11309],"mapped",[11357]],[[11310,11310],"mapped",[11358]],[[11311,11311],"disallowed"],[[11312,11358],"valid"],[[11359,11359],"disallowed"],[[11360,11360],"mapped",[11361]],[[11361,11361],"valid"],[[11362,11362],"mapped",[619]],[[11363,11363],"mapped",[7549]],[[11364,11364],"mapped",[637]],[[11365,11366],"valid"],[[11367,11367],"mapped",[11368]],[[11368,11368],"valid"],[[11369,11369],"mapped",[11370]],[[11370,11370],"valid"],[[11371,11371],"mapped",[11372]],[[11372,11372],"valid"],[[11373,11373],"mapped",[593]],[[11374,11374],"mapped",[625]],[[11375,11375],"mapped",[592]],[[11376,11376],"mapped",[594]],[[11377,11377],"valid"],[[11378,11378],"mapped",[11379]],[[11379,11379],"valid"],[[11380,11380],"valid"],[[11381,11381],"mapped",[11382]],[[11382,11383],"valid"],[[11384,11387],"valid"],[[11388,11388],"mapped",[106]],[[11389,11389],"mapped",[118]],[[11390,11390],"mapped",[575]],[[11391,11391],"mapped",[576]],[[11392,11392],"mapped",[11393]],[[11393,11393],"valid"],[[11394,11394],"mapped",[11395]],[[11395,11395],"valid"],[[11396,11396],"mapped",[11397]],[[11397,11397],"valid"],[[11398,11398],"mapped",[11399]],[[11399,11399],"valid"],[[11400,11400],"mapped",[11401]],[[11401,11401],"valid"],[[11402,11402],"mapped",[11403]],[[11403,11403],"valid"],[[11404,11404],"mapped",[11405]],[[11405,11405],"valid"],[[11406,11406],"mapped",[11407]],[[11407,11407],"valid"],[[11408,11408],"mapped",[11409]],[[11409,11409],"valid"],[[11410,11410],"mapped",[11411]],[[11411,11411],"valid"],[[11412,11412],"mapped",[11413]],[[11413,11413],"valid"],[[11414,11414],"mapped",[11415]],[[11415,11415],"valid"],[[11416,11416],"mapped",[11417]],[[11417,11417],"valid"],[[11418,11418],"mapped",[11419]],[[11419,11419],"valid"],[[11420,11420],"mapped",[11421]],[[11421,11421],"valid"],[[11422,11422],"mapped",[11423]],[[11423,11423],"valid"],[[11424,11424],"mapped",[11425]],[[11425,11425],"valid"],[[11426,11426],"mapped",[11427]],[[11427,11427],"valid"],[[11428,11428],"mapped",[11429]],[[11429,11429],"valid"],[[11430,11430],"mapped",[11431]],[[11431,11431],"valid"],[[11432,11432],"mapped",[11433]],[[11433,11433],"valid"],[[11434,11434],"mapped",[11435]],[[11435,11435],"valid"],[[11436,11436],"mapped",[11437]],[[11437,11437],"valid"],[[11438,11438],"mapped",[11439]],[[11439,11439],"valid"],[[11440,11440],"mapped",[11441]],[[11441,11441],"valid"],[[11442,11442],"mapped",[11443]],[[11443,11443],"valid"],[[11444,11444],"mapped",[11445]],[[11445,11445],"valid"],[[11446,11446],"mapped",[11447]],[[11447,11447],"valid"],[[11448,11448],"mapped",[11449]],[[11449,11449],"valid"],[[11450,11450],"mapped",[11451]],[[11451,11451],"valid"],[[11452,11452],"mapped",[11453]],[[11453,11453],"valid"],[[11454,11454],"mapped",[11455]],[[11455,11455],"valid"],[[11456,11456],"mapped",[11457]],[[11457,11457],"valid"],[[11458,11458],"mapped",[11459]],[[11459,11459],"valid"],[[11460,11460],"mapped",[11461]],[[11461,11461],"valid"],[[11462,11462],"mapped",[11463]],[[11463,11463],"valid"],[[11464,11464],"mapped",[11465]],[[11465,11465],"valid"],[[11466,11466],"mapped",[11467]],[[11467,11467],"valid"],[[11468,11468],"mapped",[11469]],[[11469,11469],"valid"],[[11470,11470],"mapped",[11471]],[[11471,11471],"valid"],[[11472,11472],"mapped",[11473]],[[11473,11473],"valid"],[[11474,11474],"mapped",[11475]],[[11475,11475],"valid"],[[11476,11476],"mapped",[11477]],[[11477,11477],"valid"],[[11478,11478],"mapped",[11479]],[[11479,11479],"valid"],[[11480,11480],"mapped",[11481]],[[11481,11481],"valid"],[[11482,11482],"mapped",[11483]],[[11483,11483],"valid"],[[11484,11484],"mapped",[11485]],[[11485,11485],"valid"],[[11486,11486],"mapped",[11487]],[[11487,11487],"valid"],[[11488,11488],"mapped",[11489]],[[11489,11489],"valid"],[[11490,11490],"mapped",[11491]],[[11491,11492],"valid"],[[11493,11498],"valid",[],"NV8"],[[11499,11499],"mapped",[11500]],[[11500,11500],"valid"],[[11501,11501],"mapped",[11502]],[[11502,11505],"valid"],[[11506,11506],"mapped",[11507]],[[11507,11507],"valid"],[[11508,11512],"disallowed"],[[11513,11519],"valid",[],"NV8"],[[11520,11557],"valid"],[[11558,11558],"disallowed"],[[11559,11559],"valid"],[[11560,11564],"disallowed"],[[11565,11565],"valid"],[[11566,11567],"disallowed"],[[11568,11621],"valid"],[[11622,11623],"valid"],[[11624,11630],"disallowed"],[[11631,11631],"mapped",[11617]],[[11632,11632],"valid",[],"NV8"],[[11633,11646],"disallowed"],[[11647,11647],"valid"],[[11648,11670],"valid"],[[11671,11679],"disallowed"],[[11680,11686],"valid"],[[11687,11687],"disallowed"],[[11688,11694],"valid"],[[11695,11695],"disallowed"],[[11696,11702],"valid"],[[11703,11703],"disallowed"],[[11704,11710],"valid"],[[11711,11711],"disallowed"],[[11712,11718],"valid"],[[11719,11719],"disallowed"],[[11720,11726],"valid"],[[11727,11727],"disallowed"],[[11728,11734],"valid"],[[11735,11735],"disallowed"],[[11736,11742],"valid"],[[11743,11743],"disallowed"],[[11744,11775],"valid"],[[11776,11799],"valid",[],"NV8"],[[11800,11803],"valid",[],"NV8"],[[11804,11805],"valid",[],"NV8"],[[11806,11822],"valid",[],"NV8"],[[11823,11823],"valid"],[[11824,11824],"valid",[],"NV8"],[[11825,11825],"valid",[],"NV8"],[[11826,11835],"valid",[],"NV8"],[[11836,11842],"valid",[],"NV8"],[[11843,11903],"disallowed"],[[11904,11929],"valid",[],"NV8"],[[11930,11930],"disallowed"],[[11931,11934],"valid",[],"NV8"],[[11935,11935],"mapped",[27597]],[[11936,12018],"valid",[],"NV8"],[[12019,12019],"mapped",[40863]],[[12020,12031],"disallowed"],[[12032,12032],"mapped",[19968]],[[12033,12033],"mapped",[20008]],[[12034,12034],"mapped",[20022]],[[12035,12035],"mapped",[20031]],[[12036,12036],"mapped",[20057]],[[12037,12037],"mapped",[20101]],[[12038,12038],"mapped",[20108]],[[12039,12039],"mapped",[20128]],[[12040,12040],"mapped",[20154]],[[12041,12041],"mapped",[20799]],[[12042,12042],"mapped",[20837]],[[12043,12043],"mapped",[20843]],[[12044,12044],"mapped",[20866]],[[12045,12045],"mapped",[20886]],[[12046,12046],"mapped",[20907]],[[12047,12047],"mapped",[20960]],[[12048,12048],"mapped",[20981]],[[12049,12049],"mapped",[20992]],[[12050,12050],"mapped",[21147]],[[12051,12051],"mapped",[21241]],[[12052,12052],"mapped",[21269]],[[12053,12053],"mapped",[21274]],[[12054,12054],"mapped",[21304]],[[12055,12055],"mapped",[21313]],[[12056,12056],"mapped",[21340]],[[12057,12057],"mapped",[21353]],[[12058,12058],"mapped",[21378]],[[12059,12059],"mapped",[21430]],[[12060,12060],"mapped",[21448]],[[12061,12061],"mapped",[21475]],[[12062,12062],"mapped",[22231]],[[12063,12063],"mapped",[22303]],[[12064,12064],"mapped",[22763]],[[12065,12065],"mapped",[22786]],[[12066,12066],"mapped",[22794]],[[12067,12067],"mapped",[22805]],[[12068,12068],"mapped",[22823]],[[12069,12069],"mapped",[22899]],[[12070,12070],"mapped",[23376]],[[12071,12071],"mapped",[23424]],[[12072,12072],"mapped",[23544]],[[12073,12073],"mapped",[23567]],[[12074,12074],"mapped",[23586]],[[12075,12075],"mapped",[23608]],[[12076,12076],"mapped",[23662]],[[12077,12077],"mapped",[23665]],[[12078,12078],"mapped",[24027]],[[12079,12079],"mapped",[24037]],[[12080,12080],"mapped",[24049]],[[12081,12081],"mapped",[24062]],[[12082,12082],"mapped",[24178]],[[12083,12083],"mapped",[24186]],[[12084,12084],"mapped",[24191]],[[12085,12085],"mapped",[24308]],[[12086,12086],"mapped",[24318]],[[12087,12087],"mapped",[24331]],[[12088,12088],"mapped",[24339]],[[12089,12089],"mapped",[24400]],[[12090,12090],"mapped",[24417]],[[12091,12091],"mapped",[24435]],[[12092,12092],"mapped",[24515]],[[12093,12093],"mapped",[25096]],[[12094,12094],"mapped",[25142]],[[12095,12095],"mapped",[25163]],[[12096,12096],"mapped",[25903]],[[12097,12097],"mapped",[25908]],[[12098,12098],"mapped",[25991]],[[12099,12099],"mapped",[26007]],[[12100,12100],"mapped",[26020]],[[12101,12101],"mapped",[26041]],[[12102,12102],"mapped",[26080]],[[12103,12103],"mapped",[26085]],[[12104,12104],"mapped",[26352]],[[12105,12105],"mapped",[26376]],[[12106,12106],"mapped",[26408]],[[12107,12107],"mapped",[27424]],[[12108,12108],"mapped",[27490]],[[12109,12109],"mapped",[27513]],[[12110,12110],"mapped",[27571]],[[12111,12111],"mapped",[27595]],[[12112,12112],"mapped",[27604]],[[12113,12113],"mapped",[27611]],[[12114,12114],"mapped",[27663]],[[12115,12115],"mapped",[27668]],[[12116,12116],"mapped",[27700]],[[12117,12117],"mapped",[28779]],[[12118,12118],"mapped",[29226]],[[12119,12119],"mapped",[29238]],[[12120,12120],"mapped",[29243]],[[12121,12121],"mapped",[29247]],[[12122,12122],"mapped",[29255]],[[12123,12123],"mapped",[29273]],[[12124,12124],"mapped",[29275]],[[12125,12125],"mapped",[29356]],[[12126,12126],"mapped",[29572]],[[12127,12127],"mapped",[29577]],[[12128,12128],"mapped",[29916]],[[12129,12129],"mapped",[29926]],[[12130,12130],"mapped",[29976]],[[12131,12131],"mapped",[29983]],[[12132,12132],"mapped",[29992]],[[12133,12133],"mapped",[30000]],[[12134,12134],"mapped",[30091]],[[12135,12135],"mapped",[30098]],[[12136,12136],"mapped",[30326]],[[12137,12137],"mapped",[30333]],[[12138,12138],"mapped",[30382]],[[12139,12139],"mapped",[30399]],[[12140,12140],"mapped",[30446]],[[12141,12141],"mapped",[30683]],[[12142,12142],"mapped",[30690]],[[12143,12143],"mapped",[30707]],[[12144,12144],"mapped",[31034]],[[12145,12145],"mapped",[31160]],[[12146,12146],"mapped",[31166]],[[12147,12147],"mapped",[31348]],[[12148,12148],"mapped",[31435]],[[12149,12149],"mapped",[31481]],[[12150,12150],"mapped",[31859]],[[12151,12151],"mapped",[31992]],[[12152,12152],"mapped",[32566]],[[12153,12153],"mapped",[32593]],[[12154,12154],"mapped",[32650]],[[12155,12155],"mapped",[32701]],[[12156,12156],"mapped",[32769]],[[12157,12157],"mapped",[32780]],[[12158,12158],"mapped",[32786]],[[12159,12159],"mapped",[32819]],[[12160,12160],"mapped",[32895]],[[12161,12161],"mapped",[32905]],[[12162,12162],"mapped",[33251]],[[12163,12163],"mapped",[33258]],[[12164,12164],"mapped",[33267]],[[12165,12165],"mapped",[33276]],[[12166,12166],"mapped",[33292]],[[12167,12167],"mapped",[33307]],[[12168,12168],"mapped",[33311]],[[12169,12169],"mapped",[33390]],[[12170,12170],"mapped",[33394]],[[12171,12171],"mapped",[33400]],[[12172,12172],"mapped",[34381]],[[12173,12173],"mapped",[34411]],[[12174,12174],"mapped",[34880]],[[12175,12175],"mapped",[34892]],[[12176,12176],"mapped",[34915]],[[12177,12177],"mapped",[35198]],[[12178,12178],"mapped",[35211]],[[12179,12179],"mapped",[35282]],[[12180,12180],"mapped",[35328]],[[12181,12181],"mapped",[35895]],[[12182,12182],"mapped",[35910]],[[12183,12183],"mapped",[35925]],[[12184,12184],"mapped",[35960]],[[12185,12185],"mapped",[35997]],[[12186,12186],"mapped",[36196]],[[12187,12187],"mapped",[36208]],[[12188,12188],"mapped",[36275]],[[12189,12189],"mapped",[36523]],[[12190,12190],"mapped",[36554]],[[12191,12191],"mapped",[36763]],[[12192,12192],"mapped",[36784]],[[12193,12193],"mapped",[36789]],[[12194,12194],"mapped",[37009]],[[12195,12195],"mapped",[37193]],[[12196,12196],"mapped",[37318]],[[12197,12197],"mapped",[37324]],[[12198,12198],"mapped",[37329]],[[12199,12199],"mapped",[38263]],[[12200,12200],"mapped",[38272]],[[12201,12201],"mapped",[38428]],[[12202,12202],"mapped",[38582]],[[12203,12203],"mapped",[38585]],[[12204,12204],"mapped",[38632]],[[12205,12205],"mapped",[38737]],[[12206,12206],"mapped",[38750]],[[12207,12207],"mapped",[38754]],[[12208,12208],"mapped",[38761]],[[12209,12209],"mapped",[38859]],[[12210,12210],"mapped",[38893]],[[12211,12211],"mapped",[38899]],[[12212,12212],"mapped",[38913]],[[12213,12213],"mapped",[39080]],[[12214,12214],"mapped",[39131]],[[12215,12215],"mapped",[39135]],[[12216,12216],"mapped",[39318]],[[12217,12217],"mapped",[39321]],[[12218,12218],"mapped",[39340]],[[12219,12219],"mapped",[39592]],[[12220,12220],"mapped",[39640]],[[12221,12221],"mapped",[39647]],[[12222,12222],"mapped",[39717]],[[12223,12223],"mapped",[39727]],[[12224,12224],"mapped",[39730]],[[12225,12225],"mapped",[39740]],[[12226,12226],"mapped",[39770]],[[12227,12227],"mapped",[40165]],[[12228,12228],"mapped",[40565]],[[12229,12229],"mapped",[40575]],[[12230,12230],"mapped",[40613]],[[12231,12231],"mapped",[40635]],[[12232,12232],"mapped",[40643]],[[12233,12233],"mapped",[40653]],[[12234,12234],"mapped",[40657]],[[12235,12235],"mapped",[40697]],[[12236,12236],"mapped",[40701]],[[12237,12237],"mapped",[40718]],[[12238,12238],"mapped",[40723]],[[12239,12239],"mapped",[40736]],[[12240,12240],"mapped",[40763]],[[12241,12241],"mapped",[40778]],[[12242,12242],"mapped",[40786]],[[12243,12243],"mapped",[40845]],[[12244,12244],"mapped",[40860]],[[12245,12245],"mapped",[40864]],[[12246,12271],"disallowed"],[[12272,12283],"disallowed"],[[12284,12287],"disallowed"],[[12288,12288],"disallowed_STD3_mapped",[32]],[[12289,12289],"valid",[],"NV8"],[[12290,12290],"mapped",[46]],[[12291,12292],"valid",[],"NV8"],[[12293,12295],"valid"],[[12296,12329],"valid",[],"NV8"],[[12330,12333],"valid"],[[12334,12341],"valid",[],"NV8"],[[12342,12342],"mapped",[12306]],[[12343,12343],"valid",[],"NV8"],[[12344,12344],"mapped",[21313]],[[12345,12345],"mapped",[21316]],[[12346,12346],"mapped",[21317]],[[12347,12347],"valid",[],"NV8"],[[12348,12348],"valid"],[[12349,12349],"valid",[],"NV8"],[[12350,12350],"valid",[],"NV8"],[[12351,12351],"valid",[],"NV8"],[[12352,12352],"disallowed"],[[12353,12436],"valid"],[[12437,12438],"valid"],[[12439,12440],"disallowed"],[[12441,12442],"valid"],[[12443,12443],"disallowed_STD3_mapped",[32,12441]],[[12444,12444],"disallowed_STD3_mapped",[32,12442]],[[12445,12446],"valid"],[[12447,12447],"mapped",[12424,12426]],[[12448,12448],"valid",[],"NV8"],[[12449,12542],"valid"],[[12543,12543],"mapped",[12467,12488]],[[12544,12548],"disallowed"],[[12549,12588],"valid"],[[12589,12589],"valid"],[[12590,12592],"disallowed"],[[12593,12593],"mapped",[4352]],[[12594,12594],"mapped",[4353]],[[12595,12595],"mapped",[4522]],[[12596,12596],"mapped",[4354]],[[12597,12597],"mapped",[4524]],[[12598,12598],"mapped",[4525]],[[12599,12599],"mapped",[4355]],[[12600,12600],"mapped",[4356]],[[12601,12601],"mapped",[4357]],[[12602,12602],"mapped",[4528]],[[12603,12603],"mapped",[4529]],[[12604,12604],"mapped",[4530]],[[12605,12605],"mapped",[4531]],[[12606,12606],"mapped",[4532]],[[12607,12607],"mapped",[4533]],[[12608,12608],"mapped",[4378]],[[12609,12609],"mapped",[4358]],[[12610,12610],"mapped",[4359]],[[12611,12611],"mapped",[4360]],[[12612,12612],"mapped",[4385]],[[12613,12613],"mapped",[4361]],[[12614,12614],"mapped",[4362]],[[12615,12615],"mapped",[4363]],[[12616,12616],"mapped",[4364]],[[12617,12617],"mapped",[4365]],[[12618,12618],"mapped",[4366]],[[12619,12619],"mapped",[4367]],[[12620,12620],"mapped",[4368]],[[12621,12621],"mapped",[4369]],[[12622,12622],"mapped",[4370]],[[12623,12623],"mapped",[4449]],[[12624,12624],"mapped",[4450]],[[12625,12625],"mapped",[4451]],[[12626,12626],"mapped",[4452]],[[12627,12627],"mapped",[4453]],[[12628,12628],"mapped",[4454]],[[12629,12629],"mapped",[4455]],[[12630,12630],"mapped",[4456]],[[12631,12631],"mapped",[4457]],[[12632,12632],"mapped",[4458]],[[12633,12633],"mapped",[4459]],[[12634,12634],"mapped",[4460]],[[12635,12635],"mapped",[4461]],[[12636,12636],"mapped",[4462]],[[12637,12637],"mapped",[4463]],[[12638,12638],"mapped",[4464]],[[12639,12639],"mapped",[4465]],[[12640,12640],"mapped",[4466]],[[12641,12641],"mapped",[4467]],[[12642,12642],"mapped",[4468]],[[12643,12643],"mapped",[4469]],[[12644,12644],"disallowed"],[[12645,12645],"mapped",[4372]],[[12646,12646],"mapped",[4373]],[[12647,12647],"mapped",[4551]],[[12648,12648],"mapped",[4552]],[[12649,12649],"mapped",[4556]],[[12650,12650],"mapped",[4558]],[[12651,12651],"mapped",[4563]],[[12652,12652],"mapped",[4567]],[[12653,12653],"mapped",[4569]],[[12654,12654],"mapped",[4380]],[[12655,12655],"mapped",[4573]],[[12656,12656],"mapped",[4575]],[[12657,12657],"mapped",[4381]],[[12658,12658],"mapped",[4382]],[[12659,12659],"mapped",[4384]],[[12660,12660],"mapped",[4386]],[[12661,12661],"mapped",[4387]],[[12662,12662],"mapped",[4391]],[[12663,12663],"mapped",[4393]],[[12664,12664],"mapped",[4395]],[[12665,12665],"mapped",[4396]],[[12666,12666],"mapped",[4397]],[[12667,12667],"mapped",[4398]],[[12668,12668],"mapped",[4399]],[[12669,12669],"mapped",[4402]],[[12670,12670],"mapped",[4406]],[[12671,12671],"mapped",[4416]],[[12672,12672],"mapped",[4423]],[[12673,12673],"mapped",[4428]],[[12674,12674],"mapped",[4593]],[[12675,12675],"mapped",[4594]],[[12676,12676],"mapped",[4439]],[[12677,12677],"mapped",[4440]],[[12678,12678],"mapped",[4441]],[[12679,12679],"mapped",[4484]],[[12680,12680],"mapped",[4485]],[[12681,12681],"mapped",[4488]],[[12682,12682],"mapped",[4497]],[[12683,12683],"mapped",[4498]],[[12684,12684],"mapped",[4500]],[[12685,12685],"mapped",[4510]],[[12686,12686],"mapped",[4513]],[[12687,12687],"disallowed"],[[12688,12689],"valid",[],"NV8"],[[12690,12690],"mapped",[19968]],[[12691,12691],"mapped",[20108]],[[12692,12692],"mapped",[19977]],[[12693,12693],"mapped",[22235]],[[12694,12694],"mapped",[19978]],[[12695,12695],"mapped",[20013]],[[12696,12696],"mapped",[19979]],[[12697,12697],"mapped",[30002]],[[12698,12698],"mapped",[20057]],[[12699,12699],"mapped",[19993]],[[12700,12700],"mapped",[19969]],[[12701,12701],"mapped",[22825]],[[12702,12702],"mapped",[22320]],[[12703,12703],"mapped",[20154]],[[12704,12727],"valid"],[[12728,12730],"valid"],[[12731,12735],"disallowed"],[[12736,12751],"valid",[],"NV8"],[[12752,12771],"valid",[],"NV8"],[[12772,12783],"disallowed"],[[12784,12799],"valid"],[[12800,12800],"disallowed_STD3_mapped",[40,4352,41]],[[12801,12801],"disallowed_STD3_mapped",[40,4354,41]],[[12802,12802],"disallowed_STD3_mapped",[40,4355,41]],[[12803,12803],"disallowed_STD3_mapped",[40,4357,41]],[[12804,12804],"disallowed_STD3_mapped",[40,4358,41]],[[12805,12805],"disallowed_STD3_mapped",[40,4359,41]],[[12806,12806],"disallowed_STD3_mapped",[40,4361,41]],[[12807,12807],"disallowed_STD3_mapped",[40,4363,41]],[[12808,12808],"disallowed_STD3_mapped",[40,4364,41]],[[12809,12809],"disallowed_STD3_mapped",[40,4366,41]],[[12810,12810],"disallowed_STD3_mapped",[40,4367,41]],[[12811,12811],"disallowed_STD3_mapped",[40,4368,41]],[[12812,12812],"disallowed_STD3_mapped",[40,4369,41]],[[12813,12813],"disallowed_STD3_mapped",[40,4370,41]],[[12814,12814],"disallowed_STD3_mapped",[40,44032,41]],[[12815,12815],"disallowed_STD3_mapped",[40,45208,41]],[[12816,12816],"disallowed_STD3_mapped",[40,45796,41]],[[12817,12817],"disallowed_STD3_mapped",[40,46972,41]],[[12818,12818],"disallowed_STD3_mapped",[40,47560,41]],[[12819,12819],"disallowed_STD3_mapped",[40,48148,41]],[[12820,12820],"disallowed_STD3_mapped",[40,49324,41]],[[12821,12821],"disallowed_STD3_mapped",[40,50500,41]],[[12822,12822],"disallowed_STD3_mapped",[40,51088,41]],[[12823,12823],"disallowed_STD3_mapped",[40,52264,41]],[[12824,12824],"disallowed_STD3_mapped",[40,52852,41]],[[12825,12825],"disallowed_STD3_mapped",[40,53440,41]],[[12826,12826],"disallowed_STD3_mapped",[40,54028,41]],[[12827,12827],"disallowed_STD3_mapped",[40,54616,41]],[[12828,12828],"disallowed_STD3_mapped",[40,51452,41]],[[12829,12829],"disallowed_STD3_mapped",[40,50724,51204,41]],[[12830,12830],"disallowed_STD3_mapped",[40,50724,54980,41]],[[12831,12831],"disallowed"],[[12832,12832],"disallowed_STD3_mapped",[40,19968,41]],[[12833,12833],"disallowed_STD3_mapped",[40,20108,41]],[[12834,12834],"disallowed_STD3_mapped",[40,19977,41]],[[12835,12835],"disallowed_STD3_mapped",[40,22235,41]],[[12836,12836],"disallowed_STD3_mapped",[40,20116,41]],[[12837,12837],"disallowed_STD3_mapped",[40,20845,41]],[[12838,12838],"disallowed_STD3_mapped",[40,19971,41]],[[12839,12839],"disallowed_STD3_mapped",[40,20843,41]],[[12840,12840],"disallowed_STD3_mapped",[40,20061,41]],[[12841,12841],"disallowed_STD3_mapped",[40,21313,41]],[[12842,12842],"disallowed_STD3_mapped",[40,26376,41]],[[12843,12843],"disallowed_STD3_mapped",[40,28779,41]],[[12844,12844],"disallowed_STD3_mapped",[40,27700,41]],[[12845,12845],"disallowed_STD3_mapped",[40,26408,41]],[[12846,12846],"disallowed_STD3_mapped",[40,37329,41]],[[12847,12847],"disallowed_STD3_mapped",[40,22303,41]],[[12848,12848],"disallowed_STD3_mapped",[40,26085,41]],[[12849,12849],"disallowed_STD3_mapped",[40,26666,41]],[[12850,12850],"disallowed_STD3_mapped",[40,26377,41]],[[12851,12851],"disallowed_STD3_mapped",[40,31038,41]],[[12852,12852],"disallowed_STD3_mapped",[40,21517,41]],[[12853,12853],"disallowed_STD3_mapped",[40,29305,41]],[[12854,12854],"disallowed_STD3_mapped",[40,36001,41]],[[12855,12855],"disallowed_STD3_mapped",[40,31069,41]],[[12856,12856],"disallowed_STD3_mapped",[40,21172,41]],[[12857,12857],"disallowed_STD3_mapped",[40,20195,41]],[[12858,12858],"disallowed_STD3_mapped",[40,21628,41]],[[12859,12859],"disallowed_STD3_mapped",[40,23398,41]],[[12860,12860],"disallowed_STD3_mapped",[40,30435,41]],[[12861,12861],"disallowed_STD3_mapped",[40,20225,41]],[[12862,12862],"disallowed_STD3_mapped",[40,36039,41]],[[12863,12863],"disallowed_STD3_mapped",[40,21332,41]],[[12864,12864],"disallowed_STD3_mapped",[40,31085,41]],[[12865,12865],"disallowed_STD3_mapped",[40,20241,41]],[[12866,12866],"disallowed_STD3_mapped",[40,33258,41]],[[12867,12867],"disallowed_STD3_mapped",[40,33267,41]],[[12868,12868],"mapped",[21839]],[[12869,12869],"mapped",[24188]],[[12870,12870],"mapped",[25991]],[[12871,12871],"mapped",[31631]],[[12872,12879],"valid",[],"NV8"],[[12880,12880],"mapped",[112,116,101]],[[12881,12881],"mapped",[50,49]],[[12882,12882],"mapped",[50,50]],[[12883,12883],"mapped",[50,51]],[[12884,12884],"mapped",[50,52]],[[12885,12885],"mapped",[50,53]],[[12886,12886],"mapped",[50,54]],[[12887,12887],"mapped",[50,55]],[[12888,12888],"mapped",[50,56]],[[12889,12889],"mapped",[50,57]],[[12890,12890],"mapped",[51,48]],[[12891,12891],"mapped",[51,49]],[[12892,12892],"mapped",[51,50]],[[12893,12893],"mapped",[51,51]],[[12894,12894],"mapped",[51,52]],[[12895,12895],"mapped",[51,53]],[[12896,12896],"mapped",[4352]],[[12897,12897],"mapped",[4354]],[[12898,12898],"mapped",[4355]],[[12899,12899],"mapped",[4357]],[[12900,12900],"mapped",[4358]],[[12901,12901],"mapped",[4359]],[[12902,12902],"mapped",[4361]],[[12903,12903],"mapped",[4363]],[[12904,12904],"mapped",[4364]],[[12905,12905],"mapped",[4366]],[[12906,12906],"mapped",[4367]],[[12907,12907],"mapped",[4368]],[[12908,12908],"mapped",[4369]],[[12909,12909],"mapped",[4370]],[[12910,12910],"mapped",[44032]],[[12911,12911],"mapped",[45208]],[[12912,12912],"mapped",[45796]],[[12913,12913],"mapped",[46972]],[[12914,12914],"mapped",[47560]],[[12915,12915],"mapped",[48148]],[[12916,12916],"mapped",[49324]],[[12917,12917],"mapped",[50500]],[[12918,12918],"mapped",[51088]],[[12919,12919],"mapped",[52264]],[[12920,12920],"mapped",[52852]],[[12921,12921],"mapped",[53440]],[[12922,12922],"mapped",[54028]],[[12923,12923],"mapped",[54616]],[[12924,12924],"mapped",[52280,44256]],[[12925,12925],"mapped",[51452,51032]],[[12926,12926],"mapped",[50864]],[[12927,12927],"valid",[],"NV8"],[[12928,12928],"mapped",[19968]],[[12929,12929],"mapped",[20108]],[[12930,12930],"mapped",[19977]],[[12931,12931],"mapped",[22235]],[[12932,12932],"mapped",[20116]],[[12933,12933],"mapped",[20845]],[[12934,12934],"mapped",[19971]],[[12935,12935],"mapped",[20843]],[[12936,12936],"mapped",[20061]],[[12937,12937],"mapped",[21313]],[[12938,12938],"mapped",[26376]],[[12939,12939],"mapped",[28779]],[[12940,12940],"mapped",[27700]],[[12941,12941],"mapped",[26408]],[[12942,12942],"mapped",[37329]],[[12943,12943],"mapped",[22303]],[[12944,12944],"mapped",[26085]],[[12945,12945],"mapped",[26666]],[[12946,12946],"mapped",[26377]],[[12947,12947],"mapped",[31038]],[[12948,12948],"mapped",[21517]],[[12949,12949],"mapped",[29305]],[[12950,12950],"mapped",[36001]],[[12951,12951],"mapped",[31069]],[[12952,12952],"mapped",[21172]],[[12953,12953],"mapped",[31192]],[[12954,12954],"mapped",[30007]],[[12955,12955],"mapped",[22899]],[[12956,12956],"mapped",[36969]],[[12957,12957],"mapped",[20778]],[[12958,12958],"mapped",[21360]],[[12959,12959],"mapped",[27880]],[[12960,12960],"mapped",[38917]],[[12961,12961],"mapped",[20241]],[[12962,12962],"mapped",[20889]],[[12963,12963],"mapped",[27491]],[[12964,12964],"mapped",[19978]],[[12965,12965],"mapped",[20013]],[[12966,12966],"mapped",[19979]],[[12967,12967],"mapped",[24038]],[[12968,12968],"mapped",[21491]],[[12969,12969],"mapped",[21307]],[[12970,12970],"mapped",[23447]],[[12971,12971],"mapped",[23398]],[[12972,12972],"mapped",[30435]],[[12973,12973],"mapped",[20225]],[[12974,12974],"mapped",[36039]],[[12975,12975],"mapped",[21332]],[[12976,12976],"mapped",[22812]],[[12977,12977],"mapped",[51,54]],[[12978,12978],"mapped",[51,55]],[[12979,12979],"mapped",[51,56]],[[12980,12980],"mapped",[51,57]],[[12981,12981],"mapped",[52,48]],[[12982,12982],"mapped",[52,49]],[[12983,12983],"mapped",[52,50]],[[12984,12984],"mapped",[52,51]],[[12985,12985],"mapped",[52,52]],[[12986,12986],"mapped",[52,53]],[[12987,12987],"mapped",[52,54]],[[12988,12988],"mapped",[52,55]],[[12989,12989],"mapped",[52,56]],[[12990,12990],"mapped",[52,57]],[[12991,12991],"mapped",[53,48]],[[12992,12992],"mapped",[49,26376]],[[12993,12993],"mapped",[50,26376]],[[12994,12994],"mapped",[51,26376]],[[12995,12995],"mapped",[52,26376]],[[12996,12996],"mapped",[53,26376]],[[12997,12997],"mapped",[54,26376]],[[12998,12998],"mapped",[55,26376]],[[12999,12999],"mapped",[56,26376]],[[13000,13000],"mapped",[57,26376]],[[13001,13001],"mapped",[49,48,26376]],[[13002,13002],"mapped",[49,49,26376]],[[13003,13003],"mapped",[49,50,26376]],[[13004,13004],"mapped",[104,103]],[[13005,13005],"mapped",[101,114,103]],[[13006,13006],"mapped",[101,118]],[[13007,13007],"mapped",[108,116,100]],[[13008,13008],"mapped",[12450]],[[13009,13009],"mapped",[12452]],[[13010,13010],"mapped",[12454]],[[13011,13011],"mapped",[12456]],[[13012,13012],"mapped",[12458]],[[13013,13013],"mapped",[12459]],[[13014,13014],"mapped",[12461]],[[13015,13015],"mapped",[12463]],[[13016,13016],"mapped",[12465]],[[13017,13017],"mapped",[12467]],[[13018,13018],"mapped",[12469]],[[13019,13019],"mapped",[12471]],[[13020,13020],"mapped",[12473]],[[13021,13021],"mapped",[12475]],[[13022,13022],"mapped",[12477]],[[13023,13023],"mapped",[12479]],[[13024,13024],"mapped",[12481]],[[13025,13025],"mapped",[12484]],[[13026,13026],"mapped",[12486]],[[13027,13027],"mapped",[12488]],[[13028,13028],"mapped",[12490]],[[13029,13029],"mapped",[12491]],[[13030,13030],"mapped",[12492]],[[13031,13031],"mapped",[12493]],[[13032,13032],"mapped",[12494]],[[13033,13033],"mapped",[12495]],[[13034,13034],"mapped",[12498]],[[13035,13035],"mapped",[12501]],[[13036,13036],"mapped",[12504]],[[13037,13037],"mapped",[12507]],[[13038,13038],"mapped",[12510]],[[13039,13039],"mapped",[12511]],[[13040,13040],"mapped",[12512]],[[13041,13041],"mapped",[12513]],[[13042,13042],"mapped",[12514]],[[13043,13043],"mapped",[12516]],[[13044,13044],"mapped",[12518]],[[13045,13045],"mapped",[12520]],[[13046,13046],"mapped",[12521]],[[13047,13047],"mapped",[12522]],[[13048,13048],"mapped",[12523]],[[13049,13049],"mapped",[12524]],[[13050,13050],"mapped",[12525]],[[13051,13051],"mapped",[12527]],[[13052,13052],"mapped",[12528]],[[13053,13053],"mapped",[12529]],[[13054,13054],"mapped",[12530]],[[13055,13055],"disallowed"],[[13056,13056],"mapped",[12450,12497,12540,12488]],[[13057,13057],"mapped",[12450,12523,12501,12449]],[[13058,13058],"mapped",[12450,12531,12506,12450]],[[13059,13059],"mapped",[12450,12540,12523]],[[13060,13060],"mapped",[12452,12491,12531,12464]],[[13061,13061],"mapped",[12452,12531,12481]],[[13062,13062],"mapped",[12454,12457,12531]],[[13063,13063],"mapped",[12456,12473,12463,12540,12489]],[[13064,13064],"mapped",[12456,12540,12459,12540]],[[13065,13065],"mapped",[12458,12531,12473]],[[13066,13066],"mapped",[12458,12540,12512]],[[13067,13067],"mapped",[12459,12452,12522]],[[13068,13068],"mapped",[12459,12521,12483,12488]],[[13069,13069],"mapped",[12459,12525,12522,12540]],[[13070,13070],"mapped",[12460,12525,12531]],[[13071,13071],"mapped",[12460,12531,12510]],[[13072,13072],"mapped",[12462,12460]],[[13073,13073],"mapped",[12462,12491,12540]],[[13074,13074],"mapped",[12461,12517,12522,12540]],[[13075,13075],"mapped",[12462,12523,12480,12540]],[[13076,13076],"mapped",[12461,12525]],[[13077,13077],"mapped",[12461,12525,12464,12521,12512]],[[13078,13078],"mapped",[12461,12525,12513,12540,12488,12523]],[[13079,13079],"mapped",[12461,12525,12527,12483,12488]],[[13080,13080],"mapped",[12464,12521,12512]],[[13081,13081],"mapped",[12464,12521,12512,12488,12531]],[[13082,13082],"mapped",[12463,12523,12476,12452,12525]],[[13083,13083],"mapped",[12463,12525,12540,12493]],[[13084,13084],"mapped",[12465,12540,12473]],[[13085,13085],"mapped",[12467,12523,12490]],[[13086,13086],"mapped",[12467,12540,12509]],[[13087,13087],"mapped",[12469,12452,12463,12523]],[[13088,13088],"mapped",[12469,12531,12481,12540,12512]],[[13089,13089],"mapped",[12471,12522,12531,12464]],[[13090,13090],"mapped",[12475,12531,12481]],[[13091,13091],"mapped",[12475,12531,12488]],[[13092,13092],"mapped",[12480,12540,12473]],[[13093,13093],"mapped",[12487,12471]],[[13094,13094],"mapped",[12489,12523]],[[13095,13095],"mapped",[12488,12531]],[[13096,13096],"mapped",[12490,12494]],[[13097,13097],"mapped",[12494,12483,12488]],[[13098,13098],"mapped",[12495,12452,12484]],[[13099,13099],"mapped",[12497,12540,12475,12531,12488]],[[13100,13100],"mapped",[12497,12540,12484]],[[13101,13101],"mapped",[12496,12540,12524,12523]],[[13102,13102],"mapped",[12500,12450,12473,12488,12523]],[[13103,13103],"mapped",[12500,12463,12523]],[[13104,13104],"mapped",[12500,12467]],[[13105,13105],"mapped",[12499,12523]],[[13106,13106],"mapped",[12501,12449,12521,12483,12489]],[[13107,13107],"mapped",[12501,12451,12540,12488]],[[13108,13108],"mapped",[12502,12483,12471,12455,12523]],[[13109,13109],"mapped",[12501,12521,12531]],[[13110,13110],"mapped",[12504,12463,12479,12540,12523]],[[13111,13111],"mapped",[12506,12477]],[[13112,13112],"mapped",[12506,12491,12498]],[[13113,13113],"mapped",[12504,12523,12484]],[[13114,13114],"mapped",[12506,12531,12473]],[[13115,13115],"mapped",[12506,12540,12472]],[[13116,13116],"mapped",[12505,12540,12479]],[[13117,13117],"mapped",[12509,12452,12531,12488]],[[13118,13118],"mapped",[12508,12523,12488]],[[13119,13119],"mapped",[12507,12531]],[[13120,13120],"mapped",[12509,12531,12489]],[[13121,13121],"mapped",[12507,12540,12523]],[[13122,13122],"mapped",[12507,12540,12531]],[[13123,13123],"mapped",[12510,12452,12463,12525]],[[13124,13124],"mapped",[12510,12452,12523]],[[13125,13125],"mapped",[12510,12483,12495]],[[13126,13126],"mapped",[12510,12523,12463]],[[13127,13127],"mapped",[12510,12531,12471,12519,12531]],[[13128,13128],"mapped",[12511,12463,12525,12531]],[[13129,13129],"mapped",[12511,12522]],[[13130,13130],"mapped",[12511,12522,12496,12540,12523]],[[13131,13131],"mapped",[12513,12460]],[[13132,13132],"mapped",[12513,12460,12488,12531]],[[13133,13133],"mapped",[12513,12540,12488,12523]],[[13134,13134],"mapped",[12516,12540,12489]],[[13135,13135],"mapped",[12516,12540,12523]],[[13136,13136],"mapped",[12518,12450,12531]],[[13137,13137],"mapped",[12522,12483,12488,12523]],[[13138,13138],"mapped",[12522,12521]],[[13139,13139],"mapped",[12523,12500,12540]],[[13140,13140],"mapped",[12523,12540,12502,12523]],[[13141,13141],"mapped",[12524,12512]],[[13142,13142],"mapped",[12524,12531,12488,12466,12531]],[[13143,13143],"mapped",[12527,12483,12488]],[[13144,13144],"mapped",[48,28857]],[[13145,13145],"mapped",[49,28857]],[[13146,13146],"mapped",[50,28857]],[[13147,13147],"mapped",[51,28857]],[[13148,13148],"mapped",[52,28857]],[[13149,13149],"mapped",[53,28857]],[[13150,13150],"mapped",[54,28857]],[[13151,13151],"mapped",[55,28857]],[[13152,13152],"mapped",[56,28857]],[[13153,13153],"mapped",[57,28857]],[[13154,13154],"mapped",[49,48,28857]],[[13155,13155],"mapped",[49,49,28857]],[[13156,13156],"mapped",[49,50,28857]],[[13157,13157],"mapped",[49,51,28857]],[[13158,13158],"mapped",[49,52,28857]],[[13159,13159],"mapped",[49,53,28857]],[[13160,13160],"mapped",[49,54,28857]],[[13161,13161],"mapped",[49,55,28857]],[[13162,13162],"mapped",[49,56,28857]],[[13163,13163],"mapped",[49,57,28857]],[[13164,13164],"mapped",[50,48,28857]],[[13165,13165],"mapped",[50,49,28857]],[[13166,13166],"mapped",[50,50,28857]],[[13167,13167],"mapped",[50,51,28857]],[[13168,13168],"mapped",[50,52,28857]],[[13169,13169],"mapped",[104,112,97]],[[13170,13170],"mapped",[100,97]],[[13171,13171],"mapped",[97,117]],[[13172,13172],"mapped",[98,97,114]],[[13173,13173],"mapped",[111,118]],[[13174,13174],"mapped",[112,99]],[[13175,13175],"mapped",[100,109]],[[13176,13176],"mapped",[100,109,50]],[[13177,13177],"mapped",[100,109,51]],[[13178,13178],"mapped",[105,117]],[[13179,13179],"mapped",[24179,25104]],[[13180,13180],"mapped",[26157,21644]],[[13181,13181],"mapped",[22823,27491]],[[13182,13182],"mapped",[26126,27835]],[[13183,13183],"mapped",[26666,24335,20250,31038]],[[13184,13184],"mapped",[112,97]],[[13185,13185],"mapped",[110,97]],[[13186,13186],"mapped",[956,97]],[[13187,13187],"mapped",[109,97]],[[13188,13188],"mapped",[107,97]],[[13189,13189],"mapped",[107,98]],[[13190,13190],"mapped",[109,98]],[[13191,13191],"mapped",[103,98]],[[13192,13192],"mapped",[99,97,108]],[[13193,13193],"mapped",[107,99,97,108]],[[13194,13194],"mapped",[112,102]],[[13195,13195],"mapped",[110,102]],[[13196,13196],"mapped",[956,102]],[[13197,13197],"mapped",[956,103]],[[13198,13198],"mapped",[109,103]],[[13199,13199],"mapped",[107,103]],[[13200,13200],"mapped",[104,122]],[[13201,13201],"mapped",[107,104,122]],[[13202,13202],"mapped",[109,104,122]],[[13203,13203],"mapped",[103,104,122]],[[13204,13204],"mapped",[116,104,122]],[[13205,13205],"mapped",[956,108]],[[13206,13206],"mapped",[109,108]],[[13207,13207],"mapped",[100,108]],[[13208,13208],"mapped",[107,108]],[[13209,13209],"mapped",[102,109]],[[13210,13210],"mapped",[110,109]],[[13211,13211],"mapped",[956,109]],[[13212,13212],"mapped",[109,109]],[[13213,13213],"mapped",[99,109]],[[13214,13214],"mapped",[107,109]],[[13215,13215],"mapped",[109,109,50]],[[13216,13216],"mapped",[99,109,50]],[[13217,13217],"mapped",[109,50]],[[13218,13218],"mapped",[107,109,50]],[[13219,13219],"mapped",[109,109,51]],[[13220,13220],"mapped",[99,109,51]],[[13221,13221],"mapped",[109,51]],[[13222,13222],"mapped",[107,109,51]],[[13223,13223],"mapped",[109,8725,115]],[[13224,13224],"mapped",[109,8725,115,50]],[[13225,13225],"mapped",[112,97]],[[13226,13226],"mapped",[107,112,97]],[[13227,13227],"mapped",[109,112,97]],[[13228,13228],"mapped",[103,112,97]],[[13229,13229],"mapped",[114,97,100]],[[13230,13230],"mapped",[114,97,100,8725,115]],[[13231,13231],"mapped",[114,97,100,8725,115,50]],[[13232,13232],"mapped",[112,115]],[[13233,13233],"mapped",[110,115]],[[13234,13234],"mapped",[956,115]],[[13235,13235],"mapped",[109,115]],[[13236,13236],"mapped",[112,118]],[[13237,13237],"mapped",[110,118]],[[13238,13238],"mapped",[956,118]],[[13239,13239],"mapped",[109,118]],[[13240,13240],"mapped",[107,118]],[[13241,13241],"mapped",[109,118]],[[13242,13242],"mapped",[112,119]],[[13243,13243],"mapped",[110,119]],[[13244,13244],"mapped",[956,119]],[[13245,13245],"mapped",[109,119]],[[13246,13246],"mapped",[107,119]],[[13247,13247],"mapped",[109,119]],[[13248,13248],"mapped",[107,969]],[[13249,13249],"mapped",[109,969]],[[13250,13250],"disallowed"],[[13251,13251],"mapped",[98,113]],[[13252,13252],"mapped",[99,99]],[[13253,13253],"mapped",[99,100]],[[13254,13254],"mapped",[99,8725,107,103]],[[13255,13255],"disallowed"],[[13256,13256],"mapped",[100,98]],[[13257,13257],"mapped",[103,121]],[[13258,13258],"mapped",[104,97]],[[13259,13259],"mapped",[104,112]],[[13260,13260],"mapped",[105,110]],[[13261,13261],"mapped",[107,107]],[[13262,13262],"mapped",[107,109]],[[13263,13263],"mapped",[107,116]],[[13264,13264],"mapped",[108,109]],[[13265,13265],"mapped",[108,110]],[[13266,13266],"mapped",[108,111,103]],[[13267,13267],"mapped",[108,120]],[[13268,13268],"mapped",[109,98]],[[13269,13269],"mapped",[109,105,108]],[[13270,13270],"mapped",[109,111,108]],[[13271,13271],"mapped",[112,104]],[[13272,13272],"disallowed"],[[13273,13273],"mapped",[112,112,109]],[[13274,13274],"mapped",[112,114]],[[13275,13275],"mapped",[115,114]],[[13276,13276],"mapped",[115,118]],[[13277,13277],"mapped",[119,98]],[[13278,13278],"mapped",[118,8725,109]],[[13279,13279],"mapped",[97,8725,109]],[[13280,13280],"mapped",[49,26085]],[[13281,13281],"mapped",[50,26085]],[[13282,13282],"mapped",[51,26085]],[[13283,13283],"mapped",[52,26085]],[[13284,13284],"mapped",[53,26085]],[[13285,13285],"mapped",[54,26085]],[[13286,13286],"mapped",[55,26085]],[[13287,13287],"mapped",[56,26085]],[[13288,13288],"mapped",[57,26085]],[[13289,13289],"mapped",[49,48,26085]],[[13290,13290],"mapped",[49,49,26085]],[[13291,13291],"mapped",[49,50,26085]],[[13292,13292],"mapped",[49,51,26085]],[[13293,13293],"mapped",[49,52,26085]],[[13294,13294],"mapped",[49,53,26085]],[[13295,13295],"mapped",[49,54,26085]],[[13296,13296],"mapped",[49,55,26085]],[[13297,13297],"mapped",[49,56,26085]],[[13298,13298],"mapped",[49,57,26085]],[[13299,13299],"mapped",[50,48,26085]],[[13300,13300],"mapped",[50,49,26085]],[[13301,13301],"mapped",[50,50,26085]],[[13302,13302],"mapped",[50,51,26085]],[[13303,13303],"mapped",[50,52,26085]],[[13304,13304],"mapped",[50,53,26085]],[[13305,13305],"mapped",[50,54,26085]],[[13306,13306],"mapped",[50,55,26085]],[[13307,13307],"mapped",[50,56,26085]],[[13308,13308],"mapped",[50,57,26085]],[[13309,13309],"mapped",[51,48,26085]],[[13310,13310],"mapped",[51,49,26085]],[[13311,13311],"mapped",[103,97,108]],[[13312,19893],"valid"],[[19894,19903],"disallowed"],[[19904,19967],"valid",[],"NV8"],[[19968,40869],"valid"],[[40870,40891],"valid"],[[40892,40899],"valid"],[[40900,40907],"valid"],[[40908,40908],"valid"],[[40909,40917],"valid"],[[40918,40959],"disallowed"],[[40960,42124],"valid"],[[42125,42127],"disallowed"],[[42128,42145],"valid",[],"NV8"],[[42146,42147],"valid",[],"NV8"],[[42148,42163],"valid",[],"NV8"],[[42164,42164],"valid",[],"NV8"],[[42165,42176],"valid",[],"NV8"],[[42177,42177],"valid",[],"NV8"],[[42178,42180],"valid",[],"NV8"],[[42181,42181],"valid",[],"NV8"],[[42182,42182],"valid",[],"NV8"],[[42183,42191],"disallowed"],[[42192,42237],"valid"],[[42238,42239],"valid",[],"NV8"],[[42240,42508],"valid"],[[42509,42511],"valid",[],"NV8"],[[42512,42539],"valid"],[[42540,42559],"disallowed"],[[42560,42560],"mapped",[42561]],[[42561,42561],"valid"],[[42562,42562],"mapped",[42563]],[[42563,42563],"valid"],[[42564,42564],"mapped",[42565]],[[42565,42565],"valid"],[[42566,42566],"mapped",[42567]],[[42567,42567],"valid"],[[42568,42568],"mapped",[42569]],[[42569,42569],"valid"],[[42570,42570],"mapped",[42571]],[[42571,42571],"valid"],[[42572,42572],"mapped",[42573]],[[42573,42573],"valid"],[[42574,42574],"mapped",[42575]],[[42575,42575],"valid"],[[42576,42576],"mapped",[42577]],[[42577,42577],"valid"],[[42578,42578],"mapped",[42579]],[[42579,42579],"valid"],[[42580,42580],"mapped",[42581]],[[42581,42581],"valid"],[[42582,42582],"mapped",[42583]],[[42583,42583],"valid"],[[42584,42584],"mapped",[42585]],[[42585,42585],"valid"],[[42586,42586],"mapped",[42587]],[[42587,42587],"valid"],[[42588,42588],"mapped",[42589]],[[42589,42589],"valid"],[[42590,42590],"mapped",[42591]],[[42591,42591],"valid"],[[42592,42592],"mapped",[42593]],[[42593,42593],"valid"],[[42594,42594],"mapped",[42595]],[[42595,42595],"valid"],[[42596,42596],"mapped",[42597]],[[42597,42597],"valid"],[[42598,42598],"mapped",[42599]],[[42599,42599],"valid"],[[42600,42600],"mapped",[42601]],[[42601,42601],"valid"],[[42602,42602],"mapped",[42603]],[[42603,42603],"valid"],[[42604,42604],"mapped",[42605]],[[42605,42607],"valid"],[[42608,42611],"valid",[],"NV8"],[[42612,42619],"valid"],[[42620,42621],"valid"],[[42622,42622],"valid",[],"NV8"],[[42623,42623],"valid"],[[42624,42624],"mapped",[42625]],[[42625,42625],"valid"],[[42626,42626],"mapped",[42627]],[[42627,42627],"valid"],[[42628,42628],"mapped",[42629]],[[42629,42629],"valid"],[[42630,42630],"mapped",[42631]],[[42631,42631],"valid"],[[42632,42632],"mapped",[42633]],[[42633,42633],"valid"],[[42634,42634],"mapped",[42635]],[[42635,42635],"valid"],[[42636,42636],"mapped",[42637]],[[42637,42637],"valid"],[[42638,42638],"mapped",[42639]],[[42639,42639],"valid"],[[42640,42640],"mapped",[42641]],[[42641,42641],"valid"],[[42642,42642],"mapped",[42643]],[[42643,42643],"valid"],[[42644,42644],"mapped",[42645]],[[42645,42645],"valid"],[[42646,42646],"mapped",[42647]],[[42647,42647],"valid"],[[42648,42648],"mapped",[42649]],[[42649,42649],"valid"],[[42650,42650],"mapped",[42651]],[[42651,42651],"valid"],[[42652,42652],"mapped",[1098]],[[42653,42653],"mapped",[1100]],[[42654,42654],"valid"],[[42655,42655],"valid"],[[42656,42725],"valid"],[[42726,42735],"valid",[],"NV8"],[[42736,42737],"valid"],[[42738,42743],"valid",[],"NV8"],[[42744,42751],"disallowed"],[[42752,42774],"valid",[],"NV8"],[[42775,42778],"valid"],[[42779,42783],"valid"],[[42784,42785],"valid",[],"NV8"],[[42786,42786],"mapped",[42787]],[[42787,42787],"valid"],[[42788,42788],"mapped",[42789]],[[42789,42789],"valid"],[[42790,42790],"mapped",[42791]],[[42791,42791],"valid"],[[42792,42792],"mapped",[42793]],[[42793,42793],"valid"],[[42794,42794],"mapped",[42795]],[[42795,42795],"valid"],[[42796,42796],"mapped",[42797]],[[42797,42797],"valid"],[[42798,42798],"mapped",[42799]],[[42799,42801],"valid"],[[42802,42802],"mapped",[42803]],[[42803,42803],"valid"],[[42804,42804],"mapped",[42805]],[[42805,42805],"valid"],[[42806,42806],"mapped",[42807]],[[42807,42807],"valid"],[[42808,42808],"mapped",[42809]],[[42809,42809],"valid"],[[42810,42810],"mapped",[42811]],[[42811,42811],"valid"],[[42812,42812],"mapped",[42813]],[[42813,42813],"valid"],[[42814,42814],"mapped",[42815]],[[42815,42815],"valid"],[[42816,42816],"mapped",[42817]],[[42817,42817],"valid"],[[42818,42818],"mapped",[42819]],[[42819,42819],"valid"],[[42820,42820],"mapped",[42821]],[[42821,42821],"valid"],[[42822,42822],"mapped",[42823]],[[42823,42823],"valid"],[[42824,42824],"mapped",[42825]],[[42825,42825],"valid"],[[42826,42826],"mapped",[42827]],[[42827,42827],"valid"],[[42828,42828],"mapped",[42829]],[[42829,42829],"valid"],[[42830,42830],"mapped",[42831]],[[42831,42831],"valid"],[[42832,42832],"mapped",[42833]],[[42833,42833],"valid"],[[42834,42834],"mapped",[42835]],[[42835,42835],"valid"],[[42836,42836],"mapped",[42837]],[[42837,42837],"valid"],[[42838,42838],"mapped",[42839]],[[42839,42839],"valid"],[[42840,42840],"mapped",[42841]],[[42841,42841],"valid"],[[42842,42842],"mapped",[42843]],[[42843,42843],"valid"],[[42844,42844],"mapped",[42845]],[[42845,42845],"valid"],[[42846,42846],"mapped",[42847]],[[42847,42847],"valid"],[[42848,42848],"mapped",[42849]],[[42849,42849],"valid"],[[42850,42850],"mapped",[42851]],[[42851,42851],"valid"],[[42852,42852],"mapped",[42853]],[[42853,42853],"valid"],[[42854,42854],"mapped",[42855]],[[42855,42855],"valid"],[[42856,42856],"mapped",[42857]],[[42857,42857],"valid"],[[42858,42858],"mapped",[42859]],[[42859,42859],"valid"],[[42860,42860],"mapped",[42861]],[[42861,42861],"valid"],[[42862,42862],"mapped",[42863]],[[42863,42863],"valid"],[[42864,42864],"mapped",[42863]],[[42865,42872],"valid"],[[42873,42873],"mapped",[42874]],[[42874,42874],"valid"],[[42875,42875],"mapped",[42876]],[[42876,42876],"valid"],[[42877,42877],"mapped",[7545]],[[42878,42878],"mapped",[42879]],[[42879,42879],"valid"],[[42880,42880],"mapped",[42881]],[[42881,42881],"valid"],[[42882,42882],"mapped",[42883]],[[42883,42883],"valid"],[[42884,42884],"mapped",[42885]],[[42885,42885],"valid"],[[42886,42886],"mapped",[42887]],[[42887,42888],"valid"],[[42889,42890],"valid",[],"NV8"],[[42891,42891],"mapped",[42892]],[[42892,42892],"valid"],[[42893,42893],"mapped",[613]],[[42894,42894],"valid"],[[42895,42895],"valid"],[[42896,42896],"mapped",[42897]],[[42897,42897],"valid"],[[42898,42898],"mapped",[42899]],[[42899,42899],"valid"],[[42900,42901],"valid"],[[42902,42902],"mapped",[42903]],[[42903,42903],"valid"],[[42904,42904],"mapped",[42905]],[[42905,42905],"valid"],[[42906,42906],"mapped",[42907]],[[42907,42907],"valid"],[[42908,42908],"mapped",[42909]],[[42909,42909],"valid"],[[42910,42910],"mapped",[42911]],[[42911,42911],"valid"],[[42912,42912],"mapped",[42913]],[[42913,42913],"valid"],[[42914,42914],"mapped",[42915]],[[42915,42915],"valid"],[[42916,42916],"mapped",[42917]],[[42917,42917],"valid"],[[42918,42918],"mapped",[42919]],[[42919,42919],"valid"],[[42920,42920],"mapped",[42921]],[[42921,42921],"valid"],[[42922,42922],"mapped",[614]],[[42923,42923],"mapped",[604]],[[42924,42924],"mapped",[609]],[[42925,42925],"mapped",[620]],[[42926,42927],"disallowed"],[[42928,42928],"mapped",[670]],[[42929,42929],"mapped",[647]],[[42930,42930],"mapped",[669]],[[42931,42931],"mapped",[43859]],[[42932,42932],"mapped",[42933]],[[42933,42933],"valid"],[[42934,42934],"mapped",[42935]],[[42935,42935],"valid"],[[42936,42998],"disallowed"],[[42999,42999],"valid"],[[43000,43000],"mapped",[295]],[[43001,43001],"mapped",[339]],[[43002,43002],"valid"],[[43003,43007],"valid"],[[43008,43047],"valid"],[[43048,43051],"valid",[],"NV8"],[[43052,43055],"disallowed"],[[43056,43065],"valid",[],"NV8"],[[43066,43071],"disallowed"],[[43072,43123],"valid"],[[43124,43127],"valid",[],"NV8"],[[43128,43135],"disallowed"],[[43136,43204],"valid"],[[43205,43213],"disallowed"],[[43214,43215],"valid",[],"NV8"],[[43216,43225],"valid"],[[43226,43231],"disallowed"],[[43232,43255],"valid"],[[43256,43258],"valid",[],"NV8"],[[43259,43259],"valid"],[[43260,43260],"valid",[],"NV8"],[[43261,43261],"valid"],[[43262,43263],"disallowed"],[[43264,43309],"valid"],[[43310,43311],"valid",[],"NV8"],[[43312,43347],"valid"],[[43348,43358],"disallowed"],[[43359,43359],"valid",[],"NV8"],[[43360,43388],"valid",[],"NV8"],[[43389,43391],"disallowed"],[[43392,43456],"valid"],[[43457,43469],"valid",[],"NV8"],[[43470,43470],"disallowed"],[[43471,43481],"valid"],[[43482,43485],"disallowed"],[[43486,43487],"valid",[],"NV8"],[[43488,43518],"valid"],[[43519,43519],"disallowed"],[[43520,43574],"valid"],[[43575,43583],"disallowed"],[[43584,43597],"valid"],[[43598,43599],"disallowed"],[[43600,43609],"valid"],[[43610,43611],"disallowed"],[[43612,43615],"valid",[],"NV8"],[[43616,43638],"valid"],[[43639,43641],"valid",[],"NV8"],[[43642,43643],"valid"],[[43644,43647],"valid"],[[43648,43714],"valid"],[[43715,43738],"disallowed"],[[43739,43741],"valid"],[[43742,43743],"valid",[],"NV8"],[[43744,43759],"valid"],[[43760,43761],"valid",[],"NV8"],[[43762,43766],"valid"],[[43767,43776],"disallowed"],[[43777,43782],"valid"],[[43783,43784],"disallowed"],[[43785,43790],"valid"],[[43791,43792],"disallowed"],[[43793,43798],"valid"],[[43799,43807],"disallowed"],[[43808,43814],"valid"],[[43815,43815],"disallowed"],[[43816,43822],"valid"],[[43823,43823],"disallowed"],[[43824,43866],"valid"],[[43867,43867],"valid",[],"NV8"],[[43868,43868],"mapped",[42791]],[[43869,43869],"mapped",[43831]],[[43870,43870],"mapped",[619]],[[43871,43871],"mapped",[43858]],[[43872,43875],"valid"],[[43876,43877],"valid"],[[43878,43887],"disallowed"],[[43888,43888],"mapped",[5024]],[[43889,43889],"mapped",[5025]],[[43890,43890],"mapped",[5026]],[[43891,43891],"mapped",[5027]],[[43892,43892],"mapped",[5028]],[[43893,43893],"mapped",[5029]],[[43894,43894],"mapped",[5030]],[[43895,43895],"mapped",[5031]],[[43896,43896],"mapped",[5032]],[[43897,43897],"mapped",[5033]],[[43898,43898],"mapped",[5034]],[[43899,43899],"mapped",[5035]],[[43900,43900],"mapped",[5036]],[[43901,43901],"mapped",[5037]],[[43902,43902],"mapped",[5038]],[[43903,43903],"mapped",[5039]],[[43904,43904],"mapped",[5040]],[[43905,43905],"mapped",[5041]],[[43906,43906],"mapped",[5042]],[[43907,43907],"mapped",[5043]],[[43908,43908],"mapped",[5044]],[[43909,43909],"mapped",[5045]],[[43910,43910],"mapped",[5046]],[[43911,43911],"mapped",[5047]],[[43912,43912],"mapped",[5048]],[[43913,43913],"mapped",[5049]],[[43914,43914],"mapped",[5050]],[[43915,43915],"mapped",[5051]],[[43916,43916],"mapped",[5052]],[[43917,43917],"mapped",[5053]],[[43918,43918],"mapped",[5054]],[[43919,43919],"mapped",[5055]],[[43920,43920],"mapped",[5056]],[[43921,43921],"mapped",[5057]],[[43922,43922],"mapped",[5058]],[[43923,43923],"mapped",[5059]],[[43924,43924],"mapped",[5060]],[[43925,43925],"mapped",[5061]],[[43926,43926],"mapped",[5062]],[[43927,43927],"mapped",[5063]],[[43928,43928],"mapped",[5064]],[[43929,43929],"mapped",[5065]],[[43930,43930],"mapped",[5066]],[[43931,43931],"mapped",[5067]],[[43932,43932],"mapped",[5068]],[[43933,43933],"mapped",[5069]],[[43934,43934],"mapped",[5070]],[[43935,43935],"mapped",[5071]],[[43936,43936],"mapped",[5072]],[[43937,43937],"mapped",[5073]],[[43938,43938],"mapped",[5074]],[[43939,43939],"mapped",[5075]],[[43940,43940],"mapped",[5076]],[[43941,43941],"mapped",[5077]],[[43942,43942],"mapped",[5078]],[[43943,43943],"mapped",[5079]],[[43944,43944],"mapped",[5080]],[[43945,43945],"mapped",[5081]],[[43946,43946],"mapped",[5082]],[[43947,43947],"mapped",[5083]],[[43948,43948],"mapped",[5084]],[[43949,43949],"mapped",[5085]],[[43950,43950],"mapped",[5086]],[[43951,43951],"mapped",[5087]],[[43952,43952],"mapped",[5088]],[[43953,43953],"mapped",[5089]],[[43954,43954],"mapped",[5090]],[[43955,43955],"mapped",[5091]],[[43956,43956],"mapped",[5092]],[[43957,43957],"mapped",[5093]],[[43958,43958],"mapped",[5094]],[[43959,43959],"mapped",[5095]],[[43960,43960],"mapped",[5096]],[[43961,43961],"mapped",[5097]],[[43962,43962],"mapped",[5098]],[[43963,43963],"mapped",[5099]],[[43964,43964],"mapped",[5100]],[[43965,43965],"mapped",[5101]],[[43966,43966],"mapped",[5102]],[[43967,43967],"mapped",[5103]],[[43968,44010],"valid"],[[44011,44011],"valid",[],"NV8"],[[44012,44013],"valid"],[[44014,44015],"disallowed"],[[44016,44025],"valid"],[[44026,44031],"disallowed"],[[44032,55203],"valid"],[[55204,55215],"disallowed"],[[55216,55238],"valid",[],"NV8"],[[55239,55242],"disallowed"],[[55243,55291],"valid",[],"NV8"],[[55292,55295],"disallowed"],[[55296,57343],"disallowed"],[[57344,63743],"disallowed"],[[63744,63744],"mapped",[35912]],[[63745,63745],"mapped",[26356]],[[63746,63746],"mapped",[36554]],[[63747,63747],"mapped",[36040]],[[63748,63748],"mapped",[28369]],[[63749,63749],"mapped",[20018]],[[63750,63750],"mapped",[21477]],[[63751,63752],"mapped",[40860]],[[63753,63753],"mapped",[22865]],[[63754,63754],"mapped",[37329]],[[63755,63755],"mapped",[21895]],[[63756,63756],"mapped",[22856]],[[63757,63757],"mapped",[25078]],[[63758,63758],"mapped",[30313]],[[63759,63759],"mapped",[32645]],[[63760,63760],"mapped",[34367]],[[63761,63761],"mapped",[34746]],[[63762,63762],"mapped",[35064]],[[63763,63763],"mapped",[37007]],[[63764,63764],"mapped",[27138]],[[63765,63765],"mapped",[27931]],[[63766,63766],"mapped",[28889]],[[63767,63767],"mapped",[29662]],[[63768,63768],"mapped",[33853]],[[63769,63769],"mapped",[37226]],[[63770,63770],"mapped",[39409]],[[63771,63771],"mapped",[20098]],[[63772,63772],"mapped",[21365]],[[63773,63773],"mapped",[27396]],[[63774,63774],"mapped",[29211]],[[63775,63775],"mapped",[34349]],[[63776,63776],"mapped",[40478]],[[63777,63777],"mapped",[23888]],[[63778,63778],"mapped",[28651]],[[63779,63779],"mapped",[34253]],[[63780,63780],"mapped",[35172]],[[63781,63781],"mapped",[25289]],[[63782,63782],"mapped",[33240]],[[63783,63783],"mapped",[34847]],[[63784,63784],"mapped",[24266]],[[63785,63785],"mapped",[26391]],[[63786,63786],"mapped",[28010]],[[63787,63787],"mapped",[29436]],[[63788,63788],"mapped",[37070]],[[63789,63789],"mapped",[20358]],[[63790,63790],"mapped",[20919]],[[63791,63791],"mapped",[21214]],[[63792,63792],"mapped",[25796]],[[63793,63793],"mapped",[27347]],[[63794,63794],"mapped",[29200]],[[63795,63795],"mapped",[30439]],[[63796,63796],"mapped",[32769]],[[63797,63797],"mapped",[34310]],[[63798,63798],"mapped",[34396]],[[63799,63799],"mapped",[36335]],[[63800,63800],"mapped",[38706]],[[63801,63801],"mapped",[39791]],[[63802,63802],"mapped",[40442]],[[63803,63803],"mapped",[30860]],[[63804,63804],"mapped",[31103]],[[63805,63805],"mapped",[32160]],[[63806,63806],"mapped",[33737]],[[63807,63807],"mapped",[37636]],[[63808,63808],"mapped",[40575]],[[63809,63809],"mapped",[35542]],[[63810,63810],"mapped",[22751]],[[63811,63811],"mapped",[24324]],[[63812,63812],"mapped",[31840]],[[63813,63813],"mapped",[32894]],[[63814,63814],"mapped",[29282]],[[63815,63815],"mapped",[30922]],[[63816,63816],"mapped",[36034]],[[63817,63817],"mapped",[38647]],[[63818,63818],"mapped",[22744]],[[63819,63819],"mapped",[23650]],[[63820,63820],"mapped",[27155]],[[63821,63821],"mapped",[28122]],[[63822,63822],"mapped",[28431]],[[63823,63823],"mapped",[32047]],[[63824,63824],"mapped",[32311]],[[63825,63825],"mapped",[38475]],[[63826,63826],"mapped",[21202]],[[63827,63827],"mapped",[32907]],[[63828,63828],"mapped",[20956]],[[63829,63829],"mapped",[20940]],[[63830,63830],"mapped",[31260]],[[63831,63831],"mapped",[32190]],[[63832,63832],"mapped",[33777]],[[63833,63833],"mapped",[38517]],[[63834,63834],"mapped",[35712]],[[63835,63835],"mapped",[25295]],[[63836,63836],"mapped",[27138]],[[63837,63837],"mapped",[35582]],[[63838,63838],"mapped",[20025]],[[63839,63839],"mapped",[23527]],[[63840,63840],"mapped",[24594]],[[63841,63841],"mapped",[29575]],[[63842,63842],"mapped",[30064]],[[63843,63843],"mapped",[21271]],[[63844,63844],"mapped",[30971]],[[63845,63845],"mapped",[20415]],[[63846,63846],"mapped",[24489]],[[63847,63847],"mapped",[19981]],[[63848,63848],"mapped",[27852]],[[63849,63849],"mapped",[25976]],[[63850,63850],"mapped",[32034]],[[63851,63851],"mapped",[21443]],[[63852,63852],"mapped",[22622]],[[63853,63853],"mapped",[30465]],[[63854,63854],"mapped",[33865]],[[63855,63855],"mapped",[35498]],[[63856,63856],"mapped",[27578]],[[63857,63857],"mapped",[36784]],[[63858,63858],"mapped",[27784]],[[63859,63859],"mapped",[25342]],[[63860,63860],"mapped",[33509]],[[63861,63861],"mapped",[25504]],[[63862,63862],"mapped",[30053]],[[63863,63863],"mapped",[20142]],[[63864,63864],"mapped",[20841]],[[63865,63865],"mapped",[20937]],[[63866,63866],"mapped",[26753]],[[63867,63867],"mapped",[31975]],[[63868,63868],"mapped",[33391]],[[63869,63869],"mapped",[35538]],[[63870,63870],"mapped",[37327]],[[63871,63871],"mapped",[21237]],[[63872,63872],"mapped",[21570]],[[63873,63873],"mapped",[22899]],[[63874,63874],"mapped",[24300]],[[63875,63875],"mapped",[26053]],[[63876,63876],"mapped",[28670]],[[63877,63877],"mapped",[31018]],[[63878,63878],"mapped",[38317]],[[63879,63879],"mapped",[39530]],[[63880,63880],"mapped",[40599]],[[63881,63881],"mapped",[40654]],[[63882,63882],"mapped",[21147]],[[63883,63883],"mapped",[26310]],[[63884,63884],"mapped",[27511]],[[63885,63885],"mapped",[36706]],[[63886,63886],"mapped",[24180]],[[63887,63887],"mapped",[24976]],[[63888,63888],"mapped",[25088]],[[63889,63889],"mapped",[25754]],[[63890,63890],"mapped",[28451]],[[63891,63891],"mapped",[29001]],[[63892,63892],"mapped",[29833]],[[63893,63893],"mapped",[31178]],[[63894,63894],"mapped",[32244]],[[63895,63895],"mapped",[32879]],[[63896,63896],"mapped",[36646]],[[63897,63897],"mapped",[34030]],[[63898,63898],"mapped",[36899]],[[63899,63899],"mapped",[37706]],[[63900,63900],"mapped",[21015]],[[63901,63901],"mapped",[21155]],[[63902,63902],"mapped",[21693]],[[63903,63903],"mapped",[28872]],[[63904,63904],"mapped",[35010]],[[63905,63905],"mapped",[35498]],[[63906,63906],"mapped",[24265]],[[63907,63907],"mapped",[24565]],[[63908,63908],"mapped",[25467]],[[63909,63909],"mapped",[27566]],[[63910,63910],"mapped",[31806]],[[63911,63911],"mapped",[29557]],[[63912,63912],"mapped",[20196]],[[63913,63913],"mapped",[22265]],[[63914,63914],"mapped",[23527]],[[63915,63915],"mapped",[23994]],[[63916,63916],"mapped",[24604]],[[63917,63917],"mapped",[29618]],[[63918,63918],"mapped",[29801]],[[63919,63919],"mapped",[32666]],[[63920,63920],"mapped",[32838]],[[63921,63921],"mapped",[37428]],[[63922,63922],"mapped",[38646]],[[63923,63923],"mapped",[38728]],[[63924,63924],"mapped",[38936]],[[63925,63925],"mapped",[20363]],[[63926,63926],"mapped",[31150]],[[63927,63927],"mapped",[37300]],[[63928,63928],"mapped",[38584]],[[63929,63929],"mapped",[24801]],[[63930,63930],"mapped",[20102]],[[63931,63931],"mapped",[20698]],[[63932,63932],"mapped",[23534]],[[63933,63933],"mapped",[23615]],[[63934,63934],"mapped",[26009]],[[63935,63935],"mapped",[27138]],[[63936,63936],"mapped",[29134]],[[63937,63937],"mapped",[30274]],[[63938,63938],"mapped",[34044]],[[63939,63939],"mapped",[36988]],[[63940,63940],"mapped",[40845]],[[63941,63941],"mapped",[26248]],[[63942,63942],"mapped",[38446]],[[63943,63943],"mapped",[21129]],[[63944,63944],"mapped",[26491]],[[63945,63945],"mapped",[26611]],[[63946,63946],"mapped",[27969]],[[63947,63947],"mapped",[28316]],[[63948,63948],"mapped",[29705]],[[63949,63949],"mapped",[30041]],[[63950,63950],"mapped",[30827]],[[63951,63951],"mapped",[32016]],[[63952,63952],"mapped",[39006]],[[63953,63953],"mapped",[20845]],[[63954,63954],"mapped",[25134]],[[63955,63955],"mapped",[38520]],[[63956,63956],"mapped",[20523]],[[63957,63957],"mapped",[23833]],[[63958,63958],"mapped",[28138]],[[63959,63959],"mapped",[36650]],[[63960,63960],"mapped",[24459]],[[63961,63961],"mapped",[24900]],[[63962,63962],"mapped",[26647]],[[63963,63963],"mapped",[29575]],[[63964,63964],"mapped",[38534]],[[63965,63965],"mapped",[21033]],[[63966,63966],"mapped",[21519]],[[63967,63967],"mapped",[23653]],[[63968,63968],"mapped",[26131]],[[63969,63969],"mapped",[26446]],[[63970,63970],"mapped",[26792]],[[63971,63971],"mapped",[27877]],[[63972,63972],"mapped",[29702]],[[63973,63973],"mapped",[30178]],[[63974,63974],"mapped",[32633]],[[63975,63975],"mapped",[35023]],[[63976,63976],"mapped",[35041]],[[63977,63977],"mapped",[37324]],[[63978,63978],"mapped",[38626]],[[63979,63979],"mapped",[21311]],[[63980,63980],"mapped",[28346]],[[63981,63981],"mapped",[21533]],[[63982,63982],"mapped",[29136]],[[63983,63983],"mapped",[29848]],[[63984,63984],"mapped",[34298]],[[63985,63985],"mapped",[38563]],[[63986,63986],"mapped",[40023]],[[63987,63987],"mapped",[40607]],[[63988,63988],"mapped",[26519]],[[63989,63989],"mapped",[28107]],[[63990,63990],"mapped",[33256]],[[63991,63991],"mapped",[31435]],[[63992,63992],"mapped",[31520]],[[63993,63993],"mapped",[31890]],[[63994,63994],"mapped",[29376]],[[63995,63995],"mapped",[28825]],[[63996,63996],"mapped",[35672]],[[63997,63997],"mapped",[20160]],[[63998,63998],"mapped",[33590]],[[63999,63999],"mapped",[21050]],[[64000,64000],"mapped",[20999]],[[64001,64001],"mapped",[24230]],[[64002,64002],"mapped",[25299]],[[64003,64003],"mapped",[31958]],[[64004,64004],"mapped",[23429]],[[64005,64005],"mapped",[27934]],[[64006,64006],"mapped",[26292]],[[64007,64007],"mapped",[36667]],[[64008,64008],"mapped",[34892]],[[64009,64009],"mapped",[38477]],[[64010,64010],"mapped",[35211]],[[64011,64011],"mapped",[24275]],[[64012,64012],"mapped",[20800]],[[64013,64013],"mapped",[21952]],[[64014,64015],"valid"],[[64016,64016],"mapped",[22618]],[[64017,64017],"valid"],[[64018,64018],"mapped",[26228]],[[64019,64020],"valid"],[[64021,64021],"mapped",[20958]],[[64022,64022],"mapped",[29482]],[[64023,64023],"mapped",[30410]],[[64024,64024],"mapped",[31036]],[[64025,64025],"mapped",[31070]],[[64026,64026],"mapped",[31077]],[[64027,64027],"mapped",[31119]],[[64028,64028],"mapped",[38742]],[[64029,64029],"mapped",[31934]],[[64030,64030],"mapped",[32701]],[[64031,64031],"valid"],[[64032,64032],"mapped",[34322]],[[64033,64033],"valid"],[[64034,64034],"mapped",[35576]],[[64035,64036],"valid"],[[64037,64037],"mapped",[36920]],[[64038,64038],"mapped",[37117]],[[64039,64041],"valid"],[[64042,64042],"mapped",[39151]],[[64043,64043],"mapped",[39164]],[[64044,64044],"mapped",[39208]],[[64045,64045],"mapped",[40372]],[[64046,64046],"mapped",[37086]],[[64047,64047],"mapped",[38583]],[[64048,64048],"mapped",[20398]],[[64049,64049],"mapped",[20711]],[[64050,64050],"mapped",[20813]],[[64051,64051],"mapped",[21193]],[[64052,64052],"mapped",[21220]],[[64053,64053],"mapped",[21329]],[[64054,64054],"mapped",[21917]],[[64055,64055],"mapped",[22022]],[[64056,64056],"mapped",[22120]],[[64057,64057],"mapped",[22592]],[[64058,64058],"mapped",[22696]],[[64059,64059],"mapped",[23652]],[[64060,64060],"mapped",[23662]],[[64061,64061],"mapped",[24724]],[[64062,64062],"mapped",[24936]],[[64063,64063],"mapped",[24974]],[[64064,64064],"mapped",[25074]],[[64065,64065],"mapped",[25935]],[[64066,64066],"mapped",[26082]],[[64067,64067],"mapped",[26257]],[[64068,64068],"mapped",[26757]],[[64069,64069],"mapped",[28023]],[[64070,64070],"mapped",[28186]],[[64071,64071],"mapped",[28450]],[[64072,64072],"mapped",[29038]],[[64073,64073],"mapped",[29227]],[[64074,64074],"mapped",[29730]],[[64075,64075],"mapped",[30865]],[[64076,64076],"mapped",[31038]],[[64077,64077],"mapped",[31049]],[[64078,64078],"mapped",[31048]],[[64079,64079],"mapped",[31056]],[[64080,64080],"mapped",[31062]],[[64081,64081],"mapped",[31069]],[[64082,64082],"mapped",[31117]],[[64083,64083],"mapped",[31118]],[[64084,64084],"mapped",[31296]],[[64085,64085],"mapped",[31361]],[[64086,64086],"mapped",[31680]],[[64087,64087],"mapped",[32244]],[[64088,64088],"mapped",[32265]],[[64089,64089],"mapped",[32321]],[[64090,64090],"mapped",[32626]],[[64091,64091],"mapped",[32773]],[[64092,64092],"mapped",[33261]],[[64093,64094],"mapped",[33401]],[[64095,64095],"mapped",[33879]],[[64096,64096],"mapped",[35088]],[[64097,64097],"mapped",[35222]],[[64098,64098],"mapped",[35585]],[[64099,64099],"mapped",[35641]],[[64100,64100],"mapped",[36051]],[[64101,64101],"mapped",[36104]],[[64102,64102],"mapped",[36790]],[[64103,64103],"mapped",[36920]],[[64104,64104],"mapped",[38627]],[[64105,64105],"mapped",[38911]],[[64106,64106],"mapped",[38971]],[[64107,64107],"mapped",[24693]],[[64108,64108],"mapped",[148206]],[[64109,64109],"mapped",[33304]],[[64110,64111],"disallowed"],[[64112,64112],"mapped",[20006]],[[64113,64113],"mapped",[20917]],[[64114,64114],"mapped",[20840]],[[64115,64115],"mapped",[20352]],[[64116,64116],"mapped",[20805]],[[64117,64117],"mapped",[20864]],[[64118,64118],"mapped",[21191]],[[64119,64119],"mapped",[21242]],[[64120,64120],"mapped",[21917]],[[64121,64121],"mapped",[21845]],[[64122,64122],"mapped",[21913]],[[64123,64123],"mapped",[21986]],[[64124,64124],"mapped",[22618]],[[64125,64125],"mapped",[22707]],[[64126,64126],"mapped",[22852]],[[64127,64127],"mapped",[22868]],[[64128,64128],"mapped",[23138]],[[64129,64129],"mapped",[23336]],[[64130,64130],"mapped",[24274]],[[64131,64131],"mapped",[24281]],[[64132,64132],"mapped",[24425]],[[64133,64133],"mapped",[24493]],[[64134,64134],"mapped",[24792]],[[64135,64135],"mapped",[24910]],[[64136,64136],"mapped",[24840]],[[64137,64137],"mapped",[24974]],[[64138,64138],"mapped",[24928]],[[64139,64139],"mapped",[25074]],[[64140,64140],"mapped",[25140]],[[64141,64141],"mapped",[25540]],[[64142,64142],"mapped",[25628]],[[64143,64143],"mapped",[25682]],[[64144,64144],"mapped",[25942]],[[64145,64145],"mapped",[26228]],[[64146,64146],"mapped",[26391]],[[64147,64147],"mapped",[26395]],[[64148,64148],"mapped",[26454]],[[64149,64149],"mapped",[27513]],[[64150,64150],"mapped",[27578]],[[64151,64151],"mapped",[27969]],[[64152,64152],"mapped",[28379]],[[64153,64153],"mapped",[28363]],[[64154,64154],"mapped",[28450]],[[64155,64155],"mapped",[28702]],[[64156,64156],"mapped",[29038]],[[64157,64157],"mapped",[30631]],[[64158,64158],"mapped",[29237]],[[64159,64159],"mapped",[29359]],[[64160,64160],"mapped",[29482]],[[64161,64161],"mapped",[29809]],[[64162,64162],"mapped",[29958]],[[64163,64163],"mapped",[30011]],[[64164,64164],"mapped",[30237]],[[64165,64165],"mapped",[30239]],[[64166,64166],"mapped",[30410]],[[64167,64167],"mapped",[30427]],[[64168,64168],"mapped",[30452]],[[64169,64169],"mapped",[30538]],[[64170,64170],"mapped",[30528]],[[64171,64171],"mapped",[30924]],[[64172,64172],"mapped",[31409]],[[64173,64173],"mapped",[31680]],[[64174,64174],"mapped",[31867]],[[64175,64175],"mapped",[32091]],[[64176,64176],"mapped",[32244]],[[64177,64177],"mapped",[32574]],[[64178,64178],"mapped",[32773]],[[64179,64179],"mapped",[33618]],[[64180,64180],"mapped",[33775]],[[64181,64181],"mapped",[34681]],[[64182,64182],"mapped",[35137]],[[64183,64183],"mapped",[35206]],[[64184,64184],"mapped",[35222]],[[64185,64185],"mapped",[35519]],[[64186,64186],"mapped",[35576]],[[64187,64187],"mapped",[35531]],[[64188,64188],"mapped",[35585]],[[64189,64189],"mapped",[35582]],[[64190,64190],"mapped",[35565]],[[64191,64191],"mapped",[35641]],[[64192,64192],"mapped",[35722]],[[64193,64193],"mapped",[36104]],[[64194,64194],"mapped",[36664]],[[64195,64195],"mapped",[36978]],[[64196,64196],"mapped",[37273]],[[64197,64197],"mapped",[37494]],[[64198,64198],"mapped",[38524]],[[64199,64199],"mapped",[38627]],[[64200,64200],"mapped",[38742]],[[64201,64201],"mapped",[38875]],[[64202,64202],"mapped",[38911]],[[64203,64203],"mapped",[38923]],[[64204,64204],"mapped",[38971]],[[64205,64205],"mapped",[39698]],[[64206,64206],"mapped",[40860]],[[64207,64207],"mapped",[141386]],[[64208,64208],"mapped",[141380]],[[64209,64209],"mapped",[144341]],[[64210,64210],"mapped",[15261]],[[64211,64211],"mapped",[16408]],[[64212,64212],"mapped",[16441]],[[64213,64213],"mapped",[152137]],[[64214,64214],"mapped",[154832]],[[64215,64215],"mapped",[163539]],[[64216,64216],"mapped",[40771]],[[64217,64217],"mapped",[40846]],[[64218,64255],"disallowed"],[[64256,64256],"mapped",[102,102]],[[64257,64257],"mapped",[102,105]],[[64258,64258],"mapped",[102,108]],[[64259,64259],"mapped",[102,102,105]],[[64260,64260],"mapped",[102,102,108]],[[64261,64262],"mapped",[115,116]],[[64263,64274],"disallowed"],[[64275,64275],"mapped",[1396,1398]],[[64276,64276],"mapped",[1396,1381]],[[64277,64277],"mapped",[1396,1387]],[[64278,64278],"mapped",[1406,1398]],[[64279,64279],"mapped",[1396,1389]],[[64280,64284],"disallowed"],[[64285,64285],"mapped",[1497,1460]],[[64286,64286],"valid"],[[64287,64287],"mapped",[1522,1463]],[[64288,64288],"mapped",[1506]],[[64289,64289],"mapped",[1488]],[[64290,64290],"mapped",[1491]],[[64291,64291],"mapped",[1492]],[[64292,64292],"mapped",[1499]],[[64293,64293],"mapped",[1500]],[[64294,64294],"mapped",[1501]],[[64295,64295],"mapped",[1512]],[[64296,64296],"mapped",[1514]],[[64297,64297],"disallowed_STD3_mapped",[43]],[[64298,64298],"mapped",[1513,1473]],[[64299,64299],"mapped",[1513,1474]],[[64300,64300],"mapped",[1513,1468,1473]],[[64301,64301],"mapped",[1513,1468,1474]],[[64302,64302],"mapped",[1488,1463]],[[64303,64303],"mapped",[1488,1464]],[[64304,64304],"mapped",[1488,1468]],[[64305,64305],"mapped",[1489,1468]],[[64306,64306],"mapped",[1490,1468]],[[64307,64307],"mapped",[1491,1468]],[[64308,64308],"mapped",[1492,1468]],[[64309,64309],"mapped",[1493,1468]],[[64310,64310],"mapped",[1494,1468]],[[64311,64311],"disallowed"],[[64312,64312],"mapped",[1496,1468]],[[64313,64313],"mapped",[1497,1468]],[[64314,64314],"mapped",[1498,1468]],[[64315,64315],"mapped",[1499,1468]],[[64316,64316],"mapped",[1500,1468]],[[64317,64317],"disallowed"],[[64318,64318],"mapped",[1502,1468]],[[64319,64319],"disallowed"],[[64320,64320],"mapped",[1504,1468]],[[64321,64321],"mapped",[1505,1468]],[[64322,64322],"disallowed"],[[64323,64323],"mapped",[1507,1468]],[[64324,64324],"mapped",[1508,1468]],[[64325,64325],"disallowed"],[[64326,64326],"mapped",[1510,1468]],[[64327,64327],"mapped",[1511,1468]],[[64328,64328],"mapped",[1512,1468]],[[64329,64329],"mapped",[1513,1468]],[[64330,64330],"mapped",[1514,1468]],[[64331,64331],"mapped",[1493,1465]],[[64332,64332],"mapped",[1489,1471]],[[64333,64333],"mapped",[1499,1471]],[[64334,64334],"mapped",[1508,1471]],[[64335,64335],"mapped",[1488,1500]],[[64336,64337],"mapped",[1649]],[[64338,64341],"mapped",[1659]],[[64342,64345],"mapped",[1662]],[[64346,64349],"mapped",[1664]],[[64350,64353],"mapped",[1658]],[[64354,64357],"mapped",[1663]],[[64358,64361],"mapped",[1657]],[[64362,64365],"mapped",[1700]],[[64366,64369],"mapped",[1702]],[[64370,64373],"mapped",[1668]],[[64374,64377],"mapped",[1667]],[[64378,64381],"mapped",[1670]],[[64382,64385],"mapped",[1671]],[[64386,64387],"mapped",[1677]],[[64388,64389],"mapped",[1676]],[[64390,64391],"mapped",[1678]],[[64392,64393],"mapped",[1672]],[[64394,64395],"mapped",[1688]],[[64396,64397],"mapped",[1681]],[[64398,64401],"mapped",[1705]],[[64402,64405],"mapped",[1711]],[[64406,64409],"mapped",[1715]],[[64410,64413],"mapped",[1713]],[[64414,64415],"mapped",[1722]],[[64416,64419],"mapped",[1723]],[[64420,64421],"mapped",[1728]],[[64422,64425],"mapped",[1729]],[[64426,64429],"mapped",[1726]],[[64430,64431],"mapped",[1746]],[[64432,64433],"mapped",[1747]],[[64434,64449],"valid",[],"NV8"],[[64450,64466],"disallowed"],[[64467,64470],"mapped",[1709]],[[64471,64472],"mapped",[1735]],[[64473,64474],"mapped",[1734]],[[64475,64476],"mapped",[1736]],[[64477,64477],"mapped",[1735,1652]],[[64478,64479],"mapped",[1739]],[[64480,64481],"mapped",[1733]],[[64482,64483],"mapped",[1737]],[[64484,64487],"mapped",[1744]],[[64488,64489],"mapped",[1609]],[[64490,64491],"mapped",[1574,1575]],[[64492,64493],"mapped",[1574,1749]],[[64494,64495],"mapped",[1574,1608]],[[64496,64497],"mapped",[1574,1735]],[[64498,64499],"mapped",[1574,1734]],[[64500,64501],"mapped",[1574,1736]],[[64502,64504],"mapped",[1574,1744]],[[64505,64507],"mapped",[1574,1609]],[[64508,64511],"mapped",[1740]],[[64512,64512],"mapped",[1574,1580]],[[64513,64513],"mapped",[1574,1581]],[[64514,64514],"mapped",[1574,1605]],[[64515,64515],"mapped",[1574,1609]],[[64516,64516],"mapped",[1574,1610]],[[64517,64517],"mapped",[1576,1580]],[[64518,64518],"mapped",[1576,1581]],[[64519,64519],"mapped",[1576,1582]],[[64520,64520],"mapped",[1576,1605]],[[64521,64521],"mapped",[1576,1609]],[[64522,64522],"mapped",[1576,1610]],[[64523,64523],"mapped",[1578,1580]],[[64524,64524],"mapped",[1578,1581]],[[64525,64525],"mapped",[1578,1582]],[[64526,64526],"mapped",[1578,1605]],[[64527,64527],"mapped",[1578,1609]],[[64528,64528],"mapped",[1578,1610]],[[64529,64529],"mapped",[1579,1580]],[[64530,64530],"mapped",[1579,1605]],[[64531,64531],"mapped",[1579,1609]],[[64532,64532],"mapped",[1579,1610]],[[64533,64533],"mapped",[1580,1581]],[[64534,64534],"mapped",[1580,1605]],[[64535,64535],"mapped",[1581,1580]],[[64536,64536],"mapped",[1581,1605]],[[64537,64537],"mapped",[1582,1580]],[[64538,64538],"mapped",[1582,1581]],[[64539,64539],"mapped",[1582,1605]],[[64540,64540],"mapped",[1587,1580]],[[64541,64541],"mapped",[1587,1581]],[[64542,64542],"mapped",[1587,1582]],[[64543,64543],"mapped",[1587,1605]],[[64544,64544],"mapped",[1589,1581]],[[64545,64545],"mapped",[1589,1605]],[[64546,64546],"mapped",[1590,1580]],[[64547,64547],"mapped",[1590,1581]],[[64548,64548],"mapped",[1590,1582]],[[64549,64549],"mapped",[1590,1605]],[[64550,64550],"mapped",[1591,1581]],[[64551,64551],"mapped",[1591,1605]],[[64552,64552],"mapped",[1592,1605]],[[64553,64553],"mapped",[1593,1580]],[[64554,64554],"mapped",[1593,1605]],[[64555,64555],"mapped",[1594,1580]],[[64556,64556],"mapped",[1594,1605]],[[64557,64557],"mapped",[1601,1580]],[[64558,64558],"mapped",[1601,1581]],[[64559,64559],"mapped",[1601,1582]],[[64560,64560],"mapped",[1601,1605]],[[64561,64561],"mapped",[1601,1609]],[[64562,64562],"mapped",[1601,1610]],[[64563,64563],"mapped",[1602,1581]],[[64564,64564],"mapped",[1602,1605]],[[64565,64565],"mapped",[1602,1609]],[[64566,64566],"mapped",[1602,1610]],[[64567,64567],"mapped",[1603,1575]],[[64568,64568],"mapped",[1603,1580]],[[64569,64569],"mapped",[1603,1581]],[[64570,64570],"mapped",[1603,1582]],[[64571,64571],"mapped",[1603,1604]],[[64572,64572],"mapped",[1603,1605]],[[64573,64573],"mapped",[1603,1609]],[[64574,64574],"mapped",[1603,1610]],[[64575,64575],"mapped",[1604,1580]],[[64576,64576],"mapped",[1604,1581]],[[64577,64577],"mapped",[1604,1582]],[[64578,64578],"mapped",[1604,1605]],[[64579,64579],"mapped",[1604,1609]],[[64580,64580],"mapped",[1604,1610]],[[64581,64581],"mapped",[1605,1580]],[[64582,64582],"mapped",[1605,1581]],[[64583,64583],"mapped",[1605,1582]],[[64584,64584],"mapped",[1605,1605]],[[64585,64585],"mapped",[1605,1609]],[[64586,64586],"mapped",[1605,1610]],[[64587,64587],"mapped",[1606,1580]],[[64588,64588],"mapped",[1606,1581]],[[64589,64589],"mapped",[1606,1582]],[[64590,64590],"mapped",[1606,1605]],[[64591,64591],"mapped",[1606,1609]],[[64592,64592],"mapped",[1606,1610]],[[64593,64593],"mapped",[1607,1580]],[[64594,64594],"mapped",[1607,1605]],[[64595,64595],"mapped",[1607,1609]],[[64596,64596],"mapped",[1607,1610]],[[64597,64597],"mapped",[1610,1580]],[[64598,64598],"mapped",[1610,1581]],[[64599,64599],"mapped",[1610,1582]],[[64600,64600],"mapped",[1610,1605]],[[64601,64601],"mapped",[1610,1609]],[[64602,64602],"mapped",[1610,1610]],[[64603,64603],"mapped",[1584,1648]],[[64604,64604],"mapped",[1585,1648]],[[64605,64605],"mapped",[1609,1648]],[[64606,64606],"disallowed_STD3_mapped",[32,1612,1617]],[[64607,64607],"disallowed_STD3_mapped",[32,1613,1617]],[[64608,64608],"disallowed_STD3_mapped",[32,1614,1617]],[[64609,64609],"disallowed_STD3_mapped",[32,1615,1617]],[[64610,64610],"disallowed_STD3_mapped",[32,1616,1617]],[[64611,64611],"disallowed_STD3_mapped",[32,1617,1648]],[[64612,64612],"mapped",[1574,1585]],[[64613,64613],"mapped",[1574,1586]],[[64614,64614],"mapped",[1574,1605]],[[64615,64615],"mapped",[1574,1606]],[[64616,64616],"mapped",[1574,1609]],[[64617,64617],"mapped",[1574,1610]],[[64618,64618],"mapped",[1576,1585]],[[64619,64619],"mapped",[1576,1586]],[[64620,64620],"mapped",[1576,1605]],[[64621,64621],"mapped",[1576,1606]],[[64622,64622],"mapped",[1576,1609]],[[64623,64623],"mapped",[1576,1610]],[[64624,64624],"mapped",[1578,1585]],[[64625,64625],"mapped",[1578,1586]],[[64626,64626],"mapped",[1578,1605]],[[64627,64627],"mapped",[1578,1606]],[[64628,64628],"mapped",[1578,1609]],[[64629,64629],"mapped",[1578,1610]],[[64630,64630],"mapped",[1579,1585]],[[64631,64631],"mapped",[1579,1586]],[[64632,64632],"mapped",[1579,1605]],[[64633,64633],"mapped",[1579,1606]],[[64634,64634],"mapped",[1579,1609]],[[64635,64635],"mapped",[1579,1610]],[[64636,64636],"mapped",[1601,1609]],[[64637,64637],"mapped",[1601,1610]],[[64638,64638],"mapped",[1602,1609]],[[64639,64639],"mapped",[1602,1610]],[[64640,64640],"mapped",[1603,1575]],[[64641,64641],"mapped",[1603,1604]],[[64642,64642],"mapped",[1603,1605]],[[64643,64643],"mapped",[1603,1609]],[[64644,64644],"mapped",[1603,1610]],[[64645,64645],"mapped",[1604,1605]],[[64646,64646],"mapped",[1604,1609]],[[64647,64647],"mapped",[1604,1610]],[[64648,64648],"mapped",[1605,1575]],[[64649,64649],"mapped",[1605,1605]],[[64650,64650],"mapped",[1606,1585]],[[64651,64651],"mapped",[1606,1586]],[[64652,64652],"mapped",[1606,1605]],[[64653,64653],"mapped",[1606,1606]],[[64654,64654],"mapped",[1606,1609]],[[64655,64655],"mapped",[1606,1610]],[[64656,64656],"mapped",[1609,1648]],[[64657,64657],"mapped",[1610,1585]],[[64658,64658],"mapped",[1610,1586]],[[64659,64659],"mapped",[1610,1605]],[[64660,64660],"mapped",[1610,1606]],[[64661,64661],"mapped",[1610,1609]],[[64662,64662],"mapped",[1610,1610]],[[64663,64663],"mapped",[1574,1580]],[[64664,64664],"mapped",[1574,1581]],[[64665,64665],"mapped",[1574,1582]],[[64666,64666],"mapped",[1574,1605]],[[64667,64667],"mapped",[1574,1607]],[[64668,64668],"mapped",[1576,1580]],[[64669,64669],"mapped",[1576,1581]],[[64670,64670],"mapped",[1576,1582]],[[64671,64671],"mapped",[1576,1605]],[[64672,64672],"mapped",[1576,1607]],[[64673,64673],"mapped",[1578,1580]],[[64674,64674],"mapped",[1578,1581]],[[64675,64675],"mapped",[1578,1582]],[[64676,64676],"mapped",[1578,1605]],[[64677,64677],"mapped",[1578,1607]],[[64678,64678],"mapped",[1579,1605]],[[64679,64679],"mapped",[1580,1581]],[[64680,64680],"mapped",[1580,1605]],[[64681,64681],"mapped",[1581,1580]],[[64682,64682],"mapped",[1581,1605]],[[64683,64683],"mapped",[1582,1580]],[[64684,64684],"mapped",[1582,1605]],[[64685,64685],"mapped",[1587,1580]],[[64686,64686],"mapped",[1587,1581]],[[64687,64687],"mapped",[1587,1582]],[[64688,64688],"mapped",[1587,1605]],[[64689,64689],"mapped",[1589,1581]],[[64690,64690],"mapped",[1589,1582]],[[64691,64691],"mapped",[1589,1605]],[[64692,64692],"mapped",[1590,1580]],[[64693,64693],"mapped",[1590,1581]],[[64694,64694],"mapped",[1590,1582]],[[64695,64695],"mapped",[1590,1605]],[[64696,64696],"mapped",[1591,1581]],[[64697,64697],"mapped",[1592,1605]],[[64698,64698],"mapped",[1593,1580]],[[64699,64699],"mapped",[1593,1605]],[[64700,64700],"mapped",[1594,1580]],[[64701,64701],"mapped",[1594,1605]],[[64702,64702],"mapped",[1601,1580]],[[64703,64703],"mapped",[1601,1581]],[[64704,64704],"mapped",[1601,1582]],[[64705,64705],"mapped",[1601,1605]],[[64706,64706],"mapped",[1602,1581]],[[64707,64707],"mapped",[1602,1605]],[[64708,64708],"mapped",[1603,1580]],[[64709,64709],"mapped",[1603,1581]],[[64710,64710],"mapped",[1603,1582]],[[64711,64711],"mapped",[1603,1604]],[[64712,64712],"mapped",[1603,1605]],[[64713,64713],"mapped",[1604,1580]],[[64714,64714],"mapped",[1604,1581]],[[64715,64715],"mapped",[1604,1582]],[[64716,64716],"mapped",[1604,1605]],[[64717,64717],"mapped",[1604,1607]],[[64718,64718],"mapped",[1605,1580]],[[64719,64719],"mapped",[1605,1581]],[[64720,64720],"mapped",[1605,1582]],[[64721,64721],"mapped",[1605,1605]],[[64722,64722],"mapped",[1606,1580]],[[64723,64723],"mapped",[1606,1581]],[[64724,64724],"mapped",[1606,1582]],[[64725,64725],"mapped",[1606,1605]],[[64726,64726],"mapped",[1606,1607]],[[64727,64727],"mapped",[1607,1580]],[[64728,64728],"mapped",[1607,1605]],[[64729,64729],"mapped",[1607,1648]],[[64730,64730],"mapped",[1610,1580]],[[64731,64731],"mapped",[1610,1581]],[[64732,64732],"mapped",[1610,1582]],[[64733,64733],"mapped",[1610,1605]],[[64734,64734],"mapped",[1610,1607]],[[64735,64735],"mapped",[1574,1605]],[[64736,64736],"mapped",[1574,1607]],[[64737,64737],"mapped",[1576,1605]],[[64738,64738],"mapped",[1576,1607]],[[64739,64739],"mapped",[1578,1605]],[[64740,64740],"mapped",[1578,1607]],[[64741,64741],"mapped",[1579,1605]],[[64742,64742],"mapped",[1579,1607]],[[64743,64743],"mapped",[1587,1605]],[[64744,64744],"mapped",[1587,1607]],[[64745,64745],"mapped",[1588,1605]],[[64746,64746],"mapped",[1588,1607]],[[64747,64747],"mapped",[1603,1604]],[[64748,64748],"mapped",[1603,1605]],[[64749,64749],"mapped",[1604,1605]],[[64750,64750],"mapped",[1606,1605]],[[64751,64751],"mapped",[1606,1607]],[[64752,64752],"mapped",[1610,1605]],[[64753,64753],"mapped",[1610,1607]],[[64754,64754],"mapped",[1600,1614,1617]],[[64755,64755],"mapped",[1600,1615,1617]],[[64756,64756],"mapped",[1600,1616,1617]],[[64757,64757],"mapped",[1591,1609]],[[64758,64758],"mapped",[1591,1610]],[[64759,64759],"mapped",[1593,1609]],[[64760,64760],"mapped",[1593,1610]],[[64761,64761],"mapped",[1594,1609]],[[64762,64762],"mapped",[1594,1610]],[[64763,64763],"mapped",[1587,1609]],[[64764,64764],"mapped",[1587,1610]],[[64765,64765],"mapped",[1588,1609]],[[64766,64766],"mapped",[1588,1610]],[[64767,64767],"mapped",[1581,1609]],[[64768,64768],"mapped",[1581,1610]],[[64769,64769],"mapped",[1580,1609]],[[64770,64770],"mapped",[1580,1610]],[[64771,64771],"mapped",[1582,1609]],[[64772,64772],"mapped",[1582,1610]],[[64773,64773],"mapped",[1589,1609]],[[64774,64774],"mapped",[1589,1610]],[[64775,64775],"mapped",[1590,1609]],[[64776,64776],"mapped",[1590,1610]],[[64777,64777],"mapped",[1588,1580]],[[64778,64778],"mapped",[1588,1581]],[[64779,64779],"mapped",[1588,1582]],[[64780,64780],"mapped",[1588,1605]],[[64781,64781],"mapped",[1588,1585]],[[64782,64782],"mapped",[1587,1585]],[[64783,64783],"mapped",[1589,1585]],[[64784,64784],"mapped",[1590,1585]],[[64785,64785],"mapped",[1591,1609]],[[64786,64786],"mapped",[1591,1610]],[[64787,64787],"mapped",[1593,1609]],[[64788,64788],"mapped",[1593,1610]],[[64789,64789],"mapped",[1594,1609]],[[64790,64790],"mapped",[1594,1610]],[[64791,64791],"mapped",[1587,1609]],[[64792,64792],"mapped",[1587,1610]],[[64793,64793],"mapped",[1588,1609]],[[64794,64794],"mapped",[1588,1610]],[[64795,64795],"mapped",[1581,1609]],[[64796,64796],"mapped",[1581,1610]],[[64797,64797],"mapped",[1580,1609]],[[64798,64798],"mapped",[1580,1610]],[[64799,64799],"mapped",[1582,1609]],[[64800,64800],"mapped",[1582,1610]],[[64801,64801],"mapped",[1589,1609]],[[64802,64802],"mapped",[1589,1610]],[[64803,64803],"mapped",[1590,1609]],[[64804,64804],"mapped",[1590,1610]],[[64805,64805],"mapped",[1588,1580]],[[64806,64806],"mapped",[1588,1581]],[[64807,64807],"mapped",[1588,1582]],[[64808,64808],"mapped",[1588,1605]],[[64809,64809],"mapped",[1588,1585]],[[64810,64810],"mapped",[1587,1585]],[[64811,64811],"mapped",[1589,1585]],[[64812,64812],"mapped",[1590,1585]],[[64813,64813],"mapped",[1588,1580]],[[64814,64814],"mapped",[1588,1581]],[[64815,64815],"mapped",[1588,1582]],[[64816,64816],"mapped",[1588,1605]],[[64817,64817],"mapped",[1587,1607]],[[64818,64818],"mapped",[1588,1607]],[[64819,64819],"mapped",[1591,1605]],[[64820,64820],"mapped",[1587,1580]],[[64821,64821],"mapped",[1587,1581]],[[64822,64822],"mapped",[1587,1582]],[[64823,64823],"mapped",[1588,1580]],[[64824,64824],"mapped",[1588,1581]],[[64825,64825],"mapped",[1588,1582]],[[64826,64826],"mapped",[1591,1605]],[[64827,64827],"mapped",[1592,1605]],[[64828,64829],"mapped",[1575,1611]],[[64830,64831],"valid",[],"NV8"],[[64832,64847],"disallowed"],[[64848,64848],"mapped",[1578,1580,1605]],[[64849,64850],"mapped",[1578,1581,1580]],[[64851,64851],"mapped",[1578,1581,1605]],[[64852,64852],"mapped",[1578,1582,1605]],[[64853,64853],"mapped",[1578,1605,1580]],[[64854,64854],"mapped",[1578,1605,1581]],[[64855,64855],"mapped",[1578,1605,1582]],[[64856,64857],"mapped",[1580,1605,1581]],[[64858,64858],"mapped",[1581,1605,1610]],[[64859,64859],"mapped",[1581,1605,1609]],[[64860,64860],"mapped",[1587,1581,1580]],[[64861,64861],"mapped",[1587,1580,1581]],[[64862,64862],"mapped",[1587,1580,1609]],[[64863,64864],"mapped",[1587,1605,1581]],[[64865,64865],"mapped",[1587,1605,1580]],[[64866,64867],"mapped",[1587,1605,1605]],[[64868,64869],"mapped",[1589,1581,1581]],[[64870,64870],"mapped",[1589,1605,1605]],[[64871,64872],"mapped",[1588,1581,1605]],[[64873,64873],"mapped",[1588,1580,1610]],[[64874,64875],"mapped",[1588,1605,1582]],[[64876,64877],"mapped",[1588,1605,1605]],[[64878,64878],"mapped",[1590,1581,1609]],[[64879,64880],"mapped",[1590,1582,1605]],[[64881,64882],"mapped",[1591,1605,1581]],[[64883,64883],"mapped",[1591,1605,1605]],[[64884,64884],"mapped",[1591,1605,1610]],[[64885,64885],"mapped",[1593,1580,1605]],[[64886,64887],"mapped",[1593,1605,1605]],[[64888,64888],"mapped",[1593,1605,1609]],[[64889,64889],"mapped",[1594,1605,1605]],[[64890,64890],"mapped",[1594,1605,1610]],[[64891,64891],"mapped",[1594,1605,1609]],[[64892,64893],"mapped",[1601,1582,1605]],[[64894,64894],"mapped",[1602,1605,1581]],[[64895,64895],"mapped",[1602,1605,1605]],[[64896,64896],"mapped",[1604,1581,1605]],[[64897,64897],"mapped",[1604,1581,1610]],[[64898,64898],"mapped",[1604,1581,1609]],[[64899,64900],"mapped",[1604,1580,1580]],[[64901,64902],"mapped",[1604,1582,1605]],[[64903,64904],"mapped",[1604,1605,1581]],[[64905,64905],"mapped",[1605,1581,1580]],[[64906,64906],"mapped",[1605,1581,1605]],[[64907,64907],"mapped",[1605,1581,1610]],[[64908,64908],"mapped",[1605,1580,1581]],[[64909,64909],"mapped",[1605,1580,1605]],[[64910,64910],"mapped",[1605,1582,1580]],[[64911,64911],"mapped",[1605,1582,1605]],[[64912,64913],"disallowed"],[[64914,64914],"mapped",[1605,1580,1582]],[[64915,64915],"mapped",[1607,1605,1580]],[[64916,64916],"mapped",[1607,1605,1605]],[[64917,64917],"mapped",[1606,1581,1605]],[[64918,64918],"mapped",[1606,1581,1609]],[[64919,64920],"mapped",[1606,1580,1605]],[[64921,64921],"mapped",[1606,1580,1609]],[[64922,64922],"mapped",[1606,1605,1610]],[[64923,64923],"mapped",[1606,1605,1609]],[[64924,64925],"mapped",[1610,1605,1605]],[[64926,64926],"mapped",[1576,1582,1610]],[[64927,64927],"mapped",[1578,1580,1610]],[[64928,64928],"mapped",[1578,1580,1609]],[[64929,64929],"mapped",[1578,1582,1610]],[[64930,64930],"mapped",[1578,1582,1609]],[[64931,64931],"mapped",[1578,1605,1610]],[[64932,64932],"mapped",[1578,1605,1609]],[[64933,64933],"mapped",[1580,1605,1610]],[[64934,64934],"mapped",[1580,1581,1609]],[[64935,64935],"mapped",[1580,1605,1609]],[[64936,64936],"mapped",[1587,1582,1609]],[[64937,64937],"mapped",[1589,1581,1610]],[[64938,64938],"mapped",[1588,1581,1610]],[[64939,64939],"mapped",[1590,1581,1610]],[[64940,64940],"mapped",[1604,1580,1610]],[[64941,64941],"mapped",[1604,1605,1610]],[[64942,64942],"mapped",[1610,1581,1610]],[[64943,64943],"mapped",[1610,1580,1610]],[[64944,64944],"mapped",[1610,1605,1610]],[[64945,64945],"mapped",[1605,1605,1610]],[[64946,64946],"mapped",[1602,1605,1610]],[[64947,64947],"mapped",[1606,1581,1610]],[[64948,64948],"mapped",[1602,1605,1581]],[[64949,64949],"mapped",[1604,1581,1605]],[[64950,64950],"mapped",[1593,1605,1610]],[[64951,64951],"mapped",[1603,1605,1610]],[[64952,64952],"mapped",[1606,1580,1581]],[[64953,64953],"mapped",[1605,1582,1610]],[[64954,64954],"mapped",[1604,1580,1605]],[[64955,64955],"mapped",[1603,1605,1605]],[[64956,64956],"mapped",[1604,1580,1605]],[[64957,64957],"mapped",[1606,1580,1581]],[[64958,64958],"mapped",[1580,1581,1610]],[[64959,64959],"mapped",[1581,1580,1610]],[[64960,64960],"mapped",[1605,1580,1610]],[[64961,64961],"mapped",[1601,1605,1610]],[[64962,64962],"mapped",[1576,1581,1610]],[[64963,64963],"mapped",[1603,1605,1605]],[[64964,64964],"mapped",[1593,1580,1605]],[[64965,64965],"mapped",[1589,1605,1605]],[[64966,64966],"mapped",[1587,1582,1610]],[[64967,64967],"mapped",[1606,1580,1610]],[[64968,64975],"disallowed"],[[64976,65007],"disallowed"],[[65008,65008],"mapped",[1589,1604,1746]],[[65009,65009],"mapped",[1602,1604,1746]],[[65010,65010],"mapped",[1575,1604,1604,1607]],[[65011,65011],"mapped",[1575,1603,1576,1585]],[[65012,65012],"mapped",[1605,1581,1605,1583]],[[65013,65013],"mapped",[1589,1604,1593,1605]],[[65014,65014],"mapped",[1585,1587,1608,1604]],[[65015,65015],"mapped",[1593,1604,1610,1607]],[[65016,65016],"mapped",[1608,1587,1604,1605]],[[65017,65017],"mapped",[1589,1604,1609]],[[65018,65018],"disallowed_STD3_mapped",[1589,1604,1609,32,1575,1604,1604,1607,32,1593,1604,1610,1607,32,1608,1587,1604,1605]],[[65019,65019],"disallowed_STD3_mapped",[1580,1604,32,1580,1604,1575,1604,1607]],[[65020,65020],"mapped",[1585,1740,1575,1604]],[[65021,65021],"valid",[],"NV8"],[[65022,65023],"disallowed"],[[65024,65039],"ignored"],[[65040,65040],"disallowed_STD3_mapped",[44]],[[65041,65041],"mapped",[12289]],[[65042,65042],"disallowed"],[[65043,65043],"disallowed_STD3_mapped",[58]],[[65044,65044],"disallowed_STD3_mapped",[59]],[[65045,65045],"disallowed_STD3_mapped",[33]],[[65046,65046],"disallowed_STD3_mapped",[63]],[[65047,65047],"mapped",[12310]],[[65048,65048],"mapped",[12311]],[[65049,65049],"disallowed"],[[65050,65055],"disallowed"],[[65056,65059],"valid"],[[65060,65062],"valid"],[[65063,65069],"valid"],[[65070,65071],"valid"],[[65072,65072],"disallowed"],[[65073,65073],"mapped",[8212]],[[65074,65074],"mapped",[8211]],[[65075,65076],"disallowed_STD3_mapped",[95]],[[65077,65077],"disallowed_STD3_mapped",[40]],[[65078,65078],"disallowed_STD3_mapped",[41]],[[65079,65079],"disallowed_STD3_mapped",[123]],[[65080,65080],"disallowed_STD3_mapped",[125]],[[65081,65081],"mapped",[12308]],[[65082,65082],"mapped",[12309]],[[65083,65083],"mapped",[12304]],[[65084,65084],"mapped",[12305]],[[65085,65085],"mapped",[12298]],[[65086,65086],"mapped",[12299]],[[65087,65087],"mapped",[12296]],[[65088,65088],"mapped",[12297]],[[65089,65089],"mapped",[12300]],[[65090,65090],"mapped",[12301]],[[65091,65091],"mapped",[12302]],[[65092,65092],"mapped",[12303]],[[65093,65094],"valid",[],"NV8"],[[65095,65095],"disallowed_STD3_mapped",[91]],[[65096,65096],"disallowed_STD3_mapped",[93]],[[65097,65100],"disallowed_STD3_mapped",[32,773]],[[65101,65103],"disallowed_STD3_mapped",[95]],[[65104,65104],"disallowed_STD3_mapped",[44]],[[65105,65105],"mapped",[12289]],[[65106,65106],"disallowed"],[[65107,65107],"disallowed"],[[65108,65108],"disallowed_STD3_mapped",[59]],[[65109,65109],"disallowed_STD3_mapped",[58]],[[65110,65110],"disallowed_STD3_mapped",[63]],[[65111,65111],"disallowed_STD3_mapped",[33]],[[65112,65112],"mapped",[8212]],[[65113,65113],"disallowed_STD3_mapped",[40]],[[65114,65114],"disallowed_STD3_mapped",[41]],[[65115,65115],"disallowed_STD3_mapped",[123]],[[65116,65116],"disallowed_STD3_mapped",[125]],[[65117,65117],"mapped",[12308]],[[65118,65118],"mapped",[12309]],[[65119,65119],"disallowed_STD3_mapped",[35]],[[65120,65120],"disallowed_STD3_mapped",[38]],[[65121,65121],"disallowed_STD3_mapped",[42]],[[65122,65122],"disallowed_STD3_mapped",[43]],[[65123,65123],"mapped",[45]],[[65124,65124],"disallowed_STD3_mapped",[60]],[[65125,65125],"disallowed_STD3_mapped",[62]],[[65126,65126],"disallowed_STD3_mapped",[61]],[[65127,65127],"disallowed"],[[65128,65128],"disallowed_STD3_mapped",[92]],[[65129,65129],"disallowed_STD3_mapped",[36]],[[65130,65130],"disallowed_STD3_mapped",[37]],[[65131,65131],"disallowed_STD3_mapped",[64]],[[65132,65135],"disallowed"],[[65136,65136],"disallowed_STD3_mapped",[32,1611]],[[65137,65137],"mapped",[1600,1611]],[[65138,65138],"disallowed_STD3_mapped",[32,1612]],[[65139,65139],"valid"],[[65140,65140],"disallowed_STD3_mapped",[32,1613]],[[65141,65141],"disallowed"],[[65142,65142],"disallowed_STD3_mapped",[32,1614]],[[65143,65143],"mapped",[1600,1614]],[[65144,65144],"disallowed_STD3_mapped",[32,1615]],[[65145,65145],"mapped",[1600,1615]],[[65146,65146],"disallowed_STD3_mapped",[32,1616]],[[65147,65147],"mapped",[1600,1616]],[[65148,65148],"disallowed_STD3_mapped",[32,1617]],[[65149,65149],"mapped",[1600,1617]],[[65150,65150],"disallowed_STD3_mapped",[32,1618]],[[65151,65151],"mapped",[1600,1618]],[[65152,65152],"mapped",[1569]],[[65153,65154],"mapped",[1570]],[[65155,65156],"mapped",[1571]],[[65157,65158],"mapped",[1572]],[[65159,65160],"mapped",[1573]],[[65161,65164],"mapped",[1574]],[[65165,65166],"mapped",[1575]],[[65167,65170],"mapped",[1576]],[[65171,65172],"mapped",[1577]],[[65173,65176],"mapped",[1578]],[[65177,65180],"mapped",[1579]],[[65181,65184],"mapped",[1580]],[[65185,65188],"mapped",[1581]],[[65189,65192],"mapped",[1582]],[[65193,65194],"mapped",[1583]],[[65195,65196],"mapped",[1584]],[[65197,65198],"mapped",[1585]],[[65199,65200],"mapped",[1586]],[[65201,65204],"mapped",[1587]],[[65205,65208],"mapped",[1588]],[[65209,65212],"mapped",[1589]],[[65213,65216],"mapped",[1590]],[[65217,65220],"mapped",[1591]],[[65221,65224],"mapped",[1592]],[[65225,65228],"mapped",[1593]],[[65229,65232],"mapped",[1594]],[[65233,65236],"mapped",[1601]],[[65237,65240],"mapped",[1602]],[[65241,65244],"mapped",[1603]],[[65245,65248],"mapped",[1604]],[[65249,65252],"mapped",[1605]],[[65253,65256],"mapped",[1606]],[[65257,65260],"mapped",[1607]],[[65261,65262],"mapped",[1608]],[[65263,65264],"mapped",[1609]],[[65265,65268],"mapped",[1610]],[[65269,65270],"mapped",[1604,1570]],[[65271,65272],"mapped",[1604,1571]],[[65273,65274],"mapped",[1604,1573]],[[65275,65276],"mapped",[1604,1575]],[[65277,65278],"disallowed"],[[65279,65279],"ignored"],[[65280,65280],"disallowed"],[[65281,65281],"disallowed_STD3_mapped",[33]],[[65282,65282],"disallowed_STD3_mapped",[34]],[[65283,65283],"disallowed_STD3_mapped",[35]],[[65284,65284],"disallowed_STD3_mapped",[36]],[[65285,65285],"disallowed_STD3_mapped",[37]],[[65286,65286],"disallowed_STD3_mapped",[38]],[[65287,65287],"disallowed_STD3_mapped",[39]],[[65288,65288],"disallowed_STD3_mapped",[40]],[[65289,65289],"disallowed_STD3_mapped",[41]],[[65290,65290],"disallowed_STD3_mapped",[42]],[[65291,65291],"disallowed_STD3_mapped",[43]],[[65292,65292],"disallowed_STD3_mapped",[44]],[[65293,65293],"mapped",[45]],[[65294,65294],"mapped",[46]],[[65295,65295],"disallowed_STD3_mapped",[47]],[[65296,65296],"mapped",[48]],[[65297,65297],"mapped",[49]],[[65298,65298],"mapped",[50]],[[65299,65299],"mapped",[51]],[[65300,65300],"mapped",[52]],[[65301,65301],"mapped",[53]],[[65302,65302],"mapped",[54]],[[65303,65303],"mapped",[55]],[[65304,65304],"mapped",[56]],[[65305,65305],"mapped",[57]],[[65306,65306],"disallowed_STD3_mapped",[58]],[[65307,65307],"disallowed_STD3_mapped",[59]],[[65308,65308],"disallowed_STD3_mapped",[60]],[[65309,65309],"disallowed_STD3_mapped",[61]],[[65310,65310],"disallowed_STD3_mapped",[62]],[[65311,65311],"disallowed_STD3_mapped",[63]],[[65312,65312],"disallowed_STD3_mapped",[64]],[[65313,65313],"mapped",[97]],[[65314,65314],"mapped",[98]],[[65315,65315],"mapped",[99]],[[65316,65316],"mapped",[100]],[[65317,65317],"mapped",[101]],[[65318,65318],"mapped",[102]],[[65319,65319],"mapped",[103]],[[65320,65320],"mapped",[104]],[[65321,65321],"mapped",[105]],[[65322,65322],"mapped",[106]],[[65323,65323],"mapped",[107]],[[65324,65324],"mapped",[108]],[[65325,65325],"mapped",[109]],[[65326,65326],"mapped",[110]],[[65327,65327],"mapped",[111]],[[65328,65328],"mapped",[112]],[[65329,65329],"mapped",[113]],[[65330,65330],"mapped",[114]],[[65331,65331],"mapped",[115]],[[65332,65332],"mapped",[116]],[[65333,65333],"mapped",[117]],[[65334,65334],"mapped",[118]],[[65335,65335],"mapped",[119]],[[65336,65336],"mapped",[120]],[[65337,65337],"mapped",[121]],[[65338,65338],"mapped",[122]],[[65339,65339],"disallowed_STD3_mapped",[91]],[[65340,65340],"disallowed_STD3_mapped",[92]],[[65341,65341],"disallowed_STD3_mapped",[93]],[[65342,65342],"disallowed_STD3_mapped",[94]],[[65343,65343],"disallowed_STD3_mapped",[95]],[[65344,65344],"disallowed_STD3_mapped",[96]],[[65345,65345],"mapped",[97]],[[65346,65346],"mapped",[98]],[[65347,65347],"mapped",[99]],[[65348,65348],"mapped",[100]],[[65349,65349],"mapped",[101]],[[65350,65350],"mapped",[102]],[[65351,65351],"mapped",[103]],[[65352,65352],"mapped",[104]],[[65353,65353],"mapped",[105]],[[65354,65354],"mapped",[106]],[[65355,65355],"mapped",[107]],[[65356,65356],"mapped",[108]],[[65357,65357],"mapped",[109]],[[65358,65358],"mapped",[110]],[[65359,65359],"mapped",[111]],[[65360,65360],"mapped",[112]],[[65361,65361],"mapped",[113]],[[65362,65362],"mapped",[114]],[[65363,65363],"mapped",[115]],[[65364,65364],"mapped",[116]],[[65365,65365],"mapped",[117]],[[65366,65366],"mapped",[118]],[[65367,65367],"mapped",[119]],[[65368,65368],"mapped",[120]],[[65369,65369],"mapped",[121]],[[65370,65370],"mapped",[122]],[[65371,65371],"disallowed_STD3_mapped",[123]],[[65372,65372],"disallowed_STD3_mapped",[124]],[[65373,65373],"disallowed_STD3_mapped",[125]],[[65374,65374],"disallowed_STD3_mapped",[126]],[[65375,65375],"mapped",[10629]],[[65376,65376],"mapped",[10630]],[[65377,65377],"mapped",[46]],[[65378,65378],"mapped",[12300]],[[65379,65379],"mapped",[12301]],[[65380,65380],"mapped",[12289]],[[65381,65381],"mapped",[12539]],[[65382,65382],"mapped",[12530]],[[65383,65383],"mapped",[12449]],[[65384,65384],"mapped",[12451]],[[65385,65385],"mapped",[12453]],[[65386,65386],"mapped",[12455]],[[65387,65387],"mapped",[12457]],[[65388,65388],"mapped",[12515]],[[65389,65389],"mapped",[12517]],[[65390,65390],"mapped",[12519]],[[65391,65391],"mapped",[12483]],[[65392,65392],"mapped",[12540]],[[65393,65393],"mapped",[12450]],[[65394,65394],"mapped",[12452]],[[65395,65395],"mapped",[12454]],[[65396,65396],"mapped",[12456]],[[65397,65397],"mapped",[12458]],[[65398,65398],"mapped",[12459]],[[65399,65399],"mapped",[12461]],[[65400,65400],"mapped",[12463]],[[65401,65401],"mapped",[12465]],[[65402,65402],"mapped",[12467]],[[65403,65403],"mapped",[12469]],[[65404,65404],"mapped",[12471]],[[65405,65405],"mapped",[12473]],[[65406,65406],"mapped",[12475]],[[65407,65407],"mapped",[12477]],[[65408,65408],"mapped",[12479]],[[65409,65409],"mapped",[12481]],[[65410,65410],"mapped",[12484]],[[65411,65411],"mapped",[12486]],[[65412,65412],"mapped",[12488]],[[65413,65413],"mapped",[12490]],[[65414,65414],"mapped",[12491]],[[65415,65415],"mapped",[12492]],[[65416,65416],"mapped",[12493]],[[65417,65417],"mapped",[12494]],[[65418,65418],"mapped",[12495]],[[65419,65419],"mapped",[12498]],[[65420,65420],"mapped",[12501]],[[65421,65421],"mapped",[12504]],[[65422,65422],"mapped",[12507]],[[65423,65423],"mapped",[12510]],[[65424,65424],"mapped",[12511]],[[65425,65425],"mapped",[12512]],[[65426,65426],"mapped",[12513]],[[65427,65427],"mapped",[12514]],[[65428,65428],"mapped",[12516]],[[65429,65429],"mapped",[12518]],[[65430,65430],"mapped",[12520]],[[65431,65431],"mapped",[12521]],[[65432,65432],"mapped",[12522]],[[65433,65433],"mapped",[12523]],[[65434,65434],"mapped",[12524]],[[65435,65435],"mapped",[12525]],[[65436,65436],"mapped",[12527]],[[65437,65437],"mapped",[12531]],[[65438,65438],"mapped",[12441]],[[65439,65439],"mapped",[12442]],[[65440,65440],"disallowed"],[[65441,65441],"mapped",[4352]],[[65442,65442],"mapped",[4353]],[[65443,65443],"mapped",[4522]],[[65444,65444],"mapped",[4354]],[[65445,65445],"mapped",[4524]],[[65446,65446],"mapped",[4525]],[[65447,65447],"mapped",[4355]],[[65448,65448],"mapped",[4356]],[[65449,65449],"mapped",[4357]],[[65450,65450],"mapped",[4528]],[[65451,65451],"mapped",[4529]],[[65452,65452],"mapped",[4530]],[[65453,65453],"mapped",[4531]],[[65454,65454],"mapped",[4532]],[[65455,65455],"mapped",[4533]],[[65456,65456],"mapped",[4378]],[[65457,65457],"mapped",[4358]],[[65458,65458],"mapped",[4359]],[[65459,65459],"mapped",[4360]],[[65460,65460],"mapped",[4385]],[[65461,65461],"mapped",[4361]],[[65462,65462],"mapped",[4362]],[[65463,65463],"mapped",[4363]],[[65464,65464],"mapped",[4364]],[[65465,65465],"mapped",[4365]],[[65466,65466],"mapped",[4366]],[[65467,65467],"mapped",[4367]],[[65468,65468],"mapped",[4368]],[[65469,65469],"mapped",[4369]],[[65470,65470],"mapped",[4370]],[[65471,65473],"disallowed"],[[65474,65474],"mapped",[4449]],[[65475,65475],"mapped",[4450]],[[65476,65476],"mapped",[4451]],[[65477,65477],"mapped",[4452]],[[65478,65478],"mapped",[4453]],[[65479,65479],"mapped",[4454]],[[65480,65481],"disallowed"],[[65482,65482],"mapped",[4455]],[[65483,65483],"mapped",[4456]],[[65484,65484],"mapped",[4457]],[[65485,65485],"mapped",[4458]],[[65486,65486],"mapped",[4459]],[[65487,65487],"mapped",[4460]],[[65488,65489],"disallowed"],[[65490,65490],"mapped",[4461]],[[65491,65491],"mapped",[4462]],[[65492,65492],"mapped",[4463]],[[65493,65493],"mapped",[4464]],[[65494,65494],"mapped",[4465]],[[65495,65495],"mapped",[4466]],[[65496,65497],"disallowed"],[[65498,65498],"mapped",[4467]],[[65499,65499],"mapped",[4468]],[[65500,65500],"mapped",[4469]],[[65501,65503],"disallowed"],[[65504,65504],"mapped",[162]],[[65505,65505],"mapped",[163]],[[65506,65506],"mapped",[172]],[[65507,65507],"disallowed_STD3_mapped",[32,772]],[[65508,65508],"mapped",[166]],[[65509,65509],"mapped",[165]],[[65510,65510],"mapped",[8361]],[[65511,65511],"disallowed"],[[65512,65512],"mapped",[9474]],[[65513,65513],"mapped",[8592]],[[65514,65514],"mapped",[8593]],[[65515,65515],"mapped",[8594]],[[65516,65516],"mapped",[8595]],[[65517,65517],"mapped",[9632]],[[65518,65518],"mapped",[9675]],[[65519,65528],"disallowed"],[[65529,65531],"disallowed"],[[65532,65532],"disallowed"],[[65533,65533],"disallowed"],[[65534,65535],"disallowed"],[[65536,65547],"valid"],[[65548,65548],"disallowed"],[[65549,65574],"valid"],[[65575,65575],"disallowed"],[[65576,65594],"valid"],[[65595,65595],"disallowed"],[[65596,65597],"valid"],[[65598,65598],"disallowed"],[[65599,65613],"valid"],[[65614,65615],"disallowed"],[[65616,65629],"valid"],[[65630,65663],"disallowed"],[[65664,65786],"valid"],[[65787,65791],"disallowed"],[[65792,65794],"valid",[],"NV8"],[[65795,65798],"disallowed"],[[65799,65843],"valid",[],"NV8"],[[65844,65846],"disallowed"],[[65847,65855],"valid",[],"NV8"],[[65856,65930],"valid",[],"NV8"],[[65931,65932],"valid",[],"NV8"],[[65933,65935],"disallowed"],[[65936,65947],"valid",[],"NV8"],[[65948,65951],"disallowed"],[[65952,65952],"valid",[],"NV8"],[[65953,65999],"disallowed"],[[66000,66044],"valid",[],"NV8"],[[66045,66045],"valid"],[[66046,66175],"disallowed"],[[66176,66204],"valid"],[[66205,66207],"disallowed"],[[66208,66256],"valid"],[[66257,66271],"disallowed"],[[66272,66272],"valid"],[[66273,66299],"valid",[],"NV8"],[[66300,66303],"disallowed"],[[66304,66334],"valid"],[[66335,66335],"valid"],[[66336,66339],"valid",[],"NV8"],[[66340,66351],"disallowed"],[[66352,66368],"valid"],[[66369,66369],"valid",[],"NV8"],[[66370,66377],"valid"],[[66378,66378],"valid",[],"NV8"],[[66379,66383],"disallowed"],[[66384,66426],"valid"],[[66427,66431],"disallowed"],[[66432,66461],"valid"],[[66462,66462],"disallowed"],[[66463,66463],"valid",[],"NV8"],[[66464,66499],"valid"],[[66500,66503],"disallowed"],[[66504,66511],"valid"],[[66512,66517],"valid",[],"NV8"],[[66518,66559],"disallowed"],[[66560,66560],"mapped",[66600]],[[66561,66561],"mapped",[66601]],[[66562,66562],"mapped",[66602]],[[66563,66563],"mapped",[66603]],[[66564,66564],"mapped",[66604]],[[66565,66565],"mapped",[66605]],[[66566,66566],"mapped",[66606]],[[66567,66567],"mapped",[66607]],[[66568,66568],"mapped",[66608]],[[66569,66569],"mapped",[66609]],[[66570,66570],"mapped",[66610]],[[66571,66571],"mapped",[66611]],[[66572,66572],"mapped",[66612]],[[66573,66573],"mapped",[66613]],[[66574,66574],"mapped",[66614]],[[66575,66575],"mapped",[66615]],[[66576,66576],"mapped",[66616]],[[66577,66577],"mapped",[66617]],[[66578,66578],"mapped",[66618]],[[66579,66579],"mapped",[66619]],[[66580,66580],"mapped",[66620]],[[66581,66581],"mapped",[66621]],[[66582,66582],"mapped",[66622]],[[66583,66583],"mapped",[66623]],[[66584,66584],"mapped",[66624]],[[66585,66585],"mapped",[66625]],[[66586,66586],"mapped",[66626]],[[66587,66587],"mapped",[66627]],[[66588,66588],"mapped",[66628]],[[66589,66589],"mapped",[66629]],[[66590,66590],"mapped",[66630]],[[66591,66591],"mapped",[66631]],[[66592,66592],"mapped",[66632]],[[66593,66593],"mapped",[66633]],[[66594,66594],"mapped",[66634]],[[66595,66595],"mapped",[66635]],[[66596,66596],"mapped",[66636]],[[66597,66597],"mapped",[66637]],[[66598,66598],"mapped",[66638]],[[66599,66599],"mapped",[66639]],[[66600,66637],"valid"],[[66638,66717],"valid"],[[66718,66719],"disallowed"],[[66720,66729],"valid"],[[66730,66815],"disallowed"],[[66816,66855],"valid"],[[66856,66863],"disallowed"],[[66864,66915],"valid"],[[66916,66926],"disallowed"],[[66927,66927],"valid",[],"NV8"],[[66928,67071],"disallowed"],[[67072,67382],"valid"],[[67383,67391],"disallowed"],[[67392,67413],"valid"],[[67414,67423],"disallowed"],[[67424,67431],"valid"],[[67432,67583],"disallowed"],[[67584,67589],"valid"],[[67590,67591],"disallowed"],[[67592,67592],"valid"],[[67593,67593],"disallowed"],[[67594,67637],"valid"],[[67638,67638],"disallowed"],[[67639,67640],"valid"],[[67641,67643],"disallowed"],[[67644,67644],"valid"],[[67645,67646],"disallowed"],[[67647,67647],"valid"],[[67648,67669],"valid"],[[67670,67670],"disallowed"],[[67671,67679],"valid",[],"NV8"],[[67680,67702],"valid"],[[67703,67711],"valid",[],"NV8"],[[67712,67742],"valid"],[[67743,67750],"disallowed"],[[67751,67759],"valid",[],"NV8"],[[67760,67807],"disallowed"],[[67808,67826],"valid"],[[67827,67827],"disallowed"],[[67828,67829],"valid"],[[67830,67834],"disallowed"],[[67835,67839],"valid",[],"NV8"],[[67840,67861],"valid"],[[67862,67865],"valid",[],"NV8"],[[67866,67867],"valid",[],"NV8"],[[67868,67870],"disallowed"],[[67871,67871],"valid",[],"NV8"],[[67872,67897],"valid"],[[67898,67902],"disallowed"],[[67903,67903],"valid",[],"NV8"],[[67904,67967],"disallowed"],[[67968,68023],"valid"],[[68024,68027],"disallowed"],[[68028,68029],"valid",[],"NV8"],[[68030,68031],"valid"],[[68032,68047],"valid",[],"NV8"],[[68048,68049],"disallowed"],[[68050,68095],"valid",[],"NV8"],[[68096,68099],"valid"],[[68100,68100],"disallowed"],[[68101,68102],"valid"],[[68103,68107],"disallowed"],[[68108,68115],"valid"],[[68116,68116],"disallowed"],[[68117,68119],"valid"],[[68120,68120],"disallowed"],[[68121,68147],"valid"],[[68148,68151],"disallowed"],[[68152,68154],"valid"],[[68155,68158],"disallowed"],[[68159,68159],"valid"],[[68160,68167],"valid",[],"NV8"],[[68168,68175],"disallowed"],[[68176,68184],"valid",[],"NV8"],[[68185,68191],"disallowed"],[[68192,68220],"valid"],[[68221,68223],"valid",[],"NV8"],[[68224,68252],"valid"],[[68253,68255],"valid",[],"NV8"],[[68256,68287],"disallowed"],[[68288,68295],"valid"],[[68296,68296],"valid",[],"NV8"],[[68297,68326],"valid"],[[68327,68330],"disallowed"],[[68331,68342],"valid",[],"NV8"],[[68343,68351],"disallowed"],[[68352,68405],"valid"],[[68406,68408],"disallowed"],[[68409,68415],"valid",[],"NV8"],[[68416,68437],"valid"],[[68438,68439],"disallowed"],[[68440,68447],"valid",[],"NV8"],[[68448,68466],"valid"],[[68467,68471],"disallowed"],[[68472,68479],"valid",[],"NV8"],[[68480,68497],"valid"],[[68498,68504],"disallowed"],[[68505,68508],"valid",[],"NV8"],[[68509,68520],"disallowed"],[[68521,68527],"valid",[],"NV8"],[[68528,68607],"disallowed"],[[68608,68680],"valid"],[[68681,68735],"disallowed"],[[68736,68736],"mapped",[68800]],[[68737,68737],"mapped",[68801]],[[68738,68738],"mapped",[68802]],[[68739,68739],"mapped",[68803]],[[68740,68740],"mapped",[68804]],[[68741,68741],"mapped",[68805]],[[68742,68742],"mapped",[68806]],[[68743,68743],"mapped",[68807]],[[68744,68744],"mapped",[68808]],[[68745,68745],"mapped",[68809]],[[68746,68746],"mapped",[68810]],[[68747,68747],"mapped",[68811]],[[68748,68748],"mapped",[68812]],[[68749,68749],"mapped",[68813]],[[68750,68750],"mapped",[68814]],[[68751,68751],"mapped",[68815]],[[68752,68752],"mapped",[68816]],[[68753,68753],"mapped",[68817]],[[68754,68754],"mapped",[68818]],[[68755,68755],"mapped",[68819]],[[68756,68756],"mapped",[68820]],[[68757,68757],"mapped",[68821]],[[68758,68758],"mapped",[68822]],[[68759,68759],"mapped",[68823]],[[68760,68760],"mapped",[68824]],[[68761,68761],"mapped",[68825]],[[68762,68762],"mapped",[68826]],[[68763,68763],"mapped",[68827]],[[68764,68764],"mapped",[68828]],[[68765,68765],"mapped",[68829]],[[68766,68766],"mapped",[68830]],[[68767,68767],"mapped",[68831]],[[68768,68768],"mapped",[68832]],[[68769,68769],"mapped",[68833]],[[68770,68770],"mapped",[68834]],[[68771,68771],"mapped",[68835]],[[68772,68772],"mapped",[68836]],[[68773,68773],"mapped",[68837]],[[68774,68774],"mapped",[68838]],[[68775,68775],"mapped",[68839]],[[68776,68776],"mapped",[68840]],[[68777,68777],"mapped",[68841]],[[68778,68778],"mapped",[68842]],[[68779,68779],"mapped",[68843]],[[68780,68780],"mapped",[68844]],[[68781,68781],"mapped",[68845]],[[68782,68782],"mapped",[68846]],[[68783,68783],"mapped",[68847]],[[68784,68784],"mapped",[68848]],[[68785,68785],"mapped",[68849]],[[68786,68786],"mapped",[68850]],[[68787,68799],"disallowed"],[[68800,68850],"valid"],[[68851,68857],"disallowed"],[[68858,68863],"valid",[],"NV8"],[[68864,69215],"disallowed"],[[69216,69246],"valid",[],"NV8"],[[69247,69631],"disallowed"],[[69632,69702],"valid"],[[69703,69709],"valid",[],"NV8"],[[69710,69713],"disallowed"],[[69714,69733],"valid",[],"NV8"],[[69734,69743],"valid"],[[69744,69758],"disallowed"],[[69759,69759],"valid"],[[69760,69818],"valid"],[[69819,69820],"valid",[],"NV8"],[[69821,69821],"disallowed"],[[69822,69825],"valid",[],"NV8"],[[69826,69839],"disallowed"],[[69840,69864],"valid"],[[69865,69871],"disallowed"],[[69872,69881],"valid"],[[69882,69887],"disallowed"],[[69888,69940],"valid"],[[69941,69941],"disallowed"],[[69942,69951],"valid"],[[69952,69955],"valid",[],"NV8"],[[69956,69967],"disallowed"],[[69968,70003],"valid"],[[70004,70005],"valid",[],"NV8"],[[70006,70006],"valid"],[[70007,70015],"disallowed"],[[70016,70084],"valid"],[[70085,70088],"valid",[],"NV8"],[[70089,70089],"valid",[],"NV8"],[[70090,70092],"valid"],[[70093,70093],"valid",[],"NV8"],[[70094,70095],"disallowed"],[[70096,70105],"valid"],[[70106,70106],"valid"],[[70107,70107],"valid",[],"NV8"],[[70108,70108],"valid"],[[70109,70111],"valid",[],"NV8"],[[70112,70112],"disallowed"],[[70113,70132],"valid",[],"NV8"],[[70133,70143],"disallowed"],[[70144,70161],"valid"],[[70162,70162],"disallowed"],[[70163,70199],"valid"],[[70200,70205],"valid",[],"NV8"],[[70206,70271],"disallowed"],[[70272,70278],"valid"],[[70279,70279],"disallowed"],[[70280,70280],"valid"],[[70281,70281],"disallowed"],[[70282,70285],"valid"],[[70286,70286],"disallowed"],[[70287,70301],"valid"],[[70302,70302],"disallowed"],[[70303,70312],"valid"],[[70313,70313],"valid",[],"NV8"],[[70314,70319],"disallowed"],[[70320,70378],"valid"],[[70379,70383],"disallowed"],[[70384,70393],"valid"],[[70394,70399],"disallowed"],[[70400,70400],"valid"],[[70401,70403],"valid"],[[70404,70404],"disallowed"],[[70405,70412],"valid"],[[70413,70414],"disallowed"],[[70415,70416],"valid"],[[70417,70418],"disallowed"],[[70419,70440],"valid"],[[70441,70441],"disallowed"],[[70442,70448],"valid"],[[70449,70449],"disallowed"],[[70450,70451],"valid"],[[70452,70452],"disallowed"],[[70453,70457],"valid"],[[70458,70459],"disallowed"],[[70460,70468],"valid"],[[70469,70470],"disallowed"],[[70471,70472],"valid"],[[70473,70474],"disallowed"],[[70475,70477],"valid"],[[70478,70479],"disallowed"],[[70480,70480],"valid"],[[70481,70486],"disallowed"],[[70487,70487],"valid"],[[70488,70492],"disallowed"],[[70493,70499],"valid"],[[70500,70501],"disallowed"],[[70502,70508],"valid"],[[70509,70511],"disallowed"],[[70512,70516],"valid"],[[70517,70783],"disallowed"],[[70784,70853],"valid"],[[70854,70854],"valid",[],"NV8"],[[70855,70855],"valid"],[[70856,70863],"disallowed"],[[70864,70873],"valid"],[[70874,71039],"disallowed"],[[71040,71093],"valid"],[[71094,71095],"disallowed"],[[71096,71104],"valid"],[[71105,71113],"valid",[],"NV8"],[[71114,71127],"valid",[],"NV8"],[[71128,71133],"valid"],[[71134,71167],"disallowed"],[[71168,71232],"valid"],[[71233,71235],"valid",[],"NV8"],[[71236,71236],"valid"],[[71237,71247],"disallowed"],[[71248,71257],"valid"],[[71258,71295],"disallowed"],[[71296,71351],"valid"],[[71352,71359],"disallowed"],[[71360,71369],"valid"],[[71370,71423],"disallowed"],[[71424,71449],"valid"],[[71450,71452],"disallowed"],[[71453,71467],"valid"],[[71468,71471],"disallowed"],[[71472,71481],"valid"],[[71482,71487],"valid",[],"NV8"],[[71488,71839],"disallowed"],[[71840,71840],"mapped",[71872]],[[71841,71841],"mapped",[71873]],[[71842,71842],"mapped",[71874]],[[71843,71843],"mapped",[71875]],[[71844,71844],"mapped",[71876]],[[71845,71845],"mapped",[71877]],[[71846,71846],"mapped",[71878]],[[71847,71847],"mapped",[71879]],[[71848,71848],"mapped",[71880]],[[71849,71849],"mapped",[71881]],[[71850,71850],"mapped",[71882]],[[71851,71851],"mapped",[71883]],[[71852,71852],"mapped",[71884]],[[71853,71853],"mapped",[71885]],[[71854,71854],"mapped",[71886]],[[71855,71855],"mapped",[71887]],[[71856,71856],"mapped",[71888]],[[71857,71857],"mapped",[71889]],[[71858,71858],"mapped",[71890]],[[71859,71859],"mapped",[71891]],[[71860,71860],"mapped",[71892]],[[71861,71861],"mapped",[71893]],[[71862,71862],"mapped",[71894]],[[71863,71863],"mapped",[71895]],[[71864,71864],"mapped",[71896]],[[71865,71865],"mapped",[71897]],[[71866,71866],"mapped",[71898]],[[71867,71867],"mapped",[71899]],[[71868,71868],"mapped",[71900]],[[71869,71869],"mapped",[71901]],[[71870,71870],"mapped",[71902]],[[71871,71871],"mapped",[71903]],[[71872,71913],"valid"],[[71914,71922],"valid",[],"NV8"],[[71923,71934],"disallowed"],[[71935,71935],"valid"],[[71936,72383],"disallowed"],[[72384,72440],"valid"],[[72441,73727],"disallowed"],[[73728,74606],"valid"],[[74607,74648],"valid"],[[74649,74649],"valid"],[[74650,74751],"disallowed"],[[74752,74850],"valid",[],"NV8"],[[74851,74862],"valid",[],"NV8"],[[74863,74863],"disallowed"],[[74864,74867],"valid",[],"NV8"],[[74868,74868],"valid",[],"NV8"],[[74869,74879],"disallowed"],[[74880,75075],"valid"],[[75076,77823],"disallowed"],[[77824,78894],"valid"],[[78895,82943],"disallowed"],[[82944,83526],"valid"],[[83527,92159],"disallowed"],[[92160,92728],"valid"],[[92729,92735],"disallowed"],[[92736,92766],"valid"],[[92767,92767],"disallowed"],[[92768,92777],"valid"],[[92778,92781],"disallowed"],[[92782,92783],"valid",[],"NV8"],[[92784,92879],"disallowed"],[[92880,92909],"valid"],[[92910,92911],"disallowed"],[[92912,92916],"valid"],[[92917,92917],"valid",[],"NV8"],[[92918,92927],"disallowed"],[[92928,92982],"valid"],[[92983,92991],"valid",[],"NV8"],[[92992,92995],"valid"],[[92996,92997],"valid",[],"NV8"],[[92998,93007],"disallowed"],[[93008,93017],"valid"],[[93018,93018],"disallowed"],[[93019,93025],"valid",[],"NV8"],[[93026,93026],"disallowed"],[[93027,93047],"valid"],[[93048,93052],"disallowed"],[[93053,93071],"valid"],[[93072,93951],"disallowed"],[[93952,94020],"valid"],[[94021,94031],"disallowed"],[[94032,94078],"valid"],[[94079,94094],"disallowed"],[[94095,94111],"valid"],[[94112,110591],"disallowed"],[[110592,110593],"valid"],[[110594,113663],"disallowed"],[[113664,113770],"valid"],[[113771,113775],"disallowed"],[[113776,113788],"valid"],[[113789,113791],"disallowed"],[[113792,113800],"valid"],[[113801,113807],"disallowed"],[[113808,113817],"valid"],[[113818,113819],"disallowed"],[[113820,113820],"valid",[],"NV8"],[[113821,113822],"valid"],[[113823,113823],"valid",[],"NV8"],[[113824,113827],"ignored"],[[113828,118783],"disallowed"],[[118784,119029],"valid",[],"NV8"],[[119030,119039],"disallowed"],[[119040,119078],"valid",[],"NV8"],[[119079,119080],"disallowed"],[[119081,119081],"valid",[],"NV8"],[[119082,119133],"valid",[],"NV8"],[[119134,119134],"mapped",[119127,119141]],[[119135,119135],"mapped",[119128,119141]],[[119136,119136],"mapped",[119128,119141,119150]],[[119137,119137],"mapped",[119128,119141,119151]],[[119138,119138],"mapped",[119128,119141,119152]],[[119139,119139],"mapped",[119128,119141,119153]],[[119140,119140],"mapped",[119128,119141,119154]],[[119141,119154],"valid",[],"NV8"],[[119155,119162],"disallowed"],[[119163,119226],"valid",[],"NV8"],[[119227,119227],"mapped",[119225,119141]],[[119228,119228],"mapped",[119226,119141]],[[119229,119229],"mapped",[119225,119141,119150]],[[119230,119230],"mapped",[119226,119141,119150]],[[119231,119231],"mapped",[119225,119141,119151]],[[119232,119232],"mapped",[119226,119141,119151]],[[119233,119261],"valid",[],"NV8"],[[119262,119272],"valid",[],"NV8"],[[119273,119295],"disallowed"],[[119296,119365],"valid",[],"NV8"],[[119366,119551],"disallowed"],[[119552,119638],"valid",[],"NV8"],[[119639,119647],"disallowed"],[[119648,119665],"valid",[],"NV8"],[[119666,119807],"disallowed"],[[119808,119808],"mapped",[97]],[[119809,119809],"mapped",[98]],[[119810,119810],"mapped",[99]],[[119811,119811],"mapped",[100]],[[119812,119812],"mapped",[101]],[[119813,119813],"mapped",[102]],[[119814,119814],"mapped",[103]],[[119815,119815],"mapped",[104]],[[119816,119816],"mapped",[105]],[[119817,119817],"mapped",[106]],[[119818,119818],"mapped",[107]],[[119819,119819],"mapped",[108]],[[119820,119820],"mapped",[109]],[[119821,119821],"mapped",[110]],[[119822,119822],"mapped",[111]],[[119823,119823],"mapped",[112]],[[119824,119824],"mapped",[113]],[[119825,119825],"mapped",[114]],[[119826,119826],"mapped",[115]],[[119827,119827],"mapped",[116]],[[119828,119828],"mapped",[117]],[[119829,119829],"mapped",[118]],[[119830,119830],"mapped",[119]],[[119831,119831],"mapped",[120]],[[119832,119832],"mapped",[121]],[[119833,119833],"mapped",[122]],[[119834,119834],"mapped",[97]],[[119835,119835],"mapped",[98]],[[119836,119836],"mapped",[99]],[[119837,119837],"mapped",[100]],[[119838,119838],"mapped",[101]],[[119839,119839],"mapped",[102]],[[119840,119840],"mapped",[103]],[[119841,119841],"mapped",[104]],[[119842,119842],"mapped",[105]],[[119843,119843],"mapped",[106]],[[119844,119844],"mapped",[107]],[[119845,119845],"mapped",[108]],[[119846,119846],"mapped",[109]],[[119847,119847],"mapped",[110]],[[119848,119848],"mapped",[111]],[[119849,119849],"mapped",[112]],[[119850,119850],"mapped",[113]],[[119851,119851],"mapped",[114]],[[119852,119852],"mapped",[115]],[[119853,119853],"mapped",[116]],[[119854,119854],"mapped",[117]],[[119855,119855],"mapped",[118]],[[119856,119856],"mapped",[119]],[[119857,119857],"mapped",[120]],[[119858,119858],"mapped",[121]],[[119859,119859],"mapped",[122]],[[119860,119860],"mapped",[97]],[[119861,119861],"mapped",[98]],[[119862,119862],"mapped",[99]],[[119863,119863],"mapped",[100]],[[119864,119864],"mapped",[101]],[[119865,119865],"mapped",[102]],[[119866,119866],"mapped",[103]],[[119867,119867],"mapped",[104]],[[119868,119868],"mapped",[105]],[[119869,119869],"mapped",[106]],[[119870,119870],"mapped",[107]],[[119871,119871],"mapped",[108]],[[119872,119872],"mapped",[109]],[[119873,119873],"mapped",[110]],[[119874,119874],"mapped",[111]],[[119875,119875],"mapped",[112]],[[119876,119876],"mapped",[113]],[[119877,119877],"mapped",[114]],[[119878,119878],"mapped",[115]],[[119879,119879],"mapped",[116]],[[119880,119880],"mapped",[117]],[[119881,119881],"mapped",[118]],[[119882,119882],"mapped",[119]],[[119883,119883],"mapped",[120]],[[119884,119884],"mapped",[121]],[[119885,119885],"mapped",[122]],[[119886,119886],"mapped",[97]],[[119887,119887],"mapped",[98]],[[119888,119888],"mapped",[99]],[[119889,119889],"mapped",[100]],[[119890,119890],"mapped",[101]],[[119891,119891],"mapped",[102]],[[119892,119892],"mapped",[103]],[[119893,119893],"disallowed"],[[119894,119894],"mapped",[105]],[[119895,119895],"mapped",[106]],[[119896,119896],"mapped",[107]],[[119897,119897],"mapped",[108]],[[119898,119898],"mapped",[109]],[[119899,119899],"mapped",[110]],[[119900,119900],"mapped",[111]],[[119901,119901],"mapped",[112]],[[119902,119902],"mapped",[113]],[[119903,119903],"mapped",[114]],[[119904,119904],"mapped",[115]],[[119905,119905],"mapped",[116]],[[119906,119906],"mapped",[117]],[[119907,119907],"mapped",[118]],[[119908,119908],"mapped",[119]],[[119909,119909],"mapped",[120]],[[119910,119910],"mapped",[121]],[[119911,119911],"mapped",[122]],[[119912,119912],"mapped",[97]],[[119913,119913],"mapped",[98]],[[119914,119914],"mapped",[99]],[[119915,119915],"mapped",[100]],[[119916,119916],"mapped",[101]],[[119917,119917],"mapped",[102]],[[119918,119918],"mapped",[103]],[[119919,119919],"mapped",[104]],[[119920,119920],"mapped",[105]],[[119921,119921],"mapped",[106]],[[119922,119922],"mapped",[107]],[[119923,119923],"mapped",[108]],[[119924,119924],"mapped",[109]],[[119925,119925],"mapped",[110]],[[119926,119926],"mapped",[111]],[[119927,119927],"mapped",[112]],[[119928,119928],"mapped",[113]],[[119929,119929],"mapped",[114]],[[119930,119930],"mapped",[115]],[[119931,119931],"mapped",[116]],[[119932,119932],"mapped",[117]],[[119933,119933],"mapped",[118]],[[119934,119934],"mapped",[119]],[[119935,119935],"mapped",[120]],[[119936,119936],"mapped",[121]],[[119937,119937],"mapped",[122]],[[119938,119938],"mapped",[97]],[[119939,119939],"mapped",[98]],[[119940,119940],"mapped",[99]],[[119941,119941],"mapped",[100]],[[119942,119942],"mapped",[101]],[[119943,119943],"mapped",[102]],[[119944,119944],"mapped",[103]],[[119945,119945],"mapped",[104]],[[119946,119946],"mapped",[105]],[[119947,119947],"mapped",[106]],[[119948,119948],"mapped",[107]],[[119949,119949],"mapped",[108]],[[119950,119950],"mapped",[109]],[[119951,119951],"mapped",[110]],[[119952,119952],"mapped",[111]],[[119953,119953],"mapped",[112]],[[119954,119954],"mapped",[113]],[[119955,119955],"mapped",[114]],[[119956,119956],"mapped",[115]],[[119957,119957],"mapped",[116]],[[119958,119958],"mapped",[117]],[[119959,119959],"mapped",[118]],[[119960,119960],"mapped",[119]],[[119961,119961],"mapped",[120]],[[119962,119962],"mapped",[121]],[[119963,119963],"mapped",[122]],[[119964,119964],"mapped",[97]],[[119965,119965],"disallowed"],[[119966,119966],"mapped",[99]],[[119967,119967],"mapped",[100]],[[119968,119969],"disallowed"],[[119970,119970],"mapped",[103]],[[119971,119972],"disallowed"],[[119973,119973],"mapped",[106]],[[119974,119974],"mapped",[107]],[[119975,119976],"disallowed"],[[119977,119977],"mapped",[110]],[[119978,119978],"mapped",[111]],[[119979,119979],"mapped",[112]],[[119980,119980],"mapped",[113]],[[119981,119981],"disallowed"],[[119982,119982],"mapped",[115]],[[119983,119983],"mapped",[116]],[[119984,119984],"mapped",[117]],[[119985,119985],"mapped",[118]],[[119986,119986],"mapped",[119]],[[119987,119987],"mapped",[120]],[[119988,119988],"mapped",[121]],[[119989,119989],"mapped",[122]],[[119990,119990],"mapped",[97]],[[119991,119991],"mapped",[98]],[[119992,119992],"mapped",[99]],[[119993,119993],"mapped",[100]],[[119994,119994],"disallowed"],[[119995,119995],"mapped",[102]],[[119996,119996],"disallowed"],[[119997,119997],"mapped",[104]],[[119998,119998],"mapped",[105]],[[119999,119999],"mapped",[106]],[[120000,120000],"mapped",[107]],[[120001,120001],"mapped",[108]],[[120002,120002],"mapped",[109]],[[120003,120003],"mapped",[110]],[[120004,120004],"disallowed"],[[120005,120005],"mapped",[112]],[[120006,120006],"mapped",[113]],[[120007,120007],"mapped",[114]],[[120008,120008],"mapped",[115]],[[120009,120009],"mapped",[116]],[[120010,120010],"mapped",[117]],[[120011,120011],"mapped",[118]],[[120012,120012],"mapped",[119]],[[120013,120013],"mapped",[120]],[[120014,120014],"mapped",[121]],[[120015,120015],"mapped",[122]],[[120016,120016],"mapped",[97]],[[120017,120017],"mapped",[98]],[[120018,120018],"mapped",[99]],[[120019,120019],"mapped",[100]],[[120020,120020],"mapped",[101]],[[120021,120021],"mapped",[102]],[[120022,120022],"mapped",[103]],[[120023,120023],"mapped",[104]],[[120024,120024],"mapped",[105]],[[120025,120025],"mapped",[106]],[[120026,120026],"mapped",[107]],[[120027,120027],"mapped",[108]],[[120028,120028],"mapped",[109]],[[120029,120029],"mapped",[110]],[[120030,120030],"mapped",[111]],[[120031,120031],"mapped",[112]],[[120032,120032],"mapped",[113]],[[120033,120033],"mapped",[114]],[[120034,120034],"mapped",[115]],[[120035,120035],"mapped",[116]],[[120036,120036],"mapped",[117]],[[120037,120037],"mapped",[118]],[[120038,120038],"mapped",[119]],[[120039,120039],"mapped",[120]],[[120040,120040],"mapped",[121]],[[120041,120041],"mapped",[122]],[[120042,120042],"mapped",[97]],[[120043,120043],"mapped",[98]],[[120044,120044],"mapped",[99]],[[120045,120045],"mapped",[100]],[[120046,120046],"mapped",[101]],[[120047,120047],"mapped",[102]],[[120048,120048],"mapped",[103]],[[120049,120049],"mapped",[104]],[[120050,120050],"mapped",[105]],[[120051,120051],"mapped",[106]],[[120052,120052],"mapped",[107]],[[120053,120053],"mapped",[108]],[[120054,120054],"mapped",[109]],[[120055,120055],"mapped",[110]],[[120056,120056],"mapped",[111]],[[120057,120057],"mapped",[112]],[[120058,120058],"mapped",[113]],[[120059,120059],"mapped",[114]],[[120060,120060],"mapped",[115]],[[120061,120061],"mapped",[116]],[[120062,120062],"mapped",[117]],[[120063,120063],"mapped",[118]],[[120064,120064],"mapped",[119]],[[120065,120065],"mapped",[120]],[[120066,120066],"mapped",[121]],[[120067,120067],"mapped",[122]],[[120068,120068],"mapped",[97]],[[120069,120069],"mapped",[98]],[[120070,120070],"disallowed"],[[120071,120071],"mapped",[100]],[[120072,120072],"mapped",[101]],[[120073,120073],"mapped",[102]],[[120074,120074],"mapped",[103]],[[120075,120076],"disallowed"],[[120077,120077],"mapped",[106]],[[120078,120078],"mapped",[107]],[[120079,120079],"mapped",[108]],[[120080,120080],"mapped",[109]],[[120081,120081],"mapped",[110]],[[120082,120082],"mapped",[111]],[[120083,120083],"mapped",[112]],[[120084,120084],"mapped",[113]],[[120085,120085],"disallowed"],[[120086,120086],"mapped",[115]],[[120087,120087],"mapped",[116]],[[120088,120088],"mapped",[117]],[[120089,120089],"mapped",[118]],[[120090,120090],"mapped",[119]],[[120091,120091],"mapped",[120]],[[120092,120092],"mapped",[121]],[[120093,120093],"disallowed"],[[120094,120094],"mapped",[97]],[[120095,120095],"mapped",[98]],[[120096,120096],"mapped",[99]],[[120097,120097],"mapped",[100]],[[120098,120098],"mapped",[101]],[[120099,120099],"mapped",[102]],[[120100,120100],"mapped",[103]],[[120101,120101],"mapped",[104]],[[120102,120102],"mapped",[105]],[[120103,120103],"mapped",[106]],[[120104,120104],"mapped",[107]],[[120105,120105],"mapped",[108]],[[120106,120106],"mapped",[109]],[[120107,120107],"mapped",[110]],[[120108,120108],"mapped",[111]],[[120109,120109],"mapped",[112]],[[120110,120110],"mapped",[113]],[[120111,120111],"mapped",[114]],[[120112,120112],"mapped",[115]],[[120113,120113],"mapped",[116]],[[120114,120114],"mapped",[117]],[[120115,120115],"mapped",[118]],[[120116,120116],"mapped",[119]],[[120117,120117],"mapped",[120]],[[120118,120118],"mapped",[121]],[[120119,120119],"mapped",[122]],[[120120,120120],"mapped",[97]],[[120121,120121],"mapped",[98]],[[120122,120122],"disallowed"],[[120123,120123],"mapped",[100]],[[120124,120124],"mapped",[101]],[[120125,120125],"mapped",[102]],[[120126,120126],"mapped",[103]],[[120127,120127],"disallowed"],[[120128,120128],"mapped",[105]],[[120129,120129],"mapped",[106]],[[120130,120130],"mapped",[107]],[[120131,120131],"mapped",[108]],[[120132,120132],"mapped",[109]],[[120133,120133],"disallowed"],[[120134,120134],"mapped",[111]],[[120135,120137],"disallowed"],[[120138,120138],"mapped",[115]],[[120139,120139],"mapped",[116]],[[120140,120140],"mapped",[117]],[[120141,120141],"mapped",[118]],[[120142,120142],"mapped",[119]],[[120143,120143],"mapped",[120]],[[120144,120144],"mapped",[121]],[[120145,120145],"disallowed"],[[120146,120146],"mapped",[97]],[[120147,120147],"mapped",[98]],[[120148,120148],"mapped",[99]],[[120149,120149],"mapped",[100]],[[120150,120150],"mapped",[101]],[[120151,120151],"mapped",[102]],[[120152,120152],"mapped",[103]],[[120153,120153],"mapped",[104]],[[120154,120154],"mapped",[105]],[[120155,120155],"mapped",[106]],[[120156,120156],"mapped",[107]],[[120157,120157],"mapped",[108]],[[120158,120158],"mapped",[109]],[[120159,120159],"mapped",[110]],[[120160,120160],"mapped",[111]],[[120161,120161],"mapped",[112]],[[120162,120162],"mapped",[113]],[[120163,120163],"mapped",[114]],[[120164,120164],"mapped",[115]],[[120165,120165],"mapped",[116]],[[120166,120166],"mapped",[117]],[[120167,120167],"mapped",[118]],[[120168,120168],"mapped",[119]],[[120169,120169],"mapped",[120]],[[120170,120170],"mapped",[121]],[[120171,120171],"mapped",[122]],[[120172,120172],"mapped",[97]],[[120173,120173],"mapped",[98]],[[120174,120174],"mapped",[99]],[[120175,120175],"mapped",[100]],[[120176,120176],"mapped",[101]],[[120177,120177],"mapped",[102]],[[120178,120178],"mapped",[103]],[[120179,120179],"mapped",[104]],[[120180,120180],"mapped",[105]],[[120181,120181],"mapped",[106]],[[120182,120182],"mapped",[107]],[[120183,120183],"mapped",[108]],[[120184,120184],"mapped",[109]],[[120185,120185],"mapped",[110]],[[120186,120186],"mapped",[111]],[[120187,120187],"mapped",[112]],[[120188,120188],"mapped",[113]],[[120189,120189],"mapped",[114]],[[120190,120190],"mapped",[115]],[[120191,120191],"mapped",[116]],[[120192,120192],"mapped",[117]],[[120193,120193],"mapped",[118]],[[120194,120194],"mapped",[119]],[[120195,120195],"mapped",[120]],[[120196,120196],"mapped",[121]],[[120197,120197],"mapped",[122]],[[120198,120198],"mapped",[97]],[[120199,120199],"mapped",[98]],[[120200,120200],"mapped",[99]],[[120201,120201],"mapped",[100]],[[120202,120202],"mapped",[101]],[[120203,120203],"mapped",[102]],[[120204,120204],"mapped",[103]],[[120205,120205],"mapped",[104]],[[120206,120206],"mapped",[105]],[[120207,120207],"mapped",[106]],[[120208,120208],"mapped",[107]],[[120209,120209],"mapped",[108]],[[120210,120210],"mapped",[109]],[[120211,120211],"mapped",[110]],[[120212,120212],"mapped",[111]],[[120213,120213],"mapped",[112]],[[120214,120214],"mapped",[113]],[[120215,120215],"mapped",[114]],[[120216,120216],"mapped",[115]],[[120217,120217],"mapped",[116]],[[120218,120218],"mapped",[117]],[[120219,120219],"mapped",[118]],[[120220,120220],"mapped",[119]],[[120221,120221],"mapped",[120]],[[120222,120222],"mapped",[121]],[[120223,120223],"mapped",[122]],[[120224,120224],"mapped",[97]],[[120225,120225],"mapped",[98]],[[120226,120226],"mapped",[99]],[[120227,120227],"mapped",[100]],[[120228,120228],"mapped",[101]],[[120229,120229],"mapped",[102]],[[120230,120230],"mapped",[103]],[[120231,120231],"mapped",[104]],[[120232,120232],"mapped",[105]],[[120233,120233],"mapped",[106]],[[120234,120234],"mapped",[107]],[[120235,120235],"mapped",[108]],[[120236,120236],"mapped",[109]],[[120237,120237],"mapped",[110]],[[120238,120238],"mapped",[111]],[[120239,120239],"mapped",[112]],[[120240,120240],"mapped",[113]],[[120241,120241],"mapped",[114]],[[120242,120242],"mapped",[115]],[[120243,120243],"mapped",[116]],[[120244,120244],"mapped",[117]],[[120245,120245],"mapped",[118]],[[120246,120246],"mapped",[119]],[[120247,120247],"mapped",[120]],[[120248,120248],"mapped",[121]],[[120249,120249],"mapped",[122]],[[120250,120250],"mapped",[97]],[[120251,120251],"mapped",[98]],[[120252,120252],"mapped",[99]],[[120253,120253],"mapped",[100]],[[120254,120254],"mapped",[101]],[[120255,120255],"mapped",[102]],[[120256,120256],"mapped",[103]],[[120257,120257],"mapped",[104]],[[120258,120258],"mapped",[105]],[[120259,120259],"mapped",[106]],[[120260,120260],"mapped",[107]],[[120261,120261],"mapped",[108]],[[120262,120262],"mapped",[109]],[[120263,120263],"mapped",[110]],[[120264,120264],"mapped",[111]],[[120265,120265],"mapped",[112]],[[120266,120266],"mapped",[113]],[[120267,120267],"mapped",[114]],[[120268,120268],"mapped",[115]],[[120269,120269],"mapped",[116]],[[120270,120270],"mapped",[117]],[[120271,120271],"mapped",[118]],[[120272,120272],"mapped",[119]],[[120273,120273],"mapped",[120]],[[120274,120274],"mapped",[121]],[[120275,120275],"mapped",[122]],[[120276,120276],"mapped",[97]],[[120277,120277],"mapped",[98]],[[120278,120278],"mapped",[99]],[[120279,120279],"mapped",[100]],[[120280,120280],"mapped",[101]],[[120281,120281],"mapped",[102]],[[120282,120282],"mapped",[103]],[[120283,120283],"mapped",[104]],[[120284,120284],"mapped",[105]],[[120285,120285],"mapped",[106]],[[120286,120286],"mapped",[107]],[[120287,120287],"mapped",[108]],[[120288,120288],"mapped",[109]],[[120289,120289],"mapped",[110]],[[120290,120290],"mapped",[111]],[[120291,120291],"mapped",[112]],[[120292,120292],"mapped",[113]],[[120293,120293],"mapped",[114]],[[120294,120294],"mapped",[115]],[[120295,120295],"mapped",[116]],[[120296,120296],"mapped",[117]],[[120297,120297],"mapped",[118]],[[120298,120298],"mapped",[119]],[[120299,120299],"mapped",[120]],[[120300,120300],"mapped",[121]],[[120301,120301],"mapped",[122]],[[120302,120302],"mapped",[97]],[[120303,120303],"mapped",[98]],[[120304,120304],"mapped",[99]],[[120305,120305],"mapped",[100]],[[120306,120306],"mapped",[101]],[[120307,120307],"mapped",[102]],[[120308,120308],"mapped",[103]],[[120309,120309],"mapped",[104]],[[120310,120310],"mapped",[105]],[[120311,120311],"mapped",[106]],[[120312,120312],"mapped",[107]],[[120313,120313],"mapped",[108]],[[120314,120314],"mapped",[109]],[[120315,120315],"mapped",[110]],[[120316,120316],"mapped",[111]],[[120317,120317],"mapped",[112]],[[120318,120318],"mapped",[113]],[[120319,120319],"mapped",[114]],[[120320,120320],"mapped",[115]],[[120321,120321],"mapped",[116]],[[120322,120322],"mapped",[117]],[[120323,120323],"mapped",[118]],[[120324,120324],"mapped",[119]],[[120325,120325],"mapped",[120]],[[120326,120326],"mapped",[121]],[[120327,120327],"mapped",[122]],[[120328,120328],"mapped",[97]],[[120329,120329],"mapped",[98]],[[120330,120330],"mapped",[99]],[[120331,120331],"mapped",[100]],[[120332,120332],"mapped",[101]],[[120333,120333],"mapped",[102]],[[120334,120334],"mapped",[103]],[[120335,120335],"mapped",[104]],[[120336,120336],"mapped",[105]],[[120337,120337],"mapped",[106]],[[120338,120338],"mapped",[107]],[[120339,120339],"mapped",[108]],[[120340,120340],"mapped",[109]],[[120341,120341],"mapped",[110]],[[120342,120342],"mapped",[111]],[[120343,120343],"mapped",[112]],[[120344,120344],"mapped",[113]],[[120345,120345],"mapped",[114]],[[120346,120346],"mapped",[115]],[[120347,120347],"mapped",[116]],[[120348,120348],"mapped",[117]],[[120349,120349],"mapped",[118]],[[120350,120350],"mapped",[119]],[[120351,120351],"mapped",[120]],[[120352,120352],"mapped",[121]],[[120353,120353],"mapped",[122]],[[120354,120354],"mapped",[97]],[[120355,120355],"mapped",[98]],[[120356,120356],"mapped",[99]],[[120357,120357],"mapped",[100]],[[120358,120358],"mapped",[101]],[[120359,120359],"mapped",[102]],[[120360,120360],"mapped",[103]],[[120361,120361],"mapped",[104]],[[120362,120362],"mapped",[105]],[[120363,120363],"mapped",[106]],[[120364,120364],"mapped",[107]],[[120365,120365],"mapped",[108]],[[120366,120366],"mapped",[109]],[[120367,120367],"mapped",[110]],[[120368,120368],"mapped",[111]],[[120369,120369],"mapped",[112]],[[120370,120370],"mapped",[113]],[[120371,120371],"mapped",[114]],[[120372,120372],"mapped",[115]],[[120373,120373],"mapped",[116]],[[120374,120374],"mapped",[117]],[[120375,120375],"mapped",[118]],[[120376,120376],"mapped",[119]],[[120377,120377],"mapped",[120]],[[120378,120378],"mapped",[121]],[[120379,120379],"mapped",[122]],[[120380,120380],"mapped",[97]],[[120381,120381],"mapped",[98]],[[120382,120382],"mapped",[99]],[[120383,120383],"mapped",[100]],[[120384,120384],"mapped",[101]],[[120385,120385],"mapped",[102]],[[120386,120386],"mapped",[103]],[[120387,120387],"mapped",[104]],[[120388,120388],"mapped",[105]],[[120389,120389],"mapped",[106]],[[120390,120390],"mapped",[107]],[[120391,120391],"mapped",[108]],[[120392,120392],"mapped",[109]],[[120393,120393],"mapped",[110]],[[120394,120394],"mapped",[111]],[[120395,120395],"mapped",[112]],[[120396,120396],"mapped",[113]],[[120397,120397],"mapped",[114]],[[120398,120398],"mapped",[115]],[[120399,120399],"mapped",[116]],[[120400,120400],"mapped",[117]],[[120401,120401],"mapped",[118]],[[120402,120402],"mapped",[119]],[[120403,120403],"mapped",[120]],[[120404,120404],"mapped",[121]],[[120405,120405],"mapped",[122]],[[120406,120406],"mapped",[97]],[[120407,120407],"mapped",[98]],[[120408,120408],"mapped",[99]],[[120409,120409],"mapped",[100]],[[120410,120410],"mapped",[101]],[[120411,120411],"mapped",[102]],[[120412,120412],"mapped",[103]],[[120413,120413],"mapped",[104]],[[120414,120414],"mapped",[105]],[[120415,120415],"mapped",[106]],[[120416,120416],"mapped",[107]],[[120417,120417],"mapped",[108]],[[120418,120418],"mapped",[109]],[[120419,120419],"mapped",[110]],[[120420,120420],"mapped",[111]],[[120421,120421],"mapped",[112]],[[120422,120422],"mapped",[113]],[[120423,120423],"mapped",[114]],[[120424,120424],"mapped",[115]],[[120425,120425],"mapped",[116]],[[120426,120426],"mapped",[117]],[[120427,120427],"mapped",[118]],[[120428,120428],"mapped",[119]],[[120429,120429],"mapped",[120]],[[120430,120430],"mapped",[121]],[[120431,120431],"mapped",[122]],[[120432,120432],"mapped",[97]],[[120433,120433],"mapped",[98]],[[120434,120434],"mapped",[99]],[[120435,120435],"mapped",[100]],[[120436,120436],"mapped",[101]],[[120437,120437],"mapped",[102]],[[120438,120438],"mapped",[103]],[[120439,120439],"mapped",[104]],[[120440,120440],"mapped",[105]],[[120441,120441],"mapped",[106]],[[120442,120442],"mapped",[107]],[[120443,120443],"mapped",[108]],[[120444,120444],"mapped",[109]],[[120445,120445],"mapped",[110]],[[120446,120446],"mapped",[111]],[[120447,120447],"mapped",[112]],[[120448,120448],"mapped",[113]],[[120449,120449],"mapped",[114]],[[120450,120450],"mapped",[115]],[[120451,120451],"mapped",[116]],[[120452,120452],"mapped",[117]],[[120453,120453],"mapped",[118]],[[120454,120454],"mapped",[119]],[[120455,120455],"mapped",[120]],[[120456,120456],"mapped",[121]],[[120457,120457],"mapped",[122]],[[120458,120458],"mapped",[97]],[[120459,120459],"mapped",[98]],[[120460,120460],"mapped",[99]],[[120461,120461],"mapped",[100]],[[120462,120462],"mapped",[101]],[[120463,120463],"mapped",[102]],[[120464,120464],"mapped",[103]],[[120465,120465],"mapped",[104]],[[120466,120466],"mapped",[105]],[[120467,120467],"mapped",[106]],[[120468,120468],"mapped",[107]],[[120469,120469],"mapped",[108]],[[120470,120470],"mapped",[109]],[[120471,120471],"mapped",[110]],[[120472,120472],"mapped",[111]],[[120473,120473],"mapped",[112]],[[120474,120474],"mapped",[113]],[[120475,120475],"mapped",[114]],[[120476,120476],"mapped",[115]],[[120477,120477],"mapped",[116]],[[120478,120478],"mapped",[117]],[[120479,120479],"mapped",[118]],[[120480,120480],"mapped",[119]],[[120481,120481],"mapped",[120]],[[120482,120482],"mapped",[121]],[[120483,120483],"mapped",[122]],[[120484,120484],"mapped",[305]],[[120485,120485],"mapped",[567]],[[120486,120487],"disallowed"],[[120488,120488],"mapped",[945]],[[120489,120489],"mapped",[946]],[[120490,120490],"mapped",[947]],[[120491,120491],"mapped",[948]],[[120492,120492],"mapped",[949]],[[120493,120493],"mapped",[950]],[[120494,120494],"mapped",[951]],[[120495,120495],"mapped",[952]],[[120496,120496],"mapped",[953]],[[120497,120497],"mapped",[954]],[[120498,120498],"mapped",[955]],[[120499,120499],"mapped",[956]],[[120500,120500],"mapped",[957]],[[120501,120501],"mapped",[958]],[[120502,120502],"mapped",[959]],[[120503,120503],"mapped",[960]],[[120504,120504],"mapped",[961]],[[120505,120505],"mapped",[952]],[[120506,120506],"mapped",[963]],[[120507,120507],"mapped",[964]],[[120508,120508],"mapped",[965]],[[120509,120509],"mapped",[966]],[[120510,120510],"mapped",[967]],[[120511,120511],"mapped",[968]],[[120512,120512],"mapped",[969]],[[120513,120513],"mapped",[8711]],[[120514,120514],"mapped",[945]],[[120515,120515],"mapped",[946]],[[120516,120516],"mapped",[947]],[[120517,120517],"mapped",[948]],[[120518,120518],"mapped",[949]],[[120519,120519],"mapped",[950]],[[120520,120520],"mapped",[951]],[[120521,120521],"mapped",[952]],[[120522,120522],"mapped",[953]],[[120523,120523],"mapped",[954]],[[120524,120524],"mapped",[955]],[[120525,120525],"mapped",[956]],[[120526,120526],"mapped",[957]],[[120527,120527],"mapped",[958]],[[120528,120528],"mapped",[959]],[[120529,120529],"mapped",[960]],[[120530,120530],"mapped",[961]],[[120531,120532],"mapped",[963]],[[120533,120533],"mapped",[964]],[[120534,120534],"mapped",[965]],[[120535,120535],"mapped",[966]],[[120536,120536],"mapped",[967]],[[120537,120537],"mapped",[968]],[[120538,120538],"mapped",[969]],[[120539,120539],"mapped",[8706]],[[120540,120540],"mapped",[949]],[[120541,120541],"mapped",[952]],[[120542,120542],"mapped",[954]],[[120543,120543],"mapped",[966]],[[120544,120544],"mapped",[961]],[[120545,120545],"mapped",[960]],[[120546,120546],"mapped",[945]],[[120547,120547],"mapped",[946]],[[120548,120548],"mapped",[947]],[[120549,120549],"mapped",[948]],[[120550,120550],"mapped",[949]],[[120551,120551],"mapped",[950]],[[120552,120552],"mapped",[951]],[[120553,120553],"mapped",[952]],[[120554,120554],"mapped",[953]],[[120555,120555],"mapped",[954]],[[120556,120556],"mapped",[955]],[[120557,120557],"mapped",[956]],[[120558,120558],"mapped",[957]],[[120559,120559],"mapped",[958]],[[120560,120560],"mapped",[959]],[[120561,120561],"mapped",[960]],[[120562,120562],"mapped",[961]],[[120563,120563],"mapped",[952]],[[120564,120564],"mapped",[963]],[[120565,120565],"mapped",[964]],[[120566,120566],"mapped",[965]],[[120567,120567],"mapped",[966]],[[120568,120568],"mapped",[967]],[[120569,120569],"mapped",[968]],[[120570,120570],"mapped",[969]],[[120571,120571],"mapped",[8711]],[[120572,120572],"mapped",[945]],[[120573,120573],"mapped",[946]],[[120574,120574],"mapped",[947]],[[120575,120575],"mapped",[948]],[[120576,120576],"mapped",[949]],[[120577,120577],"mapped",[950]],[[120578,120578],"mapped",[951]],[[120579,120579],"mapped",[952]],[[120580,120580],"mapped",[953]],[[120581,120581],"mapped",[954]],[[120582,120582],"mapped",[955]],[[120583,120583],"mapped",[956]],[[120584,120584],"mapped",[957]],[[120585,120585],"mapped",[958]],[[120586,120586],"mapped",[959]],[[120587,120587],"mapped",[960]],[[120588,120588],"mapped",[961]],[[120589,120590],"mapped",[963]],[[120591,120591],"mapped",[964]],[[120592,120592],"mapped",[965]],[[120593,120593],"mapped",[966]],[[120594,120594],"mapped",[967]],[[120595,120595],"mapped",[968]],[[120596,120596],"mapped",[969]],[[120597,120597],"mapped",[8706]],[[120598,120598],"mapped",[949]],[[120599,120599],"mapped",[952]],[[120600,120600],"mapped",[954]],[[120601,120601],"mapped",[966]],[[120602,120602],"mapped",[961]],[[120603,120603],"mapped",[960]],[[120604,120604],"mapped",[945]],[[120605,120605],"mapped",[946]],[[120606,120606],"mapped",[947]],[[120607,120607],"mapped",[948]],[[120608,120608],"mapped",[949]],[[120609,120609],"mapped",[950]],[[120610,120610],"mapped",[951]],[[120611,120611],"mapped",[952]],[[120612,120612],"mapped",[953]],[[120613,120613],"mapped",[954]],[[120614,120614],"mapped",[955]],[[120615,120615],"mapped",[956]],[[120616,120616],"mapped",[957]],[[120617,120617],"mapped",[958]],[[120618,120618],"mapped",[959]],[[120619,120619],"mapped",[960]],[[120620,120620],"mapped",[961]],[[120621,120621],"mapped",[952]],[[120622,120622],"mapped",[963]],[[120623,120623],"mapped",[964]],[[120624,120624],"mapped",[965]],[[120625,120625],"mapped",[966]],[[120626,120626],"mapped",[967]],[[120627,120627],"mapped",[968]],[[120628,120628],"mapped",[969]],[[120629,120629],"mapped",[8711]],[[120630,120630],"mapped",[945]],[[120631,120631],"mapped",[946]],[[120632,120632],"mapped",[947]],[[120633,120633],"mapped",[948]],[[120634,120634],"mapped",[949]],[[120635,120635],"mapped",[950]],[[120636,120636],"mapped",[951]],[[120637,120637],"mapped",[952]],[[120638,120638],"mapped",[953]],[[120639,120639],"mapped",[954]],[[120640,120640],"mapped",[955]],[[120641,120641],"mapped",[956]],[[120642,120642],"mapped",[957]],[[120643,120643],"mapped",[958]],[[120644,120644],"mapped",[959]],[[120645,120645],"mapped",[960]],[[120646,120646],"mapped",[961]],[[120647,120648],"mapped",[963]],[[120649,120649],"mapped",[964]],[[120650,120650],"mapped",[965]],[[120651,120651],"mapped",[966]],[[120652,120652],"mapped",[967]],[[120653,120653],"mapped",[968]],[[120654,120654],"mapped",[969]],[[120655,120655],"mapped",[8706]],[[120656,120656],"mapped",[949]],[[120657,120657],"mapped",[952]],[[120658,120658],"mapped",[954]],[[120659,120659],"mapped",[966]],[[120660,120660],"mapped",[961]],[[120661,120661],"mapped",[960]],[[120662,120662],"mapped",[945]],[[120663,120663],"mapped",[946]],[[120664,120664],"mapped",[947]],[[120665,120665],"mapped",[948]],[[120666,120666],"mapped",[949]],[[120667,120667],"mapped",[950]],[[120668,120668],"mapped",[951]],[[120669,120669],"mapped",[952]],[[120670,120670],"mapped",[953]],[[120671,120671],"mapped",[954]],[[120672,120672],"mapped",[955]],[[120673,120673],"mapped",[956]],[[120674,120674],"mapped",[957]],[[120675,120675],"mapped",[958]],[[120676,120676],"mapped",[959]],[[120677,120677],"mapped",[960]],[[120678,120678],"mapped",[961]],[[120679,120679],"mapped",[952]],[[120680,120680],"mapped",[963]],[[120681,120681],"mapped",[964]],[[120682,120682],"mapped",[965]],[[120683,120683],"mapped",[966]],[[120684,120684],"mapped",[967]],[[120685,120685],"mapped",[968]],[[120686,120686],"mapped",[969]],[[120687,120687],"mapped",[8711]],[[120688,120688],"mapped",[945]],[[120689,120689],"mapped",[946]],[[120690,120690],"mapped",[947]],[[120691,120691],"mapped",[948]],[[120692,120692],"mapped",[949]],[[120693,120693],"mapped",[950]],[[120694,120694],"mapped",[951]],[[120695,120695],"mapped",[952]],[[120696,120696],"mapped",[953]],[[120697,120697],"mapped",[954]],[[120698,120698],"mapped",[955]],[[120699,120699],"mapped",[956]],[[120700,120700],"mapped",[957]],[[120701,120701],"mapped",[958]],[[120702,120702],"mapped",[959]],[[120703,120703],"mapped",[960]],[[120704,120704],"mapped",[961]],[[120705,120706],"mapped",[963]],[[120707,120707],"mapped",[964]],[[120708,120708],"mapped",[965]],[[120709,120709],"mapped",[966]],[[120710,120710],"mapped",[967]],[[120711,120711],"mapped",[968]],[[120712,120712],"mapped",[969]],[[120713,120713],"mapped",[8706]],[[120714,120714],"mapped",[949]],[[120715,120715],"mapped",[952]],[[120716,120716],"mapped",[954]],[[120717,120717],"mapped",[966]],[[120718,120718],"mapped",[961]],[[120719,120719],"mapped",[960]],[[120720,120720],"mapped",[945]],[[120721,120721],"mapped",[946]],[[120722,120722],"mapped",[947]],[[120723,120723],"mapped",[948]],[[120724,120724],"mapped",[949]],[[120725,120725],"mapped",[950]],[[120726,120726],"mapped",[951]],[[120727,120727],"mapped",[952]],[[120728,120728],"mapped",[953]],[[120729,120729],"mapped",[954]],[[120730,120730],"mapped",[955]],[[120731,120731],"mapped",[956]],[[120732,120732],"mapped",[957]],[[120733,120733],"mapped",[958]],[[120734,120734],"mapped",[959]],[[120735,120735],"mapped",[960]],[[120736,120736],"mapped",[961]],[[120737,120737],"mapped",[952]],[[120738,120738],"mapped",[963]],[[120739,120739],"mapped",[964]],[[120740,120740],"mapped",[965]],[[120741,120741],"mapped",[966]],[[120742,120742],"mapped",[967]],[[120743,120743],"mapped",[968]],[[120744,120744],"mapped",[969]],[[120745,120745],"mapped",[8711]],[[120746,120746],"mapped",[945]],[[120747,120747],"mapped",[946]],[[120748,120748],"mapped",[947]],[[120749,120749],"mapped",[948]],[[120750,120750],"mapped",[949]],[[120751,120751],"mapped",[950]],[[120752,120752],"mapped",[951]],[[120753,120753],"mapped",[952]],[[120754,120754],"mapped",[953]],[[120755,120755],"mapped",[954]],[[120756,120756],"mapped",[955]],[[120757,120757],"mapped",[956]],[[120758,120758],"mapped",[957]],[[120759,120759],"mapped",[958]],[[120760,120760],"mapped",[959]],[[120761,120761],"mapped",[960]],[[120762,120762],"mapped",[961]],[[120763,120764],"mapped",[963]],[[120765,120765],"mapped",[964]],[[120766,120766],"mapped",[965]],[[120767,120767],"mapped",[966]],[[120768,120768],"mapped",[967]],[[120769,120769],"mapped",[968]],[[120770,120770],"mapped",[969]],[[120771,120771],"mapped",[8706]],[[120772,120772],"mapped",[949]],[[120773,120773],"mapped",[952]],[[120774,120774],"mapped",[954]],[[120775,120775],"mapped",[966]],[[120776,120776],"mapped",[961]],[[120777,120777],"mapped",[960]],[[120778,120779],"mapped",[989]],[[120780,120781],"disallowed"],[[120782,120782],"mapped",[48]],[[120783,120783],"mapped",[49]],[[120784,120784],"mapped",[50]],[[120785,120785],"mapped",[51]],[[120786,120786],"mapped",[52]],[[120787,120787],"mapped",[53]],[[120788,120788],"mapped",[54]],[[120789,120789],"mapped",[55]],[[120790,120790],"mapped",[56]],[[120791,120791],"mapped",[57]],[[120792,120792],"mapped",[48]],[[120793,120793],"mapped",[49]],[[120794,120794],"mapped",[50]],[[120795,120795],"mapped",[51]],[[120796,120796],"mapped",[52]],[[120797,120797],"mapped",[53]],[[120798,120798],"mapped",[54]],[[120799,120799],"mapped",[55]],[[120800,120800],"mapped",[56]],[[120801,120801],"mapped",[57]],[[120802,120802],"mapped",[48]],[[120803,120803],"mapped",[49]],[[120804,120804],"mapped",[50]],[[120805,120805],"mapped",[51]],[[120806,120806],"mapped",[52]],[[120807,120807],"mapped",[53]],[[120808,120808],"mapped",[54]],[[120809,120809],"mapped",[55]],[[120810,120810],"mapped",[56]],[[120811,120811],"mapped",[57]],[[120812,120812],"mapped",[48]],[[120813,120813],"mapped",[49]],[[120814,120814],"mapped",[50]],[[120815,120815],"mapped",[51]],[[120816,120816],"mapped",[52]],[[120817,120817],"mapped",[53]],[[120818,120818],"mapped",[54]],[[120819,120819],"mapped",[55]],[[120820,120820],"mapped",[56]],[[120821,120821],"mapped",[57]],[[120822,120822],"mapped",[48]],[[120823,120823],"mapped",[49]],[[120824,120824],"mapped",[50]],[[120825,120825],"mapped",[51]],[[120826,120826],"mapped",[52]],[[120827,120827],"mapped",[53]],[[120828,120828],"mapped",[54]],[[120829,120829],"mapped",[55]],[[120830,120830],"mapped",[56]],[[120831,120831],"mapped",[57]],[[120832,121343],"valid",[],"NV8"],[[121344,121398],"valid"],[[121399,121402],"valid",[],"NV8"],[[121403,121452],"valid"],[[121453,121460],"valid",[],"NV8"],[[121461,121461],"valid"],[[121462,121475],"valid",[],"NV8"],[[121476,121476],"valid"],[[121477,121483],"valid",[],"NV8"],[[121484,121498],"disallowed"],[[121499,121503],"valid"],[[121504,121504],"disallowed"],[[121505,121519],"valid"],[[121520,124927],"disallowed"],[[124928,125124],"valid"],[[125125,125126],"disallowed"],[[125127,125135],"valid",[],"NV8"],[[125136,125142],"valid"],[[125143,126463],"disallowed"],[[126464,126464],"mapped",[1575]],[[126465,126465],"mapped",[1576]],[[126466,126466],"mapped",[1580]],[[126467,126467],"mapped",[1583]],[[126468,126468],"disallowed"],[[126469,126469],"mapped",[1608]],[[126470,126470],"mapped",[1586]],[[126471,126471],"mapped",[1581]],[[126472,126472],"mapped",[1591]],[[126473,126473],"mapped",[1610]],[[126474,126474],"mapped",[1603]],[[126475,126475],"mapped",[1604]],[[126476,126476],"mapped",[1605]],[[126477,126477],"mapped",[1606]],[[126478,126478],"mapped",[1587]],[[126479,126479],"mapped",[1593]],[[126480,126480],"mapped",[1601]],[[126481,126481],"mapped",[1589]],[[126482,126482],"mapped",[1602]],[[126483,126483],"mapped",[1585]],[[126484,126484],"mapped",[1588]],[[126485,126485],"mapped",[1578]],[[126486,126486],"mapped",[1579]],[[126487,126487],"mapped",[1582]],[[126488,126488],"mapped",[1584]],[[126489,126489],"mapped",[1590]],[[126490,126490],"mapped",[1592]],[[126491,126491],"mapped",[1594]],[[126492,126492],"mapped",[1646]],[[126493,126493],"mapped",[1722]],[[126494,126494],"mapped",[1697]],[[126495,126495],"mapped",[1647]],[[126496,126496],"disallowed"],[[126497,126497],"mapped",[1576]],[[126498,126498],"mapped",[1580]],[[126499,126499],"disallowed"],[[126500,126500],"mapped",[1607]],[[126501,126502],"disallowed"],[[126503,126503],"mapped",[1581]],[[126504,126504],"disallowed"],[[126505,126505],"mapped",[1610]],[[126506,126506],"mapped",[1603]],[[126507,126507],"mapped",[1604]],[[126508,126508],"mapped",[1605]],[[126509,126509],"mapped",[1606]],[[126510,126510],"mapped",[1587]],[[126511,126511],"mapped",[1593]],[[126512,126512],"mapped",[1601]],[[126513,126513],"mapped",[1589]],[[126514,126514],"mapped",[1602]],[[126515,126515],"disallowed"],[[126516,126516],"mapped",[1588]],[[126517,126517],"mapped",[1578]],[[126518,126518],"mapped",[1579]],[[126519,126519],"mapped",[1582]],[[126520,126520],"disallowed"],[[126521,126521],"mapped",[1590]],[[126522,126522],"disallowed"],[[126523,126523],"mapped",[1594]],[[126524,126529],"disallowed"],[[126530,126530],"mapped",[1580]],[[126531,126534],"disallowed"],[[126535,126535],"mapped",[1581]],[[126536,126536],"disallowed"],[[126537,126537],"mapped",[1610]],[[126538,126538],"disallowed"],[[126539,126539],"mapped",[1604]],[[126540,126540],"disallowed"],[[126541,126541],"mapped",[1606]],[[126542,126542],"mapped",[1587]],[[126543,126543],"mapped",[1593]],[[126544,126544],"disallowed"],[[126545,126545],"mapped",[1589]],[[126546,126546],"mapped",[1602]],[[126547,126547],"disallowed"],[[126548,126548],"mapped",[1588]],[[126549,126550],"disallowed"],[[126551,126551],"mapped",[1582]],[[126552,126552],"disallowed"],[[126553,126553],"mapped",[1590]],[[126554,126554],"disallowed"],[[126555,126555],"mapped",[1594]],[[126556,126556],"disallowed"],[[126557,126557],"mapped",[1722]],[[126558,126558],"disallowed"],[[126559,126559],"mapped",[1647]],[[126560,126560],"disallowed"],[[126561,126561],"mapped",[1576]],[[126562,126562],"mapped",[1580]],[[126563,126563],"disallowed"],[[126564,126564],"mapped",[1607]],[[126565,126566],"disallowed"],[[126567,126567],"mapped",[1581]],[[126568,126568],"mapped",[1591]],[[126569,126569],"mapped",[1610]],[[126570,126570],"mapped",[1603]],[[126571,126571],"disallowed"],[[126572,126572],"mapped",[1605]],[[126573,126573],"mapped",[1606]],[[126574,126574],"mapped",[1587]],[[126575,126575],"mapped",[1593]],[[126576,126576],"mapped",[1601]],[[126577,126577],"mapped",[1589]],[[126578,126578],"mapped",[1602]],[[126579,126579],"disallowed"],[[126580,126580],"mapped",[1588]],[[126581,126581],"mapped",[1578]],[[126582,126582],"mapped",[1579]],[[126583,126583],"mapped",[1582]],[[126584,126584],"disallowed"],[[126585,126585],"mapped",[1590]],[[126586,126586],"mapped",[1592]],[[126587,126587],"mapped",[1594]],[[126588,126588],"mapped",[1646]],[[126589,126589],"disallowed"],[[126590,126590],"mapped",[1697]],[[126591,126591],"disallowed"],[[126592,126592],"mapped",[1575]],[[126593,126593],"mapped",[1576]],[[126594,126594],"mapped",[1580]],[[126595,126595],"mapped",[1583]],[[126596,126596],"mapped",[1607]],[[126597,126597],"mapped",[1608]],[[126598,126598],"mapped",[1586]],[[126599,126599],"mapped",[1581]],[[126600,126600],"mapped",[1591]],[[126601,126601],"mapped",[1610]],[[126602,126602],"disallowed"],[[126603,126603],"mapped",[1604]],[[126604,126604],"mapped",[1605]],[[126605,126605],"mapped",[1606]],[[126606,126606],"mapped",[1587]],[[126607,126607],"mapped",[1593]],[[126608,126608],"mapped",[1601]],[[126609,126609],"mapped",[1589]],[[126610,126610],"mapped",[1602]],[[126611,126611],"mapped",[1585]],[[126612,126612],"mapped",[1588]],[[126613,126613],"mapped",[1578]],[[126614,126614],"mapped",[1579]],[[126615,126615],"mapped",[1582]],[[126616,126616],"mapped",[1584]],[[126617,126617],"mapped",[1590]],[[126618,126618],"mapped",[1592]],[[126619,126619],"mapped",[1594]],[[126620,126624],"disallowed"],[[126625,126625],"mapped",[1576]],[[126626,126626],"mapped",[1580]],[[126627,126627],"mapped",[1583]],[[126628,126628],"disallowed"],[[126629,126629],"mapped",[1608]],[[126630,126630],"mapped",[1586]],[[126631,126631],"mapped",[1581]],[[126632,126632],"mapped",[1591]],[[126633,126633],"mapped",[1610]],[[126634,126634],"disallowed"],[[126635,126635],"mapped",[1604]],[[126636,126636],"mapped",[1605]],[[126637,126637],"mapped",[1606]],[[126638,126638],"mapped",[1587]],[[126639,126639],"mapped",[1593]],[[126640,126640],"mapped",[1601]],[[126641,126641],"mapped",[1589]],[[126642,126642],"mapped",[1602]],[[126643,126643],"mapped",[1585]],[[126644,126644],"mapped",[1588]],[[126645,126645],"mapped",[1578]],[[126646,126646],"mapped",[1579]],[[126647,126647],"mapped",[1582]],[[126648,126648],"mapped",[1584]],[[126649,126649],"mapped",[1590]],[[126650,126650],"mapped",[1592]],[[126651,126651],"mapped",[1594]],[[126652,126703],"disallowed"],[[126704,126705],"valid",[],"NV8"],[[126706,126975],"disallowed"],[[126976,127019],"valid",[],"NV8"],[[127020,127023],"disallowed"],[[127024,127123],"valid",[],"NV8"],[[127124,127135],"disallowed"],[[127136,127150],"valid",[],"NV8"],[[127151,127152],"disallowed"],[[127153,127166],"valid",[],"NV8"],[[127167,127167],"valid",[],"NV8"],[[127168,127168],"disallowed"],[[127169,127183],"valid",[],"NV8"],[[127184,127184],"disallowed"],[[127185,127199],"valid",[],"NV8"],[[127200,127221],"valid",[],"NV8"],[[127222,127231],"disallowed"],[[127232,127232],"disallowed"],[[127233,127233],"disallowed_STD3_mapped",[48,44]],[[127234,127234],"disallowed_STD3_mapped",[49,44]],[[127235,127235],"disallowed_STD3_mapped",[50,44]],[[127236,127236],"disallowed_STD3_mapped",[51,44]],[[127237,127237],"disallowed_STD3_mapped",[52,44]],[[127238,127238],"disallowed_STD3_mapped",[53,44]],[[127239,127239],"disallowed_STD3_mapped",[54,44]],[[127240,127240],"disallowed_STD3_mapped",[55,44]],[[127241,127241],"disallowed_STD3_mapped",[56,44]],[[127242,127242],"disallowed_STD3_mapped",[57,44]],[[127243,127244],"valid",[],"NV8"],[[127245,127247],"disallowed"],[[127248,127248],"disallowed_STD3_mapped",[40,97,41]],[[127249,127249],"disallowed_STD3_mapped",[40,98,41]],[[127250,127250],"disallowed_STD3_mapped",[40,99,41]],[[127251,127251],"disallowed_STD3_mapped",[40,100,41]],[[127252,127252],"disallowed_STD3_mapped",[40,101,41]],[[127253,127253],"disallowed_STD3_mapped",[40,102,41]],[[127254,127254],"disallowed_STD3_mapped",[40,103,41]],[[127255,127255],"disallowed_STD3_mapped",[40,104,41]],[[127256,127256],"disallowed_STD3_mapped",[40,105,41]],[[127257,127257],"disallowed_STD3_mapped",[40,106,41]],[[127258,127258],"disallowed_STD3_mapped",[40,107,41]],[[127259,127259],"disallowed_STD3_mapped",[40,108,41]],[[127260,127260],"disallowed_STD3_mapped",[40,109,41]],[[127261,127261],"disallowed_STD3_mapped",[40,110,41]],[[127262,127262],"disallowed_STD3_mapped",[40,111,41]],[[127263,127263],"disallowed_STD3_mapped",[40,112,41]],[[127264,127264],"disallowed_STD3_mapped",[40,113,41]],[[127265,127265],"disallowed_STD3_mapped",[40,114,41]],[[127266,127266],"disallowed_STD3_mapped",[40,115,41]],[[127267,127267],"disallowed_STD3_mapped",[40,116,41]],[[127268,127268],"disallowed_STD3_mapped",[40,117,41]],[[127269,127269],"disallowed_STD3_mapped",[40,118,41]],[[127270,127270],"disallowed_STD3_mapped",[40,119,41]],[[127271,127271],"disallowed_STD3_mapped",[40,120,41]],[[127272,127272],"disallowed_STD3_mapped",[40,121,41]],[[127273,127273],"disallowed_STD3_mapped",[40,122,41]],[[127274,127274],"mapped",[12308,115,12309]],[[127275,127275],"mapped",[99]],[[127276,127276],"mapped",[114]],[[127277,127277],"mapped",[99,100]],[[127278,127278],"mapped",[119,122]],[[127279,127279],"disallowed"],[[127280,127280],"mapped",[97]],[[127281,127281],"mapped",[98]],[[127282,127282],"mapped",[99]],[[127283,127283],"mapped",[100]],[[127284,127284],"mapped",[101]],[[127285,127285],"mapped",[102]],[[127286,127286],"mapped",[103]],[[127287,127287],"mapped",[104]],[[127288,127288],"mapped",[105]],[[127289,127289],"mapped",[106]],[[127290,127290],"mapped",[107]],[[127291,127291],"mapped",[108]],[[127292,127292],"mapped",[109]],[[127293,127293],"mapped",[110]],[[127294,127294],"mapped",[111]],[[127295,127295],"mapped",[112]],[[127296,127296],"mapped",[113]],[[127297,127297],"mapped",[114]],[[127298,127298],"mapped",[115]],[[127299,127299],"mapped",[116]],[[127300,127300],"mapped",[117]],[[127301,127301],"mapped",[118]],[[127302,127302],"mapped",[119]],[[127303,127303],"mapped",[120]],[[127304,127304],"mapped",[121]],[[127305,127305],"mapped",[122]],[[127306,127306],"mapped",[104,118]],[[127307,127307],"mapped",[109,118]],[[127308,127308],"mapped",[115,100]],[[127309,127309],"mapped",[115,115]],[[127310,127310],"mapped",[112,112,118]],[[127311,127311],"mapped",[119,99]],[[127312,127318],"valid",[],"NV8"],[[127319,127319],"valid",[],"NV8"],[[127320,127326],"valid",[],"NV8"],[[127327,127327],"valid",[],"NV8"],[[127328,127337],"valid",[],"NV8"],[[127338,127338],"mapped",[109,99]],[[127339,127339],"mapped",[109,100]],[[127340,127343],"disallowed"],[[127344,127352],"valid",[],"NV8"],[[127353,127353],"valid",[],"NV8"],[[127354,127354],"valid",[],"NV8"],[[127355,127356],"valid",[],"NV8"],[[127357,127358],"valid",[],"NV8"],[[127359,127359],"valid",[],"NV8"],[[127360,127369],"valid",[],"NV8"],[[127370,127373],"valid",[],"NV8"],[[127374,127375],"valid",[],"NV8"],[[127376,127376],"mapped",[100,106]],[[127377,127386],"valid",[],"NV8"],[[127387,127461],"disallowed"],[[127462,127487],"valid",[],"NV8"],[[127488,127488],"mapped",[12411,12363]],[[127489,127489],"mapped",[12467,12467]],[[127490,127490],"mapped",[12469]],[[127491,127503],"disallowed"],[[127504,127504],"mapped",[25163]],[[127505,127505],"mapped",[23383]],[[127506,127506],"mapped",[21452]],[[127507,127507],"mapped",[12487]],[[127508,127508],"mapped",[20108]],[[127509,127509],"mapped",[22810]],[[127510,127510],"mapped",[35299]],[[127511,127511],"mapped",[22825]],[[127512,127512],"mapped",[20132]],[[127513,127513],"mapped",[26144]],[[127514,127514],"mapped",[28961]],[[127515,127515],"mapped",[26009]],[[127516,127516],"mapped",[21069]],[[127517,127517],"mapped",[24460]],[[127518,127518],"mapped",[20877]],[[127519,127519],"mapped",[26032]],[[127520,127520],"mapped",[21021]],[[127521,127521],"mapped",[32066]],[[127522,127522],"mapped",[29983]],[[127523,127523],"mapped",[36009]],[[127524,127524],"mapped",[22768]],[[127525,127525],"mapped",[21561]],[[127526,127526],"mapped",[28436]],[[127527,127527],"mapped",[25237]],[[127528,127528],"mapped",[25429]],[[127529,127529],"mapped",[19968]],[[127530,127530],"mapped",[19977]],[[127531,127531],"mapped",[36938]],[[127532,127532],"mapped",[24038]],[[127533,127533],"mapped",[20013]],[[127534,127534],"mapped",[21491]],[[127535,127535],"mapped",[25351]],[[127536,127536],"mapped",[36208]],[[127537,127537],"mapped",[25171]],[[127538,127538],"mapped",[31105]],[[127539,127539],"mapped",[31354]],[[127540,127540],"mapped",[21512]],[[127541,127541],"mapped",[28288]],[[127542,127542],"mapped",[26377]],[[127543,127543],"mapped",[26376]],[[127544,127544],"mapped",[30003]],[[127545,127545],"mapped",[21106]],[[127546,127546],"mapped",[21942]],[[127547,127551],"disallowed"],[[127552,127552],"mapped",[12308,26412,12309]],[[127553,127553],"mapped",[12308,19977,12309]],[[127554,127554],"mapped",[12308,20108,12309]],[[127555,127555],"mapped",[12308,23433,12309]],[[127556,127556],"mapped",[12308,28857,12309]],[[127557,127557],"mapped",[12308,25171,12309]],[[127558,127558],"mapped",[12308,30423,12309]],[[127559,127559],"mapped",[12308,21213,12309]],[[127560,127560],"mapped",[12308,25943,12309]],[[127561,127567],"disallowed"],[[127568,127568],"mapped",[24471]],[[127569,127569],"mapped",[21487]],[[127570,127743],"disallowed"],[[127744,127776],"valid",[],"NV8"],[[127777,127788],"valid",[],"NV8"],[[127789,127791],"valid",[],"NV8"],[[127792,127797],"valid",[],"NV8"],[[127798,127798],"valid",[],"NV8"],[[127799,127868],"valid",[],"NV8"],[[127869,127869],"valid",[],"NV8"],[[127870,127871],"valid",[],"NV8"],[[127872,127891],"valid",[],"NV8"],[[127892,127903],"valid",[],"NV8"],[[127904,127940],"valid",[],"NV8"],[[127941,127941],"valid",[],"NV8"],[[127942,127946],"valid",[],"NV8"],[[127947,127950],"valid",[],"NV8"],[[127951,127955],"valid",[],"NV8"],[[127956,127967],"valid",[],"NV8"],[[127968,127984],"valid",[],"NV8"],[[127985,127991],"valid",[],"NV8"],[[127992,127999],"valid",[],"NV8"],[[128000,128062],"valid",[],"NV8"],[[128063,128063],"valid",[],"NV8"],[[128064,128064],"valid",[],"NV8"],[[128065,128065],"valid",[],"NV8"],[[128066,128247],"valid",[],"NV8"],[[128248,128248],"valid",[],"NV8"],[[128249,128252],"valid",[],"NV8"],[[128253,128254],"valid",[],"NV8"],[[128255,128255],"valid",[],"NV8"],[[128256,128317],"valid",[],"NV8"],[[128318,128319],"valid",[],"NV8"],[[128320,128323],"valid",[],"NV8"],[[128324,128330],"valid",[],"NV8"],[[128331,128335],"valid",[],"NV8"],[[128336,128359],"valid",[],"NV8"],[[128360,128377],"valid",[],"NV8"],[[128378,128378],"disallowed"],[[128379,128419],"valid",[],"NV8"],[[128420,128420],"disallowed"],[[128421,128506],"valid",[],"NV8"],[[128507,128511],"valid",[],"NV8"],[[128512,128512],"valid",[],"NV8"],[[128513,128528],"valid",[],"NV8"],[[128529,128529],"valid",[],"NV8"],[[128530,128532],"valid",[],"NV8"],[[128533,128533],"valid",[],"NV8"],[[128534,128534],"valid",[],"NV8"],[[128535,128535],"valid",[],"NV8"],[[128536,128536],"valid",[],"NV8"],[[128537,128537],"valid",[],"NV8"],[[128538,128538],"valid",[],"NV8"],[[128539,128539],"valid",[],"NV8"],[[128540,128542],"valid",[],"NV8"],[[128543,128543],"valid",[],"NV8"],[[128544,128549],"valid",[],"NV8"],[[128550,128551],"valid",[],"NV8"],[[128552,128555],"valid",[],"NV8"],[[128556,128556],"valid",[],"NV8"],[[128557,128557],"valid",[],"NV8"],[[128558,128559],"valid",[],"NV8"],[[128560,128563],"valid",[],"NV8"],[[128564,128564],"valid",[],"NV8"],[[128565,128576],"valid",[],"NV8"],[[128577,128578],"valid",[],"NV8"],[[128579,128580],"valid",[],"NV8"],[[128581,128591],"valid",[],"NV8"],[[128592,128639],"valid",[],"NV8"],[[128640,128709],"valid",[],"NV8"],[[128710,128719],"valid",[],"NV8"],[[128720,128720],"valid",[],"NV8"],[[128721,128735],"disallowed"],[[128736,128748],"valid",[],"NV8"],[[128749,128751],"disallowed"],[[128752,128755],"valid",[],"NV8"],[[128756,128767],"disallowed"],[[128768,128883],"valid",[],"NV8"],[[128884,128895],"disallowed"],[[128896,128980],"valid",[],"NV8"],[[128981,129023],"disallowed"],[[129024,129035],"valid",[],"NV8"],[[129036,129039],"disallowed"],[[129040,129095],"valid",[],"NV8"],[[129096,129103],"disallowed"],[[129104,129113],"valid",[],"NV8"],[[129114,129119],"disallowed"],[[129120,129159],"valid",[],"NV8"],[[129160,129167],"disallowed"],[[129168,129197],"valid",[],"NV8"],[[129198,129295],"disallowed"],[[129296,129304],"valid",[],"NV8"],[[129305,129407],"disallowed"],[[129408,129412],"valid",[],"NV8"],[[129413,129471],"disallowed"],[[129472,129472],"valid",[],"NV8"],[[129473,131069],"disallowed"],[[131070,131071],"disallowed"],[[131072,173782],"valid"],[[173783,173823],"disallowed"],[[173824,177972],"valid"],[[177973,177983],"disallowed"],[[177984,178205],"valid"],[[178206,178207],"disallowed"],[[178208,183969],"valid"],[[183970,194559],"disallowed"],[[194560,194560],"mapped",[20029]],[[194561,194561],"mapped",[20024]],[[194562,194562],"mapped",[20033]],[[194563,194563],"mapped",[131362]],[[194564,194564],"mapped",[20320]],[[194565,194565],"mapped",[20398]],[[194566,194566],"mapped",[20411]],[[194567,194567],"mapped",[20482]],[[194568,194568],"mapped",[20602]],[[194569,194569],"mapped",[20633]],[[194570,194570],"mapped",[20711]],[[194571,194571],"mapped",[20687]],[[194572,194572],"mapped",[13470]],[[194573,194573],"mapped",[132666]],[[194574,194574],"mapped",[20813]],[[194575,194575],"mapped",[20820]],[[194576,194576],"mapped",[20836]],[[194577,194577],"mapped",[20855]],[[194578,194578],"mapped",[132380]],[[194579,194579],"mapped",[13497]],[[194580,194580],"mapped",[20839]],[[194581,194581],"mapped",[20877]],[[194582,194582],"mapped",[132427]],[[194583,194583],"mapped",[20887]],[[194584,194584],"mapped",[20900]],[[194585,194585],"mapped",[20172]],[[194586,194586],"mapped",[20908]],[[194587,194587],"mapped",[20917]],[[194588,194588],"mapped",[168415]],[[194589,194589],"mapped",[20981]],[[194590,194590],"mapped",[20995]],[[194591,194591],"mapped",[13535]],[[194592,194592],"mapped",[21051]],[[194593,194593],"mapped",[21062]],[[194594,194594],"mapped",[21106]],[[194595,194595],"mapped",[21111]],[[194596,194596],"mapped",[13589]],[[194597,194597],"mapped",[21191]],[[194598,194598],"mapped",[21193]],[[194599,194599],"mapped",[21220]],[[194600,194600],"mapped",[21242]],[[194601,194601],"mapped",[21253]],[[194602,194602],"mapped",[21254]],[[194603,194603],"mapped",[21271]],[[194604,194604],"mapped",[21321]],[[194605,194605],"mapped",[21329]],[[194606,194606],"mapped",[21338]],[[194607,194607],"mapped",[21363]],[[194608,194608],"mapped",[21373]],[[194609,194611],"mapped",[21375]],[[194612,194612],"mapped",[133676]],[[194613,194613],"mapped",[28784]],[[194614,194614],"mapped",[21450]],[[194615,194615],"mapped",[21471]],[[194616,194616],"mapped",[133987]],[[194617,194617],"mapped",[21483]],[[194618,194618],"mapped",[21489]],[[194619,194619],"mapped",[21510]],[[194620,194620],"mapped",[21662]],[[194621,194621],"mapped",[21560]],[[194622,194622],"mapped",[21576]],[[194623,194623],"mapped",[21608]],[[194624,194624],"mapped",[21666]],[[194625,194625],"mapped",[21750]],[[194626,194626],"mapped",[21776]],[[194627,194627],"mapped",[21843]],[[194628,194628],"mapped",[21859]],[[194629,194630],"mapped",[21892]],[[194631,194631],"mapped",[21913]],[[194632,194632],"mapped",[21931]],[[194633,194633],"mapped",[21939]],[[194634,194634],"mapped",[21954]],[[194635,194635],"mapped",[22294]],[[194636,194636],"mapped",[22022]],[[194637,194637],"mapped",[22295]],[[194638,194638],"mapped",[22097]],[[194639,194639],"mapped",[22132]],[[194640,194640],"mapped",[20999]],[[194641,194641],"mapped",[22766]],[[194642,194642],"mapped",[22478]],[[194643,194643],"mapped",[22516]],[[194644,194644],"mapped",[22541]],[[194645,194645],"mapped",[22411]],[[194646,194646],"mapped",[22578]],[[194647,194647],"mapped",[22577]],[[194648,194648],"mapped",[22700]],[[194649,194649],"mapped",[136420]],[[194650,194650],"mapped",[22770]],[[194651,194651],"mapped",[22775]],[[194652,194652],"mapped",[22790]],[[194653,194653],"mapped",[22810]],[[194654,194654],"mapped",[22818]],[[194655,194655],"mapped",[22882]],[[194656,194656],"mapped",[136872]],[[194657,194657],"mapped",[136938]],[[194658,194658],"mapped",[23020]],[[194659,194659],"mapped",[23067]],[[194660,194660],"mapped",[23079]],[[194661,194661],"mapped",[23000]],[[194662,194662],"mapped",[23142]],[[194663,194663],"mapped",[14062]],[[194664,194664],"disallowed"],[[194665,194665],"mapped",[23304]],[[194666,194667],"mapped",[23358]],[[194668,194668],"mapped",[137672]],[[194669,194669],"mapped",[23491]],[[194670,194670],"mapped",[23512]],[[194671,194671],"mapped",[23527]],[[194672,194672],"mapped",[23539]],[[194673,194673],"mapped",[138008]],[[194674,194674],"mapped",[23551]],[[194675,194675],"mapped",[23558]],[[194676,194676],"disallowed"],[[194677,194677],"mapped",[23586]],[[194678,194678],"mapped",[14209]],[[194679,194679],"mapped",[23648]],[[194680,194680],"mapped",[23662]],[[194681,194681],"mapped",[23744]],[[194682,194682],"mapped",[23693]],[[194683,194683],"mapped",[138724]],[[194684,194684],"mapped",[23875]],[[194685,194685],"mapped",[138726]],[[194686,194686],"mapped",[23918]],[[194687,194687],"mapped",[23915]],[[194688,194688],"mapped",[23932]],[[194689,194689],"mapped",[24033]],[[194690,194690],"mapped",[24034]],[[194691,194691],"mapped",[14383]],[[194692,194692],"mapped",[24061]],[[194693,194693],"mapped",[24104]],[[194694,194694],"mapped",[24125]],[[194695,194695],"mapped",[24169]],[[194696,194696],"mapped",[14434]],[[194697,194697],"mapped",[139651]],[[194698,194698],"mapped",[14460]],[[194699,194699],"mapped",[24240]],[[194700,194700],"mapped",[24243]],[[194701,194701],"mapped",[24246]],[[194702,194702],"mapped",[24266]],[[194703,194703],"mapped",[172946]],[[194704,194704],"mapped",[24318]],[[194705,194706],"mapped",[140081]],[[194707,194707],"mapped",[33281]],[[194708,194709],"mapped",[24354]],[[194710,194710],"mapped",[14535]],[[194711,194711],"mapped",[144056]],[[194712,194712],"mapped",[156122]],[[194713,194713],"mapped",[24418]],[[194714,194714],"mapped",[24427]],[[194715,194715],"mapped",[14563]],[[194716,194716],"mapped",[24474]],[[194717,194717],"mapped",[24525]],[[194718,194718],"mapped",[24535]],[[194719,194719],"mapped",[24569]],[[194720,194720],"mapped",[24705]],[[194721,194721],"mapped",[14650]],[[194722,194722],"mapped",[14620]],[[194723,194723],"mapped",[24724]],[[194724,194724],"mapped",[141012]],[[194725,194725],"mapped",[24775]],[[194726,194726],"mapped",[24904]],[[194727,194727],"mapped",[24908]],[[194728,194728],"mapped",[24910]],[[194729,194729],"mapped",[24908]],[[194730,194730],"mapped",[24954]],[[194731,194731],"mapped",[24974]],[[194732,194732],"mapped",[25010]],[[194733,194733],"mapped",[24996]],[[194734,194734],"mapped",[25007]],[[194735,194735],"mapped",[25054]],[[194736,194736],"mapped",[25074]],[[194737,194737],"mapped",[25078]],[[194738,194738],"mapped",[25104]],[[194739,194739],"mapped",[25115]],[[194740,194740],"mapped",[25181]],[[194741,194741],"mapped",[25265]],[[194742,194742],"mapped",[25300]],[[194743,194743],"mapped",[25424]],[[194744,194744],"mapped",[142092]],[[194745,194745],"mapped",[25405]],[[194746,194746],"mapped",[25340]],[[194747,194747],"mapped",[25448]],[[194748,194748],"mapped",[25475]],[[194749,194749],"mapped",[25572]],[[194750,194750],"mapped",[142321]],[[194751,194751],"mapped",[25634]],[[194752,194752],"mapped",[25541]],[[194753,194753],"mapped",[25513]],[[194754,194754],"mapped",[14894]],[[194755,194755],"mapped",[25705]],[[194756,194756],"mapped",[25726]],[[194757,194757],"mapped",[25757]],[[194758,194758],"mapped",[25719]],[[194759,194759],"mapped",[14956]],[[194760,194760],"mapped",[25935]],[[194761,194761],"mapped",[25964]],[[194762,194762],"mapped",[143370]],[[194763,194763],"mapped",[26083]],[[194764,194764],"mapped",[26360]],[[194765,194765],"mapped",[26185]],[[194766,194766],"mapped",[15129]],[[194767,194767],"mapped",[26257]],[[194768,194768],"mapped",[15112]],[[194769,194769],"mapped",[15076]],[[194770,194770],"mapped",[20882]],[[194771,194771],"mapped",[20885]],[[194772,194772],"mapped",[26368]],[[194773,194773],"mapped",[26268]],[[194774,194774],"mapped",[32941]],[[194775,194775],"mapped",[17369]],[[194776,194776],"mapped",[26391]],[[194777,194777],"mapped",[26395]],[[194778,194778],"mapped",[26401]],[[194779,194779],"mapped",[26462]],[[194780,194780],"mapped",[26451]],[[194781,194781],"mapped",[144323]],[[194782,194782],"mapped",[15177]],[[194783,194783],"mapped",[26618]],[[194784,194784],"mapped",[26501]],[[194785,194785],"mapped",[26706]],[[194786,194786],"mapped",[26757]],[[194787,194787],"mapped",[144493]],[[194788,194788],"mapped",[26766]],[[194789,194789],"mapped",[26655]],[[194790,194790],"mapped",[26900]],[[194791,194791],"mapped",[15261]],[[194792,194792],"mapped",[26946]],[[194793,194793],"mapped",[27043]],[[194794,194794],"mapped",[27114]],[[194795,194795],"mapped",[27304]],[[194796,194796],"mapped",[145059]],[[194797,194797],"mapped",[27355]],[[194798,194798],"mapped",[15384]],[[194799,194799],"mapped",[27425]],[[194800,194800],"mapped",[145575]],[[194801,194801],"mapped",[27476]],[[194802,194802],"mapped",[15438]],[[194803,194803],"mapped",[27506]],[[194804,194804],"mapped",[27551]],[[194805,194805],"mapped",[27578]],[[194806,194806],"mapped",[27579]],[[194807,194807],"mapped",[146061]],[[194808,194808],"mapped",[138507]],[[194809,194809],"mapped",[146170]],[[194810,194810],"mapped",[27726]],[[194811,194811],"mapped",[146620]],[[194812,194812],"mapped",[27839]],[[194813,194813],"mapped",[27853]],[[194814,194814],"mapped",[27751]],[[194815,194815],"mapped",[27926]],[[194816,194816],"mapped",[27966]],[[194817,194817],"mapped",[28023]],[[194818,194818],"mapped",[27969]],[[194819,194819],"mapped",[28009]],[[194820,194820],"mapped",[28024]],[[194821,194821],"mapped",[28037]],[[194822,194822],"mapped",[146718]],[[194823,194823],"mapped",[27956]],[[194824,194824],"mapped",[28207]],[[194825,194825],"mapped",[28270]],[[194826,194826],"mapped",[15667]],[[194827,194827],"mapped",[28363]],[[194828,194828],"mapped",[28359]],[[194829,194829],"mapped",[147153]],[[194830,194830],"mapped",[28153]],[[194831,194831],"mapped",[28526]],[[194832,194832],"mapped",[147294]],[[194833,194833],"mapped",[147342]],[[194834,194834],"mapped",[28614]],[[194835,194835],"mapped",[28729]],[[194836,194836],"mapped",[28702]],[[194837,194837],"mapped",[28699]],[[194838,194838],"mapped",[15766]],[[194839,194839],"mapped",[28746]],[[194840,194840],"mapped",[28797]],[[194841,194841],"mapped",[28791]],[[194842,194842],"mapped",[28845]],[[194843,194843],"mapped",[132389]],[[194844,194844],"mapped",[28997]],[[194845,194845],"mapped",[148067]],[[194846,194846],"mapped",[29084]],[[194847,194847],"disallowed"],[[194848,194848],"mapped",[29224]],[[194849,194849],"mapped",[29237]],[[194850,194850],"mapped",[29264]],[[194851,194851],"mapped",[149000]],[[194852,194852],"mapped",[29312]],[[194853,194853],"mapped",[29333]],[[194854,194854],"mapped",[149301]],[[194855,194855],"mapped",[149524]],[[194856,194856],"mapped",[29562]],[[194857,194857],"mapped",[29579]],[[194858,194858],"mapped",[16044]],[[194859,194859],"mapped",[29605]],[[194860,194861],"mapped",[16056]],[[194862,194862],"mapped",[29767]],[[194863,194863],"mapped",[29788]],[[194864,194864],"mapped",[29809]],[[194865,194865],"mapped",[29829]],[[194866,194866],"mapped",[29898]],[[194867,194867],"mapped",[16155]],[[194868,194868],"mapped",[29988]],[[194869,194869],"mapped",[150582]],[[194870,194870],"mapped",[30014]],[[194871,194871],"mapped",[150674]],[[194872,194872],"mapped",[30064]],[[194873,194873],"mapped",[139679]],[[194874,194874],"mapped",[30224]],[[194875,194875],"mapped",[151457]],[[194876,194876],"mapped",[151480]],[[194877,194877],"mapped",[151620]],[[194878,194878],"mapped",[16380]],[[194879,194879],"mapped",[16392]],[[194880,194880],"mapped",[30452]],[[194881,194881],"mapped",[151795]],[[194882,194882],"mapped",[151794]],[[194883,194883],"mapped",[151833]],[[194884,194884],"mapped",[151859]],[[194885,194885],"mapped",[30494]],[[194886,194887],"mapped",[30495]],[[194888,194888],"mapped",[30538]],[[194889,194889],"mapped",[16441]],[[194890,194890],"mapped",[30603]],[[194891,194891],"mapped",[16454]],[[194892,194892],"mapped",[16534]],[[194893,194893],"mapped",[152605]],[[194894,194894],"mapped",[30798]],[[194895,194895],"mapped",[30860]],[[194896,194896],"mapped",[30924]],[[194897,194897],"mapped",[16611]],[[194898,194898],"mapped",[153126]],[[194899,194899],"mapped",[31062]],[[194900,194900],"mapped",[153242]],[[194901,194901],"mapped",[153285]],[[194902,194902],"mapped",[31119]],[[194903,194903],"mapped",[31211]],[[194904,194904],"mapped",[16687]],[[194905,194905],"mapped",[31296]],[[194906,194906],"mapped",[31306]],[[194907,194907],"mapped",[31311]],[[194908,194908],"mapped",[153980]],[[194909,194910],"mapped",[154279]],[[194911,194911],"disallowed"],[[194912,194912],"mapped",[16898]],[[194913,194913],"mapped",[154539]],[[194914,194914],"mapped",[31686]],[[194915,194915],"mapped",[31689]],[[194916,194916],"mapped",[16935]],[[194917,194917],"mapped",[154752]],[[194918,194918],"mapped",[31954]],[[194919,194919],"mapped",[17056]],[[194920,194920],"mapped",[31976]],[[194921,194921],"mapped",[31971]],[[194922,194922],"mapped",[32000]],[[194923,194923],"mapped",[155526]],[[194924,194924],"mapped",[32099]],[[194925,194925],"mapped",[17153]],[[194926,194926],"mapped",[32199]],[[194927,194927],"mapped",[32258]],[[194928,194928],"mapped",[32325]],[[194929,194929],"mapped",[17204]],[[194930,194930],"mapped",[156200]],[[194931,194931],"mapped",[156231]],[[194932,194932],"mapped",[17241]],[[194933,194933],"mapped",[156377]],[[194934,194934],"mapped",[32634]],[[194935,194935],"mapped",[156478]],[[194936,194936],"mapped",[32661]],[[194937,194937],"mapped",[32762]],[[194938,194938],"mapped",[32773]],[[194939,194939],"mapped",[156890]],[[194940,194940],"mapped",[156963]],[[194941,194941],"mapped",[32864]],[[194942,194942],"mapped",[157096]],[[194943,194943],"mapped",[32880]],[[194944,194944],"mapped",[144223]],[[194945,194945],"mapped",[17365]],[[194946,194946],"mapped",[32946]],[[194947,194947],"mapped",[33027]],[[194948,194948],"mapped",[17419]],[[194949,194949],"mapped",[33086]],[[194950,194950],"mapped",[23221]],[[194951,194951],"mapped",[157607]],[[194952,194952],"mapped",[157621]],[[194953,194953],"mapped",[144275]],[[194954,194954],"mapped",[144284]],[[194955,194955],"mapped",[33281]],[[194956,194956],"mapped",[33284]],[[194957,194957],"mapped",[36766]],[[194958,194958],"mapped",[17515]],[[194959,194959],"mapped",[33425]],[[194960,194960],"mapped",[33419]],[[194961,194961],"mapped",[33437]],[[194962,194962],"mapped",[21171]],[[194963,194963],"mapped",[33457]],[[194964,194964],"mapped",[33459]],[[194965,194965],"mapped",[33469]],[[194966,194966],"mapped",[33510]],[[194967,194967],"mapped",[158524]],[[194968,194968],"mapped",[33509]],[[194969,194969],"mapped",[33565]],[[194970,194970],"mapped",[33635]],[[194971,194971],"mapped",[33709]],[[194972,194972],"mapped",[33571]],[[194973,194973],"mapped",[33725]],[[194974,194974],"mapped",[33767]],[[194975,194975],"mapped",[33879]],[[194976,194976],"mapped",[33619]],[[194977,194977],"mapped",[33738]],[[194978,194978],"mapped",[33740]],[[194979,194979],"mapped",[33756]],[[194980,194980],"mapped",[158774]],[[194981,194981],"mapped",[159083]],[[194982,194982],"mapped",[158933]],[[194983,194983],"mapped",[17707]],[[194984,194984],"mapped",[34033]],[[194985,194985],"mapped",[34035]],[[194986,194986],"mapped",[34070]],[[194987,194987],"mapped",[160714]],[[194988,194988],"mapped",[34148]],[[194989,194989],"mapped",[159532]],[[194990,194990],"mapped",[17757]],[[194991,194991],"mapped",[17761]],[[194992,194992],"mapped",[159665]],[[194993,194993],"mapped",[159954]],[[194994,194994],"mapped",[17771]],[[194995,194995],"mapped",[34384]],[[194996,194996],"mapped",[34396]],[[194997,194997],"mapped",[34407]],[[194998,194998],"mapped",[34409]],[[194999,194999],"mapped",[34473]],[[195000,195000],"mapped",[34440]],[[195001,195001],"mapped",[34574]],[[195002,195002],"mapped",[34530]],[[195003,195003],"mapped",[34681]],[[195004,195004],"mapped",[34600]],[[195005,195005],"mapped",[34667]],[[195006,195006],"mapped",[34694]],[[195007,195007],"disallowed"],[[195008,195008],"mapped",[34785]],[[195009,195009],"mapped",[34817]],[[195010,195010],"mapped",[17913]],[[195011,195011],"mapped",[34912]],[[195012,195012],"mapped",[34915]],[[195013,195013],"mapped",[161383]],[[195014,195014],"mapped",[35031]],[[195015,195015],"mapped",[35038]],[[195016,195016],"mapped",[17973]],[[195017,195017],"mapped",[35066]],[[195018,195018],"mapped",[13499]],[[195019,195019],"mapped",[161966]],[[195020,195020],"mapped",[162150]],[[195021,195021],"mapped",[18110]],[[195022,195022],"mapped",[18119]],[[195023,195023],"mapped",[35488]],[[195024,195024],"mapped",[35565]],[[195025,195025],"mapped",[35722]],[[195026,195026],"mapped",[35925]],[[195027,195027],"mapped",[162984]],[[195028,195028],"mapped",[36011]],[[195029,195029],"mapped",[36033]],[[195030,195030],"mapped",[36123]],[[195031,195031],"mapped",[36215]],[[195032,195032],"mapped",[163631]],[[195033,195033],"mapped",[133124]],[[195034,195034],"mapped",[36299]],[[195035,195035],"mapped",[36284]],[[195036,195036],"mapped",[36336]],[[195037,195037],"mapped",[133342]],[[195038,195038],"mapped",[36564]],[[195039,195039],"mapped",[36664]],[[195040,195040],"mapped",[165330]],[[195041,195041],"mapped",[165357]],[[195042,195042],"mapped",[37012]],[[195043,195043],"mapped",[37105]],[[195044,195044],"mapped",[37137]],[[195045,195045],"mapped",[165678]],[[195046,195046],"mapped",[37147]],[[195047,195047],"mapped",[37432]],[[195048,195048],"mapped",[37591]],[[195049,195049],"mapped",[37592]],[[195050,195050],"mapped",[37500]],[[195051,195051],"mapped",[37881]],[[195052,195052],"mapped",[37909]],[[195053,195053],"mapped",[166906]],[[195054,195054],"mapped",[38283]],[[195055,195055],"mapped",[18837]],[[195056,195056],"mapped",[38327]],[[195057,195057],"mapped",[167287]],[[195058,195058],"mapped",[18918]],[[195059,195059],"mapped",[38595]],[[195060,195060],"mapped",[23986]],[[195061,195061],"mapped",[38691]],[[195062,195062],"mapped",[168261]],[[195063,195063],"mapped",[168474]],[[195064,195064],"mapped",[19054]],[[195065,195065],"mapped",[19062]],[[195066,195066],"mapped",[38880]],[[195067,195067],"mapped",[168970]],[[195068,195068],"mapped",[19122]],[[195069,195069],"mapped",[169110]],[[195070,195071],"mapped",[38923]],[[195072,195072],"mapped",[38953]],[[195073,195073],"mapped",[169398]],[[195074,195074],"mapped",[39138]],[[195075,195075],"mapped",[19251]],[[195076,195076],"mapped",[39209]],[[195077,195077],"mapped",[39335]],[[195078,195078],"mapped",[39362]],[[195079,195079],"mapped",[39422]],[[195080,195080],"mapped",[19406]],[[195081,195081],"mapped",[170800]],[[195082,195082],"mapped",[39698]],[[195083,195083],"mapped",[40000]],[[195084,195084],"mapped",[40189]],[[195085,195085],"mapped",[19662]],[[195086,195086],"mapped",[19693]],[[195087,195087],"mapped",[40295]],[[195088,195088],"mapped",[172238]],[[195089,195089],"mapped",[19704]],[[195090,195090],"mapped",[172293]],[[195091,195091],"mapped",[172558]],[[195092,195092],"mapped",[172689]],[[195093,195093],"mapped",[40635]],[[195094,195094],"mapped",[19798]],[[195095,195095],"mapped",[40697]],[[195096,195096],"mapped",[40702]],[[195097,195097],"mapped",[40709]],[[195098,195098],"mapped",[40719]],[[195099,195099],"mapped",[40726]],[[195100,195100],"mapped",[40763]],[[195101,195101],"mapped",[173568]],[[195102,196605],"disallowed"],[[196606,196607],"disallowed"],[[196608,262141],"disallowed"],[[262142,262143],"disallowed"],[[262144,327677],"disallowed"],[[327678,327679],"disallowed"],[[327680,393213],"disallowed"],[[393214,393215],"disallowed"],[[393216,458749],"disallowed"],[[458750,458751],"disallowed"],[[458752,524285],"disallowed"],[[524286,524287],"disallowed"],[[524288,589821],"disallowed"],[[589822,589823],"disallowed"],[[589824,655357],"disallowed"],[[655358,655359],"disallowed"],[[655360,720893],"disallowed"],[[720894,720895],"disallowed"],[[720896,786429],"disallowed"],[[786430,786431],"disallowed"],[[786432,851965],"disallowed"],[[851966,851967],"disallowed"],[[851968,917501],"disallowed"],[[917502,917503],"disallowed"],[[917504,917504],"disallowed"],[[917505,917505],"disallowed"],[[917506,917535],"disallowed"],[[917536,917631],"disallowed"],[[917632,917759],"disallowed"],[[917760,917999],"ignored"],[[918000,983037],"disallowed"],[[983038,983039],"disallowed"],[[983040,1048573],"disallowed"],[[1048574,1048575],"disallowed"],[[1048576,1114109],"disallowed"],[[1114110,1114111],"disallowed"]]'); + +/***/ }), + +/***/ 6086: +/***/ ((module) => { + +module.exports = JSON.parse('[["8740","䏰䰲䘃䖦䕸𧉧䵷䖳𧲱䳢𧳅㮕䜶䝄䱇䱀𤊿𣘗𧍒𦺋𧃒䱗𪍑䝏䗚䲅𧱬䴇䪤䚡𦬣爥𥩔𡩣𣸆𣽡晍囻"],["8767","綕夝𨮹㷴霴𧯯寛𡵞媤㘥𩺰嫑宷峼杮薓𩥅瑡璝㡵𡵓𣚞𦀡㻬"],["87a1","𥣞㫵竼龗𤅡𨤍𣇪𠪊𣉞䌊蒄龖鐯䤰蘓墖靊鈘秐稲晠権袝瑌篅枂稬剏遆㓦珄𥶹瓆鿇垳䤯呌䄱𣚎堘穲𧭥讏䚮𦺈䆁𥶙箮𢒼鿈𢓁𢓉𢓌鿉蔄𣖻䂴鿊䓡𪷿拁灮鿋"],["8840","㇀",4,"𠄌㇅𠃑𠃍㇆㇇𠃋𡿨㇈𠃊㇉㇊㇋㇌𠄎㇍㇎ĀÁǍÀĒÉĚÈŌÓǑÒ࿿Ê̄Ế࿿Ê̌ỀÊāáǎàɑēéěèīíǐìōóǒòūúǔùǖǘǚ"],["88a1","ǜü࿿ê̄ế࿿ê̌ềêɡ⏚⏛"],["8940","𪎩𡅅"],["8943","攊"],["8946","丽滝鵎釟"],["894c","𧜵撑会伨侨兖兴农凤务动医华发变团声处备夲头学实実岚庆总斉柾栄桥济炼电纤纬纺织经统缆缷艺苏药视设询车轧轮"],["89a1","琑糼緍楆竉刧"],["89ab","醌碸酞肼"],["89b0","贋胶𠧧"],["89b5","肟黇䳍鷉鸌䰾𩷶𧀎鸊𪄳㗁"],["89c1","溚舾甙"],["89c5","䤑马骏龙禇𨑬𡷊𠗐𢫦两亁亀亇亿仫伷㑌侽㹈倃傈㑽㒓㒥円夅凛凼刅争剹劐匧㗇厩㕑厰㕓参吣㕭㕲㚁咓咣咴咹哐哯唘唣唨㖘唿㖥㖿嗗㗅"],["8a40","𧶄唥"],["8a43","𠱂𠴕𥄫喐𢳆㧬𠍁蹆𤶸𩓥䁓𨂾睺𢰸㨴䟕𨅝𦧲𤷪擝𠵼𠾴𠳕𡃴撍蹾𠺖𠰋𠽤𢲩𨉖𤓓"],["8a64","𠵆𩩍𨃩䟴𤺧𢳂骲㩧𩗴㿭㔆𥋇𩟔𧣈𢵄鵮頕"],["8a76","䏙𦂥撴哣𢵌𢯊𡁷㧻𡁯"],["8aa1","𦛚𦜖𧦠擪𥁒𠱃蹨𢆡𨭌𠜱"],["8aac","䠋𠆩㿺塳𢶍"],["8ab2","𤗈𠓼𦂗𠽌𠶖啹䂻䎺"],["8abb","䪴𢩦𡂝膪飵𠶜捹㧾𢝵跀嚡摼㹃"],["8ac9","𪘁𠸉𢫏𢳉"],["8ace","𡃈𣧂㦒㨆𨊛㕸𥹉𢃇噒𠼱𢲲𩜠㒼氽𤸻"],["8adf","𧕴𢺋𢈈𪙛𨳍𠹺𠰴𦠜羓𡃏𢠃𢤹㗻𥇣𠺌𠾍𠺪㾓𠼰𠵇𡅏𠹌"],["8af6","𠺫𠮩𠵈𡃀𡄽㿹𢚖搲𠾭"],["8b40","𣏴𧘹𢯎𠵾𠵿𢱑𢱕㨘𠺘𡃇𠼮𪘲𦭐𨳒𨶙𨳊閪哌苄喹"],["8b55","𩻃鰦骶𧝞𢷮煀腭胬尜𦕲脴㞗卟𨂽醶𠻺𠸏𠹷𠻻㗝𤷫㘉𠳖嚯𢞵𡃉𠸐𠹸𡁸𡅈𨈇𡑕𠹹𤹐𢶤婔𡀝𡀞𡃵𡃶垜𠸑"],["8ba1","𧚔𨋍𠾵𠹻𥅾㜃𠾶𡆀𥋘𪊽𤧚𡠺𤅷𨉼墙剨㘚𥜽箲孨䠀䬬鼧䧧鰟鮍𥭴𣄽嗻㗲嚉丨夂𡯁屮靑𠂆乛亻㔾尣彑忄㣺扌攵歺氵氺灬爫丬犭𤣩罒礻糹罓𦉪㓁"],["8bde","𦍋耂肀𦘒𦥑卝衤见𧢲讠贝钅镸长门𨸏韦页风飞饣𩠐鱼鸟黄歯龜丷𠂇阝户钢"],["8c40","倻淾𩱳龦㷉袏𤅎灷峵䬠𥇍㕙𥴰愢𨨲辧釶熑朙玺𣊁𪄇㲋𡦀䬐磤琂冮𨜏䀉橣𪊺䈣蘏𠩯稪𩥇𨫪靕灍匤𢁾鏴盙𨧣龧矝亣俰傼丯众龨吴綋墒壐𡶶庒庙忂𢜒斋"],["8ca1","𣏹椙橃𣱣泿"],["8ca7","爀𤔅玌㻛𤨓嬕璹讃𥲤𥚕窓篬糃繬苸薗龩袐龪躹龫迏蕟駠鈡龬𨶹𡐿䁱䊢娚"],["8cc9","顨杫䉶圽"],["8cce","藖𤥻芿𧄍䲁𦵴嵻𦬕𦾾龭龮宖龯曧繛湗秊㶈䓃𣉖𢞖䎚䔶"],["8ce6","峕𣬚諹屸㴒𣕑嵸龲煗䕘𤃬𡸣䱷㥸㑊𠆤𦱁諌侴𠈹妿腬顖𩣺弻"],["8d40","𠮟"],["8d42","𢇁𨥭䄂䚻𩁹㼇龳𪆵䃸㟖䛷𦱆䅼𨚲𧏿䕭㣔𥒚䕡䔛䶉䱻䵶䗪㿈𤬏㙡䓞䒽䇭崾嵈嵖㷼㠏嶤嶹㠠㠸幂庽弥徃㤈㤔㤿㥍惗愽峥㦉憷憹懏㦸戬抐拥挘㧸嚱"],["8da1","㨃揢揻搇摚㩋擀崕嘡龟㪗斆㪽旿晓㫲暒㬢朖㭂枤栀㭘桊梄㭲㭱㭻椉楃牜楤榟榅㮼槖㯝橥橴橱檂㯬檙㯲檫檵櫔櫶殁毁毪汵沪㳋洂洆洦涁㳯涤涱渕渘温溆𨧀溻滢滚齿滨滩漤漴㵆𣽁澁澾㵪㵵熷岙㶊瀬㶑灐灔灯灿炉𠌥䏁㗱𠻘"],["8e40","𣻗垾𦻓焾𥟠㙎榢𨯩孴穉𥣡𩓙穥穽𥦬窻窰竂竃燑𦒍䇊竚竝竪䇯咲𥰁笋筕笩𥌎𥳾箢筯莜𥮴𦱿篐萡箒箸𥴠㶭𥱥蒒篺簆簵𥳁籄粃𤢂粦晽𤕸糉糇糦籴糳糵糎"],["8ea1","繧䔝𦹄絝𦻖璍綉綫焵綳緒𤁗𦀩緤㴓緵𡟹緥𨍭縝𦄡𦅚繮纒䌫鑬縧罀罁罇礶𦋐駡羗𦍑羣𡙡𠁨䕜𣝦䔃𨌺翺𦒉者耈耝耨耯𪂇𦳃耻耼聡𢜔䦉𦘦𣷣𦛨朥肧𨩈脇脚墰𢛶汿𦒘𤾸擧𡒊舘𡡞橓𤩥𤪕䑺舩𠬍𦩒𣵾俹𡓽蓢荢𦬊𤦧𣔰𡝳𣷸芪椛芳䇛"],["8f40","蕋苐茚𠸖𡞴㛁𣅽𣕚艻苢茘𣺋𦶣𦬅𦮗𣗎㶿茝嗬莅䔋𦶥莬菁菓㑾𦻔橗蕚㒖𦹂𢻯葘𥯤葱㷓䓤檧葊𣲵祘蒨𦮖𦹷𦹃蓞萏莑䒠蒓蓤𥲑䉀𥳀䕃蔴嫲𦺙䔧蕳䔖枿蘖"],["8fa1","𨘥𨘻藁𧂈蘂𡖂𧃍䕫䕪蘨㙈𡢢号𧎚虾蝱𪃸蟮𢰧螱蟚蠏噡虬桖䘏衅衆𧗠𣶹𧗤衞袜䙛袴袵揁装睷𧜏覇覊覦覩覧覼𨨥觧𧤤𧪽誜瞓釾誐𧩙竩𧬺𣾏䜓𧬸煼謌謟𥐰𥕥謿譌譍誩𤩺讐讛誯𡛟䘕衏貛𧵔𧶏貫㜥𧵓賖𧶘𧶽贒贃𡤐賛灜贑𤳉㻐起"],["9040","趩𨀂𡀔𤦊㭼𨆼𧄌竧躭躶軃鋔輙輭𨍥𨐒辥錃𪊟𠩐辳䤪𨧞𨔽𣶻廸𣉢迹𪀔𨚼𨔁𢌥㦀𦻗逷𨔼𧪾遡𨕬𨘋邨𨜓郄𨛦邮都酧㫰醩釄粬𨤳𡺉鈎沟鉁鉢𥖹銹𨫆𣲛𨬌𥗛"],["90a1","𠴱錬鍫𨫡𨯫炏嫃𨫢𨫥䥥鉄𨯬𨰹𨯿鍳鑛躼閅閦鐦閠濶䊹𢙺𨛘𡉼𣸮䧟氜陻隖䅬隣𦻕懚隶磵𨫠隽双䦡𦲸𠉴𦐐𩂯𩃥𤫑𡤕𣌊霱虂霶䨏䔽䖅𤫩灵孁霛靜𩇕靗孊𩇫靟鐥僐𣂷𣂼鞉鞟鞱鞾韀韒韠𥑬韮琜𩐳響韵𩐝𧥺䫑頴頳顋顦㬎𧅵㵑𠘰𤅜"],["9140","𥜆飊颷飈飇䫿𦴧𡛓喰飡飦飬鍸餹𤨩䭲𩡗𩤅駵騌騻騐驘𥜥㛄𩂱𩯕髠髢𩬅髴䰎鬔鬭𨘀倴鬴𦦨㣃𣁽魐魀𩴾婅𡡣鮎𤉋鰂鯿鰌𩹨鷔𩾷𪆒𪆫𪃡𪄣𪇟鵾鶃𪄴鸎梈"],["91a1","鷄𢅛𪆓𪈠𡤻𪈳鴹𪂹𪊴麐麕麞麢䴴麪麯𤍤黁㭠㧥㴝伲㞾𨰫鼂鼈䮖鐤𦶢鼗鼖鼹嚟嚊齅馸𩂋韲葿齢齩竜龎爖䮾𤥵𤦻煷𤧸𤍈𤩑玞𨯚𡣺禟𨥾𨸶鍩鏳𨩄鋬鎁鏋𨥬𤒹爗㻫睲穃烐𤑳𤏸煾𡟯炣𡢾𣖙㻇𡢅𥐯𡟸㜢𡛻𡠹㛡𡝴𡣑𥽋㜣𡛀坛𤨥𡏾𡊨"],["9240","𡏆𡒶蔃𣚦蔃葕𤦔𧅥𣸱𥕜𣻻𧁒䓴𣛮𩦝𦼦柹㜳㰕㷧塬𡤢栐䁗𣜿𤃡𤂋𤄏𦰡哋嚞𦚱嚒𠿟𠮨𠸍鏆𨬓鎜仸儫㠙𤐶亼𠑥𠍿佋侊𥙑婨𠆫𠏋㦙𠌊𠐔㐵伩𠋀𨺳𠉵諚𠈌亘"],["92a1","働儍侢伃𤨎𣺊佂倮偬傁俌俥偘僼兙兛兝兞湶𣖕𣸹𣺿浲𡢄𣺉冨凃𠗠䓝𠒣𠒒𠒑赺𨪜𠜎剙劤𠡳勡鍮䙺熌𤎌𠰠𤦬𡃤槑𠸝瑹㻞璙琔瑖玘䮎𤪼𤂍叐㖄爏𤃉喴𠍅响𠯆圝鉝雴鍦埝垍坿㘾壋媙𨩆𡛺𡝯𡜐娬妸銏婾嫏娒𥥆𡧳𡡡𤊕㛵洅瑃娡𥺃"],["9340","媁𨯗𠐓鏠璌𡌃焅䥲鐈𨧻鎽㞠尞岞幞幈𡦖𡥼𣫮廍孏𡤃𡤄㜁𡢠㛝𡛾㛓脪𨩇𡶺𣑲𨦨弌弎𡤧𡞫婫𡜻孄蘔𧗽衠恾𢡠𢘫忛㺸𢖯𢖾𩂈𦽳懀𠀾𠁆𢘛憙憘恵𢲛𢴇𤛔𩅍"],["93a1","摱𤙥𢭪㨩𢬢𣑐𩣪𢹸挷𪑛撶挱揑𤧣𢵧护𢲡搻敫楲㯴𣂎𣊭𤦉𣊫唍𣋠𡣙𩐿曎𣊉𣆳㫠䆐𥖄𨬢𥖏𡛼𥕛𥐥磮𣄃𡠪𣈴㑤𣈏𣆂𤋉暎𦴤晫䮓昰𧡰𡷫晣𣋒𣋡昞𥡲㣑𣠺𣞼㮙𣞢𣏾瓐㮖枏𤘪梶栞㯄檾㡣𣟕𤒇樳橒櫉欅𡤒攑梘橌㯗橺歗𣿀𣲚鎠鋲𨯪𨫋"],["9440","銉𨀞𨧜鑧涥漋𤧬浧𣽿㶏渄𤀼娽渊塇洤硂焻𤌚𤉶烱牐犇犔𤞏𤜥兹𤪤𠗫瑺𣻸𣙟𤩊𤤗𥿡㼆㺱𤫟𨰣𣼵悧㻳瓌琼鎇琷䒟𦷪䕑疃㽣𤳙𤴆㽘畕癳𪗆㬙瑨𨫌𤦫𤦎㫻"],["94a1","㷍𤩎㻿𤧅𤣳釺圲鍂𨫣𡡤僟𥈡𥇧睸𣈲眎眏睻𤚗𣞁㩞𤣰琸璛㺿𤪺𤫇䃈𤪖𦆮錇𥖁砞碍碈磒珐祙𧝁𥛣䄎禛蒖禥樭𣻺稺秴䅮𡛦䄲鈵秱𠵌𤦌𠊙𣶺𡝮㖗啫㕰㚪𠇔𠰍竢婙𢛵𥪯𥪜娍𠉛磰娪𥯆竾䇹籝籭䈑𥮳𥺼𥺦糍𤧹𡞰粎籼粮檲緜縇緓罎𦉡"],["9540","𦅜𧭈綗𥺂䉪𦭵𠤖柖𠁎𣗏埄𦐒𦏸𤥢翝笧𠠬𥫩𥵃笌𥸎駦虅驣樜𣐿㧢𤧷𦖭騟𦖠蒀𧄧𦳑䓪脷䐂胆脉腂𦞴飃𦩂艢艥𦩑葓𦶧蘐𧈛媆䅿𡡀嬫𡢡嫤𡣘蚠蜨𣶏蠭𧐢娂"],["95a1","衮佅袇袿裦襥襍𥚃襔𧞅𧞄𨯵𨯙𨮜𨧹㺭蒣䛵䛏㟲訽訜𩑈彍鈫𤊄旔焩烄𡡅鵭貟賩𧷜妚矃姰䍮㛔踪躧𤰉輰轊䋴汘澻𢌡䢛潹溋𡟚鯩㚵𤤯邻邗啱䤆醻鐄𨩋䁢𨫼鐧𨰝𨰻蓥訫閙閧閗閖𨴴瑅㻂𤣿𤩂𤏪㻧𣈥随𨻧𨹦𨹥㻌𤧭𤩸𣿮琒瑫㻼靁𩂰"],["9640","桇䨝𩂓𥟟靝鍨𨦉𨰦𨬯𦎾銺嬑譩䤼珹𤈛鞛靱餸𠼦巁𨯅𤪲頟𩓚鋶𩗗釥䓀𨭐𤩧𨭤飜𨩅㼀鈪䤥萔餻饍𧬆㷽馛䭯馪驜𨭥𥣈檏騡嫾騯𩣱䮐𩥈馼䮽䮗鍽塲𡌂堢𤦸"],["96a1","𡓨硄𢜟𣶸棅㵽鑘㤧慐𢞁𢥫愇鱏鱓鱻鰵鰐魿鯏𩸭鮟𪇵𪃾鴡䲮𤄄鸘䲰鴌𪆴𪃭𪃳𩤯鶥蒽𦸒𦿟𦮂藼䔳𦶤𦺄𦷰萠藮𦸀𣟗𦁤秢𣖜𣙀䤭𤧞㵢鏛銾鍈𠊿碹鉷鑍俤㑀遤𥕝砽硔碶硋𡝗𣇉𤥁㚚佲濚濙瀞瀞吔𤆵垻壳垊鴖埗焴㒯𤆬燫𦱀𤾗嬨𡞵𨩉"],["9740","愌嫎娋䊼𤒈㜬䭻𨧼鎻鎸𡣖𠼝葲𦳀𡐓𤋺𢰦𤏁妔𣶷𦝁綨𦅛𦂤𤦹𤦋𨧺鋥珢㻩璴𨭣𡢟㻡𤪳櫘珳珻㻖𤨾𤪔𡟙𤩦𠎧𡐤𤧥瑈𤤖炥𤥶銄珦鍟𠓾錱𨫎𨨖鎆𨯧𥗕䤵𨪂煫"],["97a1","𤥃𠳿嚤𠘚𠯫𠲸唂秄𡟺緾𡛂𤩐𡡒䔮鐁㜊𨫀𤦭妰𡢿𡢃𧒄媡㛢𣵛㚰鉟婹𨪁𡡢鍴㳍𠪴䪖㦊僴㵩㵌𡎜煵䋻𨈘渏𩃤䓫浗𧹏灧沯㳖𣿭𣸭渂漌㵯𠏵畑㚼㓈䚀㻚䡱姄鉮䤾轁𨰜𦯀堒埈㛖𡑒烾𤍢𤩱𢿣𡊰𢎽梹楧𡎘𣓥𧯴𣛟𨪃𣟖𣏺𤲟樚𣚭𦲷萾䓟䓎"],["9840","𦴦𦵑𦲂𦿞漗𧄉茽𡜺菭𦲀𧁓𡟛妉媂𡞳婡婱𡤅𤇼㜭姯𡜼㛇熎鎐暚𤊥婮娫𤊓樫𣻹𧜶𤑛𤋊焝𤉙𨧡侰𦴨峂𤓎𧹍𤎽樌𤉖𡌄炦焳𤏩㶥泟勇𤩏繥姫崯㷳彜𤩝𡟟綤萦"],["98a1","咅𣫺𣌀𠈔坾𠣕𠘙㿥𡾞𪊶瀃𩅛嵰玏糓𨩙𩐠俈翧狍猐𧫴猸猹𥛶獁獈㺩𧬘遬燵𤣲珡臶㻊県㻑沢国琙琞琟㻢㻰㻴㻺瓓㼎㽓畂畭畲疍㽼痈痜㿀癍㿗癴㿜発𤽜熈嘣覀塩䀝睃䀹条䁅㗛瞘䁪䁯属瞾矋売砘点砜䂨砹硇硑硦葈𥔵礳栃礲䄃"],["9940","䄉禑禙辻稆込䅧窑䆲窼艹䇄竏竛䇏両筢筬筻簒簛䉠䉺类粜䊌粸䊔糭输烀𠳏総緔緐緽羮羴犟䎗耠耥笹耮耱联㷌垴炠肷胩䏭脌猪脎脒畠脔䐁㬹腖腙腚"],["99a1","䐓堺腼膄䐥膓䐭膥埯臁臤艔䒏芦艶苊苘苿䒰荗险榊萅烵葤惣蒈䔄蒾蓡蓸蔐蔸蕒䔻蕯蕰藠䕷虲蚒蚲蛯际螋䘆䘗袮裿褤襇覑𧥧訩訸誔誴豑賔賲贜䞘塟跃䟭仮踺嗘坔蹱嗵躰䠷軎転軤軭軲辷迁迊迌逳駄䢭飠鈓䤞鈨鉘鉫銱銮銿"],["9a40","鋣鋫鋳鋴鋽鍃鎄鎭䥅䥑麿鐗匁鐝鐭鐾䥪鑔鑹锭関䦧间阳䧥枠䨤靀䨵鞲韂噔䫤惨颹䬙飱塄餎餙冴餜餷饂饝饢䭰駅䮝騼鬏窃魩鮁鯝鯱鯴䱭鰠㝯𡯂鵉鰺"],["9aa1","黾噐鶓鶽鷀鷼银辶鹻麬麱麽黆铜黢黱黸竈齄𠂔𠊷𠎠椚铃妬𠓗塀铁㞹𠗕𠘕𠙶𡚺块煳𠫂𠫍𠮿呪吆𠯋咞𠯻𠰻𠱓𠱥𠱼惧𠲍噺𠲵𠳝𠳭𠵯𠶲𠷈楕鰯螥𠸄𠸎𠻗𠾐𠼭𠹳尠𠾼帋𡁜𡁏𡁶朞𡁻𡂈𡂖㙇𡂿𡃓𡄯𡄻卤蒭𡋣𡍵𡌶讁𡕷𡘙𡟃𡟇乸炻𡠭𡥪"],["9b40","𡨭𡩅𡰪𡱰𡲬𡻈拃𡻕𡼕熘桕𢁅槩㛈𢉼𢏗𢏺𢜪𢡱𢥏苽𢥧𢦓𢫕覥𢫨辠𢬎鞸𢬿顇骽𢱌"],["9b62","𢲈𢲷𥯨𢴈𢴒𢶷𢶕𢹂𢽴𢿌𣀳𣁦𣌟𣏞徱晈暿𧩹𣕧𣗳爁𤦺矗𣘚𣜖纇𠍆墵朎"],["9ba1","椘𣪧𧙗𥿢𣸑𣺹𧗾𢂚䣐䪸𤄙𨪚𤋮𤌍𤀻𤌴𤎖𤩅𠗊凒𠘑妟𡺨㮾𣳿𤐄𤓖垈𤙴㦛𤜯𨗨𩧉㝢𢇃譞𨭎駖𤠒𤣻𤨕爉𤫀𠱸奥𤺥𤾆𠝹軚𥀬劏圿煱𥊙𥐙𣽊𤪧喼𥑆𥑮𦭒釔㑳𥔿𧘲𥕞䜘𥕢𥕦𥟇𤤿𥡝偦㓻𣏌惞𥤃䝼𨥈𥪮𥮉𥰆𡶐垡煑澶𦄂𧰒遖𦆲𤾚譢𦐂𦑊"],["9c40","嵛𦯷輶𦒄𡤜諪𤧶𦒈𣿯𦔒䯀𦖿𦚵𢜛鑥𥟡憕娧晉侻嚹𤔡𦛼乪𤤴陖涏𦲽㘘襷𦞙𦡮𦐑𦡞營𦣇筂𩃀𠨑𦤦鄄𦤹穅鷰𦧺騦𦨭㙟𦑩𠀡禃𦨴𦭛崬𣔙菏𦮝䛐𦲤画补𦶮墶"],["9ca1","㜜𢖍𧁋𧇍㱔𧊀𧊅銁𢅺𧊋錰𧋦𤧐氹钟𧑐𠻸蠧裵𢤦𨑳𡞱溸𤨪𡠠㦤㚹尐秣䔿暶𩲭𩢤襃𧟌𧡘囖䃟𡘊㦡𣜯𨃨𡏅熭荦𧧝𩆨婧䲷𧂯𨦫𧧽𧨊𧬋𧵦𤅺筃祾𨀉澵𪋟樃𨌘厢𦸇鎿栶靝𨅯𨀣𦦵𡏭𣈯𨁈嶅𨰰𨂃圕頣𨥉嶫𤦈斾槕叒𤪥𣾁㰑朶𨂐𨃴𨄮𡾡𨅏"],["9d40","𨆉𨆯𨈚𨌆𨌯𨎊㗊𨑨𨚪䣺揦𨥖砈鉕𨦸䏲𨧧䏟𨧨𨭆𨯔姸𨰉輋𨿅𩃬筑𩄐𩄼㷷𩅞𤫊运犏嚋𩓧𩗩𩖰𩖸𩜲𩣑𩥉𩥪𩧃𩨨𩬎𩵚𩶛纟𩻸𩼣䲤镇𪊓熢𪋿䶑递𪗋䶜𠲜达嗁"],["9da1","辺𢒰边𤪓䔉繿潖檱仪㓤𨬬𧢝㜺躀𡟵𨀤𨭬𨮙𧨾𦚯㷫𧙕𣲷𥘵𥥖亚𥺁𦉘嚿𠹭踎孭𣺈𤲞揞拐𡟶𡡻攰嘭𥱊吚𥌑㷆𩶘䱽嘢嘞罉𥻘奵𣵀蝰东𠿪𠵉𣚺脗鵞贘瘻鱅癎瞹鍅吲腈苷嘥脲萘肽嗪祢噃吖𠺝㗎嘅嗱曱𨋢㘭甴嗰喺咗啲𠱁𠲖廐𥅈𠹶𢱢"],["9e40","𠺢麫絚嗞𡁵抝靭咔賍燶酶揼掹揾啩𢭃鱲𢺳冚㓟𠶧冧呍唞唓癦踭𦢊疱肶蠄螆裇膶萜𡃁䓬猄𤜆宐茋𦢓噻𢛴𧴯𤆣𧵳𦻐𧊶酰𡇙鈈𣳼𪚩𠺬𠻹牦𡲢䝎𤿂𧿹𠿫䃺"],["9ea1","鱝攟𢶠䣳𤟠𩵼𠿬𠸊恢𧖣𠿭"],["9ead","𦁈𡆇熣纎鵐业丄㕷嬍沲卧㚬㧜卽㚥𤘘墚𤭮舭呋垪𥪕𠥹"],["9ec5","㩒𢑥獴𩺬䴉鯭𣳾𩼰䱛𤾩𩖞𩿞葜𣶶𧊲𦞳𣜠挮紥𣻷𣸬㨪逈勌㹴㙺䗩𠒎癀嫰𠺶硺𧼮墧䂿噼鮋嵴癔𪐴麅䳡痹㟻愙𣃚𤏲"],["9ef5","噝𡊩垧𤥣𩸆刴𧂮㖭汊鵼"],["9f40","籖鬹埞𡝬屓擓𩓐𦌵𧅤蚭𠴨𦴢𤫢𠵱"],["9f4f","凾𡼏嶎霃𡷑麁遌笟鬂峑箣扨挵髿篏鬪籾鬮籂粆鰕篼鬉鼗鰛𤤾齚啳寃俽麘俲剠㸆勑坧偖妷帒韈鶫轜呩鞴饀鞺匬愰"],["9fa1","椬叚鰊鴂䰻陁榀傦畆𡝭駚剳"],["9fae","酙隁酜"],["9fb2","酑𨺗捿𦴣櫊嘑醎畺抅𠏼獏籰𥰡𣳽"],["9fc1","𤤙盖鮝个𠳔莾衂"],["9fc9","届槀僭坺刟巵从氱𠇲伹咜哚劚趂㗾弌㗳"],["9fdb","歒酼龥鮗頮颴骺麨麄煺笔"],["9fe7","毺蠘罸"],["9feb","嘠𪙊蹷齓"],["9ff0","跔蹏鸜踁抂𨍽踨蹵竓𤩷稾磘泪詧瘇"],["a040","𨩚鼦泎蟖痃𪊲硓咢贌狢獱謭猂瓱賫𤪻蘯徺袠䒷"],["a055","𡠻𦸅"],["a058","詾𢔛"],["a05b","惽癧髗鵄鍮鮏蟵"],["a063","蠏賷猬霡鮰㗖犲䰇籑饊𦅙慙䰄麖慽"],["a073","坟慯抦戹拎㩜懢厪𣏵捤栂㗒"],["a0a1","嵗𨯂迚𨸹"],["a0a6","僙𡵆礆匲阸𠼻䁥"],["a0ae","矾"],["a0b0","糂𥼚糚稭聦聣絍甅瓲覔舚朌聢𧒆聛瓰脃眤覉𦟌畓𦻑螩蟎臈螌詉貭譃眫瓸蓚㘵榲趦"],["a0d4","覩瑨涹蟁𤀑瓧㷛煶悤憜㳑煢恷"],["a0e2","罱𨬭牐惩䭾删㰘𣳇𥻗𧙖𥔱𡥄𡋾𩤃𦷜𧂭峁𦆭𨨏𣙷𠃮𦡆𤼎䕢嬟𦍌齐麦𦉫"],["a3c0","␀",31,"␡"],["c6a1","①",9,"⑴",9,"ⅰ",9,"丶丿亅亠冂冖冫勹匸卩厶夊宀巛⼳广廴彐彡攴无疒癶辵隶¨ˆヽヾゝゞ〃仝々〆〇ー[]✽ぁ",23],["c740","す",58,"ァアィイ"],["c7a1","ゥ",81,"А",5,"ЁЖ",4],["c840","Л",26,"ёж",25,"⇧↸↹㇏𠃌乚𠂊刂䒑"],["c8a1","龰冈龱𧘇"],["c8cd","¬¦'"㈱№℡゛゜⺀⺄⺆⺇⺈⺊⺌⺍⺕⺜⺝⺥⺧⺪⺬⺮⺶⺼⺾⻆⻊⻌⻍⻏⻖⻗⻞⻣"],["c8f5","ʃɐɛɔɵœøŋʊɪ"],["f9fe","■"],["fa40","𠕇鋛𠗟𣿅蕌䊵珯况㙉𤥂𨧤鍄𡧛苮𣳈砼杄拟𤤳𨦪𠊠𦮳𡌅侫𢓭倈𦴩𧪄𣘀𤪱𢔓倩𠍾徤𠎀𠍇滛𠐟偽儁㑺儎顬㝃萖𤦤𠒇兠𣎴兪𠯿𢃼𠋥𢔰𠖎𣈳𡦃宂蝽𠖳𣲙冲冸"],["faa1","鴴凉减凑㳜凓𤪦决凢卂凭菍椾𣜭彻刋刦刼劵剗劔効勅簕蕂勠蘍𦬓包𨫞啉滙𣾀𠥔𣿬匳卄𠯢泋𡜦栛珕恊㺪㣌𡛨燝䒢卭却𨚫卾卿𡖖𡘓矦厓𨪛厠厫厮玧𥝲㽙玜叁叅汉义埾叙㪫𠮏叠𣿫𢶣叶𠱷吓灹唫晗浛呭𦭓𠵴啝咏咤䞦𡜍𠻝㶴𠵍"],["fb40","𨦼𢚘啇䳭启琗喆喩嘅𡣗𤀺䕒𤐵暳𡂴嘷曍𣊊暤暭噍噏磱囱鞇叾圀囯园𨭦㘣𡉏坆𤆥汮炋坂㚱𦱾埦𡐖堃𡑔𤍣堦𤯵塜墪㕡壠壜𡈼壻寿坃𪅐𤉸鏓㖡够梦㛃湙"],["fba1","𡘾娤啓𡚒蔅姉𠵎𦲁𦴪𡟜姙𡟻𡞲𦶦浱𡠨𡛕姹𦹅媫婣㛦𤦩婷㜈媖瑥嫓𦾡𢕔㶅𡤑㜲𡚸広勐孶斈孼𧨎䀄䡝𠈄寕慠𡨴𥧌𠖥寳宝䴐尅𡭄尓珎尔𡲥𦬨屉䣝岅峩峯嶋𡷹𡸷崐崘嵆𡺤岺巗苼㠭𤤁𢁉𢅳芇㠶㯂帮檊幵幺𤒼𠳓厦亷廐厨𡝱帉廴𨒂"],["fc40","廹廻㢠廼栾鐛弍𠇁弢㫞䢮𡌺强𦢈𢏐彘𢑱彣鞽𦹮彲鍀𨨶徧嶶㵟𥉐𡽪𧃸𢙨釖𠊞𨨩怱暅𡡷㥣㷇㘹垐𢞴祱㹀悞悤悳𤦂𤦏𧩓璤僡媠慤萤慂慈𦻒憁凴𠙖憇宪𣾷"],["fca1","𢡟懓𨮝𩥝懐㤲𢦀𢣁怣慜攞掋𠄘担𡝰拕𢸍捬𤧟㨗搸揸𡎎𡟼撐澊𢸶頔𤂌𥜝擡擥鑻㩦携㩗敍漖𤨨𤨣斅敭敟𣁾斵𤥀䬷旑䃘𡠩无旣忟𣐀昘𣇷𣇸晄𣆤𣆥晋𠹵晧𥇦晳晴𡸽𣈱𨗴𣇈𥌓矅𢣷馤朂𤎜𤨡㬫槺𣟂杞杧杢𤇍𩃭柗䓩栢湐鈼栁𣏦𦶠桝"],["fd40","𣑯槡樋𨫟楳棃𣗍椁椀㴲㨁𣘼㮀枬楡𨩊䋼椶榘㮡𠏉荣傐槹𣙙𢄪橅𣜃檝㯳枱櫈𩆜㰍欝𠤣惞欵歴𢟍溵𣫛𠎵𡥘㝀吡𣭚毡𣻼毜氷𢒋𤣱𦭑汚舦汹𣶼䓅𣶽𤆤𤤌𤤀"],["fda1","𣳉㛥㳫𠴲鮃𣇹𢒑羏样𦴥𦶡𦷫涖浜湼漄𤥿𤂅𦹲蔳𦽴凇沜渝萮𨬡港𣸯瑓𣾂秌湏媑𣁋濸㜍澝𣸰滺𡒗𤀽䕕鏰潄潜㵎潴𩅰㴻澟𤅄濓𤂑𤅕𤀹𣿰𣾴𤄿凟𤅖𤅗𤅀𦇝灋灾炧炁烌烕烖烟䄄㷨熴熖𤉷焫煅媈煊煮岜𤍥煏鍢𤋁焬𤑚𤨧𤨢熺𨯨炽爎"],["fe40","鑂爕夑鑃爤鍁𥘅爮牀𤥴梽牕牗㹕𣁄栍漽犂猪猫𤠣𨠫䣭𨠄猨献珏玪𠰺𦨮珉瑉𤇢𡛧𤨤昣㛅𤦷𤦍𤧻珷琕椃𤨦琹𠗃㻗瑜𢢭瑠𨺲瑇珤瑶莹瑬㜰瑴鏱樬璂䥓𤪌"],["fea1","𤅟𤩹𨮏孆𨰃𡢞瓈𡦈甎瓩甞𨻙𡩋寗𨺬鎅畍畊畧畮𤾂㼄𤴓疎瑝疞疴瘂瘬癑癏癯癶𦏵皐臯㟸𦤑𦤎皡皥皷盌𦾟葢𥂝𥅽𡸜眞眦着撯𥈠睘𣊬瞯𨥤𨥨𡛁矴砉𡍶𤨒棊碯磇磓隥礮𥗠磗礴碱𧘌辸袄𨬫𦂃𢘜禆褀椂禀𥡗禝𧬹礼禩渪𧄦㺨秆𩄍秔"]]'); + +/***/ }), + +/***/ 4847: +/***/ ((module) => { + +module.exports = JSON.parse('[["0","\\u0000",127,"€"],["8140","丂丄丅丆丏丒丗丟丠両丣並丩丮丯丱丳丵丷丼乀乁乂乄乆乊乑乕乗乚乛乢乣乤乥乧乨乪",5,"乲乴",9,"乿",6,"亇亊"],["8180","亐亖亗亙亜亝亞亣亪亯亰亱亴亶亷亸亹亼亽亾仈仌仏仐仒仚仛仜仠仢仦仧仩仭仮仯仱仴仸仹仺仼仾伀伂",6,"伋伌伒",4,"伜伝伡伣伨伩伬伭伮伱伳伵伷伹伻伾",4,"佄佅佇",5,"佒佔佖佡佢佦佨佪佫佭佮佱佲併佷佸佹佺佽侀侁侂侅來侇侊侌侎侐侒侓侕侖侘侙侚侜侞侟価侢"],["8240","侤侫侭侰",4,"侶",8,"俀俁係俆俇俈俉俋俌俍俒",4,"俙俛俠俢俤俥俧俫俬俰俲俴俵俶俷俹俻俼俽俿",11],["8280","個倎倐們倓倕倖倗倛倝倞倠倢倣値倧倫倯",10,"倻倽倿偀偁偂偄偅偆偉偊偋偍偐",4,"偖偗偘偙偛偝",7,"偦",5,"偭",8,"偸偹偺偼偽傁傂傃傄傆傇傉傊傋傌傎",20,"傤傦傪傫傭",4,"傳",6,"傼"],["8340","傽",17,"僐",5,"僗僘僙僛",10,"僨僩僪僫僯僰僱僲僴僶",4,"僼",9,"儈"],["8380","儉儊儌",5,"儓",13,"儢",28,"兂兇兊兌兎兏児兒兓兗兘兙兛兝",4,"兣兤兦內兩兪兯兲兺兾兿冃冄円冇冊冋冎冏冐冑冓冔冘冚冝冞冟冡冣冦",4,"冭冮冴冸冹冺冾冿凁凂凃凅凈凊凍凎凐凒",5],["8440","凘凙凚凜凞凟凢凣凥",5,"凬凮凱凲凴凷凾刄刅刉刋刌刏刐刓刔刕刜刞刟刡刢刣別刦刧刪刬刯刱刲刴刵刼刾剄",5,"剋剎剏剒剓剕剗剘"],["8480","剙剚剛剝剟剠剢剣剤剦剨剫剬剭剮剰剱剳",9,"剾劀劃",4,"劉",6,"劑劒劔",6,"劜劤劥劦劧劮劯劰労",9,"勀勁勂勄勅勆勈勊勌勍勎勏勑勓勔動勗務",5,"勠勡勢勣勥",10,"勱",7,"勻勼勽匁匂匃匄匇匉匊匋匌匎"],["8540","匑匒匓匔匘匛匜匞匟匢匤匥匧匨匩匫匬匭匯",9,"匼匽區卂卄卆卋卌卍卐協単卙卛卝卥卨卪卬卭卲卶卹卻卼卽卾厀厁厃厇厈厊厎厏"],["8580","厐",4,"厖厗厙厛厜厞厠厡厤厧厪厫厬厭厯",6,"厷厸厹厺厼厽厾叀參",4,"収叏叐叒叓叕叚叜叝叞叡叢叧叴叺叾叿吀吂吅吇吋吔吘吙吚吜吢吤吥吪吰吳吶吷吺吽吿呁呂呄呅呇呉呌呍呎呏呑呚呝",4,"呣呥呧呩",7,"呴呹呺呾呿咁咃咅咇咈咉咊咍咑咓咗咘咜咞咟咠咡"],["8640","咢咥咮咰咲咵咶咷咹咺咼咾哃哅哊哋哖哘哛哠",4,"哫哬哯哰哱哴",5,"哻哾唀唂唃唄唅唈唊",4,"唒唓唕",5,"唜唝唞唟唡唥唦"],["8680","唨唩唫唭唲唴唵唶唸唹唺唻唽啀啂啅啇啈啋",4,"啑啒啓啔啗",4,"啝啞啟啠啢啣啨啩啫啯",5,"啹啺啽啿喅喆喌喍喎喐喒喓喕喖喗喚喛喞喠",6,"喨",8,"喲喴営喸喺喼喿",4,"嗆嗇嗈嗊嗋嗎嗏嗐嗕嗗",4,"嗞嗠嗢嗧嗩嗭嗮嗰嗱嗴嗶嗸",4,"嗿嘂嘃嘄嘅"],["8740","嘆嘇嘊嘋嘍嘐",7,"嘙嘚嘜嘝嘠嘡嘢嘥嘦嘨嘩嘪嘫嘮嘯嘰嘳嘵嘷嘸嘺嘼嘽嘾噀",11,"噏",4,"噕噖噚噛噝",4],["8780","噣噥噦噧噭噮噯噰噲噳噴噵噷噸噹噺噽",7,"嚇",6,"嚐嚑嚒嚔",14,"嚤",10,"嚰",6,"嚸嚹嚺嚻嚽",12,"囋",8,"囕囖囘囙囜団囥",5,"囬囮囯囲図囶囷囸囻囼圀圁圂圅圇國",6],["8840","園",9,"圝圞圠圡圢圤圥圦圧圫圱圲圴",4,"圼圽圿坁坃坄坅坆坈坉坋坒",4,"坘坙坢坣坥坧坬坮坰坱坲坴坵坸坹坺坽坾坿垀"],["8880","垁垇垈垉垊垍",4,"垔",6,"垜垝垞垟垥垨垪垬垯垰垱垳垵垶垷垹",8,"埄",6,"埌埍埐埑埓埖埗埛埜埞埡埢埣埥",7,"埮埰埱埲埳埵埶執埻埼埾埿堁堃堄堅堈堉堊堌堎堏堐堒堓堔堖堗堘堚堛堜堝堟堢堣堥",4,"堫",4,"報堲堳場堶",7],["8940","堾",5,"塅",6,"塎塏塐塒塓塕塖塗塙",4,"塟",5,"塦",4,"塭",16,"塿墂墄墆墇墈墊墋墌"],["8980","墍",4,"墔",4,"墛墜墝墠",7,"墪",17,"墽墾墿壀壂壃壄壆",10,"壒壓壔壖",13,"壥",5,"壭壯壱売壴壵壷壸壺",7,"夃夅夆夈",4,"夎夐夑夒夓夗夘夛夝夞夠夡夢夣夦夨夬夰夲夳夵夶夻"],["8a40","夽夾夿奀奃奅奆奊奌奍奐奒奓奙奛",4,"奡奣奤奦",12,"奵奷奺奻奼奾奿妀妅妉妋妌妎妏妐妑妔妕妘妚妛妜妝妟妠妡妢妦"],["8a80","妧妬妭妰妱妳",5,"妺妼妽妿",6,"姇姈姉姌姍姎姏姕姖姙姛姞",4,"姤姦姧姩姪姫姭",11,"姺姼姽姾娀娂娊娋娍娎娏娐娒娔娕娖娗娙娚娛娝娞娡娢娤娦娧娨娪",6,"娳娵娷",4,"娽娾娿婁",4,"婇婈婋",9,"婖婗婘婙婛",5],["8b40","婡婣婤婥婦婨婩婫",8,"婸婹婻婼婽婾媀",17,"媓",6,"媜",13,"媫媬"],["8b80","媭",4,"媴媶媷媹",4,"媿嫀嫃",5,"嫊嫋嫍",4,"嫓嫕嫗嫙嫚嫛嫝嫞嫟嫢嫤嫥嫧嫨嫪嫬",4,"嫲",22,"嬊",11,"嬘",25,"嬳嬵嬶嬸",7,"孁",6],["8c40","孈",7,"孒孖孞孠孡孧孨孫孭孮孯孲孴孶孷學孹孻孼孾孿宂宆宊宍宎宐宑宒宔宖実宧宨宩宬宭宮宯宱宲宷宺宻宼寀寁寃寈寉寊寋寍寎寏"],["8c80","寑寔",8,"寠寢寣實寧審",4,"寯寱",6,"寽対尀専尃尅將專尋尌對導尐尒尓尗尙尛尞尟尠尡尣尦尨尩尪尫尭尮尯尰尲尳尵尶尷屃屄屆屇屌屍屒屓屔屖屗屘屚屛屜屝屟屢層屧",6,"屰屲",6,"屻屼屽屾岀岃",4,"岉岊岋岎岏岒岓岕岝",4,"岤",4],["8d40","岪岮岯岰岲岴岶岹岺岻岼岾峀峂峃峅",5,"峌",5,"峓",5,"峚",6,"峢峣峧峩峫峬峮峯峱",9,"峼",4],["8d80","崁崄崅崈",5,"崏",4,"崕崗崘崙崚崜崝崟",4,"崥崨崪崫崬崯",4,"崵",7,"崿",7,"嵈嵉嵍",10,"嵙嵚嵜嵞",10,"嵪嵭嵮嵰嵱嵲嵳嵵",12,"嶃",21,"嶚嶛嶜嶞嶟嶠"],["8e40","嶡",21,"嶸",12,"巆",6,"巎",12,"巜巟巠巣巤巪巬巭"],["8e80","巰巵巶巸",4,"巿帀帄帇帉帊帋帍帎帒帓帗帞",7,"帨",4,"帯帰帲",4,"帹帺帾帿幀幁幃幆",5,"幍",6,"幖",4,"幜幝幟幠幣",14,"幵幷幹幾庁庂広庅庈庉庌庍庎庒庘庛庝庡庢庣庤庨",4,"庮",4,"庴庺庻庼庽庿",6],["8f40","廆廇廈廋",5,"廔廕廗廘廙廚廜",11,"廩廫",8,"廵廸廹廻廼廽弅弆弇弉弌弍弎弐弒弔弖弙弚弜弝弞弡弢弣弤"],["8f80","弨弫弬弮弰弲",6,"弻弽弾弿彁",14,"彑彔彙彚彛彜彞彟彠彣彥彧彨彫彮彯彲彴彵彶彸彺彽彾彿徃徆徍徎徏徑従徔徖徚徛徝從徟徠徢",5,"復徫徬徯",5,"徶徸徹徺徻徾",4,"忇忈忊忋忎忓忔忕忚忛応忞忟忢忣忥忦忨忩忬忯忰忲忳忴忶忷忹忺忼怇"],["9040","怈怉怋怌怐怑怓怗怘怚怞怟怢怣怤怬怭怮怰",4,"怶",4,"怽怾恀恄",6,"恌恎恏恑恓恔恖恗恘恛恜恞恟恠恡恥恦恮恱恲恴恵恷恾悀"],["9080","悁悂悅悆悇悈悊悋悎悏悐悑悓悕悗悘悙悜悞悡悢悤悥悧悩悪悮悰悳悵悶悷悹悺悽",7,"惇惈惉惌",4,"惒惓惔惖惗惙惛惞惡",4,"惪惱惲惵惷惸惻",4,"愂愃愄愅愇愊愋愌愐",4,"愖愗愘愙愛愜愝愞愡愢愥愨愩愪愬",18,"慀",6],["9140","慇慉態慍慏慐慒慓慔慖",6,"慞慟慠慡慣慤慥慦慩",6,"慱慲慳慴慶慸",18,"憌憍憏",4,"憕"],["9180","憖",6,"憞",8,"憪憫憭",9,"憸",5,"憿懀懁懃",4,"應懌",4,"懓懕",16,"懧",13,"懶",8,"戀",5,"戇戉戓戔戙戜戝戞戠戣戦戧戨戩戫戭戯戰戱戲戵戶戸",4,"扂扄扅扆扊"],["9240","扏扐払扖扗扙扚扜",6,"扤扥扨扱扲扴扵扷扸扺扻扽抁抂抃抅抆抇抈抋",5,"抔抙抜抝択抣抦抧抩抪抭抮抯抰抲抳抴抶抷抸抺抾拀拁"],["9280","拃拋拏拑拕拝拞拠拡拤拪拫拰拲拵拸拹拺拻挀挃挄挅挆挊挋挌挍挏挐挒挓挔挕挗挘挙挜挦挧挩挬挭挮挰挱挳",5,"挻挼挾挿捀捁捄捇捈捊捑捒捓捔捖",7,"捠捤捥捦捨捪捫捬捯捰捲捳捴捵捸捹捼捽捾捿掁掃掄掅掆掋掍掑掓掔掕掗掙",6,"採掤掦掫掯掱掲掵掶掹掻掽掿揀"],["9340","揁揂揃揅揇揈揊揋揌揑揓揔揕揗",6,"揟揢揤",4,"揫揬揮揯揰揱揳揵揷揹揺揻揼揾搃搄搆",4,"損搎搑搒搕",5,"搝搟搢搣搤"],["9380","搥搧搨搩搫搮",5,"搵",4,"搻搼搾摀摂摃摉摋",6,"摓摕摖摗摙",4,"摟",7,"摨摪摫摬摮",9,"摻",6,"撃撆撈",8,"撓撔撗撘撚撛撜撝撟",4,"撥撦撧撨撪撫撯撱撲撳撴撶撹撻撽撾撿擁擃擄擆",6,"擏擑擓擔擕擖擙據"],["9440","擛擜擝擟擠擡擣擥擧",24,"攁",7,"攊",7,"攓",4,"攙",8],["9480","攢攣攤攦",4,"攬攭攰攱攲攳攷攺攼攽敀",4,"敆敇敊敋敍敎敐敒敓敔敗敘敚敜敟敠敡敤敥敧敨敩敪敭敮敯敱敳敵敶數",14,"斈斉斊斍斎斏斒斔斕斖斘斚斝斞斠斢斣斦斨斪斬斮斱",7,"斺斻斾斿旀旂旇旈旉旊旍旐旑旓旔旕旘",7,"旡旣旤旪旫"],["9540","旲旳旴旵旸旹旻",4,"昁昄昅昇昈昉昋昍昐昑昒昖昗昘昚昛昜昞昡昢昣昤昦昩昪昫昬昮昰昲昳昷",4,"昽昿晀時晄",6,"晍晎晐晑晘"],["9580","晙晛晜晝晞晠晢晣晥晧晩",4,"晱晲晳晵晸晹晻晼晽晿暀暁暃暅暆暈暉暊暋暍暎暏暐暒暓暔暕暘",4,"暞",8,"暩",4,"暯",4,"暵暶暷暸暺暻暼暽暿",25,"曚曞",7,"曧曨曪",5,"曱曵曶書曺曻曽朁朂會"],["9640","朄朅朆朇朌朎朏朑朒朓朖朘朙朚朜朞朠",5,"朧朩朮朰朲朳朶朷朸朹朻朼朾朿杁杄杅杇杊杋杍杒杔杕杗",4,"杝杢杣杤杦杧杫杬杮東杴杶"],["9680","杸杹杺杻杽枀枂枃枅枆枈枊枌枍枎枏枑枒枓枔枖枙枛枟枠枡枤枦枩枬枮枱枲枴枹",7,"柂柅",9,"柕柖柗柛柟柡柣柤柦柧柨柪柫柭柮柲柵",7,"柾栁栂栃栄栆栍栐栒栔栕栘",4,"栞栟栠栢",6,"栫",6,"栴栵栶栺栻栿桇桋桍桏桒桖",5],["9740","桜桝桞桟桪桬",7,"桵桸",8,"梂梄梇",7,"梐梑梒梔梕梖梘",9,"梣梤梥梩梪梫梬梮梱梲梴梶梷梸"],["9780","梹",6,"棁棃",5,"棊棌棎棏棐棑棓棔棖棗棙棛",4,"棡棢棤",9,"棯棲棳棴棶棷棸棻棽棾棿椀椂椃椄椆",4,"椌椏椑椓",11,"椡椢椣椥",7,"椮椯椱椲椳椵椶椷椸椺椻椼椾楀楁楃",16,"楕楖楘楙楛楜楟"],["9840","楡楢楤楥楧楨楩楪楬業楯楰楲",4,"楺楻楽楾楿榁榃榅榊榋榌榎",5,"榖榗榙榚榝",9,"榩榪榬榮榯榰榲榳榵榶榸榹榺榼榽"],["9880","榾榿槀槂",7,"構槍槏槑槒槓槕",5,"槜槝槞槡",11,"槮槯槰槱槳",9,"槾樀",9,"樋",11,"標",5,"樠樢",5,"権樫樬樭樮樰樲樳樴樶",6,"樿",4,"橅橆橈",7,"橑",6,"橚"],["9940","橜",4,"橢橣橤橦",10,"橲",6,"橺橻橽橾橿檁檂檃檅",8,"檏檒",4,"檘",7,"檡",5],["9980","檧檨檪檭",114,"欥欦欨",6],["9a40","欯欰欱欳欴欵欶欸欻欼欽欿歀歁歂歄歅歈歊歋歍",11,"歚",7,"歨歩歫",13,"歺歽歾歿殀殅殈"],["9a80","殌殎殏殐殑殔殕殗殘殙殜",4,"殢",7,"殫",7,"殶殸",6,"毀毃毄毆",4,"毌毎毐毑毘毚毜",4,"毢",7,"毬毭毮毰毱毲毴毶毷毸毺毻毼毾",6,"氈",4,"氎氒気氜氝氞氠氣氥氫氬氭氱氳氶氷氹氺氻氼氾氿汃汄汅汈汋",4,"汑汒汓汖汘"],["9b40","汙汚汢汣汥汦汧汫",4,"汱汳汵汷汸決汻汼汿沀沄沇沊沋沍沎沑沒沕沖沗沘沚沜沝沞沠沢沨沬沯沰沴沵沶沷沺泀況泂泃泆泇泈泋泍泎泏泑泒泘"],["9b80","泙泚泜泝泟泤泦泧泩泬泭泲泴泹泿洀洂洃洅洆洈洉洊洍洏洐洑洓洔洕洖洘洜洝洟",5,"洦洨洩洬洭洯洰洴洶洷洸洺洿浀浂浄浉浌浐浕浖浗浘浛浝浟浡浢浤浥浧浨浫浬浭浰浱浲浳浵浶浹浺浻浽",4,"涃涄涆涇涊涋涍涏涐涒涖",4,"涜涢涥涬涭涰涱涳涴涶涷涹",5,"淁淂淃淈淉淊"],["9c40","淍淎淏淐淒淓淔淕淗淚淛淜淟淢淣淥淧淨淩淪淭淯淰淲淴淵淶淸淺淽",7,"渆渇済渉渋渏渒渓渕渘渙減渜渞渟渢渦渧渨渪測渮渰渱渳渵"],["9c80","渶渷渹渻",7,"湅",7,"湏湐湑湒湕湗湙湚湜湝湞湠",10,"湬湭湯",14,"満溁溂溄溇溈溊",4,"溑",6,"溙溚溛溝溞溠溡溣溤溦溨溩溫溬溭溮溰溳溵溸溹溼溾溿滀滃滄滅滆滈滉滊滌滍滎滐滒滖滘滙滛滜滝滣滧滪",5],["9d40","滰滱滲滳滵滶滷滸滺",7,"漃漄漅漇漈漊",4,"漐漑漒漖",9,"漡漢漣漥漦漧漨漬漮漰漲漴漵漷",6,"漿潀潁潂"],["9d80","潃潄潅潈潉潊潌潎",9,"潙潚潛潝潟潠潡潣潤潥潧",5,"潯潰潱潳潵潶潷潹潻潽",6,"澅澆澇澊澋澏",12,"澝澞澟澠澢",4,"澨",10,"澴澵澷澸澺",5,"濁濃",5,"濊",6,"濓",10,"濟濢濣濤濥"],["9e40","濦",7,"濰",32,"瀒",7,"瀜",6,"瀤",6],["9e80","瀫",9,"瀶瀷瀸瀺",17,"灍灎灐",13,"灟",11,"灮灱灲灳灴灷灹灺灻災炁炂炃炄炆炇炈炋炌炍炏炐炑炓炗炘炚炛炞",12,"炰炲炴炵炶為炾炿烄烅烆烇烉烋",12,"烚"],["9f40","烜烝烞烠烡烢烣烥烪烮烰",6,"烸烺烻烼烾",10,"焋",4,"焑焒焔焗焛",10,"焧",7,"焲焳焴"],["9f80","焵焷",13,"煆煇煈煉煋煍煏",12,"煝煟",4,"煥煩",4,"煯煰煱煴煵煶煷煹煻煼煾",5,"熅",4,"熋熌熍熎熐熑熒熓熕熖熗熚",4,"熡",6,"熩熪熫熭",5,"熴熶熷熸熺",8,"燄",9,"燏",4],["a040","燖",9,"燡燢燣燤燦燨",5,"燯",9,"燺",11,"爇",19],["a080","爛爜爞",9,"爩爫爭爮爯爲爳爴爺爼爾牀",6,"牉牊牋牎牏牐牑牓牔牕牗牘牚牜牞牠牣牤牥牨牪牫牬牭牰牱牳牴牶牷牸牻牼牽犂犃犅",4,"犌犎犐犑犓",11,"犠",11,"犮犱犲犳犵犺",6,"狅狆狇狉狊狋狌狏狑狓狔狕狖狘狚狛"],["a1a1"," 、。·ˉˇ¨〃々—~‖…‘’“”〔〕〈",7,"〖〗【】±×÷∶∧∨∑∏∪∩∈∷√⊥∥∠⌒⊙∫∮≡≌≈∽∝≠≮≯≤≥∞∵∴♂♀°′″℃$¤¢£‰§№☆★○●◎◇◆□■△▲※→←↑↓〓"],["a2a1","ⅰ",9],["a2b1","⒈",19,"⑴",19,"①",9],["a2e5","㈠",9],["a2f1","Ⅰ",11],["a3a1","!"#¥%",88," ̄"],["a4a1","ぁ",82],["a5a1","ァ",85],["a6a1","Α",16,"Σ",6],["a6c1","α",16,"σ",6],["a6e0","︵︶︹︺︿﹀︽︾﹁﹂﹃﹄"],["a6ee","︻︼︷︸︱"],["a6f4","︳︴"],["a7a1","А",5,"ЁЖ",25],["a7d1","а",5,"ёж",25],["a840","ˊˋ˙–―‥‵℅℉↖↗↘↙∕∟∣≒≦≧⊿═",35,"▁",6],["a880","█",7,"▓▔▕▼▽◢◣◤◥☉⊕〒〝〞"],["a8a1","āáǎàēéěèīíǐìōóǒòūúǔùǖǘǚǜüêɑ"],["a8bd","ńň"],["a8c0","ɡ"],["a8c5","ㄅ",36],["a940","〡",8,"㊣㎎㎏㎜㎝㎞㎡㏄㏎㏑㏒㏕︰¬¦"],["a959","℡㈱"],["a95c","‐"],["a960","ー゛゜ヽヾ〆ゝゞ﹉",9,"﹔﹕﹖﹗﹙",8],["a980","﹢",4,"﹨﹩﹪﹫"],["a996","〇"],["a9a4","─",75],["aa40","狜狝狟狢",5,"狪狫狵狶狹狽狾狿猀猂猄",5,"猋猌猍猏猐猑猒猔猘猙猚猟猠猣猤猦猧猨猭猯猰猲猳猵猶猺猻猼猽獀",8],["aa80","獉獊獋獌獎獏獑獓獔獕獖獘",7,"獡",10,"獮獰獱"],["ab40","獲",11,"獿",4,"玅玆玈玊玌玍玏玐玒玓玔玕玗玘玙玚玜玝玞玠玡玣",5,"玪玬玭玱玴玵玶玸玹玼玽玾玿珁珃",4],["ab80","珋珌珎珒",6,"珚珛珜珝珟珡珢珣珤珦珨珪珫珬珮珯珰珱珳",4],["ac40","珸",10,"琄琇琈琋琌琍琎琑",8,"琜",5,"琣琤琧琩琫琭琯琱琲琷",4,"琽琾琿瑀瑂",11],["ac80","瑎",6,"瑖瑘瑝瑠",12,"瑮瑯瑱",4,"瑸瑹瑺"],["ad40","瑻瑼瑽瑿璂璄璅璆璈璉璊璌璍璏璑",10,"璝璟",7,"璪",15,"璻",12],["ad80","瓈",9,"瓓",8,"瓝瓟瓡瓥瓧",6,"瓰瓱瓲"],["ae40","瓳瓵瓸",6,"甀甁甂甃甅",7,"甎甐甒甔甕甖甗甛甝甞甠",4,"甦甧甪甮甴甶甹甼甽甿畁畂畃畄畆畇畉畊畍畐畑畒畓畕畖畗畘"],["ae80","畝",7,"畧畨畩畫",6,"畳畵當畷畺",4,"疀疁疂疄疅疇"],["af40","疈疉疊疌疍疎疐疓疕疘疛疜疞疢疦",4,"疭疶疷疺疻疿痀痁痆痋痌痎痏痐痑痓痗痙痚痜痝痟痠痡痥痩痬痭痮痯痲痳痵痶痷痸痺痻痽痾瘂瘄瘆瘇"],["af80","瘈瘉瘋瘍瘎瘏瘑瘒瘓瘔瘖瘚瘜瘝瘞瘡瘣瘧瘨瘬瘮瘯瘱瘲瘶瘷瘹瘺瘻瘽癁療癄"],["b040","癅",6,"癎",5,"癕癗",4,"癝癟癠癡癢癤",6,"癬癭癮癰",7,"癹発發癿皀皁皃皅皉皊皌皍皏皐皒皔皕皗皘皚皛"],["b080","皜",7,"皥",8,"皯皰皳皵",9,"盀盁盃啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬扳般颁板版扮拌伴瓣半办绊邦帮梆榜膀绑棒磅蚌镑傍谤苞胞包褒剥"],["b140","盄盇盉盋盌盓盕盙盚盜盝盞盠",4,"盦",7,"盰盳盵盶盷盺盻盽盿眀眂眃眅眆眊県眎",10,"眛眜眝眞眡眣眤眥眧眪眫"],["b180","眬眮眰",4,"眹眻眽眾眿睂睄睅睆睈",7,"睒",7,"睜薄雹保堡饱宝抱报暴豹鲍爆杯碑悲卑北辈背贝钡倍狈备惫焙被奔苯本笨崩绷甭泵蹦迸逼鼻比鄙笔彼碧蓖蔽毕毙毖币庇痹闭敝弊必辟壁臂避陛鞭边编贬扁便变卞辨辩辫遍标彪膘表鳖憋别瘪彬斌濒滨宾摈兵冰柄丙秉饼炳"],["b240","睝睞睟睠睤睧睩睪睭",11,"睺睻睼瞁瞂瞃瞆",5,"瞏瞐瞓",11,"瞡瞣瞤瞦瞨瞫瞭瞮瞯瞱瞲瞴瞶",4],["b280","瞼瞾矀",12,"矎",8,"矘矙矚矝",4,"矤病并玻菠播拨钵波博勃搏铂箔伯帛舶脖膊渤泊驳捕卜哺补埠不布步簿部怖擦猜裁材才财睬踩采彩菜蔡餐参蚕残惭惨灿苍舱仓沧藏操糙槽曹草厕策侧册测层蹭插叉茬茶查碴搽察岔差诧拆柴豺搀掺蝉馋谗缠铲产阐颤昌猖"],["b340","矦矨矪矯矰矱矲矴矵矷矹矺矻矼砃",5,"砊砋砎砏砐砓砕砙砛砞砠砡砢砤砨砪砫砮砯砱砲砳砵砶砽砿硁硂硃硄硆硈硉硊硋硍硏硑硓硔硘硙硚"],["b380","硛硜硞",11,"硯",7,"硸硹硺硻硽",6,"场尝常长偿肠厂敞畅唱倡超抄钞朝嘲潮巢吵炒车扯撤掣彻澈郴臣辰尘晨忱沉陈趁衬撑称城橙成呈乘程惩澄诚承逞骋秤吃痴持匙池迟弛驰耻齿侈尺赤翅斥炽充冲虫崇宠抽酬畴踌稠愁筹仇绸瞅丑臭初出橱厨躇锄雏滁除楚"],["b440","碄碅碆碈碊碋碏碐碒碔碕碖碙碝碞碠碢碤碦碨",7,"碵碶碷碸確碻碼碽碿磀磂磃磄磆磇磈磌磍磎磏磑磒磓磖磗磘磚",9],["b480","磤磥磦磧磩磪磫磭",4,"磳磵磶磸磹磻",5,"礂礃礄礆",6,"础储矗搐触处揣川穿椽传船喘串疮窗幢床闯创吹炊捶锤垂春椿醇唇淳纯蠢戳绰疵茨磁雌辞慈瓷词此刺赐次聪葱囱匆从丛凑粗醋簇促蹿篡窜摧崔催脆瘁粹淬翠村存寸磋撮搓措挫错搭达答瘩打大呆歹傣戴带殆代贷袋待逮"],["b540","礍",5,"礔",9,"礟",4,"礥",14,"礵",4,"礽礿祂祃祄祅祇祊",8,"祔祕祘祙祡祣"],["b580","祤祦祩祪祫祬祮祰",6,"祹祻",4,"禂禃禆禇禈禉禋禌禍禎禐禑禒怠耽担丹单郸掸胆旦氮但惮淡诞弹蛋当挡党荡档刀捣蹈倒岛祷导到稻悼道盗德得的蹬灯登等瞪凳邓堤低滴迪敌笛狄涤翟嫡抵底地蒂第帝弟递缔颠掂滇碘点典靛垫电佃甸店惦奠淀殿碉叼雕凋刁掉吊钓调跌爹碟蝶迭谍叠"],["b640","禓",6,"禛",11,"禨",10,"禴",4,"禼禿秂秄秅秇秈秊秌秎秏秐秓秔秖秗秙",5,"秠秡秢秥秨秪"],["b680","秬秮秱",6,"秹秺秼秾秿稁稄稅稇稈稉稊稌稏",4,"稕稖稘稙稛稜丁盯叮钉顶鼎锭定订丢东冬董懂动栋侗恫冻洞兜抖斗陡豆逗痘都督毒犊独读堵睹赌杜镀肚度渡妒端短锻段断缎堆兑队对墩吨蹲敦顿囤钝盾遁掇哆多夺垛躲朵跺舵剁惰堕蛾峨鹅俄额讹娥恶厄扼遏鄂饿恩而儿耳尔饵洱二"],["b740","稝稟稡稢稤",14,"稴稵稶稸稺稾穀",5,"穇",9,"穒",4,"穘",16],["b780","穩",6,"穱穲穳穵穻穼穽穾窂窅窇窉窊窋窌窎窏窐窓窔窙窚窛窞窡窢贰发罚筏伐乏阀法珐藩帆番翻樊矾钒繁凡烦反返范贩犯饭泛坊芳方肪房防妨仿访纺放菲非啡飞肥匪诽吠肺废沸费芬酚吩氛分纷坟焚汾粉奋份忿愤粪丰封枫蜂峰锋风疯烽逢冯缝讽奉凤佛否夫敷肤孵扶拂辐幅氟符伏俘服"],["b840","窣窤窧窩窪窫窮",4,"窴",10,"竀",10,"竌",9,"竗竘竚竛竜竝竡竢竤竧",5,"竮竰竱竲竳"],["b880","竴",4,"竻竼竾笀笁笂笅笇笉笌笍笎笐笒笓笖笗笘笚笜笝笟笡笢笣笧笩笭浮涪福袱弗甫抚辅俯釜斧脯腑府腐赴副覆赋复傅付阜父腹负富讣附妇缚咐噶嘎该改概钙盖溉干甘杆柑竿肝赶感秆敢赣冈刚钢缸肛纲岗港杠篙皋高膏羔糕搞镐稿告哥歌搁戈鸽胳疙割革葛格蛤阁隔铬个各给根跟耕更庚羹"],["b940","笯笰笲笴笵笶笷笹笻笽笿",5,"筆筈筊筍筎筓筕筗筙筜筞筟筡筣",10,"筯筰筳筴筶筸筺筼筽筿箁箂箃箄箆",6,"箎箏"],["b980","箑箒箓箖箘箙箚箛箞箟箠箣箤箥箮箯箰箲箳箵箶箷箹",7,"篂篃範埂耿梗工攻功恭龚供躬公宫弓巩汞拱贡共钩勾沟苟狗垢构购够辜菇咕箍估沽孤姑鼓古蛊骨谷股故顾固雇刮瓜剐寡挂褂乖拐怪棺关官冠观管馆罐惯灌贯光广逛瑰规圭硅归龟闺轨鬼诡癸桂柜跪贵刽辊滚棍锅郭国果裹过哈"],["ba40","篅篈築篊篋篍篎篏篐篒篔",4,"篛篜篞篟篠篢篣篤篧篨篩篫篬篭篯篰篲",4,"篸篹篺篻篽篿",7,"簈簉簊簍簎簐",5,"簗簘簙"],["ba80","簚",4,"簠",5,"簨簩簫",12,"簹",5,"籂骸孩海氦亥害骇酣憨邯韩含涵寒函喊罕翰撼捍旱憾悍焊汗汉夯杭航壕嚎豪毫郝好耗号浩呵喝荷菏核禾和何合盒貉阂河涸赫褐鹤贺嘿黑痕很狠恨哼亨横衡恒轰哄烘虹鸿洪宏弘红喉侯猴吼厚候后呼乎忽瑚壶葫胡蝴狐糊湖"],["bb40","籃",9,"籎",36,"籵",5,"籾",9],["bb80","粈粊",6,"粓粔粖粙粚粛粠粡粣粦粧粨粩粫粬粭粯粰粴",4,"粺粻弧虎唬护互沪户花哗华猾滑画划化话槐徊怀淮坏欢环桓还缓换患唤痪豢焕涣宦幻荒慌黄磺蝗簧皇凰惶煌晃幌恍谎灰挥辉徽恢蛔回毁悔慧卉惠晦贿秽会烩汇讳诲绘荤昏婚魂浑混豁活伙火获或惑霍货祸击圾基机畸稽积箕"],["bc40","粿糀糂糃糄糆糉糋糎",6,"糘糚糛糝糞糡",6,"糩",5,"糰",7,"糹糺糼",13,"紋",5],["bc80","紑",14,"紡紣紤紥紦紨紩紪紬紭紮細",6,"肌饥迹激讥鸡姬绩缉吉极棘辑籍集及急疾汲即嫉级挤几脊己蓟技冀季伎祭剂悸济寄寂计记既忌际妓继纪嘉枷夹佳家加荚颊贾甲钾假稼价架驾嫁歼监坚尖笺间煎兼肩艰奸缄茧检柬碱硷拣捡简俭剪减荐槛鉴践贱见键箭件"],["bd40","紷",54,"絯",7],["bd80","絸",32,"健舰剑饯渐溅涧建僵姜将浆江疆蒋桨奖讲匠酱降蕉椒礁焦胶交郊浇骄娇嚼搅铰矫侥脚狡角饺缴绞剿教酵轿较叫窖揭接皆秸街阶截劫节桔杰捷睫竭洁结解姐戒藉芥界借介疥诫届巾筋斤金今津襟紧锦仅谨进靳晋禁近烬浸"],["be40","継",12,"綧",6,"綯",42],["be80","線",32,"尽劲荆兢茎睛晶鲸京惊精粳经井警景颈静境敬镜径痉靖竟竞净炯窘揪究纠玖韭久灸九酒厩救旧臼舅咎就疚鞠拘狙疽居驹菊局咀矩举沮聚拒据巨具距踞锯俱句惧炬剧捐鹃娟倦眷卷绢撅攫抉掘倔爵觉决诀绝均菌钧军君峻"],["bf40","緻",62],["bf80","縺縼",4,"繂",4,"繈",21,"俊竣浚郡骏喀咖卡咯开揩楷凯慨刊堪勘坎砍看康慷糠扛抗亢炕考拷烤靠坷苛柯棵磕颗科壳咳可渴克刻客课肯啃垦恳坑吭空恐孔控抠口扣寇枯哭窟苦酷库裤夸垮挎跨胯块筷侩快宽款匡筐狂框矿眶旷况亏盔岿窥葵奎魁傀"],["c040","繞",35,"纃",23,"纜纝纞"],["c080","纮纴纻纼绖绤绬绹缊缐缞缷缹缻",6,"罃罆",9,"罒罓馈愧溃坤昆捆困括扩廓阔垃拉喇蜡腊辣啦莱来赖蓝婪栏拦篮阑兰澜谰揽览懒缆烂滥琅榔狼廊郎朗浪捞劳牢老佬姥酪烙涝勒乐雷镭蕾磊累儡垒擂肋类泪棱楞冷厘梨犁黎篱狸离漓理李里鲤礼莉荔吏栗丽厉励砾历利傈例俐"],["c140","罖罙罛罜罝罞罠罣",4,"罫罬罭罯罰罳罵罶罷罸罺罻罼罽罿羀羂",7,"羋羍羏",4,"羕",4,"羛羜羠羢羣羥羦羨",6,"羱"],["c180","羳",4,"羺羻羾翀翂翃翄翆翇翈翉翋翍翏",4,"翖翗翙",5,"翢翣痢立粒沥隶力璃哩俩联莲连镰廉怜涟帘敛脸链恋炼练粮凉梁粱良两辆量晾亮谅撩聊僚疗燎寥辽潦了撂镣廖料列裂烈劣猎琳林磷霖临邻鳞淋凛赁吝拎玲菱零龄铃伶羚凌灵陵岭领另令溜琉榴硫馏留刘瘤流柳六龙聋咙笼窿"],["c240","翤翧翨翪翫翬翭翯翲翴",6,"翽翾翿耂耇耈耉耊耎耏耑耓耚耛耝耞耟耡耣耤耫",5,"耲耴耹耺耼耾聀聁聄聅聇聈聉聎聏聐聑聓聕聖聗"],["c280","聙聛",13,"聫",5,"聲",11,"隆垄拢陇楼娄搂篓漏陋芦卢颅庐炉掳卤虏鲁麓碌露路赂鹿潞禄录陆戮驴吕铝侣旅履屡缕虑氯律率滤绿峦挛孪滦卵乱掠略抡轮伦仑沦纶论萝螺罗逻锣箩骡裸落洛骆络妈麻玛码蚂马骂嘛吗埋买麦卖迈脉瞒馒蛮满蔓曼慢漫"],["c340","聾肁肂肅肈肊肍",5,"肔肕肗肙肞肣肦肧肨肬肰肳肵肶肸肹肻胅胇",4,"胏",6,"胘胟胠胢胣胦胮胵胷胹胻胾胿脀脁脃脄脅脇脈脋"],["c380","脌脕脗脙脛脜脝脟",12,"脭脮脰脳脴脵脷脹",4,"脿谩芒茫盲氓忙莽猫茅锚毛矛铆卯茂冒帽貌贸么玫枚梅酶霉煤没眉媒镁每美昧寐妹媚门闷们萌蒙檬盟锰猛梦孟眯醚靡糜迷谜弥米秘觅泌蜜密幂棉眠绵冕免勉娩缅面苗描瞄藐秒渺庙妙蔑灭民抿皿敏悯闽明螟鸣铭名命谬摸"],["c440","腀",5,"腇腉腍腎腏腒腖腗腘腛",4,"腡腢腣腤腦腨腪腫腬腯腲腳腵腶腷腸膁膃",4,"膉膋膌膍膎膐膒",5,"膙膚膞",4,"膤膥"],["c480","膧膩膫",7,"膴",5,"膼膽膾膿臄臅臇臈臉臋臍",6,"摹蘑模膜磨摩魔抹末莫墨默沫漠寞陌谋牟某拇牡亩姆母墓暮幕募慕木目睦牧穆拿哪呐钠那娜纳氖乃奶耐奈南男难囊挠脑恼闹淖呢馁内嫩能妮霓倪泥尼拟你匿腻逆溺蔫拈年碾撵捻念娘酿鸟尿捏聂孽啮镊镍涅您柠狞凝宁"],["c540","臔",14,"臤臥臦臨臩臫臮",4,"臵",5,"臽臿舃與",4,"舎舏舑舓舕",5,"舝舠舤舥舦舧舩舮舲舺舼舽舿"],["c580","艀艁艂艃艅艆艈艊艌艍艎艐",7,"艙艛艜艝艞艠",7,"艩拧泞牛扭钮纽脓浓农弄奴努怒女暖虐疟挪懦糯诺哦欧鸥殴藕呕偶沤啪趴爬帕怕琶拍排牌徘湃派攀潘盘磐盼畔判叛乓庞旁耪胖抛咆刨炮袍跑泡呸胚培裴赔陪配佩沛喷盆砰抨烹澎彭蓬棚硼篷膨朋鹏捧碰坯砒霹批披劈琵毗"],["c640","艪艫艬艭艱艵艶艷艸艻艼芀芁芃芅芆芇芉芌芐芓芔芕芖芚芛芞芠芢芣芧芲芵芶芺芻芼芿苀苂苃苅苆苉苐苖苙苚苝苢苧苨苩苪苬苭苮苰苲苳苵苶苸"],["c680","苺苼",4,"茊茋茍茐茒茓茖茘茙茝",9,"茩茪茮茰茲茷茻茽啤脾疲皮匹痞僻屁譬篇偏片骗飘漂瓢票撇瞥拼频贫品聘乒坪苹萍平凭瓶评屏坡泼颇婆破魄迫粕剖扑铺仆莆葡菩蒲埔朴圃普浦谱曝瀑期欺栖戚妻七凄漆柒沏其棋奇歧畦崎脐齐旗祈祁骑起岂乞企启契砌器气迄弃汽泣讫掐"],["c740","茾茿荁荂荄荅荈荊",4,"荓荕",4,"荝荢荰",6,"荹荺荾",6,"莇莈莊莋莌莍莏莐莑莔莕莖莗莙莚莝莟莡",6,"莬莭莮"],["c780","莯莵莻莾莿菂菃菄菆菈菉菋菍菎菐菑菒菓菕菗菙菚菛菞菢菣菤菦菧菨菫菬菭恰洽牵扦钎铅千迁签仟谦乾黔钱钳前潜遣浅谴堑嵌欠歉枪呛腔羌墙蔷强抢橇锹敲悄桥瞧乔侨巧鞘撬翘峭俏窍切茄且怯窃钦侵亲秦琴勤芹擒禽寝沁青轻氢倾卿清擎晴氰情顷请庆琼穷秋丘邱球求囚酋泅趋区蛆曲躯屈驱渠"],["c840","菮華菳",4,"菺菻菼菾菿萀萂萅萇萈萉萊萐萒",5,"萙萚萛萞",5,"萩",7,"萲",5,"萹萺萻萾",7,"葇葈葉"],["c880","葊",6,"葒",4,"葘葝葞葟葠葢葤",4,"葪葮葯葰葲葴葷葹葻葼取娶龋趣去圈颧权醛泉全痊拳犬券劝缺炔瘸却鹊榷确雀裙群然燃冉染瓤壤攘嚷让饶扰绕惹热壬仁人忍韧任认刃妊纫扔仍日戎茸蓉荣融熔溶容绒冗揉柔肉茹蠕儒孺如辱乳汝入褥软阮蕊瑞锐闰润若弱撒洒萨腮鳃塞赛三叁"],["c940","葽",4,"蒃蒄蒅蒆蒊蒍蒏",7,"蒘蒚蒛蒝蒞蒟蒠蒢",12,"蒰蒱蒳蒵蒶蒷蒻蒼蒾蓀蓂蓃蓅蓆蓇蓈蓋蓌蓎蓏蓒蓔蓕蓗"],["c980","蓘",4,"蓞蓡蓢蓤蓧",4,"蓭蓮蓯蓱",10,"蓽蓾蔀蔁蔂伞散桑嗓丧搔骚扫嫂瑟色涩森僧莎砂杀刹沙纱傻啥煞筛晒珊苫杉山删煽衫闪陕擅赡膳善汕扇缮墒伤商赏晌上尚裳梢捎稍烧芍勺韶少哨邵绍奢赊蛇舌舍赦摄射慑涉社设砷申呻伸身深娠绅神沈审婶甚肾慎渗声生甥牲升绳"],["ca40","蔃",8,"蔍蔎蔏蔐蔒蔔蔕蔖蔘蔙蔛蔜蔝蔞蔠蔢",8,"蔭",9,"蔾",4,"蕄蕅蕆蕇蕋",10],["ca80","蕗蕘蕚蕛蕜蕝蕟",4,"蕥蕦蕧蕩",8,"蕳蕵蕶蕷蕸蕼蕽蕿薀薁省盛剩胜圣师失狮施湿诗尸虱十石拾时什食蚀实识史矢使屎驶始式示士世柿事拭誓逝势是嗜噬适仕侍释饰氏市恃室视试收手首守寿授售受瘦兽蔬枢梳殊抒输叔舒淑疏书赎孰熟薯暑曙署蜀黍鼠属术述树束戍竖墅庶数漱"],["cb40","薂薃薆薈",6,"薐",10,"薝",6,"薥薦薧薩薫薬薭薱",5,"薸薺",6,"藂",6,"藊",4,"藑藒"],["cb80","藔藖",5,"藝",6,"藥藦藧藨藪",14,"恕刷耍摔衰甩帅栓拴霜双爽谁水睡税吮瞬顺舜说硕朔烁斯撕嘶思私司丝死肆寺嗣四伺似饲巳松耸怂颂送宋讼诵搜艘擞嗽苏酥俗素速粟僳塑溯宿诉肃酸蒜算虽隋随绥髓碎岁穗遂隧祟孙损笋蓑梭唆缩琐索锁所塌他它她塔"],["cc40","藹藺藼藽藾蘀",4,"蘆",10,"蘒蘓蘔蘕蘗",15,"蘨蘪",13,"蘹蘺蘻蘽蘾蘿虀"],["cc80","虁",11,"虒虓處",4,"虛虜虝號虠虡虣",7,"獭挞蹋踏胎苔抬台泰酞太态汰坍摊贪瘫滩坛檀痰潭谭谈坦毯袒碳探叹炭汤塘搪堂棠膛唐糖倘躺淌趟烫掏涛滔绦萄桃逃淘陶讨套特藤腾疼誊梯剔踢锑提题蹄啼体替嚏惕涕剃屉天添填田甜恬舔腆挑条迢眺跳贴铁帖厅听烃"],["cd40","虭虯虰虲",6,"蚃",6,"蚎",4,"蚔蚖",5,"蚞",4,"蚥蚦蚫蚭蚮蚲蚳蚷蚸蚹蚻",4,"蛁蛂蛃蛅蛈蛌蛍蛒蛓蛕蛖蛗蛚蛜"],["cd80","蛝蛠蛡蛢蛣蛥蛦蛧蛨蛪蛫蛬蛯蛵蛶蛷蛺蛻蛼蛽蛿蜁蜄蜅蜆蜋蜌蜎蜏蜐蜑蜔蜖汀廷停亭庭挺艇通桐酮瞳同铜彤童桶捅筒统痛偷投头透凸秃突图徒途涂屠土吐兔湍团推颓腿蜕褪退吞屯臀拖托脱鸵陀驮驼椭妥拓唾挖哇蛙洼娃瓦袜歪外豌弯湾玩顽丸烷完碗挽晚皖惋宛婉万腕汪王亡枉网往旺望忘妄威"],["ce40","蜙蜛蜝蜟蜠蜤蜦蜧蜨蜪蜫蜬蜭蜯蜰蜲蜳蜵蜶蜸蜹蜺蜼蜽蝀",6,"蝊蝋蝍蝏蝐蝑蝒蝔蝕蝖蝘蝚",5,"蝡蝢蝦",7,"蝯蝱蝲蝳蝵"],["ce80","蝷蝸蝹蝺蝿螀螁螄螆螇螉螊螌螎",4,"螔螕螖螘",6,"螠",4,"巍微危韦违桅围唯惟为潍维苇萎委伟伪尾纬未蔚味畏胃喂魏位渭谓尉慰卫瘟温蚊文闻纹吻稳紊问嗡翁瓮挝蜗涡窝我斡卧握沃巫呜钨乌污诬屋无芜梧吾吴毋武五捂午舞伍侮坞戊雾晤物勿务悟误昔熙析西硒矽晰嘻吸锡牺"],["cf40","螥螦螧螩螪螮螰螱螲螴螶螷螸螹螻螼螾螿蟁",4,"蟇蟈蟉蟌",4,"蟔",6,"蟜蟝蟞蟟蟡蟢蟣蟤蟦蟧蟨蟩蟫蟬蟭蟯",9],["cf80","蟺蟻蟼蟽蟿蠀蠁蠂蠄",5,"蠋",7,"蠔蠗蠘蠙蠚蠜",4,"蠣稀息希悉膝夕惜熄烯溪汐犀檄袭席习媳喜铣洗系隙戏细瞎虾匣霞辖暇峡侠狭下厦夏吓掀锨先仙鲜纤咸贤衔舷闲涎弦嫌显险现献县腺馅羡宪陷限线相厢镶香箱襄湘乡翔祥详想响享项巷橡像向象萧硝霄削哮嚣销消宵淆晓"],["d040","蠤",13,"蠳",5,"蠺蠻蠽蠾蠿衁衂衃衆",5,"衎",5,"衕衖衘衚",6,"衦衧衪衭衯衱衳衴衵衶衸衹衺"],["d080","衻衼袀袃袆袇袉袊袌袎袏袐袑袓袔袕袗",4,"袝",4,"袣袥",5,"小孝校肖啸笑效楔些歇蝎鞋协挟携邪斜胁谐写械卸蟹懈泄泻谢屑薪芯锌欣辛新忻心信衅星腥猩惺兴刑型形邢行醒幸杏性姓兄凶胸匈汹雄熊休修羞朽嗅锈秀袖绣墟戌需虚嘘须徐许蓄酗叙旭序畜恤絮婿绪续轩喧宣悬旋玄"],["d140","袬袮袯袰袲",4,"袸袹袺袻袽袾袿裀裃裄裇裈裊裋裌裍裏裐裑裓裖裗裚",4,"裠裡裦裧裩",6,"裲裵裶裷裺裻製裿褀褁褃",5],["d180","褉褋",4,"褑褔",4,"褜",4,"褢褣褤褦褧褨褩褬褭褮褯褱褲褳褵褷选癣眩绚靴薛学穴雪血勋熏循旬询寻驯巡殉汛训讯逊迅压押鸦鸭呀丫芽牙蚜崖衙涯雅哑亚讶焉咽阉烟淹盐严研蜒岩延言颜阎炎沿奄掩眼衍演艳堰燕厌砚雁唁彦焰宴谚验殃央鸯秧杨扬佯疡羊洋阳氧仰痒养样漾邀腰妖瑶"],["d240","褸",8,"襂襃襅",24,"襠",5,"襧",19,"襼"],["d280","襽襾覀覂覄覅覇",26,"摇尧遥窑谣姚咬舀药要耀椰噎耶爷野冶也页掖业叶曳腋夜液一壹医揖铱依伊衣颐夷遗移仪胰疑沂宜姨彝椅蚁倚已乙矣以艺抑易邑屹亿役臆逸肄疫亦裔意毅忆义益溢诣议谊译异翼翌绎茵荫因殷音阴姻吟银淫寅饮尹引隐"],["d340","覢",30,"觃觍觓觔觕觗觘觙觛觝觟觠觡觢觤觧觨觩觪觬觭觮觰觱觲觴",6],["d380","觻",4,"訁",5,"計",21,"印英樱婴鹰应缨莹萤营荧蝇迎赢盈影颖硬映哟拥佣臃痈庸雍踊蛹咏泳涌永恿勇用幽优悠忧尤由邮铀犹油游酉有友右佑釉诱又幼迂淤于盂榆虞愚舆余俞逾鱼愉渝渔隅予娱雨与屿禹宇语羽玉域芋郁吁遇喻峪御愈欲狱育誉"],["d440","訞",31,"訿",8,"詉",21],["d480","詟",25,"詺",6,"浴寓裕预豫驭鸳渊冤元垣袁原援辕园员圆猿源缘远苑愿怨院曰约越跃钥岳粤月悦阅耘云郧匀陨允运蕴酝晕韵孕匝砸杂栽哉灾宰载再在咱攒暂赞赃脏葬遭糟凿藻枣早澡蚤躁噪造皂灶燥责择则泽贼怎增憎曾赠扎喳渣札轧"],["d540","誁",7,"誋",7,"誔",46],["d580","諃",32,"铡闸眨栅榨咋乍炸诈摘斋宅窄债寨瞻毡詹粘沾盏斩辗崭展蘸栈占战站湛绽樟章彰漳张掌涨杖丈帐账仗胀瘴障招昭找沼赵照罩兆肇召遮折哲蛰辙者锗蔗这浙珍斟真甄砧臻贞针侦枕疹诊震振镇阵蒸挣睁征狰争怔整拯正政"],["d640","諤",34,"謈",27],["d680","謤謥謧",30,"帧症郑证芝枝支吱蜘知肢脂汁之织职直植殖执值侄址指止趾只旨纸志挚掷至致置帜峙制智秩稚质炙痔滞治窒中盅忠钟衷终种肿重仲众舟周州洲诌粥轴肘帚咒皱宙昼骤珠株蛛朱猪诸诛逐竹烛煮拄瞩嘱主著柱助蛀贮铸筑"],["d740","譆",31,"譧",4,"譭",25],["d780","讇",24,"讬讱讻诇诐诪谉谞住注祝驻抓爪拽专砖转撰赚篆桩庄装妆撞壮状椎锥追赘坠缀谆准捉拙卓桌琢茁酌啄着灼浊兹咨资姿滋淄孜紫仔籽滓子自渍字鬃棕踪宗综总纵邹走奏揍租足卒族祖诅阻组钻纂嘴醉最罪尊遵昨左佐柞做作坐座"],["d840","谸",8,"豂豃豄豅豈豊豋豍",7,"豖豗豘豙豛",5,"豣",6,"豬",6,"豴豵豶豷豻",6,"貃貄貆貇"],["d880","貈貋貍",6,"貕貖貗貙",20,"亍丌兀丐廿卅丕亘丞鬲孬噩丨禺丿匕乇夭爻卮氐囟胤馗毓睾鼗丶亟鼐乜乩亓芈孛啬嘏仄厍厝厣厥厮靥赝匚叵匦匮匾赜卦卣刂刈刎刭刳刿剀剌剞剡剜蒯剽劂劁劐劓冂罔亻仃仉仂仨仡仫仞伛仳伢佤仵伥伧伉伫佞佧攸佚佝"],["d940","貮",62],["d980","賭",32,"佟佗伲伽佶佴侑侉侃侏佾佻侪佼侬侔俦俨俪俅俚俣俜俑俟俸倩偌俳倬倏倮倭俾倜倌倥倨偾偃偕偈偎偬偻傥傧傩傺僖儆僭僬僦僮儇儋仝氽佘佥俎龠汆籴兮巽黉馘冁夔勹匍訇匐凫夙兕亠兖亳衮袤亵脔裒禀嬴蠃羸冫冱冽冼"],["da40","贎",14,"贠赑赒赗赟赥赨赩赪赬赮赯赱赲赸",8,"趂趃趆趇趈趉趌",4,"趒趓趕",9,"趠趡"],["da80","趢趤",12,"趲趶趷趹趻趽跀跁跂跅跇跈跉跊跍跐跒跓跔凇冖冢冥讠讦讧讪讴讵讷诂诃诋诏诎诒诓诔诖诘诙诜诟诠诤诨诩诮诰诳诶诹诼诿谀谂谄谇谌谏谑谒谔谕谖谙谛谘谝谟谠谡谥谧谪谫谮谯谲谳谵谶卩卺阝阢阡阱阪阽阼陂陉陔陟陧陬陲陴隈隍隗隰邗邛邝邙邬邡邴邳邶邺"],["db40","跕跘跙跜跠跡跢跥跦跧跩跭跮跰跱跲跴跶跼跾",6,"踆踇踈踋踍踎踐踑踒踓踕",7,"踠踡踤",4,"踫踭踰踲踳踴踶踷踸踻踼踾"],["db80","踿蹃蹅蹆蹌",4,"蹓",5,"蹚",11,"蹧蹨蹪蹫蹮蹱邸邰郏郅邾郐郄郇郓郦郢郜郗郛郫郯郾鄄鄢鄞鄣鄱鄯鄹酃酆刍奂劢劬劭劾哿勐勖勰叟燮矍廴凵凼鬯厶弁畚巯坌垩垡塾墼壅壑圩圬圪圳圹圮圯坜圻坂坩垅坫垆坼坻坨坭坶坳垭垤垌垲埏垧垴垓垠埕埘埚埙埒垸埴埯埸埤埝"],["dc40","蹳蹵蹷",4,"蹽蹾躀躂躃躄躆躈",6,"躑躒躓躕",6,"躝躟",11,"躭躮躰躱躳",6,"躻",7],["dc80","軃",10,"軏",21,"堋堍埽埭堀堞堙塄堠塥塬墁墉墚墀馨鼙懿艹艽艿芏芊芨芄芎芑芗芙芫芸芾芰苈苊苣芘芷芮苋苌苁芩芴芡芪芟苄苎芤苡茉苷苤茏茇苜苴苒苘茌苻苓茑茚茆茔茕苠苕茜荑荛荜茈莒茼茴茱莛荞茯荏荇荃荟荀茗荠茭茺茳荦荥"],["dd40","軥",62],["dd80","輤",32,"荨茛荩荬荪荭荮莰荸莳莴莠莪莓莜莅荼莶莩荽莸荻莘莞莨莺莼菁萁菥菘堇萘萋菝菽菖萜萸萑萆菔菟萏萃菸菹菪菅菀萦菰菡葜葑葚葙葳蒇蒈葺蒉葸萼葆葩葶蒌蒎萱葭蓁蓍蓐蓦蒽蓓蓊蒿蒺蓠蒡蒹蒴蒗蓥蓣蔌甍蔸蓰蔹蔟蔺"],["de40","轅",32,"轪辀辌辒辝辠辡辢辤辥辦辧辪辬辭辮辯農辳辴辵辷辸辺辻込辿迀迃迆"],["de80","迉",4,"迏迒迖迗迚迠迡迣迧迬迯迱迲迴迵迶迺迻迼迾迿逇逈逌逎逓逕逘蕖蔻蓿蓼蕙蕈蕨蕤蕞蕺瞢蕃蕲蕻薤薨薇薏蕹薮薜薅薹薷薰藓藁藜藿蘧蘅蘩蘖蘼廾弈夼奁耷奕奚奘匏尢尥尬尴扌扪抟抻拊拚拗拮挢拶挹捋捃掭揶捱捺掎掴捭掬掊捩掮掼揲揸揠揿揄揞揎摒揆掾摅摁搋搛搠搌搦搡摞撄摭撖"],["df40","這逜連逤逥逧",5,"逰",4,"逷逹逺逽逿遀遃遅遆遈",4,"過達違遖遙遚遜",5,"遤遦遧適遪遫遬遯",4,"遶",6,"遾邁"],["df80","還邅邆邇邉邊邌",4,"邒邔邖邘邚邜邞邟邠邤邥邧邨邩邫邭邲邷邼邽邿郀摺撷撸撙撺擀擐擗擤擢攉攥攮弋忒甙弑卟叱叽叩叨叻吒吖吆呋呒呓呔呖呃吡呗呙吣吲咂咔呷呱呤咚咛咄呶呦咝哐咭哂咴哒咧咦哓哔呲咣哕咻咿哌哙哚哜咩咪咤哝哏哞唛哧唠哽唔哳唢唣唏唑唧唪啧喏喵啉啭啁啕唿啐唼"],["e040","郂郃郆郈郉郋郌郍郒郔郕郖郘郙郚郞郟郠郣郤郥郩郪郬郮郰郱郲郳郵郶郷郹郺郻郼郿鄀鄁鄃鄅",19,"鄚鄛鄜"],["e080","鄝鄟鄠鄡鄤",10,"鄰鄲",6,"鄺",8,"酄唷啖啵啶啷唳唰啜喋嗒喃喱喹喈喁喟啾嗖喑啻嗟喽喾喔喙嗪嗷嗉嘟嗑嗫嗬嗔嗦嗝嗄嗯嗥嗲嗳嗌嗍嗨嗵嗤辔嘞嘈嘌嘁嘤嘣嗾嘀嘧嘭噘嘹噗嘬噍噢噙噜噌噔嚆噤噱噫噻噼嚅嚓嚯囔囗囝囡囵囫囹囿圄圊圉圜帏帙帔帑帱帻帼"],["e140","酅酇酈酑酓酔酕酖酘酙酛酜酟酠酦酧酨酫酭酳酺酻酼醀",4,"醆醈醊醎醏醓",6,"醜",5,"醤",5,"醫醬醰醱醲醳醶醷醸醹醻"],["e180","醼",10,"釈釋釐釒",9,"針",8,"帷幄幔幛幞幡岌屺岍岐岖岈岘岙岑岚岜岵岢岽岬岫岱岣峁岷峄峒峤峋峥崂崃崧崦崮崤崞崆崛嵘崾崴崽嵬嵛嵯嵝嵫嵋嵊嵩嵴嶂嶙嶝豳嶷巅彳彷徂徇徉後徕徙徜徨徭徵徼衢彡犭犰犴犷犸狃狁狎狍狒狨狯狩狲狴狷猁狳猃狺"],["e240","釦",62],["e280","鈥",32,"狻猗猓猡猊猞猝猕猢猹猥猬猸猱獐獍獗獠獬獯獾舛夥飧夤夂饣饧",5,"饴饷饽馀馄馇馊馍馐馑馓馔馕庀庑庋庖庥庠庹庵庾庳赓廒廑廛廨廪膺忄忉忖忏怃忮怄忡忤忾怅怆忪忭忸怙怵怦怛怏怍怩怫怊怿怡恸恹恻恺恂"],["e340","鉆",45,"鉵",16],["e380","銆",7,"銏",24,"恪恽悖悚悭悝悃悒悌悛惬悻悱惝惘惆惚悴愠愦愕愣惴愀愎愫慊慵憬憔憧憷懔懵忝隳闩闫闱闳闵闶闼闾阃阄阆阈阊阋阌阍阏阒阕阖阗阙阚丬爿戕氵汔汜汊沣沅沐沔沌汨汩汴汶沆沩泐泔沭泷泸泱泗沲泠泖泺泫泮沱泓泯泾"],["e440","銨",5,"銯",24,"鋉",31],["e480","鋩",32,"洹洧洌浃浈洇洄洙洎洫浍洮洵洚浏浒浔洳涑浯涞涠浞涓涔浜浠浼浣渚淇淅淞渎涿淠渑淦淝淙渖涫渌涮渫湮湎湫溲湟溆湓湔渲渥湄滟溱溘滠漭滢溥溧溽溻溷滗溴滏溏滂溟潢潆潇漤漕滹漯漶潋潴漪漉漩澉澍澌潸潲潼潺濑"],["e540","錊",51,"錿",10],["e580","鍊",31,"鍫濉澧澹澶濂濡濮濞濠濯瀚瀣瀛瀹瀵灏灞宀宄宕宓宥宸甯骞搴寤寮褰寰蹇謇辶迓迕迥迮迤迩迦迳迨逅逄逋逦逑逍逖逡逵逶逭逯遄遑遒遐遨遘遢遛暹遴遽邂邈邃邋彐彗彖彘尻咫屐屙孱屣屦羼弪弩弭艴弼鬻屮妁妃妍妩妪妣"],["e640","鍬",34,"鎐",27],["e680","鎬",29,"鏋鏌鏍妗姊妫妞妤姒妲妯姗妾娅娆姝娈姣姘姹娌娉娲娴娑娣娓婀婧婊婕娼婢婵胬媪媛婷婺媾嫫媲嫒嫔媸嫠嫣嫱嫖嫦嫘嫜嬉嬗嬖嬲嬷孀尕尜孚孥孳孑孓孢驵驷驸驺驿驽骀骁骅骈骊骐骒骓骖骘骛骜骝骟骠骢骣骥骧纟纡纣纥纨纩"],["e740","鏎",7,"鏗",54],["e780","鐎",32,"纭纰纾绀绁绂绉绋绌绐绔绗绛绠绡绨绫绮绯绱绲缍绶绺绻绾缁缂缃缇缈缋缌缏缑缒缗缙缜缛缟缡",6,"缪缫缬缭缯",4,"缵幺畿巛甾邕玎玑玮玢玟珏珂珑玷玳珀珉珈珥珙顼琊珩珧珞玺珲琏琪瑛琦琥琨琰琮琬"],["e840","鐯",14,"鐿",43,"鑬鑭鑮鑯"],["e880","鑰",20,"钑钖钘铇铏铓铔铚铦铻锜锠琛琚瑁瑜瑗瑕瑙瑷瑭瑾璜璎璀璁璇璋璞璨璩璐璧瓒璺韪韫韬杌杓杞杈杩枥枇杪杳枘枧杵枨枞枭枋杷杼柰栉柘栊柩枰栌柙枵柚枳柝栀柃枸柢栎柁柽栲栳桠桡桎桢桄桤梃栝桕桦桁桧桀栾桊桉栩梵梏桴桷梓桫棂楮棼椟椠棹"],["e940","锧锳锽镃镈镋镕镚镠镮镴镵長",7,"門",42],["e980","閫",32,"椤棰椋椁楗棣椐楱椹楠楂楝榄楫榀榘楸椴槌榇榈槎榉楦楣楹榛榧榻榫榭槔榱槁槊槟榕槠榍槿樯槭樗樘橥槲橄樾檠橐橛樵檎橹樽樨橘橼檑檐檩檗檫猷獒殁殂殇殄殒殓殍殚殛殡殪轫轭轱轲轳轵轶轸轷轹轺轼轾辁辂辄辇辋"],["ea40","闌",27,"闬闿阇阓阘阛阞阠阣",6,"阫阬阭阯阰阷阸阹阺阾陁陃陊陎陏陑陒陓陖陗"],["ea80","陘陙陚陜陝陞陠陣陥陦陫陭",4,"陳陸",12,"隇隉隊辍辎辏辘辚軎戋戗戛戟戢戡戥戤戬臧瓯瓴瓿甏甑甓攴旮旯旰昊昙杲昃昕昀炅曷昝昴昱昶昵耆晟晔晁晏晖晡晗晷暄暌暧暝暾曛曜曦曩贲贳贶贻贽赀赅赆赈赉赇赍赕赙觇觊觋觌觎觏觐觑牮犟牝牦牯牾牿犄犋犍犏犒挈挲掰"],["eb40","隌階隑隒隓隕隖隚際隝",9,"隨",7,"隱隲隴隵隷隸隺隻隿雂雃雈雊雋雐雑雓雔雖",9,"雡",6,"雫"],["eb80","雬雭雮雰雱雲雴雵雸雺電雼雽雿霂霃霅霊霋霌霐霑霒霔霕霗",4,"霝霟霠搿擘耄毪毳毽毵毹氅氇氆氍氕氘氙氚氡氩氤氪氲攵敕敫牍牒牖爰虢刖肟肜肓肼朊肽肱肫肭肴肷胧胨胩胪胛胂胄胙胍胗朐胝胫胱胴胭脍脎胲胼朕脒豚脶脞脬脘脲腈腌腓腴腙腚腱腠腩腼腽腭腧塍媵膈膂膑滕膣膪臌朦臊膻"],["ec40","霡",8,"霫霬霮霯霱霳",4,"霺霻霼霽霿",18,"靔靕靗靘靚靜靝靟靣靤靦靧靨靪",7],["ec80","靲靵靷",4,"靽",7,"鞆",4,"鞌鞎鞏鞐鞓鞕鞖鞗鞙",4,"臁膦欤欷欹歃歆歙飑飒飓飕飙飚殳彀毂觳斐齑斓於旆旄旃旌旎旒旖炀炜炖炝炻烀炷炫炱烨烊焐焓焖焯焱煳煜煨煅煲煊煸煺熘熳熵熨熠燠燔燧燹爝爨灬焘煦熹戾戽扃扈扉礻祀祆祉祛祜祓祚祢祗祠祯祧祺禅禊禚禧禳忑忐"],["ed40","鞞鞟鞡鞢鞤",6,"鞬鞮鞰鞱鞳鞵",46],["ed80","韤韥韨韮",4,"韴韷",23,"怼恝恚恧恁恙恣悫愆愍慝憩憝懋懑戆肀聿沓泶淼矶矸砀砉砗砘砑斫砭砜砝砹砺砻砟砼砥砬砣砩硎硭硖硗砦硐硇硌硪碛碓碚碇碜碡碣碲碹碥磔磙磉磬磲礅磴礓礤礞礴龛黹黻黼盱眄眍盹眇眈眚眢眙眭眦眵眸睐睑睇睃睚睨"],["ee40","頏",62],["ee80","顎",32,"睢睥睿瞍睽瞀瞌瞑瞟瞠瞰瞵瞽町畀畎畋畈畛畲畹疃罘罡罟詈罨罴罱罹羁罾盍盥蠲钅钆钇钋钊钌钍钏钐钔钗钕钚钛钜钣钤钫钪钭钬钯钰钲钴钶",4,"钼钽钿铄铈",6,"铐铑铒铕铖铗铙铘铛铞铟铠铢铤铥铧铨铪"],["ef40","顯",5,"颋颎颒颕颙颣風",37,"飏飐飔飖飗飛飜飝飠",4],["ef80","飥飦飩",30,"铩铫铮铯铳铴铵铷铹铼铽铿锃锂锆锇锉锊锍锎锏锒",4,"锘锛锝锞锟锢锪锫锩锬锱锲锴锶锷锸锼锾锿镂锵镄镅镆镉镌镎镏镒镓镔镖镗镘镙镛镞镟镝镡镢镤",8,"镯镱镲镳锺矧矬雉秕秭秣秫稆嵇稃稂稞稔"],["f040","餈",4,"餎餏餑",28,"餯",26],["f080","饊",9,"饖",12,"饤饦饳饸饹饻饾馂馃馉稹稷穑黏馥穰皈皎皓皙皤瓞瓠甬鸠鸢鸨",4,"鸲鸱鸶鸸鸷鸹鸺鸾鹁鹂鹄鹆鹇鹈鹉鹋鹌鹎鹑鹕鹗鹚鹛鹜鹞鹣鹦",6,"鹱鹭鹳疒疔疖疠疝疬疣疳疴疸痄疱疰痃痂痖痍痣痨痦痤痫痧瘃痱痼痿瘐瘀瘅瘌瘗瘊瘥瘘瘕瘙"],["f140","馌馎馚",10,"馦馧馩",47],["f180","駙",32,"瘛瘼瘢瘠癀瘭瘰瘿瘵癃瘾瘳癍癞癔癜癖癫癯翊竦穸穹窀窆窈窕窦窠窬窨窭窳衤衩衲衽衿袂袢裆袷袼裉裢裎裣裥裱褚裼裨裾裰褡褙褓褛褊褴褫褶襁襦襻疋胥皲皴矜耒耔耖耜耠耢耥耦耧耩耨耱耋耵聃聆聍聒聩聱覃顸颀颃"],["f240","駺",62],["f280","騹",32,"颉颌颍颏颔颚颛颞颟颡颢颥颦虍虔虬虮虿虺虼虻蚨蚍蚋蚬蚝蚧蚣蚪蚓蚩蚶蛄蚵蛎蚰蚺蚱蚯蛉蛏蚴蛩蛱蛲蛭蛳蛐蜓蛞蛴蛟蛘蛑蜃蜇蛸蜈蜊蜍蜉蜣蜻蜞蜥蜮蜚蜾蝈蜴蜱蜩蜷蜿螂蜢蝽蝾蝻蝠蝰蝌蝮螋蝓蝣蝼蝤蝙蝥螓螯螨蟒"],["f340","驚",17,"驲骃骉骍骎骔骕骙骦骩",6,"骲骳骴骵骹骻骽骾骿髃髄髆",4,"髍髎髏髐髒體髕髖髗髙髚髛髜"],["f380","髝髞髠髢髣髤髥髧髨髩髪髬髮髰",8,"髺髼",6,"鬄鬅鬆蟆螈螅螭螗螃螫蟥螬螵螳蟋蟓螽蟑蟀蟊蟛蟪蟠蟮蠖蠓蟾蠊蠛蠡蠹蠼缶罂罄罅舐竺竽笈笃笄笕笊笫笏筇笸笪笙笮笱笠笥笤笳笾笞筘筚筅筵筌筝筠筮筻筢筲筱箐箦箧箸箬箝箨箅箪箜箢箫箴篑篁篌篝篚篥篦篪簌篾篼簏簖簋"],["f440","鬇鬉",5,"鬐鬑鬒鬔",10,"鬠鬡鬢鬤",10,"鬰鬱鬳",7,"鬽鬾鬿魀魆魊魋魌魎魐魒魓魕",5],["f480","魛",32,"簟簪簦簸籁籀臾舁舂舄臬衄舡舢舣舭舯舨舫舸舻舳舴舾艄艉艋艏艚艟艨衾袅袈裘裟襞羝羟羧羯羰羲籼敉粑粝粜粞粢粲粼粽糁糇糌糍糈糅糗糨艮暨羿翎翕翥翡翦翩翮翳糸絷綦綮繇纛麸麴赳趄趔趑趱赧赭豇豉酊酐酎酏酤"],["f540","魼",62],["f580","鮻",32,"酢酡酰酩酯酽酾酲酴酹醌醅醐醍醑醢醣醪醭醮醯醵醴醺豕鹾趸跫踅蹙蹩趵趿趼趺跄跖跗跚跞跎跏跛跆跬跷跸跣跹跻跤踉跽踔踝踟踬踮踣踯踺蹀踹踵踽踱蹉蹁蹂蹑蹒蹊蹰蹶蹼蹯蹴躅躏躔躐躜躞豸貂貊貅貘貔斛觖觞觚觜"],["f640","鯜",62],["f680","鰛",32,"觥觫觯訾謦靓雩雳雯霆霁霈霏霎霪霭霰霾龀龃龅",5,"龌黾鼋鼍隹隼隽雎雒瞿雠銎銮鋈錾鍪鏊鎏鐾鑫鱿鲂鲅鲆鲇鲈稣鲋鲎鲐鲑鲒鲔鲕鲚鲛鲞",5,"鲥",4,"鲫鲭鲮鲰",7,"鲺鲻鲼鲽鳄鳅鳆鳇鳊鳋"],["f740","鰼",62],["f780","鱻鱽鱾鲀鲃鲄鲉鲊鲌鲏鲓鲖鲗鲘鲙鲝鲪鲬鲯鲹鲾",4,"鳈鳉鳑鳒鳚鳛鳠鳡鳌",4,"鳓鳔鳕鳗鳘鳙鳜鳝鳟鳢靼鞅鞑鞒鞔鞯鞫鞣鞲鞴骱骰骷鹘骶骺骼髁髀髅髂髋髌髑魅魃魇魉魈魍魑飨餍餮饕饔髟髡髦髯髫髻髭髹鬈鬏鬓鬟鬣麽麾縻麂麇麈麋麒鏖麝麟黛黜黝黠黟黢黩黧黥黪黯鼢鼬鼯鼹鼷鼽鼾齄"],["f840","鳣",62],["f880","鴢",32],["f940","鵃",62],["f980","鶂",32],["fa40","鶣",62],["fa80","鷢",32],["fb40","鸃",27,"鸤鸧鸮鸰鸴鸻鸼鹀鹍鹐鹒鹓鹔鹖鹙鹝鹟鹠鹡鹢鹥鹮鹯鹲鹴",9,"麀"],["fb80","麁麃麄麅麆麉麊麌",5,"麔",8,"麞麠",5,"麧麨麩麪"],["fc40","麫",8,"麵麶麷麹麺麼麿",4,"黅黆黇黈黊黋黌黐黒黓黕黖黗黙黚點黡黣黤黦黨黫黬黭黮黰",8,"黺黽黿",6],["fc80","鼆",4,"鼌鼏鼑鼒鼔鼕鼖鼘鼚",5,"鼡鼣",8,"鼭鼮鼰鼱"],["fd40","鼲",4,"鼸鼺鼼鼿",4,"齅",10,"齒",38],["fd80","齹",5,"龁龂龍",11,"龜龝龞龡",4,"郎凉秊裏隣"],["fe40","兀嗀﨎﨏﨑﨓﨔礼﨟蘒﨡﨣﨤﨧﨨﨩"]]'); + +/***/ }), + +/***/ 2683: +/***/ ((module) => { + +module.exports = JSON.parse('[["0","\\u0000",127],["8141","갂갃갅갆갋",4,"갘갞갟갡갢갣갥",6,"갮갲갳갴"],["8161","갵갶갷갺갻갽갾갿걁",9,"걌걎",5,"걕"],["8181","걖걗걙걚걛걝",18,"걲걳걵걶걹걻",4,"겂겇겈겍겎겏겑겒겓겕",6,"겞겢",5,"겫겭겮겱",6,"겺겾겿곀곂곃곅곆곇곉곊곋곍",7,"곖곘",7,"곢곣곥곦곩곫곭곮곲곴곷",4,"곾곿괁괂괃괅괇",4,"괎괐괒괓"],["8241","괔괕괖괗괙괚괛괝괞괟괡",7,"괪괫괮",5],["8261","괶괷괹괺괻괽",6,"굆굈굊",5,"굑굒굓굕굖굗"],["8281","굙",7,"굢굤",7,"굮굯굱굲굷굸굹굺굾궀궃",4,"궊궋궍궎궏궑",10,"궞",5,"궥",17,"궸",7,"귂귃귅귆귇귉",6,"귒귔",7,"귝귞귟귡귢귣귥",18],["8341","귺귻귽귾긂",5,"긊긌긎",5,"긕",7],["8361","긝",18,"긲긳긵긶긹긻긼"],["8381","긽긾긿깂깄깇깈깉깋깏깑깒깓깕깗",4,"깞깢깣깤깦깧깪깫깭깮깯깱",6,"깺깾",5,"꺆",5,"꺍",46,"꺿껁껂껃껅",6,"껎껒",5,"껚껛껝",8],["8441","껦껧껩껪껬껮",5,"껵껶껷껹껺껻껽",8],["8461","꼆꼉꼊꼋꼌꼎꼏꼑",18],["8481","꼤",7,"꼮꼯꼱꼳꼵",6,"꼾꽀꽄꽅꽆꽇꽊",5,"꽑",10,"꽞",5,"꽦",18,"꽺",5,"꾁꾂꾃꾅꾆꾇꾉",6,"꾒꾓꾔꾖",5,"꾝",26,"꾺꾻꾽꾾"],["8541","꾿꿁",5,"꿊꿌꿏",4,"꿕",6,"꿝",4],["8561","꿢",5,"꿪",5,"꿲꿳꿵꿶꿷꿹",6,"뀂뀃"],["8581","뀅",6,"뀍뀎뀏뀑뀒뀓뀕",6,"뀞",9,"뀩",26,"끆끇끉끋끍끏끐끑끒끖끘끚끛끜끞",29,"끾끿낁낂낃낅",6,"낎낐낒",5,"낛낝낞낣낤"],["8641","낥낦낧낪낰낲낶낷낹낺낻낽",6,"냆냊",5,"냒"],["8661","냓냕냖냗냙",6,"냡냢냣냤냦",10],["8681","냱",22,"넊넍넎넏넑넔넕넖넗넚넞",4,"넦넧넩넪넫넭",6,"넶넺",5,"녂녃녅녆녇녉",6,"녒녓녖녗녙녚녛녝녞녟녡",22,"녺녻녽녾녿놁놃",4,"놊놌놎놏놐놑놕놖놗놙놚놛놝"],["8741","놞",9,"놩",15],["8761","놹",18,"뇍뇎뇏뇑뇒뇓뇕"],["8781","뇖",5,"뇞뇠",7,"뇪뇫뇭뇮뇯뇱",7,"뇺뇼뇾",5,"눆눇눉눊눍",6,"눖눘눚",5,"눡",18,"눵",6,"눽",26,"뉙뉚뉛뉝뉞뉟뉡",6,"뉪",4],["8841","뉯",4,"뉶",5,"뉽",6,"늆늇늈늊",4],["8861","늏늒늓늕늖늗늛",4,"늢늤늧늨늩늫늭늮늯늱늲늳늵늶늷"],["8881","늸",15,"닊닋닍닎닏닑닓",4,"닚닜닞닟닠닡닣닧닩닪닰닱닲닶닼닽닾댂댃댅댆댇댉",6,"댒댖",5,"댝",54,"덗덙덚덝덠덡덢덣"],["8941","덦덨덪덬덭덯덲덳덵덶덷덹",6,"뎂뎆",5,"뎍"],["8961","뎎뎏뎑뎒뎓뎕",10,"뎢",5,"뎩뎪뎫뎭"],["8981","뎮",21,"돆돇돉돊돍돏돑돒돓돖돘돚돜돞돟돡돢돣돥돦돧돩",18,"돽",18,"됑",6,"됙됚됛됝됞됟됡",6,"됪됬",7,"됵",15],["8a41","둅",10,"둒둓둕둖둗둙",6,"둢둤둦"],["8a61","둧",4,"둭",18,"뒁뒂"],["8a81","뒃",4,"뒉",19,"뒞",5,"뒥뒦뒧뒩뒪뒫뒭",7,"뒶뒸뒺",5,"듁듂듃듅듆듇듉",6,"듑듒듓듔듖",5,"듞듟듡듢듥듧",4,"듮듰듲",5,"듹",26,"딖딗딙딚딝"],["8b41","딞",5,"딦딫",4,"딲딳딵딶딷딹",6,"땂땆"],["8b61","땇땈땉땊땎땏땑땒땓땕",6,"땞땢",8],["8b81","땫",52,"떢떣떥떦떧떩떬떭떮떯떲떶",4,"떾떿뗁뗂뗃뗅",6,"뗎뗒",5,"뗙",18,"뗭",18],["8c41","똀",15,"똒똓똕똖똗똙",4],["8c61","똞",6,"똦",5,"똭",6,"똵",5],["8c81","똻",12,"뙉",26,"뙥뙦뙧뙩",50,"뚞뚟뚡뚢뚣뚥",5,"뚭뚮뚯뚰뚲",16],["8d41","뛃",16,"뛕",8],["8d61","뛞",17,"뛱뛲뛳뛵뛶뛷뛹뛺"],["8d81","뛻",4,"뜂뜃뜄뜆",33,"뜪뜫뜭뜮뜱",6,"뜺뜼",7,"띅띆띇띉띊띋띍",6,"띖",9,"띡띢띣띥띦띧띩",6,"띲띴띶",5,"띾띿랁랂랃랅",6,"랎랓랔랕랚랛랝랞"],["8e41","랟랡",6,"랪랮",5,"랶랷랹",8],["8e61","럂",4,"럈럊",19],["8e81","럞",13,"럮럯럱럲럳럵",6,"럾렂",4,"렊렋렍렎렏렑",6,"렚렜렞",5,"렦렧렩렪렫렭",6,"렶렺",5,"롁롂롃롅",11,"롒롔",7,"롞롟롡롢롣롥",6,"롮롰롲",5,"롹롺롻롽",7],["8f41","뢅",7,"뢎",17],["8f61","뢠",7,"뢩",6,"뢱뢲뢳뢵뢶뢷뢹",4],["8f81","뢾뢿룂룄룆",5,"룍룎룏룑룒룓룕",7,"룞룠룢",5,"룪룫룭룮룯룱",6,"룺룼룾",5,"뤅",18,"뤙",6,"뤡",26,"뤾뤿륁륂륃륅",6,"륍륎륐륒",5],["9041","륚륛륝륞륟륡",6,"륪륬륮",5,"륶륷륹륺륻륽"],["9061","륾",5,"릆릈릋릌릏",15],["9081","릟",12,"릮릯릱릲릳릵",6,"릾맀맂",5,"맊맋맍맓",4,"맚맜맟맠맢맦맧맩맪맫맭",6,"맶맻",4,"먂",5,"먉",11,"먖",33,"먺먻먽먾먿멁멃멄멅멆"],["9141","멇멊멌멏멐멑멒멖멗멙멚멛멝",6,"멦멪",5],["9161","멲멳멵멶멷멹",9,"몆몈몉몊몋몍",5],["9181","몓",20,"몪몭몮몯몱몳",4,"몺몼몾",5,"뫅뫆뫇뫉",14,"뫚",33,"뫽뫾뫿묁묂묃묅",7,"묎묐묒",5,"묙묚묛묝묞묟묡",6],["9241","묨묪묬",7,"묷묹묺묿",4,"뭆뭈뭊뭋뭌뭎뭑뭒"],["9261","뭓뭕뭖뭗뭙",7,"뭢뭤",7,"뭭",4],["9281","뭲",21,"뮉뮊뮋뮍뮎뮏뮑",18,"뮥뮦뮧뮩뮪뮫뮭",6,"뮵뮶뮸",7,"믁믂믃믅믆믇믉",6,"믑믒믔",35,"믺믻믽믾밁"],["9341","밃",4,"밊밎밐밒밓밙밚밠밡밢밣밦밨밪밫밬밮밯밲밳밵"],["9361","밶밷밹",6,"뱂뱆뱇뱈뱊뱋뱎뱏뱑",8],["9381","뱚뱛뱜뱞",37,"벆벇벉벊벍벏",4,"벖벘벛",4,"벢벣벥벦벩",6,"벲벶",5,"벾벿볁볂볃볅",7,"볎볒볓볔볖볗볙볚볛볝",22,"볷볹볺볻볽"],["9441","볾",5,"봆봈봊",5,"봑봒봓봕",8],["9461","봞",5,"봥",6,"봭",12],["9481","봺",5,"뵁",6,"뵊뵋뵍뵎뵏뵑",6,"뵚",9,"뵥뵦뵧뵩",22,"붂붃붅붆붋",4,"붒붔붖붗붘붛붝",6,"붥",10,"붱",6,"붹",24],["9541","뷒뷓뷖뷗뷙뷚뷛뷝",11,"뷪",5,"뷱"],["9561","뷲뷳뷵뷶뷷뷹",6,"븁븂븄븆",5,"븎븏븑븒븓"],["9581","븕",6,"븞븠",35,"빆빇빉빊빋빍빏",4,"빖빘빜빝빞빟빢빣빥빦빧빩빫",4,"빲빶",4,"빾빿뺁뺂뺃뺅",6,"뺎뺒",5,"뺚",13,"뺩",14],["9641","뺸",23,"뻒뻓"],["9661","뻕뻖뻙",6,"뻡뻢뻦",5,"뻭",8],["9681","뻶",10,"뼂",5,"뼊",13,"뼚뼞",33,"뽂뽃뽅뽆뽇뽉",6,"뽒뽓뽔뽖",44],["9741","뾃",16,"뾕",8],["9761","뾞",17,"뾱",7],["9781","뾹",11,"뿆",5,"뿎뿏뿑뿒뿓뿕",6,"뿝뿞뿠뿢",89,"쀽쀾쀿"],["9841","쁀",16,"쁒",5,"쁙쁚쁛"],["9861","쁝쁞쁟쁡",6,"쁪",15],["9881","쁺",21,"삒삓삕삖삗삙",6,"삢삤삦",5,"삮삱삲삷",4,"삾샂샃샄샆샇샊샋샍샎샏샑",6,"샚샞",5,"샦샧샩샪샫샭",6,"샶샸샺",5,"섁섂섃섅섆섇섉",6,"섑섒섓섔섖",5,"섡섢섥섨섩섪섫섮"],["9941","섲섳섴섵섷섺섻섽섾섿셁",6,"셊셎",5,"셖셗"],["9961","셙셚셛셝",6,"셦셪",5,"셱셲셳셵셶셷셹셺셻"],["9981","셼",8,"솆",5,"솏솑솒솓솕솗",4,"솞솠솢솣솤솦솧솪솫솭솮솯솱",11,"솾",5,"쇅쇆쇇쇉쇊쇋쇍",6,"쇕쇖쇙",6,"쇡쇢쇣쇥쇦쇧쇩",6,"쇲쇴",7,"쇾쇿숁숂숃숅",6,"숎숐숒",5,"숚숛숝숞숡숢숣"],["9a41","숤숥숦숧숪숬숮숰숳숵",16],["9a61","쉆쉇쉉",6,"쉒쉓쉕쉖쉗쉙",6,"쉡쉢쉣쉤쉦"],["9a81","쉧",4,"쉮쉯쉱쉲쉳쉵",6,"쉾슀슂",5,"슊",5,"슑",6,"슙슚슜슞",5,"슦슧슩슪슫슮",5,"슶슸슺",33,"싞싟싡싢싥",5,"싮싰싲싳싴싵싷싺싽싾싿쌁",6,"쌊쌋쌎쌏"],["9b41","쌐쌑쌒쌖쌗쌙쌚쌛쌝",6,"쌦쌧쌪",8],["9b61","쌳",17,"썆",7],["9b81","썎",25,"썪썫썭썮썯썱썳",4,"썺썻썾",5,"쎅쎆쎇쎉쎊쎋쎍",50,"쏁",22,"쏚"],["9c41","쏛쏝쏞쏡쏣",4,"쏪쏫쏬쏮",5,"쏶쏷쏹",5],["9c61","쏿",8,"쐉",6,"쐑",9],["9c81","쐛",8,"쐥",6,"쐭쐮쐯쐱쐲쐳쐵",6,"쐾",9,"쑉",26,"쑦쑧쑩쑪쑫쑭",6,"쑶쑷쑸쑺",5,"쒁",18,"쒕",6,"쒝",12],["9d41","쒪",13,"쒹쒺쒻쒽",8],["9d61","쓆",25],["9d81","쓠",8,"쓪",5,"쓲쓳쓵쓶쓷쓹쓻쓼쓽쓾씂",9,"씍씎씏씑씒씓씕",6,"씝",10,"씪씫씭씮씯씱",6,"씺씼씾",5,"앆앇앋앏앐앑앒앖앚앛앜앟앢앣앥앦앧앩",6,"앲앶",5,"앾앿얁얂얃얅얆얈얉얊얋얎얐얒얓얔"],["9e41","얖얙얚얛얝얞얟얡",7,"얪",9,"얶"],["9e61","얷얺얿",4,"엋엍엏엒엓엕엖엗엙",6,"엢엤엦엧"],["9e81","엨엩엪엫엯엱엲엳엵엸엹엺엻옂옃옄옉옊옋옍옎옏옑",6,"옚옝",6,"옦옧옩옪옫옯옱옲옶옸옺옼옽옾옿왂왃왅왆왇왉",6,"왒왖",5,"왞왟왡",10,"왭왮왰왲",5,"왺왻왽왾왿욁",6,"욊욌욎",5,"욖욗욙욚욛욝",6,"욦"],["9f41","욨욪",5,"욲욳욵욶욷욻",4,"웂웄웆",5,"웎"],["9f61","웏웑웒웓웕",6,"웞웟웢",5,"웪웫웭웮웯웱웲"],["9f81","웳",4,"웺웻웼웾",5,"윆윇윉윊윋윍",6,"윖윘윚",5,"윢윣윥윦윧윩",6,"윲윴윶윸윹윺윻윾윿읁읂읃읅",4,"읋읎읐읙읚읛읝읞읟읡",6,"읩읪읬",7,"읶읷읹읺읻읿잀잁잂잆잋잌잍잏잒잓잕잙잛",4,"잢잧",4,"잮잯잱잲잳잵잶잷"],["a041","잸잹잺잻잾쟂",5,"쟊쟋쟍쟏쟑",6,"쟙쟚쟛쟜"],["a061","쟞",5,"쟥쟦쟧쟩쟪쟫쟭",13],["a081","쟻",4,"젂젃젅젆젇젉젋",4,"젒젔젗",4,"젞젟젡젢젣젥",6,"젮젰젲",5,"젹젺젻젽젾젿졁",6,"졊졋졎",5,"졕",26,"졲졳졵졶졷졹졻",4,"좂좄좈좉좊좎",5,"좕",7,"좞좠좢좣좤"],["a141","좥좦좧좩",18,"좾좿죀죁"],["a161","죂죃죅죆죇죉죊죋죍",6,"죖죘죚",5,"죢죣죥"],["a181","죦",14,"죶",5,"죾죿줁줂줃줇",4,"줎 、。·‥…¨〃­―∥\∼‘’“”〔〕〈",9,"±×÷≠≤≥∞∴°′″℃Å¢£¥♂♀∠⊥⌒∂∇≡≒§※☆★○●◎◇◆□■△▲▽▼→←↑↓↔〓≪≫√∽∝∵∫∬∈∋⊆⊇⊂⊃∪∩∧∨¬"],["a241","줐줒",5,"줙",18],["a261","줭",6,"줵",18],["a281","쥈",7,"쥒쥓쥕쥖쥗쥙",6,"쥢쥤",7,"쥭쥮쥯⇒⇔∀∃´~ˇ˘˝˚˙¸˛¡¿ː∮∑∏¤℉‰◁◀▷▶♤♠♡♥♧♣⊙◈▣◐◑▒▤▥▨▧▦▩♨☏☎☜☞¶†‡↕↗↙↖↘♭♩♪♬㉿㈜№㏇™㏂㏘℡€®"],["a341","쥱쥲쥳쥵",6,"쥽",10,"즊즋즍즎즏"],["a361","즑",6,"즚즜즞",16],["a381","즯",16,"짂짃짅짆짉짋",4,"짒짔짗짘짛!",58,"₩]",32," ̄"],["a441","짞짟짡짣짥짦짨짩짪짫짮짲",5,"짺짻짽짾짿쨁쨂쨃쨄"],["a461","쨅쨆쨇쨊쨎",5,"쨕쨖쨗쨙",12],["a481","쨦쨧쨨쨪",28,"ㄱ",93],["a541","쩇",4,"쩎쩏쩑쩒쩓쩕",6,"쩞쩢",5,"쩩쩪"],["a561","쩫",17,"쩾",5,"쪅쪆"],["a581","쪇",16,"쪙",14,"ⅰ",9],["a5b0","Ⅰ",9],["a5c1","Α",16,"Σ",6],["a5e1","α",16,"σ",6],["a641","쪨",19,"쪾쪿쫁쫂쫃쫅"],["a661","쫆",5,"쫎쫐쫒쫔쫕쫖쫗쫚",5,"쫡",6],["a681","쫨쫩쫪쫫쫭",6,"쫵",18,"쬉쬊─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂┒┑┚┙┖┕┎┍┞┟┡┢┦┧┩┪┭┮┱┲┵┶┹┺┽┾╀╁╃",7],["a741","쬋",4,"쬑쬒쬓쬕쬖쬗쬙",6,"쬢",7],["a761","쬪",22,"쭂쭃쭄"],["a781","쭅쭆쭇쭊쭋쭍쭎쭏쭑",6,"쭚쭛쭜쭞",5,"쭥",7,"㎕㎖㎗ℓ㎘㏄㎣㎤㎥㎦㎙",9,"㏊㎍㎎㎏㏏㎈㎉㏈㎧㎨㎰",9,"㎀",4,"㎺",5,"㎐",4,"Ω㏀㏁㎊㎋㎌㏖㏅㎭㎮㎯㏛㎩㎪㎫㎬㏝㏐㏓㏃㏉㏜㏆"],["a841","쭭",10,"쭺",14],["a861","쮉",18,"쮝",6],["a881","쮤",19,"쮹",11,"ÆÐªĦ"],["a8a6","IJ"],["a8a8","ĿŁØŒºÞŦŊ"],["a8b1","㉠",27,"ⓐ",25,"①",14,"½⅓⅔¼¾⅛⅜⅝⅞"],["a941","쯅",14,"쯕",10],["a961","쯠쯡쯢쯣쯥쯦쯨쯪",18],["a981","쯽",14,"찎찏찑찒찓찕",6,"찞찟찠찣찤æđðħıijĸŀłøœßþŧŋʼn㈀",27,"⒜",25,"⑴",14,"¹²³⁴ⁿ₁₂₃₄"],["aa41","찥찦찪찫찭찯찱",6,"찺찿",4,"챆챇챉챊챋챍챎"],["aa61","챏",4,"챖챚",5,"챡챢챣챥챧챩",6,"챱챲"],["aa81","챳챴챶",29,"ぁ",82],["ab41","첔첕첖첗첚첛첝첞첟첡",6,"첪첮",5,"첶첷첹"],["ab61","첺첻첽",6,"쳆쳈쳊",5,"쳑쳒쳓쳕",5],["ab81","쳛",8,"쳥",6,"쳭쳮쳯쳱",12,"ァ",85],["ac41","쳾쳿촀촂",5,"촊촋촍촎촏촑",6,"촚촜촞촟촠"],["ac61","촡촢촣촥촦촧촩촪촫촭",11,"촺",4],["ac81","촿",28,"쵝쵞쵟А",5,"ЁЖ",25],["acd1","а",5,"ёж",25],["ad41","쵡쵢쵣쵥",6,"쵮쵰쵲",5,"쵹",7],["ad61","춁",6,"춉",10,"춖춗춙춚춛춝춞춟"],["ad81","춠춡춢춣춦춨춪",5,"춱",18,"췅"],["ae41","췆",5,"췍췎췏췑",16],["ae61","췢",5,"췩췪췫췭췮췯췱",6,"췺췼췾",4],["ae81","츃츅츆츇츉츊츋츍",6,"츕츖츗츘츚",5,"츢츣츥츦츧츩츪츫"],["af41","츬츭츮츯츲츴츶",19],["af61","칊",13,"칚칛칝칞칢",5,"칪칬"],["af81","칮",5,"칶칷칹칺칻칽",6,"캆캈캊",5,"캒캓캕캖캗캙"],["b041","캚",5,"캢캦",5,"캮",12],["b061","캻",5,"컂",19],["b081","컖",13,"컦컧컩컪컭",6,"컶컺",5,"가각간갇갈갉갊감",7,"같",4,"갠갤갬갭갯갰갱갸갹갼걀걋걍걔걘걜거걱건걷걸걺검겁것겄겅겆겉겊겋게겐겔겜겝겟겠겡겨격겪견겯결겸겹겻겼경곁계곈곌곕곗고곡곤곧골곪곬곯곰곱곳공곶과곽관괄괆"],["b141","켂켃켅켆켇켉",6,"켒켔켖",5,"켝켞켟켡켢켣"],["b161","켥",6,"켮켲",5,"켹",11],["b181","콅",14,"콖콗콙콚콛콝",6,"콦콨콪콫콬괌괍괏광괘괜괠괩괬괭괴괵괸괼굄굅굇굉교굔굘굡굣구국군굳굴굵굶굻굼굽굿궁궂궈궉권궐궜궝궤궷귀귁귄귈귐귑귓규균귤그극근귿글긁금급긋긍긔기긱긴긷길긺김깁깃깅깆깊까깍깎깐깔깖깜깝깟깠깡깥깨깩깬깰깸"],["b241","콭콮콯콲콳콵콶콷콹",6,"쾁쾂쾃쾄쾆",5,"쾍"],["b261","쾎",18,"쾢",5,"쾩"],["b281","쾪",5,"쾱",18,"쿅",6,"깹깻깼깽꺄꺅꺌꺼꺽꺾껀껄껌껍껏껐껑께껙껜껨껫껭껴껸껼꼇꼈꼍꼐꼬꼭꼰꼲꼴꼼꼽꼿꽁꽂꽃꽈꽉꽐꽜꽝꽤꽥꽹꾀꾄꾈꾐꾑꾕꾜꾸꾹꾼꿀꿇꿈꿉꿋꿍꿎꿔꿜꿨꿩꿰꿱꿴꿸뀀뀁뀄뀌뀐뀔뀜뀝뀨끄끅끈끊끌끎끓끔끕끗끙"],["b341","쿌",19,"쿢쿣쿥쿦쿧쿩"],["b361","쿪",5,"쿲쿴쿶",5,"쿽쿾쿿퀁퀂퀃퀅",5],["b381","퀋",5,"퀒",5,"퀙",19,"끝끼끽낀낄낌낍낏낑나낙낚난낟날낡낢남납낫",4,"낱낳내낵낸낼냄냅냇냈냉냐냑냔냘냠냥너넉넋넌널넒넓넘넙넛넜넝넣네넥넨넬넴넵넷넸넹녀녁년녈념녑녔녕녘녜녠노녹논놀놂놈놉놋농높놓놔놘놜놨뇌뇐뇔뇜뇝"],["b441","퀮",5,"퀶퀷퀹퀺퀻퀽",6,"큆큈큊",5],["b461","큑큒큓큕큖큗큙",6,"큡",10,"큮큯"],["b481","큱큲큳큵",6,"큾큿킀킂",18,"뇟뇨뇩뇬뇰뇹뇻뇽누눅눈눋눌눔눕눗눙눠눴눼뉘뉜뉠뉨뉩뉴뉵뉼늄늅늉느늑는늘늙늚늠늡늣능늦늪늬늰늴니닉닌닐닒님닙닛닝닢다닥닦단닫",4,"닳담답닷",4,"닿대댁댄댈댐댑댓댔댕댜더덕덖던덛덜덞덟덤덥"],["b541","킕",14,"킦킧킩킪킫킭",5],["b561","킳킶킸킺",5,"탂탃탅탆탇탊",5,"탒탖",4],["b581","탛탞탟탡탢탣탥",6,"탮탲",5,"탹",11,"덧덩덫덮데덱덴델뎀뎁뎃뎄뎅뎌뎐뎔뎠뎡뎨뎬도독돈돋돌돎돐돔돕돗동돛돝돠돤돨돼됐되된될됨됩됫됴두둑둔둘둠둡둣둥둬뒀뒈뒝뒤뒨뒬뒵뒷뒹듀듄듈듐듕드득든듣들듦듬듭듯등듸디딕딘딛딜딤딥딧딨딩딪따딱딴딸"],["b641","턅",7,"턎",17],["b661","턠",15,"턲턳턵턶턷턹턻턼턽턾"],["b681","턿텂텆",5,"텎텏텑텒텓텕",6,"텞텠텢",5,"텩텪텫텭땀땁땃땄땅땋때땍땐땔땜땝땟땠땡떠떡떤떨떪떫떰떱떳떴떵떻떼떽뗀뗄뗌뗍뗏뗐뗑뗘뗬또똑똔똘똥똬똴뙈뙤뙨뚜뚝뚠뚤뚫뚬뚱뛔뛰뛴뛸뜀뜁뜅뜨뜩뜬뜯뜰뜸뜹뜻띄띈띌띔띕띠띤띨띰띱띳띵라락란랄람랍랏랐랑랒랖랗"],["b741","텮",13,"텽",6,"톅톆톇톉톊"],["b761","톋",20,"톢톣톥톦톧"],["b781","톩",6,"톲톴톶톷톸톹톻톽톾톿퇁",14,"래랙랜랠램랩랫랬랭랴략랸럇량러럭런럴럼럽럿렀렁렇레렉렌렐렘렙렛렝려력련렬렴렵렷렸령례롄롑롓로록론롤롬롭롯롱롸롼뢍뢨뢰뢴뢸룀룁룃룅료룐룔룝룟룡루룩룬룰룸룹룻룽뤄뤘뤠뤼뤽륀륄륌륏륑류륙륜률륨륩"],["b841","퇐",7,"퇙",17],["b861","퇫",8,"퇵퇶퇷퇹",13],["b881","툈툊",5,"툑",24,"륫륭르륵른를름릅릇릉릊릍릎리릭린릴림립릿링마막만많",4,"맘맙맛망맞맡맣매맥맨맬맴맵맷맸맹맺먀먁먈먕머먹먼멀멂멈멉멋멍멎멓메멕멘멜멤멥멧멨멩며멱면멸몃몄명몇몌모목몫몬몰몲몸몹못몽뫄뫈뫘뫙뫼"],["b941","툪툫툮툯툱툲툳툵",6,"툾퉀퉂",5,"퉉퉊퉋퉌"],["b961","퉍",14,"퉝",6,"퉥퉦퉧퉨"],["b981","퉩",22,"튂튃튅튆튇튉튊튋튌묀묄묍묏묑묘묜묠묩묫무묵묶문묻물묽묾뭄뭅뭇뭉뭍뭏뭐뭔뭘뭡뭣뭬뮈뮌뮐뮤뮨뮬뮴뮷므믄믈믐믓미믹민믿밀밂밈밉밋밌밍및밑바",4,"받",4,"밤밥밧방밭배백밴밸뱀뱁뱃뱄뱅뱉뱌뱍뱐뱝버벅번벋벌벎범법벗"],["ba41","튍튎튏튒튓튔튖",5,"튝튞튟튡튢튣튥",6,"튭"],["ba61","튮튯튰튲",5,"튺튻튽튾틁틃",4,"틊틌",5],["ba81","틒틓틕틖틗틙틚틛틝",6,"틦",9,"틲틳틵틶틷틹틺벙벚베벡벤벧벨벰벱벳벴벵벼벽변별볍볏볐병볕볘볜보복볶본볼봄봅봇봉봐봔봤봬뵀뵈뵉뵌뵐뵘뵙뵤뵨부북분붇불붉붊붐붑붓붕붙붚붜붤붰붸뷔뷕뷘뷜뷩뷰뷴뷸븀븃븅브븍븐블븜븝븟비빅빈빌빎빔빕빗빙빚빛빠빡빤"],["bb41","틻",4,"팂팄팆",5,"팏팑팒팓팕팗",4,"팞팢팣"],["bb61","팤팦팧팪팫팭팮팯팱",6,"팺팾",5,"퍆퍇퍈퍉"],["bb81","퍊",31,"빨빪빰빱빳빴빵빻빼빽뺀뺄뺌뺍뺏뺐뺑뺘뺙뺨뻐뻑뻔뻗뻘뻠뻣뻤뻥뻬뼁뼈뼉뼘뼙뼛뼜뼝뽀뽁뽄뽈뽐뽑뽕뾔뾰뿅뿌뿍뿐뿔뿜뿟뿡쀼쁑쁘쁜쁠쁨쁩삐삑삔삘삠삡삣삥사삭삯산삳살삵삶삼삽삿샀상샅새색샌샐샘샙샛샜생샤"],["bc41","퍪",17,"퍾퍿펁펂펃펅펆펇"],["bc61","펈펉펊펋펎펒",5,"펚펛펝펞펟펡",6,"펪펬펮"],["bc81","펯",4,"펵펶펷펹펺펻펽",6,"폆폇폊",5,"폑",5,"샥샨샬샴샵샷샹섀섄섈섐섕서",4,"섣설섦섧섬섭섯섰성섶세섹센셀셈셉셋셌셍셔셕션셜셤셥셧셨셩셰셴셸솅소속솎손솔솖솜솝솟송솥솨솩솬솰솽쇄쇈쇌쇔쇗쇘쇠쇤쇨쇰쇱쇳쇼쇽숀숄숌숍숏숑수숙순숟술숨숩숫숭"],["bd41","폗폙",7,"폢폤",7,"폮폯폱폲폳폵폶폷"],["bd61","폸폹폺폻폾퐀퐂",5,"퐉",13],["bd81","퐗",5,"퐞",25,"숯숱숲숴쉈쉐쉑쉔쉘쉠쉥쉬쉭쉰쉴쉼쉽쉿슁슈슉슐슘슛슝스슥슨슬슭슴습슷승시식신싣실싫심십싯싱싶싸싹싻싼쌀쌈쌉쌌쌍쌓쌔쌕쌘쌜쌤쌥쌨쌩썅써썩썬썰썲썸썹썼썽쎄쎈쎌쏀쏘쏙쏜쏟쏠쏢쏨쏩쏭쏴쏵쏸쐈쐐쐤쐬쐰"],["be41","퐸",7,"푁푂푃푅",14],["be61","푔",7,"푝푞푟푡푢푣푥",7,"푮푰푱푲"],["be81","푳",4,"푺푻푽푾풁풃",4,"풊풌풎",5,"풕",8,"쐴쐼쐽쑈쑤쑥쑨쑬쑴쑵쑹쒀쒔쒜쒸쒼쓩쓰쓱쓴쓸쓺쓿씀씁씌씐씔씜씨씩씬씰씸씹씻씽아악안앉않알앍앎앓암압앗았앙앝앞애액앤앨앰앱앳앴앵야약얀얄얇얌얍얏양얕얗얘얜얠얩어억언얹얻얼얽얾엄",6,"엌엎"],["bf41","풞",10,"풪",14],["bf61","풹",18,"퓍퓎퓏퓑퓒퓓퓕"],["bf81","퓖",5,"퓝퓞퓠",7,"퓩퓪퓫퓭퓮퓯퓱",6,"퓹퓺퓼에엑엔엘엠엡엣엥여역엮연열엶엷염",5,"옅옆옇예옌옐옘옙옛옜오옥온올옭옮옰옳옴옵옷옹옻와왁완왈왐왑왓왔왕왜왝왠왬왯왱외왹왼욀욈욉욋욍요욕욘욜욤욥욧용우욱운울욹욺움웁웃웅워웍원월웜웝웠웡웨"],["c041","퓾",5,"픅픆픇픉픊픋픍",6,"픖픘",5],["c061","픞",25],["c081","픸픹픺픻픾픿핁핂핃핅",6,"핎핐핒",5,"핚핛핝핞핟핡핢핣웩웬웰웸웹웽위윅윈윌윔윕윗윙유육윤율윰윱윳융윷으윽은을읊음읍읏응",7,"읜읠읨읫이익인일읽읾잃임입잇있잉잊잎자작잔잖잗잘잚잠잡잣잤장잦재잭잰잴잼잽잿쟀쟁쟈쟉쟌쟎쟐쟘쟝쟤쟨쟬저적전절젊"],["c141","핤핦핧핪핬핮",5,"핶핷핹핺핻핽",6,"햆햊햋"],["c161","햌햍햎햏햑",19,"햦햧"],["c181","햨",31,"점접젓정젖제젝젠젤젬젭젯젱져젼졀졈졉졌졍졔조족존졸졺좀좁좃종좆좇좋좌좍좔좝좟좡좨좼좽죄죈죌죔죕죗죙죠죡죤죵주죽준줄줅줆줌줍줏중줘줬줴쥐쥑쥔쥘쥠쥡쥣쥬쥰쥴쥼즈즉즌즐즘즙즛증지직진짇질짊짐집짓"],["c241","헊헋헍헎헏헑헓",4,"헚헜헞",5,"헦헧헩헪헫헭헮"],["c261","헯",4,"헶헸헺",5,"혂혃혅혆혇혉",6,"혒"],["c281","혖",5,"혝혞혟혡혢혣혥",7,"혮",9,"혺혻징짖짙짚짜짝짠짢짤짧짬짭짯짰짱째짹짼쨀쨈쨉쨋쨌쨍쨔쨘쨩쩌쩍쩐쩔쩜쩝쩟쩠쩡쩨쩽쪄쪘쪼쪽쫀쫄쫌쫍쫏쫑쫓쫘쫙쫠쫬쫴쬈쬐쬔쬘쬠쬡쭁쭈쭉쭌쭐쭘쭙쭝쭤쭸쭹쮜쮸쯔쯤쯧쯩찌찍찐찔찜찝찡찢찧차착찬찮찰참찹찻"],["c341","혽혾혿홁홂홃홄홆홇홊홌홎홏홐홒홓홖홗홙홚홛홝",4],["c361","홢",4,"홨홪",5,"홲홳홵",11],["c381","횁횂횄횆",5,"횎횏횑횒횓횕",7,"횞횠횢",5,"횩횪찼창찾채책챈챌챔챕챗챘챙챠챤챦챨챰챵처척천철첨첩첫첬청체첵첸첼쳄쳅쳇쳉쳐쳔쳤쳬쳰촁초촉촌촐촘촙촛총촤촨촬촹최쵠쵤쵬쵭쵯쵱쵸춈추축춘출춤춥춧충춰췄췌췐취췬췰췸췹췻췽츄츈츌츔츙츠측츤츨츰츱츳층"],["c441","횫횭횮횯횱",7,"횺횼",7,"훆훇훉훊훋"],["c461","훍훎훏훐훒훓훕훖훘훚",5,"훡훢훣훥훦훧훩",4],["c481","훮훯훱훲훳훴훶",5,"훾훿휁휂휃휅",11,"휒휓휔치칙친칟칠칡침칩칫칭카칵칸칼캄캅캇캉캐캑캔캘캠캡캣캤캥캬캭컁커컥컨컫컬컴컵컷컸컹케켁켄켈켐켑켓켕켜켠켤켬켭켯켰켱켸코콕콘콜콤콥콧콩콰콱콴콸쾀쾅쾌쾡쾨쾰쿄쿠쿡쿤쿨쿰쿱쿳쿵쿼퀀퀄퀑퀘퀭퀴퀵퀸퀼"],["c541","휕휖휗휚휛휝휞휟휡",6,"휪휬휮",5,"휶휷휹"],["c561","휺휻휽",6,"흅흆흈흊",5,"흒흓흕흚",4],["c581","흟흢흤흦흧흨흪흫흭흮흯흱흲흳흵",6,"흾흿힀힂",5,"힊힋큄큅큇큉큐큔큘큠크큭큰클큼큽킁키킥킨킬킴킵킷킹타탁탄탈탉탐탑탓탔탕태택탠탤탬탭탯탰탱탸턍터턱턴털턺텀텁텃텄텅테텍텐텔템텝텟텡텨텬텼톄톈토톡톤톨톰톱톳통톺톼퇀퇘퇴퇸툇툉툐투툭툰툴툼툽툿퉁퉈퉜"],["c641","힍힎힏힑",6,"힚힜힞",5],["c6a1","퉤튀튁튄튈튐튑튕튜튠튤튬튱트특튼튿틀틂틈틉틋틔틘틜틤틥티틱틴틸팀팁팃팅파팍팎판팔팖팜팝팟팠팡팥패팩팬팰팸팹팻팼팽퍄퍅퍼퍽펀펄펌펍펏펐펑페펙펜펠펨펩펫펭펴편펼폄폅폈평폐폘폡폣포폭폰폴폼폽폿퐁"],["c7a1","퐈퐝푀푄표푠푤푭푯푸푹푼푿풀풂품풉풋풍풔풩퓌퓐퓔퓜퓟퓨퓬퓰퓸퓻퓽프픈플픔픕픗피픽핀필핌핍핏핑하학한할핥함합핫항해핵핸핼햄햅햇했행햐향허헉헌헐헒험헙헛헝헤헥헨헬헴헵헷헹혀혁현혈혐협혓혔형혜혠"],["c8a1","혤혭호혹혼홀홅홈홉홋홍홑화확환활홧황홰홱홴횃횅회획횐횔횝횟횡효횬횰횹횻후훅훈훌훑훔훗훙훠훤훨훰훵훼훽휀휄휑휘휙휜휠휨휩휫휭휴휵휸휼흄흇흉흐흑흔흖흗흘흙흠흡흣흥흩희흰흴흼흽힁히힉힌힐힘힙힛힝"],["caa1","伽佳假價加可呵哥嘉嫁家暇架枷柯歌珂痂稼苛茄街袈訶賈跏軻迦駕刻却各恪慤殼珏脚覺角閣侃刊墾奸姦干幹懇揀杆柬桿澗癎看磵稈竿簡肝艮艱諫間乫喝曷渴碣竭葛褐蝎鞨勘坎堪嵌感憾戡敢柑橄減甘疳監瞰紺邯鑑鑒龕"],["cba1","匣岬甲胛鉀閘剛堈姜岡崗康强彊慷江畺疆糠絳綱羌腔舡薑襁講鋼降鱇介价個凱塏愷愾慨改槪漑疥皆盖箇芥蓋豈鎧開喀客坑更粳羹醵倨去居巨拒据據擧渠炬祛距踞車遽鉅鋸乾件健巾建愆楗腱虔蹇鍵騫乞傑杰桀儉劍劒檢"],["cca1","瞼鈐黔劫怯迲偈憩揭擊格檄激膈覡隔堅牽犬甄絹繭肩見譴遣鵑抉決潔結缺訣兼慊箝謙鉗鎌京俓倞傾儆勁勍卿坰境庚徑慶憬擎敬景暻更梗涇炅烱璟璥瓊痙硬磬竟競絅經耕耿脛莖警輕逕鏡頃頸驚鯨係啓堺契季屆悸戒桂械"],["cda1","棨溪界癸磎稽系繫繼計誡谿階鷄古叩告呱固姑孤尻庫拷攷故敲暠枯槁沽痼皐睾稿羔考股膏苦苽菰藁蠱袴誥賈辜錮雇顧高鼓哭斛曲梏穀谷鵠困坤崑昆梱棍滾琨袞鯤汨滑骨供公共功孔工恐恭拱控攻珙空蚣貢鞏串寡戈果瓜"],["cea1","科菓誇課跨過鍋顆廓槨藿郭串冠官寬慣棺款灌琯瓘管罐菅觀貫關館刮恝括适侊光匡壙廣曠洸炚狂珖筐胱鑛卦掛罫乖傀塊壞怪愧拐槐魁宏紘肱轟交僑咬喬嬌嶠巧攪敎校橋狡皎矯絞翹膠蕎蛟較轎郊餃驕鮫丘久九仇俱具勾"],["cfa1","區口句咎嘔坵垢寇嶇廐懼拘救枸柩構歐毆毬求溝灸狗玖球瞿矩究絿耉臼舅舊苟衢謳購軀逑邱鉤銶駒驅鳩鷗龜國局菊鞠鞫麴君窘群裙軍郡堀屈掘窟宮弓穹窮芎躬倦券勸卷圈拳捲權淃眷厥獗蕨蹶闕机櫃潰詭軌饋句晷歸貴"],["d0a1","鬼龜叫圭奎揆槻珪硅窺竅糾葵規赳逵閨勻均畇筠菌鈞龜橘克剋劇戟棘極隙僅劤勤懃斤根槿瑾筋芹菫覲謹近饉契今妗擒昑檎琴禁禽芩衾衿襟金錦伋及急扱汲級給亘兢矜肯企伎其冀嗜器圻基埼夔奇妓寄岐崎己幾忌技旗旣"],["d1a1","朞期杞棋棄機欺氣汽沂淇玘琦琪璂璣畸畿碁磯祁祇祈祺箕紀綺羈耆耭肌記譏豈起錡錤飢饑騎騏驥麒緊佶吉拮桔金喫儺喇奈娜懦懶拏拿癩",5,"那樂",4,"諾酪駱亂卵暖欄煖爛蘭難鸞捏捺南嵐枏楠湳濫男藍襤拉"],["d2a1","納臘蠟衲囊娘廊",4,"乃來內奈柰耐冷女年撚秊念恬拈捻寧寗努勞奴弩怒擄櫓爐瑙盧",5,"駑魯",10,"濃籠聾膿農惱牢磊腦賂雷尿壘",7,"嫩訥杻紐勒",5,"能菱陵尼泥匿溺多茶"],["d3a1","丹亶但單團壇彖斷旦檀段湍短端簞緞蛋袒鄲鍛撻澾獺疸達啖坍憺擔曇淡湛潭澹痰聃膽蕁覃談譚錟沓畓答踏遝唐堂塘幢戇撞棠當糖螳黨代垈坮大對岱帶待戴擡玳臺袋貸隊黛宅德悳倒刀到圖堵塗導屠島嶋度徒悼挑掉搗桃"],["d4a1","棹櫂淘渡滔濤燾盜睹禱稻萄覩賭跳蹈逃途道都鍍陶韜毒瀆牘犢獨督禿篤纛讀墩惇敦旽暾沌焞燉豚頓乭突仝冬凍動同憧東桐棟洞潼疼瞳童胴董銅兜斗杜枓痘竇荳讀豆逗頭屯臀芚遁遯鈍得嶝橙燈登等藤謄鄧騰喇懶拏癩羅"],["d5a1","蘿螺裸邏樂洛烙珞絡落諾酪駱丹亂卵欄欒瀾爛蘭鸞剌辣嵐擥攬欖濫籃纜藍襤覽拉臘蠟廊朗浪狼琅瑯螂郞來崍徠萊冷掠略亮倆兩凉梁樑粮粱糧良諒輛量侶儷勵呂廬慮戾旅櫚濾礪藜蠣閭驢驪麗黎力曆歷瀝礫轢靂憐戀攣漣"],["d6a1","煉璉練聯蓮輦連鍊冽列劣洌烈裂廉斂殮濂簾獵令伶囹寧岺嶺怜玲笭羚翎聆逞鈴零靈領齡例澧禮醴隷勞怒撈擄櫓潞瀘爐盧老蘆虜路輅露魯鷺鹵碌祿綠菉錄鹿麓論壟弄朧瀧瓏籠聾儡瀨牢磊賂賚賴雷了僚寮廖料燎療瞭聊蓼"],["d7a1","遼鬧龍壘婁屢樓淚漏瘻累縷蔞褸鏤陋劉旒柳榴流溜瀏琉瑠留瘤硫謬類六戮陸侖倫崙淪綸輪律慄栗率隆勒肋凜凌楞稜綾菱陵俚利厘吏唎履悧李梨浬犁狸理璃異痢籬罹羸莉裏裡里釐離鯉吝潾燐璘藺躪隣鱗麟林淋琳臨霖砬"],["d8a1","立笠粒摩瑪痲碼磨馬魔麻寞幕漠膜莫邈万卍娩巒彎慢挽晩曼滿漫灣瞞萬蔓蠻輓饅鰻唜抹末沫茉襪靺亡妄忘忙望網罔芒茫莽輞邙埋妹媒寐昧枚梅每煤罵買賣邁魅脈貊陌驀麥孟氓猛盲盟萌冪覓免冕勉棉沔眄眠綿緬面麵滅"],["d9a1","蔑冥名命明暝椧溟皿瞑茗蓂螟酩銘鳴袂侮冒募姆帽慕摸摹暮某模母毛牟牡瑁眸矛耗芼茅謀謨貌木沐牧目睦穆鶩歿沒夢朦蒙卯墓妙廟描昴杳渺猫竗苗錨務巫憮懋戊拇撫无楙武毋無珷畝繆舞茂蕪誣貿霧鵡墨默們刎吻問文"],["daa1","汶紊紋聞蚊門雯勿沕物味媚尾嵋彌微未梶楣渼湄眉米美薇謎迷靡黴岷悶愍憫敏旻旼民泯玟珉緡閔密蜜謐剝博拍搏撲朴樸泊珀璞箔粕縛膊舶薄迫雹駁伴半反叛拌搬攀斑槃泮潘班畔瘢盤盼磐磻礬絆般蟠返頒飯勃拔撥渤潑"],["dba1","發跋醱鉢髮魃倣傍坊妨尨幇彷房放方旁昉枋榜滂磅紡肪膀舫芳蒡蚌訪謗邦防龐倍俳北培徘拜排杯湃焙盃背胚裴裵褙賠輩配陪伯佰帛柏栢白百魄幡樊煩燔番磻繁蕃藩飜伐筏罰閥凡帆梵氾汎泛犯範范法琺僻劈壁擘檗璧癖"],["dca1","碧蘗闢霹便卞弁變辨辯邊別瞥鱉鼈丙倂兵屛幷昞昺柄棅炳甁病秉竝輧餠騈保堡報寶普步洑湺潽珤甫菩補褓譜輔伏僕匐卜宓復服福腹茯蔔複覆輹輻馥鰒本乶俸奉封峯峰捧棒烽熢琫縫蓬蜂逢鋒鳳不付俯傅剖副否咐埠夫婦"],["dda1","孚孵富府復扶敷斧浮溥父符簿缶腐腑膚艀芙莩訃負賦賻赴趺部釜阜附駙鳧北分吩噴墳奔奮忿憤扮昐汾焚盆粉糞紛芬賁雰不佛弗彿拂崩朋棚硼繃鵬丕備匕匪卑妃婢庇悲憊扉批斐枇榧比毖毗毘沸泌琵痺砒碑秕秘粃緋翡肥"],["dea1","脾臂菲蜚裨誹譬費鄙非飛鼻嚬嬪彬斌檳殯浜濱瀕牝玭貧賓頻憑氷聘騁乍事些仕伺似使俟僿史司唆嗣四士奢娑寫寺射巳師徙思捨斜斯柶査梭死沙泗渣瀉獅砂社祀祠私篩紗絲肆舍莎蓑蛇裟詐詞謝賜赦辭邪飼駟麝削數朔索"],["dfa1","傘刪山散汕珊産疝算蒜酸霰乷撒殺煞薩三參杉森渗芟蔘衫揷澁鈒颯上傷像償商喪嘗孀尙峠常床庠廂想桑橡湘爽牀狀相祥箱翔裳觴詳象賞霜塞璽賽嗇塞穡索色牲生甥省笙墅壻嶼序庶徐恕抒捿敍暑曙書栖棲犀瑞筮絮緖署"],["e0a1","胥舒薯西誓逝鋤黍鼠夕奭席惜昔晳析汐淅潟石碩蓆釋錫仙僊先善嬋宣扇敾旋渲煽琁瑄璇璿癬禪線繕羨腺膳船蘚蟬詵跣選銑鐥饍鮮卨屑楔泄洩渫舌薛褻設說雪齧剡暹殲纖蟾贍閃陝攝涉燮葉城姓宬性惺成星晟猩珹盛省筬"],["e1a1","聖聲腥誠醒世勢歲洗稅笹細說貰召嘯塑宵小少巢所掃搔昭梳沼消溯瀟炤燒甦疏疎瘙笑篠簫素紹蔬蕭蘇訴逍遡邵銷韶騷俗屬束涑粟續謖贖速孫巽損蓀遜飡率宋悚松淞訟誦送頌刷殺灑碎鎖衰釗修受嗽囚垂壽嫂守岫峀帥愁"],["e2a1","戍手授搜收數樹殊水洙漱燧狩獸琇璲瘦睡秀穗竪粹綏綬繡羞脩茱蒐蓚藪袖誰讐輸遂邃酬銖銹隋隧隨雖需須首髓鬚叔塾夙孰宿淑潚熟琡璹肅菽巡徇循恂旬栒楯橓殉洵淳珣盾瞬筍純脣舜荀蓴蕣詢諄醇錞順馴戌術述鉥崇崧"],["e3a1","嵩瑟膝蝨濕拾習褶襲丞乘僧勝升承昇繩蠅陞侍匙嘶始媤尸屎屍市弑恃施是時枾柴猜矢示翅蒔蓍視試詩諡豕豺埴寔式息拭植殖湜熄篒蝕識軾食飾伸侁信呻娠宸愼新晨燼申神紳腎臣莘薪藎蜃訊身辛辰迅失室實悉審尋心沁"],["e4a1","沈深瀋甚芯諶什十拾雙氏亞俄兒啞娥峨我牙芽莪蛾衙訝阿雅餓鴉鵝堊岳嶽幄惡愕握樂渥鄂鍔顎鰐齷安岸按晏案眼雁鞍顔鮟斡謁軋閼唵岩巖庵暗癌菴闇壓押狎鴨仰央怏昻殃秧鴦厓哀埃崖愛曖涯碍艾隘靄厄扼掖液縊腋額"],["e5a1","櫻罌鶯鸚也倻冶夜惹揶椰爺耶若野弱掠略約若葯蒻藥躍亮佯兩凉壤孃恙揚攘敭暘梁楊樣洋瀁煬痒瘍禳穰糧羊良襄諒讓釀陽量養圄御於漁瘀禦語馭魚齬億憶抑檍臆偃堰彦焉言諺孼蘖俺儼嚴奄掩淹嶪業円予余勵呂女如廬"],["e6a1","旅歟汝濾璵礖礪與艅茹輿轝閭餘驪麗黎亦力域役易曆歷疫繹譯轢逆驛嚥堧姸娟宴年延憐戀捐挻撚椽沇沿涎涓淵演漣烟然煙煉燃燕璉硏硯秊筵緣練縯聯衍軟輦蓮連鉛鍊鳶列劣咽悅涅烈熱裂說閱厭廉念捻染殮炎焰琰艶苒"],["e7a1","簾閻髥鹽曄獵燁葉令囹塋寧嶺嶸影怜映暎楹榮永泳渶潁濚瀛瀯煐營獰玲瑛瑩瓔盈穎纓羚聆英詠迎鈴鍈零霙靈領乂倪例刈叡曳汭濊猊睿穢芮藝蘂禮裔詣譽豫醴銳隸霓預五伍俉傲午吾吳嗚塢墺奧娛寤悟惡懊敖旿晤梧汚澳"],["e8a1","烏熬獒筽蜈誤鰲鼇屋沃獄玉鈺溫瑥瘟穩縕蘊兀壅擁瓮甕癰翁邕雍饔渦瓦窩窪臥蛙蝸訛婉完宛梡椀浣玩琓琬碗緩翫脘腕莞豌阮頑曰往旺枉汪王倭娃歪矮外嵬巍猥畏了僚僥凹堯夭妖姚寥寮尿嶢拗搖撓擾料曜樂橈燎燿瑤療"],["e9a1","窈窯繇繞耀腰蓼蟯要謠遙遼邀饒慾欲浴縟褥辱俑傭冗勇埇墉容庸慂榕涌湧溶熔瑢用甬聳茸蓉踊鎔鏞龍于佑偶優又友右宇寓尤愚憂旴牛玗瑀盂祐禑禹紆羽芋藕虞迂遇郵釪隅雨雩勖彧旭昱栯煜稶郁頊云暈橒殞澐熉耘芸蕓"],["eaa1","運隕雲韻蔚鬱亐熊雄元原員圓園垣媛嫄寃怨愿援沅洹湲源爰猿瑗苑袁轅遠阮院願鴛月越鉞位偉僞危圍委威尉慰暐渭爲瑋緯胃萎葦蔿蝟衛褘謂違韋魏乳侑儒兪劉唯喩孺宥幼幽庾悠惟愈愉揄攸有杻柔柚柳楡楢油洧流游溜"],["eba1","濡猶猷琉瑜由留癒硫紐維臾萸裕誘諛諭踰蹂遊逾遺酉釉鍮類六堉戮毓肉育陸倫允奫尹崙淪潤玧胤贇輪鈗閏律慄栗率聿戎瀜絨融隆垠恩慇殷誾銀隱乙吟淫蔭陰音飮揖泣邑凝應膺鷹依倚儀宜意懿擬椅毅疑矣義艤薏蟻衣誼"],["eca1","議醫二以伊利吏夷姨履已弛彛怡易李梨泥爾珥理異痍痢移罹而耳肄苡荑裏裡貽貳邇里離飴餌匿溺瀷益翊翌翼謚人仁刃印吝咽因姻寅引忍湮燐璘絪茵藺蚓認隣靭靷鱗麟一佚佾壹日溢逸鎰馹任壬妊姙恁林淋稔臨荏賃入卄"],["eda1","立笠粒仍剩孕芿仔刺咨姉姿子字孜恣慈滋炙煮玆瓷疵磁紫者自茨蔗藉諮資雌作勺嚼斫昨灼炸爵綽芍酌雀鵲孱棧殘潺盞岑暫潛箴簪蠶雜丈仗匠場墻壯奬將帳庄張掌暲杖樟檣欌漿牆狀獐璋章粧腸臟臧莊葬蔣薔藏裝贓醬長"],["eea1","障再哉在宰才材栽梓渽滓災縡裁財載齋齎爭箏諍錚佇低儲咀姐底抵杵楮樗沮渚狙猪疽箸紵苧菹著藷詛貯躇這邸雎齟勣吊嫡寂摘敵滴狄炙的積笛籍績翟荻謫賊赤跡蹟迪迹適鏑佃佺傳全典前剪塡塼奠專展廛悛戰栓殿氈澱"],["efa1","煎琠田甸畑癲筌箋箭篆纏詮輾轉鈿銓錢鐫電顚顫餞切截折浙癤竊節絶占岾店漸点粘霑鮎點接摺蝶丁井亭停偵呈姃定幀庭廷征情挺政整旌晶晸柾楨檉正汀淀淨渟湞瀞炡玎珽町睛碇禎程穽精綎艇訂諪貞鄭酊釘鉦鋌錠霆靖"],["f0a1","靜頂鼎制劑啼堤帝弟悌提梯濟祭第臍薺製諸蹄醍除際霽題齊俎兆凋助嘲弔彫措操早晁曺曹朝條棗槽漕潮照燥爪璪眺祖祚租稠窕粗糟組繰肇藻蚤詔調趙躁造遭釣阻雕鳥族簇足鏃存尊卒拙猝倧宗從悰慫棕淙琮種終綜縱腫"],["f1a1","踪踵鍾鐘佐坐左座挫罪主住侏做姝胄呪周嗾奏宙州廚晝朱柱株注洲湊澍炷珠疇籌紂紬綢舟蛛註誅走躊輳週酎酒鑄駐竹粥俊儁准埈寯峻晙樽浚準濬焌畯竣蠢逡遵雋駿茁中仲衆重卽櫛楫汁葺增憎曾拯烝甑症繒蒸證贈之只"],["f2a1","咫地址志持指摯支旨智枝枳止池沚漬知砥祉祗紙肢脂至芝芷蜘誌識贄趾遲直稙稷織職唇嗔塵振搢晉晋桭榛殄津溱珍瑨璡畛疹盡眞瞋秦縉縝臻蔯袗診賑軫辰進鎭陣陳震侄叱姪嫉帙桎瓆疾秩窒膣蛭質跌迭斟朕什執潗緝輯"],["f3a1","鏶集徵懲澄且侘借叉嗟嵯差次此磋箚茶蹉車遮捉搾着窄錯鑿齪撰澯燦璨瓚竄簒纂粲纘讚贊鑽餐饌刹察擦札紮僭參塹慘慙懺斬站讒讖倉倡創唱娼廠彰愴敞昌昶暢槍滄漲猖瘡窓脹艙菖蒼債埰寀寨彩採砦綵菜蔡采釵冊柵策"],["f4a1","責凄妻悽處倜刺剔尺慽戚拓擲斥滌瘠脊蹠陟隻仟千喘天川擅泉淺玔穿舛薦賤踐遷釧闡阡韆凸哲喆徹撤澈綴輟轍鐵僉尖沾添甛瞻簽籤詹諂堞妾帖捷牒疊睫諜貼輒廳晴淸聽菁請靑鯖切剃替涕滯締諦逮遞體初剿哨憔抄招梢"],["f5a1","椒楚樵炒焦硝礁礎秒稍肖艸苕草蕉貂超酢醋醮促囑燭矗蜀觸寸忖村邨叢塚寵悤憁摠總聰蔥銃撮催崔最墜抽推椎楸樞湫皺秋芻萩諏趨追鄒酋醜錐錘鎚雛騶鰍丑畜祝竺筑築縮蓄蹙蹴軸逐春椿瑃出朮黜充忠沖蟲衝衷悴膵萃"],["f6a1","贅取吹嘴娶就炊翠聚脆臭趣醉驟鷲側仄厠惻測層侈値嗤峙幟恥梔治淄熾痔痴癡稚穉緇緻置致蚩輜雉馳齒則勅飭親七柒漆侵寢枕沈浸琛砧針鍼蟄秤稱快他咤唾墮妥惰打拖朶楕舵陀馱駝倬卓啄坼度托拓擢晫柝濁濯琢琸託"],["f7a1","鐸呑嘆坦彈憚歎灘炭綻誕奪脫探眈耽貪塔搭榻宕帑湯糖蕩兌台太怠態殆汰泰笞胎苔跆邰颱宅擇澤撑攄兎吐土討慟桶洞痛筒統通堆槌腿褪退頹偸套妬投透鬪慝特闖坡婆巴把播擺杷波派爬琶破罷芭跛頗判坂板版瓣販辦鈑"],["f8a1","阪八叭捌佩唄悖敗沛浿牌狽稗覇貝彭澎烹膨愎便偏扁片篇編翩遍鞭騙貶坪平枰萍評吠嬖幣廢弊斃肺蔽閉陛佈包匍匏咆哺圃布怖抛抱捕暴泡浦疱砲胞脯苞葡蒲袍褒逋鋪飽鮑幅暴曝瀑爆輻俵剽彪慓杓標漂瓢票表豹飇飄驃"],["f9a1","品稟楓諷豊風馮彼披疲皮被避陂匹弼必泌珌畢疋筆苾馝乏逼下何厦夏廈昰河瑕荷蝦賀遐霞鰕壑學虐謔鶴寒恨悍旱汗漢澣瀚罕翰閑閒限韓割轄函含咸啣喊檻涵緘艦銜陷鹹合哈盒蛤閤闔陜亢伉姮嫦巷恒抗杭桁沆港缸肛航"],["faa1","行降項亥偕咳垓奚孩害懈楷海瀣蟹解該諧邂駭骸劾核倖幸杏荇行享向嚮珦鄕響餉饗香噓墟虛許憲櫶獻軒歇險驗奕爀赫革俔峴弦懸晛泫炫玄玹現眩睍絃絢縣舷衒見賢鉉顯孑穴血頁嫌俠協夾峽挾浹狹脅脇莢鋏頰亨兄刑型"],["fba1","形泂滎瀅灐炯熒珩瑩荊螢衡逈邢鎣馨兮彗惠慧暳蕙蹊醯鞋乎互呼壕壺好岵弧戶扈昊晧毫浩淏湖滸澔濠濩灝狐琥瑚瓠皓祜糊縞胡芦葫蒿虎號蝴護豪鎬頀顥惑或酷婚昏混渾琿魂忽惚笏哄弘汞泓洪烘紅虹訌鴻化和嬅樺火畵"],["fca1","禍禾花華話譁貨靴廓擴攫確碻穫丸喚奐宦幻患換歡晥桓渙煥環紈還驩鰥活滑猾豁闊凰幌徨恍惶愰慌晃晄榥況湟滉潢煌璜皇篁簧荒蝗遑隍黃匯回廻徊恢悔懷晦會檜淮澮灰獪繪膾茴蛔誨賄劃獲宖橫鐄哮嚆孝效斅曉梟涍淆"],["fda1","爻肴酵驍侯候厚后吼喉嗅帿後朽煦珝逅勛勳塤壎焄熏燻薰訓暈薨喧暄煊萱卉喙毁彙徽揮暉煇諱輝麾休携烋畦虧恤譎鷸兇凶匈洶胸黑昕欣炘痕吃屹紇訖欠欽歆吸恰洽翕興僖凞喜噫囍姬嬉希憙憘戱晞曦熙熹熺犧禧稀羲詰"]]'); + +/***/ }), + +/***/ 8867: +/***/ ((module) => { + +module.exports = JSON.parse('[["0","\\u0000",127],["a140"," ,、。.‧;:?!︰…‥﹐﹑﹒·﹔﹕﹖﹗|–︱—︳╴︴﹏()︵︶{}︷︸〔〕︹︺【】︻︼《》︽︾〈〉︿﹀「」﹁﹂『』﹃﹄﹙﹚"],["a1a1","﹛﹜﹝﹞‘’“”〝〞‵′#&*※§〃○●△▲◎☆★◇◆□■▽▼㊣℅¯ ̄_ˍ﹉﹊﹍﹎﹋﹌﹟﹠﹡+-×÷±√<>=≦≧≠∞≒≡﹢",4,"~∩∪⊥∠∟⊿㏒㏑∫∮∵∴♀♂⊕⊙↑↓←→↖↗↙↘∥∣/"],["a240","\∕﹨$¥〒¢£%@℃℉﹩﹪﹫㏕㎜㎝㎞㏎㎡㎎㎏㏄°兙兛兞兝兡兣嗧瓩糎▁",7,"▏▎▍▌▋▊▉┼┴┬┤├▔─│▕┌┐└┘╭"],["a2a1","╮╰╯═╞╪╡◢◣◥◤╱╲╳0",9,"Ⅰ",9,"〡",8,"十卄卅A",25,"a",21],["a340","wxyzΑ",16,"Σ",6,"α",16,"σ",6,"ㄅ",10],["a3a1","ㄐ",25,"˙ˉˊˇˋ"],["a3e1","€"],["a440","一乙丁七乃九了二人儿入八几刀刁力匕十卜又三下丈上丫丸凡久么也乞于亡兀刃勺千叉口土士夕大女子孑孓寸小尢尸山川工己已巳巾干廾弋弓才"],["a4a1","丑丐不中丰丹之尹予云井互五亢仁什仃仆仇仍今介仄元允內六兮公冗凶分切刈勻勾勿化匹午升卅卞厄友及反壬天夫太夭孔少尤尺屯巴幻廿弔引心戈戶手扎支文斗斤方日曰月木欠止歹毋比毛氏水火爪父爻片牙牛犬王丙"],["a540","世丕且丘主乍乏乎以付仔仕他仗代令仙仞充兄冉冊冬凹出凸刊加功包匆北匝仟半卉卡占卯卮去可古右召叮叩叨叼司叵叫另只史叱台句叭叻四囚外"],["a5a1","央失奴奶孕它尼巨巧左市布平幼弁弘弗必戊打扔扒扑斥旦朮本未末札正母民氐永汁汀氾犯玄玉瓜瓦甘生用甩田由甲申疋白皮皿目矛矢石示禾穴立丞丟乒乓乩亙交亦亥仿伉伙伊伕伍伐休伏仲件任仰仳份企伋光兇兆先全"],["a640","共再冰列刑划刎刖劣匈匡匠印危吉吏同吊吐吁吋各向名合吃后吆吒因回囝圳地在圭圬圯圩夙多夷夸妄奸妃好她如妁字存宇守宅安寺尖屹州帆并年"],["a6a1","式弛忙忖戎戌戍成扣扛托收早旨旬旭曲曳有朽朴朱朵次此死氖汝汗汙江池汐汕污汛汍汎灰牟牝百竹米糸缶羊羽老考而耒耳聿肉肋肌臣自至臼舌舛舟艮色艾虫血行衣西阡串亨位住佇佗佞伴佛何估佐佑伽伺伸佃佔似但佣"],["a740","作你伯低伶余佝佈佚兌克免兵冶冷別判利刪刨劫助努劬匣即卵吝吭吞吾否呎吧呆呃吳呈呂君吩告吹吻吸吮吵吶吠吼呀吱含吟听囪困囤囫坊坑址坍"],["a7a1","均坎圾坐坏圻壯夾妝妒妨妞妣妙妖妍妤妓妊妥孝孜孚孛完宋宏尬局屁尿尾岐岑岔岌巫希序庇床廷弄弟彤形彷役忘忌志忍忱快忸忪戒我抄抗抖技扶抉扭把扼找批扳抒扯折扮投抓抑抆改攻攸旱更束李杏材村杜杖杞杉杆杠"],["a840","杓杗步每求汞沙沁沈沉沅沛汪決沐汰沌汨沖沒汽沃汲汾汴沆汶沍沔沘沂灶灼災灸牢牡牠狄狂玖甬甫男甸皂盯矣私秀禿究系罕肖肓肝肘肛肚育良芒"],["a8a1","芋芍見角言谷豆豕貝赤走足身車辛辰迂迆迅迄巡邑邢邪邦那酉釆里防阮阱阪阬並乖乳事些亞享京佯依侍佳使佬供例來侃佰併侈佩佻侖佾侏侑佺兔兒兕兩具其典冽函刻券刷刺到刮制剁劾劻卒協卓卑卦卷卸卹取叔受味呵"],["a940","咖呸咕咀呻呷咄咒咆呼咐呱呶和咚呢周咋命咎固垃坷坪坩坡坦坤坼夜奉奇奈奄奔妾妻委妹妮姑姆姐姍始姓姊妯妳姒姅孟孤季宗定官宜宙宛尚屈居"],["a9a1","屆岷岡岸岩岫岱岳帘帚帖帕帛帑幸庚店府底庖延弦弧弩往征彿彼忝忠忽念忿怏怔怯怵怖怪怕怡性怩怫怛或戕房戾所承拉拌拄抿拂抹拒招披拓拔拋拈抨抽押拐拙拇拍抵拚抱拘拖拗拆抬拎放斧於旺昔易昌昆昂明昀昏昕昊"],["aa40","昇服朋杭枋枕東果杳杷枇枝林杯杰板枉松析杵枚枓杼杪杲欣武歧歿氓氛泣注泳沱泌泥河沽沾沼波沫法泓沸泄油況沮泗泅泱沿治泡泛泊沬泯泜泖泠"],["aaa1","炕炎炒炊炙爬爭爸版牧物狀狎狙狗狐玩玨玟玫玥甽疝疙疚的盂盲直知矽社祀祁秉秈空穹竺糾罔羌羋者肺肥肢肱股肫肩肴肪肯臥臾舍芳芝芙芭芽芟芹花芬芥芯芸芣芰芾芷虎虱初表軋迎返近邵邸邱邶采金長門阜陀阿阻附"],["ab40","陂隹雨青非亟亭亮信侵侯便俠俑俏保促侶俘俟俊俗侮俐俄係俚俎俞侷兗冒冑冠剎剃削前剌剋則勇勉勃勁匍南卻厚叛咬哀咨哎哉咸咦咳哇哂咽咪品"],["aba1","哄哈咯咫咱咻咩咧咿囿垂型垠垣垢城垮垓奕契奏奎奐姜姘姿姣姨娃姥姪姚姦威姻孩宣宦室客宥封屎屏屍屋峙峒巷帝帥帟幽庠度建弈弭彥很待徊律徇後徉怒思怠急怎怨恍恰恨恢恆恃恬恫恪恤扁拜挖按拼拭持拮拽指拱拷"],["ac40","拯括拾拴挑挂政故斫施既春昭映昧是星昨昱昤曷柿染柱柔某柬架枯柵柩柯柄柑枴柚查枸柏柞柳枰柙柢柝柒歪殃殆段毒毗氟泉洋洲洪流津洌洱洞洗"],["aca1","活洽派洶洛泵洹洧洸洩洮洵洎洫炫為炳炬炯炭炸炮炤爰牲牯牴狩狠狡玷珊玻玲珍珀玳甚甭畏界畎畋疫疤疥疢疣癸皆皇皈盈盆盃盅省盹相眉看盾盼眇矜砂研砌砍祆祉祈祇禹禺科秒秋穿突竿竽籽紂紅紀紉紇約紆缸美羿耄"],["ad40","耐耍耑耶胖胥胚胃胄背胡胛胎胞胤胝致舢苧范茅苣苛苦茄若茂茉苒苗英茁苜苔苑苞苓苟苯茆虐虹虻虺衍衫要觔計訂訃貞負赴赳趴軍軌述迦迢迪迥"],["ada1","迭迫迤迨郊郎郁郃酋酊重閂限陋陌降面革韋韭音頁風飛食首香乘亳倌倍倣俯倦倥俸倩倖倆值借倚倒們俺倀倔倨俱倡個候倘俳修倭倪俾倫倉兼冤冥冢凍凌准凋剖剜剔剛剝匪卿原厝叟哨唐唁唷哼哥哲唆哺唔哩哭員唉哮哪"],["ae40","哦唧唇哽唏圃圄埂埔埋埃堉夏套奘奚娑娘娜娟娛娓姬娠娣娩娥娌娉孫屘宰害家宴宮宵容宸射屑展屐峭峽峻峪峨峰島崁峴差席師庫庭座弱徒徑徐恙"],["aea1","恣恥恐恕恭恩息悄悟悚悍悔悌悅悖扇拳挈拿捎挾振捕捂捆捏捉挺捐挽挪挫挨捍捌效敉料旁旅時晉晏晃晒晌晅晁書朔朕朗校核案框桓根桂桔栩梳栗桌桑栽柴桐桀格桃株桅栓栘桁殊殉殷氣氧氨氦氤泰浪涕消涇浦浸海浙涓"],["af40","浬涉浮浚浴浩涌涊浹涅浥涔烊烘烤烙烈烏爹特狼狹狽狸狷玆班琉珮珠珪珞畔畝畜畚留疾病症疲疳疽疼疹痂疸皋皰益盍盎眩真眠眨矩砰砧砸砝破砷"],["afa1","砥砭砠砟砲祕祐祠祟祖神祝祗祚秤秣秧租秦秩秘窄窈站笆笑粉紡紗紋紊素索純紐紕級紜納紙紛缺罟羔翅翁耆耘耕耙耗耽耿胱脂胰脅胭胴脆胸胳脈能脊胼胯臭臬舀舐航舫舨般芻茫荒荔荊茸荐草茵茴荏茲茹茶茗荀茱茨荃"],["b040","虔蚊蚪蚓蚤蚩蚌蚣蚜衰衷袁袂衽衹記訐討訌訕訊託訓訖訏訑豈豺豹財貢起躬軒軔軏辱送逆迷退迺迴逃追逅迸邕郡郝郢酒配酌釘針釗釜釙閃院陣陡"],["b0a1","陛陝除陘陞隻飢馬骨高鬥鬲鬼乾偺偽停假偃偌做偉健偶偎偕偵側偷偏倏偯偭兜冕凰剪副勒務勘動匐匏匙匿區匾參曼商啪啦啄啞啡啃啊唱啖問啕唯啤唸售啜唬啣唳啁啗圈國圉域堅堊堆埠埤基堂堵執培夠奢娶婁婉婦婪婀"],["b140","娼婢婚婆婊孰寇寅寄寂宿密尉專將屠屜屝崇崆崎崛崖崢崑崩崔崙崤崧崗巢常帶帳帷康庸庶庵庾張強彗彬彩彫得徙從徘御徠徜恿患悉悠您惋悴惦悽"],["b1a1","情悻悵惜悼惘惕惆惟悸惚惇戚戛扈掠控捲掖探接捷捧掘措捱掩掉掃掛捫推掄授掙採掬排掏掀捻捩捨捺敝敖救教敗啟敏敘敕敔斜斛斬族旋旌旎晝晚晤晨晦晞曹勗望梁梯梢梓梵桿桶梱梧梗械梃棄梭梆梅梔條梨梟梡梂欲殺"],["b240","毫毬氫涎涼淳淙液淡淌淤添淺清淇淋涯淑涮淞淹涸混淵淅淒渚涵淚淫淘淪深淮淨淆淄涪淬涿淦烹焉焊烽烯爽牽犁猜猛猖猓猙率琅琊球理現琍瓠瓶"],["b2a1","瓷甜產略畦畢異疏痔痕疵痊痍皎盔盒盛眷眾眼眶眸眺硫硃硎祥票祭移窒窕笠笨笛第符笙笞笮粒粗粕絆絃統紮紹紼絀細紳組累終紲紱缽羞羚翌翎習耜聊聆脯脖脣脫脩脰脤舂舵舷舶船莎莞莘荸莢莖莽莫莒莊莓莉莠荷荻荼"],["b340","莆莧處彪蛇蛀蚶蛄蚵蛆蛋蚱蚯蛉術袞袈被袒袖袍袋覓規訪訝訣訥許設訟訛訢豉豚販責貫貨貪貧赧赦趾趺軛軟這逍通逗連速逝逐逕逞造透逢逖逛途"],["b3a1","部郭都酗野釵釦釣釧釭釩閉陪陵陳陸陰陴陶陷陬雀雪雩章竟頂頃魚鳥鹵鹿麥麻傢傍傅備傑傀傖傘傚最凱割剴創剩勞勝勛博厥啻喀喧啼喊喝喘喂喜喪喔喇喋喃喳單喟唾喲喚喻喬喱啾喉喫喙圍堯堪場堤堰報堡堝堠壹壺奠"],["b440","婷媚婿媒媛媧孳孱寒富寓寐尊尋就嵌嵐崴嵇巽幅帽幀幃幾廊廁廂廄弼彭復循徨惑惡悲悶惠愜愣惺愕惰惻惴慨惱愎惶愉愀愒戟扉掣掌描揀揩揉揆揍"],["b4a1","插揣提握揖揭揮捶援揪換摒揚揹敞敦敢散斑斐斯普晰晴晶景暑智晾晷曾替期朝棺棕棠棘棗椅棟棵森棧棹棒棲棣棋棍植椒椎棉棚楮棻款欺欽殘殖殼毯氮氯氬港游湔渡渲湧湊渠渥渣減湛湘渤湖湮渭渦湯渴湍渺測湃渝渾滋"],["b540","溉渙湎湣湄湲湩湟焙焚焦焰無然煮焜牌犄犀猶猥猴猩琺琪琳琢琥琵琶琴琯琛琦琨甥甦畫番痢痛痣痙痘痞痠登發皖皓皴盜睏短硝硬硯稍稈程稅稀窘"],["b5a1","窗窖童竣等策筆筐筒答筍筋筏筑粟粥絞結絨絕紫絮絲絡給絢絰絳善翔翕耋聒肅腕腔腋腑腎脹腆脾腌腓腴舒舜菩萃菸萍菠菅萋菁華菱菴著萊菰萌菌菽菲菊萸萎萄菜萇菔菟虛蛟蛙蛭蛔蛛蛤蛐蛞街裁裂袱覃視註詠評詞証詁"],["b640","詔詛詐詆訴診訶詖象貂貯貼貳貽賁費賀貴買貶貿貸越超趁跎距跋跚跑跌跛跆軻軸軼辜逮逵週逸進逶鄂郵鄉郾酣酥量鈔鈕鈣鈉鈞鈍鈐鈇鈑閔閏開閑"],["b6a1","間閒閎隊階隋陽隅隆隍陲隄雁雅雄集雇雯雲韌項順須飧飪飯飩飲飭馮馭黃黍黑亂傭債傲傳僅傾催傷傻傯僇剿剷剽募勦勤勢勣匯嗟嗨嗓嗦嗎嗜嗇嗑嗣嗤嗯嗚嗡嗅嗆嗥嗉園圓塞塑塘塗塚塔填塌塭塊塢塒塋奧嫁嫉嫌媾媽媼"],["b740","媳嫂媲嵩嵯幌幹廉廈弒彙徬微愚意慈感想愛惹愁愈慎慌慄慍愾愴愧愍愆愷戡戢搓搾搞搪搭搽搬搏搜搔損搶搖搗搆敬斟新暗暉暇暈暖暄暘暍會榔業"],["b7a1","楚楷楠楔極椰概楊楨楫楞楓楹榆楝楣楛歇歲毀殿毓毽溢溯滓溶滂源溝滇滅溥溘溼溺溫滑準溜滄滔溪溧溴煎煙煩煤煉照煜煬煦煌煥煞煆煨煖爺牒猷獅猿猾瑯瑚瑕瑟瑞瑁琿瑙瑛瑜當畸瘀痰瘁痲痱痺痿痴痳盞盟睛睫睦睞督"],["b840","睹睪睬睜睥睨睢矮碎碰碗碘碌碉硼碑碓硿祺祿禁萬禽稜稚稠稔稟稞窟窠筷節筠筮筧粱粳粵經絹綑綁綏絛置罩罪署義羨群聖聘肆肄腱腰腸腥腮腳腫"],["b8a1","腹腺腦舅艇蒂葷落萱葵葦葫葉葬葛萼萵葡董葩葭葆虞虜號蛹蜓蜈蜇蜀蛾蛻蜂蜃蜆蜊衙裟裔裙補裘裝裡裊裕裒覜解詫該詳試詩詰誇詼詣誠話誅詭詢詮詬詹詻訾詨豢貊貉賊資賈賄貲賃賂賅跡跟跨路跳跺跪跤跦躲較載軾輊"],["b940","辟農運遊道遂達逼違遐遇遏過遍遑逾遁鄒鄗酬酪酩釉鈷鉗鈸鈽鉀鈾鉛鉋鉤鉑鈴鉉鉍鉅鈹鈿鉚閘隘隔隕雍雋雉雊雷電雹零靖靴靶預頑頓頊頒頌飼飴"],["b9a1","飽飾馳馱馴髡鳩麂鼎鼓鼠僧僮僥僖僭僚僕像僑僱僎僩兢凳劃劂匱厭嗾嘀嘛嘗嗽嘔嘆嘉嘍嘎嗷嘖嘟嘈嘐嗶團圖塵塾境墓墊塹墅塽壽夥夢夤奪奩嫡嫦嫩嫗嫖嫘嫣孵寞寧寡寥實寨寢寤察對屢嶄嶇幛幣幕幗幔廓廖弊彆彰徹慇"],["ba40","愿態慷慢慣慟慚慘慵截撇摘摔撤摸摟摺摑摧搴摭摻敲斡旗旖暢暨暝榜榨榕槁榮槓構榛榷榻榫榴槐槍榭槌榦槃榣歉歌氳漳演滾漓滴漩漾漠漬漏漂漢"],["baa1","滿滯漆漱漸漲漣漕漫漯澈漪滬漁滲滌滷熔熙煽熊熄熒爾犒犖獄獐瑤瑣瑪瑰瑭甄疑瘧瘍瘋瘉瘓盡監瞄睽睿睡磁碟碧碳碩碣禎福禍種稱窪窩竭端管箕箋筵算箝箔箏箸箇箄粹粽精綻綰綜綽綾綠緊綴網綱綺綢綿綵綸維緒緇綬"],["bb40","罰翠翡翟聞聚肇腐膀膏膈膊腿膂臧臺與舔舞艋蓉蒿蓆蓄蒙蒞蒲蒜蓋蒸蓀蓓蒐蒼蓑蓊蜿蜜蜻蜢蜥蜴蜘蝕蜷蜩裳褂裴裹裸製裨褚裯誦誌語誣認誡誓誤"],["bba1","說誥誨誘誑誚誧豪貍貌賓賑賒赫趙趕跼輔輒輕輓辣遠遘遜遣遙遞遢遝遛鄙鄘鄞酵酸酷酴鉸銀銅銘銖鉻銓銜銨鉼銑閡閨閩閣閥閤隙障際雌雒需靼鞅韶頗領颯颱餃餅餌餉駁骯骰髦魁魂鳴鳶鳳麼鼻齊億儀僻僵價儂儈儉儅凜"],["bc40","劇劈劉劍劊勰厲嘮嘻嘹嘲嘿嘴嘩噓噎噗噴嘶嘯嘰墀墟增墳墜墮墩墦奭嬉嫻嬋嫵嬌嬈寮寬審寫層履嶝嶔幢幟幡廢廚廟廝廣廠彈影德徵慶慧慮慝慕憂"],["bca1","慼慰慫慾憧憐憫憎憬憚憤憔憮戮摩摯摹撞撲撈撐撰撥撓撕撩撒撮播撫撚撬撙撢撳敵敷數暮暫暴暱樣樟槨樁樞標槽模樓樊槳樂樅槭樑歐歎殤毅毆漿潼澄潑潦潔澆潭潛潸潮澎潺潰潤澗潘滕潯潠潟熟熬熱熨牖犛獎獗瑩璋璃"],["bd40","瑾璀畿瘠瘩瘟瘤瘦瘡瘢皚皺盤瞎瞇瞌瞑瞋磋磅確磊碾磕碼磐稿稼穀稽稷稻窯窮箭箱範箴篆篇篁箠篌糊締練緯緻緘緬緝編緣線緞緩綞緙緲緹罵罷羯"],["bda1","翩耦膛膜膝膠膚膘蔗蔽蔚蓮蔬蔭蔓蔑蔣蔡蔔蓬蔥蓿蔆螂蝴蝶蝠蝦蝸蝨蝙蝗蝌蝓衛衝褐複褒褓褕褊誼諒談諄誕請諸課諉諂調誰論諍誶誹諛豌豎豬賠賞賦賤賬賭賢賣賜質賡赭趟趣踫踐踝踢踏踩踟踡踞躺輝輛輟輩輦輪輜輞"],["be40","輥適遮遨遭遷鄰鄭鄧鄱醇醉醋醃鋅銻銷鋪銬鋤鋁銳銼鋒鋇鋰銲閭閱霄霆震霉靠鞍鞋鞏頡頫頜颳養餓餒餘駝駐駟駛駑駕駒駙骷髮髯鬧魅魄魷魯鴆鴉"],["bea1","鴃麩麾黎墨齒儒儘儔儐儕冀冪凝劑劓勳噙噫噹噩噤噸噪器噥噱噯噬噢噶壁墾壇壅奮嬝嬴學寰導彊憲憑憩憊懍憶憾懊懈戰擅擁擋撻撼據擄擇擂操撿擒擔撾整曆曉暹曄曇暸樽樸樺橙橫橘樹橄橢橡橋橇樵機橈歙歷氅濂澱澡"],["bf40","濃澤濁澧澳激澹澶澦澠澴熾燉燐燒燈燕熹燎燙燜燃燄獨璜璣璘璟璞瓢甌甍瘴瘸瘺盧盥瞠瞞瞟瞥磨磚磬磧禦積穎穆穌穋窺篙簑築篤篛篡篩篦糕糖縊"],["bfa1","縑縈縛縣縞縝縉縐罹羲翰翱翮耨膳膩膨臻興艘艙蕊蕙蕈蕨蕩蕃蕉蕭蕪蕞螃螟螞螢融衡褪褲褥褫褡親覦諦諺諫諱謀諜諧諮諾謁謂諷諭諳諶諼豫豭貓賴蹄踱踴蹂踹踵輻輯輸輳辨辦遵遴選遲遼遺鄴醒錠錶鋸錳錯錢鋼錫錄錚"],["c040","錐錦錡錕錮錙閻隧隨險雕霎霑霖霍霓霏靛靜靦鞘頰頸頻頷頭頹頤餐館餞餛餡餚駭駢駱骸骼髻髭鬨鮑鴕鴣鴦鴨鴒鴛默黔龍龜優償儡儲勵嚎嚀嚐嚅嚇"],["c0a1","嚏壕壓壑壎嬰嬪嬤孺尷屨嶼嶺嶽嶸幫彌徽應懂懇懦懋戲戴擎擊擘擠擰擦擬擱擢擭斂斃曙曖檀檔檄檢檜櫛檣橾檗檐檠歜殮毚氈濘濱濟濠濛濤濫濯澀濬濡濩濕濮濰燧營燮燦燥燭燬燴燠爵牆獰獲璩環璦璨癆療癌盪瞳瞪瞰瞬"],["c140","瞧瞭矯磷磺磴磯礁禧禪穗窿簇簍篾篷簌篠糠糜糞糢糟糙糝縮績繆縷縲繃縫總縱繅繁縴縹繈縵縿縯罄翳翼聱聲聰聯聳臆臃膺臂臀膿膽臉膾臨舉艱薪"],["c1a1","薄蕾薜薑薔薯薛薇薨薊虧蟀蟑螳蟒蟆螫螻螺蟈蟋褻褶襄褸褽覬謎謗謙講謊謠謝謄謐豁谿豳賺賽購賸賻趨蹉蹋蹈蹊轄輾轂轅輿避遽還邁邂邀鄹醣醞醜鍍鎂錨鍵鍊鍥鍋錘鍾鍬鍛鍰鍚鍔闊闋闌闈闆隱隸雖霜霞鞠韓顆颶餵騁"],["c240","駿鮮鮫鮪鮭鴻鴿麋黏點黜黝黛鼾齋叢嚕嚮壙壘嬸彝懣戳擴擲擾攆擺擻擷斷曜朦檳檬櫃檻檸櫂檮檯歟歸殯瀉瀋濾瀆濺瀑瀏燻燼燾燸獷獵璧璿甕癖癘"],["c2a1","癒瞽瞿瞻瞼礎禮穡穢穠竄竅簫簧簪簞簣簡糧織繕繞繚繡繒繙罈翹翻職聶臍臏舊藏薩藍藐藉薰薺薹薦蟯蟬蟲蟠覆覲觴謨謹謬謫豐贅蹙蹣蹦蹤蹟蹕軀轉轍邇邃邈醫醬釐鎔鎊鎖鎢鎳鎮鎬鎰鎘鎚鎗闔闖闐闕離雜雙雛雞霤鞣鞦"],["c340","鞭韹額顏題顎顓颺餾餿餽餮馥騎髁鬃鬆魏魎魍鯊鯉鯽鯈鯀鵑鵝鵠黠鼕鼬儳嚥壞壟壢寵龐廬懲懷懶懵攀攏曠曝櫥櫝櫚櫓瀛瀟瀨瀚瀝瀕瀘爆爍牘犢獸"],["c3a1","獺璽瓊瓣疇疆癟癡矇礙禱穫穩簾簿簸簽簷籀繫繭繹繩繪羅繳羶羹羸臘藩藝藪藕藤藥藷蟻蠅蠍蟹蟾襠襟襖襞譁譜識證譚譎譏譆譙贈贊蹼蹲躇蹶蹬蹺蹴轔轎辭邊邋醱醮鏡鏑鏟鏃鏈鏜鏝鏖鏢鏍鏘鏤鏗鏨關隴難霪霧靡韜韻類"],["c440","願顛颼饅饉騖騙鬍鯨鯧鯖鯛鶉鵡鵲鵪鵬麒麗麓麴勸嚨嚷嚶嚴嚼壤孀孃孽寶巉懸懺攘攔攙曦朧櫬瀾瀰瀲爐獻瓏癢癥礦礪礬礫竇競籌籃籍糯糰辮繽繼"],["c4a1","纂罌耀臚艦藻藹蘑藺蘆蘋蘇蘊蠔蠕襤覺觸議譬警譯譟譫贏贍躉躁躅躂醴釋鐘鐃鏽闡霰飄饒饑馨騫騰騷騵鰓鰍鹹麵黨鼯齟齣齡儷儸囁囀囂夔屬巍懼懾攝攜斕曩櫻欄櫺殲灌爛犧瓖瓔癩矓籐纏續羼蘗蘭蘚蠣蠢蠡蠟襪襬覽譴"],["c540","護譽贓躊躍躋轟辯醺鐮鐳鐵鐺鐸鐲鐫闢霸霹露響顧顥饗驅驃驀騾髏魔魑鰭鰥鶯鶴鷂鶸麝黯鼙齜齦齧儼儻囈囊囉孿巔巒彎懿攤權歡灑灘玀瓤疊癮癬"],["c5a1","禳籠籟聾聽臟襲襯觼讀贖贗躑躓轡酈鑄鑑鑒霽霾韃韁顫饕驕驍髒鬚鱉鰱鰾鰻鷓鷗鼴齬齪龔囌巖戀攣攫攪曬欐瓚竊籤籣籥纓纖纔臢蘸蘿蠱變邐邏鑣鑠鑤靨顯饜驚驛驗髓體髑鱔鱗鱖鷥麟黴囑壩攬灞癱癲矗罐羈蠶蠹衢讓讒"],["c640","讖艷贛釀鑪靂靈靄韆顰驟鬢魘鱟鷹鷺鹼鹽鼇齷齲廳欖灣籬籮蠻觀躡釁鑲鑰顱饞髖鬣黌灤矚讚鑷韉驢驥纜讜躪釅鑽鑾鑼鱷鱸黷豔鑿鸚爨驪鬱鸛鸞籲"],["c940","乂乜凵匚厂万丌乇亍囗兀屮彳丏冇与丮亓仂仉仈冘勼卬厹圠夃夬尐巿旡殳毌气爿丱丼仨仜仩仡仝仚刌匜卌圢圣夗夯宁宄尒尻屴屳帄庀庂忉戉扐氕"],["c9a1","氶汃氿氻犮犰玊禸肊阞伎优伬仵伔仱伀价伈伝伂伅伢伓伄仴伒冱刓刉刐劦匢匟卍厊吇囡囟圮圪圴夼妀奼妅奻奾奷奿孖尕尥屼屺屻屾巟幵庄异弚彴忕忔忏扜扞扤扡扦扢扙扠扚扥旯旮朾朹朸朻机朿朼朳氘汆汒汜汏汊汔汋"],["ca40","汌灱牞犴犵玎甪癿穵网艸艼芀艽艿虍襾邙邗邘邛邔阢阤阠阣佖伻佢佉体佤伾佧佒佟佁佘伭伳伿佡冏冹刜刞刡劭劮匉卣卲厎厏吰吷吪呔呅吙吜吥吘"],["caa1","吽呏呁吨吤呇囮囧囥坁坅坌坉坋坒夆奀妦妘妠妗妎妢妐妏妧妡宎宒尨尪岍岏岈岋岉岒岊岆岓岕巠帊帎庋庉庌庈庍弅弝彸彶忒忑忐忭忨忮忳忡忤忣忺忯忷忻怀忴戺抃抌抎抏抔抇扱扻扺扰抁抈扷扽扲扴攷旰旴旳旲旵杅杇"],["cb40","杙杕杌杈杝杍杚杋毐氙氚汸汧汫沄沋沏汱汯汩沚汭沇沕沜汦汳汥汻沎灴灺牣犿犽狃狆狁犺狅玕玗玓玔玒町甹疔疕皁礽耴肕肙肐肒肜芐芏芅芎芑芓"],["cba1","芊芃芄豸迉辿邟邡邥邞邧邠阰阨阯阭丳侘佼侅佽侀侇佶佴侉侄佷佌侗佪侚佹侁佸侐侜侔侞侒侂侕佫佮冞冼冾刵刲刳剆刱劼匊匋匼厒厔咇呿咁咑咂咈呫呺呾呥呬呴呦咍呯呡呠咘呣呧呤囷囹坯坲坭坫坱坰坶垀坵坻坳坴坢"],["cc40","坨坽夌奅妵妺姏姎妲姌姁妶妼姃姖妱妽姀姈妴姇孢孥宓宕屄屇岮岤岠岵岯岨岬岟岣岭岢岪岧岝岥岶岰岦帗帔帙弨弢弣弤彔徂彾彽忞忥怭怦怙怲怋"],["cca1","怴怊怗怳怚怞怬怢怍怐怮怓怑怌怉怜戔戽抭抴拑抾抪抶拊抮抳抯抻抩抰抸攽斨斻昉旼昄昒昈旻昃昋昍昅旽昑昐曶朊枅杬枎枒杶杻枘枆构杴枍枌杺枟枑枙枃杽极杸杹枔欥殀歾毞氝沓泬泫泮泙沶泔沭泧沷泐泂沺泃泆泭泲"],["cd40","泒泝沴沊沝沀泞泀洰泍泇沰泹泏泩泑炔炘炅炓炆炄炑炖炂炚炃牪狖狋狘狉狜狒狔狚狌狑玤玡玭玦玢玠玬玝瓝瓨甿畀甾疌疘皯盳盱盰盵矸矼矹矻矺"],["cda1","矷祂礿秅穸穻竻籵糽耵肏肮肣肸肵肭舠芠苀芫芚芘芛芵芧芮芼芞芺芴芨芡芩苂芤苃芶芢虰虯虭虮豖迒迋迓迍迖迕迗邲邴邯邳邰阹阽阼阺陃俍俅俓侲俉俋俁俔俜俙侻侳俛俇俖侺俀侹俬剄剉勀勂匽卼厗厖厙厘咺咡咭咥哏"],["ce40","哃茍咷咮哖咶哅哆咠呰咼咢咾呲哞咰垵垞垟垤垌垗垝垛垔垘垏垙垥垚垕壴复奓姡姞姮娀姱姝姺姽姼姶姤姲姷姛姩姳姵姠姾姴姭宨屌峐峘峌峗峋峛"],["cea1","峞峚峉峇峊峖峓峔峏峈峆峎峟峸巹帡帢帣帠帤庰庤庢庛庣庥弇弮彖徆怷怹恔恲恞恅恓恇恉恛恌恀恂恟怤恄恘恦恮扂扃拏挍挋拵挎挃拫拹挏挌拸拶挀挓挔拺挕拻拰敁敃斪斿昶昡昲昵昜昦昢昳昫昺昝昴昹昮朏朐柁柲柈枺"],["cf40","柜枻柸柘柀枷柅柫柤柟枵柍枳柷柶柮柣柂枹柎柧柰枲柼柆柭柌枮柦柛柺柉柊柃柪柋欨殂殄殶毖毘毠氠氡洨洴洭洟洼洿洒洊泚洳洄洙洺洚洑洀洝浂"],["cfa1","洁洘洷洃洏浀洇洠洬洈洢洉洐炷炟炾炱炰炡炴炵炩牁牉牊牬牰牳牮狊狤狨狫狟狪狦狣玅珌珂珈珅玹玶玵玴珫玿珇玾珃珆玸珋瓬瓮甮畇畈疧疪癹盄眈眃眄眅眊盷盻盺矧矨砆砑砒砅砐砏砎砉砃砓祊祌祋祅祄秕种秏秖秎窀"],["d040","穾竑笀笁籺籸籹籿粀粁紃紈紁罘羑羍羾耇耎耏耔耷胘胇胠胑胈胂胐胅胣胙胜胊胕胉胏胗胦胍臿舡芔苙苾苹茇苨茀苕茺苫苖苴苬苡苲苵茌苻苶苰苪"],["d0a1","苤苠苺苳苭虷虴虼虳衁衎衧衪衩觓訄訇赲迣迡迮迠郱邽邿郕郅邾郇郋郈釔釓陔陏陑陓陊陎倞倅倇倓倢倰倛俵俴倳倷倬俶俷倗倜倠倧倵倯倱倎党冔冓凊凄凅凈凎剡剚剒剞剟剕剢勍匎厞唦哢唗唒哧哳哤唚哿唄唈哫唑唅哱"],["d140","唊哻哷哸哠唎唃唋圁圂埌堲埕埒垺埆垽垼垸垶垿埇埐垹埁夎奊娙娖娭娮娕娏娗娊娞娳孬宧宭宬尃屖屔峬峿峮峱峷崀峹帩帨庨庮庪庬弳弰彧恝恚恧"],["d1a1","恁悢悈悀悒悁悝悃悕悛悗悇悜悎戙扆拲挐捖挬捄捅挶捃揤挹捋捊挼挩捁挴捘捔捙挭捇挳捚捑挸捗捀捈敊敆旆旃旄旂晊晟晇晑朒朓栟栚桉栲栳栻桋桏栖栱栜栵栫栭栯桎桄栴栝栒栔栦栨栮桍栺栥栠欬欯欭欱欴歭肂殈毦毤"],["d240","毨毣毢毧氥浺浣浤浶洍浡涒浘浢浭浯涑涍淯浿涆浞浧浠涗浰浼浟涂涘洯浨涋浾涀涄洖涃浻浽浵涐烜烓烑烝烋缹烢烗烒烞烠烔烍烅烆烇烚烎烡牂牸"],["d2a1","牷牶猀狺狴狾狶狳狻猁珓珙珥珖玼珧珣珩珜珒珛珔珝珚珗珘珨瓞瓟瓴瓵甡畛畟疰痁疻痄痀疿疶疺皊盉眝眛眐眓眒眣眑眕眙眚眢眧砣砬砢砵砯砨砮砫砡砩砳砪砱祔祛祏祜祓祒祑秫秬秠秮秭秪秜秞秝窆窉窅窋窌窊窇竘笐"],["d340","笄笓笅笏笈笊笎笉笒粄粑粊粌粈粍粅紞紝紑紎紘紖紓紟紒紏紌罜罡罞罠罝罛羖羒翃翂翀耖耾耹胺胲胹胵脁胻脀舁舯舥茳茭荄茙荑茥荖茿荁茦茜茢"],["d3a1","荂荎茛茪茈茼荍茖茤茠茷茯茩荇荅荌荓茞茬荋茧荈虓虒蚢蚨蚖蚍蚑蚞蚇蚗蚆蚋蚚蚅蚥蚙蚡蚧蚕蚘蚎蚝蚐蚔衃衄衭衵衶衲袀衱衿衯袃衾衴衼訒豇豗豻貤貣赶赸趵趷趶軑軓迾迵适迿迻逄迼迶郖郠郙郚郣郟郥郘郛郗郜郤酐"],["d440","酎酏釕釢釚陜陟隼飣髟鬯乿偰偪偡偞偠偓偋偝偲偈偍偁偛偊偢倕偅偟偩偫偣偤偆偀偮偳偗偑凐剫剭剬剮勖勓匭厜啵啶唼啍啐唴唪啑啢唶唵唰啒啅"],["d4a1","唌唲啥啎唹啈唭唻啀啋圊圇埻堔埢埶埜埴堀埭埽堈埸堋埳埏堇埮埣埲埥埬埡堎埼堐埧堁堌埱埩埰堍堄奜婠婘婕婧婞娸娵婭婐婟婥婬婓婤婗婃婝婒婄婛婈媎娾婍娹婌婰婩婇婑婖婂婜孲孮寁寀屙崞崋崝崚崠崌崨崍崦崥崏"],["d540","崰崒崣崟崮帾帴庱庴庹庲庳弶弸徛徖徟悊悐悆悾悰悺惓惔惏惤惙惝惈悱惛悷惊悿惃惍惀挲捥掊掂捽掽掞掭掝掗掫掎捯掇掐据掯捵掜捭掮捼掤挻掟"],["d5a1","捸掅掁掑掍捰敓旍晥晡晛晙晜晢朘桹梇梐梜桭桮梮梫楖桯梣梬梩桵桴梲梏桷梒桼桫桲梪梀桱桾梛梖梋梠梉梤桸桻梑梌梊桽欶欳欷欸殑殏殍殎殌氪淀涫涴涳湴涬淩淢涷淶淔渀淈淠淟淖涾淥淜淝淛淴淊涽淭淰涺淕淂淏淉"],["d640","淐淲淓淽淗淍淣涻烺焍烷焗烴焌烰焄烳焐烼烿焆焓焀烸烶焋焂焎牾牻牼牿猝猗猇猑猘猊猈狿猏猞玈珶珸珵琄琁珽琇琀珺珼珿琌琋珴琈畤畣痎痒痏"],["d6a1","痋痌痑痐皏皉盓眹眯眭眱眲眴眳眽眥眻眵硈硒硉硍硊硌砦硅硐祤祧祩祪祣祫祡离秺秸秶秷窏窔窐笵筇笴笥笰笢笤笳笘笪笝笱笫笭笯笲笸笚笣粔粘粖粣紵紽紸紶紺絅紬紩絁絇紾紿絊紻紨罣羕羜羝羛翊翋翍翐翑翇翏翉耟"],["d740","耞耛聇聃聈脘脥脙脛脭脟脬脞脡脕脧脝脢舑舸舳舺舴舲艴莐莣莨莍荺荳莤荴莏莁莕莙荵莔莩荽莃莌莝莛莪莋荾莥莯莈莗莰荿莦莇莮荶莚虙虖蚿蚷"],["d7a1","蛂蛁蛅蚺蚰蛈蚹蚳蚸蛌蚴蚻蚼蛃蚽蚾衒袉袕袨袢袪袚袑袡袟袘袧袙袛袗袤袬袌袓袎覂觖觙觕訰訧訬訞谹谻豜豝豽貥赽赻赹趼跂趹趿跁軘軞軝軜軗軠軡逤逋逑逜逌逡郯郪郰郴郲郳郔郫郬郩酖酘酚酓酕釬釴釱釳釸釤釹釪"],["d840","釫釷釨釮镺閆閈陼陭陫陱陯隿靪頄飥馗傛傕傔傞傋傣傃傌傎傝偨傜傒傂傇兟凔匒匑厤厧喑喨喥喭啷噅喢喓喈喏喵喁喣喒喤啽喌喦啿喕喡喎圌堩堷"],["d8a1","堙堞堧堣堨埵塈堥堜堛堳堿堶堮堹堸堭堬堻奡媯媔媟婺媢媞婸媦婼媥媬媕媮娷媄媊媗媃媋媩婻婽媌媜媏媓媝寪寍寋寔寑寊寎尌尰崷嵃嵫嵁嵋崿崵嵑嵎嵕崳崺嵒崽崱嵙嵂崹嵉崸崼崲崶嵀嵅幄幁彘徦徥徫惉悹惌惢惎惄愔"],["d940","惲愊愖愅惵愓惸惼惾惁愃愘愝愐惿愄愋扊掔掱掰揎揥揨揯揃撝揳揊揠揶揕揲揵摡揟掾揝揜揄揘揓揂揇揌揋揈揰揗揙攲敧敪敤敜敨敥斌斝斞斮旐旒"],["d9a1","晼晬晻暀晱晹晪晲朁椌棓椄棜椪棬棪棱椏棖棷棫棤棶椓椐棳棡椇棌椈楰梴椑棯棆椔棸棐棽棼棨椋椊椗棎棈棝棞棦棴棑椆棔棩椕椥棇欹欻欿欼殔殗殙殕殽毰毲毳氰淼湆湇渟湉溈渼渽湅湢渫渿湁湝湳渜渳湋湀湑渻渃渮湞"],["da40","湨湜湡渱渨湠湱湫渹渢渰湓湥渧湸湤湷湕湹湒湦渵渶湚焠焞焯烻焮焱焣焥焢焲焟焨焺焛牋牚犈犉犆犅犋猒猋猰猢猱猳猧猲猭猦猣猵猌琮琬琰琫琖"],["daa1","琚琡琭琱琤琣琝琩琠琲瓻甯畯畬痧痚痡痦痝痟痤痗皕皒盚睆睇睄睍睅睊睎睋睌矞矬硠硤硥硜硭硱硪确硰硩硨硞硢祴祳祲祰稂稊稃稌稄窙竦竤筊笻筄筈筌筎筀筘筅粢粞粨粡絘絯絣絓絖絧絪絏絭絜絫絒絔絩絑絟絎缾缿罥"],["db40","罦羢羠羡翗聑聏聐胾胔腃腊腒腏腇脽腍脺臦臮臷臸臹舄舼舽舿艵茻菏菹萣菀菨萒菧菤菼菶萐菆菈菫菣莿萁菝菥菘菿菡菋菎菖菵菉萉萏菞萑萆菂菳"],["dba1","菕菺菇菑菪萓菃菬菮菄菻菗菢萛菛菾蛘蛢蛦蛓蛣蛚蛪蛝蛫蛜蛬蛩蛗蛨蛑衈衖衕袺裗袹袸裀袾袶袼袷袽袲褁裉覕覘覗觝觚觛詎詍訹詙詀詗詘詄詅詒詈詑詊詌詏豟貁貀貺貾貰貹貵趄趀趉跘跓跍跇跖跜跏跕跙跈跗跅軯軷軺"],["dc40","軹軦軮軥軵軧軨軶軫軱軬軴軩逭逴逯鄆鄬鄄郿郼鄈郹郻鄁鄀鄇鄅鄃酡酤酟酢酠鈁鈊鈥鈃鈚鈦鈏鈌鈀鈒釿釽鈆鈄鈧鈂鈜鈤鈙鈗鈅鈖镻閍閌閐隇陾隈"],["dca1","隉隃隀雂雈雃雱雰靬靰靮頇颩飫鳦黹亃亄亶傽傿僆傮僄僊傴僈僂傰僁傺傱僋僉傶傸凗剺剸剻剼嗃嗛嗌嗐嗋嗊嗝嗀嗔嗄嗩喿嗒喍嗏嗕嗢嗖嗈嗲嗍嗙嗂圔塓塨塤塏塍塉塯塕塎塝塙塥塛堽塣塱壼嫇嫄嫋媺媸媱媵媰媿嫈媻嫆"],["dd40","媷嫀嫊媴媶嫍媹媐寖寘寙尟尳嵱嵣嵊嵥嵲嵬嵞嵨嵧嵢巰幏幎幊幍幋廅廌廆廋廇彀徯徭惷慉慊愫慅愶愲愮慆愯慏愩慀戠酨戣戥戤揅揱揫搐搒搉搠搤"],["dda1","搳摃搟搕搘搹搷搢搣搌搦搰搨摁搵搯搊搚摀搥搧搋揧搛搮搡搎敯斒旓暆暌暕暐暋暊暙暔晸朠楦楟椸楎楢楱椿楅楪椹楂楗楙楺楈楉椵楬椳椽楥棰楸椴楩楀楯楄楶楘楁楴楌椻楋椷楜楏楑椲楒椯楻椼歆歅歃歂歈歁殛嗀毻毼"],["de40","毹毷毸溛滖滈溏滀溟溓溔溠溱溹滆滒溽滁溞滉溷溰滍溦滏溲溾滃滜滘溙溒溎溍溤溡溿溳滐滊溗溮溣煇煔煒煣煠煁煝煢煲煸煪煡煂煘煃煋煰煟煐煓"],["dea1","煄煍煚牏犍犌犑犐犎猼獂猻猺獀獊獉瑄瑊瑋瑒瑑瑗瑀瑏瑐瑎瑂瑆瑍瑔瓡瓿瓾瓽甝畹畷榃痯瘏瘃痷痾痼痹痸瘐痻痶痭痵痽皙皵盝睕睟睠睒睖睚睩睧睔睙睭矠碇碚碔碏碄碕碅碆碡碃硹碙碀碖硻祼禂祽祹稑稘稙稒稗稕稢稓"],["df40","稛稐窣窢窞竫筦筤筭筴筩筲筥筳筱筰筡筸筶筣粲粴粯綈綆綀綍絿綅絺綎絻綃絼綌綔綄絽綒罭罫罧罨罬羦羥羧翛翜耡腤腠腷腜腩腛腢腲朡腞腶腧腯"],["dfa1","腄腡舝艉艄艀艂艅蓱萿葖葶葹蒏蒍葥葑葀蒆葧萰葍葽葚葙葴葳葝蔇葞萷萺萴葺葃葸萲葅萩菙葋萯葂萭葟葰萹葎葌葒葯蓅蒎萻葇萶萳葨葾葄萫葠葔葮葐蜋蜄蛷蜌蛺蛖蛵蝍蛸蜎蜉蜁蛶蜍蜅裖裋裍裎裞裛裚裌裐覅覛觟觥觤"],["e040","觡觠觢觜触詶誆詿詡訿詷誂誄詵誃誁詴詺谼豋豊豥豤豦貆貄貅賌赨赩趑趌趎趏趍趓趔趐趒跰跠跬跱跮跐跩跣跢跧跲跫跴輆軿輁輀輅輇輈輂輋遒逿"],["e0a1","遄遉逽鄐鄍鄏鄑鄖鄔鄋鄎酮酯鉈鉒鈰鈺鉦鈳鉥鉞銃鈮鉊鉆鉭鉬鉏鉠鉧鉯鈶鉡鉰鈱鉔鉣鉐鉲鉎鉓鉌鉖鈲閟閜閞閛隒隓隑隗雎雺雽雸雵靳靷靸靲頏頍頎颬飶飹馯馲馰馵骭骫魛鳪鳭鳧麀黽僦僔僗僨僳僛僪僝僤僓僬僰僯僣僠"],["e140","凘劀劁勩勫匰厬嘧嘕嘌嘒嗼嘏嘜嘁嘓嘂嗺嘝嘄嗿嗹墉塼墐墘墆墁塿塴墋塺墇墑墎塶墂墈塻墔墏壾奫嫜嫮嫥嫕嫪嫚嫭嫫嫳嫢嫠嫛嫬嫞嫝嫙嫨嫟孷寠"],["e1a1","寣屣嶂嶀嵽嶆嵺嶁嵷嶊嶉嶈嵾嵼嶍嵹嵿幘幙幓廘廑廗廎廜廕廙廒廔彄彃彯徶愬愨慁慞慱慳慒慓慲慬憀慴慔慺慛慥愻慪慡慖戩戧戫搫摍摛摝摴摶摲摳摽摵摦撦摎撂摞摜摋摓摠摐摿搿摬摫摙摥摷敳斠暡暠暟朅朄朢榱榶槉"],["e240","榠槎榖榰榬榼榑榙榎榧榍榩榾榯榿槄榽榤槔榹槊榚槏榳榓榪榡榞槙榗榐槂榵榥槆歊歍歋殞殟殠毃毄毾滎滵滱漃漥滸漷滻漮漉潎漙漚漧漘漻漒滭漊"],["e2a1","漶潳滹滮漭潀漰漼漵滫漇漎潃漅滽滶漹漜滼漺漟漍漞漈漡熇熐熉熀熅熂熏煻熆熁熗牄牓犗犕犓獃獍獑獌瑢瑳瑱瑵瑲瑧瑮甀甂甃畽疐瘖瘈瘌瘕瘑瘊瘔皸瞁睼瞅瞂睮瞀睯睾瞃碲碪碴碭碨硾碫碞碥碠碬碢碤禘禊禋禖禕禔禓"],["e340","禗禈禒禐稫穊稰稯稨稦窨窫窬竮箈箜箊箑箐箖箍箌箛箎箅箘劄箙箤箂粻粿粼粺綧綷緂綣綪緁緀緅綝緎緄緆緋緌綯綹綖綼綟綦綮綩綡緉罳翢翣翥翞"],["e3a1","耤聝聜膉膆膃膇膍膌膋舕蒗蒤蒡蒟蒺蓎蓂蒬蒮蒫蒹蒴蓁蓍蒪蒚蒱蓐蒝蒧蒻蒢蒔蓇蓌蒛蒩蒯蒨蓖蒘蒶蓏蒠蓗蓔蓒蓛蒰蒑虡蜳蜣蜨蝫蝀蜮蜞蜡蜙蜛蝃蜬蝁蜾蝆蜠蜲蜪蜭蜼蜒蜺蜱蜵蝂蜦蜧蜸蜤蜚蜰蜑裷裧裱裲裺裾裮裼裶裻"],["e440","裰裬裫覝覡覟覞觩觫觨誫誙誋誒誏誖谽豨豩賕賏賗趖踉踂跿踍跽踊踃踇踆踅跾踀踄輐輑輎輍鄣鄜鄠鄢鄟鄝鄚鄤鄡鄛酺酲酹酳銥銤鉶銛鉺銠銔銪銍"],["e4a1","銦銚銫鉹銗鉿銣鋮銎銂銕銢鉽銈銡銊銆銌銙銧鉾銇銩銝銋鈭隞隡雿靘靽靺靾鞃鞀鞂靻鞄鞁靿韎韍頖颭颮餂餀餇馝馜駃馹馻馺駂馽駇骱髣髧鬾鬿魠魡魟鳱鳲鳵麧僿儃儰僸儆儇僶僾儋儌僽儊劋劌勱勯噈噂噌嘵噁噊噉噆噘"],["e540","噚噀嘳嘽嘬嘾嘸嘪嘺圚墫墝墱墠墣墯墬墥墡壿嫿嫴嫽嫷嫶嬃嫸嬂嫹嬁嬇嬅嬏屧嶙嶗嶟嶒嶢嶓嶕嶠嶜嶡嶚嶞幩幝幠幜緳廛廞廡彉徲憋憃慹憱憰憢憉"],["e5a1","憛憓憯憭憟憒憪憡憍慦憳戭摮摰撖撠撅撗撜撏撋撊撌撣撟摨撱撘敶敺敹敻斲斳暵暰暩暲暷暪暯樀樆樗槥槸樕槱槤樠槿槬槢樛樝槾樧槲槮樔槷槧橀樈槦槻樍槼槫樉樄樘樥樏槶樦樇槴樖歑殥殣殢殦氁氀毿氂潁漦潾澇濆澒"],["e640","澍澉澌潢潏澅潚澖潶潬澂潕潲潒潐潗澔澓潝漀潡潫潽潧澐潓澋潩潿澕潣潷潪潻熲熯熛熰熠熚熩熵熝熥熞熤熡熪熜熧熳犘犚獘獒獞獟獠獝獛獡獚獙"],["e6a1","獢璇璉璊璆璁瑽璅璈瑼瑹甈甇畾瘥瘞瘙瘝瘜瘣瘚瘨瘛皜皝皞皛瞍瞏瞉瞈磍碻磏磌磑磎磔磈磃磄磉禚禡禠禜禢禛歶稹窲窴窳箷篋箾箬篎箯箹篊箵糅糈糌糋緷緛緪緧緗緡縃緺緦緶緱緰緮緟罶羬羰羭翭翫翪翬翦翨聤聧膣膟"],["e740","膞膕膢膙膗舖艏艓艒艐艎艑蔤蔻蔏蔀蔩蔎蔉蔍蔟蔊蔧蔜蓻蔫蓺蔈蔌蓴蔪蓲蔕蓷蓫蓳蓼蔒蓪蓩蔖蓾蔨蔝蔮蔂蓽蔞蓶蔱蔦蓧蓨蓰蓯蓹蔘蔠蔰蔋蔙蔯虢"],["e7a1","蝖蝣蝤蝷蟡蝳蝘蝔蝛蝒蝡蝚蝑蝞蝭蝪蝐蝎蝟蝝蝯蝬蝺蝮蝜蝥蝏蝻蝵蝢蝧蝩衚褅褌褔褋褗褘褙褆褖褑褎褉覢覤覣觭觰觬諏諆誸諓諑諔諕誻諗誾諀諅諘諃誺誽諙谾豍貏賥賟賙賨賚賝賧趠趜趡趛踠踣踥踤踮踕踛踖踑踙踦踧"],["e840","踔踒踘踓踜踗踚輬輤輘輚輠輣輖輗遳遰遯遧遫鄯鄫鄩鄪鄲鄦鄮醅醆醊醁醂醄醀鋐鋃鋄鋀鋙銶鋏鋱鋟鋘鋩鋗鋝鋌鋯鋂鋨鋊鋈鋎鋦鋍鋕鋉鋠鋞鋧鋑鋓"],["e8a1","銵鋡鋆銴镼閬閫閮閰隤隢雓霅霈霂靚鞊鞎鞈韐韏頞頝頦頩頨頠頛頧颲餈飺餑餔餖餗餕駜駍駏駓駔駎駉駖駘駋駗駌骳髬髫髳髲髱魆魃魧魴魱魦魶魵魰魨魤魬鳼鳺鳽鳿鳷鴇鴀鳹鳻鴈鴅鴄麃黓鼏鼐儜儓儗儚儑凞匴叡噰噠噮"],["e940","噳噦噣噭噲噞噷圜圛壈墽壉墿墺壂墼壆嬗嬙嬛嬡嬔嬓嬐嬖嬨嬚嬠嬞寯嶬嶱嶩嶧嶵嶰嶮嶪嶨嶲嶭嶯嶴幧幨幦幯廩廧廦廨廥彋徼憝憨憖懅憴懆懁懌憺"],["e9a1","憿憸憌擗擖擐擏擉撽撉擃擛擳擙攳敿敼斢曈暾曀曊曋曏暽暻暺曌朣樴橦橉橧樲橨樾橝橭橶橛橑樨橚樻樿橁橪橤橐橏橔橯橩橠樼橞橖橕橍橎橆歕歔歖殧殪殫毈毇氄氃氆澭濋澣濇澼濎濈潞濄澽澞濊澨瀄澥澮澺澬澪濏澿澸"],["ea40","澢濉澫濍澯澲澰燅燂熿熸燖燀燁燋燔燊燇燏熽燘熼燆燚燛犝犞獩獦獧獬獥獫獪瑿璚璠璔璒璕璡甋疀瘯瘭瘱瘽瘳瘼瘵瘲瘰皻盦瞚瞝瞡瞜瞛瞢瞣瞕瞙"],["eaa1","瞗磝磩磥磪磞磣磛磡磢磭磟磠禤穄穈穇窶窸窵窱窷篞篣篧篝篕篥篚篨篹篔篪篢篜篫篘篟糒糔糗糐糑縒縡縗縌縟縠縓縎縜縕縚縢縋縏縖縍縔縥縤罃罻罼罺羱翯耪耩聬膱膦膮膹膵膫膰膬膴膲膷膧臲艕艖艗蕖蕅蕫蕍蕓蕡蕘"],["eb40","蕀蕆蕤蕁蕢蕄蕑蕇蕣蔾蕛蕱蕎蕮蕵蕕蕧蕠薌蕦蕝蕔蕥蕬虣虥虤螛螏螗螓螒螈螁螖螘蝹螇螣螅螐螑螝螄螔螜螚螉褞褦褰褭褮褧褱褢褩褣褯褬褟觱諠"],["eba1","諢諲諴諵諝謔諤諟諰諈諞諡諨諿諯諻貑貒貐賵賮賱賰賳赬赮趥趧踳踾踸蹀蹅踶踼踽蹁踰踿躽輶輮輵輲輹輷輴遶遹遻邆郺鄳鄵鄶醓醐醑醍醏錧錞錈錟錆錏鍺錸錼錛錣錒錁鍆錭錎錍鋋錝鋺錥錓鋹鋷錴錂錤鋿錩錹錵錪錔錌"],["ec40","錋鋾錉錀鋻錖閼闍閾閹閺閶閿閵閽隩雔霋霒霐鞙鞗鞔韰韸頵頯頲餤餟餧餩馞駮駬駥駤駰駣駪駩駧骹骿骴骻髶髺髹髷鬳鮀鮅鮇魼魾魻鮂鮓鮒鮐魺鮕"],["eca1","魽鮈鴥鴗鴠鴞鴔鴩鴝鴘鴢鴐鴙鴟麈麆麇麮麭黕黖黺鼒鼽儦儥儢儤儠儩勴嚓嚌嚍嚆嚄嚃噾嚂噿嚁壖壔壏壒嬭嬥嬲嬣嬬嬧嬦嬯嬮孻寱寲嶷幬幪徾徻懃憵憼懧懠懥懤懨懞擯擩擣擫擤擨斁斀斶旚曒檍檖檁檥檉檟檛檡檞檇檓檎"],["ed40","檕檃檨檤檑橿檦檚檅檌檒歛殭氉濌澩濴濔濣濜濭濧濦濞濲濝濢濨燡燱燨燲燤燰燢獳獮獯璗璲璫璐璪璭璱璥璯甐甑甒甏疄癃癈癉癇皤盩瞵瞫瞲瞷瞶"],["eda1","瞴瞱瞨矰磳磽礂磻磼磲礅磹磾礄禫禨穜穛穖穘穔穚窾竀竁簅簏篲簀篿篻簎篴簋篳簂簉簃簁篸篽簆篰篱簐簊糨縭縼繂縳顈縸縪繉繀繇縩繌縰縻縶繄縺罅罿罾罽翴翲耬膻臄臌臊臅臇膼臩艛艚艜薃薀薏薧薕薠薋薣蕻薤薚薞"],["ee40","蕷蕼薉薡蕺蕸蕗薎薖薆薍薙薝薁薢薂薈薅蕹蕶薘薐薟虨螾螪螭蟅螰螬螹螵螼螮蟉蟃蟂蟌螷螯蟄蟊螴螶螿螸螽蟞螲褵褳褼褾襁襒褷襂覭覯覮觲觳謞"],["eea1","謘謖謑謅謋謢謏謒謕謇謍謈謆謜謓謚豏豰豲豱豯貕貔賹赯蹎蹍蹓蹐蹌蹇轃轀邅遾鄸醚醢醛醙醟醡醝醠鎡鎃鎯鍤鍖鍇鍼鍘鍜鍶鍉鍐鍑鍠鍭鎏鍌鍪鍹鍗鍕鍒鍏鍱鍷鍻鍡鍞鍣鍧鎀鍎鍙闇闀闉闃闅閷隮隰隬霠霟霘霝霙鞚鞡鞜"],["ef40","鞞鞝韕韔韱顁顄顊顉顅顃餥餫餬餪餳餲餯餭餱餰馘馣馡騂駺駴駷駹駸駶駻駽駾駼騃骾髾髽鬁髼魈鮚鮨鮞鮛鮦鮡鮥鮤鮆鮢鮠鮯鴳鵁鵧鴶鴮鴯鴱鴸鴰"],["efa1","鵅鵂鵃鴾鴷鵀鴽翵鴭麊麉麍麰黈黚黻黿鼤鼣鼢齔龠儱儭儮嚘嚜嚗嚚嚝嚙奰嬼屩屪巀幭幮懘懟懭懮懱懪懰懫懖懩擿攄擽擸攁攃擼斔旛曚曛曘櫅檹檽櫡櫆檺檶檷櫇檴檭歞毉氋瀇瀌瀍瀁瀅瀔瀎濿瀀濻瀦濼濷瀊爁燿燹爃燽獶"],["f040","璸瓀璵瓁璾璶璻瓂甔甓癜癤癙癐癓癗癚皦皽盬矂瞺磿礌礓礔礉礐礒礑禭禬穟簜簩簙簠簟簭簝簦簨簢簥簰繜繐繖繣繘繢繟繑繠繗繓羵羳翷翸聵臑臒"],["f0a1","臐艟艞薴藆藀藃藂薳薵薽藇藄薿藋藎藈藅薱薶藒蘤薸薷薾虩蟧蟦蟢蟛蟫蟪蟥蟟蟳蟤蟔蟜蟓蟭蟘蟣螤蟗蟙蠁蟴蟨蟝襓襋襏襌襆襐襑襉謪謧謣謳謰謵譇謯謼謾謱謥謷謦謶謮謤謻謽謺豂豵貙貘貗賾贄贂贀蹜蹢蹠蹗蹖蹞蹥蹧"],["f140","蹛蹚蹡蹝蹩蹔轆轇轈轋鄨鄺鄻鄾醨醥醧醯醪鎵鎌鎒鎷鎛鎝鎉鎧鎎鎪鎞鎦鎕鎈鎙鎟鎍鎱鎑鎲鎤鎨鎴鎣鎥闒闓闑隳雗雚巂雟雘雝霣霢霥鞬鞮鞨鞫鞤鞪"],["f1a1","鞢鞥韗韙韖韘韺顐顑顒颸饁餼餺騏騋騉騍騄騑騊騅騇騆髀髜鬈鬄鬅鬩鬵魊魌魋鯇鯆鯃鮿鯁鮵鮸鯓鮶鯄鮹鮽鵜鵓鵏鵊鵛鵋鵙鵖鵌鵗鵒鵔鵟鵘鵚麎麌黟鼁鼀鼖鼥鼫鼪鼩鼨齌齕儴儵劖勷厴嚫嚭嚦嚧嚪嚬壚壝壛夒嬽嬾嬿巃幰"],["f240","徿懻攇攐攍攉攌攎斄旞旝曞櫧櫠櫌櫑櫙櫋櫟櫜櫐櫫櫏櫍櫞歠殰氌瀙瀧瀠瀖瀫瀡瀢瀣瀩瀗瀤瀜瀪爌爊爇爂爅犥犦犤犣犡瓋瓅璷瓃甖癠矉矊矄矱礝礛"],["f2a1","礡礜礗礞禰穧穨簳簼簹簬簻糬糪繶繵繸繰繷繯繺繲繴繨罋罊羃羆羷翽翾聸臗臕艤艡艣藫藱藭藙藡藨藚藗藬藲藸藘藟藣藜藑藰藦藯藞藢蠀蟺蠃蟶蟷蠉蠌蠋蠆蟼蠈蟿蠊蠂襢襚襛襗襡襜襘襝襙覈覷覶觶譐譈譊譀譓譖譔譋譕"],["f340","譑譂譒譗豃豷豶貚贆贇贉趬趪趭趫蹭蹸蹳蹪蹯蹻軂轒轑轏轐轓辴酀鄿醰醭鏞鏇鏏鏂鏚鏐鏹鏬鏌鏙鎩鏦鏊鏔鏮鏣鏕鏄鏎鏀鏒鏧镽闚闛雡霩霫霬霨霦"],["f3a1","鞳鞷鞶韝韞韟顜顙顝顗颿颽颻颾饈饇饃馦馧騚騕騥騝騤騛騢騠騧騣騞騜騔髂鬋鬊鬎鬌鬷鯪鯫鯠鯞鯤鯦鯢鯰鯔鯗鯬鯜鯙鯥鯕鯡鯚鵷鶁鶊鶄鶈鵱鶀鵸鶆鶋鶌鵽鵫鵴鵵鵰鵩鶅鵳鵻鶂鵯鵹鵿鶇鵨麔麑黀黼鼭齀齁齍齖齗齘匷嚲"],["f440","嚵嚳壣孅巆巇廮廯忀忁懹攗攖攕攓旟曨曣曤櫳櫰櫪櫨櫹櫱櫮櫯瀼瀵瀯瀷瀴瀱灂瀸瀿瀺瀹灀瀻瀳灁爓爔犨獽獼璺皫皪皾盭矌矎矏矍矲礥礣礧礨礤礩"],["f4a1","禲穮穬穭竷籉籈籊籇籅糮繻繾纁纀羺翿聹臛臙舋艨艩蘢藿蘁藾蘛蘀藶蘄蘉蘅蘌藽蠙蠐蠑蠗蠓蠖襣襦覹觷譠譪譝譨譣譥譧譭趮躆躈躄轙轖轗轕轘轚邍酃酁醷醵醲醳鐋鐓鏻鐠鐏鐔鏾鐕鐐鐨鐙鐍鏵鐀鏷鐇鐎鐖鐒鏺鐉鏸鐊鏿"],["f540","鏼鐌鏶鐑鐆闞闠闟霮霯鞹鞻韽韾顠顢顣顟飁飂饐饎饙饌饋饓騲騴騱騬騪騶騩騮騸騭髇髊髆鬐鬒鬑鰋鰈鯷鰅鰒鯸鱀鰇鰎鰆鰗鰔鰉鶟鶙鶤鶝鶒鶘鶐鶛"],["f5a1","鶠鶔鶜鶪鶗鶡鶚鶢鶨鶞鶣鶿鶩鶖鶦鶧麙麛麚黥黤黧黦鼰鼮齛齠齞齝齙龑儺儹劘劗囃嚽嚾孈孇巋巏廱懽攛欂櫼欃櫸欀灃灄灊灈灉灅灆爝爚爙獾甗癪矐礭礱礯籔籓糲纊纇纈纋纆纍罍羻耰臝蘘蘪蘦蘟蘣蘜蘙蘧蘮蘡蘠蘩蘞蘥"],["f640","蠩蠝蠛蠠蠤蠜蠫衊襭襩襮襫觺譹譸譅譺譻贐贔趯躎躌轞轛轝酆酄酅醹鐿鐻鐶鐩鐽鐼鐰鐹鐪鐷鐬鑀鐱闥闤闣霵霺鞿韡顤飉飆飀饘饖騹騽驆驄驂驁騺"],["f6a1","騿髍鬕鬗鬘鬖鬺魒鰫鰝鰜鰬鰣鰨鰩鰤鰡鶷鶶鶼鷁鷇鷊鷏鶾鷅鷃鶻鶵鷎鶹鶺鶬鷈鶱鶭鷌鶳鷍鶲鹺麜黫黮黭鼛鼘鼚鼱齎齥齤龒亹囆囅囋奱孋孌巕巑廲攡攠攦攢欋欈欉氍灕灖灗灒爞爟犩獿瓘瓕瓙瓗癭皭礵禴穰穱籗籜籙籛籚"],["f740","糴糱纑罏羇臞艫蘴蘵蘳蘬蘲蘶蠬蠨蠦蠪蠥襱覿覾觻譾讄讂讆讅譿贕躕躔躚躒躐躖躗轠轢酇鑌鑐鑊鑋鑏鑇鑅鑈鑉鑆霿韣顪顩飋饔饛驎驓驔驌驏驈驊"],["f7a1","驉驒驐髐鬙鬫鬻魖魕鱆鱈鰿鱄鰹鰳鱁鰼鰷鰴鰲鰽鰶鷛鷒鷞鷚鷋鷐鷜鷑鷟鷩鷙鷘鷖鷵鷕鷝麶黰鼵鼳鼲齂齫龕龢儽劙壨壧奲孍巘蠯彏戁戃戄攩攥斖曫欑欒欏毊灛灚爢玂玁玃癰矔籧籦纕艬蘺虀蘹蘼蘱蘻蘾蠰蠲蠮蠳襶襴襳觾"],["f840","讌讎讋讈豅贙躘轤轣醼鑢鑕鑝鑗鑞韄韅頀驖驙鬞鬟鬠鱒鱘鱐鱊鱍鱋鱕鱙鱌鱎鷻鷷鷯鷣鷫鷸鷤鷶鷡鷮鷦鷲鷰鷢鷬鷴鷳鷨鷭黂黐黲黳鼆鼜鼸鼷鼶齃齏"],["f8a1","齱齰齮齯囓囍孎屭攭曭曮欓灟灡灝灠爣瓛瓥矕礸禷禶籪纗羉艭虃蠸蠷蠵衋讔讕躞躟躠躝醾醽釂鑫鑨鑩雥靆靃靇韇韥驞髕魙鱣鱧鱦鱢鱞鱠鸂鷾鸇鸃鸆鸅鸀鸁鸉鷿鷽鸄麠鼞齆齴齵齶囔攮斸欘欙欗欚灢爦犪矘矙礹籩籫糶纚"],["f940","纘纛纙臠臡虆虇虈襹襺襼襻觿讘讙躥躤躣鑮鑭鑯鑱鑳靉顲饟鱨鱮鱭鸋鸍鸐鸏鸒鸑麡黵鼉齇齸齻齺齹圞灦籯蠼趲躦釃鑴鑸鑶鑵驠鱴鱳鱱鱵鸔鸓黶鼊"],["f9a1","龤灨灥糷虪蠾蠽蠿讞貜躩軉靋顳顴飌饡馫驤驦驧鬤鸕鸗齈戇欞爧虌躨钂钀钁驩驨鬮鸙爩虋讟钃鱹麷癵驫鱺鸝灩灪麤齾齉龘碁銹裏墻恒粧嫺╔╦╗╠╬╣╚╩╝╒╤╕╞╪╡╘╧╛╓╥╖╟╫╢╙╨╜║═╭╮╰╯▓"]]'); + +/***/ }), + +/***/ 3078: +/***/ ((module) => { + +module.exports = JSON.parse('[["0","\\u0000",127],["8ea1","。",62],["a1a1"," 、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈",9,"+-±×÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇"],["a2a1","◆□■△▲▽▼※〒→←↑↓〓"],["a2ba","∈∋⊆⊇⊂⊃∪∩"],["a2ca","∧∨¬⇒⇔∀∃"],["a2dc","∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬"],["a2f2","ʼn♯♭♪†‡¶"],["a2fe","◯"],["a3b0","0",9],["a3c1","A",25],["a3e1","a",25],["a4a1","ぁ",82],["a5a1","ァ",85],["a6a1","Α",16,"Σ",6],["a6c1","α",16,"σ",6],["a7a1","А",5,"ЁЖ",25],["a7d1","а",5,"ёж",25],["a8a1","─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂"],["ada1","①",19,"Ⅰ",9],["adc0","㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡"],["addf","㍻〝〟№㏍℡㊤",4,"㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪"],["b0a1","亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭"],["b1a1","院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応"],["b2a1","押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改"],["b3a1","魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱"],["b4a1","粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄"],["b5a1","機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京"],["b6a1","供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈"],["b7a1","掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲"],["b8a1","検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向"],["b9a1","后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込"],["baa1","此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷"],["bba1","察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時"],["bca1","次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周"],["bda1","宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償"],["bea1","勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾"],["bfa1","拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾"],["c0a1","澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線"],["c1a1","繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎"],["c2a1","臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只"],["c3a1","叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵"],["c4a1","帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓"],["c5a1","邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到"],["c6a1","董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入"],["c7a1","如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦"],["c8a1","函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美"],["c9a1","鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服"],["caa1","福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋"],["cba1","法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満"],["cca1","漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒"],["cda1","諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃"],["cea1","痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯"],["cfa1","蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕"],["d0a1","弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲"],["d1a1","僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨"],["d2a1","辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨"],["d3a1","咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉"],["d4a1","圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩"],["d5a1","奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓"],["d6a1","屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏"],["d7a1","廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚"],["d8a1","悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛"],["d9a1","戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼"],["daa1","據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼"],["dba1","曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍"],["dca1","棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣"],["dda1","檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾"],["dea1","沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌"],["dfa1","漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼"],["e0a1","燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱"],["e1a1","瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰"],["e2a1","癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬"],["e3a1","磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐"],["e4a1","筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆"],["e5a1","紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺"],["e6a1","罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋"],["e7a1","隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙"],["e8a1","茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈"],["e9a1","蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙"],["eaa1","蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞"],["eba1","襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫"],["eca1","譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊"],["eda1","蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸"],["eea1","遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮"],["efa1","錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞"],["f0a1","陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰"],["f1a1","顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷"],["f2a1","髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈"],["f3a1","鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠"],["f4a1","堯槇遙瑤凜熙"],["f9a1","纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德"],["faa1","忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱"],["fba1","犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚"],["fca1","釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"],["fcf1","ⅰ",9,"¬¦'""],["8fa2af","˘ˇ¸˙˝¯˛˚~΄΅"],["8fa2c2","¡¦¿"],["8fa2eb","ºª©®™¤№"],["8fa6e1","ΆΈΉΊΪ"],["8fa6e7","Ό"],["8fa6e9","ΎΫ"],["8fa6ec","Ώ"],["8fa6f1","άέήίϊΐόςύϋΰώ"],["8fa7c2","Ђ",10,"ЎЏ"],["8fa7f2","ђ",10,"ўџ"],["8fa9a1","ÆĐ"],["8fa9a4","Ħ"],["8fa9a6","IJ"],["8fa9a8","ŁĿ"],["8fa9ab","ŊØŒ"],["8fa9af","ŦÞ"],["8fa9c1","æđðħıijĸłŀʼnŋøœßŧþ"],["8faaa1","ÁÀÄÂĂǍĀĄÅÃĆĈČÇĊĎÉÈËÊĚĖĒĘ"],["8faaba","ĜĞĢĠĤÍÌÏÎǏİĪĮĨĴĶĹĽĻŃŇŅÑÓÒÖÔǑŐŌÕŔŘŖŚŜŠŞŤŢÚÙÜÛŬǓŰŪŲŮŨǗǛǙǕŴÝŸŶŹŽŻ"],["8faba1","áàäâăǎāąåãćĉčçċďéèëêěėēęǵĝğ"],["8fabbd","ġĥíìïîǐ"],["8fabc5","īįĩĵķĺľļńňņñóòöôǒőōõŕřŗśŝšşťţúùüûŭǔűūųůũǘǜǚǖŵýÿŷźžż"],["8fb0a1","丂丄丅丌丒丟丣两丨丫丮丯丰丵乀乁乄乇乑乚乜乣乨乩乴乵乹乿亍亖亗亝亯亹仃仐仚仛仠仡仢仨仯仱仳仵份仾仿伀伂伃伈伋伌伒伕伖众伙伮伱你伳伵伷伹伻伾佀佂佈佉佋佌佒佔佖佘佟佣佪佬佮佱佷佸佹佺佽佾侁侂侄"],["8fb1a1","侅侉侊侌侎侐侒侓侔侗侙侚侞侟侲侷侹侻侼侽侾俀俁俅俆俈俉俋俌俍俏俒俜俠俢俰俲俼俽俿倀倁倄倇倊倌倎倐倓倗倘倛倜倝倞倢倧倮倰倲倳倵偀偁偂偅偆偊偌偎偑偒偓偗偙偟偠偢偣偦偧偪偭偰偱倻傁傃傄傆傊傎傏傐"],["8fb2a1","傒傓傔傖傛傜傞",4,"傪傯傰傹傺傽僀僃僄僇僌僎僐僓僔僘僜僝僟僢僤僦僨僩僯僱僶僺僾儃儆儇儈儋儌儍儎僲儐儗儙儛儜儝儞儣儧儨儬儭儯儱儳儴儵儸儹兂兊兏兓兕兗兘兟兤兦兾冃冄冋冎冘冝冡冣冭冸冺冼冾冿凂"],["8fb3a1","凈减凑凒凓凕凘凞凢凥凮凲凳凴凷刁刂刅划刓刕刖刘刢刨刱刲刵刼剅剉剕剗剘剚剜剟剠剡剦剮剷剸剹劀劂劅劊劌劓劕劖劗劘劚劜劤劥劦劧劯劰劶劷劸劺劻劽勀勄勆勈勌勏勑勔勖勛勜勡勥勨勩勪勬勰勱勴勶勷匀匃匊匋"],["8fb4a1","匌匑匓匘匛匜匞匟匥匧匨匩匫匬匭匰匲匵匼匽匾卂卌卋卙卛卡卣卥卬卭卲卹卾厃厇厈厎厓厔厙厝厡厤厪厫厯厲厴厵厷厸厺厽叀叅叏叒叓叕叚叝叞叠另叧叵吂吓吚吡吧吨吪启吱吴吵呃呄呇呍呏呞呢呤呦呧呩呫呭呮呴呿"],["8fb5a1","咁咃咅咈咉咍咑咕咖咜咟咡咦咧咩咪咭咮咱咷咹咺咻咿哆哊响哎哠哪哬哯哶哼哾哿唀唁唅唈唉唌唍唎唕唪唫唲唵唶唻唼唽啁啇啉啊啍啐啑啘啚啛啞啠啡啤啦啿喁喂喆喈喎喏喑喒喓喔喗喣喤喭喲喿嗁嗃嗆嗉嗋嗌嗎嗑嗒"],["8fb6a1","嗓嗗嗘嗛嗞嗢嗩嗶嗿嘅嘈嘊嘍",5,"嘙嘬嘰嘳嘵嘷嘹嘻嘼嘽嘿噀噁噃噄噆噉噋噍噏噔噞噠噡噢噣噦噩噭噯噱噲噵嚄嚅嚈嚋嚌嚕嚙嚚嚝嚞嚟嚦嚧嚨嚩嚫嚬嚭嚱嚳嚷嚾囅囉囊囋囏囐囌囍囙囜囝囟囡囤",4,"囱囫园"],["8fb7a1","囶囷圁圂圇圊圌圑圕圚圛圝圠圢圣圤圥圩圪圬圮圯圳圴圽圾圿坅坆坌坍坒坢坥坧坨坫坭",4,"坳坴坵坷坹坺坻坼坾垁垃垌垔垗垙垚垜垝垞垟垡垕垧垨垩垬垸垽埇埈埌埏埕埝埞埤埦埧埩埭埰埵埶埸埽埾埿堃堄堈堉埡"],["8fb8a1","堌堍堛堞堟堠堦堧堭堲堹堿塉塌塍塏塐塕塟塡塤塧塨塸塼塿墀墁墇墈墉墊墌墍墏墐墔墖墝墠墡墢墦墩墱墲壄墼壂壈壍壎壐壒壔壖壚壝壡壢壩壳夅夆夋夌夒夓夔虁夝夡夣夤夨夯夰夳夵夶夿奃奆奒奓奙奛奝奞奟奡奣奫奭"],["8fb9a1","奯奲奵奶她奻奼妋妌妎妒妕妗妟妤妧妭妮妯妰妳妷妺妼姁姃姄姈姊姍姒姝姞姟姣姤姧姮姯姱姲姴姷娀娄娌娍娎娒娓娞娣娤娧娨娪娭娰婄婅婇婈婌婐婕婞婣婥婧婭婷婺婻婾媋媐媓媖媙媜媞媟媠媢媧媬媱媲媳媵媸媺媻媿"],["8fbaa1","嫄嫆嫈嫏嫚嫜嫠嫥嫪嫮嫵嫶嫽嬀嬁嬈嬗嬴嬙嬛嬝嬡嬥嬭嬸孁孋孌孒孖孞孨孮孯孼孽孾孿宁宄宆宊宎宐宑宓宔宖宨宩宬宭宯宱宲宷宺宼寀寁寍寏寖",4,"寠寯寱寴寽尌尗尞尟尣尦尩尫尬尮尰尲尵尶屙屚屜屢屣屧屨屩"],["8fbba1","屭屰屴屵屺屻屼屽岇岈岊岏岒岝岟岠岢岣岦岪岲岴岵岺峉峋峒峝峗峮峱峲峴崁崆崍崒崫崣崤崦崧崱崴崹崽崿嵂嵃嵆嵈嵕嵑嵙嵊嵟嵠嵡嵢嵤嵪嵭嵰嵹嵺嵾嵿嶁嶃嶈嶊嶒嶓嶔嶕嶙嶛嶟嶠嶧嶫嶰嶴嶸嶹巃巇巋巐巎巘巙巠巤"],["8fbca1","巩巸巹帀帇帍帒帔帕帘帟帠帮帨帲帵帾幋幐幉幑幖幘幛幜幞幨幪",4,"幰庀庋庎庢庤庥庨庪庬庱庳庽庾庿廆廌廋廎廑廒廔廕廜廞廥廫异弆弇弈弎弙弜弝弡弢弣弤弨弫弬弮弰弴弶弻弽弿彀彄彅彇彍彐彔彘彛彠彣彤彧"],["8fbda1","彯彲彴彵彸彺彽彾徉徍徏徖徜徝徢徧徫徤徬徯徰徱徸忄忇忈忉忋忐",4,"忞忡忢忨忩忪忬忭忮忯忲忳忶忺忼怇怊怍怓怔怗怘怚怟怤怭怳怵恀恇恈恉恌恑恔恖恗恝恡恧恱恾恿悂悆悈悊悎悑悓悕悘悝悞悢悤悥您悰悱悷"],["8fbea1","悻悾惂惄惈惉惊惋惎惏惔惕惙惛惝惞惢惥惲惵惸惼惽愂愇愊愌愐",4,"愖愗愙愜愞愢愪愫愰愱愵愶愷愹慁慅慆慉慞慠慬慲慸慻慼慿憀憁憃憄憋憍憒憓憗憘憜憝憟憠憥憨憪憭憸憹憼懀懁懂懎懏懕懜懝懞懟懡懢懧懩懥"],["8fbfa1","懬懭懯戁戃戄戇戓戕戜戠戢戣戧戩戫戹戽扂扃扄扆扌扐扑扒扔扖扚扜扤扭扯扳扺扽抍抎抏抐抦抨抳抶抷抺抾抿拄拎拕拖拚拪拲拴拼拽挃挄挊挋挍挐挓挖挘挩挪挭挵挶挹挼捁捂捃捄捆捊捋捎捒捓捔捘捛捥捦捬捭捱捴捵"],["8fc0a1","捸捼捽捿掂掄掇掊掐掔掕掙掚掞掤掦掭掮掯掽揁揅揈揎揑揓揔揕揜揠揥揪揬揲揳揵揸揹搉搊搐搒搔搘搞搠搢搤搥搩搪搯搰搵搽搿摋摏摑摒摓摔摚摛摜摝摟摠摡摣摭摳摴摻摽撅撇撏撐撑撘撙撛撝撟撡撣撦撨撬撳撽撾撿"],["8fc1a1","擄擉擊擋擌擎擐擑擕擗擤擥擩擪擭擰擵擷擻擿攁攄攈攉攊攏攓攔攖攙攛攞攟攢攦攩攮攱攺攼攽敃敇敉敐敒敔敟敠敧敫敺敽斁斅斊斒斕斘斝斠斣斦斮斲斳斴斿旂旈旉旎旐旔旖旘旟旰旲旴旵旹旾旿昀昄昈昉昍昑昒昕昖昝"],["8fc2a1","昞昡昢昣昤昦昩昪昫昬昮昰昱昳昹昷晀晅晆晊晌晑晎晗晘晙晛晜晠晡曻晪晫晬晾晳晵晿晷晸晹晻暀晼暋暌暍暐暒暙暚暛暜暟暠暤暭暱暲暵暻暿曀曂曃曈曌曎曏曔曛曟曨曫曬曮曺朅朇朎朓朙朜朠朢朳朾杅杇杈杌杔杕杝"],["8fc3a1","杦杬杮杴杶杻极构枎枏枑枓枖枘枙枛枰枱枲枵枻枼枽柹柀柂柃柅柈柉柒柗柙柜柡柦柰柲柶柷桒栔栙栝栟栨栧栬栭栯栰栱栳栻栿桄桅桊桌桕桗桘桛桫桮",4,"桵桹桺桻桼梂梄梆梈梖梘梚梜梡梣梥梩梪梮梲梻棅棈棌棏"],["8fc4a1","棐棑棓棖棙棜棝棥棨棪棫棬棭棰棱棵棶棻棼棽椆椉椊椐椑椓椖椗椱椳椵椸椻楂楅楉楎楗楛楣楤楥楦楨楩楬楰楱楲楺楻楿榀榍榒榖榘榡榥榦榨榫榭榯榷榸榺榼槅槈槑槖槗槢槥槮槯槱槳槵槾樀樁樃樏樑樕樚樝樠樤樨樰樲"],["8fc5a1","樴樷樻樾樿橅橆橉橊橎橐橑橒橕橖橛橤橧橪橱橳橾檁檃檆檇檉檋檑檛檝檞檟檥檫檯檰檱檴檽檾檿櫆櫉櫈櫌櫐櫔櫕櫖櫜櫝櫤櫧櫬櫰櫱櫲櫼櫽欂欃欆欇欉欏欐欑欗欛欞欤欨欫欬欯欵欶欻欿歆歊歍歒歖歘歝歠歧歫歮歰歵歽"],["8fc6a1","歾殂殅殗殛殟殠殢殣殨殩殬殭殮殰殸殹殽殾毃毄毉毌毖毚毡毣毦毧毮毱毷毹毿氂氄氅氉氍氎氐氒氙氟氦氧氨氬氮氳氵氶氺氻氿汊汋汍汏汒汔汙汛汜汫汭汯汴汶汸汹汻沅沆沇沉沔沕沗沘沜沟沰沲沴泂泆泍泏泐泑泒泔泖"],["8fc7a1","泚泜泠泧泩泫泬泮泲泴洄洇洊洎洏洑洓洚洦洧洨汧洮洯洱洹洼洿浗浞浟浡浥浧浯浰浼涂涇涑涒涔涖涗涘涪涬涴涷涹涽涿淄淈淊淎淏淖淛淝淟淠淢淥淩淯淰淴淶淼渀渄渞渢渧渲渶渹渻渼湄湅湈湉湋湏湑湒湓湔湗湜湝湞"],["8fc8a1","湢湣湨湳湻湽溍溓溙溠溧溭溮溱溳溻溿滀滁滃滇滈滊滍滎滏滫滭滮滹滻滽漄漈漊漌漍漖漘漚漛漦漩漪漯漰漳漶漻漼漭潏潑潒潓潗潙潚潝潞潡潢潨潬潽潾澃澇澈澋澌澍澐澒澓澔澖澚澟澠澥澦澧澨澮澯澰澵澶澼濅濇濈濊"],["8fc9a1","濚濞濨濩濰濵濹濼濽瀀瀅瀆瀇瀍瀗瀠瀣瀯瀴瀷瀹瀼灃灄灈灉灊灋灔灕灝灞灎灤灥灬灮灵灶灾炁炅炆炔",4,"炛炤炫炰炱炴炷烊烑烓烔烕烖烘烜烤烺焃",4,"焋焌焏焞焠焫焭焯焰焱焸煁煅煆煇煊煋煐煒煗煚煜煞煠"],["8fcaa1","煨煹熀熅熇熌熒熚熛熠熢熯熰熲熳熺熿燀燁燄燋燌燓燖燙燚燜燸燾爀爇爈爉爓爗爚爝爟爤爫爯爴爸爹牁牂牃牅牎牏牐牓牕牖牚牜牞牠牣牨牫牮牯牱牷牸牻牼牿犄犉犍犎犓犛犨犭犮犱犴犾狁狇狉狌狕狖狘狟狥狳狴狺狻"],["8fcba1","狾猂猄猅猇猋猍猒猓猘猙猞猢猤猧猨猬猱猲猵猺猻猽獃獍獐獒獖獘獝獞獟獠獦獧獩獫獬獮獯獱獷獹獼玀玁玃玅玆玎玐玓玕玗玘玜玞玟玠玢玥玦玪玫玭玵玷玹玼玽玿珅珆珉珋珌珏珒珓珖珙珝珡珣珦珧珩珴珵珷珹珺珻珽"],["8fcca1","珿琀琁琄琇琊琑琚琛琤琦琨",9,"琹瑀瑃瑄瑆瑇瑋瑍瑑瑒瑗瑝瑢瑦瑧瑨瑫瑭瑮瑱瑲璀璁璅璆璇璉璏璐璑璒璘璙璚璜璟璠璡璣璦璨璩璪璫璮璯璱璲璵璹璻璿瓈瓉瓌瓐瓓瓘瓚瓛瓞瓟瓤瓨瓪瓫瓯瓴瓺瓻瓼瓿甆"],["8fcda1","甒甖甗甠甡甤甧甩甪甯甶甹甽甾甿畀畃畇畈畎畐畒畗畞畟畡畯畱畹",5,"疁疅疐疒疓疕疙疜疢疤疴疺疿痀痁痄痆痌痎痏痗痜痟痠痡痤痧痬痮痯痱痹瘀瘂瘃瘄瘇瘈瘊瘌瘏瘒瘓瘕瘖瘙瘛瘜瘝瘞瘣瘥瘦瘩瘭瘲瘳瘵瘸瘹"],["8fcea1","瘺瘼癊癀癁癃癄癅癉癋癕癙癟癤癥癭癮癯癱癴皁皅皌皍皕皛皜皝皟皠皢",6,"皪皭皽盁盅盉盋盌盎盔盙盠盦盨盬盰盱盶盹盼眀眆眊眎眒眔眕眗眙眚眜眢眨眭眮眯眴眵眶眹眽眾睂睅睆睊睍睎睏睒睖睗睜睞睟睠睢"],["8fcfa1","睤睧睪睬睰睲睳睴睺睽瞀瞄瞌瞍瞔瞕瞖瞚瞟瞢瞧瞪瞮瞯瞱瞵瞾矃矉矑矒矕矙矞矟矠矤矦矪矬矰矱矴矸矻砅砆砉砍砎砑砝砡砢砣砭砮砰砵砷硃硄硇硈硌硎硒硜硞硠硡硣硤硨硪确硺硾碊碏碔碘碡碝碞碟碤碨碬碭碰碱碲碳"],["8fd0a1","碻碽碿磇磈磉磌磎磒磓磕磖磤磛磟磠磡磦磪磲磳礀磶磷磺磻磿礆礌礐礚礜礞礟礠礥礧礩礭礱礴礵礻礽礿祄祅祆祊祋祏祑祔祘祛祜祧祩祫祲祹祻祼祾禋禌禑禓禔禕禖禘禛禜禡禨禩禫禯禱禴禸离秂秄秇秈秊秏秔秖秚秝秞"],["8fd1a1","秠秢秥秪秫秭秱秸秼稂稃稇稉稊稌稑稕稛稞稡稧稫稭稯稰稴稵稸稹稺穄穅穇穈穌穕穖穙穜穝穟穠穥穧穪穭穵穸穾窀窂窅窆窊窋窐窑窔窞窠窣窬窳窵窹窻窼竆竉竌竎竑竛竨竩竫竬竱竴竻竽竾笇笔笟笣笧笩笪笫笭笮笯笰"],["8fd2a1","笱笴笽笿筀筁筇筎筕筠筤筦筩筪筭筯筲筳筷箄箉箎箐箑箖箛箞箠箥箬箯箰箲箵箶箺箻箼箽篂篅篈篊篔篖篗篙篚篛篨篪篲篴篵篸篹篺篼篾簁簂簃簄簆簉簋簌簎簏簙簛簠簥簦簨簬簱簳簴簶簹簺籆籊籕籑籒籓籙",5],["8fd3a1","籡籣籧籩籭籮籰籲籹籼籽粆粇粏粔粞粠粦粰粶粷粺粻粼粿糄糇糈糉糍糏糓糔糕糗糙糚糝糦糩糫糵紃紇紈紉紏紑紒紓紖紝紞紣紦紪紭紱紼紽紾絀絁絇絈絍絑絓絗絙絚絜絝絥絧絪絰絸絺絻絿綁綂綃綅綆綈綋綌綍綑綖綗綝"],["8fd4a1","綞綦綧綪綳綶綷綹緂",4,"緌緍緎緗緙縀緢緥緦緪緫緭緱緵緶緹緺縈縐縑縕縗縜縝縠縧縨縬縭縯縳縶縿繄繅繇繎繐繒繘繟繡繢繥繫繮繯繳繸繾纁纆纇纊纍纑纕纘纚纝纞缼缻缽缾缿罃罄罇罏罒罓罛罜罝罡罣罤罥罦罭"],["8fd5a1","罱罽罾罿羀羋羍羏羐羑羖羗羜羡羢羦羪羭羴羼羿翀翃翈翎翏翛翟翣翥翨翬翮翯翲翺翽翾翿耇耈耊耍耎耏耑耓耔耖耝耞耟耠耤耦耬耮耰耴耵耷耹耺耼耾聀聄聠聤聦聭聱聵肁肈肎肜肞肦肧肫肸肹胈胍胏胒胔胕胗胘胠胭胮"],["8fd6a1","胰胲胳胶胹胺胾脃脋脖脗脘脜脞脠脤脧脬脰脵脺脼腅腇腊腌腒腗腠腡腧腨腩腭腯腷膁膐膄膅膆膋膎膖膘膛膞膢膮膲膴膻臋臃臅臊臎臏臕臗臛臝臞臡臤臫臬臰臱臲臵臶臸臹臽臿舀舃舏舓舔舙舚舝舡舢舨舲舴舺艃艄艅艆"],["8fd7a1","艋艎艏艑艖艜艠艣艧艭艴艻艽艿芀芁芃芄芇芉芊芎芑芔芖芘芚芛芠芡芣芤芧芨芩芪芮芰芲芴芷芺芼芾芿苆苐苕苚苠苢苤苨苪苭苯苶苷苽苾茀茁茇茈茊茋荔茛茝茞茟茡茢茬茭茮茰茳茷茺茼茽荂荃荄荇荍荎荑荕荖荗荰荸"],["8fd8a1","荽荿莀莂莄莆莍莒莔莕莘莙莛莜莝莦莧莩莬莾莿菀菇菉菏菐菑菔菝荓菨菪菶菸菹菼萁萆萊萏萑萕萙莭萯萹葅葇葈葊葍葏葑葒葖葘葙葚葜葠葤葥葧葪葰葳葴葶葸葼葽蒁蒅蒒蒓蒕蒞蒦蒨蒩蒪蒯蒱蒴蒺蒽蒾蓀蓂蓇蓈蓌蓏蓓"],["8fd9a1","蓜蓧蓪蓯蓰蓱蓲蓷蔲蓺蓻蓽蔂蔃蔇蔌蔎蔐蔜蔞蔢蔣蔤蔥蔧蔪蔫蔯蔳蔴蔶蔿蕆蕏",4,"蕖蕙蕜",6,"蕤蕫蕯蕹蕺蕻蕽蕿薁薅薆薉薋薌薏薓薘薝薟薠薢薥薧薴薶薷薸薼薽薾薿藂藇藊藋藎薭藘藚藟藠藦藨藭藳藶藼"],["8fdaa1","藿蘀蘄蘅蘍蘎蘐蘑蘒蘘蘙蘛蘞蘡蘧蘩蘶蘸蘺蘼蘽虀虂虆虒虓虖虗虘虙虝虠",4,"虩虬虯虵虶虷虺蚍蚑蚖蚘蚚蚜蚡蚦蚧蚨蚭蚱蚳蚴蚵蚷蚸蚹蚿蛀蛁蛃蛅蛑蛒蛕蛗蛚蛜蛠蛣蛥蛧蚈蛺蛼蛽蜄蜅蜇蜋蜎蜏蜐蜓蜔蜙蜞蜟蜡蜣"],["8fdba1","蜨蜮蜯蜱蜲蜹蜺蜼蜽蜾蝀蝃蝅蝍蝘蝝蝡蝤蝥蝯蝱蝲蝻螃",6,"螋螌螐螓螕螗螘螙螞螠螣螧螬螭螮螱螵螾螿蟁蟈蟉蟊蟎蟕蟖蟙蟚蟜蟟蟢蟣蟤蟪蟫蟭蟱蟳蟸蟺蟿蠁蠃蠆蠉蠊蠋蠐蠙蠒蠓蠔蠘蠚蠛蠜蠞蠟蠨蠭蠮蠰蠲蠵"],["8fdca1","蠺蠼衁衃衅衈衉衊衋衎衑衕衖衘衚衜衟衠衤衩衱衹衻袀袘袚袛袜袟袠袨袪袺袽袾裀裊",4,"裑裒裓裛裞裧裯裰裱裵裷褁褆褍褎褏褕褖褘褙褚褜褠褦褧褨褰褱褲褵褹褺褾襀襂襅襆襉襏襒襗襚襛襜襡襢襣襫襮襰襳襵襺"],["8fdda1","襻襼襽覉覍覐覔覕覛覜覟覠覥覰覴覵覶覷覼觔",4,"觥觩觫觭觱觳觶觹觽觿訄訅訇訏訑訒訔訕訞訠訢訤訦訫訬訯訵訷訽訾詀詃詅詇詉詍詎詓詖詗詘詜詝詡詥詧詵詶詷詹詺詻詾詿誀誃誆誋誏誐誒誖誗誙誟誧誩誮誯誳"],["8fdea1","誶誷誻誾諃諆諈諉諊諑諓諔諕諗諝諟諬諰諴諵諶諼諿謅謆謋謑謜謞謟謊謭謰謷謼譂",4,"譈譒譓譔譙譍譞譣譭譶譸譹譼譾讁讄讅讋讍讏讔讕讜讞讟谸谹谽谾豅豇豉豋豏豑豓豔豗豘豛豝豙豣豤豦豨豩豭豳豵豶豻豾貆"],["8fdfa1","貇貋貐貒貓貙貛貜貤貹貺賅賆賉賋賏賖賕賙賝賡賨賬賯賰賲賵賷賸賾賿贁贃贉贒贗贛赥赩赬赮赿趂趄趈趍趐趑趕趞趟趠趦趫趬趯趲趵趷趹趻跀跅跆跇跈跊跎跑跔跕跗跙跤跥跧跬跰趼跱跲跴跽踁踄踅踆踋踑踔踖踠踡踢"],["8fe0a1","踣踦踧踱踳踶踷踸踹踽蹀蹁蹋蹍蹎蹏蹔蹛蹜蹝蹞蹡蹢蹩蹬蹭蹯蹰蹱蹹蹺蹻躂躃躉躐躒躕躚躛躝躞躢躧躩躭躮躳躵躺躻軀軁軃軄軇軏軑軔軜軨軮軰軱軷軹軺軭輀輂輇輈輏輐輖輗輘輞輠輡輣輥輧輨輬輭輮輴輵輶輷輺轀轁"],["8fe1a1","轃轇轏轑",4,"轘轝轞轥辝辠辡辤辥辦辵辶辸达迀迁迆迊迋迍运迒迓迕迠迣迤迨迮迱迵迶迻迾适逄逈逌逘逛逨逩逯逪逬逭逳逴逷逿遃遄遌遛遝遢遦遧遬遰遴遹邅邈邋邌邎邐邕邗邘邙邛邠邡邢邥邰邲邳邴邶邽郌邾郃"],["8fe2a1","郄郅郇郈郕郗郘郙郜郝郟郥郒郶郫郯郰郴郾郿鄀鄄鄅鄆鄈鄍鄐鄔鄖鄗鄘鄚鄜鄞鄠鄥鄢鄣鄧鄩鄮鄯鄱鄴鄶鄷鄹鄺鄼鄽酃酇酈酏酓酗酙酚酛酡酤酧酭酴酹酺酻醁醃醅醆醊醎醑醓醔醕醘醞醡醦醨醬醭醮醰醱醲醳醶醻醼醽醿"],["8fe3a1","釂釃釅釓釔釗釙釚釞釤釥釩釪釬",5,"釷釹釻釽鈀鈁鈄鈅鈆鈇鈉鈊鈌鈐鈒鈓鈖鈘鈜鈝鈣鈤鈥鈦鈨鈮鈯鈰鈳鈵鈶鈸鈹鈺鈼鈾鉀鉂鉃鉆鉇鉊鉍鉎鉏鉑鉘鉙鉜鉝鉠鉡鉥鉧鉨鉩鉮鉯鉰鉵",4,"鉻鉼鉽鉿銈銉銊銍銎銒銗"],["8fe4a1","銙銟銠銤銥銧銨銫銯銲銶銸銺銻銼銽銿",4,"鋅鋆鋇鋈鋋鋌鋍鋎鋐鋓鋕鋗鋘鋙鋜鋝鋟鋠鋡鋣鋥鋧鋨鋬鋮鋰鋹鋻鋿錀錂錈錍錑錔錕錜錝錞錟錡錤錥錧錩錪錳錴錶錷鍇鍈鍉鍐鍑鍒鍕鍗鍘鍚鍞鍤鍥鍧鍩鍪鍭鍯鍰鍱鍳鍴鍶"],["8fe5a1","鍺鍽鍿鎀鎁鎂鎈鎊鎋鎍鎏鎒鎕鎘鎛鎞鎡鎣鎤鎦鎨鎫鎴鎵鎶鎺鎩鏁鏄鏅鏆鏇鏉",4,"鏓鏙鏜鏞鏟鏢鏦鏧鏹鏷鏸鏺鏻鏽鐁鐂鐄鐈鐉鐍鐎鐏鐕鐖鐗鐟鐮鐯鐱鐲鐳鐴鐻鐿鐽鑃鑅鑈鑊鑌鑕鑙鑜鑟鑡鑣鑨鑫鑭鑮鑯鑱鑲钄钃镸镹"],["8fe6a1","镾閄閈閌閍閎閝閞閟閡閦閩閫閬閴閶閺閽閿闆闈闉闋闐闑闒闓闙闚闝闞闟闠闤闦阝阞阢阤阥阦阬阱阳阷阸阹阺阼阽陁陒陔陖陗陘陡陮陴陻陼陾陿隁隂隃隄隉隑隖隚隝隟隤隥隦隩隮隯隳隺雊雒嶲雘雚雝雞雟雩雯雱雺霂"],["8fe7a1","霃霅霉霚霛霝霡霢霣霨霱霳靁靃靊靎靏靕靗靘靚靛靣靧靪靮靳靶靷靸靻靽靿鞀鞉鞕鞖鞗鞙鞚鞞鞟鞢鞬鞮鞱鞲鞵鞶鞸鞹鞺鞼鞾鞿韁韄韅韇韉韊韌韍韎韐韑韔韗韘韙韝韞韠韛韡韤韯韱韴韷韸韺頇頊頙頍頎頔頖頜頞頠頣頦"],["8fe8a1","頫頮頯頰頲頳頵頥頾顄顇顊顑顒顓顖顗顙顚顢顣顥顦顪顬颫颭颮颰颴颷颸颺颻颿飂飅飈飌飡飣飥飦飧飪飳飶餂餇餈餑餕餖餗餚餛餜餟餢餦餧餫餱",4,"餹餺餻餼饀饁饆饇饈饍饎饔饘饙饛饜饞饟饠馛馝馟馦馰馱馲馵"],["8fe9a1","馹馺馽馿駃駉駓駔駙駚駜駞駧駪駫駬駰駴駵駹駽駾騂騃騄騋騌騐騑騖騞騠騢騣騤騧騭騮騳騵騶騸驇驁驄驊驋驌驎驑驔驖驝骪骬骮骯骲骴骵骶骹骻骾骿髁髃髆髈髎髐髒髕髖髗髛髜髠髤髥髧髩髬髲髳髵髹髺髽髿",4],["8feaa1","鬄鬅鬈鬉鬋鬌鬍鬎鬐鬒鬖鬙鬛鬜鬠鬦鬫鬭鬳鬴鬵鬷鬹鬺鬽魈魋魌魕魖魗魛魞魡魣魥魦魨魪",4,"魳魵魷魸魹魿鮀鮄鮅鮆鮇鮉鮊鮋鮍鮏鮐鮔鮚鮝鮞鮦鮧鮩鮬鮰鮱鮲鮷鮸鮻鮼鮾鮿鯁鯇鯈鯎鯐鯗鯘鯝鯟鯥鯧鯪鯫鯯鯳鯷鯸"],["8feba1","鯹鯺鯽鯿鰀鰂鰋鰏鰑鰖鰘鰙鰚鰜鰞鰢鰣鰦",4,"鰱鰵鰶鰷鰽鱁鱃鱄鱅鱉鱊鱎鱏鱐鱓鱔鱖鱘鱛鱝鱞鱟鱣鱩鱪鱜鱫鱨鱮鱰鱲鱵鱷鱻鳦鳲鳷鳹鴋鴂鴑鴗鴘鴜鴝鴞鴯鴰鴲鴳鴴鴺鴼鵅鴽鵂鵃鵇鵊鵓鵔鵟鵣鵢鵥鵩鵪鵫鵰鵶鵷鵻"],["8feca1","鵼鵾鶃鶄鶆鶊鶍鶎鶒鶓鶕鶖鶗鶘鶡鶪鶬鶮鶱鶵鶹鶼鶿鷃鷇鷉鷊鷔鷕鷖鷗鷚鷞鷟鷠鷥鷧鷩鷫鷮鷰鷳鷴鷾鸊鸂鸇鸎鸐鸑鸒鸕鸖鸙鸜鸝鹺鹻鹼麀麂麃麄麅麇麎麏麖麘麛麞麤麨麬麮麯麰麳麴麵黆黈黋黕黟黤黧黬黭黮黰黱黲黵"],["8feda1","黸黿鼂鼃鼉鼏鼐鼑鼒鼔鼖鼗鼙鼚鼛鼟鼢鼦鼪鼫鼯鼱鼲鼴鼷鼹鼺鼼鼽鼿齁齃",4,"齓齕齖齗齘齚齝齞齨齩齭",4,"齳齵齺齽龏龐龑龒龔龖龗龞龡龢龣龥"]]'); + +/***/ }), + +/***/ 3567: +/***/ ((module) => { + +module.exports = JSON.parse('{"uChars":[128,165,169,178,184,216,226,235,238,244,248,251,253,258,276,284,300,325,329,334,364,463,465,467,469,471,473,475,477,506,594,610,712,716,730,930,938,962,970,1026,1104,1106,8209,8215,8218,8222,8231,8241,8244,8246,8252,8365,8452,8454,8458,8471,8482,8556,8570,8596,8602,8713,8720,8722,8726,8731,8737,8740,8742,8748,8751,8760,8766,8777,8781,8787,8802,8808,8816,8854,8858,8870,8896,8979,9322,9372,9548,9588,9616,9622,9634,9652,9662,9672,9676,9680,9702,9735,9738,9793,9795,11906,11909,11913,11917,11928,11944,11947,11951,11956,11960,11964,11979,12284,12292,12312,12319,12330,12351,12436,12447,12535,12543,12586,12842,12850,12964,13200,13215,13218,13253,13263,13267,13270,13384,13428,13727,13839,13851,14617,14703,14801,14816,14964,15183,15471,15585,16471,16736,17208,17325,17330,17374,17623,17997,18018,18212,18218,18301,18318,18760,18811,18814,18820,18823,18844,18848,18872,19576,19620,19738,19887,40870,59244,59336,59367,59413,59417,59423,59431,59437,59443,59452,59460,59478,59493,63789,63866,63894,63976,63986,64016,64018,64021,64025,64034,64037,64042,65074,65093,65107,65112,65127,65132,65375,65510,65536],"gbChars":[0,36,38,45,50,81,89,95,96,100,103,104,105,109,126,133,148,172,175,179,208,306,307,308,309,310,311,312,313,341,428,443,544,545,558,741,742,749,750,805,819,820,7922,7924,7925,7927,7934,7943,7944,7945,7950,8062,8148,8149,8152,8164,8174,8236,8240,8262,8264,8374,8380,8381,8384,8388,8390,8392,8393,8394,8396,8401,8406,8416,8419,8424,8437,8439,8445,8482,8485,8496,8521,8603,8936,8946,9046,9050,9063,9066,9076,9092,9100,9108,9111,9113,9131,9162,9164,9218,9219,11329,11331,11334,11336,11346,11361,11363,11366,11370,11372,11375,11389,11682,11686,11687,11692,11694,11714,11716,11723,11725,11730,11736,11982,11989,12102,12336,12348,12350,12384,12393,12395,12397,12510,12553,12851,12962,12973,13738,13823,13919,13933,14080,14298,14585,14698,15583,15847,16318,16434,16438,16481,16729,17102,17122,17315,17320,17402,17418,17859,17909,17911,17915,17916,17936,17939,17961,18664,18703,18814,18962,19043,33469,33470,33471,33484,33485,33490,33497,33501,33505,33513,33520,33536,33550,37845,37921,37948,38029,38038,38064,38065,38066,38069,38075,38076,38078,39108,39109,39113,39114,39115,39116,39265,39394,189000]}'); + +/***/ }), + +/***/ 7235: +/***/ ((module) => { + +module.exports = JSON.parse('[["a140","",62],["a180","",32],["a240","",62],["a280","",32],["a2ab","",5],["a2e3","€"],["a2ef",""],["a2fd",""],["a340","",62],["a380","",31," "],["a440","",62],["a480","",32],["a4f4","",10],["a540","",62],["a580","",32],["a5f7","",7],["a640","",62],["a680","",32],["a6b9","",7],["a6d9","",6],["a6ec",""],["a6f3",""],["a6f6","",8],["a740","",62],["a780","",32],["a7c2","",14],["a7f2","",12],["a896","",10],["a8bc","ḿ"],["a8bf","ǹ"],["a8c1",""],["a8ea","",20],["a958",""],["a95b",""],["a95d",""],["a989","〾⿰",11],["a997","",12],["a9f0","",14],["aaa1","",93],["aba1","",93],["aca1","",93],["ada1","",93],["aea1","",93],["afa1","",93],["d7fa","",4],["f8a1","",93],["f9a1","",93],["faa1","",93],["fba1","",93],["fca1","",93],["fda1","",93],["fe50","⺁⺄㑳㑇⺈⺋㖞㘚㘎⺌⺗㥮㤘㧏㧟㩳㧐㭎㱮㳠⺧⺪䁖䅟⺮䌷⺳⺶⺷䎱䎬⺻䏝䓖䙡䙌"],["fe80","䜣䜩䝼䞍⻊䥇䥺䥽䦂䦃䦅䦆䦟䦛䦷䦶䲣䲟䲠䲡䱷䲢䴓",6,"䶮",93],["8135f437",""]]'); + +/***/ }), + +/***/ 2348: +/***/ ((module) => { + +module.exports = JSON.parse('[["0","\\u0000",128],["a1","。",62],["8140"," 、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈",9,"+-±×"],["8180","÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇◆□■△▲▽▼※〒→←↑↓〓"],["81b8","∈∋⊆⊇⊂⊃∪∩"],["81c8","∧∨¬⇒⇔∀∃"],["81da","∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬"],["81f0","ʼn♯♭♪†‡¶"],["81fc","◯"],["824f","0",9],["8260","A",25],["8281","a",25],["829f","ぁ",82],["8340","ァ",62],["8380","ム",22],["839f","Α",16,"Σ",6],["83bf","α",16,"σ",6],["8440","А",5,"ЁЖ",25],["8470","а",5,"ёж",7],["8480","о",17],["849f","─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂"],["8740","①",19,"Ⅰ",9],["875f","㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡"],["877e","㍻"],["8780","〝〟№㏍℡㊤",4,"㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪"],["889f","亜唖娃阿哀愛挨姶逢葵茜穐悪握渥旭葦芦鯵梓圧斡扱宛姐虻飴絢綾鮎或粟袷安庵按暗案闇鞍杏以伊位依偉囲夷委威尉惟意慰易椅為畏異移維緯胃萎衣謂違遺医井亥域育郁磯一壱溢逸稲茨芋鰯允印咽員因姻引飲淫胤蔭"],["8940","院陰隠韻吋右宇烏羽迂雨卯鵜窺丑碓臼渦嘘唄欝蔚鰻姥厩浦瓜閏噂云運雲荏餌叡営嬰影映曳栄永泳洩瑛盈穎頴英衛詠鋭液疫益駅悦謁越閲榎厭円"],["8980","園堰奄宴延怨掩援沿演炎焔煙燕猿縁艶苑薗遠鉛鴛塩於汚甥凹央奥往応押旺横欧殴王翁襖鴬鴎黄岡沖荻億屋憶臆桶牡乙俺卸恩温穏音下化仮何伽価佳加可嘉夏嫁家寡科暇果架歌河火珂禍禾稼箇花苛茄荷華菓蝦課嘩貨迦過霞蚊俄峨我牙画臥芽蛾賀雅餓駕介会解回塊壊廻快怪悔恢懐戒拐改"],["8a40","魁晦械海灰界皆絵芥蟹開階貝凱劾外咳害崖慨概涯碍蓋街該鎧骸浬馨蛙垣柿蛎鈎劃嚇各廓拡撹格核殻獲確穫覚角赫較郭閣隔革学岳楽額顎掛笠樫"],["8a80","橿梶鰍潟割喝恰括活渇滑葛褐轄且鰹叶椛樺鞄株兜竃蒲釜鎌噛鴨栢茅萱粥刈苅瓦乾侃冠寒刊勘勧巻喚堪姦完官寛干幹患感慣憾換敢柑桓棺款歓汗漢澗潅環甘監看竿管簡緩缶翰肝艦莞観諌貫還鑑間閑関陥韓館舘丸含岸巌玩癌眼岩翫贋雁頑顔願企伎危喜器基奇嬉寄岐希幾忌揮机旗既期棋棄"],["8b40","機帰毅気汽畿祈季稀紀徽規記貴起軌輝飢騎鬼亀偽儀妓宜戯技擬欺犠疑祇義蟻誼議掬菊鞠吉吃喫桔橘詰砧杵黍却客脚虐逆丘久仇休及吸宮弓急救"],["8b80","朽求汲泣灸球究窮笈級糾給旧牛去居巨拒拠挙渠虚許距鋸漁禦魚亨享京供侠僑兇競共凶協匡卿叫喬境峡強彊怯恐恭挟教橋況狂狭矯胸脅興蕎郷鏡響饗驚仰凝尭暁業局曲極玉桐粁僅勤均巾錦斤欣欽琴禁禽筋緊芹菌衿襟謹近金吟銀九倶句区狗玖矩苦躯駆駈駒具愚虞喰空偶寓遇隅串櫛釧屑屈"],["8c40","掘窟沓靴轡窪熊隈粂栗繰桑鍬勲君薫訓群軍郡卦袈祁係傾刑兄啓圭珪型契形径恵慶慧憩掲携敬景桂渓畦稽系経継繋罫茎荊蛍計詣警軽頚鶏芸迎鯨"],["8c80","劇戟撃激隙桁傑欠決潔穴結血訣月件倹倦健兼券剣喧圏堅嫌建憲懸拳捲検権牽犬献研硯絹県肩見謙賢軒遣鍵険顕験鹸元原厳幻弦減源玄現絃舷言諺限乎個古呼固姑孤己庫弧戸故枯湖狐糊袴股胡菰虎誇跨鈷雇顧鼓五互伍午呉吾娯後御悟梧檎瑚碁語誤護醐乞鯉交佼侯候倖光公功効勾厚口向"],["8d40","后喉坑垢好孔孝宏工巧巷幸広庚康弘恒慌抗拘控攻昂晃更杭校梗構江洪浩港溝甲皇硬稿糠紅紘絞綱耕考肯肱腔膏航荒行衡講貢購郊酵鉱砿鋼閤降"],["8d80","項香高鴻剛劫号合壕拷濠豪轟麹克刻告国穀酷鵠黒獄漉腰甑忽惚骨狛込此頃今困坤墾婚恨懇昏昆根梱混痕紺艮魂些佐叉唆嵯左差査沙瑳砂詐鎖裟坐座挫債催再最哉塞妻宰彩才採栽歳済災采犀砕砦祭斎細菜裁載際剤在材罪財冴坂阪堺榊肴咲崎埼碕鷺作削咋搾昨朔柵窄策索錯桜鮭笹匙冊刷"],["8e40","察拶撮擦札殺薩雑皐鯖捌錆鮫皿晒三傘参山惨撒散桟燦珊産算纂蚕讃賛酸餐斬暫残仕仔伺使刺司史嗣四士始姉姿子屍市師志思指支孜斯施旨枝止"],["8e80","死氏獅祉私糸紙紫肢脂至視詞詩試誌諮資賜雌飼歯事似侍児字寺慈持時次滋治爾璽痔磁示而耳自蒔辞汐鹿式識鴫竺軸宍雫七叱執失嫉室悉湿漆疾質実蔀篠偲柴芝屡蕊縞舎写射捨赦斜煮社紗者謝車遮蛇邪借勺尺杓灼爵酌釈錫若寂弱惹主取守手朱殊狩珠種腫趣酒首儒受呪寿授樹綬需囚収周"],["8f40","宗就州修愁拾洲秀秋終繍習臭舟蒐衆襲讐蹴輯週酋酬集醜什住充十従戎柔汁渋獣縦重銃叔夙宿淑祝縮粛塾熟出術述俊峻春瞬竣舜駿准循旬楯殉淳"],["8f80","準潤盾純巡遵醇順処初所暑曙渚庶緒署書薯藷諸助叙女序徐恕鋤除傷償勝匠升召哨商唱嘗奨妾娼宵将小少尚庄床廠彰承抄招掌捷昇昌昭晶松梢樟樵沼消渉湘焼焦照症省硝礁祥称章笑粧紹肖菖蒋蕉衝裳訟証詔詳象賞醤鉦鍾鐘障鞘上丈丞乗冗剰城場壌嬢常情擾条杖浄状畳穣蒸譲醸錠嘱埴飾"],["9040","拭植殖燭織職色触食蝕辱尻伸信侵唇娠寝審心慎振新晋森榛浸深申疹真神秦紳臣芯薪親診身辛進針震人仁刃塵壬尋甚尽腎訊迅陣靭笥諏須酢図厨"],["9080","逗吹垂帥推水炊睡粋翠衰遂酔錐錘随瑞髄崇嵩数枢趨雛据杉椙菅頗雀裾澄摺寸世瀬畝是凄制勢姓征性成政整星晴棲栖正清牲生盛精聖声製西誠誓請逝醒青静斉税脆隻席惜戚斥昔析石積籍績脊責赤跡蹟碩切拙接摂折設窃節説雪絶舌蝉仙先千占宣専尖川戦扇撰栓栴泉浅洗染潜煎煽旋穿箭線"],["9140","繊羨腺舛船薦詮賎践選遷銭銑閃鮮前善漸然全禅繕膳糎噌塑岨措曾曽楚狙疏疎礎祖租粗素組蘇訴阻遡鼠僧創双叢倉喪壮奏爽宋層匝惣想捜掃挿掻"],["9180","操早曹巣槍槽漕燥争痩相窓糟総綜聡草荘葬蒼藻装走送遭鎗霜騒像増憎臓蔵贈造促側則即息捉束測足速俗属賊族続卒袖其揃存孫尊損村遜他多太汰詑唾堕妥惰打柁舵楕陀駄騨体堆対耐岱帯待怠態戴替泰滞胎腿苔袋貸退逮隊黛鯛代台大第醍題鷹滝瀧卓啄宅托択拓沢濯琢託鐸濁諾茸凧蛸只"],["9240","叩但達辰奪脱巽竪辿棚谷狸鱈樽誰丹単嘆坦担探旦歎淡湛炭短端箪綻耽胆蛋誕鍛団壇弾断暖檀段男談値知地弛恥智池痴稚置致蜘遅馳築畜竹筑蓄"],["9280","逐秩窒茶嫡着中仲宙忠抽昼柱注虫衷註酎鋳駐樗瀦猪苧著貯丁兆凋喋寵帖帳庁弔張彫徴懲挑暢朝潮牒町眺聴脹腸蝶調諜超跳銚長頂鳥勅捗直朕沈珍賃鎮陳津墜椎槌追鎚痛通塚栂掴槻佃漬柘辻蔦綴鍔椿潰坪壷嬬紬爪吊釣鶴亭低停偵剃貞呈堤定帝底庭廷弟悌抵挺提梯汀碇禎程締艇訂諦蹄逓"],["9340","邸鄭釘鼎泥摘擢敵滴的笛適鏑溺哲徹撤轍迭鉄典填天展店添纏甜貼転顛点伝殿澱田電兎吐堵塗妬屠徒斗杜渡登菟賭途都鍍砥砺努度土奴怒倒党冬"],["9380","凍刀唐塔塘套宕島嶋悼投搭東桃梼棟盗淘湯涛灯燈当痘祷等答筒糖統到董蕩藤討謄豆踏逃透鐙陶頭騰闘働動同堂導憧撞洞瞳童胴萄道銅峠鴇匿得徳涜特督禿篤毒独読栃橡凸突椴届鳶苫寅酉瀞噸屯惇敦沌豚遁頓呑曇鈍奈那内乍凪薙謎灘捺鍋楢馴縄畷南楠軟難汝二尼弐迩匂賑肉虹廿日乳入"],["9440","如尿韮任妊忍認濡禰祢寧葱猫熱年念捻撚燃粘乃廼之埜嚢悩濃納能脳膿農覗蚤巴把播覇杷波派琶破婆罵芭馬俳廃拝排敗杯盃牌背肺輩配倍培媒梅"],["9480","楳煤狽買売賠陪這蝿秤矧萩伯剥博拍柏泊白箔粕舶薄迫曝漠爆縛莫駁麦函箱硲箸肇筈櫨幡肌畑畠八鉢溌発醗髪伐罰抜筏閥鳩噺塙蛤隼伴判半反叛帆搬斑板氾汎版犯班畔繁般藩販範釆煩頒飯挽晩番盤磐蕃蛮匪卑否妃庇彼悲扉批披斐比泌疲皮碑秘緋罷肥被誹費避非飛樋簸備尾微枇毘琵眉美"],["9540","鼻柊稗匹疋髭彦膝菱肘弼必畢筆逼桧姫媛紐百謬俵彪標氷漂瓢票表評豹廟描病秒苗錨鋲蒜蛭鰭品彬斌浜瀕貧賓頻敏瓶不付埠夫婦富冨布府怖扶敷"],["9580","斧普浮父符腐膚芙譜負賦赴阜附侮撫武舞葡蕪部封楓風葺蕗伏副復幅服福腹複覆淵弗払沸仏物鮒分吻噴墳憤扮焚奮粉糞紛雰文聞丙併兵塀幣平弊柄並蔽閉陛米頁僻壁癖碧別瞥蔑箆偏変片篇編辺返遍便勉娩弁鞭保舗鋪圃捕歩甫補輔穂募墓慕戊暮母簿菩倣俸包呆報奉宝峰峯崩庖抱捧放方朋"],["9640","法泡烹砲縫胞芳萌蓬蜂褒訪豊邦鋒飽鳳鵬乏亡傍剖坊妨帽忘忙房暴望某棒冒紡肪膨謀貌貿鉾防吠頬北僕卜墨撲朴牧睦穆釦勃没殆堀幌奔本翻凡盆"],["9680","摩磨魔麻埋妹昧枚毎哩槙幕膜枕鮪柾鱒桝亦俣又抹末沫迄侭繭麿万慢満漫蔓味未魅巳箕岬密蜜湊蓑稔脈妙粍民眠務夢無牟矛霧鵡椋婿娘冥名命明盟迷銘鳴姪牝滅免棉綿緬面麺摸模茂妄孟毛猛盲網耗蒙儲木黙目杢勿餅尤戻籾貰問悶紋門匁也冶夜爺耶野弥矢厄役約薬訳躍靖柳薮鑓愉愈油癒"],["9740","諭輸唯佑優勇友宥幽悠憂揖有柚湧涌猶猷由祐裕誘遊邑郵雄融夕予余与誉輿預傭幼妖容庸揚揺擁曜楊様洋溶熔用窯羊耀葉蓉要謡踊遥陽養慾抑欲"],["9780","沃浴翌翼淀羅螺裸来莱頼雷洛絡落酪乱卵嵐欄濫藍蘭覧利吏履李梨理璃痢裏裡里離陸律率立葎掠略劉流溜琉留硫粒隆竜龍侶慮旅虜了亮僚両凌寮料梁涼猟療瞭稜糧良諒遼量陵領力緑倫厘林淋燐琳臨輪隣鱗麟瑠塁涙累類令伶例冷励嶺怜玲礼苓鈴隷零霊麗齢暦歴列劣烈裂廉恋憐漣煉簾練聯"],["9840","蓮連錬呂魯櫓炉賂路露労婁廊弄朗楼榔浪漏牢狼篭老聾蝋郎六麓禄肋録論倭和話歪賄脇惑枠鷲亙亘鰐詫藁蕨椀湾碗腕"],["989f","弌丐丕个丱丶丼丿乂乖乘亂亅豫亊舒弍于亞亟亠亢亰亳亶从仍仄仆仂仗仞仭仟价伉佚估佛佝佗佇佶侈侏侘佻佩佰侑佯來侖儘俔俟俎俘俛俑俚俐俤俥倚倨倔倪倥倅伜俶倡倩倬俾俯們倆偃假會偕偐偈做偖偬偸傀傚傅傴傲"],["9940","僉僊傳僂僖僞僥僭僣僮價僵儉儁儂儖儕儔儚儡儺儷儼儻儿兀兒兌兔兢竸兩兪兮冀冂囘册冉冏冑冓冕冖冤冦冢冩冪冫决冱冲冰况冽凅凉凛几處凩凭"],["9980","凰凵凾刄刋刔刎刧刪刮刳刹剏剄剋剌剞剔剪剴剩剳剿剽劍劔劒剱劈劑辨辧劬劭劼劵勁勍勗勞勣勦飭勠勳勵勸勹匆匈甸匍匐匏匕匚匣匯匱匳匸區卆卅丗卉卍凖卞卩卮夘卻卷厂厖厠厦厥厮厰厶參簒雙叟曼燮叮叨叭叺吁吽呀听吭吼吮吶吩吝呎咏呵咎呟呱呷呰咒呻咀呶咄咐咆哇咢咸咥咬哄哈咨"],["9a40","咫哂咤咾咼哘哥哦唏唔哽哮哭哺哢唹啀啣啌售啜啅啖啗唸唳啝喙喀咯喊喟啻啾喘喞單啼喃喩喇喨嗚嗅嗟嗄嗜嗤嗔嘔嗷嘖嗾嗽嘛嗹噎噐營嘴嘶嘲嘸"],["9a80","噫噤嘯噬噪嚆嚀嚊嚠嚔嚏嚥嚮嚶嚴囂嚼囁囃囀囈囎囑囓囗囮囹圀囿圄圉圈國圍圓團圖嗇圜圦圷圸坎圻址坏坩埀垈坡坿垉垓垠垳垤垪垰埃埆埔埒埓堊埖埣堋堙堝塲堡塢塋塰毀塒堽塹墅墹墟墫墺壞墻墸墮壅壓壑壗壙壘壥壜壤壟壯壺壹壻壼壽夂夊夐夛梦夥夬夭夲夸夾竒奕奐奎奚奘奢奠奧奬奩"],["9b40","奸妁妝佞侫妣妲姆姨姜妍姙姚娥娟娑娜娉娚婀婬婉娵娶婢婪媚媼媾嫋嫂媽嫣嫗嫦嫩嫖嫺嫻嬌嬋嬖嬲嫐嬪嬶嬾孃孅孀孑孕孚孛孥孩孰孳孵學斈孺宀"],["9b80","它宦宸寃寇寉寔寐寤實寢寞寥寫寰寶寳尅將專對尓尠尢尨尸尹屁屆屎屓屐屏孱屬屮乢屶屹岌岑岔妛岫岻岶岼岷峅岾峇峙峩峽峺峭嶌峪崋崕崗嵜崟崛崑崔崢崚崙崘嵌嵒嵎嵋嵬嵳嵶嶇嶄嶂嶢嶝嶬嶮嶽嶐嶷嶼巉巍巓巒巖巛巫已巵帋帚帙帑帛帶帷幄幃幀幎幗幔幟幢幤幇幵并幺麼广庠廁廂廈廐廏"],["9c40","廖廣廝廚廛廢廡廨廩廬廱廳廰廴廸廾弃弉彝彜弋弑弖弩弭弸彁彈彌彎弯彑彖彗彙彡彭彳彷徃徂彿徊很徑徇從徙徘徠徨徭徼忖忻忤忸忱忝悳忿怡恠"],["9c80","怙怐怩怎怱怛怕怫怦怏怺恚恁恪恷恟恊恆恍恣恃恤恂恬恫恙悁悍惧悃悚悄悛悖悗悒悧悋惡悸惠惓悴忰悽惆悵惘慍愕愆惶惷愀惴惺愃愡惻惱愍愎慇愾愨愧慊愿愼愬愴愽慂慄慳慷慘慙慚慫慴慯慥慱慟慝慓慵憙憖憇憬憔憚憊憑憫憮懌懊應懷懈懃懆憺懋罹懍懦懣懶懺懴懿懽懼懾戀戈戉戍戌戔戛"],["9d40","戞戡截戮戰戲戳扁扎扞扣扛扠扨扼抂抉找抒抓抖拔抃抔拗拑抻拏拿拆擔拈拜拌拊拂拇抛拉挌拮拱挧挂挈拯拵捐挾捍搜捏掖掎掀掫捶掣掏掉掟掵捫"],["9d80","捩掾揩揀揆揣揉插揶揄搖搴搆搓搦搶攝搗搨搏摧摯摶摎攪撕撓撥撩撈撼據擒擅擇撻擘擂擱擧舉擠擡抬擣擯攬擶擴擲擺攀擽攘攜攅攤攣攫攴攵攷收攸畋效敖敕敍敘敞敝敲數斂斃變斛斟斫斷旃旆旁旄旌旒旛旙无旡旱杲昊昃旻杳昵昶昴昜晏晄晉晁晞晝晤晧晨晟晢晰暃暈暎暉暄暘暝曁暹曉暾暼"],["9e40","曄暸曖曚曠昿曦曩曰曵曷朏朖朞朦朧霸朮朿朶杁朸朷杆杞杠杙杣杤枉杰枩杼杪枌枋枦枡枅枷柯枴柬枳柩枸柤柞柝柢柮枹柎柆柧檜栞框栩桀桍栲桎"],["9e80","梳栫桙档桷桿梟梏梭梔條梛梃檮梹桴梵梠梺椏梍桾椁棊椈棘椢椦棡椌棍棔棧棕椶椒椄棗棣椥棹棠棯椨椪椚椣椡棆楹楷楜楸楫楔楾楮椹楴椽楙椰楡楞楝榁楪榲榮槐榿槁槓榾槎寨槊槝榻槃榧樮榑榠榜榕榴槞槨樂樛槿權槹槲槧樅榱樞槭樔槫樊樒櫁樣樓橄樌橲樶橸橇橢橙橦橈樸樢檐檍檠檄檢檣"],["9f40","檗蘗檻櫃櫂檸檳檬櫞櫑櫟檪櫚櫪櫻欅蘖櫺欒欖鬱欟欸欷盜欹飮歇歃歉歐歙歔歛歟歡歸歹歿殀殄殃殍殘殕殞殤殪殫殯殲殱殳殷殼毆毋毓毟毬毫毳毯"],["9f80","麾氈氓气氛氤氣汞汕汢汪沂沍沚沁沛汾汨汳沒沐泄泱泓沽泗泅泝沮沱沾沺泛泯泙泪洟衍洶洫洽洸洙洵洳洒洌浣涓浤浚浹浙涎涕濤涅淹渕渊涵淇淦涸淆淬淞淌淨淒淅淺淙淤淕淪淮渭湮渮渙湲湟渾渣湫渫湶湍渟湃渺湎渤滿渝游溂溪溘滉溷滓溽溯滄溲滔滕溏溥滂溟潁漑灌滬滸滾漿滲漱滯漲滌"],["e040","漾漓滷澆潺潸澁澀潯潛濳潭澂潼潘澎澑濂潦澳澣澡澤澹濆澪濟濕濬濔濘濱濮濛瀉瀋濺瀑瀁瀏濾瀛瀚潴瀝瀘瀟瀰瀾瀲灑灣炙炒炯烱炬炸炳炮烟烋烝"],["e080","烙焉烽焜焙煥煕熈煦煢煌煖煬熏燻熄熕熨熬燗熹熾燒燉燔燎燠燬燧燵燼燹燿爍爐爛爨爭爬爰爲爻爼爿牀牆牋牘牴牾犂犁犇犒犖犢犧犹犲狃狆狄狎狒狢狠狡狹狷倏猗猊猜猖猝猴猯猩猥猾獎獏默獗獪獨獰獸獵獻獺珈玳珎玻珀珥珮珞璢琅瑯琥珸琲琺瑕琿瑟瑙瑁瑜瑩瑰瑣瑪瑶瑾璋璞璧瓊瓏瓔珱"],["e140","瓠瓣瓧瓩瓮瓲瓰瓱瓸瓷甄甃甅甌甎甍甕甓甞甦甬甼畄畍畊畉畛畆畚畩畤畧畫畭畸當疆疇畴疊疉疂疔疚疝疥疣痂疳痃疵疽疸疼疱痍痊痒痙痣痞痾痿"],["e180","痼瘁痰痺痲痳瘋瘍瘉瘟瘧瘠瘡瘢瘤瘴瘰瘻癇癈癆癜癘癡癢癨癩癪癧癬癰癲癶癸發皀皃皈皋皎皖皓皙皚皰皴皸皹皺盂盍盖盒盞盡盥盧盪蘯盻眈眇眄眩眤眞眥眦眛眷眸睇睚睨睫睛睥睿睾睹瞎瞋瞑瞠瞞瞰瞶瞹瞿瞼瞽瞻矇矍矗矚矜矣矮矼砌砒礦砠礪硅碎硴碆硼碚碌碣碵碪碯磑磆磋磔碾碼磅磊磬"],["e240","磧磚磽磴礇礒礑礙礬礫祀祠祗祟祚祕祓祺祿禊禝禧齋禪禮禳禹禺秉秕秧秬秡秣稈稍稘稙稠稟禀稱稻稾稷穃穗穉穡穢穩龝穰穹穽窈窗窕窘窖窩竈窰"],["e280","窶竅竄窿邃竇竊竍竏竕竓站竚竝竡竢竦竭竰笂笏笊笆笳笘笙笞笵笨笶筐筺笄筍笋筌筅筵筥筴筧筰筱筬筮箝箘箟箍箜箚箋箒箏筝箙篋篁篌篏箴篆篝篩簑簔篦篥籠簀簇簓篳篷簗簍篶簣簧簪簟簷簫簽籌籃籔籏籀籐籘籟籤籖籥籬籵粃粐粤粭粢粫粡粨粳粲粱粮粹粽糀糅糂糘糒糜糢鬻糯糲糴糶糺紆"],["e340","紂紜紕紊絅絋紮紲紿紵絆絳絖絎絲絨絮絏絣經綉絛綏絽綛綺綮綣綵緇綽綫總綢綯緜綸綟綰緘緝緤緞緻緲緡縅縊縣縡縒縱縟縉縋縢繆繦縻縵縹繃縷"],["e380","縲縺繧繝繖繞繙繚繹繪繩繼繻纃緕繽辮繿纈纉續纒纐纓纔纖纎纛纜缸缺罅罌罍罎罐网罕罔罘罟罠罨罩罧罸羂羆羃羈羇羌羔羞羝羚羣羯羲羹羮羶羸譱翅翆翊翕翔翡翦翩翳翹飜耆耄耋耒耘耙耜耡耨耿耻聊聆聒聘聚聟聢聨聳聲聰聶聹聽聿肄肆肅肛肓肚肭冐肬胛胥胙胝胄胚胖脉胯胱脛脩脣脯腋"],["e440","隋腆脾腓腑胼腱腮腥腦腴膃膈膊膀膂膠膕膤膣腟膓膩膰膵膾膸膽臀臂膺臉臍臑臙臘臈臚臟臠臧臺臻臾舁舂舅與舊舍舐舖舩舫舸舳艀艙艘艝艚艟艤"],["e480","艢艨艪艫舮艱艷艸艾芍芒芫芟芻芬苡苣苟苒苴苳苺莓范苻苹苞茆苜茉苙茵茴茖茲茱荀茹荐荅茯茫茗茘莅莚莪莟莢莖茣莎莇莊荼莵荳荵莠莉莨菴萓菫菎菽萃菘萋菁菷萇菠菲萍萢萠莽萸蔆菻葭萪萼蕚蒄葷葫蒭葮蒂葩葆萬葯葹萵蓊葢蒹蒿蒟蓙蓍蒻蓚蓐蓁蓆蓖蒡蔡蓿蓴蔗蔘蔬蔟蔕蔔蓼蕀蕣蕘蕈"],["e540","蕁蘂蕋蕕薀薤薈薑薊薨蕭薔薛藪薇薜蕷蕾薐藉薺藏薹藐藕藝藥藜藹蘊蘓蘋藾藺蘆蘢蘚蘰蘿虍乕虔號虧虱蚓蚣蚩蚪蚋蚌蚶蚯蛄蛆蚰蛉蠣蚫蛔蛞蛩蛬"],["e580","蛟蛛蛯蜒蜆蜈蜀蜃蛻蜑蜉蜍蛹蜊蜴蜿蜷蜻蜥蜩蜚蝠蝟蝸蝌蝎蝴蝗蝨蝮蝙蝓蝣蝪蠅螢螟螂螯蟋螽蟀蟐雖螫蟄螳蟇蟆螻蟯蟲蟠蠏蠍蟾蟶蟷蠎蟒蠑蠖蠕蠢蠡蠱蠶蠹蠧蠻衄衂衒衙衞衢衫袁衾袞衵衽袵衲袂袗袒袮袙袢袍袤袰袿袱裃裄裔裘裙裝裹褂裼裴裨裲褄褌褊褓襃褞褥褪褫襁襄褻褶褸襌褝襠襞"],["e640","襦襤襭襪襯襴襷襾覃覈覊覓覘覡覩覦覬覯覲覺覽覿觀觚觜觝觧觴觸訃訖訐訌訛訝訥訶詁詛詒詆詈詼詭詬詢誅誂誄誨誡誑誥誦誚誣諄諍諂諚諫諳諧"],["e680","諤諱謔諠諢諷諞諛謌謇謚諡謖謐謗謠謳鞫謦謫謾謨譁譌譏譎證譖譛譚譫譟譬譯譴譽讀讌讎讒讓讖讙讚谺豁谿豈豌豎豐豕豢豬豸豺貂貉貅貊貍貎貔豼貘戝貭貪貽貲貳貮貶賈賁賤賣賚賽賺賻贄贅贊贇贏贍贐齎贓賍贔贖赧赭赱赳趁趙跂趾趺跏跚跖跌跛跋跪跫跟跣跼踈踉跿踝踞踐踟蹂踵踰踴蹊"],["e740","蹇蹉蹌蹐蹈蹙蹤蹠踪蹣蹕蹶蹲蹼躁躇躅躄躋躊躓躑躔躙躪躡躬躰軆躱躾軅軈軋軛軣軼軻軫軾輊輅輕輒輙輓輜輟輛輌輦輳輻輹轅轂輾轌轉轆轎轗轜"],["e780","轢轣轤辜辟辣辭辯辷迚迥迢迪迯邇迴逅迹迺逑逕逡逍逞逖逋逧逶逵逹迸遏遐遑遒逎遉逾遖遘遞遨遯遶隨遲邂遽邁邀邊邉邏邨邯邱邵郢郤扈郛鄂鄒鄙鄲鄰酊酖酘酣酥酩酳酲醋醉醂醢醫醯醪醵醴醺釀釁釉釋釐釖釟釡釛釼釵釶鈞釿鈔鈬鈕鈑鉞鉗鉅鉉鉤鉈銕鈿鉋鉐銜銖銓銛鉚鋏銹銷鋩錏鋺鍄錮"],["e840","錙錢錚錣錺錵錻鍜鍠鍼鍮鍖鎰鎬鎭鎔鎹鏖鏗鏨鏥鏘鏃鏝鏐鏈鏤鐚鐔鐓鐃鐇鐐鐶鐫鐵鐡鐺鑁鑒鑄鑛鑠鑢鑞鑪鈩鑰鑵鑷鑽鑚鑼鑾钁鑿閂閇閊閔閖閘閙"],["e880","閠閨閧閭閼閻閹閾闊濶闃闍闌闕闔闖關闡闥闢阡阨阮阯陂陌陏陋陷陜陞陝陟陦陲陬隍隘隕隗險隧隱隲隰隴隶隸隹雎雋雉雍襍雜霍雕雹霄霆霈霓霎霑霏霖霙霤霪霰霹霽霾靄靆靈靂靉靜靠靤靦靨勒靫靱靹鞅靼鞁靺鞆鞋鞏鞐鞜鞨鞦鞣鞳鞴韃韆韈韋韜韭齏韲竟韶韵頏頌頸頤頡頷頽顆顏顋顫顯顰"],["e940","顱顴顳颪颯颱颶飄飃飆飩飫餃餉餒餔餘餡餝餞餤餠餬餮餽餾饂饉饅饐饋饑饒饌饕馗馘馥馭馮馼駟駛駝駘駑駭駮駱駲駻駸騁騏騅駢騙騫騷驅驂驀驃"],["e980","騾驕驍驛驗驟驢驥驤驩驫驪骭骰骼髀髏髑髓體髞髟髢髣髦髯髫髮髴髱髷髻鬆鬘鬚鬟鬢鬣鬥鬧鬨鬩鬪鬮鬯鬲魄魃魏魍魎魑魘魴鮓鮃鮑鮖鮗鮟鮠鮨鮴鯀鯊鮹鯆鯏鯑鯒鯣鯢鯤鯔鯡鰺鯲鯱鯰鰕鰔鰉鰓鰌鰆鰈鰒鰊鰄鰮鰛鰥鰤鰡鰰鱇鰲鱆鰾鱚鱠鱧鱶鱸鳧鳬鳰鴉鴈鳫鴃鴆鴪鴦鶯鴣鴟鵄鴕鴒鵁鴿鴾鵆鵈"],["ea40","鵝鵞鵤鵑鵐鵙鵲鶉鶇鶫鵯鵺鶚鶤鶩鶲鷄鷁鶻鶸鶺鷆鷏鷂鷙鷓鷸鷦鷭鷯鷽鸚鸛鸞鹵鹹鹽麁麈麋麌麒麕麑麝麥麩麸麪麭靡黌黎黏黐黔黜點黝黠黥黨黯"],["ea80","黴黶黷黹黻黼黽鼇鼈皷鼕鼡鼬鼾齊齒齔齣齟齠齡齦齧齬齪齷齲齶龕龜龠堯槇遙瑤凜熙"],["ed40","纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏"],["ed80","塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱"],["ee40","犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙"],["ee80","蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"],["eeef","ⅰ",9,"¬¦'""],["f040","",62],["f080","",124],["f140","",62],["f180","",124],["f240","",62],["f280","",124],["f340","",62],["f380","",124],["f440","",62],["f480","",124],["f540","",62],["f580","",124],["f640","",62],["f680","",124],["f740","",62],["f780","",124],["f840","",62],["f880","",124],["f940",""],["fa40","ⅰ",9,"Ⅰ",9,"¬¦'"㈱№℡∵纊褜鍈銈蓜俉炻昱棈鋹曻彅丨仡仼伀伃伹佖侒侊侚侔俍偀倢俿倞偆偰偂傔僴僘兊"],["fa80","兤冝冾凬刕劜劦勀勛匀匇匤卲厓厲叝﨎咜咊咩哿喆坙坥垬埈埇﨏塚增墲夋奓奛奝奣妤妺孖寀甯寘寬尞岦岺峵崧嵓﨑嵂嵭嶸嶹巐弡弴彧德忞恝悅悊惞惕愠惲愑愷愰憘戓抦揵摠撝擎敎昀昕昻昉昮昞昤晥晗晙晴晳暙暠暲暿曺朎朗杦枻桒柀栁桄棏﨓楨﨔榘槢樰橫橆橳橾櫢櫤毖氿汜沆汯泚洄涇浯"],["fb40","涖涬淏淸淲淼渹湜渧渼溿澈澵濵瀅瀇瀨炅炫焏焄煜煆煇凞燁燾犱犾猤猪獷玽珉珖珣珒琇珵琦琪琩琮瑢璉璟甁畯皂皜皞皛皦益睆劯砡硎硤硺礰礼神"],["fb80","祥禔福禛竑竧靖竫箞精絈絜綷綠緖繒罇羡羽茁荢荿菇菶葈蒴蕓蕙蕫﨟薰蘒﨡蠇裵訒訷詹誧誾諟諸諶譓譿賰賴贒赶﨣軏﨤逸遧郞都鄕鄧釚釗釞釭釮釤釥鈆鈐鈊鈺鉀鈼鉎鉙鉑鈹鉧銧鉷鉸鋧鋗鋙鋐﨧鋕鋠鋓錥錡鋻﨨錞鋿錝錂鍰鍗鎤鏆鏞鏸鐱鑅鑈閒隆﨩隝隯霳霻靃靍靏靑靕顗顥飯飼餧館馞驎髙"],["fc40","髜魵魲鮏鮱鮻鰀鵰鵫鶴鸙黑"]]'); + +/***/ }) + +/******/ }); +/************************************************************************/ +/******/ // The module cache +/******/ var __webpack_module_cache__ = {}; +/******/ +/******/ // The require function +/******/ function __nccwpck_require__(moduleId) { +/******/ // Check if module is in cache +/******/ var cachedModule = __webpack_module_cache__[moduleId]; +/******/ if (cachedModule !== undefined) { +/******/ return cachedModule.exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = __webpack_module_cache__[moduleId] = { +/******/ // no module.id needed +/******/ // no module.loaded needed +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ var threw = true; +/******/ try { +/******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __nccwpck_require__); +/******/ threw = false; +/******/ } finally { +/******/ if(threw) delete __webpack_module_cache__[moduleId]; +/******/ } +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __nccwpck_require__.m = __webpack_modules__; +/******/ +/************************************************************************/ +/******/ /* webpack/runtime/define property getters */ +/******/ (() => { +/******/ // define getter functions for harmony exports +/******/ __nccwpck_require__.d = (exports, definition) => { +/******/ for(var key in definition) { +/******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) { +/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] }); +/******/ } +/******/ } +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/ensure chunk */ +/******/ (() => { +/******/ __nccwpck_require__.f = {}; +/******/ // This file contains only the entry chunk. +/******/ // The chunk loading function for additional chunks +/******/ __nccwpck_require__.e = (chunkId) => { +/******/ return Promise.all(Object.keys(__nccwpck_require__.f).reduce((promises, key) => { +/******/ __nccwpck_require__.f[key](chunkId, promises); +/******/ return promises; +/******/ }, [])); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/get javascript chunk filename */ +/******/ (() => { +/******/ // This function allow to reference async chunks +/******/ __nccwpck_require__.u = (chunkId) => { +/******/ // return url for filenames based on template +/******/ return "" + chunkId + ".index.js"; +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/hasOwnProperty shorthand */ +/******/ (() => { +/******/ __nccwpck_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) +/******/ })(); +/******/ +/******/ /* webpack/runtime/make namespace object */ +/******/ (() => { +/******/ // define __esModule on exports +/******/ __nccwpck_require__.r = (exports) => { +/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { +/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); +/******/ } +/******/ Object.defineProperty(exports, '__esModule', { value: true }); +/******/ }; +/******/ })(); +/******/ +/******/ /* webpack/runtime/compat */ +/******/ +/******/ if (typeof __nccwpck_require__ !== 'undefined') __nccwpck_require__.ab = new URL('.', import.meta.url).pathname.slice(import.meta.url.match(/^file:\/\/\/\w:/) ? 1 : 0, -1) + "/"; +/******/ +/******/ /* webpack/runtime/import chunk loading */ +/******/ (() => { +/******/ // no baseURI +/******/ +/******/ // object to store loaded and loading chunks +/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched +/******/ // [resolve, reject, Promise] = chunk loading, 0 = chunk loaded +/******/ var installedChunks = { +/******/ 179: 0 +/******/ }; +/******/ +/******/ var installChunk = (data) => { +/******/ var {ids, modules, runtime} = data; +/******/ // add "modules" to the modules object, +/******/ // then flag all "ids" as loaded and fire callback +/******/ var moduleId, chunkId, i = 0; +/******/ for(moduleId in modules) { +/******/ if(__nccwpck_require__.o(modules, moduleId)) { +/******/ __nccwpck_require__.m[moduleId] = modules[moduleId]; +/******/ } +/******/ } +/******/ if(runtime) runtime(__nccwpck_require__); +/******/ for(;i < ids.length; i++) { +/******/ chunkId = ids[i]; +/******/ if(__nccwpck_require__.o(installedChunks, chunkId) && installedChunks[chunkId]) { +/******/ installedChunks[chunkId][0](); +/******/ } +/******/ installedChunks[ids[i]] = 0; +/******/ } +/******/ +/******/ } +/******/ +/******/ __nccwpck_require__.f.j = (chunkId, promises) => { +/******/ // import() chunk loading for javascript +/******/ var installedChunkData = __nccwpck_require__.o(installedChunks, chunkId) ? installedChunks[chunkId] : undefined; +/******/ if(installedChunkData !== 0) { // 0 means "already installed". +/******/ +/******/ // a Promise means "currently loading". +/******/ if(installedChunkData) { +/******/ promises.push(installedChunkData[1]); +/******/ } else { +/******/ if(true) { // all chunks have JS +/******/ // setup Promise in chunk cache +/******/ var promise = import("./" + __nccwpck_require__.u(chunkId)).then(installChunk, (e) => { +/******/ if(installedChunks[chunkId] !== 0) installedChunks[chunkId] = undefined; +/******/ throw e; +/******/ }); +/******/ var promise = Promise.race([promise, new Promise((resolve) => (installedChunkData = installedChunks[chunkId] = [resolve]))]) +/******/ promises.push(installedChunkData[1] = promise); +/******/ } else installedChunks[chunkId] = 0; +/******/ } +/******/ } +/******/ }; +/******/ +/******/ // no external install chunk +/******/ +/******/ // no on chunks loaded +/******/ })(); +/******/ +/************************************************************************/ +var __webpack_exports__ = {}; +// This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. +(() => { + +// EXTERNAL MODULE: ./node_modules/@actions/core/lib/core.js +var core = __nccwpck_require__(2186); +// EXTERNAL MODULE: ./node_modules/@actions/github/lib/github.js +var github = __nccwpck_require__(5438); +// EXTERNAL MODULE: ./node_modules/hasha/index.js +var hasha = __nccwpck_require__(4933); +;// CONCATENATED MODULE: external "node:http" +const external_node_http_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:http"); +;// CONCATENATED MODULE: external "node:https" +const external_node_https_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:https"); +;// CONCATENATED MODULE: external "node:zlib" +const external_node_zlib_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:zlib"); +;// CONCATENATED MODULE: external "node:stream" +const external_node_stream_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:stream"); +;// CONCATENATED MODULE: external "node:buffer" +const external_node_buffer_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:buffer"); +;// CONCATENATED MODULE: ./node_modules/data-uri-to-buffer/dist/index.js +/** + * Returns a `Buffer` instance from the given data URI `uri`. + * + * @param {String} uri Data URI to turn into a Buffer instance + * @returns {Buffer} Buffer instance from Data URI + * @api public + */ +function dataUriToBuffer(uri) { + if (!/^data:/i.test(uri)) { + throw new TypeError('`uri` does not appear to be a Data URI (must begin with "data:")'); + } + // strip newlines + uri = uri.replace(/\r?\n/g, ''); + // split the URI up into the "metadata" and the "data" portions + const firstComma = uri.indexOf(','); + if (firstComma === -1 || firstComma <= 4) { + throw new TypeError('malformed data: URI'); + } + // remove the "data:" scheme and parse the metadata + const meta = uri.substring(5, firstComma).split(';'); + let charset = ''; + let base64 = false; + const type = meta[0] || 'text/plain'; + let typeFull = type; + for (let i = 1; i < meta.length; i++) { + if (meta[i] === 'base64') { + base64 = true; + } + else if (meta[i]) { + typeFull += `;${meta[i]}`; + if (meta[i].indexOf('charset=') === 0) { + charset = meta[i].substring(8); + } + } + } + // defaults to US-ASCII only if type is not provided + if (!meta[0] && !charset.length) { + typeFull += ';charset=US-ASCII'; + charset = 'US-ASCII'; + } + // get the encoded data portion and decode URI-encoded chars + const encoding = base64 ? 'base64' : 'ascii'; + const data = unescape(uri.substring(firstComma + 1)); + const buffer = Buffer.from(data, encoding); + // set `.type` and `.typeFull` properties to MIME type + buffer.type = type; + buffer.typeFull = typeFull; + // set the `.charset` property + buffer.charset = charset; + return buffer; +} +/* harmony default export */ const dist = (dataUriToBuffer); +//# sourceMappingURL=index.js.map +;// CONCATENATED MODULE: external "node:util" +const external_node_util_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:util"); +// EXTERNAL MODULE: ./node_modules/fetch-blob/index.js +var fetch_blob = __nccwpck_require__(1410); +// EXTERNAL MODULE: ./node_modules/formdata-polyfill/esm.min.js +var esm_min = __nccwpck_require__(8010); +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/errors/base.js +class FetchBaseError extends Error { + constructor(message, type) { + super(message); + // Hide custom error implementation details from end-users + Error.captureStackTrace(this, this.constructor); + + this.type = type; + } + + get name() { + return this.constructor.name; + } + + get [Symbol.toStringTag]() { + return this.constructor.name; + } +} + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/errors/fetch-error.js + + + +/** + * @typedef {{ address?: string, code: string, dest?: string, errno: number, info?: object, message: string, path?: string, port?: number, syscall: string}} SystemError +*/ + +/** + * FetchError interface for operational errors + */ +class FetchError extends FetchBaseError { + /** + * @param {string} message - Error message for human + * @param {string} [type] - Error type for machine + * @param {SystemError} [systemError] - For Node.js system error + */ + constructor(message, type, systemError) { + super(message, type); + // When err.type is `system`, err.erroredSysCall contains system error and err.code contains system error code + if (systemError) { + // eslint-disable-next-line no-multi-assign + this.code = this.errno = systemError.code; + this.erroredSysCall = systemError.syscall; + } + } +} + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/utils/is.js +/** + * Is.js + * + * Object type checks. + */ + +const NAME = Symbol.toStringTag; + +/** + * Check if `obj` is a URLSearchParams object + * ref: https://github.com/node-fetch/node-fetch/issues/296#issuecomment-307598143 + * @param {*} object - Object to check for + * @return {boolean} + */ +const isURLSearchParameters = object => { + return ( + typeof object === 'object' && + typeof object.append === 'function' && + typeof object.delete === 'function' && + typeof object.get === 'function' && + typeof object.getAll === 'function' && + typeof object.has === 'function' && + typeof object.set === 'function' && + typeof object.sort === 'function' && + object[NAME] === 'URLSearchParams' + ); +}; + +/** + * Check if `object` is a W3C `Blob` object (which `File` inherits from) + * @param {*} object - Object to check for + * @return {boolean} + */ +const isBlob = object => { + return ( + object && + typeof object === 'object' && + typeof object.arrayBuffer === 'function' && + typeof object.type === 'string' && + typeof object.stream === 'function' && + typeof object.constructor === 'function' && + /^(Blob|File)$/.test(object[NAME]) + ); +}; + +/** + * Check if `obj` is an instance of AbortSignal. + * @param {*} object - Object to check for + * @return {boolean} + */ +const isAbortSignal = object => { + return ( + typeof object === 'object' && ( + object[NAME] === 'AbortSignal' || + object[NAME] === 'EventTarget' + ) + ); +}; + +/** + * isDomainOrSubdomain reports whether sub is a subdomain (or exact match) of + * the parent domain. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isDomainOrSubdomain = (destination, original) => { + const orig = new URL(original).hostname; + const dest = new URL(destination).hostname; + + return orig === dest || orig.endsWith(`.${dest}`); +}; + +/** + * isSameProtocol reports whether the two provided URLs use the same protocol. + * + * Both domains must already be in canonical form. + * @param {string|URL} original + * @param {string|URL} destination + */ +const isSameProtocol = (destination, original) => { + const orig = new URL(original).protocol; + const dest = new URL(destination).protocol; + + return orig === dest; +}; + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/body.js + +/** + * Body.js + * + * Body interface provides common methods for Request and Response + */ + + + + + + + + + + + + +const pipeline = (0,external_node_util_namespaceObject.promisify)(external_node_stream_namespaceObject.pipeline); +const INTERNALS = Symbol('Body internals'); + +/** + * Body mixin + * + * Ref: https://fetch.spec.whatwg.org/#body + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Body { + constructor(body, { + size = 0 + } = {}) { + let boundary = null; + + if (body === null) { + // Body is undefined or null + body = null; + } else if (isURLSearchParameters(body)) { + // Body is a URLSearchParams + body = external_node_buffer_namespaceObject.Buffer.from(body.toString()); + } else if (isBlob(body)) { + // Body is blob + } else if (external_node_buffer_namespaceObject.Buffer.isBuffer(body)) { + // Body is Buffer + } else if (external_node_util_namespaceObject.types.isAnyArrayBuffer(body)) { + // Body is ArrayBuffer + body = external_node_buffer_namespaceObject.Buffer.from(body); + } else if (ArrayBuffer.isView(body)) { + // Body is ArrayBufferView + body = external_node_buffer_namespaceObject.Buffer.from(body.buffer, body.byteOffset, body.byteLength); + } else if (body instanceof external_node_stream_namespaceObject) { + // Body is stream + } else if (body instanceof esm_min/* FormData */.Ct) { + // Body is FormData + body = (0,esm_min/* formDataToBlob */.au)(body); + boundary = body.type.split('=')[1]; + } else { + // None of the above + // coerce to string then buffer + body = external_node_buffer_namespaceObject.Buffer.from(String(body)); + } + + let stream = body; + + if (external_node_buffer_namespaceObject.Buffer.isBuffer(body)) { + stream = external_node_stream_namespaceObject.Readable.from(body); + } else if (isBlob(body)) { + stream = external_node_stream_namespaceObject.Readable.from(body.stream()); + } + + this[INTERNALS] = { + body, + stream, + boundary, + disturbed: false, + error: null + }; + this.size = size; + + if (body instanceof external_node_stream_namespaceObject) { + body.on('error', error_ => { + const error = error_ instanceof FetchBaseError ? + error_ : + new FetchError(`Invalid response body while trying to fetch ${this.url}: ${error_.message}`, 'system', error_); + this[INTERNALS].error = error; + }); + } + } + + get body() { + return this[INTERNALS].stream; + } + + get bodyUsed() { + return this[INTERNALS].disturbed; + } + + /** + * Decode response as ArrayBuffer + * + * @return Promise + */ + async arrayBuffer() { + const {buffer, byteOffset, byteLength} = await consumeBody(this); + return buffer.slice(byteOffset, byteOffset + byteLength); + } + + async formData() { + const ct = this.headers.get('content-type'); + + if (ct.startsWith('application/x-www-form-urlencoded')) { + const formData = new esm_min/* FormData */.Ct(); + const parameters = new URLSearchParams(await this.text()); + + for (const [name, value] of parameters) { + formData.append(name, value); + } + + return formData; + } + + const {toFormData} = await __nccwpck_require__.e(/* import() */ 37).then(__nccwpck_require__.bind(__nccwpck_require__, 4037)); + return toFormData(this.body, ct); + } + + /** + * Return raw response as Blob + * + * @return Promise + */ + async blob() { + const ct = (this.headers && this.headers.get('content-type')) || (this[INTERNALS].body && this[INTERNALS].body.type) || ''; + const buf = await this.arrayBuffer(); + + return new fetch_blob/* default */.Z([buf], { + type: ct + }); + } + + /** + * Decode response as json + * + * @return Promise + */ + async json() { + const text = await this.text(); + return JSON.parse(text); + } + + /** + * Decode response as text + * + * @return Promise + */ + async text() { + const buffer = await consumeBody(this); + return new TextDecoder().decode(buffer); + } + + /** + * Decode response as buffer (non-spec api) + * + * @return Promise + */ + buffer() { + return consumeBody(this); + } +} + +Body.prototype.buffer = (0,external_node_util_namespaceObject.deprecate)(Body.prototype.buffer, 'Please use \'response.arrayBuffer()\' instead of \'response.buffer()\'', 'node-fetch#buffer'); + +// In browsers, all properties are enumerable. +Object.defineProperties(Body.prototype, { + body: {enumerable: true}, + bodyUsed: {enumerable: true}, + arrayBuffer: {enumerable: true}, + blob: {enumerable: true}, + json: {enumerable: true}, + text: {enumerable: true}, + data: {get: (0,external_node_util_namespaceObject.deprecate)(() => {}, + 'data doesn\'t exist, use json(), text(), arrayBuffer(), or body instead', + 'https://github.com/node-fetch/node-fetch/issues/1000 (response)')} +}); + +/** + * Consume and convert an entire Body to a Buffer. + * + * Ref: https://fetch.spec.whatwg.org/#concept-body-consume-body + * + * @return Promise + */ +async function consumeBody(data) { + if (data[INTERNALS].disturbed) { + throw new TypeError(`body used already for: ${data.url}`); + } + + data[INTERNALS].disturbed = true; + + if (data[INTERNALS].error) { + throw data[INTERNALS].error; + } + + const {body} = data; + + // Body is null + if (body === null) { + return external_node_buffer_namespaceObject.Buffer.alloc(0); + } + + /* c8 ignore next 3 */ + if (!(body instanceof external_node_stream_namespaceObject)) { + return external_node_buffer_namespaceObject.Buffer.alloc(0); + } + + // Body is stream + // get ready to actually consume the body + const accum = []; + let accumBytes = 0; + + try { + for await (const chunk of body) { + if (data.size > 0 && accumBytes + chunk.length > data.size) { + const error = new FetchError(`content size at ${data.url} over limit: ${data.size}`, 'max-size'); + body.destroy(error); + throw error; + } + + accumBytes += chunk.length; + accum.push(chunk); + } + } catch (error) { + const error_ = error instanceof FetchBaseError ? error : new FetchError(`Invalid response body while trying to fetch ${data.url}: ${error.message}`, 'system', error); + throw error_; + } + + if (body.readableEnded === true || body._readableState.ended === true) { + try { + if (accum.every(c => typeof c === 'string')) { + return external_node_buffer_namespaceObject.Buffer.from(accum.join('')); + } + + return external_node_buffer_namespaceObject.Buffer.concat(accum, accumBytes); + } catch (error) { + throw new FetchError(`Could not create Buffer from response body for ${data.url}: ${error.message}`, 'system', error); + } + } else { + throw new FetchError(`Premature close of server response while trying to fetch ${data.url}`); + } +} + +/** + * Clone body given Res/Req instance + * + * @param Mixed instance Response or Request instance + * @param String highWaterMark highWaterMark for both PassThrough body streams + * @return Mixed + */ +const clone = (instance, highWaterMark) => { + let p1; + let p2; + let {body} = instance[INTERNALS]; + + // Don't allow cloning a used body + if (instance.bodyUsed) { + throw new Error('cannot clone body after it is used'); + } + + // Check that body is a stream and not form-data object + // note: we can't clone the form-data object without having it as a dependency + if ((body instanceof external_node_stream_namespaceObject) && (typeof body.getBoundary !== 'function')) { + // Tee instance body + p1 = new external_node_stream_namespaceObject.PassThrough({highWaterMark}); + p2 = new external_node_stream_namespaceObject.PassThrough({highWaterMark}); + body.pipe(p1); + body.pipe(p2); + // Set instance body to teed body and return the other teed body + instance[INTERNALS].stream = p1; + body = p2; + } + + return body; +}; + +const getNonSpecFormDataBoundary = (0,external_node_util_namespaceObject.deprecate)( + body => body.getBoundary(), + 'form-data doesn\'t follow the spec and requires special treatment. Use alternative package', + 'https://github.com/node-fetch/node-fetch/issues/1167' +); + +/** + * Performs the operation "extract a `Content-Type` value from |object|" as + * specified in the specification: + * https://fetch.spec.whatwg.org/#concept-bodyinit-extract + * + * This function assumes that instance.body is present. + * + * @param {any} body Any options.body input + * @returns {string | null} + */ +const extractContentType = (body, request) => { + // Body is null or undefined + if (body === null) { + return null; + } + + // Body is string + if (typeof body === 'string') { + return 'text/plain;charset=UTF-8'; + } + + // Body is a URLSearchParams + if (isURLSearchParameters(body)) { + return 'application/x-www-form-urlencoded;charset=UTF-8'; + } + + // Body is blob + if (isBlob(body)) { + return body.type || null; + } + + // Body is a Buffer (Buffer, ArrayBuffer or ArrayBufferView) + if (external_node_buffer_namespaceObject.Buffer.isBuffer(body) || external_node_util_namespaceObject.types.isAnyArrayBuffer(body) || ArrayBuffer.isView(body)) { + return null; + } + + if (body instanceof esm_min/* FormData */.Ct) { + return `multipart/form-data; boundary=${request[INTERNALS].boundary}`; + } + + // Detect form data input from form-data module + if (body && typeof body.getBoundary === 'function') { + return `multipart/form-data;boundary=${getNonSpecFormDataBoundary(body)}`; + } + + // Body is stream - can't really do much about this + if (body instanceof external_node_stream_namespaceObject) { + return null; + } + + // Body constructor defaults other things to string + return 'text/plain;charset=UTF-8'; +}; + +/** + * The Fetch Standard treats this as if "total bytes" is a property on the body. + * For us, we have to explicitly get it with a function. + * + * ref: https://fetch.spec.whatwg.org/#concept-body-total-bytes + * + * @param {any} obj.body Body object from the Body instance. + * @returns {number | null} + */ +const getTotalBytes = request => { + const {body} = request[INTERNALS]; + + // Body is null or undefined + if (body === null) { + return 0; + } + + // Body is Blob + if (isBlob(body)) { + return body.size; + } + + // Body is Buffer + if (external_node_buffer_namespaceObject.Buffer.isBuffer(body)) { + return body.length; + } + + // Detect form data input from form-data module + if (body && typeof body.getLengthSync === 'function') { + return body.hasKnownLength && body.hasKnownLength() ? body.getLengthSync() : null; + } + + // Body is stream + return null; +}; + +/** + * Write a Body to a Node.js WritableStream (e.g. http.Request) object. + * + * @param {Stream.Writable} dest The stream to write to. + * @param obj.body Body object from the Body instance. + * @returns {Promise<void>} + */ +const writeToStream = async (dest, {body}) => { + if (body === null) { + // Body is null + dest.end(); + } else { + // Body is stream + await pipeline(body, dest); + } +}; + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/headers.js +/** + * Headers.js + * + * Headers class offers convenient helpers + */ + + + + +/* c8 ignore next 9 */ +const validateHeaderName = typeof external_node_http_namespaceObject.validateHeaderName === 'function' ? + external_node_http_namespaceObject.validateHeaderName : + name => { + if (!/^[\^`\-\w!#$%&'*+.|~]+$/.test(name)) { + const error = new TypeError(`Header name must be a valid HTTP token [${name}]`); + Object.defineProperty(error, 'code', {value: 'ERR_INVALID_HTTP_TOKEN'}); + throw error; + } + }; + +/* c8 ignore next 9 */ +const validateHeaderValue = typeof external_node_http_namespaceObject.validateHeaderValue === 'function' ? + external_node_http_namespaceObject.validateHeaderValue : + (name, value) => { + if (/[^\t\u0020-\u007E\u0080-\u00FF]/.test(value)) { + const error = new TypeError(`Invalid character in header content ["${name}"]`); + Object.defineProperty(error, 'code', {value: 'ERR_INVALID_CHAR'}); + throw error; + } + }; + +/** + * @typedef {Headers | Record<string, string> | Iterable<readonly [string, string]> | Iterable<Iterable<string>>} HeadersInit + */ + +/** + * This Fetch API interface allows you to perform various actions on HTTP request and response headers. + * These actions include retrieving, setting, adding to, and removing. + * A Headers object has an associated header list, which is initially empty and consists of zero or more name and value pairs. + * You can add to this using methods like append() (see Examples.) + * In all methods of this interface, header names are matched by case-insensitive byte sequence. + * + */ +class Headers extends URLSearchParams { + /** + * Headers class + * + * @constructor + * @param {HeadersInit} [init] - Response headers + */ + constructor(init) { + // Validate and normalize init object in [name, value(s)][] + /** @type {string[][]} */ + let result = []; + if (init instanceof Headers) { + const raw = init.raw(); + for (const [name, values] of Object.entries(raw)) { + result.push(...values.map(value => [name, value])); + } + } else if (init == null) { // eslint-disable-line no-eq-null, eqeqeq + // No op + } else if (typeof init === 'object' && !external_node_util_namespaceObject.types.isBoxedPrimitive(init)) { + const method = init[Symbol.iterator]; + // eslint-disable-next-line no-eq-null, eqeqeq + if (method == null) { + // Record<ByteString, ByteString> + result.push(...Object.entries(init)); + } else { + if (typeof method !== 'function') { + throw new TypeError('Header pairs must be iterable'); + } + + // Sequence<sequence<ByteString>> + // Note: per spec we have to first exhaust the lists then process them + result = [...init] + .map(pair => { + if ( + typeof pair !== 'object' || external_node_util_namespaceObject.types.isBoxedPrimitive(pair) + ) { + throw new TypeError('Each header pair must be an iterable object'); + } + + return [...pair]; + }).map(pair => { + if (pair.length !== 2) { + throw new TypeError('Each header pair must be a name/value tuple'); + } + + return [...pair]; + }); + } + } else { + throw new TypeError('Failed to construct \'Headers\': The provided value is not of type \'(sequence<sequence<ByteString>> or record<ByteString, ByteString>)'); + } + + // Validate and lowercase + result = + result.length > 0 ? + result.map(([name, value]) => { + validateHeaderName(name); + validateHeaderValue(name, String(value)); + return [String(name).toLowerCase(), String(value)]; + }) : + undefined; + + super(result); + + // Returning a Proxy that will lowercase key names, validate parameters and sort keys + // eslint-disable-next-line no-constructor-return + return new Proxy(this, { + get(target, p, receiver) { + switch (p) { + case 'append': + case 'set': + return (name, value) => { + validateHeaderName(name); + validateHeaderValue(name, String(value)); + return URLSearchParams.prototype[p].call( + target, + String(name).toLowerCase(), + String(value) + ); + }; + + case 'delete': + case 'has': + case 'getAll': + return name => { + validateHeaderName(name); + return URLSearchParams.prototype[p].call( + target, + String(name).toLowerCase() + ); + }; + + case 'keys': + return () => { + target.sort(); + return new Set(URLSearchParams.prototype.keys.call(target)).keys(); + }; + + default: + return Reflect.get(target, p, receiver); + } + } + }); + /* c8 ignore next */ + } + + get [Symbol.toStringTag]() { + return this.constructor.name; + } + + toString() { + return Object.prototype.toString.call(this); + } + + get(name) { + const values = this.getAll(name); + if (values.length === 0) { + return null; + } + + let value = values.join(', '); + if (/^content-encoding$/i.test(name)) { + value = value.toLowerCase(); + } + + return value; + } + + forEach(callback, thisArg = undefined) { + for (const name of this.keys()) { + Reflect.apply(callback, thisArg, [this.get(name), name, this]); + } + } + + * values() { + for (const name of this.keys()) { + yield this.get(name); + } + } + + /** + * @type {() => IterableIterator<[string, string]>} + */ + * entries() { + for (const name of this.keys()) { + yield [name, this.get(name)]; + } + } + + [Symbol.iterator]() { + return this.entries(); + } + + /** + * Node-fetch non-spec method + * returning all headers and their values as array + * @returns {Record<string, string[]>} + */ + raw() { + return [...this.keys()].reduce((result, key) => { + result[key] = this.getAll(key); + return result; + }, {}); + } + + /** + * For better console.log(headers) and also to convert Headers into Node.js Request compatible format + */ + [Symbol.for('nodejs.util.inspect.custom')]() { + return [...this.keys()].reduce((result, key) => { + const values = this.getAll(key); + // Http.request() only supports string as Host header. + // This hack makes specifying custom Host header possible. + if (key === 'host') { + result[key] = values[0]; + } else { + result[key] = values.length > 1 ? values : values[0]; + } + + return result; + }, {}); + } +} + +/** + * Re-shaping object for Web IDL tests + * Only need to do it for overridden methods + */ +Object.defineProperties( + Headers.prototype, + ['get', 'entries', 'forEach', 'values'].reduce((result, property) => { + result[property] = {enumerable: true}; + return result; + }, {}) +); + +/** + * Create a Headers object from an http.IncomingMessage.rawHeaders, ignoring those that do + * not conform to HTTP grammar productions. + * @param {import('http').IncomingMessage['rawHeaders']} headers + */ +function fromRawHeaders(headers = []) { + return new Headers( + headers + // Split into pairs + .reduce((result, value, index, array) => { + if (index % 2 === 0) { + result.push(array.slice(index, index + 2)); + } + + return result; + }, []) + .filter(([name, value]) => { + try { + validateHeaderName(name); + validateHeaderValue(name, String(value)); + return true; + } catch { + return false; + } + }) + + ); +} + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/utils/is-redirect.js +const redirectStatus = new Set([301, 302, 303, 307, 308]); + +/** + * Redirect code matching + * + * @param {number} code - Status code + * @return {boolean} + */ +const isRedirect = code => { + return redirectStatus.has(code); +}; + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/response.js +/** + * Response.js + * + * Response class provides content decoding + */ + + + + + +const response_INTERNALS = Symbol('Response internals'); + +/** + * Response class + * + * Ref: https://fetch.spec.whatwg.org/#response-class + * + * @param Stream body Readable stream + * @param Object opts Response options + * @return Void + */ +class Response extends Body { + constructor(body = null, options = {}) { + super(body, options); + + // eslint-disable-next-line no-eq-null, eqeqeq, no-negated-condition + const status = options.status != null ? options.status : 200; + + const headers = new Headers(options.headers); + + if (body !== null && !headers.has('Content-Type')) { + const contentType = extractContentType(body, this); + if (contentType) { + headers.append('Content-Type', contentType); + } + } + + this[response_INTERNALS] = { + type: 'default', + url: options.url, + status, + statusText: options.statusText || '', + headers, + counter: options.counter, + highWaterMark: options.highWaterMark + }; + } + + get type() { + return this[response_INTERNALS].type; + } + + get url() { + return this[response_INTERNALS].url || ''; + } + + get status() { + return this[response_INTERNALS].status; + } + + /** + * Convenience property representing if the request ended normally + */ + get ok() { + return this[response_INTERNALS].status >= 200 && this[response_INTERNALS].status < 300; + } + + get redirected() { + return this[response_INTERNALS].counter > 0; + } + + get statusText() { + return this[response_INTERNALS].statusText; + } + + get headers() { + return this[response_INTERNALS].headers; + } + + get highWaterMark() { + return this[response_INTERNALS].highWaterMark; + } + + /** + * Clone this response + * + * @return Response + */ + clone() { + return new Response(clone(this, this.highWaterMark), { + type: this.type, + url: this.url, + status: this.status, + statusText: this.statusText, + headers: this.headers, + ok: this.ok, + redirected: this.redirected, + size: this.size, + highWaterMark: this.highWaterMark + }); + } + + /** + * @param {string} url The URL that the new response is to originate from. + * @param {number} status An optional status code for the response (e.g., 302.) + * @returns {Response} A Response object. + */ + static redirect(url, status = 302) { + if (!isRedirect(status)) { + throw new RangeError('Failed to execute "redirect" on "response": Invalid status code'); + } + + return new Response(null, { + headers: { + location: new URL(url).toString() + }, + status + }); + } + + static error() { + const response = new Response(null, {status: 0, statusText: ''}); + response[response_INTERNALS].type = 'error'; + return response; + } + + static json(data = undefined, init = {}) { + const body = JSON.stringify(data); + + if (body === undefined) { + throw new TypeError('data is not JSON serializable'); + } + + const headers = new Headers(init && init.headers); + + if (!headers.has('content-type')) { + headers.set('content-type', 'application/json'); + } + + return new Response(body, { + ...init, + headers + }); + } + + get [Symbol.toStringTag]() { + return 'Response'; + } +} + +Object.defineProperties(Response.prototype, { + type: {enumerable: true}, + url: {enumerable: true}, + status: {enumerable: true}, + ok: {enumerable: true}, + redirected: {enumerable: true}, + statusText: {enumerable: true}, + headers: {enumerable: true}, + clone: {enumerable: true} +}); + +;// CONCATENATED MODULE: external "node:url" +const external_node_url_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:url"); +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/utils/get-search.js +const getSearch = parsedURL => { + if (parsedURL.search) { + return parsedURL.search; + } + + const lastOffset = parsedURL.href.length - 1; + const hash = parsedURL.hash || (parsedURL.href[lastOffset] === '#' ? '#' : ''); + return parsedURL.href[lastOffset - hash.length] === '?' ? '?' : ''; +}; + +;// CONCATENATED MODULE: external "node:net" +const external_node_net_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("node:net"); +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/utils/referrer.js + + +/** + * @external URL + * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/URL|URL} + */ + +/** + * @module utils/referrer + * @private + */ + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#strip-url|Referrer Policy §8.4. Strip url for use as a referrer} + * @param {string} URL + * @param {boolean} [originOnly=false] + */ +function stripURLForUseAsAReferrer(url, originOnly = false) { + // 1. If url is null, return no referrer. + if (url == null) { // eslint-disable-line no-eq-null, eqeqeq + return 'no-referrer'; + } + + url = new URL(url); + + // 2. If url's scheme is a local scheme, then return no referrer. + if (/^(about|blob|data):$/.test(url.protocol)) { + return 'no-referrer'; + } + + // 3. Set url's username to the empty string. + url.username = ''; + + // 4. Set url's password to null. + // Note: `null` appears to be a mistake as this actually results in the password being `"null"`. + url.password = ''; + + // 5. Set url's fragment to null. + // Note: `null` appears to be a mistake as this actually results in the fragment being `"#null"`. + url.hash = ''; + + // 6. If the origin-only flag is true, then: + if (originOnly) { + // 6.1. Set url's path to null. + // Note: `null` appears to be a mistake as this actually results in the path being `"/null"`. + url.pathname = ''; + + // 6.2. Set url's query to null. + // Note: `null` appears to be a mistake as this actually results in the query being `"?null"`. + url.search = ''; + } + + // 7. Return url. + return url; +} + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#enumdef-referrerpolicy|enum ReferrerPolicy} + */ +const ReferrerPolicy = new Set([ + '', + 'no-referrer', + 'no-referrer-when-downgrade', + 'same-origin', + 'origin', + 'strict-origin', + 'origin-when-cross-origin', + 'strict-origin-when-cross-origin', + 'unsafe-url' +]); + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#default-referrer-policy|default referrer policy} + */ +const DEFAULT_REFERRER_POLICY = 'strict-origin-when-cross-origin'; + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#referrer-policies|Referrer Policy §3. Referrer Policies} + * @param {string} referrerPolicy + * @returns {string} referrerPolicy + */ +function validateReferrerPolicy(referrerPolicy) { + if (!ReferrerPolicy.has(referrerPolicy)) { + throw new TypeError(`Invalid referrerPolicy: ${referrerPolicy}`); + } + + return referrerPolicy; +} + +/** + * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-origin-trustworthy|Referrer Policy §3.2. Is origin potentially trustworthy?} + * @param {external:URL} url + * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy" + */ +function isOriginPotentiallyTrustworthy(url) { + // 1. If origin is an opaque origin, return "Not Trustworthy". + // Not applicable + + // 2. Assert: origin is a tuple origin. + // Not for implementations + + // 3. If origin's scheme is either "https" or "wss", return "Potentially Trustworthy". + if (/^(http|ws)s:$/.test(url.protocol)) { + return true; + } + + // 4. If origin's host component matches one of the CIDR notations 127.0.0.0/8 or ::1/128 [RFC4632], return "Potentially Trustworthy". + const hostIp = url.host.replace(/(^\[)|(]$)/g, ''); + const hostIPVersion = (0,external_node_net_namespaceObject.isIP)(hostIp); + + if (hostIPVersion === 4 && /^127\./.test(hostIp)) { + return true; + } + + if (hostIPVersion === 6 && /^(((0+:){7})|(::(0+:){0,6}))0*1$/.test(hostIp)) { + return true; + } + + // 5. If origin's host component is "localhost" or falls within ".localhost", and the user agent conforms to the name resolution rules in [let-localhost-be-localhost], return "Potentially Trustworthy". + // We are returning FALSE here because we cannot ensure conformance to + // let-localhost-be-loalhost (https://tools.ietf.org/html/draft-west-let-localhost-be-localhost) + if (url.host === 'localhost' || url.host.endsWith('.localhost')) { + return false; + } + + // 6. If origin's scheme component is file, return "Potentially Trustworthy". + if (url.protocol === 'file:') { + return true; + } + + // 7. If origin's scheme component is one which the user agent considers to be authenticated, return "Potentially Trustworthy". + // Not supported + + // 8. If origin has been configured as a trustworthy origin, return "Potentially Trustworthy". + // Not supported + + // 9. Return "Not Trustworthy". + return false; +} + +/** + * @see {@link https://w3c.github.io/webappsec-secure-contexts/#is-url-trustworthy|Referrer Policy §3.3. Is url potentially trustworthy?} + * @param {external:URL} url + * @returns `true`: "Potentially Trustworthy", `false`: "Not Trustworthy" + */ +function isUrlPotentiallyTrustworthy(url) { + // 1. If url is "about:blank" or "about:srcdoc", return "Potentially Trustworthy". + if (/^about:(blank|srcdoc)$/.test(url)) { + return true; + } + + // 2. If url's scheme is "data", return "Potentially Trustworthy". + if (url.protocol === 'data:') { + return true; + } + + // Note: The origin of blob: and filesystem: URLs is the origin of the context in which they were + // created. Therefore, blobs created in a trustworthy origin will themselves be potentially + // trustworthy. + if (/^(blob|filesystem):$/.test(url.protocol)) { + return true; + } + + // 3. Return the result of executing §3.2 Is origin potentially trustworthy? on url's origin. + return isOriginPotentiallyTrustworthy(url); +} + +/** + * Modifies the referrerURL to enforce any extra security policy considerations. + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7 + * @callback module:utils/referrer~referrerURLCallback + * @param {external:URL} referrerURL + * @returns {external:URL} modified referrerURL + */ + +/** + * Modifies the referrerOrigin to enforce any extra security policy considerations. + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer}, step 7 + * @callback module:utils/referrer~referrerOriginCallback + * @param {external:URL} referrerOrigin + * @returns {external:URL} modified referrerOrigin + */ + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer|Referrer Policy §8.3. Determine request's Referrer} + * @param {Request} request + * @param {object} o + * @param {module:utils/referrer~referrerURLCallback} o.referrerURLCallback + * @param {module:utils/referrer~referrerOriginCallback} o.referrerOriginCallback + * @returns {external:URL} Request's referrer + */ +function determineRequestsReferrer(request, {referrerURLCallback, referrerOriginCallback} = {}) { + // There are 2 notes in the specification about invalid pre-conditions. We return null, here, for + // these cases: + // > Note: If request's referrer is "no-referrer", Fetch will not call into this algorithm. + // > Note: If request's referrer policy is the empty string, Fetch will not call into this + // > algorithm. + if (request.referrer === 'no-referrer' || request.referrerPolicy === '') { + return null; + } + + // 1. Let policy be request's associated referrer policy. + const policy = request.referrerPolicy; + + // 2. Let environment be request's client. + // not applicable to node.js + + // 3. Switch on request's referrer: + if (request.referrer === 'about:client') { + return 'no-referrer'; + } + + // "a URL": Let referrerSource be request's referrer. + const referrerSource = request.referrer; + + // 4. Let request's referrerURL be the result of stripping referrerSource for use as a referrer. + let referrerURL = stripURLForUseAsAReferrer(referrerSource); + + // 5. Let referrerOrigin be the result of stripping referrerSource for use as a referrer, with the + // origin-only flag set to true. + let referrerOrigin = stripURLForUseAsAReferrer(referrerSource, true); + + // 6. If the result of serializing referrerURL is a string whose length is greater than 4096, set + // referrerURL to referrerOrigin. + if (referrerURL.toString().length > 4096) { + referrerURL = referrerOrigin; + } + + // 7. The user agent MAY alter referrerURL or referrerOrigin at this point to enforce arbitrary + // policy considerations in the interests of minimizing data leakage. For example, the user + // agent could strip the URL down to an origin, modify its host, replace it with an empty + // string, etc. + if (referrerURLCallback) { + referrerURL = referrerURLCallback(referrerURL); + } + + if (referrerOriginCallback) { + referrerOrigin = referrerOriginCallback(referrerOrigin); + } + + // 8.Execute the statements corresponding to the value of policy: + const currentURL = new URL(request.url); + + switch (policy) { + case 'no-referrer': + return 'no-referrer'; + + case 'origin': + return referrerOrigin; + + case 'unsafe-url': + return referrerURL; + + case 'strict-origin': + // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a + // potentially trustworthy URL, then return no referrer. + if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) { + return 'no-referrer'; + } + + // 2. Return referrerOrigin. + return referrerOrigin.toString(); + + case 'strict-origin-when-cross-origin': + // 1. If the origin of referrerURL and the origin of request's current URL are the same, then + // return referrerURL. + if (referrerURL.origin === currentURL.origin) { + return referrerURL; + } + + // 2. If referrerURL is a potentially trustworthy URL and request's current URL is not a + // potentially trustworthy URL, then return no referrer. + if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) { + return 'no-referrer'; + } + + // 3. Return referrerOrigin. + return referrerOrigin; + + case 'same-origin': + // 1. If the origin of referrerURL and the origin of request's current URL are the same, then + // return referrerURL. + if (referrerURL.origin === currentURL.origin) { + return referrerURL; + } + + // 2. Return no referrer. + return 'no-referrer'; + + case 'origin-when-cross-origin': + // 1. If the origin of referrerURL and the origin of request's current URL are the same, then + // return referrerURL. + if (referrerURL.origin === currentURL.origin) { + return referrerURL; + } + + // Return referrerOrigin. + return referrerOrigin; + + case 'no-referrer-when-downgrade': + // 1. If referrerURL is a potentially trustworthy URL and request's current URL is not a + // potentially trustworthy URL, then return no referrer. + if (isUrlPotentiallyTrustworthy(referrerURL) && !isUrlPotentiallyTrustworthy(currentURL)) { + return 'no-referrer'; + } + + // 2. Return referrerURL. + return referrerURL; + + default: + throw new TypeError(`Invalid referrerPolicy: ${policy}`); + } +} + +/** + * @see {@link https://w3c.github.io/webappsec-referrer-policy/#parse-referrer-policy-from-header|Referrer Policy §8.1. Parse a referrer policy from a Referrer-Policy header} + * @param {Headers} headers Response headers + * @returns {string} policy + */ +function parseReferrerPolicyFromHeader(headers) { + // 1. Let policy-tokens be the result of extracting header list values given `Referrer-Policy` + // and response’s header list. + const policyTokens = (headers.get('referrer-policy') || '').split(/[,\s]+/); + + // 2. Let policy be the empty string. + let policy = ''; + + // 3. For each token in policy-tokens, if token is a referrer policy and token is not the empty + // string, then set policy to token. + // Note: This algorithm loops over multiple policy values to allow deployment of new policy + // values with fallbacks for older user agents, as described in § 11.1 Unknown Policy Values. + for (const token of policyTokens) { + if (token && ReferrerPolicy.has(token)) { + policy = token; + } + } + + // 4. Return policy. + return policy; +} + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/request.js +/** + * Request.js + * + * Request class contains server only options + * + * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/. + */ + + + + + + + + + +const request_INTERNALS = Symbol('Request internals'); + +/** + * Check if `obj` is an instance of Request. + * + * @param {*} object + * @return {boolean} + */ +const isRequest = object => { + return ( + typeof object === 'object' && + typeof object[request_INTERNALS] === 'object' + ); +}; + +const doBadDataWarn = (0,external_node_util_namespaceObject.deprecate)(() => {}, + '.data is not a valid RequestInit property, use .body instead', + 'https://github.com/node-fetch/node-fetch/issues/1000 (request)'); + +/** + * Request class + * + * Ref: https://fetch.spec.whatwg.org/#request-class + * + * @param Mixed input Url or Request instance + * @param Object init Custom options + * @return Void + */ +class Request extends Body { + constructor(input, init = {}) { + let parsedURL; + + // Normalize input and force URL to be encoded as UTF-8 (https://github.com/node-fetch/node-fetch/issues/245) + if (isRequest(input)) { + parsedURL = new URL(input.url); + } else { + parsedURL = new URL(input); + input = {}; + } + + if (parsedURL.username !== '' || parsedURL.password !== '') { + throw new TypeError(`${parsedURL} is an url with embedded credentials.`); + } + + let method = init.method || input.method || 'GET'; + if (/^(delete|get|head|options|post|put)$/i.test(method)) { + method = method.toUpperCase(); + } + + if (!isRequest(init) && 'data' in init) { + doBadDataWarn(); + } + + // eslint-disable-next-line no-eq-null, eqeqeq + if ((init.body != null || (isRequest(input) && input.body !== null)) && + (method === 'GET' || method === 'HEAD')) { + throw new TypeError('Request with GET/HEAD method cannot have body'); + } + + const inputBody = init.body ? + init.body : + (isRequest(input) && input.body !== null ? + clone(input) : + null); + + super(inputBody, { + size: init.size || input.size || 0 + }); + + const headers = new Headers(init.headers || input.headers || {}); + + if (inputBody !== null && !headers.has('Content-Type')) { + const contentType = extractContentType(inputBody, this); + if (contentType) { + headers.set('Content-Type', contentType); + } + } + + let signal = isRequest(input) ? + input.signal : + null; + if ('signal' in init) { + signal = init.signal; + } + + // eslint-disable-next-line no-eq-null, eqeqeq + if (signal != null && !isAbortSignal(signal)) { + throw new TypeError('Expected signal to be an instanceof AbortSignal or EventTarget'); + } + + // §5.4, Request constructor steps, step 15.1 + // eslint-disable-next-line no-eq-null, eqeqeq + let referrer = init.referrer == null ? input.referrer : init.referrer; + if (referrer === '') { + // §5.4, Request constructor steps, step 15.2 + referrer = 'no-referrer'; + } else if (referrer) { + // §5.4, Request constructor steps, step 15.3.1, 15.3.2 + const parsedReferrer = new URL(referrer); + // §5.4, Request constructor steps, step 15.3.3, 15.3.4 + referrer = /^about:(\/\/)?client$/.test(parsedReferrer) ? 'client' : parsedReferrer; + } else { + referrer = undefined; + } + + this[request_INTERNALS] = { + method, + redirect: init.redirect || input.redirect || 'follow', + headers, + parsedURL, + signal, + referrer + }; + + // Node-fetch-only options + this.follow = init.follow === undefined ? (input.follow === undefined ? 20 : input.follow) : init.follow; + this.compress = init.compress === undefined ? (input.compress === undefined ? true : input.compress) : init.compress; + this.counter = init.counter || input.counter || 0; + this.agent = init.agent || input.agent; + this.highWaterMark = init.highWaterMark || input.highWaterMark || 16384; + this.insecureHTTPParser = init.insecureHTTPParser || input.insecureHTTPParser || false; + + // §5.4, Request constructor steps, step 16. + // Default is empty string per https://fetch.spec.whatwg.org/#concept-request-referrer-policy + this.referrerPolicy = init.referrerPolicy || input.referrerPolicy || ''; + } + + /** @returns {string} */ + get method() { + return this[request_INTERNALS].method; + } + + /** @returns {string} */ + get url() { + return (0,external_node_url_namespaceObject.format)(this[request_INTERNALS].parsedURL); + } + + /** @returns {Headers} */ + get headers() { + return this[request_INTERNALS].headers; + } + + get redirect() { + return this[request_INTERNALS].redirect; + } + + /** @returns {AbortSignal} */ + get signal() { + return this[request_INTERNALS].signal; + } + + // https://fetch.spec.whatwg.org/#dom-request-referrer + get referrer() { + if (this[request_INTERNALS].referrer === 'no-referrer') { + return ''; + } + + if (this[request_INTERNALS].referrer === 'client') { + return 'about:client'; + } + + if (this[request_INTERNALS].referrer) { + return this[request_INTERNALS].referrer.toString(); + } + + return undefined; + } + + get referrerPolicy() { + return this[request_INTERNALS].referrerPolicy; + } + + set referrerPolicy(referrerPolicy) { + this[request_INTERNALS].referrerPolicy = validateReferrerPolicy(referrerPolicy); + } + + /** + * Clone this request + * + * @return Request + */ + clone() { + return new Request(this); + } + + get [Symbol.toStringTag]() { + return 'Request'; + } +} + +Object.defineProperties(Request.prototype, { + method: {enumerable: true}, + url: {enumerable: true}, + headers: {enumerable: true}, + redirect: {enumerable: true}, + clone: {enumerable: true}, + signal: {enumerable: true}, + referrer: {enumerable: true}, + referrerPolicy: {enumerable: true} +}); + +/** + * Convert a Request to Node.js http request options. + * + * @param {Request} request - A Request instance + * @return The options object to be passed to http.request + */ +const getNodeRequestOptions = request => { + const {parsedURL} = request[request_INTERNALS]; + const headers = new Headers(request[request_INTERNALS].headers); + + // Fetch step 1.3 + if (!headers.has('Accept')) { + headers.set('Accept', '*/*'); + } + + // HTTP-network-or-cache fetch steps 2.4-2.7 + let contentLengthValue = null; + if (request.body === null && /^(post|put)$/i.test(request.method)) { + contentLengthValue = '0'; + } + + if (request.body !== null) { + const totalBytes = getTotalBytes(request); + // Set Content-Length if totalBytes is a number (that is not NaN) + if (typeof totalBytes === 'number' && !Number.isNaN(totalBytes)) { + contentLengthValue = String(totalBytes); + } + } + + if (contentLengthValue) { + headers.set('Content-Length', contentLengthValue); + } + + // 4.1. Main fetch, step 2.6 + // > If request's referrer policy is the empty string, then set request's referrer policy to the + // > default referrer policy. + if (request.referrerPolicy === '') { + request.referrerPolicy = DEFAULT_REFERRER_POLICY; + } + + // 4.1. Main fetch, step 2.7 + // > If request's referrer is not "no-referrer", set request's referrer to the result of invoking + // > determine request's referrer. + if (request.referrer && request.referrer !== 'no-referrer') { + request[request_INTERNALS].referrer = determineRequestsReferrer(request); + } else { + request[request_INTERNALS].referrer = 'no-referrer'; + } + + // 4.5. HTTP-network-or-cache fetch, step 6.9 + // > If httpRequest's referrer is a URL, then append `Referer`/httpRequest's referrer, serialized + // > and isomorphic encoded, to httpRequest's header list. + if (request[request_INTERNALS].referrer instanceof URL) { + headers.set('Referer', request.referrer); + } + + // HTTP-network-or-cache fetch step 2.11 + if (!headers.has('User-Agent')) { + headers.set('User-Agent', 'node-fetch'); + } + + // HTTP-network-or-cache fetch step 2.15 + if (request.compress && !headers.has('Accept-Encoding')) { + headers.set('Accept-Encoding', 'gzip, deflate, br'); + } + + let {agent} = request; + if (typeof agent === 'function') { + agent = agent(parsedURL); + } + + // HTTP-network fetch step 4.2 + // chunked encoding is handled by Node.js + + const search = getSearch(parsedURL); + + // Pass the full URL directly to request(), but overwrite the following + // options: + const options = { + // Overwrite search to retain trailing ? (issue #776) + path: parsedURL.pathname + search, + // The following options are not expressed in the URL + method: request.method, + headers: headers[Symbol.for('nodejs.util.inspect.custom')](), + insecureHTTPParser: request.insecureHTTPParser, + agent + }; + + return { + /** @type {URL} */ + parsedURL, + options + }; +}; + +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/errors/abort-error.js + + +/** + * AbortError interface for cancelled requests + */ +class AbortError extends FetchBaseError { + constructor(message, type = 'aborted') { + super(message, type); + } +} + +// EXTERNAL MODULE: ./node_modules/fetch-blob/from.js + 2 modules +var from = __nccwpck_require__(2777); +;// CONCATENATED MODULE: ./node_modules/node-fetch/src/index.js +/** + * Index.js + * + * a request API compatible with window.fetch + * + * All spec algorithm step numbers are based on https://fetch.spec.whatwg.org/commit-snapshots/ae716822cb3a61843226cd090eefc6589446c1d2/. + */ + + + + + + + + + + + + + + + + + + + + + + + + +const supportedSchemas = new Set(['data:', 'http:', 'https:']); + +/** + * Fetch function + * + * @param {string | URL | import('./request').default} url - Absolute url or Request instance + * @param {*} [options_] - Fetch options + * @return {Promise<import('./response').default>} + */ +async function fetch(url, options_) { + return new Promise((resolve, reject) => { + // Build request object + const request = new Request(url, options_); + const {parsedURL, options} = getNodeRequestOptions(request); + if (!supportedSchemas.has(parsedURL.protocol)) { + throw new TypeError(`node-fetch cannot load ${url}. URL scheme "${parsedURL.protocol.replace(/:$/, '')}" is not supported.`); + } + + if (parsedURL.protocol === 'data:') { + const data = dist(request.url); + const response = new Response(data, {headers: {'Content-Type': data.typeFull}}); + resolve(response); + return; + } + + // Wrap http.request into fetch + const send = (parsedURL.protocol === 'https:' ? external_node_https_namespaceObject : external_node_http_namespaceObject).request; + const {signal} = request; + let response = null; + + const abort = () => { + const error = new AbortError('The operation was aborted.'); + reject(error); + if (request.body && request.body instanceof external_node_stream_namespaceObject.Readable) { + request.body.destroy(error); + } + + if (!response || !response.body) { + return; + } + + response.body.emit('error', error); + }; + + if (signal && signal.aborted) { + abort(); + return; + } + + const abortAndFinalize = () => { + abort(); + finalize(); + }; + + // Send request + const request_ = send(parsedURL.toString(), options); + + if (signal) { + signal.addEventListener('abort', abortAndFinalize); + } + + const finalize = () => { + request_.abort(); + if (signal) { + signal.removeEventListener('abort', abortAndFinalize); + } + }; + + request_.on('error', error => { + reject(new FetchError(`request to ${request.url} failed, reason: ${error.message}`, 'system', error)); + finalize(); + }); + + fixResponseChunkedTransferBadEnding(request_, error => { + if (response && response.body) { + response.body.destroy(error); + } + }); + + /* c8 ignore next 18 */ + if (process.version < 'v14') { + // Before Node.js 14, pipeline() does not fully support async iterators and does not always + // properly handle when the socket close/end events are out of order. + request_.on('socket', s => { + let endedWithEventsCount; + s.prependListener('end', () => { + endedWithEventsCount = s._eventsCount; + }); + s.prependListener('close', hadError => { + // if end happened before close but the socket didn't emit an error, do it now + if (response && endedWithEventsCount < s._eventsCount && !hadError) { + const error = new Error('Premature close'); + error.code = 'ERR_STREAM_PREMATURE_CLOSE'; + response.body.emit('error', error); + } + }); + }); + } + + request_.on('response', response_ => { + request_.setTimeout(0); + const headers = fromRawHeaders(response_.rawHeaders); + + // HTTP fetch step 5 + if (isRedirect(response_.statusCode)) { + // HTTP fetch step 5.2 + const location = headers.get('Location'); + + // HTTP fetch step 5.3 + let locationURL = null; + try { + locationURL = location === null ? null : new URL(location, request.url); + } catch { + // error here can only be invalid URL in Location: header + // do not throw when options.redirect == manual + // let the user extract the errorneous redirect URL + if (request.redirect !== 'manual') { + reject(new FetchError(`uri requested responds with an invalid redirect URL: ${location}`, 'invalid-redirect')); + finalize(); + return; + } + } + + // HTTP fetch step 5.5 + switch (request.redirect) { + case 'error': + reject(new FetchError(`uri requested responds with a redirect, redirect mode is set to error: ${request.url}`, 'no-redirect')); + finalize(); + return; + case 'manual': + // Nothing to do + break; + case 'follow': { + // HTTP-redirect fetch step 2 + if (locationURL === null) { + break; + } + + // HTTP-redirect fetch step 5 + if (request.counter >= request.follow) { + reject(new FetchError(`maximum redirect reached at: ${request.url}`, 'max-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 6 (counter increment) + // Create a new Request object. + const requestOptions = { + headers: new Headers(request.headers), + follow: request.follow, + counter: request.counter + 1, + agent: request.agent, + compress: request.compress, + method: request.method, + body: clone(request), + signal: request.signal, + size: request.size, + referrer: request.referrer, + referrerPolicy: request.referrerPolicy + }; + + // when forwarding sensitive headers like "Authorization", + // "WWW-Authenticate", and "Cookie" to untrusted targets, + // headers will be ignored when following a redirect to a domain + // that is not a subdomain match or exact match of the initial domain. + // For example, a redirect from "foo.com" to either "foo.com" or "sub.foo.com" + // will forward the sensitive headers, but a redirect to "bar.com" will not. + // headers will also be ignored when following a redirect to a domain using + // a different protocol. For example, a redirect from "https://foo.com" to "http://foo.com" + // will not forward the sensitive headers + if (!isDomainOrSubdomain(request.url, locationURL) || !isSameProtocol(request.url, locationURL)) { + for (const name of ['authorization', 'www-authenticate', 'cookie', 'cookie2']) { + requestOptions.headers.delete(name); + } + } + + // HTTP-redirect fetch step 9 + if (response_.statusCode !== 303 && request.body && options_.body instanceof external_node_stream_namespaceObject.Readable) { + reject(new FetchError('Cannot follow redirect with body being a readable stream', 'unsupported-redirect')); + finalize(); + return; + } + + // HTTP-redirect fetch step 11 + if (response_.statusCode === 303 || ((response_.statusCode === 301 || response_.statusCode === 302) && request.method === 'POST')) { + requestOptions.method = 'GET'; + requestOptions.body = undefined; + requestOptions.headers.delete('content-length'); + } + + // HTTP-redirect fetch step 14 + const responseReferrerPolicy = parseReferrerPolicyFromHeader(headers); + if (responseReferrerPolicy) { + requestOptions.referrerPolicy = responseReferrerPolicy; + } + + // HTTP-redirect fetch step 15 + resolve(fetch(new Request(locationURL, requestOptions))); + finalize(); + return; + } + + default: + return reject(new TypeError(`Redirect option '${request.redirect}' is not a valid value of RequestRedirect`)); + } + } + + // Prepare response + if (signal) { + response_.once('end', () => { + signal.removeEventListener('abort', abortAndFinalize); + }); + } + + let body = (0,external_node_stream_namespaceObject.pipeline)(response_, new external_node_stream_namespaceObject.PassThrough(), error => { + if (error) { + reject(error); + } + }); + // see https://github.com/nodejs/node/pull/29376 + /* c8 ignore next 3 */ + if (process.version < 'v12.10') { + response_.on('aborted', abortAndFinalize); + } + + const responseOptions = { + url: request.url, + status: response_.statusCode, + statusText: response_.statusMessage, + headers, + size: request.size, + counter: request.counter, + highWaterMark: request.highWaterMark + }; + + // HTTP-network fetch step 12.1.1.3 + const codings = headers.get('Content-Encoding'); + + // HTTP-network fetch step 12.1.1.4: handle content codings + + // in following scenarios we ignore compression support + // 1. compression support is disabled + // 2. HEAD request + // 3. no Content-Encoding header + // 4. no content response (204) + // 5. content not modified response (304) + if (!request.compress || request.method === 'HEAD' || codings === null || response_.statusCode === 204 || response_.statusCode === 304) { + response = new Response(body, responseOptions); + resolve(response); + return; + } + + // For Node v6+ + // Be less strict when decoding compressed responses, since sometimes + // servers send slightly invalid responses that are still accepted + // by common browsers. + // Always using Z_SYNC_FLUSH is what cURL does. + const zlibOptions = { + flush: external_node_zlib_namespaceObject.Z_SYNC_FLUSH, + finishFlush: external_node_zlib_namespaceObject.Z_SYNC_FLUSH + }; + + // For gzip + if (codings === 'gzip' || codings === 'x-gzip') { + body = (0,external_node_stream_namespaceObject.pipeline)(body, external_node_zlib_namespaceObject.createGunzip(zlibOptions), error => { + if (error) { + reject(error); + } + }); + response = new Response(body, responseOptions); + resolve(response); + return; + } + + // For deflate + if (codings === 'deflate' || codings === 'x-deflate') { + // Handle the infamous raw deflate response from old servers + // a hack for old IIS and Apache servers + const raw = (0,external_node_stream_namespaceObject.pipeline)(response_, new external_node_stream_namespaceObject.PassThrough(), error => { + if (error) { + reject(error); + } + }); + raw.once('data', chunk => { + // See http://stackoverflow.com/questions/37519828 + if ((chunk[0] & 0x0F) === 0x08) { + body = (0,external_node_stream_namespaceObject.pipeline)(body, external_node_zlib_namespaceObject.createInflate(), error => { + if (error) { + reject(error); + } + }); + } else { + body = (0,external_node_stream_namespaceObject.pipeline)(body, external_node_zlib_namespaceObject.createInflateRaw(), error => { + if (error) { + reject(error); + } + }); + } + + response = new Response(body, responseOptions); + resolve(response); + }); + raw.once('end', () => { + // Some old IIS servers return zero-length OK deflate responses, so + // 'data' is never emitted. See https://github.com/node-fetch/node-fetch/pull/903 + if (!response) { + response = new Response(body, responseOptions); + resolve(response); + } + }); + return; + } + + // For br + if (codings === 'br') { + body = (0,external_node_stream_namespaceObject.pipeline)(body, external_node_zlib_namespaceObject.createBrotliDecompress(), error => { + if (error) { + reject(error); + } + }); + response = new Response(body, responseOptions); + resolve(response); + return; + } + + // Otherwise, use response as-is + response = new Response(body, responseOptions); + resolve(response); + }); + + // eslint-disable-next-line promise/prefer-await-to-then + writeToStream(request_, request).catch(reject); + }); +} + +function fixResponseChunkedTransferBadEnding(request, errorCallback) { + const LAST_CHUNK = external_node_buffer_namespaceObject.Buffer.from('0\r\n\r\n'); + + let isChunkedTransfer = false; + let properLastChunkReceived = false; + let previousChunk; + + request.on('response', response => { + const {headers} = response; + isChunkedTransfer = headers['transfer-encoding'] === 'chunked' && !headers['content-length']; + }); + + request.on('socket', socket => { + const onSocketClose = () => { + if (isChunkedTransfer && !properLastChunkReceived) { + const error = new Error('Premature close'); + error.code = 'ERR_STREAM_PREMATURE_CLOSE'; + errorCallback(error); + } + }; + + const onData = buf => { + properLastChunkReceived = external_node_buffer_namespaceObject.Buffer.compare(buf.slice(-5), LAST_CHUNK) === 0; + + // Sometimes final 0-length chunk and end of message code are in separate packets + if (!properLastChunkReceived && previousChunk) { + properLastChunkReceived = ( + external_node_buffer_namespaceObject.Buffer.compare(previousChunk.slice(-3), LAST_CHUNK.slice(0, 3)) === 0 && + external_node_buffer_namespaceObject.Buffer.compare(buf.slice(-2), LAST_CHUNK.slice(3)) === 0 + ); + } + + previousChunk = buf; + }; + + socket.prependListener('close', onSocketClose); + socket.on('data', onData); + + request.on('close', () => { + socket.removeListener('close', onSocketClose); + socket.removeListener('data', onData); + }); + }); +} + +// EXTERNAL MODULE: ./node_modules/@octokit/rest/dist-node/index.js +var dist_node = __nccwpck_require__(5375); +// EXTERNAL MODULE: external "fs" +var external_fs_ = __nccwpck_require__(7147); +// EXTERNAL MODULE: external "path" +var external_path_ = __nccwpck_require__(1017); +;// CONCATENATED MODULE: external "child_process" +const external_child_process_namespaceObject = __WEBPACK_EXTERNAL_createRequire(import.meta.url)("child_process"); +;// CONCATENATED MODULE: ./create-hashes.mjs + + + + + + + +function getBinInfo(path) { + // let's be super naive about it. add a+x bits on the file and try to run the command + try { + let mode = external_fs_.statSync(path).mode + external_fs_.chmodSync(path, mode | 0o111) + + const raw = (0,external_child_process_namespaceObject.execSync)(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" }); + const parsed = JSON.parse(raw) + return parsed + } catch (_) { + return undefined + } +} + +async function run(assets, algorithm, filename, cache) { + if (!cache) { + console.warn("cache is set to 'false', but we we no longer support it") + } + + try { + external_fs_.mkdirSync('.tmp'); + } catch(e) { + // ignore + } + + const hashes = {}; + let numAwaiting = 0; + for (const asset of assets) { + if (filename === "" || asset.name !== filename) { // don't hash the hash file (if the file has the same name) + numAwaiting++; + + let buffer = null; + let sig = null; + + // cache in `${WORKING_DIR}/.tmp/` + const cacheFilename = external_path_.resolve(`.tmp/${asset.name}`); + if(!external_fs_.existsSync(cacheFilename)) { + console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); + buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); + external_fs_.writeFileSync(cacheFilename, buffer); + } else { + console.log(`Loading from ${cacheFilename}`); + buffer = Buffer.from(external_fs_.readFileSync(cacheFilename)); + + // console.log('Reading signature from content'); + // if(asset.name.endsWith('.sig')) { + // sig = fs.readFileSync(cacheFilename).toString(); + // } + } + + const binInfo = getBinInfo(cacheFilename) + + if(!hashes[asset.name]) { + hashes[asset.name] = {}; + } + + if(asset.name.endsWith('.sig')) { + sig = buffer.toString(); + } + + hashes[asset.name][algorithm] = hasha(new Uint8Array(buffer), {algorithm: algorithm}); + + let platform; + let kind; + if(asset.name.endsWith('.sig')) { + kind = 'signature'; + } + if(asset.name.endsWith('.app.tar.gz')) { + platform = 'MacOS'; + kind = 'auto-updater'; + } + if(asset.name.endsWith('.app.tar.gz.sig')) { + platform = 'MacOS'; + kind = 'auto-updater-signature'; + } + if(asset.name.endsWith('.dmg')) { + platform = 'MacOS'; + kind = 'installer'; + } + if(asset.name.endsWith('.msi.zip')) { + platform = 'Windows'; + kind = 'auto-updater'; + } + if(asset.name.endsWith('.msi.zip.sig')) { + platform = 'Windows'; + kind = 'auto-updater-signature'; + } + if(asset.name.endsWith('.msi')) { + platform = 'Windows'; + kind = 'installer'; + } + if(asset.name.endsWith('.AppImage.tar.gz')) { + platform = 'Linux'; + kind = 'auto-updater'; + } + if(asset.name.endsWith('.AppImage.tar.gz.sig')) { + platform = 'Linux'; + kind = 'auto-updater-signature'; + } + if(asset.name.endsWith('.AppImage')) { + platform = 'Linux'; + kind = 'installer'; + } + + hashes[asset.name].downloadUrl = asset.browser_download_url; + + if(platform) { + hashes[asset.name].platform = platform; + } + if(kind) { + hashes[asset.name].kind = kind; + } + if(binInfo) { + hashes[asset.name].details = binInfo; + } + + // process Tauri signature files + if(asset.name.endsWith('.sig')) { + const otherFilename = asset.name.replace('.sig', ''); + if(!hashes[otherFilename]) { + hashes[otherFilename] = {}; + } + hashes[otherFilename].signature = sig; + } + } + } + return hashes; +} + +async function createHashes({ assets, algorithm, filename, cache }) { + const output = await run(assets, algorithm, filename, cache); + if(filename?.length) { + external_fs_.writeFileSync(filename, JSON.stringify(output, null, 2)); + } + return output; +} + +async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm = 'sha256', filename = 'hashes.json', cache = false, upload = true, owner = 'nymtech', repo = 'nym' }) { + console.log("🚀🚀🚀 Getting releases"); + + let auth; + let authStrategy; + if(process.env.GITHUB_TOKEN) { + console.log('Using GITHUB_TOKEN for auth'); + // authStrategy = createActionAuth(); + // auth = await authStrategy(); + } + + const octokit = new dist_node.Octokit({ + auth: process.env.GITHUB_TOKEN, + request: { fetch: fetch } + }); + + let releases; + if(cache) { + const cacheFilename = external_path_.resolve(`.tmp/releases.json`); + if(!external_fs_.existsSync(cacheFilename)) { + releases = await octokit.paginate( + octokit.rest.repos.listReleases, + { + owner, + repo, + per_page: 100, + }, + (response) => response.data + ); + external_fs_.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2)); + } else { + console.log('Loading releases from cache...'); + releases = JSON.parse(external_fs_.readFileSync(cacheFilename)); + } + } else { + releases = await octokit.paginate( + octokit.rest.repos.listReleases, + { + owner, + repo, + per_page: 100, + }, + (response) => response.data + ) + } + + // process all releases by default + let releasesToProcess = releases; + + // process a single release + if(releaseTagOrNameOrId) { + releasesToProcess = releases.filter(r => { + if (r.tag_name === releaseTagOrNameOrId) { + return true; + } + if (`${r.id}` === `${releaseTagOrNameOrId}`) { + return true; + } + if (r.name === releaseTagOrNameOrId) { + return true; + } + + return false; + }); + } + + releasesToProcess.forEach(release => { + const {tag_name, name} = release; + const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/); + + if(!matches || matches.length < 2) { + return; + } + + const tagComponents = matches.slice(1); + const componentName = tagComponents[0]; + const componentVersion = 'v' + tagComponents[1]; + + if(!tagComponents[1] || !name) { + return; + } + + release.componentName = componentName; + release.componentVersion = componentVersion; + }) + + releasesToProcess = releasesToProcess.filter(release => + !!release.name && !!release.componentVersion + ); + + console.log('Releases to process:'); + console.table(releasesToProcess.map(r => { + const { id, name, tag_name, componentName, componentVersion, assets } = r; + return { id, name, tag_name, componentName, componentVersion, assetCount: assets.length }; + })); + + for(const release of releasesToProcess) { + const {id, name, tag_name, html_url, componentName, componentVersion} = release; + + const hashes = await createHashes({ assets: release.assets, algorithm, filename, cache }); + + const output = { + id, name, tag_name, html_url, + componentName, + componentVersion, + assets: hashes, + }; + + console.log(output) + + if(upload) { + console.log(`🚚 Uploading ${filename} to release name="${release.name}" id=${release.id} (${release.upload_url})...`); + + const exists = (await octokit.repos.listReleaseAssets({ owner, repo, release_id: release.id })).data.find(a => a.name === filename) + if (exists) { + console.log(`Deleting existing asset ${filename}...`); + await octokit.repos.deleteReleaseAsset({ owner, repo, asset_id: exists.id }) + console.log('Deleted existing asset'); + } + + try { + const data = JSON.stringify(output, null, 2); + await octokit.rest.repos.uploadReleaseAsset({ + owner, + repo, + release_id: release.id, + headers: { + 'X-GitHub-Api-Version': '2022-11-28' + }, + name: filename, + data, + }); + console.log('✅ Upload to release is complete.'); + } catch(e) { + console.log('❌ failed to upload:', e.message, e.status, e.response.data); + console.log(e); + process.exit(-1); + } + } + } +} + + +;// CONCATENATED MODULE: ./index.js + + + + +const algorithm = core.getInput('hash-type'); +const filename = core.getInput("file-name"); +const owner = core.getInput("owner"); +const repo = core.getInput("repo"); + +async function main() { +// use the release id from the payload if it is set + const releaseTagOrNameOrId = core.getInput("release-tag-or-name-or-id") || github.context.payload.release?.id; + + try { + await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId, algorithm, filename, owner, repo}) + } catch (error) { + core.setFailed(error.message); + } +} + +main().catch(error => core.setFailed(error.message)); + +})(); + diff --git a/.github/actions/nym-hash-releases/dist/thread.js b/.github/actions/nym-hash-releases/dist/thread.js new file mode 100644 index 0000000000..3d4510c1e5 --- /dev/null +++ b/.github/actions/nym-hash-releases/dist/thread.js @@ -0,0 +1,57 @@ +'use strict'; +const fs = require('fs'); +const crypto = require('crypto'); +const {parentPort} = require('worker_threads'); + +const handlers = { + hashFile: (algorithm, filePath) => new Promise((resolve, reject) => { + const hasher = crypto.createHash(algorithm); + fs.createReadStream(filePath) + // TODO: Use `Stream.pipeline` when targeting Node.js 12. + .on('error', reject) + .pipe(hasher) + .on('error', reject) + .on('finish', () => { + const {buffer} = new Uint8Array(hasher.read()); + resolve({value: buffer, transferList: [buffer]}); + }); + }), + hash: async (algorithm, input) => { + const hasher = crypto.createHash(algorithm); + + if (Array.isArray(input)) { + for (const part of input) { + hasher.update(part); + } + } else { + hasher.update(input); + } + + const {buffer} = new Uint8Array(hasher.digest()); + return {value: buffer, transferList: [buffer]}; + } +}; + +parentPort.on('message', async message => { + try { + const {method, args} = message; + const handler = handlers[method]; + + if (handler === undefined) { + throw new Error(`Unknown method '${method}'`); + } + + const {value, transferList} = await handler(...args); + parentPort.postMessage({id: message.id, value}, transferList); + } catch (error) { + const newError = {message: error.message, stack: error.stack}; + + for (const [key, value] of Object.entries(error)) { + if (typeof value !== 'object') { + newError[key] = value; + } + } + + parentPort.postMessage({id: message.id, error: newError}); + } +}); diff --git a/.github/actions/nym-hash-releases/index.js b/.github/actions/nym-hash-releases/index.js deleted file mode 100644 index eecccba557..0000000000 --- a/.github/actions/nym-hash-releases/index.js +++ /dev/null @@ -1,15 +0,0 @@ -import core from "@actions/core"; -import github from "@actions/github"; -import { createHashesFromReleaseTagOrNameOrId } from './create-hashes.mjs'; - -const algorithm = core.getInput('hash-type'); -const filename = core.getInput("file-name"); - -// use the release id from the payload if it is set -const releaseTagOrNameOrId = core.getInput("release-tag-or-name-or-id") || github.context.payload.release?.id; - -try { - await createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm, filename }) -} catch (error) { - core.setFailed(error.message); -} diff --git a/.github/actions/nym-hash-releases/package.json b/.github/actions/nym-hash-releases/package.json index 6dcd6903a1..98667dd6b6 100644 --- a/.github/actions/nym-hash-releases/package.json +++ b/.github/actions/nym-hash-releases/package.json @@ -2,17 +2,6 @@ "name": "nym-hash-release", "version": "1.0.0", "description": "Generate hashes and signatures for assets in Nym releases", - "main": "index.js", - "type": "module", - "scripts": { - "local": "node run-local.mjs" - }, - "dependencies": { - "@actions/core": "^1.10.0", - "@actions/github": "^5.1.1", - "@octokit/auth-action": "^4.0.0", - "@octokit/rest": "^20.0.1", - "hasha": "^5.2.0", - "node-fetch": "^3.2.10" - } + "main": "dist/index.js", + "type": "module" } diff --git a/.github/actions/nym-hash-releases/src/README.md b/.github/actions/nym-hash-releases/src/README.md new file mode 100644 index 0000000000..ef76200a77 --- /dev/null +++ b/.github/actions/nym-hash-releases/src/README.md @@ -0,0 +1,14 @@ +# nym-hash-release + +This is the source code for the custom GitHub Action to calculate hashes. + +It is in a subdirectory to avoid issues with `package.json`. + +## Build + +The following will bundle all code and dependencies into the `dist` folder, and copy it into place for GitHub Actions. + +``` +npm run build +npm run dist:copy +``` \ No newline at end of file diff --git a/.github/actions/nym-hash-releases/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs similarity index 97% rename from .github/actions/nym-hash-releases/create-hashes.mjs rename to .github/actions/nym-hash-releases/src/create-hashes.mjs index 28e1e3e282..584d364a4c 100644 --- a/.github/actions/nym-hash-releases/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -142,7 +142,7 @@ export async function createHashes({ assets, algorithm, filename, cache }) { return output; } -export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm = 'sha256', filename = 'hashes.json', cache = false, upload = true }) { +export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algorithm = 'sha256', filename = 'hashes.json', cache = false, upload = true, owner = 'nymtech', repo = 'nym' }) { console.log("🚀🚀🚀 Getting releases"); let auth; @@ -157,8 +157,6 @@ export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrI auth: process.env.GITHUB_TOKEN, request: { fetch } }); - const owner = "nymtech"; - const repo = "nym"; let releases; if(cache) { @@ -212,7 +210,13 @@ export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrI releasesToProcess.forEach(release => { const {tag_name, name} = release; - const tagComponents = tag_name.split('-v'); + const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/); + + if(!matches || matches.length < 2) { + return; + } + + const tagComponents = matches.slice(1); const componentName = tagComponents[0]; const componentVersion = 'v' + tagComponents[1]; diff --git a/.github/actions/nym-hash-releases/src/index.js b/.github/actions/nym-hash-releases/src/index.js new file mode 100644 index 0000000000..e769e9797c --- /dev/null +++ b/.github/actions/nym-hash-releases/src/index.js @@ -0,0 +1,21 @@ +import core from "@actions/core"; +import github from "@actions/github"; +import { createHashesFromReleaseTagOrNameOrId } from './create-hashes.mjs'; + +const algorithm = core.getInput('hash-type'); +const filename = core.getInput("file-name"); +const owner = core.getInput("owner"); +const repo = core.getInput("repo"); + +async function main() { +// use the release id from the payload if it is set + const releaseTagOrNameOrId = core.getInput("release-tag-or-name-or-id") || github.context.payload.release?.id; + + try { + await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId, algorithm, filename, owner, repo}) + } catch (error) { + core.setFailed(error.message); + } +} + +main().catch(error => core.setFailed(error.message)); diff --git a/.github/actions/nym-hash-releases/package-lock.json b/.github/actions/nym-hash-releases/src/package-lock.json similarity index 84% rename from .github/actions/nym-hash-releases/package-lock.json rename to .github/actions/nym-hash-releases/src/package-lock.json index ce1cc096fa..1c9a90fe9e 100644 --- a/.github/actions/nym-hash-releases/package-lock.json +++ b/.github/actions/nym-hash-releases/src/package-lock.json @@ -1,26 +1,28 @@ { - "name": "ghaction-generate-release-hashes", + "name": "nym-hash-release", "version": "1.0.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "ghaction-generate-release-hashes", + "name": "nym-hash-release", "version": "1.0.0", - "license": "MIT", "dependencies": { - "@actions/core": "^1.10.0", + "@actions/core": "^1.10.1", "@actions/github": "^5.1.1", - "@octokit/auth-action": "^4.0.0", - "@octokit/rest": "^20.0.1", + "@octokit/auth-action": "^4.0.1", + "@octokit/rest": "^20.0.2", "hasha": "^5.2.0", "node-fetch": "^3.2.10" + }, + "devDependencies": { + "@vercel/ncc": "^0.38.1" } }, "node_modules/@actions/core": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz", - "integrity": "sha512-2aZDDa3zrrZbP5ZYg159sNoLRb61nQ7awl5pSvIq5Qpj81vwDzdMRKzkWJGJuwVvWpvZKx7vspJALyvaaIQyug==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.1.tgz", + "integrity": "sha512-3lBR9EDAY+iYIpTnTIXmWcNbX3T2kCkAEQGIQx4NVQ0575nk2k3GRZDTPQG+vVtS2izSLmINlxXf0uLtnrTP+g==", "dependencies": { "@actions/http-client": "^2.0.1", "uuid": "^8.3.2" @@ -46,12 +48,12 @@ } }, "node_modules/@octokit/auth-action": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.0.tgz", - "integrity": "sha512-sMm9lWZdiX6e89YFaLrgE9EFs94k58BwIkvjOtozNWUqyTmsrnWFr/M5LolaRzZ7Kmb5FbhF9hi7FEeE274SoQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@octokit/auth-action/-/auth-action-4.0.1.tgz", + "integrity": "sha512-mJLOcFFafIivLZ7BEkGDCTFoHPJv7BeL5Zwy7j5qMDU0b/DKshhi6GCU9tw3vmKhOxTNquYfvwqsEfPpemaaxg==", "dependencies": { "@octokit/auth-token": "^4.0.0", - "@octokit/types": "^11.0.0" + "@octokit/types": "^12.0.0" }, "engines": { "node": ">= 18" @@ -66,16 +68,16 @@ } }, "node_modules/@octokit/auth-action/node_modules/@octokit/openapi-types": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-18.0.0.tgz", - "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==" + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==" }, "node_modules/@octokit/auth-action/node_modules/@octokit/types": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/@octokit/types/-/types-11.1.0.tgz", - "integrity": "sha512-Fz0+7GyLm/bHt8fwEqgvRBWwIV1S6wRRyq+V6exRKLVWaKGsuy6H9QFYeBVDV7rK6fO3XwHgQOPxv+cLj2zpXQ==", + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", "dependencies": { - "@octokit/openapi-types": "^18.0.0" + "@octokit/openapi-types": "^20.0.0" } }, "node_modules/@octokit/auth-token": { @@ -191,14 +193,14 @@ } }, "node_modules/@octokit/rest": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.1.tgz", - "integrity": "sha512-wROV21RwHQIMNb2Dgd4+pY+dVy1Dwmp85pBrgr6YRRDYRBu9Gb+D73f4Bl2EukZSj5hInq2Tui9o7gAQpc2k2Q==", + "version": "20.0.2", + "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-20.0.2.tgz", + "integrity": "sha512-Ux8NDgEraQ/DMAU1PlAohyfBBXDwhnX2j33Z1nJNziqAfHi70PuxkFYIcIt8aIAxtRE7KVuKp8lSR8pA0J5iOQ==", "dependencies": { "@octokit/core": "^5.0.0", - "@octokit/plugin-paginate-rest": "^8.0.0", + "@octokit/plugin-paginate-rest": "^9.0.0", "@octokit/plugin-request-log": "^4.0.0", - "@octokit/plugin-rest-endpoint-methods": "^9.0.0" + "@octokit/plugin-rest-endpoint-methods": "^10.0.0" }, "engines": { "node": ">= 18" @@ -261,17 +263,30 @@ "integrity": "sha512-V8GImKs3TeQRxRtXFpG2wl19V7444NIOTDF24AWuIbmNaNYOQMWRbjcGDXV5B+0n887fgDcuMNOmlul+k+oJtw==" }, "node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-8.0.0.tgz", - "integrity": "sha512-2xZ+baZWUg+qudVXnnvXz7qfrTmDeYPCzangBVq/1gXxii/OiS//4shJp9dnCCvj1x+JAm9ji1Egwm1BA47lPQ==", + "version": "9.2.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-paginate-rest/-/plugin-paginate-rest-9.2.1.tgz", + "integrity": "sha512-wfGhE/TAkXZRLjksFXuDZdmGnJQHvtU/joFQdweXUgzo1XwvBCD4o4+75NtFfjfLK5IwLf9vHTfSiU3sLRYpRw==", "dependencies": { - "@octokit/types": "^11.0.0" + "@octokit/types": "^12.6.0" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": "5" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==" + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-paginate-rest/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" } }, "node_modules/@octokit/rest/node_modules/@octokit/plugin-request-log": { @@ -286,17 +301,30 @@ } }, "node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-9.0.0.tgz", - "integrity": "sha512-KquMF/VB1IkKNiVnzJKspY5mFgGyLd7HzdJfVEGTJFzqu9BRFNWt+nwTCMuUiWc72gLQhRWYubTwOkQj+w/1PA==", + "version": "10.4.1", + "resolved": "https://registry.npmjs.org/@octokit/plugin-rest-endpoint-methods/-/plugin-rest-endpoint-methods-10.4.1.tgz", + "integrity": "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg==", "dependencies": { - "@octokit/types": "^11.0.0" + "@octokit/types": "^12.6.0" }, "engines": { "node": ">= 18" }, "peerDependencies": { - "@octokit/core": ">=5" + "@octokit/core": "5" + } + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/openapi-types": { + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/@octokit/openapi-types/-/openapi-types-20.0.0.tgz", + "integrity": "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA==" + }, + "node_modules/@octokit/rest/node_modules/@octokit/plugin-rest-endpoint-methods/node_modules/@octokit/types": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/@octokit/types/-/types-12.6.0.tgz", + "integrity": "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw==", + "dependencies": { + "@octokit/openapi-types": "^20.0.0" } }, "node_modules/@octokit/rest/node_modules/@octokit/request": { @@ -343,6 +371,15 @@ "@octokit/openapi-types": "^12.11.0" } }, + "node_modules/@vercel/ncc": { + "version": "0.38.1", + "resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.38.1.tgz", + "integrity": "sha512-IBBb+iI2NLu4VQn3Vwldyi2QwaXt5+hTyh58ggAMoCGE6DJmPvwL3KPBWcJl1m9LYPChBLE980Jw+CS4Wokqxw==", + "dev": true, + "bin": { + "ncc": "dist/ncc/cli.js" + } + }, "node_modules/before-after-hook": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-2.2.3.tgz", diff --git a/.github/actions/nym-hash-releases/src/package.json b/.github/actions/nym-hash-releases/src/package.json new file mode 100644 index 0000000000..78d73da4d6 --- /dev/null +++ b/.github/actions/nym-hash-releases/src/package.json @@ -0,0 +1,23 @@ +{ + "name": "nym-hash-release", + "version": "1.0.0", + "description": "Generate hashes and signatures for assets in Nym releases", + "main": "index.js", + "type": "module", + "scripts": { + "local": "node run-local.mjs", + "build": "ncc build index.js -o dist", + "dist:copy": "mkdir -p ../dist && cp dist/*.js ../dist" + }, + "dependencies": { + "@actions/core": "^1.10.1", + "@actions/github": "^5.1.1", + "@octokit/auth-action": "^4.0.1", + "@octokit/rest": "^20.0.2", + "hasha": "^5.2.0", + "node-fetch": "^3.2.10" + }, + "devDependencies": { + "@vercel/ncc": "^0.38.1" + } +} diff --git a/.github/actions/nym-hash-releases/run-local.mjs b/.github/actions/nym-hash-releases/src/run-local.mjs similarity index 100% rename from .github/actions/nym-hash-releases/run-local.mjs rename to .github/actions/nym-hash-releases/src/run-local.mjs From f762062f9f815a2dbf3385a596a71fcfdcacb031 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Mar 2024 10:16:06 +0000 Subject: [PATCH 183/394] create wallet context + wallet components create wallet context using cosmoskit + include nymclient + create wallet components --- .../src/components/ConnectKeplrWallet.tsx | 78 ---------------- .../components/Wallet/ConnectKeplrWallet.tsx | 43 +++++++++ .../src/components/Wallet/WalletAddress.tsx | 20 +++++ .../src/components/Wallet/WalletBalance.tsx | 25 ++++++ explorer/src/context/cosmos-kit.tsx | 3 +- explorer/src/context/wallet.tsx | 90 +++++++++++++++++++ explorer/src/hooks/useNymClient.tsx | 31 +++++++ 7 files changed, 211 insertions(+), 79 deletions(-) delete mode 100644 explorer/src/components/ConnectKeplrWallet.tsx create mode 100644 explorer/src/components/Wallet/ConnectKeplrWallet.tsx create mode 100644 explorer/src/components/Wallet/WalletAddress.tsx create mode 100644 explorer/src/components/Wallet/WalletBalance.tsx create mode 100644 explorer/src/context/wallet.tsx create mode 100644 explorer/src/hooks/useNymClient.tsx diff --git a/explorer/src/components/ConnectKeplrWallet.tsx b/explorer/src/components/ConnectKeplrWallet.tsx deleted file mode 100644 index 428c725eb2..0000000000 --- a/explorer/src/components/ConnectKeplrWallet.tsx +++ /dev/null @@ -1,78 +0,0 @@ -import React, { useEffect, useState } from 'react'; -import { useChain } from '@cosmos-kit/react'; -import { Box, Button, Typography, IconButton, Stack } from '@mui/material'; -import CloseIcon from '@mui/icons-material/Close'; -import { TokenSVG } from '../icons/TokenSVG'; -import { ElipsSVG } from '../icons/ElipsSVG'; -import { trimAddress } from '../utils'; -import { unymToNym } from '../utils/currency'; -import { useIsMobile } from '../hooks/useIsMobile'; - -export const ConnectKeplrWallet = () => { - const { connect, disconnect, wallet, address, getCosmWasmClient, isWalletConnected, isWalletConnecting } = - useChain('nyx'); - const isMobile = useIsMobile(1200); - - const [balance, setBalance] = useState<{ - status: 'loading' | 'success'; - data?: string; - }>({ status: 'loading', data: undefined }); - - useEffect(() => { - const getBalance = async (walletAddress: string) => { - setBalance({ status: 'loading', data: undefined }); - - const account = await getCosmWasmClient(); - const uNYMBalance = await account.getBalance(walletAddress, 'unym'); - const NYMBalance = unymToNym(uNYMBalance.amount); - - setBalance({ status: 'success', data: NYMBalance }); - }; - - if (address) { - getBalance(address); - } - }, [address, getCosmWasmClient]); - - const getGlobalbutton = () => { - if (isWalletConnecting) { - return <Button onClick={() => connect()}>{`Connecting ${wallet?.prettyName}`}</Button>; - } - if (isWalletConnected) { - return ( - <Stack direction="row" spacing={1}> - {!isMobile && ( - <Box display="flex" alignItems="center" gap={1}> - <TokenSVG /> - <Typography variant="body1" fontWeight={600}> - {balance.data} NYM - </Typography> - </Box> - )}{' '} - <Box display="flex" alignItems="center" gap={1}> - <ElipsSVG /> - <Typography variant="body1" fontWeight={600}> - {trimAddress(address, 7)} - </Typography> - </Box> - <IconButton - size="small" - onClick={async () => { - await disconnect(); - }} - > - <CloseIcon fontSize="small" sx={{ color: 'white' }} /> - </IconButton> - </Stack> - ); - } - - return ( - <Button variant="outlined" onClick={() => connect()}> - Connect {isMobile ? '' : ' Wallet'} - </Button> - ); - }; - - return <Box>{getGlobalbutton()}</Box>; -}; diff --git a/explorer/src/components/Wallet/ConnectKeplrWallet.tsx b/explorer/src/components/Wallet/ConnectKeplrWallet.tsx new file mode 100644 index 0000000000..ff5d2691c6 --- /dev/null +++ b/explorer/src/components/Wallet/ConnectKeplrWallet.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import { Button, IconButton, Stack, CircularProgress } from '@mui/material'; +import CloseIcon from '@mui/icons-material/Close'; +import { useIsMobile } from '@src/hooks/useIsMobile'; +import { useWalletContext } from '@src/context/wallet'; +import { WalletAddress, WalletBalance } from '@src/components/Wallet'; + +export const ConnectKeplrWallet = () => { + const { connectWallet, disconnectWallet, isWalletConnected, isWalletConnecting } = useWalletContext(); + const isMobile = useIsMobile(1200); + + if (!connectWallet || !disconnectWallet) { + return null; + } + + if (isWalletConnected) { + return ( + <Stack direction="row" spacing={1}> + <WalletBalance /> + <WalletAddress /> + <IconButton + size="small" + onClick={async () => { + await disconnectWallet(); + }} + > + <CloseIcon fontSize="small" sx={{ color: 'white' }} /> + </IconButton> + </Stack> + ); + } + + return ( + <Button + variant="outlined" + onClick={() => connectWallet()} + disabled={isWalletConnecting} + endIcon={isWalletConnecting && <CircularProgress size={14} color="inherit" />} + > + Connect {isMobile ? '' : ' Wallet'} + </Button> + ); +}; diff --git a/explorer/src/components/Wallet/WalletAddress.tsx b/explorer/src/components/Wallet/WalletAddress.tsx new file mode 100644 index 0000000000..8be6c9f291 --- /dev/null +++ b/explorer/src/components/Wallet/WalletAddress.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { Box, Typography } from '@mui/material'; +import { ElipsSVG } from '@src/icons/ElipsSVG'; +import { trimAddress } from '@src/utils'; +import { useWalletContext } from '@src/context/wallet'; + +export const WalletAddress = () => { + const { address } = useWalletContext(); + + const displayAddress = trimAddress(address, 7); + + return ( + <Box display="flex" alignItems="center" gap={0.5}> + <ElipsSVG /> + <Typography variant="body1" fontWeight={600}> + {displayAddress} + </Typography> + </Box> + ); +}; diff --git a/explorer/src/components/Wallet/WalletBalance.tsx b/explorer/src/components/Wallet/WalletBalance.tsx new file mode 100644 index 0000000000..f94935ac23 --- /dev/null +++ b/explorer/src/components/Wallet/WalletBalance.tsx @@ -0,0 +1,25 @@ +import React from 'react'; +import { Box, Typography } from '@mui/material'; +import { useWalletContext } from '@src/context/wallet'; +import { useIsMobile } from '@src/hooks'; +import { TokenSVG } from '@src/icons/TokenSVG'; + +export const WalletBalance = () => { + const { balance } = useWalletContext(); + const isMobile = useIsMobile(1200); + + const showBalance = !isMobile && balance.status === 'success'; + + if (!showBalance) { + return null; + } + + return ( + <Box display="flex" alignItems="center" gap={1}> + <TokenSVG /> + <Typography variant="body1" fontWeight={600}> + {balance.data} NYM + </Typography> + </Box> + ); +}; diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index e696106e1a..163332bf19 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -2,10 +2,11 @@ import React from 'react'; import { ChainProvider } from '@cosmos-kit/react'; import { wallets as keplr } from '@cosmos-kit/keplr'; import { wallets as ledger } from '@cosmos-kit/ledger'; +import { wallets as cosmosstation } from '@cosmos-kit/cosmostation'; import { assets, chains } from 'chain-registry'; const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( - <ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger]}> + <ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger, ...cosmosstation]}> {children} </ChainProvider> ); diff --git a/explorer/src/context/wallet.tsx b/explorer/src/context/wallet.tsx new file mode 100644 index 0000000000..bb8432f284 --- /dev/null +++ b/explorer/src/context/wallet.tsx @@ -0,0 +1,90 @@ +import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; +import { useChain } from '@cosmos-kit/react'; +import { Wallet } from '@cosmos-kit/core'; + +import { unymToNym } from '@src/utils/currency'; +import { useNymClient } from '@src/hooks'; +import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client'; + +interface WalletState { + balance: { status: 'loading' | 'success'; data?: string }; + address?: string; + isWalletConnected: boolean; + isWalletConnecting: boolean; + wallet?: Wallet; + nymClient?: MixnetClient; + nymQueryClient?: MixnetQueryClient; + connectWallet: () => Promise<void>; + disconnectWallet: () => Promise<void>; +} + +export const WalletContext = createContext<WalletState>({ + address: undefined, + balance: { status: 'loading', data: undefined }, + isWalletConnected: false, + isWalletConnecting: false, + nymClient: undefined, + nymQueryClient: undefined, + connectWallet: async () => { + throw new Error('Please connect your wallet'); + }, + disconnectWallet: async () => { + throw new Error('Please connect your wallet'); + }, +}); + +export const WalletProvider = ({ children }: { children: React.ReactNode }) => { + const [balance, setBalance] = useState<WalletState['balance']>({ status: 'loading', data: undefined }); + + const { connect, disconnect, wallet, address, isWalletConnected, isWalletConnecting, getCosmWasmClient } = + useChain('nyx'); + + const { nymClient, nymQueryClient } = useNymClient(address); + + const getBalance = async (walletAddress: string) => { + const account = await getCosmWasmClient(); + const uNYMBalance = await account.getBalance(walletAddress, 'unym'); + const NYMBalance = unymToNym(uNYMBalance.amount); + + return NYMBalance; + }; + + const init = async (walletAddress: string) => { + const walletBalance = await getBalance(walletAddress); + setBalance({ status: 'success', data: walletBalance }); + }; + + useEffect(() => { + if (isWalletConnected && address) { + init(address); + } + }, [address, isWalletConnected]); + + const handleConnectWallet = async () => { + await connect(); + }; + + const handleDisconnectWallet = async () => { + await disconnect(); + setBalance({ status: 'loading', data: undefined }); + }; + + const contextValue: WalletState = useMemo( + () => ({ + address, + balance, + wallet, + isWalletConnected, + isWalletConnecting, + nymClient, + nymQueryClient, + connectWallet: handleConnectWallet, + disconnectWallet: handleDisconnectWallet, + }), + [address, balance, wallet, isWalletConnected, isWalletConnecting, nymClient, nymQueryClient], + ); + + return <WalletContext.Provider value={contextValue}>{children}</WalletContext.Provider>; +}; + +export const useWalletContext = () => useContext(WalletContext); diff --git a/explorer/src/hooks/useNymClient.tsx b/explorer/src/hooks/useNymClient.tsx new file mode 100644 index 0000000000..b9c5d92b67 --- /dev/null +++ b/explorer/src/hooks/useNymClient.tsx @@ -0,0 +1,31 @@ +import { useEffect, useState } from 'react'; +import { useChain } from '@cosmos-kit/react'; +import { contracts } from '@nymproject/contract-clients'; +import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client'; +import { NYM_MIXNET_CONTRACT } from '@src/api/constants'; + +export const useNymClient = (address?: string) => { + const [nymClient, setNymClient] = useState<MixnetClient>(); + const [nymQueryClient, setNymQueryClient] = useState<MixnetQueryClient>(); + + const { getCosmWasmClient, getSigningCosmWasmClient } = useChain('nyx'); + + useEffect(() => { + if (address) { + const init = async () => { + const cosmWasmSigningClient = await getSigningCosmWasmClient(); + const cosmWasmClient = await getCosmWasmClient(); + + const client = new contracts.Mixnet.MixnetClient(cosmWasmSigningClient as any, address, NYM_MIXNET_CONTRACT); + const queryClient = new contracts.Mixnet.MixnetQueryClient(cosmWasmClient as any, NYM_MIXNET_CONTRACT); + + setNymClient(client); + setNymQueryClient(queryClient); + }; + + init(); + } + }, [address, getCosmWasmClient, getSigningCosmWasmClient]); + + return { nymClient, nymQueryClient }; +}; From 7602f4b1309d69e7855ed63f37e5f3e549ea85b5 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Mar 2024 10:17:29 +0000 Subject: [PATCH 184/394] create delegations context and page --- .../components/Delegations/DelegateModal.tsx | 57 +---- explorer/src/context/delegations.tsx | 200 ++++++++++++++++ explorer/src/hooks/index.ts | 1 + explorer/src/icons/ElipsSVG.tsx | 2 +- explorer/src/pages/Delegations/index.tsx | 223 ++++++++++++++++++ explorer/src/routes/index.tsx | 2 + 6 files changed, 439 insertions(+), 46 deletions(-) create mode 100644 explorer/src/context/delegations.tsx create mode 100644 explorer/src/pages/Delegations/index.tsx diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx index fc12f82664..9ebf719661 100644 --- a/explorer/src/components/Delegations/DelegateModal.tsx +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -1,15 +1,15 @@ -import React, { useState, useEffect } from 'react'; +import React, { useState } from 'react'; import { Box, SxProps } from '@mui/material'; import { IdentityKeyFormField } from '@nymproject/react/mixnodes/IdentityKeyFormField'; import { CurrencyFormField } from '@nymproject/react/currency/CurrencyFormField'; import { CurrencyDenom, DecCoin } from '@nymproject/types'; -import { useChain } from '@cosmos-kit/react'; +import { useWalletContext } from '@src/context/wallet'; +import { useDelegationsContext } from '@src/context/delegations'; import { SimpleModal } from './SimpleModal'; import { ModalListItem } from './ModalListItem'; import { DelegationModalProps } from './DelegationModal'; -import { unymToNym, validateAmount } from '../../utils/currency'; +import { validateAmount } from '../../utils/currency'; import { urls } from '../../utils'; -import { NYM_MIXNET_CONTRACT } from '../../api/constants'; const MIN_AMOUNT_TO_DELEGATE = 10; @@ -31,25 +31,9 @@ export const DelegateModal: FCWithChildren<{ const [amount, setAmount] = useState<DecCoin | undefined>({ amount: '10', denom: 'nym' }); const [isValidated, setValidated] = useState<boolean>(false); const [errorAmount, setErrorAmount] = useState<string | undefined>(); - const [balance, setBalance] = useState<{ - status: 'loading' | 'success'; - data?: string; - }>({ status: 'loading', data: undefined }); - const { address, getCosmWasmClient, getSigningCosmWasmClient } = useChain('nyx'); - - const getBalance = async (walletAddress: string) => { - const account = await getCosmWasmClient(); - const uNYMBalance = await account.getBalance(walletAddress, 'unym'); - const NYMBalance = unymToNym(uNYMBalance.amount); - - setBalance({ status: 'success', data: NYMBalance }); - }; - useEffect(() => { - if (address) { - getBalance(address); - } - }, [address]); + const { address, balance } = useWalletContext(); + const { handleDelegate } = useDelegationsContext(); const validate = async () => { let newValidatedValue = true; @@ -59,7 +43,6 @@ export const DelegateModal: FCWithChildren<{ newValidatedValue = false; errorAmountMessage = 'Please enter a valid amount'; } - console.log(amount, MIN_AMOUNT_TO_DELEGATE); if (amount && +amount.amount < MIN_AMOUNT_TO_DELEGATE) { errorAmountMessage = `Min. delegation amount: ${MIN_AMOUNT_TO_DELEGATE} ${denom.toUpperCase()}`; @@ -81,32 +64,13 @@ export const DelegateModal: FCWithChildren<{ const delegateToMixnode = async ({ delegationMixId, - delgationAddress, delegationAmount, }: { delegationMixId: number; - delgationAddress: string; delegationAmount: string; }) => { - const amountToDelegate = (Number(delegationAmount) * 1000000).toString(); - const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }]; - const memo: string = 'test delegation'; - const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] }; - try { - const signerClient = await getSigningCosmWasmClient(); - const tx = await signerClient.execute( - delgationAddress, - NYM_MIXNET_CONTRACT, - { - delegate_to_mixnode: { - mix_id: delegationMixId, - }, - }, - fee, - memo, - uNymFunds, - ); + const tx = await handleDelegate(delegationMixId, delegationAmount); return tx; } catch (e) { console.error('Failed to delegateToMixnode', e); @@ -126,10 +90,13 @@ export const DelegateModal: FCWithChildren<{ const tx = await delegateToMixnode({ delegationMixId: mixId, - delgationAddress: address, delegationAmount: amount.amount, }); + if (!tx) { + throw new Error('Failed to delegate'); + } + onOk({ status: 'success', message: 'This operation can take up to one hour to process', @@ -138,7 +105,7 @@ export const DelegateModal: FCWithChildren<{ ], }); } catch (e) { - console.error('Failed to addDelegation', e); + console.error('Failed to delegate', e); onOk({ status: 'error', message: (e as Error).message, diff --git a/explorer/src/context/delegations.tsx b/explorer/src/context/delegations.tsx new file mode 100644 index 0000000000..d77e967332 --- /dev/null +++ b/explorer/src/context/delegations.tsx @@ -0,0 +1,200 @@ +import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'; +import { ExecuteResult } from '@cosmjs/cosmwasm-stargate'; +import { Delegation, PendingEpochEventKind } from '@nymproject/contract-clients/Mixnet.types'; +import { useWalletContext } from './wallet'; +import { useMainContext } from './main'; + +const fee = { gas: '1000000', amount: [{ amount: '1000000', denom: 'unym' }] }; + +export type PendingEvent = ReturnType<typeof getEventsByAddress>; + +export type DelegationWithRewards = Delegation & { + rewards: string; + identityKey: string; + pending: PendingEvent; +}; + +const getEventsByAddress = (kind: PendingEpochEventKind, address: String) => { + if ('delegate' in kind && kind.delegate.owner === address) { + return { + kind: 'delegate' as const, + mixId: kind.delegate.mix_id, + amount: kind.delegate.amount, + }; + } + + if ('undelegate' in kind && kind.undelegate.owner === address) { + return { + kind: 'undelegate' as const, + mixId: kind.undelegate.mix_id, + }; + } + + return undefined; +}; + +interface DelegationsState { + delegations?: DelegationWithRewards[]; + handleGetDelegations: () => Promise<void>; + handleDelegate: (mixId: number, amount: string) => Promise<ExecuteResult | undefined>; + handleUndelegate: (mixId: number) => Promise<ExecuteResult | undefined>; +} + +export const DelegationsContext = createContext<DelegationsState>({ + delegations: undefined, + handleGetDelegations: async () => { + throw new Error('Please connect your wallet'); + }, + handleDelegate: async () => { + throw new Error('Please connect your wallet'); + }, + handleUndelegate: async () => { + throw new Error('Please connect your wallet'); + }, +}); + +export const DelegationsProvider = ({ children }: { children: React.ReactNode }) => { + const [delegations, setDelegations] = useState<DelegationWithRewards[]>(); + const { address, nymQueryClient, nymClient } = useWalletContext(); + const { fetchMixnodes } = useMainContext(); + + const handleGetPendingEvents = async () => { + if (!nymQueryClient) { + return undefined; + } + + if (!address) { + return undefined; + } + + const response = await nymQueryClient.getPendingEpochEvents({}); + const pendingEvents: PendingEvent[] = []; + + response.events.forEach((e) => { + const event = getEventsByAddress(e.event.kind, address); + if (event) { + pendingEvents.push(event); + } + }); + + return pendingEvents; + }; + + const handleGetDelegationRewards = async (mixId: number) => { + if (!nymQueryClient) { + return undefined; + } + + if (!address) { + return undefined; + } + + const response = await nymQueryClient.getPendingDelegatorReward({ address, mixId }); + + return response; + }; + + const handleGetDelegations = useCallback(async () => { + if (!nymQueryClient) { + setDelegations(undefined); + return undefined; + } + + if (!address) { + setDelegations(undefined); + return undefined; + } + + // Get all mixnodes - Required to get the identity key for each delegation + const mixnodes = await fetchMixnodes(); + + // Get delegations + const delegationsResponse = await nymQueryClient.getDelegatorDelegations({ delegator: address }); + + // Get rewards for each delegation + const rewardsResponse = await Promise.all( + delegationsResponse.delegations.map((d) => handleGetDelegationRewards(d.mix_id)), + ); + + // Get all pending events + const pendingEvents = await handleGetPendingEvents(); + + const delegationsWithRewards: DelegationWithRewards[] = []; + + // Merge delegations with rewards and pending events + delegationsResponse.delegations.forEach((d, index) => { + delegationsWithRewards.push({ + ...d, + pending: pendingEvents?.find((e) => (e?.mixId === d.mix_id ? e.kind : undefined)), + identityKey: mixnodes?.find((m) => m.mix_id === d.mix_id)?.mix_node.identity_key || '', + rewards: rewardsResponse[index]?.amount_earned_detailed || '0', + }); + }); + + // Add pending events that are not in the delegations list + pendingEvents?.forEach((e) => { + if (e && !delegationsWithRewards.find((d) => d.mix_id === e.mixId)) { + delegationsWithRewards.push({ + mix_id: e.mixId, + height: 0, + cumulative_reward_ratio: '0', + owner: address, + amount: { + amount: '0', + denom: 'unym', + }, + rewards: '0', + identityKey: mixnodes?.find((m) => m.mix_id === e.mixId)?.mix_node.identity_key || '', + pending: e, + }); + } + }); + + setDelegations(delegationsWithRewards); + + return undefined; + }, [address, nymQueryClient]); + + const handleDelegate = async (mixId: number, amount: string) => { + if (!address) { + throw new Error('Please connect your wallet'); + } + + const amountToDelegate = (Number(amount) * 1000000).toString(); + const uNymFunds = [{ amount: amountToDelegate, denom: 'unym' }]; + try { + const tx = await nymClient?.delegateToMixnode({ mixId }, fee, 'Delegation from Nym Explorer', uNymFunds); + + return tx; + } catch (e) { + console.error('Failed to delegate to mixnode', e); + throw e; + } + }; + + const handleUndelegate = async (mixId: number) => { + const tx = await nymClient?.undelegateFromMixnode({ mixId }, fee); + + return tx; + }; + + const contextValue: DelegationsState = useMemo( + () => ({ + delegations, + handleGetDelegations, + handleDelegate, + handleUndelegate, + }), + [delegations, handleGetDelegations], + ); + + return <DelegationsContext.Provider value={contextValue}>{children}</DelegationsContext.Provider>; +}; + +export const useDelegationsContext = () => { + const context = useContext(DelegationsContext); + if (!context) { + throw new Error('useDelegationsContext must be used within a DelegationsProvider'); + } + return context; +}; diff --git a/explorer/src/hooks/index.ts b/explorer/src/hooks/index.ts index e2c94ec1e4..ba04855f77 100644 --- a/explorer/src/hooks/index.ts +++ b/explorer/src/hooks/index.ts @@ -1,3 +1,4 @@ export * from './useIsMobile'; export * from './useIsMounted'; export * from './useGetMixnodeStatusColor'; +export * from './useNymClient'; diff --git a/explorer/src/icons/ElipsSVG.tsx b/explorer/src/icons/ElipsSVG.tsx index 6ced45169f..4a430d6cb6 100644 --- a/explorer/src/icons/ElipsSVG.tsx +++ b/explorer/src/icons/ElipsSVG.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; export const ElipsSVG: FCWithChildren = () => ( <svg xmlns="http://www.w3.org/2000/svg" width="24" height="25" viewBox="0 0 24 25" fill="none"> - <circle cx="12" cy="12.5" r="12" fill="url(#paint0_angular_2549_7570)" /> + <circle cx="12" cy="12.5" r="10" fill="url(#paint0_angular_2549_7570)" /> <defs> <radialGradient id="paint0_angular_2549_7570" diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx new file mode 100644 index 0000000000..7702bc87b2 --- /dev/null +++ b/explorer/src/pages/Delegations/index.tsx @@ -0,0 +1,223 @@ +import React, { useEffect } from 'react'; +import { Box, Button, Card, Chip, Tooltip, Typography } from '@mui/material'; +import { Link, useNavigate } from 'react-router-dom'; +import { DelegationModal, DelegationModalProps, Title, UniversalDataGrid } from '@src/components'; +import { useWalletContext } from '@src/context/wallet'; +import { ConnectKeplrWallet } from '@src/components/Wallet/ConnectKeplrWallet'; +import { GridColDef } from '@mui/x-data-grid'; +import { unymToNym } from '@src/utils/currency'; +import { + DelegationWithRewards, + DelegationsProvider, + PendingEvent, + useDelegationsContext, +} from '@src/context/delegations'; + +const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) => ({ + identity: delegation.identityKey, + mix_id: delegation.mix_id, + amount: `${unymToNym(delegation.amount.amount)} NYM`, + rewards: `${unymToNym(delegation.rewards)} NYM`, + id: index, + pending: delegation.pending, +}); + +const DelegationsPage = () => { + const [confirmationModalProps, setConfirmationModalProps] = React.useState<DelegationModalProps | undefined>(); + const [isLoading, setIsLoading] = React.useState(false); + + const { isWalletConnected } = useWalletContext(); + const { handleGetDelegations, handleUndelegate, delegations } = useDelegationsContext(); + const navigate = useNavigate(); + + useEffect(() => { + let timeoutId: NodeJS.Timeout; + + const fetchDelegations = async () => { + setIsLoading(true); + try { + await handleGetDelegations(); + } catch (error) { + setConfirmationModalProps({ + status: 'error', + message: "Couldn't fetch delegations. Please try again later.", + }); + } finally { + setIsLoading(false); + + timeoutId = setTimeout(() => { + fetchDelegations(); + }, 60_000); + } + }; + + fetchDelegations(); + + return () => { + clearTimeout(timeoutId); + }; + }, [handleGetDelegations]); + + const getTooltipTitle = (pending: PendingEvent) => { + if (pending?.kind === 'undelegate') { + return 'You have an undelegation pending'; + } + + if (pending?.kind === 'delegate') { + return `You have a delegation pending worth ${unymToNym(pending.amount.amount)} NYM`; + } + + return undefined; + }; + + const onUndelegate = async (mixId: number) => { + setConfirmationModalProps({ status: 'loading' }); + + try { + const tx = await handleUndelegate(mixId); + + if (tx) { + setConfirmationModalProps({ + status: 'success', + message: 'Undelegation successful', + transactions: [{ url: `${tx.transactionHash}`, hash: tx.transactionHash }], + }); + } + } catch (error) { + if (error instanceof Error) { + setConfirmationModalProps({ status: 'error', message: error.message }); + } + } + }; + + const columns: GridColDef[] = [ + { + field: 'identity', + headerName: 'Identity Key', + width: 400, + disableColumnMenu: true, + disableReorder: true, + sortable: false, + headerAlign: 'left', + }, + { + field: 'mix_id', + headerName: 'Mix ID', + width: 150, + disableColumnMenu: true, + disableReorder: true, + sortable: false, + headerAlign: 'left', + }, + { + field: 'amount', + headerName: 'Amount', + width: 150, + disableColumnMenu: true, + disableReorder: true, + sortable: false, + headerAlign: 'left', + }, + { + field: 'rewards', + headerName: 'Rewards', + width: 150, + disableColumnMenu: true, + disableReorder: true, + sortable: false, + headerAlign: 'left', + }, + { + field: 'undelegate', + headerName: '', + minWidth: 150, + flex: 1, + disableColumnMenu: true, + disableReorder: true, + sortable: false, + headerAlign: 'right', + renderCell: (params) => { + const { pending } = params.row; + + return ( + <Box sx={{ width: '100%', display: 'flex', justifyContent: 'end' }}> + {pending ? ( + <Tooltip + placement="left" + title={getTooltipTitle(pending as PendingEvent)} + onClick={(e) => e.stopPropagation()} + PopperProps={{}} + > + <Chip size="small" label="Pending events" /> + </Tooltip> + ) : ( + <Button + size="small" + variant="outlined" + onClick={(e) => { + e.stopPropagation(); + onUndelegate(params.row.mix_id); + }} + > + Undelegate + </Button> + )} + </Box> + ); + }, + }, + ]; + + const handleRowClick = (params: any) => { + navigate(`/network-components/mixnode/${params.row.mix_id}`); + }; + + return ( + <Box> + {confirmationModalProps && ( + <DelegationModal + {...confirmationModalProps} + open={Boolean(confirmationModalProps)} + onClose={async () => { + await handleGetDelegations(); + setConfirmationModalProps(undefined); + }} + /> + )} + <Box display="flex" justifyContent="space-between" alignItems="center"> + <Title text="Your Delegations" /> + <Button variant="contained" color="primary" component={Link} to="/network-components/mixnodes"> + Delegate + </Button> + </Box> + {!isWalletConnected ? ( + <Box> + <Typography mb={2} variant="h6"> + Connect your wallet to view your delegations. + </Typography> + <ConnectKeplrWallet /> + </Box> + ) : null} + <Card + sx={{ + mt: 2, + padding: 2, + height: '100%', + }} + > + <UniversalDataGrid + onRowClick={handleRowClick} + rows={delegations?.map(mapToDelegationsRow) || []} + columns={columns} + loading={isLoading} + /> + </Card> + </Box> + ); +}; + +export const Delegations = () => ( + <DelegationsProvider> + <DelegationsPage /> + </DelegationsProvider> +); diff --git a/explorer/src/routes/index.tsx b/explorer/src/routes/index.tsx index 57e015495d..67ef8b4621 100644 --- a/explorer/src/routes/index.tsx +++ b/explorer/src/routes/index.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import { Routes as ReactRouterRoutes, Route } from 'react-router-dom'; +import { Delegations } from '@src/pages/Delegations'; import { PageOverview } from '../pages/Overview'; import { PageMixnodesMap } from '../pages/MixnodesMap'; import { Page404 } from '../pages/404'; @@ -10,6 +11,7 @@ export const Routes: FCWithChildren = () => ( <Route path="/" element={<PageOverview />} /> <Route path="/network-components/*" element={<NetworkComponentsRoutes />} /> <Route path="/nodemap" element={<PageMixnodesMap />} /> + <Route path="/delegations" element={<Delegations />} /> <Route path="*" element={<Page404 />} /> </ReactRouterRoutes> ); From 6b25f83ee3842466f74f34196c7dd7de8fba91bf Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Mar 2024 10:19:03 +0000 Subject: [PATCH 185/394] small UI updates tidy up some text layouts + allow mixnode row selections --- explorer/src/components/Title.tsx | 1 - .../src/components/Universal-DataGrid.tsx | 6 ++-- explorer/src/pages/Gateways/index.tsx | 4 ++- explorer/src/pages/Mixnodes/index.tsx | 34 +++++++++++++------ 4 files changed, 31 insertions(+), 14 deletions(-) diff --git a/explorer/src/components/Title.tsx b/explorer/src/components/Title.tsx index 9380d2c9c5..032837d3c8 100644 --- a/explorer/src/components/Title.tsx +++ b/explorer/src/components/Title.tsx @@ -5,7 +5,6 @@ export const Title: FCWithChildren<{ text: string }> = ({ text }) => ( <Typography variant="h5" sx={{ - mb: 3, fontWeight: 600, }} data-testid={text} diff --git a/explorer/src/components/Universal-DataGrid.tsx b/explorer/src/components/Universal-DataGrid.tsx index 0dc19edda8..6598dfb485 100644 --- a/explorer/src/components/Universal-DataGrid.tsx +++ b/explorer/src/components/Universal-DataGrid.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { makeStyles } from '@mui/styles'; -import { DataGrid, GridColDef, useGridApiContext, useGridState } from '@mui/x-data-grid'; +import { DataGrid, GridColDef, GridEventListener, useGridApiContext, useGridState } from '@mui/x-data-grid'; import Pagination from '@mui/material/Pagination'; import { LinearProgress } from '@mui/material'; import { GridInitialStateCommunity } from '@mui/x-data-grid/models/gridStateCommunity'; @@ -36,6 +36,7 @@ type DataGridProps = { rows: any; loading?: boolean; initialState?: GridInitialStateCommunity; + onRowClick?: GridEventListener<'rowClick'> | undefined; }; export const UniversalDataGrid: FCWithChildren<DataGridProps> = ({ rows, @@ -44,11 +45,13 @@ export const UniversalDataGrid: FCWithChildren<DataGridProps> = ({ pagination, pageSize, initialState, + onRowClick, }) => { if (loading) return <LinearProgress />; return ( <DataGrid + onRowClick={onRowClick} pagination={pagination} rows={rows} components={{ @@ -84,7 +87,6 @@ export const UniversalDataGrid: FCWithChildren<DataGridProps> = ({ }} /> ); - return null; }; UniversalDataGrid.defaultProps = { diff --git a/explorer/src/pages/Gateways/index.tsx b/explorer/src/pages/Gateways/index.tsx index 78da55d1ab..c04b7eaf40 100644 --- a/explorer/src/pages/Gateways/index.tsx +++ b/explorer/src/pages/Gateways/index.tsx @@ -232,7 +232,9 @@ export const PageGateways: FCWithChildren = () => { if (gateways?.data) { return ( <> - <Title text="Gateways" /> + <Box mb={2}> + <Title text="Gateways" /> + </Box> <Grid container> <Grid item xs={12}> <Card diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 5baf4a546f..5e5caf9d2f 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -1,10 +1,9 @@ import * as React from 'react'; import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; -import { Stack, Card, Grid, Box } from '@mui/material'; -import { useParams, useNavigate } from 'react-router-dom'; +import { Stack, Card, Grid, Box, Button } from '@mui/material'; +import { useParams, useNavigate, Link } from 'react-router-dom'; import { SelectChangeEvent } from '@mui/material/Select'; import { CopyToClipboard } from '@nymproject/react/clipboard/CopyToClipboard'; -import { useWallet } from '@cosmos-kit/react'; import { useMainContext } from '@src/context/main'; import { DelegateIconButton, @@ -25,6 +24,8 @@ import { NYM_BIG_DIPPER } from '@src/api/constants'; import { currencyToString } from '@src/utils/currency'; import { splice } from '@src/utils'; import { useGetMixNodeStatusColor, useIsMobile } from '@src/hooks'; +import { useWalletContext } from '@src/context/wallet'; +import { DelegationsProvider } from '@src/context/delegations'; export const PageMixnodes: FCWithChildren = () => { const { mixnodes, fetchMixnodes } = useMainContext(); @@ -39,7 +40,7 @@ export const PageMixnodes: FCWithChildren = () => { const { status } = useParams<{ status: MixnodeStatusWithAll | undefined }>(); const navigate = useNavigate(); - const wallet = useWallet(); + const { isWalletConnected } = useWalletContext(); const isMobile = useIsMobile(); const handleNewDelegation = (delegationModalProps: DelegationModalProps) => { @@ -85,7 +86,7 @@ export const PageMixnodes: FCWithChildren = () => { }; const handleOnDelegate = ({ identityKey, mixId }: { identityKey: string; mixId: number }) => { - if (wallet.status !== 'Connected') { + if (!isWalletConnected) { setConfirmationModalProps({ status: 'info', message: 'Please connect your wallet to delegate', @@ -349,8 +350,10 @@ export const PageMixnodes: FCWithChildren = () => { }; return ( - <> - <Title text="Mixnodes" /> + <DelegationsProvider> + <Box mb={2}> + <Title text="Mixnodes" /> + </Box> <Grid container> <Grid item xs={12}> <Card @@ -363,6 +366,13 @@ export const PageMixnodes: FCWithChildren = () => { childrenBefore={ <MixNodeStatusDropdown sx={{ mr: 2 }} status={status} onSelectionChanged={handleMixnodeStatusChanged} /> } + childrenAfter={ + isWalletConnected && ( + <Button fullWidth size="large" variant="outlined" color="primary" component={Link} to="/delegations"> + Delegations + </Button> + ) + } onChangeSearch={handleSearch} onChangePageSize={handlePageSize} pageSize={pageSize} @@ -382,7 +392,9 @@ export const PageMixnodes: FCWithChildren = () => { {itemSelectedForDelegation && ( <DelegateModal - onClose={() => setItemSelectedForDelegation(undefined)} + onClose={() => { + setItemSelectedForDelegation(undefined); + }} header="Delegate" buttonText="Delegate stake" denom="nym" @@ -398,10 +410,12 @@ export const PageMixnodes: FCWithChildren = () => { open={Boolean(confirmationModalProps)} onClose={async () => { setConfirmationModalProps(undefined); - // await fetchBalance(); + if (confirmationModalProps.status === 'success') { + navigate('/delegations'); + } }} /> )} - </> + </DelegationsProvider> ); }; From 7db4ddff5646e38bc563fd51c10a49049b0ac672 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Mar 2024 10:20:26 +0000 Subject: [PATCH 186/394] use url as unique nav selection state --- explorer/src/components/MobileNav.tsx | 7 +++---- explorer/src/components/Nav.tsx | 13 +++++-------- explorer/src/context/main.tsx | 6 +++--- explorer/src/context/nav.tsx | 15 +++++++-------- explorer/src/pages/ServiceProviders/index.tsx | 6 ++++-- 5 files changed, 22 insertions(+), 25 deletions(-) diff --git a/explorer/src/components/MobileNav.tsx b/explorer/src/components/MobileNav.tsx index 224bd69b0c..ac4b313467 100644 --- a/explorer/src/components/MobileNav.tsx +++ b/explorer/src/components/MobileNav.tsx @@ -8,7 +8,7 @@ import { useMainContext } from '../context/main'; import { MobileDrawerClose } from '../icons/MobileDrawerClose'; import { Footer } from './Footer'; import { ExpandableButton } from './Nav'; -import { ConnectKeplrWallet } from './ConnectKeplrWallet'; +import { ConnectKeplrWallet } from './Wallet/ConnectKeplrWallet'; import NetworkTitle from './NetworkTitle'; export const MobileNav: FCWithChildren = ({ children }) => { @@ -23,8 +23,8 @@ export const MobileNav: FCWithChildren = ({ children }) => { setDrawerOpen(!drawerOpen); }; - const handleClick = (id: number) => { - updateNavState(id); + const handleClick = (url: string) => { + updateNavState(url); toggleDrawer(); }; @@ -103,7 +103,6 @@ export const MobileNav: FCWithChildren = ({ children }) => { {navState.map((props) => ( <ExpandableButton key={props.url} - id={props.id} title={props.title} openDrawer={openDrawer} url={props.url} diff --git a/explorer/src/components/Nav.tsx b/explorer/src/components/Nav.tsx index c5cfc9a00b..a0f5b16fec 100644 --- a/explorer/src/components/Nav.tsx +++ b/explorer/src/components/Nav.tsx @@ -23,7 +23,7 @@ import { MobileDrawerClose } from '../icons/MobileDrawerClose'; import { Footer } from './Footer'; import { DarkLightSwitchDesktop } from './Switch'; import { NavOptionType } from '../context/nav'; -import { ConnectKeplrWallet } from './ConnectKeplrWallet'; +import { ConnectKeplrWallet } from './Wallet/ConnectKeplrWallet'; const drawerWidth = 255; const bannerHeight = 80; @@ -72,7 +72,6 @@ const Drawer = styled(MuiDrawer, { })); type ExpandableButtonType = { - id: number; title: string; url: string; isActive?: boolean; @@ -85,11 +84,10 @@ type ExpandableButtonType = { drawIsFixed: boolean; fixDrawerClose?: () => void; isMobile: boolean; - setToActive: (num: number) => void; + setToActive: (url: string) => void; }; export const ExpandableButton: FCWithChildren<ExpandableButtonType> = ({ - id, url, setToActive, isActive, @@ -110,7 +108,7 @@ export const ExpandableButton: FCWithChildren<ExpandableButtonType> = ({ const { palette } = useTheme(); const handleClick = () => { - setToActive(id); + setToActive(url); if (title === 'Network Components' && nested) { openDrawer(); toggleNestedOptions(!nestedOptions); @@ -204,7 +202,6 @@ export const ExpandableButton: FCWithChildren<ExpandableButtonType> = ({ {nestedOptions && nested?.map((each) => ( <ExpandableButton - id={each.id} url={each.url} key={each.title} title={each.title} @@ -246,8 +243,8 @@ export const Nav: FCWithChildren = ({ children }) => { const switchNetworkLink = environment === 'mainnet' ? 'https://sandbox-explorer.nymtech.net' : 'https://explorer.nymtech.net'; - const setToActive = (id: number) => { - updateNavState(id); + const setToActive = (url: string) => { + updateNavState(url); }; const fixDrawerOpen = () => { diff --git a/explorer/src/context/main.tsx b/explorer/src/context/main.tsx index ad01e36d44..c7a74a3d0d 100644 --- a/explorer/src/context/main.tsx +++ b/explorer/src/context/main.tsx @@ -35,7 +35,7 @@ interface StateApi { fetchMixnodes: (status?: MixnodeStatus) => Promise<MixNodeResponse | undefined>; filterMixnodes: (filters: any, status: any) => void; toggleMode: () => void; - updateNavState: (id: number) => void; + updateNavState: (title: string) => void; } type State = StateData & StateApi; @@ -185,10 +185,10 @@ export const MainContextProvider: FCWithChildren = ({ children }) => { } }; - const updateNavState = (id: number) => { + const updateNavState = (url: string) => { const updated = navState.map((option) => ({ ...option, - isActive: option.id === id, + isActive: option.url === url, })); updateNav(updated); }; diff --git a/explorer/src/context/nav.tsx b/explorer/src/context/nav.tsx index ad65e0e50b..6df749f585 100644 --- a/explorer/src/context/nav.tsx +++ b/explorer/src/context/nav.tsx @@ -1,11 +1,11 @@ import * as React from 'react'; +import { DelegateIcon } from '@src/icons/DelevateSVG'; import { BIG_DIPPER } from '../api/constants'; import { OverviewSVG } from '../icons/OverviewSVG'; import { NodemapSVG } from '../icons/NodemapSVG'; import { NetworkComponentsSVG } from '../icons/NetworksSVG'; export type NavOptionType = { - id: number; isActive?: boolean; url: string; title: string; @@ -16,46 +16,45 @@ export type NavOptionType = { export const originalNavOptions: NavOptionType[] = [ { - id: 0, isActive: false, url: '/', title: 'Overview', Icon: <OverviewSVG />, }, { - id: 1, isActive: false, url: '/network-components', title: 'Network Components', Icon: <NetworkComponentsSVG />, nested: [ { - id: 3, url: '/network-components/mixnodes', title: 'Mixnodes', }, { - id: 4, url: '/network-components/gateways', title: 'Gateways', }, { - id: 5, url: `${BIG_DIPPER}/validators`, title: 'Validators', }, { - id: 6, url: 'network-components/service-providers', title: 'Service Providers', }, ], }, { - id: 2, isActive: false, url: '/nodemap', title: 'Nodemap', Icon: <NodemapSVG />, }, + { + isActive: false, + url: '/delegations', + title: 'Delegations', + Icon: <DelegateIcon />, + }, ]; diff --git a/explorer/src/pages/ServiceProviders/index.tsx b/explorer/src/pages/ServiceProviders/index.tsx index 144f578e44..618aa72924 100644 --- a/explorer/src/pages/ServiceProviders/index.tsx +++ b/explorer/src/pages/ServiceProviders/index.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Button, Card, FormControl, Grid, ListItem, Menu, SelectChangeEvent, Typography } from '@mui/material'; +import { Box, Button, Card, FormControl, Grid, ListItem, Menu, SelectChangeEvent, Typography } from '@mui/material'; import { GridColDef, GridRenderCellParams } from '@mui/x-data-grid'; import { TableToolbar } from '../../components/TableToolbar'; import { Title } from '../../components/Title'; @@ -90,7 +90,9 @@ export const ServiceProviders = () => { return ( <> - <Title text="Service Providers" /> + <Box mb={2}> + <Title text="Service Providers" /> + </Box> <Grid container> <Grid item xs={12}> <Card From 496a1bc97d85c641f617f5a9e2a2831ea3a34bdf Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 12 Mar 2024 10:20:38 +0000 Subject: [PATCH 187/394] package updates --- explorer/package.json | 3 + explorer/src/components/Wallet/index.ts | 2 + explorer/src/index.tsx | 15 +++-- explorer/webpack.config.js | 6 ++ yarn.lock | 73 +++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 6 deletions(-) create mode 100644 explorer/src/components/Wallet/index.ts diff --git a/explorer/package.json b/explorer/package.json index bd3a6cd57c..045c96e629 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -27,6 +27,8 @@ "@cosmjs/math": "^0.26.2", "@cosmjs/stargate": "^0.32.0", "@cosmjs/tendermint-rpc": "^0.32.0", + "@cosmos-kit/core": "^2.8.9", + "@cosmos-kit/cosmostation": "^2.6.10", "@cosmos-kit/keplr": "^2.6.9", "@cosmos-kit/ledger": "^2.6.9", "@cosmos-kit/react": "^2.10.10", @@ -38,6 +40,7 @@ "@mui/styles": "^5.0.1", "@mui/system": "^5.0.1", "@mui/x-data-grid": "^5.0.0-beta.5", + "@nymproject/contract-clients": "^1.2.4-rc.1", "@nymproject/mui-theme": "^1.0.0", "@nymproject/node-tester": "^1.0.0", "@nymproject/nym-validator-client": "^0.18.0", diff --git a/explorer/src/components/Wallet/index.ts b/explorer/src/components/Wallet/index.ts new file mode 100644 index 0000000000..645c8b4ffb --- /dev/null +++ b/explorer/src/components/Wallet/index.ts @@ -0,0 +1,2 @@ +export * from './WalletBalance'; +export * from './WalletAddress'; diff --git a/explorer/src/index.tsx b/explorer/src/index.tsx index 57e4315de9..0b76be7ab1 100644 --- a/explorer/src/index.tsx +++ b/explorer/src/index.tsx @@ -2,12 +2,13 @@ import * as React from 'react'; import { createRoot } from 'react-dom/client'; import { BrowserRouter as Router } from 'react-router-dom'; import { ErrorBoundary } from 'react-error-boundary'; -import { App } from './App'; import { MainContextProvider } from './context/main'; import { NetworkExplorerThemeProvider } from './theme'; import { ErrorBoundaryContent } from './errors/ErrorBoundaryContent'; import CosmosKitProvider from './context/cosmos-kit'; import '@interchain-ui/react/styles'; +import { App } from './App'; +import { WalletProvider } from './context/wallet'; import './styles.css'; const elem = document.getElementById('app'); @@ -18,11 +19,13 @@ if (elem) { <ErrorBoundary FallbackComponent={ErrorBoundaryContent}> <MainContextProvider> <CosmosKitProvider> - <NetworkExplorerThemeProvider> - <Router> - <App /> - </Router> - </NetworkExplorerThemeProvider> + <WalletProvider> + <NetworkExplorerThemeProvider> + <Router> + <App /> + </Router> + </NetworkExplorerThemeProvider> + </WalletProvider> </CosmosKitProvider> </MainContextProvider> </ErrorBoundary>, diff --git a/explorer/webpack.config.js b/explorer/webpack.config.js index e965fcd0cb..550951cb52 100644 --- a/explorer/webpack.config.js +++ b/explorer/webpack.config.js @@ -16,6 +16,12 @@ module.exports = mergeWithRules({ devtool: 'inline-source-map', module: { rules: [ + { + test: /\.m?js/, + resolve: { + fullySpecified: false, + }, + }, { test: /\.tsx?$/, use: 'ts-loader', diff --git a/yarn.lock b/yarn.lock index 5f49794e06..9b37189b65 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,6 +1267,26 @@ bfs-path "^1.0.2" cross-fetch "^3.1.5" +"@chain-registry/cosmostation@1.26.0": + version "1.26.0" + resolved "https://registry.yarnpkg.com/@chain-registry/cosmostation/-/cosmostation-1.26.0.tgz#0d3967b8d320168a5c9c7b56b3352dcf3f2945b0" + integrity sha512-MmjThpQ0U0EJF66UJzPy67iKC9hY7ljrpGtQOPfeYGB/lUlKZTsE/mgF2XkKGUf7wJK8LugOqU5Zul7C1/ZA4Q== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.17.0" + "@chain-registry/utils" "^1.15.0" + "@cosmostation/extension-client" "0.1.15" + +"@chain-registry/cosmostation@^1.26.0": + version "1.32.1" + resolved "https://registry.yarnpkg.com/@chain-registry/cosmostation/-/cosmostation-1.32.1.tgz#bdf079a4f45b5c884a33c48fb0b8d4eeaa26a743" + integrity sha512-U8YUkXKWQWmBbAJILXYqEFMnYES4fs+t8iriy6LucSyhICUs1nniMlulm04PYuiIy+bX0BpP5nlNp/CK/yzQkw== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.18.1" + "@chain-registry/utils" "^1.18.2" + "@cosmostation/extension-client" "0.1.15" + "@chain-registry/keplr@1.28.0": version "1.28.0" resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.28.0.tgz#c53d52ff0487eb6798722eb1cf5bd4dc82a141be" @@ -1292,6 +1312,23 @@ dependencies: "@babel/runtime" "^7.21.0" +"@chain-registry/types@^0.18.1": + version "0.18.1" + resolved "https://registry.yarnpkg.com/@chain-registry/types/-/types-0.18.1.tgz#bd926ddf204f2ae986a79b42f0cfe85764e2977a" + integrity sha512-H/UnOyd7WdcWHa2FGKxy4MclDDFrbE2rFwaUh9oubNJOey7UBI4dNF10oZIWM/1by15LUgDz45fVbh6uA6W5Tg== + dependencies: + "@babel/runtime" "^7.21.0" + +"@chain-registry/utils@^1.15.0", "@chain-registry/utils@^1.18.2": + version "1.18.2" + resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.2.tgz#fa67e8179afad45011c031a1181824133412e6c6" + integrity sha512-X1vBFxdMVRGFW/6fLUQgJ4aG/2RaDYDDEeDA5/x/MlssGtdSBEyytd7M9zO0uS51QYy1ysIhkG3OyZLoyGdurg== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.18.1" + bignumber.js "9.1.1" + sha.js "^2.4.11" + "@chain-registry/utils@^1.18.0": version "1.18.0" resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.0.tgz#d711efc2660b3b65077a5bee90b45ddc6af2194f" @@ -1893,6 +1930,32 @@ events "3.3.0" uuid "^9.0.1" +"@cosmos-kit/cosmostation-extension@^2.7.10": + version "2.7.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation-extension/-/cosmostation-extension-2.7.10.tgz#2120fa826c692732e7c539a35141df0f8e832876" + integrity sha512-x0rBk4Ht6uicfZxIXRbwUi5WHrvKsI11oXbf9bYL9nRBfRTgpbO6zIW9791oTVjiJLzHbKaBQoqh1R233YcHbg== + dependencies: + "@chain-registry/cosmostation" "^1.26.0" + "@cosmos-kit/core" "^2.8.9" + cosmjs-types "^0.9.0" + +"@cosmos-kit/cosmostation-mobile@^2.6.9": + version "2.6.9" + resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation-mobile/-/cosmostation-mobile-2.6.9.tgz#1c304ac12cccc05de93c9ed927243d51087426f6" + integrity sha512-GjZetNMFrz2oLisdp14ahxftkwPz5v1OYRGvD4MLTdMSA71JUTzX8A4At4uo4M7nwG09H1yQ2/CLQy9XGVRinA== + dependencies: + "@chain-registry/cosmostation" "1.26.0" + "@cosmos-kit/core" "^2.8.9" + "@cosmos-kit/walletconnect" "^2.5.9" + +"@cosmos-kit/cosmostation@^2.6.10": + version "2.6.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation/-/cosmostation-2.6.10.tgz#406d93a29c154e988f4d60425d8edbba4f0cd455" + integrity sha512-DWR28fnkv04yr5Eyo/CS7yOiYr3cwld9lE/F2qGIYGb2Tw/eUWhKSl05+2ly8S15xoKOXT7wxXOsFIXYYUQ8/g== + dependencies: + "@cosmos-kit/cosmostation-extension" "^2.7.10" + "@cosmos-kit/cosmostation-mobile" "^2.6.9" + "@cosmos-kit/keplr-extension@^2.7.9": version "2.7.9" resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.7.9.tgz#16586c94452a5e65713cdead07446447c511fa0e" @@ -1958,6 +2021,11 @@ "@walletconnect/utils" "^2.9.0" events "3.3.0" +"@cosmostation/extension-client@0.1.15": + version "0.1.15" + resolved "https://registry.yarnpkg.com/@cosmostation/extension-client/-/extension-client-0.1.15.tgz#cdc6d8fce42217704c1c0d5814f0ee7ce27e8dab" + integrity sha512-HlXYJjFrNpjiV/GUKhri1UL8/bhlOIFFLpRF78YDSqq16x0+plIqx5CAvEusFcKTDpVfpeD5sfUHiKvP7euNFg== + "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -3391,6 +3459,11 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== +"@nymproject/contract-clients@^1.2.4-rc.1": + version "1.2.4-rc.1" + resolved "https://registry.yarnpkg.com/@nymproject/contract-clients/-/contract-clients-1.2.4-rc.1.tgz#10b385f63d8b33beea6bf47d948fc7cc0c6c2357" + integrity sha512-WMiEIHNxc9oTZ8GxAE8278ifpNJ2AIZHEw4JifN1WRhn2XViYaDDJaPCA3o0p+WGRySmqdurHmployr3iUEz1Q== + "@nymproject/node-tester@^1.0.0", "@nymproject/node-tester@^1.2.3": version "1.2.3" resolved "https://registry.yarnpkg.com/@nymproject/node-tester/-/node-tester-1.2.3.tgz#79fbde8b69e2d1180eed897557c4610a1aa1038f" From 0e11cf92fc8ee3e8d9e634984697b7389936f280 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 13 Mar 2024 10:42:33 +0000 Subject: [PATCH 188/394] allow setting whole chain details in a single method --- common/network-defaults/src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index ffd5ff6384..608b6237c6 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -185,6 +185,12 @@ impl NymNetworkDetails { self } + #[must_use] + pub fn with_chain_details(mut self, chain_details: ChainDetails) -> Self { + self.chain_details = chain_details; + self + } + #[must_use] pub fn with_bech32_account_prefix<S: Into<String>>(mut self, prefix: S) -> Self { self.chain_details.bech32_account_prefix = prefix.into(); @@ -227,6 +233,12 @@ impl NymNetworkDetails { self } + #[must_use] + pub fn with_contracts(mut self, contracts: NymContracts) -> Self { + self.contracts = contracts; + self + } + #[must_use] pub fn with_mixnet_contract<S: Into<String>>(mut self, contract: Option<S>) -> Self { self.contracts.mixnet_contract_address = contract.map(Into::into); From 490319d961d547b58512cf5d75803e43d07b1d95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 13 Mar 2024 11:17:26 +0000 Subject: [PATCH 189/394] making contract addresses optional in the env --- common/network-defaults/src/lib.rs | 37 +++++++++++--------------- common/network-defaults/src/mainnet.rs | 12 +++++---- envs/local.env | 2 -- envs/mainnet.env | 9 ++----- envs/qa.env | 1 - 5 files changed, 24 insertions(+), 37 deletions(-) diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index ffd5ff6384..446ae8da35 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -79,7 +79,13 @@ impl NymNetworkDetails { pub fn new_from_env() -> Self { fn get_optional_env<K: AsRef<OsStr>>(env: K) -> Option<String> { match var(env) { - Ok(var) => Some(var), + Ok(var) => { + if var.is_empty() { + None + } else { + Some(var) + } + } Err(VarError::NotPresent) => None, err => panic!("Unable to set: {:?}", err), } @@ -113,28 +119,15 @@ impl NymNetworkDetails { Some(var(var_names::NYM_API).expect("nym api not set")), get_optional_env(var_names::NYXD_WEBSOCKET), )) - .with_mixnet_contract(Some( - var(var_names::MIXNET_CONTRACT_ADDRESS).expect("mixnet contract not set"), - )) - .with_vesting_contract(Some( - var(var_names::VESTING_CONTRACT_ADDRESS).expect("vesting contract not set"), - )) - .with_coconut_bandwidth_contract(Some( - var(var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS) - .expect("coconut bandwidth contract not set"), - )) - .with_group_contract(Some( - var(var_names::GROUP_CONTRACT_ADDRESS).expect("group contract not set"), - )) - .with_multisig_contract(Some( - var(var_names::MULTISIG_CONTRACT_ADDRESS).expect("multisig contract not set"), - )) - .with_coconut_dkg_contract(Some( - var(var_names::COCONUT_DKG_CONTRACT_ADDRESS).expect("coconut dkg contract not set"), - )) - .with_ephemera_contract(Some( - var(var_names::EPHEMERA_CONTRACT_ADDRESS).expect("ephemera contract not set"), + .with_mixnet_contract(get_optional_env(var_names::MIXNET_CONTRACT_ADDRESS)) + .with_vesting_contract(get_optional_env(var_names::VESTING_CONTRACT_ADDRESS)) + .with_coconut_bandwidth_contract(get_optional_env( + var_names::COCONUT_BANDWIDTH_CONTRACT_ADDRESS, )) + .with_group_contract(get_optional_env(var_names::GROUP_CONTRACT_ADDRESS)) + .with_multisig_contract(get_optional_env(var_names::MULTISIG_CONTRACT_ADDRESS)) + .with_coconut_dkg_contract(get_optional_env(var_names::COCONUT_DKG_CONTRACT_ADDRESS)) + .with_ephemera_contract(get_optional_env(var_names::EPHEMERA_CONTRACT_ADDRESS)) .with_service_provider_directory_contract(get_optional_env( var_names::SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS, )) diff --git a/common/network-defaults/src/mainnet.rs b/common/network-defaults/src/mainnet.rs index 4cd9d0f53c..041bd116b1 100644 --- a/common/network-defaults/src/mainnet.rs +++ b/common/network-defaults/src/mainnet.rs @@ -16,11 +16,13 @@ pub const MIXNET_CONTRACT_ADDRESS: &str = "n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr"; pub const VESTING_CONTRACT_ADDRESS: &str = "n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw"; -pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; -pub const GROUP_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; -pub const MULTISIG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; -pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; -pub const EPHEMERA_CONTRACT_ADDRESS: &str = "n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0"; + +pub const COCONUT_BANDWIDTH_CONTRACT_ADDRESS: &str = ""; +pub const GROUP_CONTRACT_ADDRESS: &str = ""; +pub const MULTISIG_CONTRACT_ADDRESS: &str = ""; +pub const COCONUT_DKG_CONTRACT_ADDRESS: &str = ""; +pub const EPHEMERA_CONTRACT_ADDRESS: &str = ""; + pub const REWARDING_VALIDATOR_ADDRESS: &str = "n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy"; pub const STATISTICS_SERVICE_DOMAIN_ADDRESS: &str = "https://mainnet-stats.nymte.ch:8090/"; diff --git a/envs/local.env b/envs/local.env index 0fba848a3e..32d5516ccf 100644 --- a/envs/local.env +++ b/envs/local.env @@ -22,5 +22,3 @@ REWARDING_VALIDATOR_ADDRESS=n1tfzd4qz3a45u8p4mr5zmzv66457uwjgcl05jdq STATISTICS_SERVICE_DOMAIN_ADDRESS="http://0.0.0.0" NYXD="http://127.0.0.1:26657" NYM_API="http://127.0.0.1:8000" - -DKG_TIME_CONFIGURATION="600,300,300,60,60,1209600" diff --git a/envs/mainnet.env b/envs/mainnet.env index 018b4f2e38..e0b19d027a 100644 --- a/envs/mainnet.env +++ b/envs/mainnet.env @@ -11,18 +11,13 @@ MIX_DENOM_DISPLAY=nym STAKE_DENOM=unyx STAKE_DENOM_DISPLAY=nyx DENOMS_EXPONENT=6 + MIXNET_CONTRACT_ADDRESS=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr VESTING_CONTRACT_ADDRESS=n1nc5tatafv6eyq7llkr2gv50ff9e22mnf70qgjlv737ktmt4eswrq73f2nw -COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 -GROUP_CONTRACT_ADDRESS=n1rw8fw2mpcpzzq3jpa4e52ufawnmj5a4u68p35umvgskewuw0nlzsaa5w4m -MULTISIG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 -COCONUT_DKG_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 -EPHEMERA_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 + REWARDING_VALIDATOR_ADDRESS=n10yyd98e2tuwu0f7ypz9dy3hhjw7v772q6287gy STATISTICS_SERVICE_DOMAIN_ADDRESS="https://mainnet-stats.nymte.ch:8090" NYXD="https://rpc.nymtech.net" NYM_API="https://validator.nymtech.net/api/" NYXD_WS="wss://rpc.nymtech.net/websocket" EXPLORER_API="https://explorer.nymtech.net/api/" - -DKG_TIME_CONFIGURATION="259200,300,300,60,60,1209600" diff --git a/envs/qa.env b/envs/qa.env index fa323cf41d..886fbb65d3 100644 --- a/envs/qa.env +++ b/envs/qa.env @@ -25,5 +25,4 @@ EXPLORER_API=https://qa-network-explorer.qa.nymte.ch/api NYXD="https://qa-validator.qa.nymte.ch" NYM_API="https://qa-nym-api.qa.nymte.ch/api" -DKG_TIME_CONFIGURATION="600,300,300,60,60,1209600" EXIT_POLICY="https://nymtech.net/.wellknown/network-requester/exit-policy.txt" \ No newline at end of file From 5e40e480bc3d7c493a5b64c0b8f42b5d7d68c109 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 13 Mar 2024 11:17:52 +0000 Subject: [PATCH 190/394] adjusting severity of logs for missing DKG contract in the gateway --- .../connection_handler/authenticated.rs | 3 +++ .../websocket/connection_handler/coconut.rs | 19 ++++++++++++++++--- gateway/src/node/mod.rs | 2 +- 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 6c9456224b..1de37065a3 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -92,6 +92,9 @@ pub(crate) enum RequestHandlingError { #[error("the provided credential did not have a bandwidth attribute")] MissingBandwidthAttribute, + + #[error("the DKG contract is unavailable")] + UnavailableDkgContract, } impl RequestHandlingError { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs index d075e01bb8..26a7e76640 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/coconut.rs @@ -36,6 +36,7 @@ pub(crate) struct CoconutVerifier { impl CoconutVerifier { pub async fn new( nyxd_client: DirectSigningHttpRpcNyxdClient, + only_coconut_credentials: bool, ) -> Result<Self, RequestHandlingError> { let mix_denom_base = nyxd_client.current_chain_details().mix_denom.base.clone(); let address = nyxd_client.address(); @@ -45,9 +46,17 @@ impl CoconutVerifier { // don't make it a hard failure in case we're running on mainnet (where DKG hasn't been deployed yet) if nyxd_client.dkg_contract_address().is_none() { - error!( - "DKG contract address is not available - no coconut credentials will be redeemable" - ); + if !only_coconut_credentials { + warn!( + "the DKG contract address is not available - \ + no coconut credentials will be redeemable \ + (if the DKG ceremony hasn't been run yet this warning is expected)" + ); + } else { + // if we require coconut credentials, we MUST have DKG contract available + return Err(RequestHandlingError::UnavailableDkgContract); + } + return Ok(CoconutVerifier { address, nyxd_client: RwLock::new(nyxd_client), @@ -60,6 +69,10 @@ impl CoconutVerifier { let Ok(current_epoch) = nyxd_client.get_current_epoch().await else { // another case of somebody putting a placeholder address that doesn't exist error!("the specified DKG contract address is invalid - no coconut credentials will be redeemable"); + if only_coconut_credentials { + // if we require coconut credentials, we MUST have DKG contract available + return Err(RequestHandlingError::UnavailableDkgContract); + } return Ok(CoconutVerifier { address, nyxd_client: RwLock::new(nyxd_client), diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 9fa6d1af8e..c5d280727e 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -456,7 +456,7 @@ impl<St> Gateway<St> { let coconut_verifier = { let nyxd_client = self.random_nyxd_client()?; - CoconutVerifier::new(nyxd_client).await + CoconutVerifier::new(nyxd_client, self.config.gateway.only_coconut_credentials).await }?; let mix_forwarding_channel = From da14947227a8758eea92f171001019b9c2e8c3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 13 Mar 2024 11:32:57 +0000 Subject: [PATCH 191/394] decreased logging level of gateway errors associated with the websocket --- .../websocket/connection_handler/authenticated.rs | 8 ++++---- .../client_handling/websocket/connection_handler/fresh.rs | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 6c9456224b..dbd5d28e7d 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -600,7 +600,7 @@ where None => break, Some(Ok(socket_msg)) => socket_msg, Some(Err(err)) => { - error!("failed to obtain message from websocket stream! stopping connection handler: {err}"); + debug!("failed to obtain message from websocket stream! stopping connection handler: {err}"); break; } }; @@ -611,7 +611,7 @@ where if let Some(response) = self.handle_request(socket_msg).await { if let Err(err) = self.inner.send_websocket_message(response).await { - warn!( + debug!( "Failed to send message over websocket: {err}. Assuming the connection is dead.", ); break; @@ -621,13 +621,13 @@ where mix_messages = self.mix_receiver.next() => { let mix_messages = match mix_messages { None => { - warn!("mix receiver was closed! Assuming the connection is dead."); + debug!("mix receiver was closed! Assuming the connection is dead."); break; } Some(mix_messages) => mix_messages, }; if let Err(err) = self.inner.push_packets_to_client(&self.client.shared_keys, mix_messages).await { - warn!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead"); + debug!("failed to send the unwrapped sphinx packets back to the client - {err}, assuming the connection is dead"); break; } } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 46dc7f5f80..93ef0508fd 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -667,7 +667,7 @@ where let msg = match msg { Ok(msg) => msg, Err(err) => { - error!("failed to obtain message from websocket stream! stopping connection handler: {err}"); + debug!("failed to obtain message from websocket stream! stopping connection handler: {err}"); break; } }; @@ -723,7 +723,7 @@ where Message::Binary(_) => { // perhaps logging level should be reduced here, let's leave it for now and see what happens // if client is working correctly, this should have never happened - warn!("possibly received a sphinx packet without prior authentication. Request is going to be ignored"); + debug!("possibly received a sphinx packet without prior authentication. Request is going to be ignored"); if let Err(err) = self .send_websocket_message( ServerResponse::new_error( From 3fcfbad4c0fce5a3bee09acc4f441f2650931d8c Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Wed, 13 Mar 2024 14:35:02 +0000 Subject: [PATCH 192/394] add sandbox to cosmos-kit --- explorer/.env.dev | 2 +- explorer/.env.prod | 1 + explorer/package.json | 3 ++- explorer/src/api/constants.ts | 1 + explorer/src/context/cosmos-kit.tsx | 37 ++++++++++++++++++++++++++++- explorer/src/context/wallet.tsx | 4 ++-- explorer/src/hooks/useNymClient.tsx | 4 ++-- yarn.lock | 10 ++++---- 8 files changed, 50 insertions(+), 12 deletions(-) diff --git a/explorer/.env.dev b/explorer/.env.dev index cc24e10870..1199cb5542 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -7,5 +7,5 @@ VALIDATOR_URL=https://rpc.sandbox.nymtech.net BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx - NYM_MIXNET_CONTRACT=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav +COSMOS_KIT_USE_CHAIN=sandbox diff --git a/explorer/.env.prod b/explorer/.env.prod index 70bd50c7ca..e71e710e15 100644 --- a/explorer/.env.prod +++ b/explorer/.env.prod @@ -4,3 +4,4 @@ VALIDATOR_URL=https://rpc.nymtech.net BIG_DIPPER_URL=https://blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx +COSMOS_KIT_USE_CHAIN=nyx \ No newline at end of file diff --git a/explorer/package.json b/explorer/package.json index 045c96e629..cccb3bc8a6 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -50,7 +50,7 @@ "big.js": "^6.2.1", "bs58": "^5.0.0", "buffer": "^6.0.3", - "chain-registry": "^1.19.0", + "chain-registry": "^1.29.1", "cosmjs-types": "^0.9.0", "d3-scale": "^4.0.0", "date-fns": "^2.24.0", @@ -69,6 +69,7 @@ }, "devDependencies": { "@babel/core": "^7.15.0", + "@chain-registry/types": "^0.18.1", "@nymproject/eslint-config-react-typescript": "^1.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", "@storybook/addon-actions": "^6.5.8", diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts index 66618a9b1f..d8d1227dd4 100644 --- a/explorer/src/api/constants.ts +++ b/explorer/src/api/constants.ts @@ -27,3 +27,4 @@ export const NYM_BIG_DIPPER = 'https://mixnet.explorers.guru'; export const NYM_MIXNET_CONTRACT = process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; +export const COSMOS_KIT_USE_CHAIN = process.env.COSMOS_KIT_USE_CHAIN || 'sandbox'; diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 163332bf19..d4b6fa51a6 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -4,9 +4,44 @@ import { wallets as keplr } from '@cosmos-kit/keplr'; import { wallets as ledger } from '@cosmos-kit/ledger'; import { wallets as cosmosstation } from '@cosmos-kit/cosmostation'; import { assets, chains } from 'chain-registry'; +import { Chain, AssetList } from '@chain-registry/types'; + +const nymSandbox: Chain = { + chain_name: 'sandbox', + chain_id: 'sandbox', + bech32_prefix: 'n', + network_type: 'devnet', + pretty_name: 'Nym Sandbox', + status: 'active', + slip44: 118, + apis: { + rpc: [ + { + address: 'https://rpc.sandbox.nymtech.net', + }, + ], + }, +}; + +const nymSandboxAssets: AssetList = { + chain_name: 'sandbox', + assets: [ + { + name: 'Nym', + base: 'unym', + symbol: 'NYM', + display: 'NYM', + denom_units: [], + }, + ], +}; const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( - <ChainProvider chains={chains} assetLists={assets} wallets={[...keplr, ...ledger, ...cosmosstation]}> + <ChainProvider + chains={[...chains, nymSandbox]} + assetLists={[...assets, nymSandboxAssets]} + wallets={[...keplr, ...ledger, ...cosmosstation]} + > {children} </ChainProvider> ); diff --git a/explorer/src/context/wallet.tsx b/explorer/src/context/wallet.tsx index bb8432f284..8ac26ee7ca 100644 --- a/explorer/src/context/wallet.tsx +++ b/explorer/src/context/wallet.tsx @@ -1,10 +1,10 @@ import React, { createContext, useContext, useEffect, useMemo, useState } from 'react'; import { useChain } from '@cosmos-kit/react'; import { Wallet } from '@cosmos-kit/core'; - import { unymToNym } from '@src/utils/currency'; import { useNymClient } from '@src/hooks'; import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client'; +import { COSMOS_KIT_USE_CHAIN } from '@src/api/constants'; interface WalletState { balance: { status: 'loading' | 'success'; data?: string }; @@ -37,7 +37,7 @@ export const WalletProvider = ({ children }: { children: React.ReactNode }) => { const [balance, setBalance] = useState<WalletState['balance']>({ status: 'loading', data: undefined }); const { connect, disconnect, wallet, address, isWalletConnected, isWalletConnecting, getCosmWasmClient } = - useChain('nyx'); + useChain(COSMOS_KIT_USE_CHAIN); const { nymClient, nymQueryClient } = useNymClient(address); diff --git a/explorer/src/hooks/useNymClient.tsx b/explorer/src/hooks/useNymClient.tsx index b9c5d92b67..26b2f529db 100644 --- a/explorer/src/hooks/useNymClient.tsx +++ b/explorer/src/hooks/useNymClient.tsx @@ -2,13 +2,13 @@ import { useEffect, useState } from 'react'; import { useChain } from '@cosmos-kit/react'; import { contracts } from '@nymproject/contract-clients'; import { MixnetClient, MixnetQueryClient } from '@nymproject/contract-clients/Mixnet.client'; -import { NYM_MIXNET_CONTRACT } from '@src/api/constants'; +import { COSMOS_KIT_USE_CHAIN, NYM_MIXNET_CONTRACT } from '@src/api/constants'; export const useNymClient = (address?: string) => { const [nymClient, setNymClient] = useState<MixnetClient>(); const [nymQueryClient, setNymQueryClient] = useState<MixnetQueryClient>(); - const { getCosmWasmClient, getSigningCosmWasmClient } = useChain('nyx'); + const { getCosmWasmClient, getSigningCosmWasmClient } = useChain(COSMOS_KIT_USE_CHAIN); useEffect(() => { if (address) { diff --git a/yarn.lock b/yarn.lock index 48562d8db0..9051f41ec8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9332,13 +9332,13 @@ ccount@^2.0.0: resolved "https://registry.yarnpkg.com/ccount/-/ccount-2.0.1.tgz#17a3bf82302e0870d6da43a01311a8bc02a3ecf5" integrity sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg== -chain-registry@^1.19.0: - version "1.20.0" - resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.20.0.tgz#1442a1d715a7ebf57781aeb185e3cbaa7b08196c" - integrity sha512-kBeQVdopECXasauhaA+HiJNSB0UpzNmxtv5AvIpJBAZc3nuM2wzPxaHAiPz1OG5ifYwMraOkvPNxwOnXd1nZzw== +chain-registry@^1.29.1: + version "1.29.1" + resolved "https://registry.yarnpkg.com/chain-registry/-/chain-registry-1.29.1.tgz#15b0392af72a95ec6eab5f4c74cb8f28eec1b80f" + integrity sha512-1VdBKme094W3NzsQO7rZkCtGVYnxFGtouv6o+qBdwcRsBUqrhD+QCfNhvuQXa10vKnnpByIDlO9Xg10mx/3KWw== dependencies: "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.17.0" + "@chain-registry/types" "^0.18.1" chalk@4.1.0: version "4.1.0" From b037c8fbebfc9580b86c396f3aaf03990d8e2c53 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Thu, 14 Mar 2024 09:50:31 +0000 Subject: [PATCH 193/394] test mobile delegations config --- explorer/.env.dev | 4 ++-- explorer/src/api/constants.ts | 1 + explorer/src/context/cosmos-kit.tsx | 8 +++++++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/explorer/.env.dev b/explorer/.env.dev index 1199cb5542..95110f2f4d 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -7,5 +7,5 @@ VALIDATOR_URL=https://rpc.sandbox.nymtech.net BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx -NYM_MIXNET_CONTRACT=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav -COSMOS_KIT_USE_CHAIN=sandbox +NYM_MIXNET_CONTRACT=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr +COSMOS_KIT_USE_CHAIN=nyx diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts index d8d1227dd4..0cd224c6f2 100644 --- a/explorer/src/api/constants.ts +++ b/explorer/src/api/constants.ts @@ -28,3 +28,4 @@ export const NYM_BIG_DIPPER = 'https://mixnet.explorers.guru'; export const NYM_MIXNET_CONTRACT = process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; export const COSMOS_KIT_USE_CHAIN = process.env.COSMOS_KIT_USE_CHAIN || 'sandbox'; +export const WALLET_CONNECT_PROJECT_ID = process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID || ''; diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index d4b6fa51a6..94c5f45f95 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -5,6 +5,7 @@ import { wallets as ledger } from '@cosmos-kit/ledger'; import { wallets as cosmosstation } from '@cosmos-kit/cosmostation'; import { assets, chains } from 'chain-registry'; import { Chain, AssetList } from '@chain-registry/types'; +import { WALLET_CONNECT_PROJECT_ID } from '@src/api/constants'; const nymSandbox: Chain = { chain_name: 'sandbox', @@ -35,12 +36,17 @@ const nymSandboxAssets: AssetList = { }, ], }; - +console.log(WALLET_CONNECT_PROJECT_ID, 'WALLET_CONNECT_PROJECT_ID'); const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( <ChainProvider chains={[...chains, nymSandbox]} assetLists={[...assets, nymSandboxAssets]} wallets={[...keplr, ...ledger, ...cosmosstation]} + walletConnectOptions={{ + signClient: { + projectId: WALLET_CONNECT_PROJECT_ID, + }, + }} > {children} </ChainProvider> From 6735c1ae585d2f1899e4ef8a64b7cf20b5a130b5 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Thu, 14 Mar 2024 21:10:10 +0000 Subject: [PATCH 194/394] append to env (dont overwrite) --- explorer/src/api/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts index 0cd224c6f2..372708f9cc 100644 --- a/explorer/src/api/constants.ts +++ b/explorer/src/api/constants.ts @@ -28,4 +28,4 @@ export const NYM_BIG_DIPPER = 'https://mixnet.explorers.guru'; export const NYM_MIXNET_CONTRACT = process.env.NYM_MIXNET_CONTRACT || 'n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr'; export const COSMOS_KIT_USE_CHAIN = process.env.COSMOS_KIT_USE_CHAIN || 'sandbox'; -export const WALLET_CONNECT_PROJECT_ID = process.env.REACT_APP_WALLET_CONNECT_PROJECT_ID || ''; +export const WALLET_CONNECT_PROJECT_ID = process.env.WALLET_CONNECT_PROJECT_ID || ''; From 25053e5e8ac223919811f5766802b5acb12f339b Mon Sep 17 00:00:00 2001 From: Drazen Urch <drazen@urch.eu> Date: Fri, 15 Mar 2024 14:59:52 +0100 Subject: [PATCH 195/394] Promethus is our friend (#4408) * Generic prom wrapper idea * Extend packet_statistics control with prom metrics * Replace counters with Counters * Add legacy mixnode api route * fmt * Sanitize metric names * Format metrics * Script to make prom targets * More metrics * Update script * Make sure we dont panic in the future * Remove fragile test * Add metrics endpoint auth * Remove per IP metrics * Update target script, node_exporter setup * Remove prom from client * Simplify node stat * Centralize metrice, break cpucycles temporarily * Remove prometheus from mixnode * Add cpu-cycles to Prom * Further centralize Registry * Cleanup old tracing * Remove spurious assignment * Move cpu-cycles to metrics * Add features * setup_logging before logging * Remove cpucycle measurement in favour of time * Cleanup, hygine --- Cargo.lock | 94 +++++---- Cargo.toml | 25 ++- common/mixnode-common/Cargo.toml | 10 +- common/mixnode-common/src/lib.rs | 37 ---- .../src/packet_processor/processor.rs | 23 +-- common/nym-metrics/Cargo.toml | 18 ++ common/nym-metrics/src/lib.rs | 180 ++++++++++++++++++ mixnode/Cargo.toml | 17 +- mixnode/src/commands/init.rs | 4 + mixnode/src/commands/mod.rs | 2 + mixnode/src/commands/run.rs | 4 + mixnode/src/config/mod.rs | 10 + mixnode/src/config/old_config_v1_1_32.rs | 1 + mixnode/src/config/template.rs | 2 + mixnode/src/main.rs | 28 +-- mixnode/src/node/http/legacy/mod.rs | 3 + mixnode/src/node/http/legacy/state.rs | 1 + mixnode/src/node/http/legacy/stats.rs | 44 ++++- mixnode/src/node/http/mod.rs | 6 + .../node/listener/connection_handler/mod.rs | 11 +- mixnode/src/node/mod.rs | 3 + mixnode/src/node/node_statistics.rs | 135 ++++++------- nym-node/src/config/mod.rs | 4 + scripts/localnet_start.sh | 6 +- scripts/node_exporter.sh | 83 ++++++++ scripts/prom_targets.py | 63 ++++++ scripts/requirements.txt | 1 + 27 files changed, 569 insertions(+), 246 deletions(-) create mode 100644 common/nym-metrics/Cargo.toml create mode 100644 common/nym-metrics/src/lib.rs create mode 100644 scripts/node_exporter.sh create mode 100644 scripts/prom_targets.py create mode 100644 scripts/requirements.txt diff --git a/Cargo.lock b/Cargo.lock index c3df2e1c05..b8d97ce94f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1429,14 +1429,6 @@ dependencies = [ "thiserror", ] -[[package]] -name = "cpu-cycles" -version = "0.1.0" -dependencies = [ - "cfg-if", - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.9" @@ -1916,12 +1908,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" +checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" dependencies = [ - "darling_core 0.20.3", - "darling_macro 0.20.3", + "darling_core 0.20.5", + "darling_macro 0.20.5", ] [[package]] @@ -1954,9 +1946,9 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" +checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" dependencies = [ "fnv", "ident_case", @@ -1990,11 +1982,11 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.3" +version = "0.20.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" +checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" dependencies = [ - "darling_core 0.20.3", + "darling_core 0.20.5", "quote", "syn 2.0.38", ] @@ -5717,6 +5709,17 @@ dependencies = [ "url", ] +[[package]] +name = "nym-metrics" +version = "0.1.0" +dependencies = [ + "dashmap", + "lazy_static", + "log", + "prometheus", + "regex", +] + [[package]] name = "nym-mixnet-client" version = "0.1.0" @@ -5757,19 +5760,19 @@ dependencies = [ "anyhow", "axum", "bs58 0.5.0", - "cfg-if", "clap 4.4.7", "colored", - "cpu-cycles", "cupid", "dirs 4.0.0", "futures", "humantime-serde", + "lazy_static", "log", "nym-bin-common", "nym-config", "nym-contracts-common", "nym-crypto", + "nym-metrics", "nym-mixnet-client", "nym-mixnode-common", "nym-node", @@ -5782,7 +5785,6 @@ dependencies = [ "nym-topology", "nym-types", "nym-validator-client", - "opentelemetry", "rand 0.7.3", "serde", "serde_json", @@ -5791,7 +5793,6 @@ dependencies = [ "tokio", "tokio-util", "toml 0.5.11", - "tracing", "url", ] @@ -5800,13 +5801,12 @@ name = "nym-mixnode-common" version = "0.1.0" dependencies = [ "bytes", - "cfg-if", - "cpu-cycles", "futures", "humantime-serde", "log", "nym-bin-common", "nym-crypto", + "nym-metrics", "nym-network-defaults", "nym-sphinx-acknowledgements", "nym-sphinx-addressing", @@ -5821,7 +5821,6 @@ dependencies = [ "thiserror", "tokio", "tokio-util", - "tracing", "url", ] @@ -7441,6 +7440,21 @@ dependencies = [ "yansi", ] +[[package]] +name = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot 0.12.1", + "protobuf", + "thiserror", +] + [[package]] name = "prometheus-client" version = "0.19.0" @@ -7563,10 +7577,16 @@ dependencies = [ ] [[package]] -name = "psl" -version = "2.1.14" +name = "protobuf" +version = "2.28.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "383703acfc34f7a00724846c14dc5ea4407c59e5aedcbbb18a1c0c1a23fe5013" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + +[[package]] +name = "psl" +version = "2.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc74a6e6a56708be1cf5c4c4d1a0dc21d33b2dcaa24e731b7fa9c287ce4f916f" dependencies = [ "psl-types", ] @@ -7962,13 +7982,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.6", "regex-syntax 0.8.2", ] @@ -7983,9 +8003,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" dependencies = [ "aho-corasick", "memchr", @@ -8808,9 +8828,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" +checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981" dependencies = [ "base64 0.21.4", "chrono", @@ -8825,11 +8845,11 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.4.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" +checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15" dependencies = [ - "darling 0.20.3", + "darling 0.20.5", "proc-macro2", "quote", "syn 2.0.38", diff --git a/Cargo.toml b/Cargo.toml index d67b66149a..45afdbdb2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -32,7 +32,7 @@ members = [ "common/cosmwasm-smart-contracts/coconut-bandwidth-contract", "common/cosmwasm-smart-contracts/coconut-dkg", "common/cosmwasm-smart-contracts/contracts-common", -# "common/cosmwasm-smart-contracts/ephemera", + # "common/cosmwasm-smart-contracts/ephemera", "common/cosmwasm-smart-contracts/group-contract", "common/cosmwasm-smart-contracts/mixnet-contract", "common/cosmwasm-smart-contracts/multisig-contract", @@ -57,6 +57,7 @@ members = [ "common/nonexhaustive-delayqueue", "common/nymcoconut", "common/nym-id", + "common/nym-metrics", "common/nymsphinx", "common/nymsphinx/acknowledgements", "common/nymsphinx/addressing", @@ -112,9 +113,10 @@ members = [ "tools/nymvisor", "tools/ts-rs-cli", "wasm/client", -# "wasm/full-nym-wasm", + # "wasm/full-nym-wasm", "wasm/mix-fetch", "wasm/node-tester", + "common/nym-metrics", ] default-members = [ @@ -130,7 +132,16 @@ default-members = [ "nym-validator-rewarder", ] -exclude = ["explorer", "contracts", "nym-wallet", "nym-connect/mobile/src-tauri", "nym-connect/desktop", "nym-vpn/ui/src-tauri", "cpu-cycles", "sdk/ffi/cpp"] +exclude = [ + "explorer", + "contracts", + "nym-wallet", + "nym-connect/mobile/src-tauri", + "nym-connect/desktop", + "nym-vpn/ui/src-tauri", + "cpu-cycles", + "sdk/ffi/cpp", +] [workspace.package] authors = ["Nym Technologies SA"] @@ -180,10 +191,12 @@ utoipa-swagger-ui = "3.1.5" url = "2.4" zeroize = "1.6.0" +prometheus = { version = "0.13.0" } + # coconut/DKG related # unfortunately until https://github.com/zkcrypto/bls12_381/issues/10 is resolved, we have to rely on the fork # as we need to be able to serialize Gt so that we could create the lookup table for baby-step-giant-step algorithm -bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch ="feature/gt-serialization-0.8.0" } +bls12_381 = { git = "https://github.com/jstuczyn/bls12_381", branch = "feature/gt-serialization-0.8.0" } group = "0.13.0" ff = "0.13.0" @@ -208,9 +221,9 @@ cw-controllers = { version = "=1.1.0" } bip32 = "0.5.1" # temporarily using a fork again (yay.) because we need staking and slashing support -cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch ="nym-temp/all-validator-features" } +cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } #cosmrs = { git = "https://github.com/jstuczyn/cosmos-rust", branch = "nym-temp/all-validator-features" } # unfortuntely we need a fork by yours truly to get the staking support -tendermint = "0.34" # same version as used by cosmrs +tendermint = "0.34" # same version as used by cosmrs tendermint-rpc = "0.34" # same version as used by cosmrs prost = "0.12" diff --git a/common/mixnode-common/Cargo.toml b/common/mixnode-common/Cargo.toml index 9cf2c51cf0..0ee39302e3 100644 --- a/common/mixnode-common/Cargo.toml +++ b/common/mixnode-common/Cargo.toml @@ -25,9 +25,6 @@ tokio-util = { workspace = true, features = ["codec"] } url = { workspace = true } thiserror = { workspace = true } -## tracing -tracing = { version = "0.1.37", optional = true } - nym-crypto = { path = "../crypto" } nym-network-defaults = { path = "../network-defaults" } nym-sphinx-acknowledgements = { path = "../nymsphinx/acknowledgements" } @@ -39,9 +36,4 @@ nym-sphinx-types = { path = "../nymsphinx/types" } nym-task = { path = "../task" } nym-validator-client = { path = "../client-libs/validator-client" } nym-bin-common = { path = "../bin-common" } - -cfg-if = "1.0.0" -cpu-cycles = { path = "../../cpu-cycles", optional = true } - -[features] -cpucycles = ["cpu-cycles", "tracing"] +nym-metrics = { path = "../nym-metrics" } diff --git a/common/mixnode-common/src/lib.rs b/common/mixnode-common/src/lib.rs index 9689b157a5..4ab41c6040 100644 --- a/common/mixnode-common/src/lib.rs +++ b/common/mixnode-common/src/lib.rs @@ -2,40 +2,3 @@ // SPDX-License-Identifier: Apache-2.0 pub mod packet_processor; pub mod verloc; - -pub fn cpu_cycles() -> Result<i64, Box<dyn std::error::Error>> { - cfg_if::cfg_if! { - if #[cfg(feature = "cpucycles")] { - Ok(cpu_cycles::cpucycles()?) - } else { - Err("`cpucycles` feature is not turned on!".into()) - } - } -} - -#[macro_export] -macro_rules! measure { - ( $x:expr ) => {{ - cfg_if::cfg_if! { - if #[cfg(feature = "cpucycles")] { - let start_cycles = $crate::cpu_cycles(); - // if the block needs to return something, we can return it - let r = $x; - let end_cycles = $crate::cpu_cycles(); - let name = if let Some(meta) = tracing::Span::current().metadata() { - meta.name() - } else { - "measure" - }; - match (start_cycles, end_cycles) { - (Ok(start), Ok(end)) => log::trace!("{} cpucycles: {}", name, end - start), - (Err(e), _) => error!("{e}"), - (_, Err(e)) => error!("{e}"), - } - r - } else { - $x - } - } - }}; -} diff --git a/common/mixnode-common/src/packet_processor/processor.rs b/common/mixnode-common/src/packet_processor/processor.rs index 314a7f68cb..b2fe24a1e9 100644 --- a/common/mixnode-common/src/packet_processor/processor.rs +++ b/common/mixnode-common/src/packet_processor/processor.rs @@ -1,9 +1,9 @@ // Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::measure; use crate::packet_processor::error::MixProcessingError; use log::*; +use nym_metrics::nanos; use nym_sphinx_acknowledgements::surb_ack::SurbAck; use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; use nym_sphinx_forwarding::packet::MixPacket; @@ -15,8 +15,6 @@ use nym_sphinx_types::{ }; use std::convert::TryFrom; use std::sync::Arc; -#[cfg(feature = "cpucycles")] -use tracing::instrument; type ForwardAck = MixPacket; @@ -51,15 +49,11 @@ impl SphinxPacketProcessor { } /// Performs a fresh sphinx unwrapping using no cache. - #[cfg_attr( - feature = "cpucycles", - instrument(skip(self, packet), fields(cpucycles)) - )] fn perform_initial_packet_processing( &self, packet: NymPacket, ) -> Result<NymProcessedPacket, MixProcessingError> { - measure!({ + nanos!("perform_initial_packet_processing", { packet.process(&self.sphinx_key).map_err(|err| { debug!("Failed to unwrap NymPacket packet: {err}"); MixProcessingError::NymPacketProcessingError(err) @@ -68,17 +62,12 @@ impl SphinxPacketProcessor { } /// Takes the received framed packet and tries to unwrap it from the sphinx encryption. - #[cfg_attr( - feature = "cpucycles", - instrument(skip(self, received), fields(cpucycles)) - )] fn perform_initial_unwrapping( &self, received: FramedNymPacket, ) -> Result<NymProcessedPacket, MixProcessingError> { - measure!({ + nanos!("perform_initial_unwrapping", { let packet = received.into_inner(); - self.perform_initial_packet_processing(packet) }) } @@ -223,16 +212,12 @@ impl SphinxPacketProcessor { } } - #[cfg_attr( - feature = "cpucycles", - instrument(skip(self, received), fields(cpucycles)) - )] pub fn process_received( &self, received: FramedNymPacket, ) -> Result<MixProcessingResult, MixProcessingError> { // explicit packet size will help to correctly parse final hop - measure!({ + nanos!("process_received", { let packet_size = received.packet_size(); let packet_type = received.packet_type(); diff --git a/common/nym-metrics/Cargo.toml b/common/nym-metrics/Cargo.toml new file mode 100644 index 0000000000..0b49297719 --- /dev/null +++ b/common/nym-metrics/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "nym-metrics" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +prometheus = { workspace = true } +log = { workspace = true } +dashmap = { workspace = true } +regex = "1.1" +lazy_static = "1.4" diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs new file mode 100644 index 0000000000..d67aae7b94 --- /dev/null +++ b/common/nym-metrics/src/lib.rs @@ -0,0 +1,180 @@ +use dashmap::DashMap; +pub use log::error; +use log::{debug, warn}; +use regex::Regex; +use std::fmt; +pub use std::time::Instant; + +use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; + +#[macro_export] +macro_rules! nanos { + ( $name:literal, $x:expr ) => {{ + let start = $crate::Instant::now(); + // if the block needs to return something, we can return it + let r = $x; + let duration = start.elapsed().as_nanos() as f64; + $crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration); + r + }}; +} + +lazy_static::lazy_static! { + pub static ref RE: Regex = Regex::new(r"[^a-zA-Z0-9_]").unwrap(); + pub static ref REGISTRY: MetricsController = MetricsController::default(); +} + +#[derive(Default)] +pub struct MetricsController { + registry: Registry, + registry_index: DashMap<String, Metric>, +} + +enum Metric { + C(Box<Counter>), + G(Box<Gauge>), +} + +fn fq_name(c: &dyn Collector) -> String { + c.desc() + .first() + .map(|d| d.fq_name.clone()) + .unwrap_or_default() +} + +impl Metric { + fn fq_name(&self) -> String { + match self { + Metric::C(c) => fq_name(c.as_ref()), + Metric::G(g) => fq_name(g.as_ref()), + } + } + + fn inc_by(&self, value: f64) { + match self { + Metric::C(c) => c.inc_by(value), + Metric::G(g) => g.add(value), + } + } + + fn set(&self, value: f64) { + match self { + Metric::C(_c) => { + warn!("Cannot set value for counter {:?}", self.fq_name()); + } + Metric::G(g) => g.set(value), + } + } +} + +impl fmt::Display for MetricsController { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + let mut buffer = vec![]; + let encoder = TextEncoder::new(); + let metrics = self.registry.gather(); + match encoder.encode(&metrics, &mut buffer) { + Ok(_) => {} + Err(e) => return write!(f, "Error encoding metrics to buffer: {}", e), + } + let output = match String::from_utf8(buffer) { + Ok(output) => output, + Err(e) => return write!(f, "Error decoding metrics to String: {}", e), + }; + write!(f, "{}", output) + } +} + +impl MetricsController { + pub fn set(&self, name: &str, value: f64) { + if let Some(metric) = self.registry_index.get(name) { + metric.set(value); + } else { + let gauge = match Gauge::new(sanitize_metric_name(name), name) { + Ok(g) => g, + Err(e) => { + debug!("Failed to create gauge {:?}:\n{}", name, e); + return; + } + }; + self.register_gauge(Box::new(gauge)); + self.set(name, value) + } + } + + pub fn inc_by(&self, name: &str, value: f64) { + if let Some(metric) = self.registry_index.get(name) { + metric.inc_by(value); + } else { + let counter = match Counter::new(sanitize_metric_name(name), name) { + Ok(c) => c, + Err(e) => { + debug!("Failed to create counter {:?}:\n{}", name, e); + return; + } + }; + self.register_counter(Box::new(counter)); + self.inc_by(name, value) + } + } + + fn register_gauge(&self, metric: Box<Gauge>) { + let fq_name = metric + .desc() + .first() + .map(|d| d.fq_name.clone()) + .unwrap_or_default(); + + if self.registry_index.contains_key(&fq_name) { + return; + } + + match self.registry.register(metric.clone()) { + Ok(_) => { + self.registry_index + .insert(fq_name, Metric::G(metric.clone())); + } + Err(e) => { + debug!("Failed to register {:?}:\n{}", fq_name, e) + } + } + } + + fn register_counter(&self, metric: Box<Counter>) { + let fq_name = metric + .desc() + .first() + .map(|d| d.fq_name.clone()) + .unwrap_or_default(); + + if self.registry_index.contains_key(&fq_name) { + return; + } + match self.registry.register(metric.clone()) { + Ok(_) => { + self.registry_index + .insert(fq_name, Metric::C(metric.clone())); + } + Err(e) => { + debug!("Failed to register {:?}:\n{}", fq_name, e) + } + } + } +} + +#[inline(always)] +fn sanitize_metric_name(name: &str) -> String { + RE.replace_all(name, "_").to_string() +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sanitization() { + assert_eq!( + sanitize_metric_name("packets_sent_34.242.65.133:1789"), + "packets_sent_34_242_65_133_1789" + ) + } +} diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 589feffebc..db0b3786db 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -26,6 +26,7 @@ cupid = "0.6.1" dirs = "4.0" futures = { workspace = true } humantime-serde = "1.0" +lazy_static = "1.4" log = { workspace = true } rand = "0.7.3" serde = { workspace = true, features = ["derive"] } @@ -35,14 +36,8 @@ tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } tokio-util = { workspace = true, features = ["codec"] } toml = "0.5.8" url = { workspace = true, features = ["serde"] } -cfg-if = "1.0.0" thiserror = { workspace = true } -## tracing -tracing = { workspace = true, optional = true } -opentelemetry = { version = "0.19.0", optional = true } - - # internal nym-node = { path = "../nym-node" } @@ -51,6 +46,7 @@ nym-crypto = { path = "../common/crypto" } nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } nym-mixnode-common = { path = "../common/mixnode-common" } +nym-metrics = { path = "../common/nym-metrics" } nym-nonexhaustive-delayqueue = { path = "../common/nonexhaustive-delayqueue" } nym-sphinx = { path = "../common/nymsphinx" } nym-sphinx-params = { path = "../common/nymsphinx/params" } @@ -60,7 +56,6 @@ nym-types = { path = "../common/types" } nym-topology = { path = "../common/topology" } nym-validator-client = { path = "../common/client-libs/validator-client" } nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } -cpu-cycles = { path = "../cpu-cycles", optional = true } [dev-dependencies] tokio = { workspace = true, features = [ @@ -73,14 +68,6 @@ tokio = { workspace = true, features = [ nym-sphinx-types = { path = "../common/nymsphinx/types" } nym-sphinx-params = { path = "../common/nymsphinx/params" } -[features] -cpucycles = [ - "nym-mixnode-common/cpucycles", - "tracing", - "opentelemetry", - "nym-bin-common/tracing", -] - [package.metadata.deb] name = "nym-mixnode" maintainer-scripts = "debian" diff --git a/mixnode/src/commands/init.rs b/mixnode/src/commands/init.rs index 3e678d3d4a..cc1f5fe5c8 100644 --- a/mixnode/src/commands/init.rs +++ b/mixnode/src/commands/init.rs @@ -42,6 +42,9 @@ pub(crate) struct Init { #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, + + #[clap(long)] + metrics_key: Option<String>, } impl From<Init> for OverrideConfig { @@ -53,6 +56,7 @@ impl From<Init> for OverrideConfig { verloc_port: init_config.verloc_port, http_api_port: init_config.http_api_port, nym_apis: init_config.nym_apis, + metrics_key: init_config.metrics_key, } } } diff --git a/mixnode/src/commands/mod.rs b/mixnode/src/commands/mod.rs index dfa1fcbd42..706bbab77d 100644 --- a/mixnode/src/commands/mod.rs +++ b/mixnode/src/commands/mod.rs @@ -59,6 +59,7 @@ struct OverrideConfig { verloc_port: Option<u16>, http_api_port: Option<u16>, nym_apis: Option<Vec<url::Url>>, + metrics_key: Option<String>, } pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { @@ -83,6 +84,7 @@ fn override_config(config: Config, args: OverrideConfig) -> Config { .with_optional(Config::with_mix_port, args.mix_port) .with_optional(Config::with_verloc_port, args.verloc_port) .with_optional(Config::with_http_api_port, args.http_api_port) + .with_optional(Config::with_metrics_key, args.metrics_key) .with_optional_custom_env( Config::with_custom_nym_apis, args.nym_apis, diff --git a/mixnode/src/commands/run.rs b/mixnode/src/commands/run.rs index c4ab5125fb..178ff31cc3 100644 --- a/mixnode/src/commands/run.rs +++ b/mixnode/src/commands/run.rs @@ -44,6 +44,9 @@ pub(crate) struct Run { #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, + + #[clap(long)] + metrics_key: Option<String>, } impl From<Run> for OverrideConfig { @@ -55,6 +58,7 @@ impl From<Run> for OverrideConfig { verloc_port: run_config.verloc_port, http_api_port: run_config.http_api_port, nym_apis: run_config.nym_apis, + metrics_key: run_config.metrics_key, } } } diff --git a/mixnode/src/config/mod.rs b/mixnode/src/config/mod.rs index a1ab25a752..03ac439a59 100644 --- a/mixnode/src/config/mod.rs +++ b/mixnode/src/config/mod.rs @@ -80,6 +80,7 @@ fn default_mixnode_http_config() -> config::Http { DEFAULT_HTTP_API_LISTENING_PORT, ), landing_page_assets_path: None, + metrics_key: None, } } @@ -208,6 +209,15 @@ impl Config { pub fn get_nym_api_endpoints(&self) -> Vec<Url> { self.mixnode.nym_api_urls.clone() } + + pub fn with_metrics_key(mut self, metrics_key: String) -> Self { + self.http.metrics_key = Some(metrics_key); + self + } + + pub fn metrics_key(&self) -> Option<&String> { + self.http.metrics_key.as_ref() + } } #[derive(Debug, Deserialize, PartialEq, Serialize)] diff --git a/mixnode/src/config/old_config_v1_1_32.rs b/mixnode/src/config/old_config_v1_1_32.rs index a17cdeadcd..f72fb49fd2 100644 --- a/mixnode/src/config/old_config_v1_1_32.rs +++ b/mixnode/src/config/old_config_v1_1_32.rs @@ -95,6 +95,7 @@ impl From<ConfigV1_1_32> for Config { value.mixnode.http_api_port, ), landing_page_assets_path: None, + metrics_key: None, }, // /\ ADDED mixnode: MixNode { diff --git a/mixnode/src/config/template.rs b/mixnode/src/config/template.rs index 79a4dd72a8..0e6651cc87 100644 --- a/mixnode/src/config/template.rs +++ b/mixnode/src/config/template.rs @@ -57,6 +57,8 @@ bind_address = '{{ http.bind_address }}' # Path to assets directory of custom landing page of this node landing_page_assets_path = '{{ http.landing_page_assets_path }}' +metrics_key = '{{ http.metrics_key }}' + [storage_paths] # Path to file containing private identity key. diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index a7b1592776..9f9cf24176 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -3,18 +3,11 @@ use ::nym_config::defaults::setup_env; use clap::{crate_name, crate_version, Parser}; -use log::info; use nym_bin_common::bin_info; use std::sync::OnceLock; #[allow(unused_imports)] use nym_bin_common::logging::{maybe_print_banner, setup_logging}; -#[cfg(feature = "cpucycles")] -use nym_bin_common::setup_tracing; -#[cfg(feature = "cpucycles")] -use nym_mixnode_common::measure; -#[cfg(feature = "cpucycles")] -use tracing::instrument; mod commands; mod config; @@ -41,12 +34,6 @@ struct Cli { command: commands::Commands, } -#[cfg(feature = "cpucycles")] -#[instrument(fields(cpucycles))] -fn test_function() { - measure!({}) -} - #[tokio::main] async fn main() -> anyhow::Result<()> { let args = Cli::parse(); @@ -56,23 +43,10 @@ async fn main() -> anyhow::Result<()> { maybe_print_banner(crate_name!(), crate_version!()); } - cfg_if::cfg_if! { - if #[cfg(feature = "cpucycles")] { - setup_tracing!("mixnode"); - info!("CPU cycles measurement is ON") - } else { - setup_logging(); - info!("CPU cycles measurement is OFF") - } - } + setup_logging(); commands::execute(args).await?; - cfg_if::cfg_if! { - if #[cfg(feature = "cpucycles")] { - opentelemetry::global::shutdown_tracer_provider(); - }} - Ok(()) } diff --git a/mixnode/src/node/http/legacy/mod.rs b/mixnode/src/node/http/legacy/mod.rs index 94ed29fc6c..ea26b3af84 100644 --- a/mixnode/src/node/http/legacy/mod.rs +++ b/mixnode/src/node/http/legacy/mod.rs @@ -4,6 +4,7 @@ use crate::node::http::legacy::description::description; use crate::node::http::legacy::hardware::hardware; use crate::node::http::legacy::state::MixnodeAppState; +use crate::node::http::legacy::stats::metrics; use crate::node::http::legacy::stats::stats; use crate::node::http::legacy::verloc::verloc; use crate::node::node_description::NodeDescription; @@ -29,6 +30,7 @@ pub(crate) mod api_routes { pub(crate) const VERLOC: &str = "/verloc"; pub(crate) const DESCRIPTION: &str = "/description"; pub(crate) const STATS: &str = "/stats"; + pub(crate) const METRICS: &str = "/metrics"; pub(crate) const HARDWARE: &str = "/hardware"; } @@ -44,6 +46,7 @@ pub(crate) fn routes<S: Send + Sync + 'static + Clone>( ) .route(api_routes::STATS, get(stats)) .route(api_routes::HARDWARE, get(hardware)) + .route(api_routes::METRICS, get(metrics)) .fallback(not_found) .with_state(state) } diff --git a/mixnode/src/node/http/legacy/state.rs b/mixnode/src/node/http/legacy/state.rs index 80cdaa01c0..914f6a856a 100644 --- a/mixnode/src/node/http/legacy/state.rs +++ b/mixnode/src/node/http/legacy/state.rs @@ -10,6 +10,7 @@ use axum::extract::FromRef; pub(crate) struct MixnodeAppState { pub(crate) verloc: VerlocState, pub(crate) stats: SharedNodeStats, + pub(crate) metrics_key: Option<String>, } impl FromRef<MixnodeAppState> for VerlocState { diff --git a/mixnode/src/node/http/legacy/stats.rs b/mixnode/src/node/http/legacy/stats.rs index b48358799b..1bbc6eea21 100644 --- a/mixnode/src/node/http/legacy/stats.rs +++ b/mixnode/src/node/http/legacy/stats.rs @@ -1,33 +1,59 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::node::node_statistics::{NodeStats, NodeStatsSimple, SharedNodeStats}; -use axum::extract::{Query, State}; +use crate::node::node_statistics::{NodeStatsSimple, SharedNodeStats}; + +use axum::{ + extract::{Query, State}, + http::HeaderMap, +}; +use nym_metrics::REGISTRY; use nym_node::http::api::{FormattedResponse, Output}; use serde::{Deserialize, Serialize}; +use super::state::MixnodeAppState; + #[derive(Serialize)] #[serde(untagged)] pub enum NodeStatsResponse { - Full(NodeStats), + Full(String), Simple(NodeStatsSimple), } +pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: HeaderMap) -> String { + if let Some(metrics_key) = state.metrics_key { + if let Some(auth) = headers.get("Authorization") { + if auth.to_str().unwrap_or_default() == format!("Bearer {}", metrics_key) { + REGISTRY.to_string() + } else { + "Unauthorized".to_string() + } + } else { + "Unauthorized".to_string() + } + } else { + "Set metrics_key in config to enable Prometheus metrics".to_string() + } +} + pub(crate) async fn stats( Query(params): Query<StatsQueryParams>, State(stats): State<SharedNodeStats>, ) -> MixnodeStatsResponse { let output = params.output.unwrap_or_default(); - let snapshot_data = stats.clone_data().await; - // there's no point in returning the entire hashmap of sending destinations in regular mode - let response = if params.debug { - NodeStatsResponse::Full(snapshot_data) + let response = generate_stats(params.debug, stats).await; + output.to_response(response) +} + +async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse { + let snapshot_data = stats.clone_data().await; + if full { + NodeStatsResponse::Full(REGISTRY.to_string()) } else { NodeStatsResponse::Simple(snapshot_data.simplify()) - }; - output.to_response(response) + } } pub type MixnodeStatsResponse = FormattedResponse<NodeStatsResponse>; diff --git a/mixnode/src/node/http/mod.rs b/mixnode/src/node/http/mod.rs index 5147664c70..55ca880e63 100644 --- a/mixnode/src/node/http/mod.rs +++ b/mixnode/src/node/http/mod.rs @@ -64,6 +64,12 @@ impl<'a> HttpApiBuilder<'a> { } } + #[must_use] + pub(crate) fn with_metrics_key(mut self, metrics_key: Option<&String>) -> Self { + self.legacy_mixnode.metrics_key = metrics_key.map(|k| k.to_string()); + self + } + #[must_use] pub(crate) fn with_verloc(mut self, verloc: VerlocState) -> Self { self.legacy_mixnode.verloc = verloc; diff --git a/mixnode/src/node/listener/connection_handler/mod.rs b/mixnode/src/node/listener/connection_handler/mod.rs index c16a700bfd..08edd7d298 100644 --- a/mixnode/src/node/listener/connection_handler/mod.rs +++ b/mixnode/src/node/listener/connection_handler/mod.rs @@ -9,7 +9,7 @@ use crate::node::TaskClient; use futures::StreamExt; use log::debug; use log::{error, info, warn}; -use nym_mixnode_common::measure; +use nym_metrics::nanos; use nym_sphinx::forwarding::packet::MixPacket; use nym_sphinx::framing::codec::NymCodec; use nym_sphinx::framing::packet::FramedNymPacket; @@ -19,9 +19,6 @@ use tokio::net::TcpStream; use tokio::time::Instant; use tokio_util::codec::Framed; -#[cfg(feature = "cpucycles")] -use tracing::instrument; - pub(crate) mod packet_processing; #[derive(Clone)] @@ -53,10 +50,6 @@ impl ConnectionHandler { .expect("the delay-forwarder has died!"); } - #[cfg_attr( - feature = "cpucycles", - instrument(skip(self, framed_sphinx_packet), fields(cpucycles)) - )] fn handle_received_packet(&self, framed_sphinx_packet: FramedNymPacket) { // // TODO: here be replay attack detection - it will require similar key cache to the one in @@ -66,7 +59,7 @@ impl ConnectionHandler { // all processing such, key caching, etc. was done. // however, if it was a forward hop, we still need to delay it - measure!({ + nanos!("handle_received_packet", { match self.packet_processor.process_received(framed_sphinx_packet) { Err(err) => debug!("We failed to process received sphinx packet - {err}"), Ok(res) => match res { diff --git a/mixnode/src/node/mod.rs b/mixnode/src/node/mod.rs index 1667b108fd..045c83211f 100644 --- a/mixnode/src/node/mod.rs +++ b/mixnode/src/node/mod.rs @@ -72,11 +72,13 @@ impl MixNode { &self, atomic_verloc_result: AtomicVerlocResult, node_stats_pointer: SharedNodeStats, + metrics_key: Option<&String>, task_client: TaskClient, ) -> Result<(), MixnodeError> { HttpApiBuilder::new(&self.config, &self.identity_keypair, &self.sphinx_keypair) .with_verloc(VerlocState::new(atomic_verloc_result)) .with_mixing_stats(node_stats_pointer) + .with_metrics_key(metrics_key) .with_descriptor(self.descriptor.clone()) .start(task_client) } @@ -249,6 +251,7 @@ impl MixNode { self.start_http_api( atomic_verloc_results, node_stats_pointer, + self.config.metrics_key(), shutdown.subscribe().named("http-api"), )?; diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index be367dea96..935ce6f3df 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -1,6 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use nym_metrics::REGISTRY; + use super::TaskClient; use futures::channel::mpsc; use futures::lock::Mutex; @@ -15,7 +17,7 @@ use std::time::{Duration, SystemTime}; use tokio::sync::{RwLock, RwLockReadGuard}; // convenience aliases -type PacketsMap = HashMap<String, u64>; +type PacketsMap = HashMap<String, f64>; type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>; type PacketDataSender = mpsc::UnboundedSender<PacketEvent>; @@ -27,14 +29,15 @@ pub(crate) struct SharedNodeStats { impl SharedNodeStats { pub(crate) fn new() -> Self { let now = SystemTime::now(); + SharedNodeStats { inner: Arc::new(RwLock::new(NodeStats { update_time: now, previous_update_time: now, - packets_received_since_startup: 0, - packets_sent_since_startup: HashMap::new(), - packets_explicitly_dropped_since_startup: HashMap::new(), - packets_received_since_last_update: 0, + packets_received_since_startup: 0., + packets_sent_since_startup_all: 0., + packets_dropped_since_startup_all: 0., + packets_received_since_last_update: 0., packets_sent_since_last_update: HashMap::new(), packets_explicitly_dropped_since_last_update: HashMap::new(), })), @@ -43,7 +46,7 @@ impl SharedNodeStats { pub(crate) async fn update( &self, - new_received: u64, + new_received: f64, new_sent: PacketsMap, new_dropped: PacketsMap, ) { @@ -54,20 +57,21 @@ impl SharedNodeStats { guard.update_time = snapshot_time; guard.packets_received_since_startup += new_received; - for (mix, count) in &new_sent { - *guard - .packets_sent_since_startup - .entry(mix.clone()) - .or_insert(0) += *count; + for count in new_sent.values() { + guard.packets_sent_since_startup_all += count; } - for (mix, count) in &new_dropped { - *guard - .packets_explicitly_dropped_since_last_update - .entry(mix.clone()) - .or_insert(0) += *count; + for count in new_dropped.values() { + guard.packets_dropped_since_startup_all += count; } + REGISTRY.inc_by("packets_received_since_startup", new_received); + REGISTRY.inc_by("packets_sent_since_startup_all", new_sent.values().sum()); + REGISTRY.inc_by( + "packets_dropped_since_startup_all", + new_dropped.values().sum(), + ); + guard.packets_received_since_last_update = new_received; guard.packets_sent_since_last_update = new_sent; guard.packets_explicitly_dropped_since_last_update = new_dropped; @@ -82,27 +86,18 @@ impl SharedNodeStats { } } -#[derive(Serialize, Clone)] +#[derive(Clone)] pub struct NodeStats { - #[serde(serialize_with = "humantime_serde::serialize")] update_time: SystemTime, - #[serde(serialize_with = "humantime_serde::serialize")] previous_update_time: SystemTime, - packets_received_since_startup: u64, - - // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_startup: PacketsMap, - - // we know for sure we dropped packets to those destinations - packets_explicitly_dropped_since_startup: PacketsMap, - - packets_received_since_last_update: u64, - + packets_received_since_startup: f64, + packets_sent_since_startup_all: f64, + packets_dropped_since_startup_all: f64, + packets_received_since_last_update: f64, // note: sent does not imply forwarded. We don't know if it was delivered successfully packets_sent_since_last_update: PacketsMap, - // we know for sure we dropped packets to those destinations packets_explicitly_dropped_since_last_update: PacketsMap, } @@ -112,10 +107,10 @@ impl Default for NodeStats { NodeStats { update_time: SystemTime::UNIX_EPOCH, previous_update_time: SystemTime::UNIX_EPOCH, - packets_received_since_startup: 0, - packets_sent_since_startup: Default::default(), - packets_explicitly_dropped_since_startup: Default::default(), - packets_received_since_last_update: 0, + packets_received_since_startup: 0., + packets_sent_since_startup_all: 0., + packets_dropped_since_startup_all: 0., + packets_received_since_last_update: 0., packets_sent_since_last_update: Default::default(), packets_explicitly_dropped_since_last_update: Default::default(), } @@ -128,11 +123,8 @@ impl NodeStats { update_time: self.update_time, previous_update_time: self.previous_update_time, packets_received_since_startup: self.packets_received_since_startup, - packets_sent_since_startup: self.packets_sent_since_startup.values().sum(), - packets_explicitly_dropped_since_startup: self - .packets_explicitly_dropped_since_startup - .values() - .sum(), + packets_sent_since_startup: self.packets_sent_since_startup_all, + packets_explicitly_dropped_since_startup: self.packets_dropped_since_startup_all, packets_received_since_last_update: self.packets_received_since_last_update, packets_sent_since_last_update: self.packets_sent_since_last_update.values().sum(), packets_explicitly_dropped_since_last_update: self @@ -151,21 +143,21 @@ pub struct NodeStatsSimple { #[serde(serialize_with = "humantime_serde::serialize")] previous_update_time: SystemTime, - packets_received_since_startup: u64, + packets_received_since_startup: f64, // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_startup: u64, + packets_sent_since_startup: f64, // we know for sure we dropped those packets - packets_explicitly_dropped_since_startup: u64, + packets_explicitly_dropped_since_startup: f64, - packets_received_since_last_update: u64, + packets_received_since_last_update: f64, // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_last_update: u64, + packets_sent_since_last_update: f64, // we know for sure we dropped those packets - packets_explicitly_dropped_since_last_update: u64, + packets_explicitly_dropped_since_last_update: f64, } pub(crate) enum PacketEvent { @@ -203,14 +195,14 @@ impl CurrentPacketData { async fn increment_sent(&self, destination: String) { let mut unlocked = self.inner.sent.lock().await; - let receiver_count = unlocked.entry(destination).or_insert(0); - *receiver_count += 1; + let receiver_count = unlocked.entry(destination).or_insert(0.); + *receiver_count += 1.; } async fn increment_dropped(&self, destination: String) { let mut unlocked = self.inner.dropped.lock().await; - let dropped_count = unlocked.entry(destination).or_insert(0); - *dropped_count += 1; + let dropped_count = unlocked.entry(destination).or_insert(0.); + *dropped_count += 1.; } async fn acquire_and_reset(&self) -> (u64, PacketsMap, PacketsMap) { @@ -332,7 +324,9 @@ impl StatsUpdater { async fn update_stats(&self) { // grab new data since last update let (received, sent, dropped) = self.current_packet_data.acquire_and_reset().await; - self.current_stats.update(received, sent, dropped).await; + self.current_stats + .update(received as f64, sent, dropped) + .await; } async fn run(&mut self) { @@ -376,21 +370,18 @@ impl PacketStatsConsoleLogger { info!( "Since startup mixed {} packets! ({} in last {} seconds)", - stats.packets_sent_since_startup.values().sum::<u64>(), - stats.packets_sent_since_last_update.values().sum::<u64>(), + stats.packets_sent_since_startup_all, + stats.packets_sent_since_last_update.values().sum::<f64>(), difference_secs, ); - if !stats.packets_explicitly_dropped_since_startup.is_empty() { + if stats.packets_dropped_since_startup_all > 0. { info!( "Since startup dropped {} packets! ({} in last {} seconds)", - stats - .packets_explicitly_dropped_since_startup - .values() - .sum::<u64>(), + stats.packets_dropped_since_startup_all, stats .packets_explicitly_dropped_since_last_update .values() - .sum::<u64>(), + .sum::<f64>(), difference_secs, ); } @@ -403,22 +394,19 @@ impl PacketStatsConsoleLogger { ); trace!( "Since startup sent packets to the following: \n{:#?} \n And in last {} seconds: {:#?})", - stats.packets_sent_since_startup, + stats.packets_sent_since_startup_all, difference_secs, stats.packets_sent_since_last_update ); } else { info!( "Since startup mixed {} packets!", - stats.packets_sent_since_startup.values().sum::<u64>(), + stats.packets_sent_since_startup_all, ); - if !stats.packets_explicitly_dropped_since_startup.is_empty() { + if stats.packets_dropped_since_startup_all > 0. { info!( "Since startup dropped {} packets!", - stats - .packets_explicitly_dropped_since_startup - .values() - .sum::<u64>(), + stats.packets_dropped_since_startup_all, ); } @@ -427,8 +415,8 @@ impl PacketStatsConsoleLogger { stats.packets_received_since_startup ); trace!( - "Since startup sent packets to the following: \n{:#?}", - stats.packets_sent_since_startup + "Since startup sent packets {}", + stats.packets_sent_since_startup_all ); } } @@ -545,14 +533,11 @@ mod tests { // Get output (stats) let stats = node_stats_pointer.read().await; - assert_eq!(&stats.packets_sent_since_startup.get("foo"), &Some(&2u64)); - assert_eq!(&stats.packets_sent_since_startup.len(), &1); - assert_eq!( - &stats.packets_sent_since_last_update.get("foo"), - &Some(&2u64) - ); + assert_eq!(&stats.packets_sent_since_startup_all, &2.); + assert_eq!(&stats.packets_sent_since_last_update.get("foo"), &Some(&2.)); assert_eq!(&stats.packets_sent_since_last_update.len(), &1); - assert_eq!(&stats.packets_received_since_startup, &0u64); - assert!(&stats.packets_explicitly_dropped_since_startup.is_empty()); + assert_eq!(&stats.packets_received_since_startup, &0.); + assert_eq!(&stats.packets_dropped_since_startup_all, &0.); + assert_eq!(REGISTRY.to_string(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") } } diff --git a/nym-node/src/config/mod.rs b/nym-node/src/config/mod.rs index 3b712f2e63..51bfe10c67 100644 --- a/nym-node/src/config/mod.rs +++ b/nym-node/src/config/mod.rs @@ -49,6 +49,9 @@ pub struct Http { /// Path to assets directory of custom landing page of this node. #[serde(deserialize_with = "de_maybe_path")] pub landing_page_assets_path: Option<PathBuf>, + + #[serde(default)] + pub metrics_key: Option<String>, } impl Default for Http { @@ -56,6 +59,7 @@ impl Default for Http { Http { bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), DEFAULT_HTTP_PORT), landing_page_assets_path: None, + metrics_key: None, } } } diff --git a/scripts/localnet_start.sh b/scripts/localnet_start.sh index 1a821c31e1..d9ffad9356 100755 --- a/scripts/localnet_start.sh +++ b/scripts/localnet_start.sh @@ -20,13 +20,13 @@ echo "Using $localnetdir for the localnet" # initialise mixnet echo "initialising mixnode1..." -cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --output=json >>"$localnetdir/mix1.json" +cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --metrics-key=lala --output=json >>"$localnetdir/mix1.json" echo "initialising mixnode2..." -cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --output=json >>"$localnetdir/mix2.json" +cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --metrics-key=lala --output=json >>"$localnetdir/mix2.json" echo "initialising mixnode3..." -cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --output=json >>"$localnetdir/mix3.json" +cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --metrics-key=lala --output=json >>"$localnetdir/mix3.json" echo "initialising gateway..." cargo run --release --bin nym-gateway -- init --id "gateway-$suffix" --host 127.0.0.1 --mix-port 10004 --clients-port 9000 --output=json >>"$localnetdir/gateway.json" diff --git a/scripts/node_exporter.sh b/scripts/node_exporter.sh new file mode 100644 index 0000000000..3bffaca32b --- /dev/null +++ b/scripts/node_exporter.sh @@ -0,0 +1,83 @@ +#!/bin/bash + +# Check if the script is run as root +if [ "$(id -u)" -ne 0 ]; then + echo "This script must be run as root. Please use sudo or log in as the root user." + exit 1 +fi + +# Hardcoded node_exporter version +node_exporter_version="1.7.0" + +# Create a user for node_exporter without a home directory +useradd --no-create-home --shell /bin/false node_exporter + +# Download node_exporter +echo "Downloading node_exporter version $node_exporter_version..." +wget "https://github.com/prometheus/node_exporter/releases/download/v$node_exporter_version/node_exporter-$node_exporter_version.linux-amd64.tar.gz" -O /tmp/node_exporter-$node_exporter_version.linux-amd64.tar.gz +if [ $? -ne 0 ]; then + echo "Failed to download node_exporter." + exit 1 +fi + +# Unarchive node_exporter +echo "Unarchiving node_exporter..." +tar xvfz /tmp/node_exporter-$node_exporter_version.linux-amd64.tar.gz -C /tmp +if [ $? -ne 0 ]; then + echo "Failed to unarchive node_exporter." + exit 1 +fi + +# Move node_exporter to /usr/local/bin +echo "Moving node_exporter to /usr/local/bin..." +mv /tmp/node_exporter-$node_exporter_version.linux-amd64/node_exporter /usr/local/bin/node_exporter +if [ $? -ne 0 ]; then + echo "Failed to move node_exporter." + exit 1 +fi + +# Set ownership and permissions +chown node_exporter:node_exporter /usr/local/bin/node_exporter +chmod 0755 /usr/local/bin/node_exporter + +# Create node_exporter service file +echo "Creating node_exporter service file..." +cat <<EOF > /etc/systemd/system/node_exporter.service +[Unit] +Description=Node Exporter +Wants=network-online.target +After=network-online.target + +[Service] +User=node_exporter +Group=node_exporter +Type=simple +ExecStart=/usr/local/bin/node_exporter --web.config.file /etc/prometheus_node_exporter/configuration.yml + +[Install] +WantedBy=multi-user.target +EOF + + +mkdir -p /etc/prometheus_node_exporter/ + +sudo cat << EOF > /etc/prometheus_node_exporter/configuration.yml +basic_auth_users: + prometheus: "\$2y\$10\$aB1RMr6ZGg2psbMOezmfluVzGcH/VHIqP4Lksx0DWuw/QSr9Iccwu" + +EOF + +ufw allow 9100 + +# Reload systemd, enable and start node_exporter service +echo "Configuring systemd for node_exporter..." +systemctl daemon-reload +systemctl enable node_exporter.service +systemctl start node_exporter.service + +# Cleanup +echo "Cleaning up..." +rm -rf /tmp/node_exporter-${node_exporter_version}.linux-amd64.tar.gz +rm -rf /tmp/node_exporter-${node_exporter_version}.linux-amd64 + +echo "node_exporter installation and configuration complete." \ No newline at end of file diff --git a/scripts/prom_targets.py b/scripts/prom_targets.py new file mode 100644 index 0000000000..ee7d3a6e38 --- /dev/null +++ b/scripts/prom_targets.py @@ -0,0 +1,63 @@ +import argparse +import os +import requests +import json +from datetime import datetime +from collections import namedtuple + +Config = namedtuple("Config", ["port", "outfile", "outlink"]) + + +def config_to_targets(config, mixnodes): + prom_targets = [make_prom_target(mixnode, config.port) for mixnode in mixnodes] + with open(config.outfile, "w") as f: + json.dump(prom_targets, f) + + os.chmod(config.outfile, 0o777) + os.rename(config.outfile, config.outlink) + os.chmod(config.outlink, 0o777) + + print(f"Prometheus -> {len(prom_targets)} targets written to {config.outlink}") + + +def make_prom_target(mixnode, port=None): + bond_info = mixnode.get("bond_information", {}) + mix_node = bond_info.get("mix_node", {}) + host = mix_node.get("host", None) + port = port if port else mix_node.get("http_api_port", None) + if host is None or port is None: + return None + + return { + "targets": [f"{host}:{port}"], + "labels": { + "mix_node_host": host, + "identity_key": mix_node.get("identity_key", None), + "sphinx_key": mix_node.get("sphinx_key", None), + "mix_node_version": mix_node.get("version", None), + }, + } + + +if __name__ == "__main__": + parser = argparse.ArgumentParser( + description="Create prometheus targets for rewarded set mixnodes." + ) + parser.add_argument( + "apiurl", + type=str, + help="Nym Api url", + ) + + args = parser.parse_args() + nym_api = args.apiurl + + targets = [ + Config(None, "/tmp/temp_targets_mix.json", "/tmp/prom_targets_mix.json"), + Config(9100, "/tmp/temp_targets_node.json", "/tmp/prom_targets_node.json"), + ] + + mixnodes = requests.get(f"{nym_api}/api/v1/mixnodes").json() + + for config in targets: + config_to_targets(config, mixnodes) diff --git a/scripts/requirements.txt b/scripts/requirements.txt new file mode 100644 index 0000000000..663bd1f6a2 --- /dev/null +++ b/scripts/requirements.txt @@ -0,0 +1 @@ +requests \ No newline at end of file From 2bc8a768996d67dc19b76e28ee1f1fa3382786ae Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:00:33 +0000 Subject: [PATCH 196/394] Bump follow-redirects from 1.15.4 to 1.15.6 in /testnet-faucet Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- testnet-faucet/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testnet-faucet/yarn.lock b/testnet-faucet/yarn.lock index d05e5b435e..3b3018585d 100644 --- a/testnet-faucet/yarn.lock +++ b/testnet-faucet/yarn.lock @@ -2277,9 +2277,9 @@ flatted@^3.1.0: integrity sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg== follow-redirects@^1.14.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== fs.realpath@^1.0.0: version "1.0.0" From 68bc4a59f733655616e8261a67dbef811f963f12 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:00:38 +0000 Subject: [PATCH 197/394] Bump follow-redirects from 1.15.4 to 1.15.6 in /nym-api/tests Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- nym-api/tests/package-lock.json | 12 ++++++------ nym-api/tests/yarn.lock | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/nym-api/tests/package-lock.json b/nym-api/tests/package-lock.json index b1d102687c..bb3eb4bc7c 100644 --- a/nym-api/tests/package-lock.json +++ b/nym-api/tests/package-lock.json @@ -2555,9 +2555,9 @@ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==" }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -6845,9 +6845,9 @@ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ==" }, "follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "form-data": { "version": "4.0.0", diff --git a/nym-api/tests/yarn.lock b/nym-api/tests/yarn.lock index b21ac8d13e..735fe57700 100644 --- a/nym-api/tests/yarn.lock +++ b/nym-api/tests/yarn.lock @@ -1568,9 +1568,9 @@ flatted@^3.1.0: integrity sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ== follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== form-data@4.0.0, form-data@^4.0.0: version "4.0.0" From 7bc1b0dbcf26c8a8cd29c9a62ece05b25b2ea2e0 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:57:47 +0000 Subject: [PATCH 198/394] Bump follow-redirects from 1.15.4 to 1.15.6 Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3ab8f0a0d7..449d0d85fc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9918,9 +9918,9 @@ focus-lock@^0.8.0: tslib "^1.9.3" follow-redirects@^1.0.0, follow-redirects@^1.14.0, follow-redirects@^1.15.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== for-each@^0.3.3: version "0.3.3" From 2cf65b3694d70a54363f3f9fdd29bc092464496a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 15 Mar 2024 14:58:42 +0000 Subject: [PATCH 199/394] Bump follow-redirects in /docker/typescript_client/upload_contract Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.14.9 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.14.9...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- .../upload_contract/package-lock.json | 29 ++++++++++--------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/docker/typescript_client/upload_contract/package-lock.json b/docker/typescript_client/upload_contract/package-lock.json index 5afb3c4577..62bfcb02b9 100644 --- a/docker/typescript_client/upload_contract/package-lock.json +++ b/docker/typescript_client/upload_contract/package-lock.json @@ -18,7 +18,7 @@ }, "devDependencies": { "@tsconfig/recommended": "^1.0.1", - "prettier": "^2.2.1", + "prettier": "^2.8.7", "typescript": "^4.1.3" } }, @@ -570,9 +570,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -875,15 +875,18 @@ } }, "node_modules/prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true, "bin": { "prettier": "bin-prettier.js" }, "engines": { "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, "node_modules/protobufjs": { @@ -1664,9 +1667,9 @@ } }, "follow-redirects": { - "version": "1.14.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.14.9.tgz", - "integrity": "sha512-MQDfihBQYMcyy5dhRDJUHcw7lb2Pv/TuE6xP1vyraLukNDHKbDxDNaOE3NbCAdKQApno+GPRyo1YAp89yCjK4w==" + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==" }, "fsevents": { "version": "2.3.2", @@ -1885,9 +1888,9 @@ "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==" }, "prettier": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.3.2.tgz", - "integrity": "sha512-lnJzDfJ66zkMy58OL5/NY5zp70S7Nz6KqcKkXYzn2tMVrNxvbqaBpg7H3qHaLxCJ5lNMsGuM8+ohS7cZrthdLQ==", + "version": "2.8.8", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.8.tgz", + "integrity": "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q==", "dev": true }, "protobufjs": { From 73e87b2debfc208f76403863e56f6557eed21955 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Fri, 15 Mar 2024 09:54:35 +0000 Subject: [PATCH 200/394] test wallet connect projectId --- explorer/.env.example | 1 + 1 file changed, 1 insertion(+) create mode 100644 explorer/.env.example diff --git a/explorer/.env.example b/explorer/.env.example new file mode 100644 index 0000000000..f081749b4c --- /dev/null +++ b/explorer/.env.example @@ -0,0 +1 @@ +WALLET_CONNECT_PROJECT_ID= \ No newline at end of file From f7e6677878523828d3c248db43b34aa63d1b07f4 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Fri, 15 Mar 2024 16:28:01 +0000 Subject: [PATCH 201/394] update dotenv config --- explorer/.env.example | 1 - ts-packages/webpack/webpack.common.js | 4 +++- 2 files changed, 3 insertions(+), 2 deletions(-) delete mode 100644 explorer/.env.example diff --git a/explorer/.env.example b/explorer/.env.example deleted file mode 100644 index f081749b4c..0000000000 --- a/explorer/.env.example +++ /dev/null @@ -1 +0,0 @@ -WALLET_CONNECT_PROJECT_ID= \ No newline at end of file diff --git a/ts-packages/webpack/webpack.common.js b/ts-packages/webpack/webpack.common.js index 64c0b8d168..2a236c22ab 100644 --- a/ts-packages/webpack/webpack.common.js +++ b/ts-packages/webpack/webpack.common.js @@ -84,7 +84,9 @@ module.exports = (baseDir, htmlPath) => ({ src: path.resolve(__dirname, '../../assets/favicon/favicon.png'), // the asset directory is relative to THIS file }), - new Dotenv(), + new Dotenv({ + systemvars: true, + }), ], output: { path: path.resolve(baseDir, 'dist'), From 70b15c9226f8e508f902d6305849fd9cdafd7e0a Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Fri, 15 Mar 2024 21:08:14 +0000 Subject: [PATCH 202/394] test mainnet mixnodes --- explorer/.env.dev | 3 ++- explorer/src/context/cosmos-kit.tsx | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/explorer/.env.dev b/explorer/.env.dev index 95110f2f4d..d8c4d4547b 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -1,7 +1,8 @@ # When running the explorer API locally #EXPLORER_API_URL=http://localhost:8000/v1 -EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1 +# EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1 +EXPLORER_API_URL=https://explorer.nymtech.net/api/v1 NYM_API_URL=https://sandbox-nym-api1.nymtech.net VALIDATOR_URL=https://rpc.sandbox.nymtech.net BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 94c5f45f95..4e002ea379 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -36,7 +36,7 @@ const nymSandboxAssets: AssetList = { }, ], }; -console.log(WALLET_CONNECT_PROJECT_ID, 'WALLET_CONNECT_PROJECT_ID'); + const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( <ChainProvider chains={[...chains, nymSandbox]} From 393b67873d049d2d0d77ac5030ab31cd5fdd6b14 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:09:28 +0000 Subject: [PATCH 203/394] Bump follow-redirects in /wasm/mix-fetch/internal-dev Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/mix-fetch/internal-dev/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock index c52d313054..f8529616d9 100644 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ b/wasm/mix-fetch/internal-dev/yarn.lock @@ -932,9 +932,9 @@ find-up@^4.0.0: path-exists "^4.0.0" follow-redirects@^1.0.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== forwarded@0.2.0: version "0.2.0" From 2172644f984c1a7179022d2a8b1008cfc85b2a28 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:10:50 +0000 Subject: [PATCH 204/394] Bump follow-redirects from 1.15.4 to 1.15.6 in /wasm/client/internal-dev Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/client/internal-dev/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/client/internal-dev/yarn.lock b/wasm/client/internal-dev/yarn.lock index e7619a0a02..e4a0f6c4c7 100644 --- a/wasm/client/internal-dev/yarn.lock +++ b/wasm/client/internal-dev/yarn.lock @@ -932,9 +932,9 @@ find-up@^4.0.0: path-exists "^4.0.0" follow-redirects@^1.0.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== forwarded@0.2.0: version "0.2.0" From c3af84a9523092dc6c7ebfdc84b4ac752762e482 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 16 Mar 2024 23:12:48 +0000 Subject: [PATCH 205/394] Bump follow-redirects in /wasm/node-tester/internal-dev Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/node-tester/internal-dev/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/node-tester/internal-dev/yarn.lock b/wasm/node-tester/internal-dev/yarn.lock index a49014f16e..1befaf7e6c 100644 --- a/wasm/node-tester/internal-dev/yarn.lock +++ b/wasm/node-tester/internal-dev/yarn.lock @@ -932,9 +932,9 @@ find-up@^4.0.0: path-exists "^4.0.0" follow-redirects@^1.0.0: - version "1.15.4" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf" - integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw== + version "1.15.6" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b" + integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA== forwarded@0.2.0: version "0.2.0" From 8231bc1c73c979d59eba4c32d0565b070ca221a6 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Mon, 18 Mar 2024 09:15:12 +0100 Subject: [PATCH 206/394] Support multiple envs --- scripts/prom_targets.py | 53 +++++++++++++++++++++++--------- scripts/prom_targets_config.json | 4 +++ 2 files changed, 43 insertions(+), 14 deletions(-) create mode 100644 scripts/prom_targets_config.json diff --git a/scripts/prom_targets.py b/scripts/prom_targets.py index ee7d3a6e38..5c76c9d0d6 100644 --- a/scripts/prom_targets.py +++ b/scripts/prom_targets.py @@ -2,14 +2,19 @@ import argparse import os import requests import json -from datetime import datetime from collections import namedtuple -Config = namedtuple("Config", ["port", "outfile", "outlink"]) +Config = namedtuple("Config", ["port", "outfile", "outlink", "env"]) + + +def validate_config_entry(entry): + return entry.get("nym_api") and entry.get("env") def config_to_targets(config, mixnodes): - prom_targets = [make_prom_target(mixnode, config.port) for mixnode in mixnodes] + prom_targets = [ + make_prom_target(config.env, mixnode, config.port) for mixnode in mixnodes + ] with open(config.outfile, "w") as f: json.dump(prom_targets, f) @@ -20,7 +25,7 @@ def config_to_targets(config, mixnodes): print(f"Prometheus -> {len(prom_targets)} targets written to {config.outlink}") -def make_prom_target(mixnode, port=None): +def make_prom_target(env, mixnode, port=None): bond_info = mixnode.get("bond_information", {}) mix_node = bond_info.get("mix_node", {}) host = mix_node.get("host", None) @@ -35,6 +40,7 @@ def make_prom_target(mixnode, port=None): "identity_key": mix_node.get("identity_key", None), "sphinx_key": mix_node.get("sphinx_key", None), "mix_node_version": mix_node.get("version", None), + "mixnet_env": env, }, } @@ -44,20 +50,39 @@ if __name__ == "__main__": description="Create prometheus targets for rewarded set mixnodes." ) parser.add_argument( - "apiurl", + "config", type=str, - help="Nym Api url", + help="Config file, see scripts/prom_targets_config.json", ) args = parser.parse_args() - nym_api = args.apiurl + config_file = args.config - targets = [ - Config(None, "/tmp/temp_targets_mix.json", "/tmp/prom_targets_mix.json"), - Config(9100, "/tmp/temp_targets_node.json", "/tmp/prom_targets_node.json"), - ] + with open(config_file, "r") as f: + config = json.load(f) - mixnodes = requests.get(f"{nym_api}/api/v1/mixnodes").json() + for entry in config: - for config in targets: - config_to_targets(config, mixnodes) + if not validate_config_entry(entry): + print(f"Invalid config entry: {entry}") + continue + + targets = [ + Config( + None, + "/tmp/temp_targets_mix.json", + f"/tmp/prom_targets_mix_{entry['env']}.json", + entry["env"], + ), + Config( + 9100, + "/tmp/temp_targets_node.json", + f"/tmp/prom_targets_node_{entry['env']}.json", + entry["env"], + ), + ] + + mixnodes = requests.get(f"{entry['nym_api']}/api/v1/mixnodes").json() + + for config in targets: + config_to_targets(config, mixnodes) diff --git a/scripts/prom_targets_config.json b/scripts/prom_targets_config.json new file mode 100644 index 0000000000..cdbae6fce3 --- /dev/null +++ b/scripts/prom_targets_config.json @@ -0,0 +1,4 @@ +[ + { "nym_api": "https://sandbox-nym-api1.nymtech.net", "env": "sandbox" }, + { "nym_api": "https://api.performance.nymte.ch", "env": "performance" } +] From 8044ad54454e7d638c61cae3411722e9799027b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 18 Mar 2024 11:52:46 +0000 Subject: [PATCH 207/394] Bugfix/gateway registration (#4442) * added timeout for gateway handshake messages * make clients downgrade their protocol version if credentials are not being used * method visibility --- Cargo.lock | 2 + .../client-libs/gateway-client/src/client.rs | 14 ++- gateway/gateway-requests/Cargo.toml | 8 ++ gateway/gateway-requests/src/lib.rs | 4 +- .../src/registration/handshake/client.rs | 9 +- .../src/registration/handshake/error.rs | 3 + .../src/registration/handshake/gateway.rs | 2 +- .../src/registration/handshake/mod.rs | 10 +- .../src/registration/handshake/state.rs | 101 +++++++++++------- gateway/gateway-requests/src/types.rs | 36 ++++++- nym-connect/desktop/Cargo.lock | 2 + 11 files changed, 137 insertions(+), 54 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b8d97ce94f..06ff9e5780 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5605,7 +5605,9 @@ dependencies = [ "serde", "serde_json", "thiserror", + "tokio", "tungstenite", + "wasmtimer", "zeroize", ] diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 46b4816e2d..77d28ca2a7 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -20,7 +20,7 @@ use nym_gateway_requests::authentication::encrypted_address::EncryptedAddressByt use nym_gateway_requests::iv::IV; use nym_gateway_requests::registration::handshake::{client_handshake, SharedKeys}; use nym_gateway_requests::{ - BinaryRequest, ClientControlRequest, ServerResponse, CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION, + BinaryRequest, ClientControlRequest, ServerResponse, CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION, CURRENT_PROTOCOL_VERSION, }; use nym_network_defaults::{REMAINING_BANDWIDTH_THRESHOLD, TOKENS_TO_BURN}; @@ -438,6 +438,7 @@ impl<C, St> GatewayClient<C, St> { ws_stream, self.local_identity.as_ref(), self.gateway_identity, + !self.disabled_credentials_mode, ) .await .map_err(GatewayClientError::RegistrationFailure), @@ -494,8 +495,13 @@ impl<C, St> GatewayClient<C, St> { .derive_destination_address(); let encrypted_address = EncryptedAddressBytes::new(&self_address, shared_key, &iv); - let msg = - ClientControlRequest::new_authenticate(self_address, encrypted_address, iv).into(); + let msg = ClientControlRequest::new_authenticate( + self_address, + encrypted_address, + iv, + !self.disabled_credentials_mode, + ) + .into(); match self.send_websocket_message(msg).await? { ServerResponse::Authenticate { @@ -599,7 +605,7 @@ impl<C, St> GatewayClient<C, St> { }); }; - if gateway_protocol < CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION { + if gateway_protocol < CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION { return Err(GatewayClientError::OutdatedGatewayCredentialVersion { negotiated_protocol: Some(gateway_protocol), }); diff --git a/gateway/gateway-requests/Cargo.toml b/gateway/gateway-requests/Cargo.toml index 2ca9a3b440..770ce79cd4 100644 --- a/gateway/gateway-requests/Cargo.toml +++ b/gateway/gateway-requests/Cargo.toml @@ -28,6 +28,14 @@ nym-sphinx = { path = "../../common/nymsphinx" } nym-credentials = { path = "../../common/credentials" } nym-credentials-interface = { path = "../../common/credentials-interface" } +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio] +workspace = true +features = ["time"] + +[target."cfg(target_arch = \"wasm32\")".dependencies.wasmtimer] +workspace = true +features = ["tokio"] + [dependencies.tungstenite] workspace = true default-features = false diff --git a/gateway/gateway-requests/src/lib.rs b/gateway/gateway-requests/src/lib.rs index 45bc486322..98feccc75b 100644 --- a/gateway/gateway-requests/src/lib.rs +++ b/gateway/gateway-requests/src/lib.rs @@ -13,7 +13,7 @@ pub mod models; pub mod registration; pub mod types; -pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION; +pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION; /// Defines the current version of the communication protocol between gateway and clients. /// It has to be incremented for any breaking change. @@ -21,7 +21,7 @@ pub const CURRENT_PROTOCOL_VERSION: u8 = CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION; // 1 - initial release // 2 - changes to client credentials structure pub const INITIAL_PROTOCOL_VERSION: u8 = 1; -pub const CREDENTIAL_UPDATE_V1_PROTOCOL_VERSION: u8 = 2; +pub const CREDENTIAL_UPDATE_V2_PROTOCOL_VERSION: u8 = 2; pub type GatewayMac = HmacOutput<GatewayIntegrityHmacAlgorithm>; diff --git a/gateway/gateway-requests/src/registration/handshake/client.rs b/gateway/gateway-requests/src/registration/handshake/client.rs index 4e3c865553..edb30ebf20 100644 --- a/gateway/gateway-requests/src/registration/handshake/client.rs +++ b/gateway/gateway-requests/src/registration/handshake/client.rs @@ -24,11 +24,18 @@ impl<'a> ClientHandshake<'a> { ws_stream: &'a mut S, identity: &'a nym_crypto::asymmetric::identity::KeyPair, gateway_pubkey: identity::PublicKey, + expects_credential_usage: bool, ) -> Self where S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a, { - let mut state = State::new(rng, ws_stream, identity, Some(gateway_pubkey)); + let mut state = State::new( + rng, + ws_stream, + identity, + Some(gateway_pubkey), + expects_credential_usage, + ); ClientHandshake { handshake_future: Box::pin(async move { diff --git a/gateway/gateway-requests/src/registration/handshake/error.rs b/gateway/gateway-requests/src/registration/handshake/error.rs index 798cd2ec55..f1357f7815 100644 --- a/gateway/gateway-requests/src/registration/handshake/error.rs +++ b/gateway/gateway-requests/src/registration/handshake/error.rs @@ -25,4 +25,7 @@ pub enum HandshakeError { MalformedRequest, #[error("sent request was malformed")] HandshakeFailure, + + #[error("timed out waiting for a handshake message")] + Timeout, } diff --git a/gateway/gateway-requests/src/registration/handshake/gateway.rs b/gateway/gateway-requests/src/registration/handshake/gateway.rs index 69381dc5d4..bb0003d0a3 100644 --- a/gateway/gateway-requests/src/registration/handshake/gateway.rs +++ b/gateway/gateway-requests/src/registration/handshake/gateway.rs @@ -26,7 +26,7 @@ impl<'a> GatewayHandshake<'a> { where S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a, { - let mut state = State::new(rng, ws_stream, identity, None); + let mut state = State::new(rng, ws_stream, identity, None, true); GatewayHandshake { handshake_future: Box::pin(async move { // If any step along the way failed (that are non-network related), diff --git a/gateway/gateway-requests/src/registration/handshake/mod.rs b/gateway/gateway-requests/src/registration/handshake/mod.rs index edf8a6fae0..4e21fcfc0d 100644 --- a/gateway/gateway-requests/src/registration/handshake/mod.rs +++ b/gateway/gateway-requests/src/registration/handshake/mod.rs @@ -30,11 +30,19 @@ pub async fn client_handshake<'a, S>( ws_stream: &'a mut S, identity: &'a identity::KeyPair, gateway_pubkey: identity::PublicKey, + expects_credential_usage: bool, ) -> Result<SharedKeys, HandshakeError> where S: Stream<Item = WsItem> + Sink<WsMessage> + Unpin + Send + 'a, { - ClientHandshake::new(rng, ws_stream, identity, gateway_pubkey).await + ClientHandshake::new( + rng, + ws_stream, + identity, + gateway_pubkey, + expects_credential_usage, + ) + .await } #[cfg(not(target_arch = "wasm32"))] diff --git a/gateway/gateway-requests/src/registration/handshake/state.rs b/gateway/gateway-requests/src/registration/handshake/state.rs index a224e24720..046f523f76 100644 --- a/gateway/gateway-requests/src/registration/handshake/state.rs +++ b/gateway/gateway-requests/src/registration/handshake/state.rs @@ -1,4 +1,4 @@ -// Copyright 2020 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2020-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use crate::registration::handshake::error::HandshakeError; @@ -15,9 +15,17 @@ use nym_crypto::{ }; use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewaySharedKeyHkdfAlgorithm}; use rand::{CryptoRng, RngCore}; -use std::convert::{TryFrom, TryInto}; +use std::convert::TryInto; +use std::str::FromStr; +use std::time::Duration; use tungstenite::Message as WsMessage; +#[cfg(not(target_arch = "wasm32"))] +use tokio::time::timeout; + +#[cfg(target_arch = "wasm32")] +use wasmtimer::tokio::timeout; + /// Handshake state. pub(crate) struct State<'a, S> { /// The underlying WebSocket stream. @@ -36,6 +44,10 @@ pub(crate) struct State<'a, S> { /// The known or received public identity key of the remote. /// Ideally it would always be known before the handshake was initiated. remote_pubkey: Option<identity::PublicKey>, + + // this field is really out of place here, however, we need to propagate this information somehow + // in order to establish correct protocol for backwards compatibility reasons + expects_credential_usage: bool, } impl<'a, S> State<'a, S> { @@ -44,6 +56,7 @@ impl<'a, S> State<'a, S> { ws_stream: &'a mut S, identity: &'a identity::KeyPair, remote_pubkey: Option<identity::PublicKey>, + expects_credential_usage: bool, ) -> Self { let ephemeral_keypair = encryption::KeyPair::new(rng); State { @@ -52,6 +65,7 @@ impl<'a, S> State<'a, S> { identity, remote_pubkey, derived_shared_keys: None, + expects_credential_usage, } } @@ -67,15 +81,8 @@ impl<'a, S> State<'a, S> { self.identity .public_key() .to_bytes() - .iter() - .cloned() - .chain( - self.ephemeral_keypair - .public_key() - .to_bytes() - .iter() - .cloned(), - ) + .into_iter() + .chain(self.ephemeral_keypair.public_key().to_bytes()) .collect() } @@ -132,9 +139,8 @@ impl<'a, S> State<'a, S> { .ephemeral_keypair .public_key() .to_bytes() - .iter() - .cloned() - .chain(remote_ephemeral_key.to_bytes().iter().cloned()) + .into_iter() + .chain(remote_ephemeral_key.to_bytes()) .collect(); let signature = self.identity.private_key().sign(message); @@ -177,15 +183,8 @@ impl<'a, S> State<'a, S> { // g^y || g^x, if y is remote and x is local let signed_payload: Vec<_> = remote_ephemeral_key .to_bytes() - .iter() - .cloned() - .chain( - self.ephemeral_keypair - .public_key() - .to_bytes() - .iter() - .cloned(), - ) + .into_iter() + .chain(self.ephemeral_keypair.public_key().to_bytes()) .collect(); self.remote_pubkey @@ -200,35 +199,56 @@ impl<'a, S> State<'a, S> { self.remote_pubkey = Some(remote_pubkey) } - pub(crate) async fn receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError> + async fn _receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError> where S: Stream<Item = WsItem> + Unpin, { loop { - if let Some(msg) = self.ws_stream.next().await { - if let Ok(msg) = msg { - match msg { - WsMessage::Text(ws_msg) => match types::RegistrationHandshake::try_from(ws_msg) { - Ok(reg_handshake_msg) => return match reg_handshake_msg { + let Some(msg) = self.ws_stream.next().await else { + return Err(HandshakeError::ClosedStream); + }; + + let Ok(msg) = msg else { + return Err(HandshakeError::NetworkError); + }; + + match msg { + WsMessage::Text(ref ws_msg) => { + match types::RegistrationHandshake::from_str(ws_msg) { + Ok(reg_handshake_msg) => { + return match reg_handshake_msg { // hehe, that's a bit disgusting that the type system requires we explicitly ignore the // protocol_version field that we actually never attach at this point // yet another reason for the overdue refactor - types::RegistrationHandshake::HandshakePayload { data, .. } => Ok(data), - types::RegistrationHandshake::HandshakeError { message } => Err(HandshakeError::RemoteError(message)), - }, - Err(_) => error!("Received a non-handshake message during the registration handshake! It's getting dropped."), - }, - _ => error!("Received non-text message during registration handshake"), + types::RegistrationHandshake::HandshakePayload { data, .. } => { + Ok(data) + } + types::RegistrationHandshake::HandshakeError { message } => { + Err(HandshakeError::RemoteError(message)) + } + }; + } + Err(_) => { + error!("Received a non-handshake message during the registration handshake! It's getting dropped. The received content was: '{msg}'"); + continue; + } } - } else { - return Err(HandshakeError::NetworkError); } - } else { - return Err(HandshakeError::ClosedStream); + _ => error!("Received non-text message during registration handshake"), } } } + pub(crate) async fn receive_handshake_message(&mut self) -> Result<Vec<u8>, HandshakeError> + where + S: Stream<Item = WsItem> + Unpin, + { + // TODO: make timeout duration configurable + timeout(Duration::from_secs(5), self._receive_handshake_message()) + .await + .map_err(|_| HandshakeError::Timeout)? + } + // upon receiving this, the receiver should terminate the handshake pub(crate) async fn send_handshake_error<M: Into<String>>( &mut self, @@ -251,7 +271,8 @@ impl<'a, S> State<'a, S> { where S: Sink<WsMessage> + Unpin, { - let handshake_message = types::RegistrationHandshake::new_payload(payload); + let handshake_message = + types::RegistrationHandshake::new_payload(payload, self.expects_credential_usage); self.ws_stream .send(WsMessage::Text(handshake_message.try_into().unwrap())) .await diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index cc85d408c6..58e82c0221 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -5,7 +5,7 @@ use crate::authentication::encrypted_address::EncryptedAddressBytes; use crate::iv::IV; use crate::models::{CredentialSpendingRequest, OldV1Credential}; use crate::registration::handshake::SharedKeys; -use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION}; +use crate::{GatewayMacSize, CURRENT_PROTOCOL_VERSION, INITIAL_PROTOCOL_VERSION}; use log::error; use nym_credentials::coconut::bandwidth::CredentialSpendingData; use nym_credentials_interface::{CoconutError, UnknownCredentialType}; @@ -19,6 +19,7 @@ use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorit use nym_sphinx::DestinationAddressBytes; use serde::{Deserialize, Serialize}; use std::convert::{TryFrom, TryInto}; +use std::str::FromStr; use std::string::FromUtf8Error; use thiserror::Error; use tungstenite::protocol::Message; @@ -37,9 +38,17 @@ pub enum RegistrationHandshake { } impl RegistrationHandshake { - pub fn new_payload(data: Vec<u8>) -> Self { + pub fn new_payload(data: Vec<u8>, will_use_credentials: bool) -> Self { + // if we're not going to be using credentials, advertise lower protocol version to allow connection + // to wider range of gateways + let protocol_version = if will_use_credentials { + Some(CURRENT_PROTOCOL_VERSION) + } else { + Some(INITIAL_PROTOCOL_VERSION) + }; + RegistrationHandshake::HandshakePayload { - protocol_version: Some(CURRENT_PROTOCOL_VERSION), + protocol_version, data, } } @@ -51,11 +60,19 @@ impl RegistrationHandshake { } } +impl FromStr for RegistrationHandshake { + type Err = serde_json::Error; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + serde_json::from_str(s) + } +} + impl TryFrom<String> for RegistrationHandshake { type Error = serde_json::Error; fn try_from(msg: String) -> Result<Self, serde_json::Error> { - serde_json::from_str(&msg) + msg.parse() } } @@ -155,9 +172,18 @@ impl ClientControlRequest { address: DestinationAddressBytes, enc_address: EncryptedAddressBytes, iv: IV, + uses_credentials: bool, ) -> Self { + // if we're not going to be using credentials, advertise lower protocol version to allow connection + // to wider range of gateways + let protocol_version = if uses_credentials { + Some(CURRENT_PROTOCOL_VERSION) + } else { + Some(INITIAL_PROTOCOL_VERSION) + }; + ClientControlRequest::Authenticate { - protocol_version: Some(CURRENT_PROTOCOL_VERSION), + protocol_version, address: address.as_base58_string(), enc_address: enc_address.to_base58_string(), iv: iv.to_base58_string(), diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index cdd144c175..f5236af60d 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -4087,7 +4087,9 @@ dependencies = [ "serde", "serde_json", "thiserror", + "tokio", "tungstenite", + "wasmtimer", "zeroize", ] From 8f1f61e247b3cb9d408c57b0f7ff8bdf0840e96d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 13 Mar 2024 15:20:32 +0100 Subject: [PATCH 208/394] Remove cli conflicts for nr vs ipr --- gateway/src/commands/init.rs | 4 ++-- gateway/src/commands/run.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index bfa12bd66d..58dc427f8b 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -82,11 +82,11 @@ pub struct Init { statistics_service_url: Option<url::Url>, /// Allows this gateway to run an embedded network requester for minimal network overhead - #[clap(long, conflicts_with = "with_ip_packet_router")] + #[clap(long)] with_network_requester: bool, /// Allows this gateway to run an embedded network requester for minimal network overhead - #[clap(long, hide = true, conflicts_with = "with_network_requester")] + #[clap(long, hide = true)] with_ip_packet_router: bool, // ##### NETWORK REQUESTER FLAGS ##### diff --git a/gateway/src/commands/run.rs b/gateway/src/commands/run.rs index 76f7629de5..3418c216ac 100644 --- a/gateway/src/commands/run.rs +++ b/gateway/src/commands/run.rs @@ -87,11 +87,11 @@ pub struct Run { statistics_service_url: Option<url::Url>, /// Allows this gateway to run an embedded network requester for minimal network overhead - #[arg(long, conflicts_with = "with_ip_packet_router")] + #[arg(long)] with_network_requester: Option<bool>, /// Allows this gateway to run an embedded network requester for minimal network overhead - #[arg(long, hide = true, conflicts_with = "with_network_requester")] + #[arg(long, hide = true)] with_ip_packet_router: Option<bool>, // ##### NETWORK REQUESTER FLAGS ##### From 6e8c0ad90e6e3643e2b00913cd8360f7e7db7464 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 13 Mar 2024 17:03:00 +0100 Subject: [PATCH 209/394] wip --- gateway/src/commands/init.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index 58dc427f8b..d8f80112aa 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -243,7 +243,9 @@ pub async fn execute(args: Init) -> anyhow::Result<()> { if config.network_requester.enabled { initialise_local_network_requester(&config, nr_opts, *identity_keys.public_key()) .await?; - } else if config.ip_packet_router.enabled { + } + + if config.ip_packet_router.enabled { initialise_local_ip_packet_router(&config, ip_opts, *identity_keys.public_key()) .await?; } From 08ed7b42de9a474a968e2074d91b5edbefdbfc29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 09:55:57 +0100 Subject: [PATCH 210/394] Change to anyhow::Result at top-level --- gateway/src/commands/mod.rs | 3 +-- gateway/src/main.rs | 3 +-- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/gateway/src/commands/mod.rs b/gateway/src/commands/mod.rs index 34ecc95b47..f3b1adac7c 100644 --- a/gateway/src/commands/mod.rs +++ b/gateway/src/commands/mod.rs @@ -5,7 +5,6 @@ use crate::Cli; use clap::CommandFactory; use clap::Subcommand; use nym_bin_common::completions::{fig_generate, ArgShell}; -use std::error::Error; pub(crate) mod build_info; pub(crate) mod helpers; @@ -50,7 +49,7 @@ pub(crate) enum Commands { GenerateFigSpec, } -pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync>> { +pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { let bin_name = "nym-gateway"; match args.command { diff --git a/gateway/src/main.rs b/gateway/src/main.rs index f88398e0b9..44e33aec73 100644 --- a/gateway/src/main.rs +++ b/gateway/src/main.rs @@ -11,7 +11,6 @@ use nym_bin_common::bin_info; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; use nym_bin_common::output_format::OutputFormat; use nym_network_defaults::setup_env; -use std::error::Error; use std::sync::OnceLock; mod commands; @@ -42,7 +41,7 @@ struct Cli { } #[tokio::main] -async fn main() -> Result<(), Box<dyn Error + Send + Sync>> { +async fn main() -> anyhow::Result<()> { setup_logging(); let args = Cli::parse(); From 30413d787771d344d15a2a335a9dd0a999aa6a4a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 09:56:18 +0100 Subject: [PATCH 211/394] Add debug derive --- gateway/src/commands/helpers.rs | 4 ++-- gateway/src/commands/init.rs | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 4b91876b75..f1ddb1a26a 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -99,7 +99,7 @@ impl OverrideConfig { } } -#[derive(Default)] +#[derive(Default, Debug)] pub(crate) struct OverrideNetworkRequesterConfig { pub(crate) fastmode: bool, pub(crate) no_cover: bool, @@ -112,7 +112,7 @@ pub(crate) struct OverrideNetworkRequesterConfig { pub(crate) statistics_recipient: Option<String>, } -#[derive(Default)] +#[derive(Default, Debug)] pub(crate) struct OverrideIpPacketRouterConfig { // TODO } diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index d8f80112aa..b65cc062d2 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -17,7 +17,7 @@ use std::{fs, io}; use super::helpers::OverrideIpPacketRouterConfig; -#[derive(Args, Clone)] +#[derive(Args, Clone, Debug)] pub struct Init { /// Id of the gateway we want to create config for #[clap(long)] From 79852d9dcde0c40dbeee860719581aca2b2e1366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 09:56:56 +0100 Subject: [PATCH 212/394] Set storage paths indepedently --- gateway/src/commands/helpers.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index f1ddb1a26a..043288db42 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -88,14 +88,15 @@ impl OverrideConfig { if config.network_requester.enabled && config.storage_paths.network_requester_config.is_none() { - Ok(config.with_default_network_requester_config_path()) - } else if config.ip_packet_router.enabled - && config.storage_paths.ip_packet_router_config.is_none() - { - Ok(config.with_default_ip_packet_router_config_path()) - } else { - Ok(config) + config = config.with_default_network_requester_config_path(); } + + if config.ip_packet_router.enabled && config.storage_paths.ip_packet_router_config.is_none() + { + config = config.with_default_ip_packet_router_config_path(); + } + + Ok(config) } } From 7132e2dae5cff8e332af2263bfdc660d0370fba4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 10:04:54 +0100 Subject: [PATCH 213/394] Remove outdated comments --- gateway/src/node/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 9fa6d1af8e..b2d7131c58 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -80,7 +80,7 @@ pub(crate) async fn create_gateway( let cfg = load_ip_packet_router_config(&config.gateway.id, path)?; Some(override_ip_packet_router_config(cfg, ip_config_override)) } else { - // if NR is enabled, the config path must be specified + // if IPR is enabled, the config path must be specified return Err(GatewayError::UnspecifiedIpPacketRouterConfig); } } else { @@ -504,8 +504,6 @@ impl<St> Gateway<St> { None }; - // NOTE: this is mutually exclusive with the network requester (for now). This is reflected - // in the command line arguments as well. if self.config.ip_packet_router.enabled { let embedded_ip_sp = self .start_ip_packet_router( From 8e6215ecf4baeaadf9c73a05b9751a51d6bb5835 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 14:52:28 +0100 Subject: [PATCH 214/394] Rename to embedded_clients --- .../{embedded_network_requester => embedded_clients}/mod.rs | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename gateway/src/node/client_handling/{embedded_network_requester => embedded_clients}/mod.rs (100%) diff --git a/gateway/src/node/client_handling/embedded_network_requester/mod.rs b/gateway/src/node/client_handling/embedded_clients/mod.rs similarity index 100% rename from gateway/src/node/client_handling/embedded_network_requester/mod.rs rename to gateway/src/node/client_handling/embedded_clients/mod.rs From 4c125792b295e56796e8c741e0afeb5d247727a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 14:52:59 +0100 Subject: [PATCH 215/394] Update mod.rs --- gateway/src/node/client_handling/mod.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gateway/src/node/client_handling/mod.rs b/gateway/src/node/client_handling/mod.rs index ae26cc558d..fb6f1169a3 100644 --- a/gateway/src/node/client_handling/mod.rs +++ b/gateway/src/node/client_handling/mod.rs @@ -3,9 +3,9 @@ use crate::node::client_handling::bandwidth::Bandwidth; -pub(crate) mod active_clients; mod bandwidth; -pub(crate) mod embedded_network_requester; +pub(crate) mod active_clients; +pub(crate) mod embedded_clients; pub(crate) mod websocket; pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = Bandwidth::new(64 * 1024 * 1024 * 1024); // 64GB From b710fbe524b5c6a332f589f7c6e64bdfa995d9b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 14:57:13 +0100 Subject: [PATCH 216/394] Imports --- gateway/src/node/client_handling/active_clients.rs | 2 +- gateway/src/node/mod.rs | 4 +--- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/gateway/src/node/client_handling/active_clients.rs b/gateway/src/node/client_handling/active_clients.rs index ef9b995a88..e60ebb6d17 100644 --- a/gateway/src/node/client_handling/active_clients.rs +++ b/gateway/src/node/client_handling/active_clients.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use super::websocket::message_receiver::{IsActiveRequestSender, MixMessageSender}; -use crate::node::client_handling::embedded_network_requester::LocalNetworkRequesterHandle; +use crate::node::client_handling::embedded_clients::LocalNetworkRequesterHandle; use dashmap::DashMap; use log::warn; use nym_sphinx::DestinationAddressBytes; diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index b2d7131c58..3568d00c14 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -11,9 +11,7 @@ use crate::config::Config; use crate::error::GatewayError; use crate::http::HttpApiBuilder; use crate::node::client_handling::active_clients::ActiveClientsStore; -use crate::node::client_handling::embedded_network_requester::{ - LocalNetworkRequesterHandle, MessageRouter, -}; +use crate::node::client_handling::embedded_clients::{LocalNetworkRequesterHandle, MessageRouter}; use crate::node::client_handling::websocket; use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier; use crate::node::helpers::{initialise_main_storage, load_network_requester_config}; From 7f3c53e19669e72feec828ca4cb579cae25ce269 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 15:00:27 +0100 Subject: [PATCH 217/394] Rename struct --- .../node/client_handling/active_clients.rs | 6 +++--- .../client_handling/embedded_clients/mod.rs | 20 +++++++++---------- gateway/src/node/client_handling/mod.rs | 2 +- gateway/src/node/mod.rs | 13 +++++------- 4 files changed, 19 insertions(+), 22 deletions(-) diff --git a/gateway/src/node/client_handling/active_clients.rs b/gateway/src/node/client_handling/active_clients.rs index e60ebb6d17..f02553ff5c 100644 --- a/gateway/src/node/client_handling/active_clients.rs +++ b/gateway/src/node/client_handling/active_clients.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use super::websocket::message_receiver::{IsActiveRequestSender, MixMessageSender}; -use crate::node::client_handling::embedded_clients::LocalNetworkRequesterHandle; +use crate::node::client_handling::embedded_clients::LocalEmbeddedClientHandle; use dashmap::DashMap; use log::warn; use nym_sphinx::DestinationAddressBytes; @@ -13,7 +13,7 @@ enum ActiveClient { Remote(ClientIncomingChannels), /// Handle to a locally (inside the same process) running network requester client. - Embedded(LocalNetworkRequesterHandle), + Embedded(LocalEmbeddedClientHandle), } impl ActiveClient { @@ -150,7 +150,7 @@ impl ActiveClientsStore { } /// Inserts a handle to the embedded network requester - pub(crate) fn insert_embedded(&self, local_nr_handle: LocalNetworkRequesterHandle) { + pub(crate) fn insert_embedded(&self, local_nr_handle: LocalEmbeddedClientHandle) { let key = local_nr_handle.client_destination(); let entry = ActiveClient::Embedded(local_nr_handle); if self.inner.insert(key, entry).is_some() { diff --git a/gateway/src/node/client_handling/embedded_clients/mod.rs b/gateway/src/node/client_handling/embedded_clients/mod.rs index 8070145cf0..1acc1991aa 100644 --- a/gateway/src/node/client_handling/embedded_clients/mod.rs +++ b/gateway/src/node/client_handling/embedded_clients/mod.rs @@ -12,15 +12,15 @@ use nym_sphinx::DestinationAddressBytes; use nym_task::TaskClient; #[derive(Debug)] -pub(crate) struct LocalNetworkRequesterHandle { - /// Nym address of the embedded network requester. +pub(crate) struct LocalEmbeddedClientHandle { + /// Nym address of the embedded client. pub(crate) address: Recipient, - /// Message channel used internally to forward any received mix packets to the network requester. + /// Message channel used internally to forward any received mix packets to the client. pub(crate) mix_message_sender: MixMessageSender, } -impl LocalNetworkRequesterHandle { +impl LocalEmbeddedClientHandle { pub(crate) fn new(address: Recipient, mix_message_sender: MixMessageSender) -> Self { Self { address, @@ -48,8 +48,8 @@ impl LocalNetworkRequesterHandle { // calling the method. however, this would have caused slightly more complexity and more overhead // (due to more data being copied to every [mix] connection) // -/// task responsible for receiving messages for locally NR requester from multiple mix connections -/// and forwarding them via the router. kinda equivalent of a client socket handler +/// task responsible for receiving messages for locally embedded client from multiple mix +/// connections and forwarding them via the router. kinda equivalent of a client socket handler pub(crate) struct MessageRouter { mix_receiver: MixMessageReceiver, packet_router: PacketRouter, @@ -76,24 +76,24 @@ impl MessageRouter { } pub(crate) async fn run_with_shutdown(mut self, mut shutdown: TaskClient) { - debug!("Started embedded network requester message router with graceful shutdown support"); + debug!("Started embedded client message router with graceful shutdown support"); while !shutdown.is_shutdown() { tokio::select! { messages = self.mix_receiver.next() => match messages { Some(messages) => self.handle_received_messages(messages), None => { - log::trace!("embedded_network_requester::MessageRouter: Stopping since channel closed"); + log::trace!("embedded_clients::MessageRouter: Stopping since channel closed"); break; } }, _ = shutdown.recv_with_delay() => { - log::trace!("embedded_network_requester::MessageRouter: Received shutdown"); + log::trace!("embedded_clients::MessageRouter: Received shutdown"); debug_assert!(shutdown.is_shutdown()); break } } } - debug!("embedded_network_requester::MessageRouter: Exiting") + debug!("embedded_network_clients::MessageRouter: Exiting") } } diff --git a/gateway/src/node/client_handling/mod.rs b/gateway/src/node/client_handling/mod.rs index fb6f1169a3..b43bb631a2 100644 --- a/gateway/src/node/client_handling/mod.rs +++ b/gateway/src/node/client_handling/mod.rs @@ -3,8 +3,8 @@ use crate::node::client_handling::bandwidth::Bandwidth; -mod bandwidth; pub(crate) mod active_clients; +mod bandwidth; pub(crate) mod embedded_clients; pub(crate) mod websocket; diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 3568d00c14..3b9fa5ccca 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -11,7 +11,7 @@ use crate::config::Config; use crate::error::GatewayError; use crate::http::HttpApiBuilder; use crate::node::client_handling::active_clients::ActiveClientsStore; -use crate::node::client_handling::embedded_clients::{LocalNetworkRequesterHandle, MessageRouter}; +use crate::node::client_handling::embedded_clients::{LocalEmbeddedClientHandle, MessageRouter}; use crate::node::client_handling::websocket; use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier; use crate::node::helpers::{initialise_main_storage, load_network_requester_config}; @@ -49,7 +49,7 @@ struct StartedNetworkRequester { used_request_filter: RequestFilter, /// Handle to interact with the local network requester - handle: LocalNetworkRequesterHandle, + handle: LocalEmbeddedClientHandle, } /// Wire up and create Gateway instance @@ -317,7 +317,7 @@ impl<St> Gateway<St> { info!("the local network requester is running on {address}",); Ok(StartedNetworkRequester { used_request_filter: start_data.request_filter, - handle: LocalNetworkRequesterHandle::new(address, nr_mix_sender), + handle: LocalEmbeddedClientHandle::new(address, nr_mix_sender), }) } @@ -325,7 +325,7 @@ impl<St> Gateway<St> { &self, forwarding_channel: MixForwardingSender, shutdown: TaskClient, - ) -> Result<LocalNetworkRequesterHandle, GatewayError> { + ) -> Result<LocalEmbeddedClientHandle, GatewayError> { info!("Starting IP packet provider..."); // if network requester is enabled, configuration file must be provided! @@ -383,10 +383,7 @@ impl<St> Gateway<St> { start_data.address ); - Ok(LocalNetworkRequesterHandle::new_ip( - start_data, - nr_mix_sender, - )) + Ok(LocalEmbeddedClientHandle::new_ip(start_data, nr_mix_sender)) } async fn wait_for_interrupt( From 34be5abaf3d9cdc2f59b25c2b3c82d07379bbf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 15:46:13 +0100 Subject: [PATCH 218/394] More minor naming fixes --- .../src/node/client_handling/active_clients.rs | 15 ++++++++------- .../node/client_handling/embedded_clients/mod.rs | 4 ++-- gateway/src/node/mod.rs | 14 +++++--------- 3 files changed, 15 insertions(+), 18 deletions(-) diff --git a/gateway/src/node/client_handling/active_clients.rs b/gateway/src/node/client_handling/active_clients.rs index f02553ff5c..e9d5ccb15f 100644 --- a/gateway/src/node/client_handling/active_clients.rs +++ b/gateway/src/node/client_handling/active_clients.rs @@ -12,7 +12,7 @@ enum ActiveClient { /// Handle to a remote client connected via a network socket. Remote(ClientIncomingChannels), - /// Handle to a locally (inside the same process) running network requester client. + /// Handle to a locally (inside the same process) running client. Embedded(LocalEmbeddedClientHandle), } @@ -149,13 +149,14 @@ impl ActiveClientsStore { } } - /// Inserts a handle to the embedded network requester - pub(crate) fn insert_embedded(&self, local_nr_handle: LocalEmbeddedClientHandle) { - let key = local_nr_handle.client_destination(); - let entry = ActiveClient::Embedded(local_nr_handle); + /// Inserts a handle to the embedded client + pub(crate) fn insert_embedded(&self, local_client_handle: LocalEmbeddedClientHandle) { + let key = local_client_handle.client_destination(); + let entry = ActiveClient::Embedded(local_client_handle); if self.inner.insert(key, entry).is_some() { - // this is literally impossible since we're starting local NR before even spawning the websocket listener task - panic!("somehow we already had a client with the same address as our local NR!") + // this is literally impossible since we're starting the local embedded client before + // even spawning the websocket listener task + panic!("somehow we already had a client with the same address as our local embedded client!") } } diff --git a/gateway/src/node/client_handling/embedded_clients/mod.rs b/gateway/src/node/client_handling/embedded_clients/mod.rs index 1acc1991aa..2166622972 100644 --- a/gateway/src/node/client_handling/embedded_clients/mod.rs +++ b/gateway/src/node/client_handling/embedded_clients/mod.rs @@ -48,7 +48,7 @@ impl LocalEmbeddedClientHandle { // calling the method. however, this would have caused slightly more complexity and more overhead // (due to more data being copied to every [mix] connection) // -/// task responsible for receiving messages for locally embedded client from multiple mix +/// task responsible for receiving messages for locally embedded clients from multiple mix /// connections and forwarding them via the router. kinda equivalent of a client socket handler pub(crate) struct MessageRouter { mix_receiver: MixMessageReceiver, @@ -71,7 +71,7 @@ impl MessageRouter { if let Err(err) = self.packet_router.route_received(messages) { // TODO: what should we do here? I don't think this could/should ever fail. // is panicking the appropriate thing to do then? - error!("failed to route packets to local NR: {err}") + error!("failed to route packets to local embedded client: {err}") } } diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 3b9fa5ccca..e798389f40 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -330,12 +330,11 @@ impl<St> Gateway<St> { // if network requester is enabled, configuration file must be provided! let Some(ip_opts) = &self.ip_packet_router_opts else { - log::error!("IP packet router is enabled but no configuration file was provided!"); return Err(GatewayError::UnspecifiedIpPacketRouterConfig); }; // this gateway, whenever it has anything to send to its local NR will use fake_client_tx - let (nr_mix_sender, nr_mix_receiver) = mpsc::unbounded(); + let (ipr_mix_sender, ipr_mix_receiver) = mpsc::unbounded(); let router_shutdown = shutdown.fork("message_router"); let (router_tx, mut router_rx) = oneshot::channel(); @@ -346,7 +345,6 @@ impl<St> Gateway<St> { router_tx, ); - // TODO: well, wire it up internally to gateway traffic, shutdowns, etc. let (on_start_tx, on_start_rx) = oneshot::channel(); let mut ip_packet_router = nym_ip_packet_router::IpPacketRouter::new(ip_opts.config.clone()) @@ -377,13 +375,11 @@ impl<St> Gateway<St> { return Err(GatewayError::IpPacketRouterStartupFailure); }; - MessageRouter::new(nr_mix_receiver, packet_router).start_with_shutdown(router_shutdown); - info!( - "the local ip packet router is running on {}", - start_data.address - ); + MessageRouter::new(ipr_mix_receiver, packet_router).start_with_shutdown(router_shutdown); + let address = start_data.address; - Ok(LocalEmbeddedClientHandle::new_ip(start_data, nr_mix_sender)) + info!("the local ip packet router is running on {address}"); + Ok(LocalEmbeddedClientHandle::new(address, ipr_mix_sender)) } async fn wait_for_interrupt( From 0b49c74ac9b7bebc1ec43e9458a70eb143057cfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 15 Mar 2024 15:54:49 +0100 Subject: [PATCH 219/394] Remove unused function --- .../src/node/client_handling/embedded_clients/mod.rs | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/gateway/src/node/client_handling/embedded_clients/mod.rs b/gateway/src/node/client_handling/embedded_clients/mod.rs index 2166622972..a7264f0985 100644 --- a/gateway/src/node/client_handling/embedded_clients/mod.rs +++ b/gateway/src/node/client_handling/embedded_clients/mod.rs @@ -28,17 +28,6 @@ impl LocalEmbeddedClientHandle { } } - // TODO: generalize this whole thing to be general. And change the name(s). - pub(crate) fn new_ip( - start_data: nym_ip_packet_router::OnStartData, - mix_message_sender: MixMessageSender, - ) -> Self { - Self { - address: start_data.address, - mix_message_sender, - } - } - pub(crate) fn client_destination(&self) -> DestinationAddressBytes { self.address.identity().derive_destination_address() } From ae6c80f0cdbc2708d036f4695f7b91a58c067231 Mon Sep 17 00:00:00 2001 From: mx <33262279+mfahampshire@users.noreply.github.com> Date: Mon, 18 Mar 2024 15:15:59 +0100 Subject: [PATCH 220/394] FFI share lib + initial uniffi-bindgen-go implementation (#4394) * fixed rebase conflict with cargo.lock * shared cleanup * moved returncode to shared * first pass at Go binding structure * minor cleanup * working on custom type udl * trying to get LDFLAG script working * commit before changing alias -> proper types * converted CCallbacks from aliases to Struct * cleanup comments * temp * push to share * cleanup * trait Lift not implemented for *const i8 issue * test of refactor: * move c-specific var casting out of shared/ into cpp/ * error returning in go/ over ffi boundary with uniffi * _internal functions ffi wrapper agnostic * moved lang-specific type conversions to cpp / go bindings and out of shared * got send_message working in c/c++ & go * split out c/c++-specific types to mod * cont. with making _internal fns lang agnostic * working on final fn for C and shared (listening for incoming messages) * fixed return err on listen_for_incoming * got full example run running again after shared/ refactor * removed unused struct * code comments * got first runthrough of go example code * script cleanup * clean up readme instructions * clippy * removed unused imports * rustfmt * Update sdk/ffi/go/README.md with link to example file Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> * updated readme with extra build and usage info * renamed binding outer directory for nicer path * moved example file from ffi/main.go -> ./example.go * updated README with new example file name --------- Co-authored-by: mfahampshire <mfahampshire@pm.me> Co-authored-by: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> --- sdk/ffi/README.md | 7 + sdk/ffi/cpp/Cargo.lock | 357 +- sdk/ffi/cpp/Cargo.toml | 8 +- sdk/ffi/cpp/README.md | 4 +- sdk/ffi/cpp/build.sh | 2 +- sdk/ffi/cpp/src/lib.rs | 216 +- sdk/ffi/cpp/src/main.cpp | 12 +- sdk/ffi/cpp/src/types.rs | 52 + sdk/ffi/go/Cargo.lock | 6061 ++++++++++++++++++++++++ sdk/ffi/go/Cargo.toml | 31 + sdk/ffi/go/README.md | 47 + sdk/ffi/go/build.rs | 4 + sdk/ffi/go/build.sh | 53 + sdk/ffi/go/example.go | 74 + sdk/ffi/go/go-nym/bindings/bindings.c | 8 + sdk/ffi/go/go-nym/bindings/bindings.go | 773 +++ sdk/ffi/go/go-nym/bindings/bindings.h | 427 ++ sdk/ffi/go/go.mod | 3 + sdk/ffi/go/go.sum | 0 sdk/ffi/go/src/bindings.udl | 28 + sdk/ffi/go/src/lib.rs | 82 + sdk/ffi/go/uniffi-bindgen.rs | 3 + sdk/ffi/shared/Cargo.lock | 6045 +++++++++++++++++++++++ sdk/ffi/shared/Cargo.toml | 27 + sdk/ffi/shared/README.md | 8 + sdk/ffi/shared/src/lib.rs | 120 + sdk/ffi/shared/uniffi-bindgen.rs | 3 + 27 files changed, 14259 insertions(+), 196 deletions(-) create mode 100644 sdk/ffi/README.md create mode 100644 sdk/ffi/cpp/src/types.rs create mode 100644 sdk/ffi/go/Cargo.lock create mode 100644 sdk/ffi/go/Cargo.toml create mode 100644 sdk/ffi/go/README.md create mode 100644 sdk/ffi/go/build.rs create mode 100755 sdk/ffi/go/build.sh create mode 100644 sdk/ffi/go/example.go create mode 100644 sdk/ffi/go/go-nym/bindings/bindings.c create mode 100644 sdk/ffi/go/go-nym/bindings/bindings.go create mode 100644 sdk/ffi/go/go-nym/bindings/bindings.h create mode 100644 sdk/ffi/go/go.mod create mode 100644 sdk/ffi/go/go.sum create mode 100644 sdk/ffi/go/src/bindings.udl create mode 100644 sdk/ffi/go/src/lib.rs create mode 100644 sdk/ffi/go/uniffi-bindgen.rs create mode 100644 sdk/ffi/shared/Cargo.lock create mode 100644 sdk/ffi/shared/Cargo.toml create mode 100644 sdk/ffi/shared/README.md create mode 100644 sdk/ffi/shared/src/lib.rs create mode 100644 sdk/ffi/shared/uniffi-bindgen.rs diff --git a/sdk/ffi/README.md b/sdk/ffi/README.md new file mode 100644 index 0000000000..562ed932ea --- /dev/null +++ b/sdk/ffi/README.md @@ -0,0 +1,7 @@ +# FFI +This repo contains bindings for C/C++ and Go in the respectively named directories. + +`shared/` contains shared 'internal' functions which are imported by bindings. Primarily these functions rely on managing: +* that the client is not mutated by multiple threads simultaneously +* that client actions happen in blocking threads + diff --git a/sdk/ffi/cpp/Cargo.lock b/sdk/ffi/cpp/Cargo.lock index e7174a3505..6b3f0b71d6 100644 --- a/sdk/ffi/cpp/Cargo.lock +++ b/sdk/ffi/cpp/Cargo.lock @@ -155,6 +155,47 @@ version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive", + "askama_escape", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + [[package]] name = "async-trait" version = "0.1.77" @@ -240,6 +281,15 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "basic-toml" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" +dependencies = [ + "serde", +] + [[package]] name = "bincode" version = "1.3.3" @@ -474,6 +524,38 @@ dependencies = [ "serde", ] +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.21", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cc" version = "1.0.83" @@ -1466,6 +1548,15 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + [[package]] name = "funty" version = "2.0.0" @@ -1650,6 +1741,12 @@ dependencies = [ "url", ] +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + [[package]] name = "gloo-net" version = "0.3.1" @@ -1696,6 +1793,17 @@ dependencies = [ "web-sys", ] +[[package]] +name = "goblin" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" +dependencies = [ + "log", + "plain", + "scroll", +] + [[package]] name = "group" version = "0.10.0" @@ -2283,6 +2391,16 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" +[[package]] +name = "mime_guess" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -2561,6 +2679,20 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-cpp-ffi" +version = "0.1.1" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "lazy_static", + "nym-bin-common", + "nym-ffi-shared", + "nym-sdk", + "nym-sphinx-anonymous-replies", + "tokio", +] + [[package]] name = "nym-credential-storage" version = "0.1.0" @@ -2696,6 +2828,21 @@ dependencies = [ "url", ] +[[package]] +name = "nym-ffi-shared" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "lazy_static", + "nym-bin-common", + "nym-sdk", + "nym-sphinx-anonymous-replies", + "tokio", + "uniffi", + "uniffi_build", +] + [[package]] name = "nym-gateway-client" version = "0.1.0" @@ -3292,19 +3439,6 @@ dependencies = [ "x25519-dalek 2.0.0", ] -[[package]] -name = "nym_cpp_ffi" -version = "0.1.0" -dependencies = [ - "anyhow", - "bs58 0.5.0", - "lazy_static", - "nym-bin-common", - "nym-sdk", - "nym-sphinx-anonymous-replies", - "tokio", -] - [[package]] name = "object" version = "0.32.2" @@ -3320,6 +3454,12 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "oneshot-uniffi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c" + [[package]] name = "opaque-debug" version = "0.2.3" @@ -3611,6 +3751,12 @@ version = "0.3.29" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + [[package]] name = "platforms" version = "3.3.0" @@ -4149,6 +4295,26 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + [[package]] name = "sct" version = "0.6.1" @@ -4220,6 +4386,9 @@ name = "semver" version = "1.0.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -4382,6 +4551,12 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + [[package]] name = "slab" version = "0.4.9" @@ -4649,6 +4824,12 @@ dependencies = [ "tokio-rustls 0.23.4", ] +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + [[package]] name = "stringprep" version = "0.1.4" @@ -5184,6 +5365,15 @@ 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" @@ -5217,6 +5407,138 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" +[[package]] +name = "uniffi" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" +dependencies = [ + "anyhow", + "camino", + "clap", + "uniffi_bindgen", + "uniffi_build", + "uniffi_core", + "uniffi_macros", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "clap", + "fs-err", + "glob", + "goblin", + "heck", + "once_cell", + "paste", + "serde", + "toml 0.5.11", + "uniffi_meta", + "uniffi_testing", + "uniffi_udl", +] + +[[package]] +name = "uniffi_build" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "uniffi_core" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b" +dependencies = [ + "anyhow", + "bytes", + "camino", + "log", + "once_cell", + "oneshot-uniffi", + "paste", + "static_assertions", +] + +[[package]] +name = "uniffi_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4" +dependencies = [ + "bincode", + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", + "toml 0.5.11", + "uniffi_build", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3" +dependencies = [ + "anyhow", + "uniffi_meta", + "uniffi_testing", + "weedle2", +] + [[package]] name = "universal-hash" version = "0.5.1" @@ -5473,6 +5795,15 @@ dependencies = [ "webpki 0.22.4", ] +[[package]] +name = "weedle2" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" +dependencies = [ + "nom", +] + [[package]] name = "winapi" version = "0.3.9" diff --git a/sdk/ffi/cpp/Cargo.toml b/sdk/ffi/cpp/Cargo.toml index 3fa5b04116..cea81dbd25 100644 --- a/sdk/ffi/cpp/Cargo.toml +++ b/sdk/ffi/cpp/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "nym_cpp_ffi" -version = "0.1.0" +name = "nym-cpp-ffi" +version = "0.1.1" edition = "2021" [lib] @@ -10,11 +10,11 @@ crate-type = ["cdylib"] [dependencies] # Async runtime tokio = { version = "1", features = ["full"] } -# Nym clients, addressing, packet format, common tools (logging) +# Nym clients, addressing, packet format, common tools (logging), ffi shared nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" } nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" } nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" } -# static var macro +nym-ffi-shared = { path = "../shared" } lazy_static = "1.4.0" # error handling anyhow = "1.0.75" diff --git a/sdk/ffi/cpp/README.md b/sdk/ffi/cpp/README.md index bc6dab6629..516c2b8f5b 100644 --- a/sdk/ffi/cpp/README.md +++ b/sdk/ffi/cpp/README.md @@ -1,8 +1,8 @@ # C++ FFI -> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel](). +> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel](https://matrix.to/#/#dev:nymtech.chat). This repo contains: -* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from C++. +* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from C++. These are essentially match statements wrapping imported functions from the `nym-ffi-shared` lib allowing for nicer [error handling](#error-handling-). * `main.cpp`: an example of using this library, relying on `Boost` for threads. The example `.cpp` file is a simple example flow of: diff --git a/sdk/ffi/cpp/build.sh b/sdk/ffi/cpp/build.sh index 020f2f6617..8fd2716352 100755 --- a/sdk/ffi/cpp/build.sh +++ b/sdk/ffi/cpp/build.sh @@ -44,7 +44,7 @@ else build_artifacts_and_link; ./main; else - echo "unknown optional argument - the only available optional argument is 'clean'" + printf "unknown optional argument - the only available optional argument is 'clean'" exit 1 fi fi diff --git a/sdk/ffi/cpp/src/lib.rs b/sdk/ffi/cpp/src/lib.rs index afcb2af51f..1c240bfb82 100644 --- a/sdk/ffi/cpp/src/lib.rs +++ b/sdk/ffi/cpp/src/lib.rs @@ -1,49 +1,13 @@ // Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use anyhow::{anyhow, bail}; -use lazy_static::lazy_static; -use nym_sdk::mixnet::{MixnetClient, MixnetMessageSender, ReconstructedMessage}; -use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag; +use nym_ffi_shared; use std::ffi::{c_char, c_int, CStr, CString}; + +use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag; use std::mem::forget; -use std::sync::{Arc, Mutex}; -use tokio::runtime::Runtime; - -/* -NYM_CLIENT: Static reference (only init-ed once) to: - - Arc: share ownership - - Mutex: thread-safe way to share data between threads - - Option: init-ed or not -RUNTIME: Tokio runtime: no need to pass back to C and deal with raw pointers as it was previously - */ -lazy_static! { - static ref NYM_CLIENT: Arc<Mutex<Option<MixnetClient>>> = Arc::new(Mutex::new(None)); - static ref RUNTIME: Runtime = Runtime::new().unwrap(); -} - -#[derive(Debug)] -pub enum StatusCode { - NoError = 0, - ClientInitError = -1, - ClientUninitialisedError = -2, - SelfAddrError = -3, - SendMsgError = -4, - ReplyError = -5, - ListenError = -6, -} - -// pub type CIntCallback = extern "C" fn(i32); -pub type CStringCallback = extern "C" fn(*const c_char); -pub type CMessageCallback = extern "C" fn(ReceivedMessage); - -// FFI-sanitised way of sending back a ReconstructedMessage to C -#[repr(C)] -pub struct ReceivedMessage { - message: *const u8, - size: usize, - sender_tag: *const c_char, -} +mod types; +use crate::types::types::{CMessageCallback, CStringCallback, ReceivedMessage, StatusCode}; #[no_mangle] pub extern "C" fn init_logging() { @@ -52,76 +16,31 @@ pub extern "C" fn init_logging() { #[no_mangle] pub extern "C" fn init_ephemeral() -> c_int { - match init_ephemeral_internal() { + match nym_ffi_shared::init_ephemeral_internal() { Ok(_) => StatusCode::NoError as c_int, Err(_) => StatusCode::ClientInitError as c_int, } } -fn init_ephemeral_internal() -> anyhow::Result<(), anyhow::Error> { - if NYM_CLIENT.lock().unwrap().as_ref().is_some() { - bail!("client already exists"); - } else { - RUNTIME.block_on(async move { - let init_client = MixnetClient::connect_new().await?; - let mut client = NYM_CLIENT.try_lock(); - if let Ok(ref mut client) = client { - **client = Some(init_client); - } else { - anyhow!("couldnt lock NYM_CLIENT"); - } - Ok::<(), anyhow::Error>(()) - })?; - } - Ok(()) -} - #[no_mangle] pub extern "C" fn get_self_address(callback: CStringCallback) -> c_int { - match get_self_address_internal(callback) { - Ok(_) => StatusCode::NoError as c_int, + match nym_ffi_shared::get_self_address_internal(/*callback*/) { + Ok(addr) => { + let c_ptr = CString::new(addr).expect("could not convert Nym address to CString"); + let call = CStringCallback::new(callback.callback); + // as_ptr() keeps ownership in rust unlike into_raw() so no need to free it + call.trigger(c_ptr.as_ptr()); + StatusCode::NoError as c_int + } Err(_) => StatusCode::SelfAddrError as c_int, } } -fn get_self_address_internal(callback: CStringCallback) -> anyhow::Result<(), anyhow::Error> { - let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); - if client.is_none() { - bail!("Client is not yet initialised"); - } - let nym_client = client - .as_ref() - .ok_or_else(|| anyhow!("could not get client as_ref()"))?; - // get address as cstring - let c_string = CString::new(nym_client.nym_address().to_string())?; - // as_ptr() keeps ownership in rust unlike into_raw() so no need to free it - callback(c_string.as_ptr()); - Ok(()) -} - #[no_mangle] pub extern "C" fn send_message(recipient: *const c_char, message: *const c_char) -> c_int { - match send_message_internal(recipient, message) { - Ok(_) => StatusCode::NoError as c_int, - Err(_) => StatusCode::SendMsgError as c_int, - } -} - -fn send_message_internal( - recipient: *const c_char, - message: *const c_char, -) -> anyhow::Result<(), anyhow::Error> { - let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); - if client.is_none() { - bail!("Client is not yet initialised"); - } - let nym_client = client - .as_ref() - .ok_or_else(|| anyhow!("could not get client as_ref()"))?; - let c_str = unsafe { if recipient.is_null() { - bail!("recipient is null"); + return StatusCode::RecipientNullError as c_int; } let c_str = CStr::from_ptr(recipient); c_str @@ -130,44 +49,24 @@ fn send_message_internal( let recipient = r_str.parse().unwrap(); let c_str = unsafe { if message.is_null() { - bail!("message is null"); + return StatusCode::MessageNullError as c_int; } let c_str = CStr::from_ptr(message); c_str }; let message = c_str.to_str().unwrap(); - // send message - RUNTIME.block_on(async move { - nym_client.send_plain_message(recipient, message).await?; - Ok::<(), anyhow::Error>(()) - })?; - Ok(()) + match nym_ffi_shared::send_message_internal(recipient, message) { + Ok(_) => StatusCode::NoError as c_int, + Err(_) => StatusCode::SendMsgError as c_int, + } } #[no_mangle] pub extern "C" fn reply(recipient: *const c_char, message: *const c_char) -> c_int { - match reply_internal(recipient, message) { - Ok(_) => StatusCode::NoError as c_int, - Err(_) => StatusCode::ReplyError as c_int, - } -} - -fn reply_internal( - recipient: *const c_char, - message: *const c_char, -) -> anyhow::Result<(), anyhow::Error> { - let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); - if client.is_none() { - bail!("Client is not yet initialised"); - } - let nym_client = client - .as_ref() - .ok_or_else(|| anyhow!("could not get client as_ref()"))?; - let recipient = unsafe { if recipient.is_null() { - bail!("recipient is null"); + return StatusCode::RecipientNullError as c_int; } let r_str = CStr::from_ptr(recipient).to_string_lossy().into_owned(); AnonymousSenderTag::try_from_base58_string(r_str) @@ -175,64 +74,39 @@ fn reply_internal( }; let message = unsafe { if message.is_null() { - bail!("message is null"); + return StatusCode::MessageNullError as c_int; } let c_str = CStr::from_ptr(message); let r_str = c_str.to_str().unwrap(); r_str }; - RUNTIME.block_on(async move { - nym_client.send_reply(recipient, message).await?; - Ok::<(), anyhow::Error>(()) - })?; - Ok(()) + + match nym_ffi_shared::reply_internal(recipient, message) { + Ok(_) => StatusCode::NoError as c_int, + Err(_) => StatusCode::ReplyError as c_int, + } } #[no_mangle] pub extern "C" fn listen_for_incoming(callback: CMessageCallback) -> c_int { - match listen_for_incoming_internal(callback) { - Ok(_) => StatusCode::NoError as c_int, + match nym_ffi_shared::listen_for_incoming_internal() { + Ok(received) => { + let message_ptr = received.message.as_ptr(); + let message_length = received.message.len(); + let c_string = CString::new(received.sender_tag.unwrap().to_string()).unwrap(); + let sender_ptr = c_string.as_ptr(); + // stop deallocation when out of scope as passing raw ptr to it elsewhere + forget(received); + let rec_for_c = ReceivedMessage { + message: message_ptr, + size: message_length, + sender_tag: sender_ptr, + }; + let call = CMessageCallback::new(callback.callback); + call.trigger(rec_for_c); + + StatusCode::NoError as c_int + } Err(_) => StatusCode::ListenError as c_int, } } - -fn listen_for_incoming_internal(callback: CMessageCallback) -> anyhow::Result<(), anyhow::Error> { - let mut binding = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); - if binding.is_none() { - bail!("recipient is null"); - } - let client = binding - .as_mut() - .ok_or_else(|| anyhow!("could not get client as_ref()"))?; - - RUNTIME.block_on(async move { - let received = wait_for_non_empty_message(client).await?; - let message_ptr = received.message.as_ptr(); - let message_length = received.message.len(); - let c_string = CString::new(received.sender_tag.unwrap().to_string())?; - let sender_ptr = c_string.as_ptr(); - // stop deallocation when out of scope as passing raw ptr to it elsewhere - forget(received); - let rec_for_c = ReceivedMessage { - message: message_ptr, - size: message_length, - sender_tag: sender_ptr, - }; - callback(rec_for_c); - Ok::<(), anyhow::Error>(()) - })?; - Ok(()) -} - -pub async fn wait_for_non_empty_message( - client: &mut MixnetClient, -) -> anyhow::Result<ReconstructedMessage> { - while let Some(mut new_message) = client.wait_for_messages().await { - if !new_message.is_empty() { - return new_message - .pop() - .ok_or_else(|| anyhow!("could not get client as_ref()")); - } - } - bail!("(Rust) did not receive any non-empty message") -} diff --git a/sdk/ffi/cpp/src/main.cpp b/sdk/ffi/cpp/src/main.cpp index 4ece3f2306..175e08d4b8 100644 --- a/sdk/ffi/cpp/src/main.cpp +++ b/sdk/ffi/cpp/src/main.cpp @@ -67,6 +67,7 @@ int main() { // - execute // - get() returned val // - handle val + // initialise an ephemeral client - aka one without specified keystore boost::packaged_task<char> init(boost::bind(init_ephemeral)); boost::unique_future<char> init_future = init.get_future(); init(); @@ -77,7 +78,7 @@ int main() { return_code = get_self_address(string_callback_function); handle(return_code); - // send a message through the mixnet - in this case to ourselves + // send a message through the mixnet - in this case to ourselves using the value from get_self_address std::cout << "(c++) message to send through mixnet: " << message << std::endl; boost::packaged_task<char> send(boost::bind(send_message, addr, message)); boost::unique_future<char> send_future = send.get_future(); @@ -94,16 +95,17 @@ int main() { return_code = listen_future.get(); handle(return_code); - // replying to incoming message (from ourselves) with SURBs- note that sending a message to a recipient and - // replying to an incoming are different functions + // replying to incoming message (from ourselves) with SURBs - note that sending a message to a recipient and + // replying to an incoming are different functions: replying relies on parsing the incoming sender_tag on the Rust + // side and creating an AnonymousSenderTag type, instead of the Recipient type which relies on a nym address boost::packaged_task<char> reply_fn(boost::bind(reply, sender_tag, reply_message)); boost::unique_future<char> reply_future = reply_fn.get_future(); reply_fn(); return_code = reply_future.get(); handle(return_code); - // sleep so that the nym side logging can catch up - in reality you'd have another process running to keep logging - // going, so this is only necessary for this reference implementation + // sleep so that the client processes can catch up - in reality you'd have another process running to keep logging + // going, so this is only necessary for this reference std::this_thread::sleep_for(std::chrono::seconds(40)); return 0; diff --git a/sdk/ffi/cpp/src/types.rs b/sdk/ffi/cpp/src/types.rs new file mode 100644 index 0000000000..745462cf27 --- /dev/null +++ b/sdk/ffi/cpp/src/types.rs @@ -0,0 +1,52 @@ +pub mod types { + + use std::ffi::c_char; + + #[derive(Debug)] + pub enum StatusCode { + NoError = 0, + ClientInitError = -1, + ClientUninitialisedError = -2, + SelfAddrError = -3, + SendMsgError = -4, + ReplyError = -5, + ListenError = -6, + RecipientNullError = -7, + MessageNullError = -8, + } + + #[repr(C)] + pub struct CStringCallback { + pub callback: extern "C" fn(*const c_char), + } + + impl CStringCallback { + pub fn new(callback: extern "C" fn(*const c_char)) -> Self { + CStringCallback { callback } + } + pub fn trigger(&self, char: *const c_char) { + (self.callback)(char); + } + } + + #[repr(C)] + pub struct CMessageCallback { + pub callback: extern "C" fn(ReceivedMessage), + } + + impl CMessageCallback { + pub fn new(callback: extern "C" fn(ReceivedMessage)) -> Self { + CMessageCallback { callback } + } + pub fn trigger(&self, message: ReceivedMessage) { + (self.callback)(message) + } + } + + #[repr(C)] + pub struct ReceivedMessage { + pub message: *const u8, + pub size: usize, + pub sender_tag: *const c_char, + } +} diff --git a/sdk/ffi/go/Cargo.lock b/sdk/ffi/go/Cargo.lock new file mode 100644 index 0000000000..f99f3151d2 --- /dev/null +++ b/sdk/ffi/go/Cargo.lock @@ -0,0 +1,6061 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "ctr 0.8.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive", + "askama_escape", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "basic-toml" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bip32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" +dependencies = [ + "bs58 0.5.0", + "hmac 0.12.1", + "k256", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "bls12_381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54757888b09a69be70b5ec303e382a74227392086ba808cb01eeca29233a2397" +dependencies = [ + "digest 0.9.0", + "ff 0.10.1", + "group 0.10.0", + "pairing 0.20.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "bls12_381" +version = "0.6.0" +source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278" +dependencies = [ + "digest 0.9.0", + "ff 0.11.1", + "group 0.11.0", + "pairing 0.21.0", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + +[[package]] +name = "boringtun" +version = "0.6.0" +source = "git+https://github.com/cloudflare/boringtun?rev=e1d6360d6ab4529fc942a078e4c54df107abe2ba#e1d6360d6ab4529fc942a078e4c54df107abe2ba" +dependencies = [ + "aead", + "base64 0.13.1", + "blake2 0.10.6", + "chacha20poly1305", + "hex", + "hmac 0.12.1", + "ip_network", + "ip_network_table", + "libc", + "nix", + "parking_lot 0.12.1", + "rand_core 0.6.4", + "ring 0.16.20", + "tracing", + "untrusted 0.9.0", + "x25519-dalek 2.0.0", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "bytecodec" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adf4c9d0bbf32eea58d7c0f812058138ee8edaf0f2802b6d03561b504729a325" +dependencies = [ + "byteorder", + "trackable 0.2.24", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.21", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher 0.4.4", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df631ae429f6613fcd3a7c1adbdb65f637271e561b03680adaa6573015dfb106" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_fig" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e571d70e22ec91d34e1c5317c8308035a2280d925167646bf094fc5de1737c" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cosmos-sdk-proto" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto", +] + +[[package]] +name = "cosmrs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" +dependencies = [ + "bip32", + "cosmos-sdk-proto", + "ecdsa", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature 2.2.0", + "subtle-encoding", + "tendermint", + "tendermint-rpc", + "thiserror", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" +dependencies = [ + "digest 0.10.7", + "ecdsa", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40abec852f3d4abec6d44ead9a58b78325021a1ead1e7229c3471414e57b2e49" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +dependencies = [ + "base64 0.13.1", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog 1.1.1", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog 2.4.0", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.7", + "subtle 2.4.1", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "cw-controllers" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-storage-plus" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2", + "schemars", + "semver 1.0.21", + "serde", + "thiserror", +] + +[[package]] +name = "cw2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "schemars", + "serde", +] + +[[package]] +name = "cw3" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.2.0", + "spki", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek 3.2.0", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "ff" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git2" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "goblin" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "byteorder", + "ff 0.10.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "byteorder", + "ff 0.11.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.2.1", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "3.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3" +dependencies = [ + "log", + "pest", + "pest_derive", + "quick-error 2.0.1", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.7", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest 0.9.0", + "hmac 0.11.0", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-api-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpcodec" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f49d64351430cabd543943b79d48aaf0bc95a41d9ccf5b8774c2cfd23422775" +dependencies = [ + "bytecodec", + "trackable 0.2.24", +] + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error 1.2.3", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime 2.1.0", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.10", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433de089bd45971eecf4668ee0ee8f4cec17db4f8bd8f7bc3197a6ce37aa7d9b" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ip_network_table" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" +dependencies = [ + "ip_network", + "ip_network_table-deps-treebitmap", +] + +[[package]] +name = "ip_network_table-deps-treebitmap" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libgit2-sys" +version = "0.13.5+1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037731f5d3aaa87a5675e895b63ddff1a87624bc29f77004ea829809654e48f6" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2 0.8.1", + "chacha", + "keystream", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[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 = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.4", + "libc", +] + +[[package]] +name = "nym-api-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmrs", + "cosmwasm-std", + "getset", + "nym-coconut-interface", + "nym-mixnet-contract-common", + "nym-node-requests", + "schemars", + "serde", +] + +[[package]] +name = "nym-bandwidth-controller" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bip39", + "nym-coconut-interface", + "nym-credential-storage", + "nym-credentials", + "nym-crypto", + "nym-network-defaults", + "nym-validator-client", + "rand 0.7.3", + "thiserror", + "url", +] + +[[package]] +name = "nym-bin-common" +version = "0.6.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "atty", + "clap", + "clap_complete", + "clap_complete_fig", + "log", + "pretty_env_logger", + "schemars", + "semver 0.11.0", + "serde", + "vergen", +] + +[[package]] +name = "nym-client-core" +version = "1.1.15" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "base64 0.21.7", + "cfg-if", + "dashmap", + "dirs 4.0.0", + "futures", + "gloo-timers", + "humantime-serde", + "log", + "nym-bandwidth-controller", + "nym-config", + "nym-credential-storage", + "nym-crypto", + "nym-explorer-client", + "nym-gateway-client", + "nym-gateway-requests", + "nym-network-defaults", + "nym-nonexhaustive-delayqueue", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "reqwest", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx 0.6.3", + "tap", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-utils", + "wasmtimer", + "zeroize", +] + +[[package]] +name = "nym-coconut" +version = "0.5.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bls12_381 0.6.0", + "bs58 0.4.0", + "digest 0.9.0", + "ff 0.11.1", + "getrandom 0.2.12", + "group 0.11.0", + "itertools 0.10.5", + "nym-dkg", + "nym-pemstore", + "rand 0.8.5", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", +] + +[[package]] +name = "nym-coconut-bandwidth-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "nym-multisig-contract-common", +] + +[[package]] +name = "nym-coconut-dkg-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "nym-contracts-common", + "nym-multisig-contract-common", +] + +[[package]] +name = "nym-coconut-interface" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "getset", + "nym-coconut", + "serde", + "thiserror", +] + +[[package]] +name = "nym-config" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "dirs 5.0.1", + "handlebars", + "log", + "nym-network-defaults", + "serde", + "toml 0.7.8", + "url", +] + +[[package]] +name = "nym-contracts-common" +version = "0.5.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmwasm-schema", + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-credential-storage" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "log", + "sqlx 0.5.13", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-credential-utils" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-config", + "nym-credential-storage", + "nym-credentials", + "nym-validator-client", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-credentials" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bls12_381 0.5.0", + "cosmrs", + "log", + "nym-api-requests", + "nym-coconut-interface", + "nym-crypto", + "nym-validator-client", + "thiserror", +] + +[[package]] +name = "nym-crypto" +version = "0.4.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "aes 0.8.3", + "blake3", + "bs58 0.4.0", + "cipher 0.4.4", + "ctr 0.9.2", + "digest 0.10.7", + "ed25519-dalek", + "generic-array 0.14.7", + "hkdf 0.12.4", + "hmac 0.12.1", + "nym-pemstore", + "nym-sphinx-types", + "rand 0.7.3", + "subtle-encoding", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + +[[package]] +name = "nym-dkg" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bitvec", + "bls12_381 0.6.0", + "bs58 0.4.0", + "ff 0.11.1", + "group 0.11.0", + "lazy_static", + "nym-pemstore", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-ephemera-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "nym-contracts-common", +] + +[[package]] +name = "nym-exit-policy" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-api-requests", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "nym-explorer-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-explorer-api-requests", + "reqwest", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "nym-ffi-shared" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "lazy_static", + "nym-bin-common", + "nym-sdk", + "nym-sphinx-anonymous-replies", + "tokio", + "uniffi", + "uniffi_build", +] + +[[package]] +name = "nym-gateway-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "getrandom 0.2.12", + "gloo-utils", + "log", + "nym-bandwidth-controller", + "nym-coconut-interface", + "nym-credential-storage", + "nym-crypto", + "nym-gateway-requests", + "nym-network-defaults", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-validator-client", + "rand 0.7.3", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-utils", + "wasmtimer", +] + +[[package]] +name = "nym-gateway-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "futures", + "generic-array 0.14.7", + "log", + "nym-coconut-interface", + "nym-credentials", + "nym-crypto", + "nym-pemstore", + "nym-sphinx", + "rand 0.7.3", + "serde", + "serde_json", + "thiserror", + "tungstenite", + "zeroize", +] + +[[package]] +name = "nym-go-ffi" +version = "0.1.0" +dependencies = [ + "anyhow", + "lazy_static", + "nym-bin-common", + "nym-ffi-shared", + "nym-sdk", + "nym-sphinx-anonymous-replies", + "thiserror", + "tokio", + "uniffi", + "uniffi_build", +] + +[[package]] +name = "nym-group-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cw-controllers", + "cw4", + "schemars", + "serde", +] + +[[package]] +name = "nym-mixnet-contract-common" +version = "0.6.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmwasm-schema", + "cosmwasm-std", + "humantime-serde", + "log", + "nym-contracts-common", + "schemars", + "serde", + "serde-json-wasm", + "serde_repr", + "thiserror", + "time", +] + +[[package]] +name = "nym-multisig-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "cw3", + "cw4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-name-service-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "serde", + "thiserror", +] + +[[package]] +name = "nym-network-defaults" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cfg-if", + "dotenvy", + "hex-literal", + "once_cell", + "schemars", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "nym-node-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "base64 0.21.7", + "nym-bin-common", + "nym-crypto", + "nym-exit-policy", + "nym-wireguard-types", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-nonexhaustive-delayqueue" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "tokio", + "tokio-stream", + "tokio-util", + "wasmtimer", +] + +[[package]] +name = "nym-ordered-buffer" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "thiserror", +] + +[[package]] +name = "nym-outfox" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "blake3", + "chacha20", + "chacha20poly1305", + "curve25519-dalek 3.2.0", + "getrandom 0.2.12", + "log", + "rand 0.7.3", + "rayon", + "sphinx-packet", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-pemstore" +version = "0.3.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "pem", +] + +[[package]] +name = "nym-sdk" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "bip39", + "bytecodec", + "bytes", + "futures", + "http", + "httpcodec", + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-credential-storage", + "nym-credential-utils", + "nym-credentials", + "nym-crypto", + "nym-gateway-requests", + "nym-network-defaults", + "nym-ordered-buffer", + "nym-service-providers-common", + "nym-socks5-client-core", + "nym-socks5-requests", + "nym-sphinx", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "tap", + "thiserror", + "toml 0.5.11", + "url", +] + +[[package]] +name = "nym-service-provider-directory-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "thiserror", +] + +[[package]] +name = "nym-service-providers-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "log", + "nym-bin-common", + "nym-sphinx-anonymous-replies", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-socks5-client-core" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "anyhow", + "dirs 4.0.0", + "futures", + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-config", + "nym-contracts-common", + "nym-credential-storage", + "nym-mixnet-contract-common", + "nym-network-defaults", + "nym-service-providers-common", + "nym-socks5-proxy-helpers", + "nym-socks5-requests", + "nym-sphinx", + "nym-task", + "nym-validator-client", + "pin-project", + "rand 0.7.3", + "reqwest", + "schemars", + "serde", + "tap", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "nym-socks5-proxy-helpers" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bytes", + "futures", + "log", + "nym-ordered-buffer", + "nym-socks5-requests", + "nym-task", + "tokio", + "tokio-util", +] + +[[package]] +name = "nym-socks5-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bincode", + "log", + "nym-exit-policy", + "nym-service-providers-common", + "nym-sphinx-addressing", + "serde", + "serde_json", + "tap", + "thiserror", +] + +[[package]] +name = "nym-sphinx" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-anonymous-replies", + "nym-sphinx-chunking", + "nym-sphinx-cover", + "nym-sphinx-forwarding", + "nym-sphinx-framing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "rand_distr", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-sphinx-acknowledgements" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-sphinx-addressing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-anonymous-replies" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "nym-crypto", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "serde", + "thiserror", + "wasm-bindgen", +] + +[[package]] +name = "nym-sphinx-chunking" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-cover" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-chunking", + "nym-sphinx-forwarding", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-forwarding" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-outfox", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-framing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bytes", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", + "tokio-util", +] + +[[package]] +name = "nym-sphinx-params" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-routing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-sphinx-addressing", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-types" +version = "0.2.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-outfox", + "sphinx-packet", + "thiserror", +] + +[[package]] +name = "nym-task" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "log", + "thiserror", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasmtimer", +] + +[[package]] +name = "nym-topology" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "bs58 0.4.0", + "log", + "nym-api-requests", + "nym-bin-common", + "nym-config", + "nym-crypto", + "nym-mixnet-contract-common", + "nym-sphinx-addressing", + "nym-sphinx-routing", + "nym-sphinx-types", + "rand 0.7.3", + "semver 0.11.0", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-validator-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bip32", + "bip39", + "colored", + "cosmrs", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "cw2", + "cw3", + "cw4", + "eyre", + "flate2", + "futures", + "http-api-client", + "itertools 0.10.5", + "log", + "nym-api-requests", + "nym-coconut-bandwidth-contract-common", + "nym-coconut-dkg-common", + "nym-coconut-interface", + "nym-config", + "nym-contracts-common", + "nym-ephemera-common", + "nym-group-contract-common", + "nym-mixnet-contract-common", + "nym-multisig-contract-common", + "nym-name-service-common", + "nym-network-defaults", + "nym-service-provider-directory-common", + "nym-vesting-contract-common", + "openssl", + "prost", + "reqwest", + "serde", + "serde_json", + "sha2 0.9.9", + "tendermint-rpc", + "thiserror", + "tokio", + "url", + "wasmtimer", + "zeroize", +] + +[[package]] +name = "nym-vesting-contract-common" +version = "0.7.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "nym-contracts-common", + "nym-mixnet-contract-common", + "serde", + "thiserror", +] + +[[package]] +name = "nym-wireguard-types" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "base64 0.21.7", + "boringtun", + "bytes", + "dashmap", + "ip_network", + "ip_network_table", + "log", + "nym-crypto", + "serde", + "thiserror", + "tokio", + "x25519-dalek 2.0.0", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oneshot-uniffi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15c9d69dd87a29568d4d017cfe8ec518706046a05184e5aea92d0af890b803c8" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.1+3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22e1bf214306098e4832460f797824c05d25aacdf896f64a985fb0fd992454ae" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pairing" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de9d09263c9966e8196fe0380c9dbbc7ea114b5cf371ba29004bc1f9c6db7f3" +dependencies = [ + "group 0.10.0", +] + +[[package]] +name = "pairing" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42" +dependencies = [ + "group 0.11.0", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac 0.12.1", +] + +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + +[[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64 0.13.1", + "once_cell", + "regex", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "pin-project" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0302c4a0442c456bd56f841aee5c3bfd17967563f6fadc9ceb9f9c23cf3807e0" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "266c042b60c9c76b8d53061e52b2e0d1116abc57cefc8c5cd671619a56ac3690" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.78" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand 0.7.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.10", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.21", +] + +[[package]] +name = "rustix" +version = "0.38.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring 0.16.20", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct 0.7.1", + "webpki 0.22.4", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki", + "sct 0.7.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.196" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.113" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "sphinx-packet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" +dependencies = [ + "aes 0.7.5", + "arrayref", + "blake2 0.8.1", + "bs58 0.4.0", + "byteorder", + "chacha", + "curve25519-dalek 3.2.0", + "digest 0.9.0", + "hkdf 0.11.0", + "hmac 0.11.0", + "lioness", + "log", + "rand 0.7.3", + "rand_distr", + "sha2 0.9.9", + "subtle 2.4.1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools 0.10.5", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.1", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core 0.5.13", + "sqlx-macros 0.5.13", +] + +[[package]] +name = "sqlx" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +dependencies = [ + "sqlx-core 0.6.3", + "sqlx-macros 0.6.3", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash 0.7.7", + "atoi 0.4.0", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc 2.1.0", + "crossbeam-queue", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.7.0", + "hex", + "indexmap 1.9.3", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.19.1", + "sha2 0.10.8", + "smallvec", + "sqlformat 0.1.8", + "sqlx-rt 0.5.13", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki 0.21.4", + "webpki-roots 0.21.1", +] + +[[package]] +name = "sqlx-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +dependencies = [ + "ahash 0.7.7", + "atoi 1.0.0", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc 3.0.1", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.8.4", + "hex", + "indexmap 1.9.3", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.20.9", + "rustls-pemfile", + "sha2 0.10.8", + "smallvec", + "sqlformat 0.2.3", + "sqlx-rt 0.6.3", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots 0.22.6", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.8", + "sqlx-core 0.5.13", + "sqlx-rt 0.5.13", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.8", + "sqlx-core 0.6.3", + "sqlx-rt 0.6.3", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.22.0", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tendermint" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519 2.2.3", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost", + "prost-types", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature 2.2.0", + "subtle 2.4.1", + "subtle-encoding", + "tendermint-proto", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint", + "toml 0.5.11", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-rpc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom 0.2.12", + "peg", + "pin-project", + "reqwest", + "semver 1.0.21", + "serde", + "serde_bytes", + "serde_json", + "subtle 2.4.1", + "subtle-encoding", + "tendermint", + "tendermint-config", + "tendermint-proto", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa", + "js-sys", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki 0.22.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.10", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.2.1", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trackable" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98abb9e7300b9ac902cc04920945a874c1973e08c310627cc4458c04b70dd32" +dependencies = [ + "trackable 1.3.0", + "trackable_derive", +] + +[[package]] +name = "trackable" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15bd114abb99ef8cee977e517c8f37aee63f184f2d08e3e6ceca092373369ae" +dependencies = [ + "trackable_derive", +] + +[[package]] +name = "trackable_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebeb235c5847e2f82cfe0f07eb971d1e5f6804b18dac2ae16349cc604380f82f" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "uniffi" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" +dependencies = [ + "anyhow", + "camino", + "clap", + "uniffi_bindgen", + "uniffi_build", + "uniffi_core", + "uniffi_macros", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "clap", + "fs-err", + "glob", + "goblin", + "heck", + "once_cell", + "paste", + "serde", + "toml 0.5.11", + "uniffi_meta", + "uniffi_testing", + "uniffi_udl", +] + +[[package]] +name = "uniffi_build" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "uniffi_core" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b" +dependencies = [ + "anyhow", + "bytes", + "camino", + "log", + "once_cell", + "oneshot-uniffi", + "paste", + "static_assertions", +] + +[[package]] +name = "uniffi_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4" +dependencies = [ + "bincode", + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", + "toml 0.5.11", + "uniffi_build", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3" +dependencies = [ + "anyhow", + "uniffi_meta", + "uniffi_testing", + "weedle2", +] + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vergen" +version = "7.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37" +dependencies = [ + "anyhow", + "cfg-if", + "enum-iterator", + "getset", + "git2", + "rustc_version", + "rustversion", + "thiserror", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "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 = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "wasm-utils" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "getrandom 0.2.12", + "gloo-net", + "gloo-utils", + "js-sys", + "tungstenite", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "slab", + "wasm-bindgen", +] + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki 0.22.4", +] + +[[package]] +name = "weedle2" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" +dependencies = [ + "nom", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1931d78a9c73861da0134f453bb1f790ce49b2e30eba8410b4b79bac72b46a2d" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +dependencies = [ + "curve25519-dalek 4.1.1", + "rand_core 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/sdk/ffi/go/Cargo.toml b/sdk/ffi/go/Cargo.toml new file mode 100644 index 0000000000..97d7125589 --- /dev/null +++ b/sdk/ffi/go/Cargo.toml @@ -0,0 +1,31 @@ +[package] +name = "nym-go-ffi" #"goffitest" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +name = "nym_go_ffi" #"go_ffi" + +[dependencies] +# Bindgen +uniffi = { version = "0.25.2", features = ["cli"] } +# Nym clients, addressing, packet format, common tools (logging), ffi shared +nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" } +nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" } +nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" } +nym-ffi-shared = { path = "../shared" } +# Async runtime +tokio = { version = "1", features = ["full"] } +lazy_static = "1.4.0" +# error handling +anyhow = "1.0.79" +thiserror = "1.0.56" + +[build-dependencies] +uniffi = { version = "0.25.2", features = ["build" ] } +uniffi_build = { version = "0.25.2", features=["builtin-bindgen"] } + +[[bin]] +name = "uniffi-bindgen" +path = "uniffi-bindgen.rs" diff --git a/sdk/ffi/go/README.md b/sdk/ffi/go/README.md new file mode 100644 index 0000000000..fd4ebd5926 --- /dev/null +++ b/sdk/ffi/go/README.md @@ -0,0 +1,47 @@ +# Go FFI +> ⚠️ This is an initial version of this library in order to give developers something to experiment with. If you use this code to begin testing out Mixnet integration and run into issues, errors, or have feedback, please feel free to open an issue; feedback from developers trying to use it will help us improve it. If you have questions feel free to reach out via our [Matrix channel](https://matrix.to/#/#dev:nymtech.chat). + +This repo contains: +* `lib.rs`: an initial version of bindings for interacting with the Mixnet via the Rust SDK from Go. These are essentially match statemtns wrapping imported functions from the `nym-ffi-shared` lib. +* `ffi/`: a directory containing: + * the `bindings/` files generated using [`uniffi-bindgen-go`](https://github.com/NordSecurity/uniffi-bindgen-go) + * [`example.go`](./example.go): an example of using this library. + +The `example.go` file is an example flow of: +* setting up Nym client logging +* creating an ephemeral Nym client (no key storage / persistent address - this will come in a future iteration) +* getting its [Nym address](https://nymtech.net/docs/clients/addressing-system.html) +* using that address to send a message to yourself via the Mixnet +* listen for and parse the incoming message for the `sender_tag` used for [anonymous replies with SURBs](https://nymtech.net/docs/architecture/traffic-flow.html#private-replies-using-surbs) +* send a reply to yourself using SURBs + +## Useage - Consuming the Library +You can import the bindings as normal and interact with them as shown in the [example file](./example.go). This example imports the bindings from the this repository (hence the `go.mod` and `go.sum` in the crate root) but you can import them remotely as usual. + +## Useage - Developing on the Library +If you want to fork and add new features/functions to this library use the following instructions to rebuild the Go bindings. + +Rust functions exposed to the Go binding library are in `./src/lib.rs`. + +The `build.sh` script in the root of the repository speeds up the task of building and linking the Rust and Go code. +* if want to quickly recompile your code run it as-is with `./build.sh` +* if you want to clean build both the Rust and Go code after removing existing compiled binaries run it with the optional `clean` argument: `./build.sh clean`. + +> Make sure to run the script from the root of the project directory, and that your LD PATH is set first! +> ``` +> RUST_BINARIES=target/release +> echo 'export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:'${RUST_BINARIES} >> ~/.zshrc +> source ~/.zshrc +> ``` + +This script will: +* (optionally if called with `clean` argument) remove existing Rust and Go artifacts +* build `lib.rs` with the `--release` flag +* compile the Go bindings + +**WIP** you need to manually add the following `cgo` flags to the generated bindings immediately underneath LN3 (`// #include <bindings.h`). In the future this will be automated in `build.sh`: + +``` +// #cgo LDFLAGS: -L../../target/release -lnym_go_ffi +``` + diff --git a/sdk/ffi/go/build.rs b/sdk/ffi/go/build.rs new file mode 100644 index 0000000000..2508803c60 --- /dev/null +++ b/sdk/ffi/go/build.rs @@ -0,0 +1,4 @@ +fn main() { + uniffi::generate_scaffolding("src/bindings.udl").unwrap(); +} + diff --git a/sdk/ffi/go/build.sh b/sdk/ffi/go/build.sh new file mode 100755 index 0000000000..5b19b083d0 --- /dev/null +++ b/sdk/ffi/go/build.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +PROJECT_NAME="go" + +set -eu +MODE="--release" + +GO_DIR="./go-nym" +UDL_PATH="./src/bindings.udl" + +build_artifacts() { + # build rust + cargo build $MODE + # build go bindings + printf "building go bindings \n" + uniffi-bindgen-go $UDL_PATH --out-dir $GO_DIR + printf "bindings built \n\n" + + # something not right with these - having to add it manually to bindings.go for the moment + # pushd $GO_DIR/bindings + # echo $(pwd) + # LD_LIBRARY_PATH="${LD_LIBRARY_PATH:-}:../../target/release" \ + # CGO_LDFLAGS="-L../target/release -lnym_go_ffi -lm -ldl" \ + # CGO_ENABLED=1 \ + # go run ../main.go +} + +clean_artifacts() { + # clean up existing things + rm -rf $GO_DIR + cargo clean +} + + +if [ $(pwd | awk -F/ '{print $NF}') != ${PROJECT_NAME} ] +then + printf "please run from root dir of project" + exit 1 +fi + +if [ $# -eq 0 ]; +then + build_artifacts; +else + arg=$1 + if [ "$arg" == "clean" ]; then + clean_artifacts; + build_artifacts; + else + printf "unknown optional argument - the only available optional argument is 'clean'" + exit 1 + fi +fi diff --git a/sdk/ffi/go/example.go b/sdk/ffi/go/example.go new file mode 100644 index 0000000000..5cedb99706 --- /dev/null +++ b/sdk/ffi/go/example.go @@ -0,0 +1,74 @@ +package main + +import ( + "fmt" + "nymffi/go-nym/bindings" + "time" +) + +func main() { + + // initialise Nym client logging - this is quite verbose but very informative + bindings.InitLogging() + + // initialise an ephemeral client - aka one without specified keystore + err := bindings.InitEphemeral() + if err != nil { + fmt.Println(err) + return + } + + // get our client's address + str, err2 := bindings.GetSelfAddress() + if err2 != nil { + fmt.Println("(Go) Error:", err2) + return + } + fmt.Println("(Go) response:") + fmt.Println(str) + + // send a message through the mixnet - in this case to ourselves using the value from GetSelfAddress + err3 := bindings.SendMessage(str, "helloworld") + if err3 != nil { + fmt.Println("(Go) Error:", err3) + return + } + + // listen out for incoming messages: in the future the client can be split into a listening and a sending client, + // allowing for this to run as a persistent process in its own thread and not have to block but instead be running + // concurrently + // + // assuming a data type like so: + // type IncomingMessage struct { + // Message string + // SenderTag vec<u8> + // } + incomingMessage, err4 := bindings.ListenForIncoming() + if err4 != nil { + fmt.Println("(Go) Error:", err4) + return + } + fmt.Println("(Go) incoming message: ", incomingMessage.Message, " from: ", incomingMessage.Sender) + + // we can just use the byte array we parsed from the incoming message to reply with: this is a + // byte representation of the sender_tag used for Single Use Reply Blocks (SURBs) + // + // replying to incoming message (from ourselves) with SURBs - note that sending a message to a recipient and + // replying to an incoming are different functions: replying relies on parsing the incoming sender_tag on the Rust + // side and creating an AnonymousSenderTag type, instead of the Recipient type which relies on a nym address + // + // you will see in the client logs that there are requests for more SURBs that we send to ourselves to + // be able to fit the full reply message in there. In a future iteration of this code we can also expose + // a send() which allows for developers to dictate the number of SURBs to send along with their outgoing message + fmt.Println("(Go) replying to received message") + err5 := bindings.Reply(incomingMessage.Sender, "replyworld") + if err5 != nil { + fmt.Println("(Go) Error:", err5) + return + } + + // sleep so that the nym client processes can catch up - in reality you'd have another process + // running to keep logging going, so this is only necessary for this reference + time.Sleep(30 * time.Second) + fmt.Println("(Go) end go example") +} diff --git a/sdk/ffi/go/go-nym/bindings/bindings.c b/sdk/ffi/go/go-nym/bindings/bindings.c new file mode 100644 index 0000000000..a2a2b404c3 --- /dev/null +++ b/sdk/ffi/go/go-nym/bindings/bindings.c @@ -0,0 +1,8 @@ +#include <bindings.h> + +// This file exists beacause of +// https://github.com/golang/go/issues/11263 + +void cgo_rust_task_callback_bridge_bindings(RustTaskCallback cb, const void * taskData, int8_t status) { + cb(taskData, status); +} \ No newline at end of file diff --git a/sdk/ffi/go/go-nym/bindings/bindings.go b/sdk/ffi/go/go-nym/bindings/bindings.go new file mode 100644 index 0000000000..07fff0f99f --- /dev/null +++ b/sdk/ffi/go/go-nym/bindings/bindings.go @@ -0,0 +1,773 @@ +package bindings + +// #include <bindings.h> +// #cgo LDFLAGS: -L../../target/release -lnym_go_ffi +import "C" + +import ( + "bytes" + "encoding/binary" + "fmt" + "io" + "math" + "unsafe" +) + +type RustBuffer = C.RustBuffer + +type RustBufferI interface { + AsReader() *bytes.Reader + Free() + ToGoBytes() []byte + Data() unsafe.Pointer + Len() int + Capacity() int +} + +func RustBufferFromExternal(b RustBufferI) RustBuffer { + return RustBuffer{ + capacity: C.int(b.Capacity()), + len: C.int(b.Len()), + data: (*C.uchar)(b.Data()), + } +} + +func (cb RustBuffer) Capacity() int { + return int(cb.capacity) +} + +func (cb RustBuffer) Len() int { + return int(cb.len) +} + +func (cb RustBuffer) Data() unsafe.Pointer { + return unsafe.Pointer(cb.data) +} + +func (cb RustBuffer) AsReader() *bytes.Reader { + b := unsafe.Slice((*byte)(cb.data), C.int(cb.len)) + return bytes.NewReader(b) +} + +func (cb RustBuffer) Free() { + rustCall(func(status *C.RustCallStatus) bool { + C.ffi_nym_go_ffi_rustbuffer_free(cb, status) + return false + }) +} + +func (cb RustBuffer) ToGoBytes() []byte { + return C.GoBytes(unsafe.Pointer(cb.data), C.int(cb.len)) +} + +func stringToRustBuffer(str string) RustBuffer { + return bytesToRustBuffer([]byte(str)) +} + +func bytesToRustBuffer(b []byte) RustBuffer { + if len(b) == 0 { + return RustBuffer{} + } + // We can pass the pointer along here, as it is pinned + // for the duration of this call + foreign := C.ForeignBytes{ + len: C.int(len(b)), + data: (*C.uchar)(unsafe.Pointer(&b[0])), + } + + return rustCall(func(status *C.RustCallStatus) RustBuffer { + return C.ffi_nym_go_ffi_rustbuffer_from_bytes(foreign, status) + }) +} + +type BufLifter[GoType any] interface { + Lift(value RustBufferI) GoType +} + +type BufLowerer[GoType any] interface { + Lower(value GoType) RustBuffer +} + +type FfiConverter[GoType any, FfiType any] interface { + Lift(value FfiType) GoType + Lower(value GoType) FfiType +} + +type BufReader[GoType any] interface { + Read(reader io.Reader) GoType +} + +type BufWriter[GoType any] interface { + Write(writer io.Writer, value GoType) +} + +type FfiRustBufConverter[GoType any, FfiType any] interface { + FfiConverter[GoType, FfiType] + BufReader[GoType] +} + +func LowerIntoRustBuffer[GoType any](bufWriter BufWriter[GoType], value GoType) RustBuffer { + // This might be not the most efficient way but it does not require knowing allocation size + // beforehand + var buffer bytes.Buffer + bufWriter.Write(&buffer, value) + + bytes, err := io.ReadAll(&buffer) + if err != nil { + panic(fmt.Errorf("reading written data: %w", err)) + } + return bytesToRustBuffer(bytes) +} + +func LiftFromRustBuffer[GoType any](bufReader BufReader[GoType], rbuf RustBufferI) GoType { + defer rbuf.Free() + reader := rbuf.AsReader() + item := bufReader.Read(reader) + if reader.Len() > 0 { + // TODO: Remove this + leftover, _ := io.ReadAll(reader) + panic(fmt.Errorf("Junk remaining in buffer after lifting: %s", string(leftover))) + } + return item +} + +func rustCallWithError[U any](converter BufLifter[error], callback func(*C.RustCallStatus) U) (U, error) { + var status C.RustCallStatus + returnValue := callback(&status) + err := checkCallStatus(converter, status) + + return returnValue, err +} + +func checkCallStatus(converter BufLifter[error], status C.RustCallStatus) error { + switch status.code { + case 0: + return nil + case 1: + return converter.Lift(status.errorBuf) + case 2: + // when the rust code sees a panic, it tries to construct a rustbuffer + // with the message. but if that code panics, then it just sends back + // an empty buffer. + if status.errorBuf.len > 0 { + panic(fmt.Errorf("%s", FfiConverterStringINSTANCE.Lift(status.errorBuf))) + } else { + panic(fmt.Errorf("Rust panicked while handling Rust panic")) + } + default: + return fmt.Errorf("unknown status code: %d", status.code) + } +} + +func checkCallStatusUnknown(status C.RustCallStatus) error { + switch status.code { + case 0: + return nil + case 1: + panic(fmt.Errorf("function not returning an error returned an error")) + case 2: + // when the rust code sees a panic, it tries to construct a rustbuffer + // with the message. but if that code panics, then it just sends back + // an empty buffer. + if status.errorBuf.len > 0 { + panic(fmt.Errorf("%s", FfiConverterStringINSTANCE.Lift(status.errorBuf))) + } else { + panic(fmt.Errorf("Rust panicked while handling Rust panic")) + } + default: + return fmt.Errorf("unknown status code: %d", status.code) + } +} + +func rustCall[U any](callback func(*C.RustCallStatus) U) U { + returnValue, err := rustCallWithError(nil, callback) + if err != nil { + panic(err) + } + return returnValue +} + +func writeInt8(writer io.Writer, value int8) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint8(writer io.Writer, value uint8) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt16(writer io.Writer, value int16) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint16(writer io.Writer, value uint16) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt32(writer io.Writer, value int32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint32(writer io.Writer, value uint32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeInt64(writer io.Writer, value int64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeUint64(writer io.Writer, value uint64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeFloat32(writer io.Writer, value float32) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func writeFloat64(writer io.Writer, value float64) { + if err := binary.Write(writer, binary.BigEndian, value); err != nil { + panic(err) + } +} + +func readInt8(reader io.Reader) int8 { + var result int8 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint8(reader io.Reader) uint8 { + var result uint8 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt16(reader io.Reader) int16 { + var result int16 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint16(reader io.Reader) uint16 { + var result uint16 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt32(reader io.Reader) int32 { + var result int32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint32(reader io.Reader) uint32 { + var result uint32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readInt64(reader io.Reader) int64 { + var result int64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readUint64(reader io.Reader) uint64 { + var result uint64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readFloat32(reader io.Reader) float32 { + var result float32 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func readFloat64(reader io.Reader) float64 { + var result float64 + if err := binary.Read(reader, binary.BigEndian, &result); err != nil { + panic(err) + } + return result +} + +func init() { + + uniffiCheckChecksums() +} + +func uniffiCheckChecksums() { + // Get the bindings contract version from our ComponentInterface + bindingsContractVersion := 24 + // Get the scaffolding contract version by calling the into the dylib + scaffoldingContractVersion := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint32_t { + return C.ffi_nym_go_ffi_uniffi_contract_version(uniffiStatus) + }) + if bindingsContractVersion != int(scaffoldingContractVersion) { + // If this happens try cleaning and rebuilding your project + panic("bindings: UniFFI contract version mismatch") + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_get_self_address(uniffiStatus) + }) + if checksum != 51546 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_get_self_address: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_init_ephemeral(uniffiStatus) + }) + if checksum != 28391 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_init_ephemeral: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_init_logging(uniffiStatus) + }) + if checksum != 1547 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_init_logging: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_listen_for_incoming(uniffiStatus) + }) + if checksum != 52894 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_listen_for_incoming: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_reply(uniffiStatus) + }) + if checksum != 50524 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_reply: UniFFI API checksum mismatch") + } + } + { + checksum := rustCall(func(uniffiStatus *C.RustCallStatus) C.uint16_t { + return C.uniffi_nym_go_ffi_checksum_func_send_message(uniffiStatus) + }) + if checksum != 33425 { + // If this happens try cleaning and rebuilding your project + panic("bindings: uniffi_nym_go_ffi_checksum_func_send_message: UniFFI API checksum mismatch") + } + } +} + +type FfiConverterString struct{} + +var FfiConverterStringINSTANCE = FfiConverterString{} + +func (FfiConverterString) Lift(rb RustBufferI) string { + defer rb.Free() + reader := rb.AsReader() + b, err := io.ReadAll(reader) + if err != nil { + panic(fmt.Errorf("reading reader: %w", err)) + } + return string(b) +} + +func (FfiConverterString) Read(reader io.Reader) string { + length := readInt32(reader) + buffer := make([]byte, length) + read_length, err := reader.Read(buffer) + if err != nil { + panic(err) + } + if read_length != int(length) { + panic(fmt.Errorf("bad read length when reading string, expected %d, read %d", length, read_length)) + } + return string(buffer) +} + +func (FfiConverterString) Lower(value string) RustBuffer { + return stringToRustBuffer(value) +} + +func (FfiConverterString) Write(writer io.Writer, value string) { + if len(value) > math.MaxInt32 { + panic("String is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + write_length, err := io.WriteString(writer, value) + if err != nil { + panic(err) + } + if write_length != len(value) { + panic(fmt.Errorf("bad write length when writing string, expected %d, written %d", len(value), write_length)) + } +} + +type FfiDestroyerString struct{} + +func (FfiDestroyerString) Destroy(_ string) {} + +type FfiConverterBytes struct{} + +var FfiConverterBytesINSTANCE = FfiConverterBytes{} + +func (c FfiConverterBytes) Lower(value []byte) RustBuffer { + return LowerIntoRustBuffer[[]byte](c, value) +} + +func (c FfiConverterBytes) Write(writer io.Writer, value []byte) { + if len(value) > math.MaxInt32 { + panic("[]byte is too large to fit into Int32") + } + + writeInt32(writer, int32(len(value))) + write_length, err := writer.Write(value) + if err != nil { + panic(err) + } + if write_length != len(value) { + panic(fmt.Errorf("bad write length when writing []byte, expected %d, written %d", len(value), write_length)) + } +} + +func (c FfiConverterBytes) Lift(rb RustBufferI) []byte { + return LiftFromRustBuffer[[]byte](c, rb) +} + +func (c FfiConverterBytes) Read(reader io.Reader) []byte { + length := readInt32(reader) + buffer := make([]byte, length) + read_length, err := reader.Read(buffer) + if err != nil { + panic(err) + } + if read_length != int(length) { + panic(fmt.Errorf("bad read length when reading []byte, expected %d, read %d", length, read_length)) + } + return buffer +} + +type FfiDestroyerBytes struct{} + +func (FfiDestroyerBytes) Destroy(_ []byte) {} + +type IncomingMessage struct { + Message string + Sender []byte +} + +func (r *IncomingMessage) Destroy() { + FfiDestroyerString{}.Destroy(r.Message) + FfiDestroyerBytes{}.Destroy(r.Sender) +} + +type FfiConverterTypeIncomingMessage struct{} + +var FfiConverterTypeIncomingMessageINSTANCE = FfiConverterTypeIncomingMessage{} + +func (c FfiConverterTypeIncomingMessage) Lift(rb RustBufferI) IncomingMessage { + return LiftFromRustBuffer[IncomingMessage](c, rb) +} + +func (c FfiConverterTypeIncomingMessage) Read(reader io.Reader) IncomingMessage { + return IncomingMessage{ + FfiConverterStringINSTANCE.Read(reader), + FfiConverterBytesINSTANCE.Read(reader), + } +} + +func (c FfiConverterTypeIncomingMessage) Lower(value IncomingMessage) RustBuffer { + return LowerIntoRustBuffer[IncomingMessage](c, value) +} + +func (c FfiConverterTypeIncomingMessage) Write(writer io.Writer, value IncomingMessage) { + FfiConverterStringINSTANCE.Write(writer, value.Message) + FfiConverterBytesINSTANCE.Write(writer, value.Sender) +} + +type FfiDestroyerTypeIncomingMessage struct{} + +func (_ FfiDestroyerTypeIncomingMessage) Destroy(value IncomingMessage) { + value.Destroy() +} + +type GoWrapError struct { + err error +} + +func (err GoWrapError) Error() string { + return fmt.Sprintf("GoWrapError: %s", err.err.Error()) +} + +func (err GoWrapError) Unwrap() error { + return err.err +} + +// Err* are used for checking error type with `errors.Is` +var ErrGoWrapErrorClientInitError = fmt.Errorf("GoWrapErrorClientInitError") +var ErrGoWrapErrorClientUninitialisedError = fmt.Errorf("GoWrapErrorClientUninitialisedError") +var ErrGoWrapErrorSelfAddrError = fmt.Errorf("GoWrapErrorSelfAddrError") +var ErrGoWrapErrorSendMsgError = fmt.Errorf("GoWrapErrorSendMsgError") +var ErrGoWrapErrorReplyError = fmt.Errorf("GoWrapErrorReplyError") +var ErrGoWrapErrorListenError = fmt.Errorf("GoWrapErrorListenError") + +// Variant structs +type GoWrapErrorClientInitError struct { + message string +} + +func NewGoWrapErrorClientInitError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorClientInitError{}, + } +} + +func (err GoWrapErrorClientInitError) Error() string { + return fmt.Sprintf("ClientInitError: %s", err.message) +} + +func (self GoWrapErrorClientInitError) Is(target error) bool { + return target == ErrGoWrapErrorClientInitError +} + +type GoWrapErrorClientUninitialisedError struct { + message string +} + +func NewGoWrapErrorClientUninitialisedError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorClientUninitialisedError{}, + } +} + +func (err GoWrapErrorClientUninitialisedError) Error() string { + return fmt.Sprintf("ClientUninitialisedError: %s", err.message) +} + +func (self GoWrapErrorClientUninitialisedError) Is(target error) bool { + return target == ErrGoWrapErrorClientUninitialisedError +} + +type GoWrapErrorSelfAddrError struct { + message string +} + +func NewGoWrapErrorSelfAddrError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorSelfAddrError{}, + } +} + +func (err GoWrapErrorSelfAddrError) Error() string { + return fmt.Sprintf("SelfAddrError: %s", err.message) +} + +func (self GoWrapErrorSelfAddrError) Is(target error) bool { + return target == ErrGoWrapErrorSelfAddrError +} + +type GoWrapErrorSendMsgError struct { + message string +} + +func NewGoWrapErrorSendMsgError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorSendMsgError{}, + } +} + +func (err GoWrapErrorSendMsgError) Error() string { + return fmt.Sprintf("SendMsgError: %s", err.message) +} + +func (self GoWrapErrorSendMsgError) Is(target error) bool { + return target == ErrGoWrapErrorSendMsgError +} + +type GoWrapErrorReplyError struct { + message string +} + +func NewGoWrapErrorReplyError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorReplyError{}, + } +} + +func (err GoWrapErrorReplyError) Error() string { + return fmt.Sprintf("ReplyError: %s", err.message) +} + +func (self GoWrapErrorReplyError) Is(target error) bool { + return target == ErrGoWrapErrorReplyError +} + +type GoWrapErrorListenError struct { + message string +} + +func NewGoWrapErrorListenError() *GoWrapError { + return &GoWrapError{ + err: &GoWrapErrorListenError{}, + } +} + +func (err GoWrapErrorListenError) Error() string { + return fmt.Sprintf("ListenError: %s", err.message) +} + +func (self GoWrapErrorListenError) Is(target error) bool { + return target == ErrGoWrapErrorListenError +} + +type FfiConverterTypeGoWrapError struct{} + +var FfiConverterTypeGoWrapErrorINSTANCE = FfiConverterTypeGoWrapError{} + +func (c FfiConverterTypeGoWrapError) Lift(eb RustBufferI) error { + return LiftFromRustBuffer[error](c, eb) +} + +func (c FfiConverterTypeGoWrapError) Lower(value *GoWrapError) RustBuffer { + return LowerIntoRustBuffer[*GoWrapError](c, value) +} + +func (c FfiConverterTypeGoWrapError) Read(reader io.Reader) error { + errorID := readUint32(reader) + + message := FfiConverterStringINSTANCE.Read(reader) + switch errorID { + case 1: + return &GoWrapError{&GoWrapErrorClientInitError{message}} + case 2: + return &GoWrapError{&GoWrapErrorClientUninitialisedError{message}} + case 3: + return &GoWrapError{&GoWrapErrorSelfAddrError{message}} + case 4: + return &GoWrapError{&GoWrapErrorSendMsgError{message}} + case 5: + return &GoWrapError{&GoWrapErrorReplyError{message}} + case 6: + return &GoWrapError{&GoWrapErrorListenError{message}} + default: + panic(fmt.Sprintf("Unknown error code %d in FfiConverterTypeGoWrapError.Read()", errorID)) + } + +} + +func (c FfiConverterTypeGoWrapError) Write(writer io.Writer, value *GoWrapError) { + switch variantValue := value.err.(type) { + case *GoWrapErrorClientInitError: + writeInt32(writer, 1) + case *GoWrapErrorClientUninitialisedError: + writeInt32(writer, 2) + case *GoWrapErrorSelfAddrError: + writeInt32(writer, 3) + case *GoWrapErrorSendMsgError: + writeInt32(writer, 4) + case *GoWrapErrorReplyError: + writeInt32(writer, 5) + case *GoWrapErrorListenError: + writeInt32(writer, 6) + default: + _ = variantValue + panic(fmt.Sprintf("invalid error value `%v` in FfiConverterTypeGoWrapError.Write", value)) + } +} + +func GetSelfAddress() (string, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeGoWrapError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_nym_go_ffi_fn_func_get_self_address(_uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue string + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterStringINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func InitEphemeral() error { + _, _uniffiErr := rustCallWithError(FfiConverterTypeGoWrapError{}, func(_uniffiStatus *C.RustCallStatus) bool { + C.uniffi_nym_go_ffi_fn_func_init_ephemeral(_uniffiStatus) + return false + }) + return _uniffiErr +} + +func InitLogging() { + rustCall(func(_uniffiStatus *C.RustCallStatus) bool { + C.uniffi_nym_go_ffi_fn_func_init_logging(_uniffiStatus) + return false + }) +} + +func ListenForIncoming() (IncomingMessage, error) { + _uniffiRV, _uniffiErr := rustCallWithError(FfiConverterTypeGoWrapError{}, func(_uniffiStatus *C.RustCallStatus) RustBufferI { + return C.uniffi_nym_go_ffi_fn_func_listen_for_incoming(_uniffiStatus) + }) + if _uniffiErr != nil { + var _uniffiDefaultValue IncomingMessage + return _uniffiDefaultValue, _uniffiErr + } else { + return FfiConverterTypeIncomingMessageINSTANCE.Lift(_uniffiRV), _uniffiErr + } +} + +func Reply(recipient []byte, message string) error { + _, _uniffiErr := rustCallWithError(FfiConverterTypeGoWrapError{}, func(_uniffiStatus *C.RustCallStatus) bool { + C.uniffi_nym_go_ffi_fn_func_reply(FfiConverterBytesINSTANCE.Lower(recipient), FfiConverterStringINSTANCE.Lower(message), _uniffiStatus) + return false + }) + return _uniffiErr +} + +func SendMessage(recipient string, message string) error { + _, _uniffiErr := rustCallWithError(FfiConverterTypeGoWrapError{}, func(_uniffiStatus *C.RustCallStatus) bool { + C.uniffi_nym_go_ffi_fn_func_send_message(FfiConverterStringINSTANCE.Lower(recipient), FfiConverterStringINSTANCE.Lower(message), _uniffiStatus) + return false + }) + return _uniffiErr +} diff --git a/sdk/ffi/go/go-nym/bindings/bindings.h b/sdk/ffi/go/go-nym/bindings/bindings.h new file mode 100644 index 0000000000..3a732f3068 --- /dev/null +++ b/sdk/ffi/go/go-nym/bindings/bindings.h @@ -0,0 +1,427 @@ + + +// This file was autogenerated by some hot garbage in the `uniffi` crate. +// Trust me, you don't want to mess with it! + + + +#include <stdbool.h> +#include <stdint.h> + +// The following structs are used to implement the lowest level +// of the FFI, and thus useful to multiple uniffied crates. +// We ensure they are declared exactly once, with a header guard, UNIFFI_SHARED_H. +#ifdef UNIFFI_SHARED_H + // We also try to prevent mixing versions of shared uniffi header structs. + // If you add anything to the #else block, you must increment the version suffix in UNIFFI_SHARED_HEADER_V6 + #ifndef UNIFFI_SHARED_HEADER_V6 + #error Combining helper code from multiple versions of uniffi is not supported + #endif // ndef UNIFFI_SHARED_HEADER_V6 +#else +#define UNIFFI_SHARED_H +#define UNIFFI_SHARED_HEADER_V6 +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V6 in this file. ⚠️ + +typedef struct RustBuffer { + int32_t capacity; + int32_t len; + uint8_t *data; +} RustBuffer; + +typedef int32_t (*ForeignCallback)(uint64_t, int32_t, uint8_t *, int32_t, RustBuffer *); + +// Task defined in Rust that Go executes +typedef void (*RustTaskCallback)(const void *, int8_t); + +// Callback to execute Rust tasks using a Go routine +// +// Args: +// executor: ForeignExecutor lowered into a uint64_t value +// delay: Delay in MS +// task: RustTaskCallback to call +// task_data: data to pass the task callback +typedef int8_t (*ForeignExecutorCallback)(uint64_t, uint32_t, RustTaskCallback, void *); + +typedef struct ForeignBytes { + int32_t len; + const uint8_t *data; +} ForeignBytes; + +// Error definitions +typedef struct RustCallStatus { + int8_t code; + RustBuffer errorBuf; +} RustCallStatus; + +// Continuation callback for UniFFI Futures +typedef void (*RustFutureContinuation)(void * , int8_t); + +// ⚠️ Attention: If you change this #else block (ending in `#endif // def UNIFFI_SHARED_H`) you *must* ⚠️ +// ⚠️ increment the version suffix in all instances of UNIFFI_SHARED_HEADER_V6 in this file. ⚠️ +#endif // def UNIFFI_SHARED_H + +// Needed because we can't execute the callback directly from go. +void cgo_rust_task_callback_bridge_bindings(RustTaskCallback, const void *, int8_t); + +int8_t uniffiForeignExecutorCallbackbindings(uint64_t, uint32_t, RustTaskCallback, void*); + +void uniffiFutureContinuationCallbackbindings(void*, int8_t); + +RustBuffer uniffi_nym_go_ffi_fn_func_get_self_address( + RustCallStatus* out_status +); + +void uniffi_nym_go_ffi_fn_func_init_ephemeral( + RustCallStatus* out_status +); + +void uniffi_nym_go_ffi_fn_func_init_logging( + RustCallStatus* out_status +); + +RustBuffer uniffi_nym_go_ffi_fn_func_listen_for_incoming( + RustCallStatus* out_status +); + +void uniffi_nym_go_ffi_fn_func_reply( + RustBuffer recipient, + RustBuffer message, + RustCallStatus* out_status +); + +void uniffi_nym_go_ffi_fn_func_send_message( + RustBuffer recipient, + RustBuffer message, + RustCallStatus* out_status +); + +RustBuffer ffi_nym_go_ffi_rustbuffer_alloc( + int32_t size, + RustCallStatus* out_status +); + +RustBuffer ffi_nym_go_ffi_rustbuffer_from_bytes( + ForeignBytes bytes, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rustbuffer_free( + RustBuffer buf, + RustCallStatus* out_status +); + +RustBuffer ffi_nym_go_ffi_rustbuffer_reserve( + RustBuffer buf, + int32_t additional, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_continuation_callback_set( + RustFutureContinuation callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_u8( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_u8( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_u8( + void* handle, + RustCallStatus* out_status +); + +uint8_t ffi_nym_go_ffi_rust_future_complete_u8( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_i8( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_i8( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_i8( + void* handle, + RustCallStatus* out_status +); + +int8_t ffi_nym_go_ffi_rust_future_complete_i8( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_u16( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_u16( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_u16( + void* handle, + RustCallStatus* out_status +); + +uint16_t ffi_nym_go_ffi_rust_future_complete_u16( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_i16( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_i16( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_i16( + void* handle, + RustCallStatus* out_status +); + +int16_t ffi_nym_go_ffi_rust_future_complete_i16( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_u32( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_u32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_u32( + void* handle, + RustCallStatus* out_status +); + +uint32_t ffi_nym_go_ffi_rust_future_complete_u32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_i32( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_i32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_i32( + void* handle, + RustCallStatus* out_status +); + +int32_t ffi_nym_go_ffi_rust_future_complete_i32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_u64( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_u64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_u64( + void* handle, + RustCallStatus* out_status +); + +uint64_t ffi_nym_go_ffi_rust_future_complete_u64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_i64( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_i64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_i64( + void* handle, + RustCallStatus* out_status +); + +int64_t ffi_nym_go_ffi_rust_future_complete_i64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_f32( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_f32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_f32( + void* handle, + RustCallStatus* out_status +); + +float ffi_nym_go_ffi_rust_future_complete_f32( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_f64( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_f64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_f64( + void* handle, + RustCallStatus* out_status +); + +double ffi_nym_go_ffi_rust_future_complete_f64( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_pointer( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_pointer( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_pointer( + void* handle, + RustCallStatus* out_status +); + +void* ffi_nym_go_ffi_rust_future_complete_pointer( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_rust_buffer( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_rust_buffer( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_rust_buffer( + void* handle, + RustCallStatus* out_status +); + +RustBuffer ffi_nym_go_ffi_rust_future_complete_rust_buffer( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_poll_void( + void* handle, + void* uniffi_callback, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_cancel_void( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_free_void( + void* handle, + RustCallStatus* out_status +); + +void ffi_nym_go_ffi_rust_future_complete_void( + void* handle, + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_get_self_address( + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_init_ephemeral( + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_init_logging( + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_listen_for_incoming( + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_reply( + RustCallStatus* out_status +); + +uint16_t uniffi_nym_go_ffi_checksum_func_send_message( + RustCallStatus* out_status +); + +uint32_t ffi_nym_go_ffi_uniffi_contract_version( + RustCallStatus* out_status +); + + + diff --git a/sdk/ffi/go/go.mod b/sdk/ffi/go/go.mod new file mode 100644 index 0000000000..1d046c25db --- /dev/null +++ b/sdk/ffi/go/go.mod @@ -0,0 +1,3 @@ +module nymffi + +go 1.20 diff --git a/sdk/ffi/go/go.sum b/sdk/ffi/go/go.sum new file mode 100644 index 0000000000..e69de29bb2 diff --git a/sdk/ffi/go/src/bindings.udl b/sdk/ffi/go/src/bindings.udl new file mode 100644 index 0000000000..0866662f3f --- /dev/null +++ b/sdk/ffi/go/src/bindings.udl @@ -0,0 +1,28 @@ +[Error] +enum GoWrapError { + "ClientInitError", + "ClientUninitialisedError", + "SelfAddrError", + "SendMsgError", + "ReplyError", + "ListenError" +}; + +dictionary IncomingMessage { + string message; + bytes sender; +}; + +namespace bindings { + void init_logging(); + [Throws=GoWrapError] + void init_ephemeral(); + [Throws=GoWrapError] + string get_self_address(); + [Throws=GoWrapError] + void send_message(string recipient, string message); + [Throws=GoWrapError] + void reply(bytes recipient, string message); + [Throws=GoWrapError] + IncomingMessage listen_for_incoming(); +}; diff --git a/sdk/ffi/go/src/lib.rs b/sdk/ffi/go/src/lib.rs new file mode 100644 index 0000000000..daa77fd203 --- /dev/null +++ b/sdk/ffi/go/src/lib.rs @@ -0,0 +1,82 @@ +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_sdk::mixnet::Recipient; +use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag; +uniffi::include_scaffolding!("bindings"); + +#[derive(Debug, thiserror::Error)] +enum GoWrapError { + #[error("Couldn't init client")] + ClientInitError {}, + #[error("Client is uninitialised: init client first")] + ClientUninitialisedError {}, + #[error("Error getting self address")] + SelfAddrError {}, + #[error("Error sending message")] + SendMsgError {}, + #[error("Error sending reply")] + ReplyError {}, + #[error("Could not start listening")] + ListenError {}, +} + +#[no_mangle] +fn init_logging() { + nym_bin_common::logging::setup_logging(); +} + +#[no_mangle] +fn init_ephemeral() -> Result<(), GoWrapError> { + match nym_ffi_shared::init_ephemeral_internal() { + Ok(_) => Ok(()), + Err(_) => Err(GoWrapError::ClientInitError {}), + } +} + +#[no_mangle] +fn get_self_address() -> Result<String, GoWrapError> { + match nym_ffi_shared::get_self_address_internal() { + Ok(addr) => Ok(addr), + Err(..) => Err(GoWrapError::SelfAddrError {}), + } +} + +#[no_mangle] +fn send_message(recipient: String, message: String) -> Result<(), GoWrapError> { + let nym_recipient_type = Recipient::try_from_base58_string(recipient).unwrap(); + match nym_ffi_shared::send_message_internal(nym_recipient_type, &message) { + Ok(_) => Ok(()), + Err(_) => Err(GoWrapError::SendMsgError {}), + } +} + +#[no_mangle] +fn reply(recipient: Vec<u8>, message: String) -> Result<(), GoWrapError> { + let mut sized_array: [u8; 16] = [0; 16]; + sized_array.copy_from_slice(&recipient[..16]); + let anon_recipient_type: AnonymousSenderTag = AnonymousSenderTag::from_bytes(sized_array); + match nym_ffi_shared::reply_internal(anon_recipient_type, &message) { + Ok(_) => Ok(()), + Err(_) => Err(GoWrapError::ReplyError {}), + } +} + +pub struct IncomingMessage { + message: String, + sender: Vec<u8>, +} + +#[no_mangle] +fn listen_for_incoming() -> Result<IncomingMessage, GoWrapError> { + match nym_ffi_shared::listen_for_incoming_internal() { + Ok(received) => { + let message = String::from_utf8_lossy(&received.message).to_string(); + // maybe change this to raw bytes to send over TODO + let sender = received.sender_tag.unwrap().to_bytes().to_vec(); //.to_base58_string(); + let incoming = IncomingMessage { message, sender }; + Ok(incoming) + } + Err(_) => Err(GoWrapError::ListenError {}), + } +} diff --git a/sdk/ffi/go/uniffi-bindgen.rs b/sdk/ffi/go/uniffi-bindgen.rs new file mode 100644 index 0000000000..d96eac70f9 --- /dev/null +++ b/sdk/ffi/go/uniffi-bindgen.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi::uniffi_bindgen_main() +} \ No newline at end of file diff --git a/sdk/ffi/shared/Cargo.lock b/sdk/ffi/shared/Cargo.lock new file mode 100644 index 0000000000..56429c1de3 --- /dev/null +++ b/sdk/ffi/shared/Cargo.lock @@ -0,0 +1,6045 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "crypto-common", + "generic-array 0.14.7", +] + +[[package]] +name = "aes" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" +dependencies = [ + "cfg-if", + "cipher 0.3.0", + "cpufeatures", + "ctr 0.8.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "aes" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "ahash" +version = "0.7.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +dependencies = [ + "getrandom 0.2.12", + "once_cell", + "version_check", +] + +[[package]] +name = "ahash" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01" +dependencies = [ + "cfg-if", + "once_cell", + "version_check", + "zerocopy", +] + +[[package]] +name = "aho-corasick" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" +dependencies = [ + "memchr", +] + +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + +[[package]] +name = "anstream" +version = "0.6.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fde6067df7359f2d6335ec1a50c1f8f825801687d10da0cc4c6b08e3f6afd15" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7079075b41f533b8c61d2a4d073c4676e1f8b249ff94a393b0595db304e0dd87" + +[[package]] +name = "anstyle-parse" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c75ac65da39e5fe5ab759307499ddad880d724eed2f6ce5b5e8a26f4f387928c" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e28923312444cdd728e4738b3f9c9cac739500909bb3d3c94b43551b16517648" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cd54b81ec8d6180e24654d0b371ad22fc3dd083b6ff8ba325b72e00c87660a7" +dependencies = [ + "anstyle", + "windows-sys 0.52.0", +] + +[[package]] +name = "anyhow" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" + +[[package]] +name = "arrayref" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b4930d2cb77ce62f89ee5d5289b4ac049559b1c45539271f5ed4fdc7db34545" + +[[package]] +name = "arrayvec" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96d30a06541fbafbc7f82ed10c06164cfbd2c401138f6addd8404629c4b16711" + +[[package]] +name = "askama" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +dependencies = [ + "askama_derive", + "askama_escape", +] + +[[package]] +name = "askama_derive" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +dependencies = [ + "askama_parser", + "basic-toml", + "mime", + "mime_guess", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", +] + +[[package]] +name = "askama_escape" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" + +[[package]] +name = "askama_parser" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +dependencies = [ + "nom", +] + +[[package]] +name = "async-trait" +version = "0.1.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "atoi" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "616896e05fc0e2649463a93a15183c6a16bf03413a7af88ef1285ddedfa9cda5" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atoi" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7c57d12312ff59c811c0643f4d80830505833c9ffaebd193d819392b265be8e" +dependencies = [ + "num-traits", +] + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi 0.1.19", + "libc", + "winapi", +] + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" +version = "0.21.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "basic-toml" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2db21524cad41c5591204d22d75e1970a2d1f71060214ca931dc7d5afe2c14e5" +dependencies = [ + "serde", +] + +[[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] +name = "bip32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" +dependencies = [ + "bs58 0.5.0", + "hmac 0.12.1", + "k256", + "once_cell", + "pbkdf2", + "rand_core 0.6.4", + "ripemd", + "sha2 0.10.8", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bip39" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93f2635620bf0b9d4576eb7bb9a38a55df78bd1205d26fa994b25911a69f212f" +dependencies = [ + "bitcoin_hashes", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "unicode-normalization", + "zeroize", +] + +[[package]] +name = "bitcoin_hashes" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90064b8dee6815a6470d60bad07bbbaee885c0e12d04177138fa3291a01b7bc4" + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94cb07b0da6a73955f8fb85d24c466778e70cda767a568229b104f0264089330" +dependencies = [ + "byte-tools", + "crypto-mac 0.7.0", + "digest 0.8.1", + "opaque-debug 0.2.3", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "blake3" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0231f06152bf547e9c2b5194f247cd97aacf6dcd8b15d8e5ec0663f64580da87" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", + "digest 0.10.7", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "bls12_381" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54757888b09a69be70b5ec303e382a74227392086ba808cb01eeca29233a2397" +dependencies = [ + "digest 0.9.0", + "ff 0.10.1", + "group 0.10.0", + "pairing 0.20.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "bls12_381" +version = "0.6.0" +source = "git+https://github.com/jstuczyn/bls12_381?branch=gt-serialisation#10fb6f700bfda17c8475af3bfd31e3fec15f2278" +dependencies = [ + "digest 0.9.0", + "ff 0.11.1", + "group 0.11.0", + "pairing 0.21.0", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "bnum" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" + +[[package]] +name = "boringtun" +version = "0.6.0" +source = "git+https://github.com/cloudflare/boringtun?rev=e1d6360d6ab4529fc942a078e4c54df107abe2ba#e1d6360d6ab4529fc942a078e4c54df107abe2ba" +dependencies = [ + "aead", + "base64 0.13.1", + "blake2 0.10.6", + "chacha20poly1305", + "hex", + "hmac 0.12.1", + "ip_network", + "ip_network_table", + "libc", + "nix", + "parking_lot 0.12.1", + "rand_core 0.6.4", + "ring 0.16.20", + "tracing", + "untrusted 0.9.0", + "x25519-dalek 2.0.0", +] + +[[package]] +name = "bs58" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" + +[[package]] +name = "bs58" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +dependencies = [ + "sha2 0.10.8", + "tinyvec", +] + +[[package]] +name = "bumpalo" +version = "3.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" + +[[package]] +name = "byte-tools" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7" + +[[package]] +name = "bytecodec" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adf4c9d0bbf32eea58d7c0f812058138ee8edaf0f2802b6d03561b504729a325" +dependencies = [ + "byteorder", + "trackable 0.2.24", +] + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "bytes" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" +dependencies = [ + "serde", +] + +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ceed8ef69d8518a5dda55c07425450b58a4e1946f4951eab6d7191ee86c2443d" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eee4243f1f26fc7a42710e7439c149e2b10b05472f88090acce52632f231a73a" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.21", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "jobserver", + "libc", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chacha" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddf3c081b5fba1e5615640aae998e0fbd10c24cbd897ee39ed754a77601a4862" +dependencies = [ + "byteorder", + "keystream", +] + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher 0.4.4", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher 0.4.4", + "poly1305", + "zeroize", +] + +[[package]] +name = "cipher" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ee52072ec15386f770805afd189a01c8841be8696bed250fa2f13c4c0d6dfb7" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e578d6ec4194633722ccf9544794b71b1385c3c027efe0c55db226fc880865c" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.4.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4df4df40ec50c46000231c914968278b1eb05098cf8f1b3a518a95030e71d1c7" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb0d4825b75ff281318c393e8e1b80c4da9fb75a6b1d98547d389d6fe1f48d2" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_complete_fig" +version = "4.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87e571d70e22ec91d34e1c5317c8308035a2280d925167646bf094fc5de1737c" +dependencies = [ + "clap", + "clap_complete", +] + +[[package]] +name = "clap_derive" +version = "4.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf9804afaaf59a91e75b022a30fb7229a7901f60c755489cc61c9b423b836442" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "clap_lex" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1" + +[[package]] +name = "colorchoice" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" + +[[package]] +name = "colored" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbf2150cce219b664a8a70df7a1f933836724b503f8a413af9365b4dcc4d90b8" +dependencies = [ + "lazy_static", + "windows-sys 0.48.0", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7144d30dcf0fafbce74250a3963025d8d52177934239851c917d29f1df280c2" + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" + +[[package]] +name = "cosmos-sdk-proto" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32560304ab4c365791fd307282f76637213d8083c1a98490c35159cd67852237" +dependencies = [ + "prost", + "prost-types", + "tendermint-proto", +] + +[[package]] +name = "cosmrs" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" +dependencies = [ + "bip32", + "cosmos-sdk-proto", + "ecdsa", + "eyre", + "k256", + "rand_core 0.6.4", + "serde", + "serde_json", + "signature 2.2.0", + "subtle-encoding", + "tendermint", + "tendermint-rpc", + "thiserror", +] + +[[package]] +name = "cosmwasm-crypto" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ed6aa9f904de106fa16443ad14ec2abe75e94ba003bb61c681c0e43d4c58d2a" +dependencies = [ + "digest 0.10.7", + "ecdsa", + "ed25519-zebra", + "k256", + "rand_core 0.6.4", + "thiserror", +] + +[[package]] +name = "cosmwasm-derive" +version = "1.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "40abec852f3d4abec6d44ead9a58b78325021a1ead1e7229c3471414e57b2e49" +dependencies = [ + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-schema" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +dependencies = [ + "cosmwasm-schema-derive", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "cosmwasm-schema-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "cosmwasm-std" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +dependencies = [ + "base64 0.13.1", + "bnum", + "cosmwasm-crypto", + "cosmwasm-derive", + "derivative", + "forward_ref", + "hex", + "schemars", + "serde", + "serde-json-wasm", + "sha2 0.10.8", + "thiserror", +] + +[[package]] +name = "cpufeatures" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49fc9a695bca7f35f5f4c15cddc84415f66a74ea78eef08e90c5024f2b540e23" +dependencies = [ + "crc-catalog 1.1.1", +] + +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog 2.4.0", +] + +[[package]] +name = "crc-catalog" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccaeedb56da03b09f598226e25e80088cb4cd25f316e6e4df7d695f0feeb1403" + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc32fast" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b540bd8bc810d3885c6ea91e2018302f68baba2129ab3e88f32389ee9370880d" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-queue" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df0346b5d5e76ac2fe4e327c5fd1118d6be7c51dfb18f9b7922923f287471e35" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto-mac" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4434400df11d95d556bac068ddfedd482915eb18fe8bea89bc80b6e4b1c179e5" +dependencies = [ + "generic-array 0.12.4", + "subtle 1.0.0", +] + +[[package]] +name = "crypto-mac" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1d1a86f49236c215f271d40892d5fc950490551400b02ef360692c29815c714" +dependencies = [ + "generic-array 0.14.7", + "subtle 2.4.1", +] + +[[package]] +name = "ctr" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "049bb91fb4aaf0e3c7efa6cd5ef877dbbbd15b39dad06d9948de4ec8a75761ea" +dependencies = [ + "cipher 0.3.0", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher 0.4.4", +] + +[[package]] +name = "curve25519-dalek" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b9fdf9972b2bd6af2d913799d9ebc165ea4d2e65878e329d9c6b372c4491b61" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.5.1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e89b8c6a2e4b1f45971ad09761aafb85514a84744b67a95e32c3cc1352d1f65c" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "fiat-crypto", + "platforms", + "rustc_version", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "curve25519-dalek-ng" +version = "4.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c359b7249347e46fb28804470d071c921156ad62b3eef5d34e2ba867533dec8" +dependencies = [ + "byteorder", + "digest 0.9.0", + "rand_core 0.6.4", + "subtle-ng", + "zeroize", +] + +[[package]] +name = "cw-controllers" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5d8edce4b78785f36413f67387e4be7d0cb7d032b5d4164bcc024f9c3f3f2ea" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw-storage-plus" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +dependencies = [ + "cosmwasm-std", + "schemars", + "serde", +] + +[[package]] +name = "cw-utils" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c80e93d1deccb8588db03945016a292c3c631e6325d349ebb35d2db6f4f946f7" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw2", + "schemars", + "semver 1.0.21", + "serde", + "thiserror", +] + +[[package]] +name = "cw2" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw20" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "schemars", + "serde", +] + +[[package]] +name = "cw3" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "cw20", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "cw4" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "schemars", + "serde", +] + +[[package]] +name = "dashmap" +version = "5.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "978747c1d849a7d2ee5e8adc0159961c48fb7e5db2f06af6723b80123bb53856" +dependencies = [ + "cfg-if", + "hashbrown 0.14.3", + "lock_api", + "once_cell", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "data-encoding" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e962a19be5cfc3f3bf6dd8f61eb50107f356ad6270fbb3ed41476571db78be5" + +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "digest" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5" +dependencies = [ + "generic-array 0.12.4", +] + +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer 0.10.4", + "const-oid", + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "dirs" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3aa72a6f96ea37bbc5aa912f6788242832f75369bdfdadcb0e38423f100059" +dependencies = [ + "dirs-sys 0.3.7", +] + +[[package]] +name = "dirs" +version = "5.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +dependencies = [ + "dirs-sys 0.4.1", +] + +[[package]] +name = "dirs-sys" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6" +dependencies = [ + "libc", + "redox_users", + "winapi", +] + +[[package]] +name = "dirs-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.48.0", +] + +[[package]] +name = "dotenv" +version = "0.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" + +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + +[[package]] +name = "dyn-clone" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d" + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest 0.10.7", + "elliptic-curve", + "rfc6979", + "signature 2.2.0", + "spki", +] + +[[package]] +name = "ed25519" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" +dependencies = [ + "signature 1.6.4", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature 2.2.0", +] + +[[package]] +name = "ed25519-consensus" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c8465edc8ee7436ffea81d21a019b16676ee3db267aa8d5a8d729581ecf998b" +dependencies = [ + "curve25519-dalek-ng", + "hex", + "rand_core 0.6.4", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-dalek" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c762bae6dcaf24c4c84667b8579785430908723d5c889f469d76a41d59cc7a9d" +dependencies = [ + "curve25519-dalek 3.2.0", + "ed25519 1.5.3", + "rand 0.7.3", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "ed25519-zebra" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c24f403d068ad0b359e577a77f92392118be3f3c927538f2bb544a5ecd828c6" +dependencies = [ + "curve25519-dalek 3.2.0", + "hashbrown 0.12.3", + "hex", + "rand_core 0.6.4", + "serde", + "sha2 0.9.9", + "zeroize", +] + +[[package]] +name = "either" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "crypto-bigint", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "encoding_rs" +version = "0.8.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "enum-iterator" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a0ac4aeb3a18f92eaf09c6bb9b3ac30ff61ca95514fc58cbead1c9a6bf5401" +dependencies = [ + "enum-iterator-derive", +] + +[[package]] +name = "enum-iterator-derive" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03cdc46ec28bd728e67540c528013c6a10eb69a02eb31078a1bda695438cbfb8" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "env_logger" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36" +dependencies = [ + "atty", + "humantime 1.3.0", + "log", + "regex", + "termcolor", +] + +[[package]] +name = "equivalent" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" + +[[package]] +name = "errno" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "eyre" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +dependencies = [ + "indenter", + "once_cell", +] + +[[package]] +name = "fastrand" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" + +[[package]] +name = "ff" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0f40b2dcd8bc322217a5f6559ae5f9e9d1de202a2ecee2e9eafcbece7562a4f" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "ff" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "131655483be284720a17d74ff97592b8e76576dc25563148601df2d7c9080924" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7" + +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + +[[package]] +name = "flate2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46303f565772937ffe1d394a4fac6f411c6013172fadde9dcdb1e147a086940e" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "flex-error" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c606d892c9de11507fa0dcffc116434f94e105d0bbdc4e405b61519464c49d7b" +dependencies = [ + "eyre", + "paste", +] + +[[package]] +name = "flume" +version = "0.10.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1657b4441c3403d9f7b3409e47575237dac27b1b5726df654a6ecbf92f0f7577" +dependencies = [ + "futures-core", + "futures-sink", + "pin-project", + "spin 0.9.8", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "forward_ref" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8cbd1169bd7b4a0a20d92b9af7a7e0422888bd38a6f5ec29c1fd8c1558a272e" + +[[package]] +name = "fs-err" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88a41f105fe1d5b6b34b2055e3dc59bb79b46b48b2040b9e6c7b4b5de097aa41" +dependencies = [ + "autocfg", +] + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" + +[[package]] +name = "futures-executor" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-intrusive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a604f7a68fbf8103337523b1fadc8ade7361ee3f112f7c680ad179651616aed5" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot 0.11.2", +] + +[[package]] +name = "futures-io" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" + +[[package]] +name = "futures-macro" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "futures-sink" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" + +[[package]] +name = "futures-task" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" + +[[package]] +name = "futures-util" +version = "0.3.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd" +dependencies = [ + "typenum", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "serde", + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.9.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getset" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e45727250e75cc04ff2846a66397da8ef2b3db8e40e0cef4df67950a07621eb9" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "gimli" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "git2" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0155506aab710a86160ddb504a480d2964d7ab5b9e62419be69e0032bc5931c" +dependencies = [ + "bitflags 1.3.2", + "libc", + "libgit2-sys", + "log", + "url", +] + +[[package]] +name = "glob" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" + +[[package]] +name = "gloo-net" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a66b4e3c7d9ed8d315fd6b97c8b1f74a7c6ecbbc2320e65ae7ed38b7068cc620" +dependencies = [ + "futures-channel", + "futures-core", + "futures-sink", + "gloo-utils", + "http", + "js-sys", + "pin-project", + "serde", + "serde_json", + "thiserror", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "gloo-timers" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b995a66bb87bebce9a0f4a95aed01daca4872c050bfcb21653361c03bc35e5c" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "gloo-utils" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037fcb07216cb3a30f7292bd0176b050b7b9a052ba830ef7d5d65f6dc64ba58e" +dependencies = [ + "js-sys", + "serde", + "serde_json", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "goblin" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d6b4de4a8eb6c46a8c77e1d3be942cb9a8bf073c22374578e5ba4b08ed0ff68" +dependencies = [ + "log", + "plain", + "scroll", +] + +[[package]] +name = "group" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c363a5301b8f153d80747126a04b3c82073b9fe3130571a9d170cacdeaf7912" +dependencies = [ + "byteorder", + "ff 0.10.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5ac374b108929de78460075f3dc439fa66df9d8fc77e8f12caa5165fcf0c89" +dependencies = [ + "byteorder", + "ff 0.11.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "h2" +version = "0.3.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http", + "indexmap 2.1.0", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "handlebars" +version = "3.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4498fc115fa7d34de968184e473529abb40eeb6be8bc5f7faba3d08c316cb3e3" +dependencies = [ + "log", + "pest", + "pest_derive", + "quick-error 2.0.1", + "serde", + "serde_json", +] + +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +dependencies = [ + "ahash 0.7.7", +] + +[[package]] +name = "hashbrown" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" +dependencies = [ + "ahash 0.8.7", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7249a3129cbc1ffccd74857f81464a323a152173cdb134e0fd81bc803b29facf" +dependencies = [ + "hashbrown 0.11.2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.3", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "hermit-abi" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d3d0e0f38255e7fa3cf31335b3a56f05febd18025f4db5ef7a0cfb4f8da651f" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hex-literal" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ebdb29d2ea9ed0083cd8cece49bbd968021bd99b0849edb4a9a7ee0fdf6a4e0" + +[[package]] +name = "hkdf" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01706d578d5c281058480e673ae4086a9f4710d8df1ad80a5b03e39ece5f886b" +dependencies = [ + "digest 0.9.0", + "hmac 0.11.0", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.1", + "digest 0.9.0", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "http" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-api-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" + +[[package]] +name = "httpcodec" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f49d64351430cabd543943b79d48aaf0bc95a41d9ccf5b8774c2cfd23422775" +dependencies = [ + "bytecodec", + "trackable 0.2.24", +] + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "humantime" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f" +dependencies = [ + "quick-error 1.2.3", +] + +[[package]] +name = "humantime" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" + +[[package]] +name = "humantime-serde" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57a3db5ea5923d99402c94e9feb261dc5ee9b4efa158b0315f788cf549cc200c" +dependencies = [ + "humantime 2.1.0", + "serde", +] + +[[package]] +name = "hyper" +version = "0.14.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "socket2", + "tokio", + "tower-service", + "tracing", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" +dependencies = [ + "futures-util", + "http", + "hyper", + "rustls 0.21.10", + "tokio", + "tokio-rustls 0.24.1", +] + +[[package]] +name = "hyper-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" +dependencies = [ + "bytes", + "hyper", + "native-tls", + "tokio", + "tokio-native-tls", +] + +[[package]] +name = "idna" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "634d9b1461af396cad843f47fdba5597a4f9e6ddd4bfb6ff5d85028c25cb12f6" +dependencies = [ + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "indenter" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683" + +[[package]] +name = "indexmap" +version = "1.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" +dependencies = [ + "autocfg", + "hashbrown 0.12.3", + "serde", +] + +[[package]] +name = "indexmap" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" +dependencies = [ + "equivalent", + "hashbrown 0.14.3", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array 0.14.7", +] + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "ip_network" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2f047c0a98b2f299aa5d6d7088443570faae494e9ae1305e48be000c9e0eb1" + +[[package]] +name = "ip_network_table" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4099b7cfc5c5e2fe8c5edf3f6f7adf7a714c9cc697534f63a5a5da30397cb2c0" +dependencies = [ + "ip_network", + "ip_network_table-deps-treebitmap", +] + +[[package]] +name = "ip_network_table-deps-treebitmap" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e537132deb99c0eb4b752f0346b6a836200eaaa3516dd7e5514b63930a09e5d" + +[[package]] +name = "ipnet" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3" + +[[package]] +name = "itertools" +version = "0.10.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + +[[package]] +name = "itertools" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25db6b064527c5d482d0423354fcd07a89a2dfe07b67892e62411946db7f07b0" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "jobserver" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c37f63953c4c63420ed5fd3d6d398c719489b9f872b9fa683262f8edd363c7d" +dependencies = [ + "libc", +] + +[[package]] +name = "js-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a1d36f1235bc969acba30b7f5990b864423a6068a10f7c90ae8f0112e3a59d1" +dependencies = [ + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "956ff9b67e26e1a6a866cb758f12c6f8746208489e3e4a4b5580802f2f0a587b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2 0.10.8", + "signature 2.2.0", +] + +[[package]] +name = "keystream" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.152" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13e3bf6590cbc649f4d1a3eefc9d5d6eb746f5200ffb04e5e142700b8faa56e7" + +[[package]] +name = "libgit2-sys" +version = "0.13.5+1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51e5ea06c26926f1002dd553fded6cfcdc9784c1f60feeb58368b4d9b07b6dba" +dependencies = [ + "cc", + "libc", + "libz-sys", + "pkg-config", +] + +[[package]] +name = "libm" +version = "0.2.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" + +[[package]] +name = "libredox" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8" +dependencies = [ + "bitflags 2.4.2", + "libc", + "redox_syscall 0.4.1", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "898745e570c7d0453cc1fbc4a701eb6c662ed54e8fec8b7d14be137ebeeb9d14" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-sys" +version = "1.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "295c17e837573c8c821dbaeb3cceb3d745ad082f7572191409e69cbc1b3fd050" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" + +[[package]] +name = "lioness" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ae926706ba42c425c9457121178330d75e273df2e82e28b758faf3de3a9acb9" +dependencies = [ + "arrayref", + "blake2 0.8.1", + "chacha", + "keystream", +] + +[[package]] +name = "lock_api" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" +dependencies = [ + "autocfg", + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" + +[[package]] +name = "memchr" +version = "2.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" + +[[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.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef" +dependencies = [ + "mime", + "unicase", +] + +[[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.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "mio" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.48.0", +] + +[[package]] +name = "native-tls" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07226173c32f2926027b63cce4bcd8076c3552846cbe7925f3aaffeac0a3b92e" +dependencies = [ + "lazy_static", + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nix" +version = "0.25.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f346ff70e7dbfd675fe90590b92d59ef2de15a8779ae305ebcbfd3f0caf59be4" +dependencies = [ + "autocfg", + "bitflags 1.3.2", + "cfg-if", + "libc", +] + +[[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 = "num-derive" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "876a53fff98e03a936a674b29568b0e605f06b29372c2489ff4de23f1949743d" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "num-traits" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39e3200413f237f41ab11ad6d161bc7239c84dcb631773ccd7de3dfe4b5c267c" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" +dependencies = [ + "hermit-abi 0.3.4", + "libc", +] + +[[package]] +name = "nym-api-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmrs", + "cosmwasm-std", + "getset", + "nym-coconut-interface", + "nym-mixnet-contract-common", + "nym-node-requests", + "schemars", + "serde", +] + +[[package]] +name = "nym-bandwidth-controller" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bip39", + "nym-coconut-interface", + "nym-credential-storage", + "nym-credentials", + "nym-crypto", + "nym-network-defaults", + "nym-validator-client", + "rand 0.7.3", + "thiserror", + "url", +] + +[[package]] +name = "nym-bin-common" +version = "0.6.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "atty", + "clap", + "clap_complete", + "clap_complete_fig", + "log", + "pretty_env_logger", + "schemars", + "semver 0.11.0", + "serde", + "vergen", +] + +[[package]] +name = "nym-client-core" +version = "1.1.15" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "base64 0.21.7", + "cfg-if", + "dashmap", + "dirs 4.0.0", + "futures", + "gloo-timers", + "humantime-serde", + "log", + "nym-bandwidth-controller", + "nym-config", + "nym-credential-storage", + "nym-crypto", + "nym-explorer-client", + "nym-gateway-client", + "nym-gateway-requests", + "nym-network-defaults", + "nym-nonexhaustive-delayqueue", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "reqwest", + "serde", + "serde_json", + "sha2 0.10.8", + "sqlx 0.6.3", + "tap", + "thiserror", + "time", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-utils", + "wasmtimer", + "zeroize", +] + +[[package]] +name = "nym-coconut" +version = "0.5.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bls12_381 0.6.0", + "bs58 0.4.0", + "digest 0.9.0", + "ff 0.11.1", + "getrandom 0.2.12", + "group 0.11.0", + "itertools 0.10.5", + "nym-dkg", + "nym-pemstore", + "rand 0.8.5", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", +] + +[[package]] +name = "nym-coconut-bandwidth-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "nym-multisig-contract-common", +] + +[[package]] +name = "nym-coconut-dkg-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "nym-contracts-common", + "nym-multisig-contract-common", +] + +[[package]] +name = "nym-coconut-interface" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "getset", + "nym-coconut", + "serde", + "thiserror", +] + +[[package]] +name = "nym-config" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "dirs 5.0.1", + "handlebars", + "log", + "nym-network-defaults", + "serde", + "toml 0.7.8", + "url", +] + +[[package]] +name = "nym-contracts-common" +version = "0.5.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmwasm-schema", + "cosmwasm-std", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-credential-storage" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "log", + "sqlx 0.5.13", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-credential-utils" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-config", + "nym-credential-storage", + "nym-credentials", + "nym-validator-client", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-credentials" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bls12_381 0.5.0", + "cosmrs", + "log", + "nym-api-requests", + "nym-coconut-interface", + "nym-crypto", + "nym-validator-client", + "thiserror", +] + +[[package]] +name = "nym-crypto" +version = "0.4.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "aes 0.8.3", + "blake3", + "bs58 0.4.0", + "cipher 0.4.4", + "ctr 0.9.2", + "digest 0.10.7", + "ed25519-dalek", + "generic-array 0.14.7", + "hkdf 0.12.4", + "hmac 0.12.1", + "nym-pemstore", + "nym-sphinx-types", + "rand 0.7.3", + "subtle-encoding", + "thiserror", + "x25519-dalek 1.1.1", + "zeroize", +] + +[[package]] +name = "nym-dkg" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bitvec", + "bls12_381 0.6.0", + "bs58 0.4.0", + "ff 0.11.1", + "group 0.11.0", + "lazy_static", + "nym-pemstore", + "rand 0.8.5", + "rand_chacha 0.3.1", + "rand_core 0.6.4", + "serde", + "serde_derive", + "sha2 0.9.9", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-ephemera-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-utils", + "nym-contracts-common", +] + +[[package]] +name = "nym-exit-policy" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "serde", + "thiserror", + "tracing", +] + +[[package]] +name = "nym-explorer-api-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-api-requests", + "nym-contracts-common", + "nym-mixnet-contract-common", + "schemars", + "serde", +] + +[[package]] +name = "nym-explorer-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-explorer-api-requests", + "reqwest", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "nym-ffi-shared" +version = "0.1.0" +dependencies = [ + "anyhow", + "bs58 0.5.0", + "lazy_static", + "nym-bin-common", + "nym-sdk", + "nym-sphinx-anonymous-replies", + "tokio", + "uniffi", + "uniffi_build", +] + +[[package]] +name = "nym-gateway-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "getrandom 0.2.12", + "gloo-utils", + "log", + "nym-bandwidth-controller", + "nym-coconut-interface", + "nym-credential-storage", + "nym-crypto", + "nym-gateway-requests", + "nym-network-defaults", + "nym-pemstore", + "nym-sphinx", + "nym-task", + "nym-validator-client", + "rand 0.7.3", + "serde", + "thiserror", + "tokio", + "tokio-stream", + "tokio-tungstenite", + "tungstenite", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-utils", + "wasmtimer", +] + +[[package]] +name = "nym-gateway-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "futures", + "generic-array 0.14.7", + "log", + "nym-coconut-interface", + "nym-credentials", + "nym-crypto", + "nym-pemstore", + "nym-sphinx", + "rand 0.7.3", + "serde", + "serde_json", + "thiserror", + "tungstenite", + "zeroize", +] + +[[package]] +name = "nym-group-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cw-controllers", + "cw4", + "schemars", + "serde", +] + +[[package]] +name = "nym-mixnet-contract-common" +version = "0.6.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "cosmwasm-schema", + "cosmwasm-std", + "humantime-serde", + "log", + "nym-contracts-common", + "schemars", + "serde", + "serde-json-wasm", + "serde_repr", + "thiserror", + "time", +] + +[[package]] +name = "nym-multisig-contract-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-storage-plus", + "cw-utils", + "cw3", + "cw4", + "schemars", + "serde", + "thiserror", +] + +[[package]] +name = "nym-name-service-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "serde", + "thiserror", +] + +[[package]] +name = "nym-network-defaults" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cfg-if", + "dotenvy", + "hex-literal", + "once_cell", + "schemars", + "serde", + "thiserror", + "url", +] + +[[package]] +name = "nym-node-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "base64 0.21.7", + "nym-bin-common", + "nym-crypto", + "nym-exit-policy", + "nym-wireguard-types", + "schemars", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-nonexhaustive-delayqueue" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "tokio", + "tokio-stream", + "tokio-util", + "wasmtimer", +] + +[[package]] +name = "nym-ordered-buffer" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "thiserror", +] + +[[package]] +name = "nym-outfox" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "blake3", + "chacha20", + "chacha20poly1305", + "curve25519-dalek 3.2.0", + "getrandom 0.2.12", + "log", + "rand 0.7.3", + "rayon", + "sphinx-packet", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-pemstore" +version = "0.3.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "pem", +] + +[[package]] +name = "nym-sdk" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "bip39", + "bytecodec", + "bytes", + "futures", + "http", + "httpcodec", + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-credential-storage", + "nym-credential-utils", + "nym-credentials", + "nym-crypto", + "nym-gateway-requests", + "nym-network-defaults", + "nym-ordered-buffer", + "nym-service-providers-common", + "nym-socks5-client-core", + "nym-socks5-requests", + "nym-sphinx", + "nym-task", + "nym-topology", + "nym-validator-client", + "rand 0.7.3", + "tap", + "thiserror", + "toml 0.5.11", + "url", +] + +[[package]] +name = "nym-service-provider-directory-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "nym-contracts-common", + "thiserror", +] + +[[package]] +name = "nym-service-providers-common" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "log", + "nym-bin-common", + "nym-sphinx-anonymous-replies", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-socks5-client-core" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "anyhow", + "dirs 4.0.0", + "futures", + "log", + "nym-bandwidth-controller", + "nym-client-core", + "nym-config", + "nym-contracts-common", + "nym-credential-storage", + "nym-mixnet-contract-common", + "nym-network-defaults", + "nym-service-providers-common", + "nym-socks5-proxy-helpers", + "nym-socks5-requests", + "nym-sphinx", + "nym-task", + "nym-validator-client", + "pin-project", + "rand 0.7.3", + "reqwest", + "schemars", + "serde", + "tap", + "thiserror", + "tokio", + "url", +] + +[[package]] +name = "nym-socks5-proxy-helpers" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bytes", + "futures", + "log", + "nym-ordered-buffer", + "nym-socks5-requests", + "nym-task", + "tokio", + "tokio-util", +] + +[[package]] +name = "nym-socks5-requests" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bincode", + "log", + "nym-exit-policy", + "nym-service-providers-common", + "nym-sphinx-addressing", + "serde", + "serde_json", + "tap", + "thiserror", +] + +[[package]] +name = "nym-sphinx" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-anonymous-replies", + "nym-sphinx-chunking", + "nym-sphinx-cover", + "nym-sphinx-forwarding", + "nym-sphinx-framing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "rand_distr", + "thiserror", + "tokio", +] + +[[package]] +name = "nym-sphinx-acknowledgements" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "thiserror", + "zeroize", +] + +[[package]] +name = "nym-sphinx-addressing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-anonymous-replies" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bs58 0.4.0", + "nym-crypto", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "serde", + "thiserror", + "wasm-bindgen", +] + +[[package]] +name = "nym-sphinx-chunking" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "log", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-cover" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-sphinx-chunking", + "nym-sphinx-forwarding", + "nym-sphinx-params", + "nym-sphinx-routing", + "nym-sphinx-types", + "nym-topology", + "rand 0.7.3", + "thiserror", +] + +[[package]] +name = "nym-sphinx-forwarding" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-outfox", + "nym-sphinx-addressing", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-framing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "bytes", + "nym-sphinx-params", + "nym-sphinx-types", + "thiserror", + "tokio-util", +] + +[[package]] +name = "nym-sphinx-params" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-crypto", + "nym-sphinx-types", + "serde", + "thiserror", +] + +[[package]] +name = "nym-sphinx-routing" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-sphinx-addressing", + "nym-sphinx-types", + "thiserror", +] + +[[package]] +name = "nym-sphinx-types" +version = "0.2.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "nym-outfox", + "sphinx-packet", + "thiserror", +] + +[[package]] +name = "nym-task" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "log", + "thiserror", + "tokio", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasmtimer", +] + +[[package]] +name = "nym-topology" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "bs58 0.4.0", + "log", + "nym-api-requests", + "nym-bin-common", + "nym-config", + "nym-crypto", + "nym-mixnet-contract-common", + "nym-sphinx-addressing", + "nym-sphinx-routing", + "nym-sphinx-types", + "rand 0.7.3", + "semver 0.11.0", + "serde", + "serde_json", + "thiserror", +] + +[[package]] +name = "nym-validator-client" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "async-trait", + "base64 0.13.1", + "bip32", + "bip39", + "colored", + "cosmrs", + "cosmwasm-std", + "cw-controllers", + "cw-utils", + "cw2", + "cw3", + "cw4", + "eyre", + "flate2", + "futures", + "http-api-client", + "itertools 0.10.5", + "log", + "nym-api-requests", + "nym-coconut-bandwidth-contract-common", + "nym-coconut-dkg-common", + "nym-coconut-interface", + "nym-config", + "nym-contracts-common", + "nym-ephemera-common", + "nym-group-contract-common", + "nym-mixnet-contract-common", + "nym-multisig-contract-common", + "nym-name-service-common", + "nym-network-defaults", + "nym-service-provider-directory-common", + "nym-vesting-contract-common", + "openssl", + "prost", + "reqwest", + "serde", + "serde_json", + "sha2 0.9.9", + "tendermint-rpc", + "thiserror", + "tokio", + "url", + "wasmtimer", + "zeroize", +] + +[[package]] +name = "nym-vesting-contract-common" +version = "0.7.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "cosmwasm-schema", + "cosmwasm-std", + "nym-contracts-common", + "nym-mixnet-contract-common", + "serde", + "thiserror", +] + +[[package]] +name = "nym-wireguard-types" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "base64 0.21.7", + "boringtun", + "bytes", + "dashmap", + "ip_network", + "ip_network_table", + "log", + "nym-crypto", + "serde", + "thiserror", + "tokio", + "x25519-dalek 2.0.0", +] + +[[package]] +name = "object" +version = "0.32.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" + +[[package]] +name = "oneshot-uniffi" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c548d5c78976f6955d72d0ced18c48ca07030f7a1d4024529fedd7c1c01b29c" + +[[package]] +name = "opaque-debug" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c" + +[[package]] +name = "opaque-debug" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" + +[[package]] +name = "openssl" +version = "0.10.62" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cde4d2d9200ad5909f8dac647e29482e07c3a35de8a13fce7c9c7747ad9f671" +dependencies = [ + "bitflags 2.4.2", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "openssl-probe" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" + +[[package]] +name = "openssl-src" +version = "300.2.1+3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fe476c29791a5ca0d1273c697e96085bbabbbea2ef7afd5617e78a4b40332d3" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.98" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1665caf8ab2dc9aef43d1c0023bd904633a6a05cb30b0ad59bec2ae986e57a7" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "pairing" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7de9d09263c9966e8196fe0380c9dbbc7ea114b5cf371ba29004bc1f9c6db7f3" +dependencies = [ + "group 0.10.0", +] + +[[package]] +name = "pairing" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2e415e349a3006dd7d9482cdab1c980a845bed1377777d768cb693a44540b42" +dependencies = [ + "group 0.11.0", +] + +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + +[[package]] +name = "parking_lot" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.9", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.4.1", + "smallvec", + "windows-targets 0.48.5", +] + +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pbkdf2" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2" +dependencies = [ + "digest 0.10.7", + "hmac 0.12.1", +] + +[[package]] +name = "peg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07c0b841ea54f523f7aa556956fbd293bcbe06f2e67d2eb732b7278aaf1d166a" +dependencies = [ + "peg-macros", + "peg-runtime", +] + +[[package]] +name = "peg-macros" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5aa52829b8decbef693af90202711348ab001456803ba2a98eb4ec8fb70844c" +dependencies = [ + "peg-runtime", + "proc-macro2", + "quote", +] + +[[package]] +name = "peg-runtime" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c719dcf55f09a3a7e764c6649ab594c18a177e3599c467983cdf644bfc0a4088" + +[[package]] +name = "pem" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd56cbd21fea48d0c440b41cd69c589faacade08c992d9a54e471b79d0fd13eb" +dependencies = [ + "base64 0.13.1", + "once_cell", + "regex", +] + +[[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.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f200d8d83c44a45b21764d1916299752ca035d15ecd46faca3e9a2a2bf6ad06" +dependencies = [ + "memchr", + "thiserror", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcd6ab1236bbdb3a49027e920e693192ebfe8913f6d60e294de57463a493cfde" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a31940305ffc96863a735bef7c7994a00b325a7138fdbc5bda0f1a0476d3275" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pest_meta" +version = "2.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7ff62f5259e53b78d1af898941cdcdccfae7385cf7d793a6e55de5d05bb4b7d" +dependencies = [ + "once_cell", + "pest", + "sha2 0.10.8", +] + +[[package]] +name = "pin-project" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fda4ed1c6c173e3fc7a83629421152e01d7b1f9b7f65fb301e490e8cfc656422" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" + +[[package]] +name = "plain" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4596b6d070b27117e987119b4dac604f3c58cfb0b191112e24771b2faeac1a6" + +[[package]] +name = "platforms" +version = "3.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "626dec3cac7cc0e1577a2ec3fc496277ec2baa084bebad95bb6fdbfae235f84c" + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug 0.3.0", + "universal-hash", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + +[[package]] +name = "pretty_env_logger" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "926d36b9553851b8b0005f1275891b392ee4d2d833852c417ed025477350fb9d" +dependencies = [ + "env_logger", + "log", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.76" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c289cda302b98a28d40c8b3b90498d6e526dd24ac2ecea73e4e491685b94a" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-derive" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efb6c9a1dd1def8e2124d17e83a20af56f1570d6c2d2bd9e266ccb768df3840e" +dependencies = [ + "anyhow", + "itertools 0.11.0", + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "prost-types" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "193898f59edcf43c26227dcd4c8427f00d99d61e95dcde58dabd49fa291d470e" +dependencies = [ + "prost", +] + +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quote" +version = "1.0.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "rand" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03" +dependencies = [ + "getrandom 0.1.16", + "libc", + "rand_chacha 0.2.2", + "rand_core 0.5.1", + "rand_hc", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402" +dependencies = [ + "ppv-lite86", + "rand_core 0.5.1", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_core" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19" +dependencies = [ + "getrandom 0.1.16", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.12", +] + +[[package]] +name = "rand_distr" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9e9532ada3929fb8b2e9dbe28d1e06c9b2cc65813f074fcb6bd5fbefeff9d56" +dependencies = [ + "num-traits", + "rand 0.7.3", +] + +[[package]] +name = "rand_hc" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c" +dependencies = [ + "rand_core 0.5.1", +] + +[[package]] +name = "rayon" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa7237101a77a10773db45d62004a272517633fbcc3df19d96455ede1122e051" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_users" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4" +dependencies = [ + "getrandom 0.2.12", + "libredox", + "thiserror", +] + +[[package]] +name = "regex" +version = "1.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" + +[[package]] +name = "reqwest" +version = "0.11.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b1ae8d9ac08420c66222fb9096fc5de435c3c48542bc5336c51892cffafb41" +dependencies = [ + "base64 0.21.7", + "bytes", + "encoding_rs", + "futures-core", + "futures-util", + "h2", + "http", + "http-body", + "hyper", + "hyper-rustls", + "hyper-tls", + "ipnet", + "js-sys", + "log", + "mime", + "native-tls", + "once_cell", + "percent-encoding", + "pin-project-lite", + "rustls 0.21.10", + "rustls-native-certs", + "rustls-pemfile", + "serde", + "serde_json", + "serde_urlencoded", + "system-configuration", + "tokio", + "tokio-native-tls", + "tokio-rustls 0.24.1", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", + "winreg", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + +[[package]] +name = "ring" +version = "0.16.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" +dependencies = [ + "cc", + "libc", + "once_cell", + "spin 0.5.2", + "untrusted 0.7.1", + "web-sys", + "winapi", +] + +[[package]] +name = "ring" +version = "0.17.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74" +dependencies = [ + "cc", + "getrandom 0.2.12", + "libc", + "spin 0.9.8", + "untrusted 0.9.0", + "windows-sys 0.48.0", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest 0.10.7", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + +[[package]] +name = "rustc_version" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" +dependencies = [ + "semver 1.0.21", +] + +[[package]] +name = "rustix" +version = "0.38.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "322394588aaf33c24007e8bb3238ee3e4c5c09c084ab32bc73890b99ff326bca" +dependencies = [ + "bitflags 2.4.2", + "errno", + "libc", + "linux-raw-sys", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustls" +version = "0.19.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35edb675feee39aec9c99fa5ff985081995a06d594114ae14cbe797ad7b7a6d7" +dependencies = [ + "base64 0.13.1", + "log", + "ring 0.16.20", + "sct 0.6.1", + "webpki 0.21.4", +] + +[[package]] +name = "rustls" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b80e3dec595989ea8510028f30c408a4630db12c9cbb8de34203b89d6577e99" +dependencies = [ + "log", + "ring 0.16.20", + "sct 0.7.1", + "webpki 0.22.4", +] + +[[package]] +name = "rustls" +version = "0.21.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +dependencies = [ + "log", + "ring 0.17.7", + "rustls-webpki", + "sct 0.7.1", +] + +[[package]] +name = "rustls-native-certs" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" +dependencies = [ + "openssl-probe", + "rustls-pemfile", + "schannel", + "security-framework", +] + +[[package]] +name = "rustls-pemfile" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" +dependencies = [ + "base64 0.21.7", +] + +[[package]] +name = "rustls-webpki" +version = "0.101.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "ryu" +version = "1.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "schannel" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fbc91545643bcf3a0bbb6569265615222618bdf33ce4ffbbd13c4bbd4c093534" +dependencies = [ + "windows-sys 0.52.0", +] + +[[package]] +name = "schemars" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +dependencies = [ + "dyn-clone", + "indexmap 1.9.3", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 1.0.109", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "scroll" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04c565b551bafbef4157586fa379538366e4385d42082f255bfd96e4fe8519da" +dependencies = [ + "scroll_derive", +] + +[[package]] +name = "scroll_derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1db149f81d46d2deba7cd3c50772474707729550221e69588478ebf9ada425ae" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "sct" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b362b83898e0e69f38515b82ee15aa80636befe47c3b6d3d89a911e78fc228ce" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "sct" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array 0.14.7", + "pkcs8", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + +[[package]] +name = "semver" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" +dependencies = [ + "serde", +] + +[[package]] +name = "semver-parser" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7" +dependencies = [ + "pest", +] + +[[package]] +name = "serde" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63261df402c67811e9ac6def069e4786148c4563f4b50fd4bf30aa370d626b02" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde-json-wasm" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a15bee9b04dd165c3f4e142628982ddde884c2022a89e8ddf99c4829bf2c3a58" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_bytes" +version = "0.11.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b8497c313fd43ab992087548117643f6fcd935cbf36f176ffda0aacf9591734" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_derive" +version = "1.0.195" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46fe8f8603d81ba86327b23a2e9cdf49e1255fb94a4c5f297f6ee0547178ea2c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_derive_internals" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85bf8229e7920a9f636479437026331ce11aa132b4dde37d121944a44d6e5f3c" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "serde_json" +version = "1.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "176e46fa42316f18edd598015a5166857fc835ec732f5215eac6b7bdbf0a84f4" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serde_repr" +version = "0.1.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b2e6b945e9d3df726b65d6ee24060aff8e3533d431f677a9695db04eff9dfdb" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "serde_spanned" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if", + "cpufeatures", + "digest 0.9.0", + "opaque-debug 0.3.0", +] + +[[package]] +name = "sha2" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "1.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + +[[package]] +name = "siphasher" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2593d31f82ead8df961d8bd23a64c2ccf2eb5dd34b0a34bfb4dd54011c72009e" + +[[package]] +name = "socket2" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" +dependencies = [ + "libc", + "windows-sys 0.48.0", +] + +[[package]] +name = "sphinx-packet" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc43eda802856ee82a7555c7b75ceb9e07451741c7a2f5f23d036020e01189d4" +dependencies = [ + "aes 0.7.5", + "arrayref", + "blake2 0.8.1", + "bs58 0.4.0", + "byteorder", + "chacha", + "curve25519-dalek 3.2.0", + "digest 0.9.0", + "hkdf 0.11.0", + "hmac 0.11.0", + "lioness", + "log", + "rand 0.7.3", + "rand_distr", + "sha2 0.9.9", + "subtle 2.4.1", +] + +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4b7922be017ee70900be125523f38bdd644f4f06a1b16e8fa5a8ee8c34bffd4" +dependencies = [ + "itertools 0.10.5", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlformat" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" +dependencies = [ + "itertools 0.12.0", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b" +dependencies = [ + "sqlx-core 0.5.13", + "sqlx-macros 0.5.13", +] + +[[package]] +name = "sqlx" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8de3b03a925878ed54a954f621e64bf55a3c1bd29652d0d1a17830405350188" +dependencies = [ + "sqlx-core 0.6.3", + "sqlx-macros 0.6.3", +] + +[[package]] +name = "sqlx-core" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5" +dependencies = [ + "ahash 0.7.7", + "atoi 0.4.0", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc 2.1.0", + "crossbeam-queue", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.7.0", + "hex", + "indexmap 1.9.3", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.19.1", + "sha2 0.10.8", + "smallvec", + "sqlformat 0.1.8", + "sqlx-rt 0.5.13", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki 0.21.4", + "webpki-roots 0.21.1", +] + +[[package]] +name = "sqlx-core" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa8241483a83a3f33aa5fff7e7d9def398ff9990b2752b6c6112b83c6d246029" +dependencies = [ + "ahash 0.7.7", + "atoi 1.0.0", + "bitflags 1.3.2", + "byteorder", + "bytes", + "crc 3.0.1", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "hashlink 0.8.4", + "hex", + "indexmap 1.9.3", + "itoa", + "libc", + "libsqlite3-sys", + "log", + "memchr", + "once_cell", + "paste", + "percent-encoding", + "rustls 0.20.9", + "rustls-pemfile", + "sha2 0.10.8", + "smallvec", + "sqlformat 0.2.3", + "sqlx-rt 0.6.3", + "stringprep", + "thiserror", + "tokio-stream", + "url", + "webpki-roots 0.22.6", +] + +[[package]] +name = "sqlx-macros" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1" +dependencies = [ + "dotenv", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.8", + "sqlx-core 0.5.13", + "sqlx-rt 0.5.13", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-macros" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9966e64ae989e7e575b19d7265cb79d7fc3cbbdf179835cb0d716f294c2049c9" +dependencies = [ + "dotenvy", + "either", + "heck", + "once_cell", + "proc-macro2", + "quote", + "sha2 0.10.8", + "sqlx-core 0.6.3", + "sqlx-rt 0.6.3", + "syn 1.0.109", + "url", +] + +[[package]] +name = "sqlx-rt" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.22.0", +] + +[[package]] +name = "sqlx-rt" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "804d3f245f894e61b1e6263c84b23ca675d96753b5abfd5cc8597d86806e8024" +dependencies = [ + "once_cell", + "tokio", + "tokio-rustls 0.23.4", +] + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "subtle" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d67a5a62ba6e01cb2192ff309324cb4875d0c451d55fe2319433abe7a05a8ee" + +[[package]] +name = "subtle" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" + +[[package]] +name = "subtle-encoding" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dcb1ed7b8330c5eed5441052651dd7a12c75e2ed88f2ec024ae1fa3a5e59945" +dependencies = [ + "zeroize", +] + +[[package]] +name = "subtle-ng" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "734676eb262c623cec13c3155096e08d1f8f29adce39ba17948b18dad1e54142" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "system-configuration" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba3a3adc5c275d719af8cb4272ea1c4a6d668a777f37e115f6d11ddbc1c8e0e7" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75fb188eb626b924683e3b95e3a48e63551fcfb51949de2f06a9d91dbee93c9" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01ce4141aa927a6d1bd34a041795abd0db1cccba5d5f24b009f694bdf3a1f3fa" +dependencies = [ + "cfg-if", + "fastrand", + "redox_syscall 0.4.1", + "rustix", + "windows-sys 0.52.0", +] + +[[package]] +name = "tendermint" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc2294fa667c8b548ee27a9ba59115472d0a09c2ba255771092a7f1dcf03a789" +dependencies = [ + "bytes", + "digest 0.10.7", + "ed25519 2.2.3", + "ed25519-consensus", + "flex-error", + "futures", + "k256", + "num-traits", + "once_cell", + "prost", + "prost-types", + "ripemd", + "serde", + "serde_bytes", + "serde_json", + "serde_repr", + "sha2 0.10.8", + "signature 2.2.0", + "subtle 2.4.1", + "subtle-encoding", + "tendermint-proto", + "time", + "zeroize", +] + +[[package]] +name = "tendermint-config" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a25dbe8b953e80f3d61789fbdb83bf9ad6c0ef16df5ca6546f49912542cc137" +dependencies = [ + "flex-error", + "serde", + "serde_json", + "tendermint", + "toml 0.5.11", + "url", +] + +[[package]] +name = "tendermint-proto" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2cc728a4f9e891d71adf66af6ecaece146f9c7a11312288a3107b3e1d6979aaf" +dependencies = [ + "bytes", + "flex-error", + "num-derive", + "num-traits", + "prost", + "prost-types", + "serde", + "serde_bytes", + "subtle-encoding", + "time", +] + +[[package]] +name = "tendermint-rpc" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbf0a4753b46a190f367337e0163d0b552a2674a6bac54e74f9f2cdcde2969b" +dependencies = [ + "async-trait", + "bytes", + "flex-error", + "futures", + "getrandom 0.2.12", + "peg", + "pin-project", + "reqwest", + "semver 1.0.21", + "serde", + "serde_bytes", + "serde_json", + "subtle 2.4.1", + "subtle-encoding", + "tendermint", + "tendermint-config", + "tendermint-proto", + "thiserror", + "time", + "tokio", + "tracing", + "url", + "uuid", + "walkdir", +] + +[[package]] +name = "termcolor" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "thiserror" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.56" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "time" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f657ba42c3f86e7680e53c8cd3af8abbe56b5491790b46e22e19c0d57463583e" +dependencies = [ + "deranged", + "itoa", + "js-sys", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26197e33420244aeb70c3e8c78376ca46571bc4e701e4791c2cd9f57dcb3a43f" +dependencies = [ + "time-core", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.35.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c89b4efa943be685f629b149f53829423f8f5531ea21249408e8e2f8671ec104" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "num_cpus", + "parking_lot 0.12.1", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.48.0", +] + +[[package]] +name = "tokio-macros" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.22.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc6844de72e57df1980054b38be3a9f4702aba4858be64dd700181a8a6d0e1b6" +dependencies = [ + "rustls 0.19.1", + "tokio", + "webpki 0.21.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.23.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59" +dependencies = [ + "rustls 0.20.9", + "tokio", + "webpki 0.22.4", +] + +[[package]] +name = "tokio-rustls" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" +dependencies = [ + "rustls 0.21.10", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" +dependencies = [ + "futures-util", + "log", + "native-tls", + "tokio", + "tokio-native-tls", + "tungstenite", +] + +[[package]] +name = "tokio-util" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "slab", + "tokio", + "tracing", +] + +[[package]] +name = "toml" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" +dependencies = [ + "serde", +] + +[[package]] +name = "toml" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd79e69d3b627db300ff956027cc6c3798cef26d22526befdfcd12feeb6d2257" +dependencies = [ + "serde", + "serde_spanned", + "toml_datetime", + "toml_edit", +] + +[[package]] +name = "toml_datetime" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" +dependencies = [ + "serde", +] + +[[package]] +name = "toml_edit" +version = "0.19.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" +dependencies = [ + "indexmap 2.1.0", + "serde", + "serde_spanned", + "toml_datetime", + "winnow", +] + +[[package]] +name = "tower-service" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" + +[[package]] +name = "tracing" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "tracing-core" +version = "0.1.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +dependencies = [ + "once_cell", +] + +[[package]] +name = "trackable" +version = "0.2.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b98abb9e7300b9ac902cc04920945a874c1973e08c310627cc4458c04b70dd32" +dependencies = [ + "trackable 1.3.0", + "trackable_derive", +] + +[[package]] +name = "trackable" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15bd114abb99ef8cee977e517c8f37aee63f184f2d08e3e6ceca092373369ae" +dependencies = [ + "trackable_derive", +] + +[[package]] +name = "trackable_derive" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebeb235c5847e2f82cfe0f07eb971d1e5f6804b18dac2ae16349cc604380f82f" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "tungstenite" +version = "0.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e3dac10fd62eaf6617d3a904ae222845979aec67c615d1c842b4002c7666fb9" +dependencies = [ + "byteorder", + "bytes", + "data-encoding", + "http", + "httparse", + "log", + "native-tls", + "rand 0.8.5", + "sha1", + "thiserror", + "url", + "utf-8", +] + +[[package]] +name = "typenum" +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" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08f95100a766bf4f8f28f90d77e0a5461bbdb219042e7679bebe79004fed8d75" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-normalization" +version = "0.1.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + +[[package]] +name = "uniffi" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21345172d31092fd48c47fd56c53d4ae9e41c4b1f559fb8c38c1ab1685fd919f" +dependencies = [ + "anyhow", + "camino", + "clap", + "uniffi_bindgen", + "uniffi_build", + "uniffi_core", + "uniffi_macros", +] + +[[package]] +name = "uniffi_bindgen" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd992f2929a053829d5875af1eff2ee3d7a7001cb3b9a46cc7895f2caede6940" +dependencies = [ + "anyhow", + "askama", + "camino", + "cargo_metadata", + "clap", + "fs-err", + "glob", + "goblin", + "heck", + "once_cell", + "paste", + "serde", + "toml 0.5.11", + "uniffi_meta", + "uniffi_testing", + "uniffi_udl", +] + +[[package]] +name = "uniffi_build" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "001964dd3682d600084b3aaf75acf9c3426699bc27b65e96bb32d175a31c74e9" +dependencies = [ + "anyhow", + "camino", + "uniffi_bindgen", +] + +[[package]] +name = "uniffi_checksum_derive" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55137c122f712d9330fd985d66fa61bdc381752e89c35708c13ce63049a3002c" +dependencies = [ + "quote", + "syn 2.0.48", +] + +[[package]] +name = "uniffi_core" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6121a127a3af1665cd90d12dd2b3683c2643c5103281d0fed5838324ca1fad5b" +dependencies = [ + "anyhow", + "bytes", + "camino", + "log", + "once_cell", + "oneshot-uniffi", + "paste", + "static_assertions", +] + +[[package]] +name = "uniffi_macros" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11cf7a58f101fcedafa5b77ea037999b88748607f0ef3a33eaa0efc5392e92e4" +dependencies = [ + "bincode", + "camino", + "fs-err", + "once_cell", + "proc-macro2", + "quote", + "serde", + "syn 2.0.48", + "toml 0.5.11", + "uniffi_build", + "uniffi_meta", +] + +[[package]] +name = "uniffi_meta" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "71dc8573a7b1ac4b71643d6da34888273ebfc03440c525121f1b3634ad3417a2" +dependencies = [ + "anyhow", + "bytes", + "siphasher", + "uniffi_checksum_derive", +] + +[[package]] +name = "uniffi_testing" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "118448debffcb676ddbe8c5305fb933ab7e0123753e659a71dc4a693f8d9f23c" +dependencies = [ + "anyhow", + "camino", + "cargo_metadata", + "fs-err", + "once_cell", +] + +[[package]] +name = "uniffi_udl" +version = "0.25.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "889edb7109c6078abe0e53e9b4070cf74a6b3468d141bdf5ef1bd4d1dc24a1c3" +dependencies = [ + "anyhow", + "uniffi_meta", + "uniffi_testing", + "weedle2", +] + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle 2.4.1", +] + +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf-8" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" + +[[package]] +name = "utf8parse" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a" + +[[package]] +name = "uuid" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc5cf98d8186244414c848017f0e2676b3fcb46807f6668a97dfe67359a3c4b7" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "vergen" +version = "7.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "447f9238a4553957277b3ee09d80babeae0811f1b3baefb093de1c0448437a37" +dependencies = [ + "anyhow", + "cfg-if", + "enum-iterator", + "getset", + "git2", + "rustc_version", + "rustversion", + "thiserror", + "time", +] + +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + +[[package]] +name = "walkdir" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" +dependencies = [ + "same-file", + "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 = "wasi" +version = "0.9.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasm-bindgen" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1223296a201415c7fad14792dbefaace9bd52b62d33453ade1c5b5f07555406" +dependencies = [ + "cfg-if", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcdc935b63408d58a32f8cc9738a0bffd8f05cc7c002086c6ef20b7312ad9dcd" +dependencies = [ + "bumpalo", + "log", + "once_cell", + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bde2032aeb86bdfaecc8b261eef3cba735cc426c1f3a3416d1e0791be95fc461" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3e4c238561b2d428924c49815533a8b9121c664599558a5d9ec51f8a1740a999" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae1abb6806dc1ad9e560ed242107c0f6c84335f1749dd4e8ddb012ebd5e25a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.90" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d91413b1c31d7539ba5ef2451af3f0b833a005eb27a631cec32bc0635a8602b" + +[[package]] +name = "wasm-utils" +version = "0.1.0" +source = "git+https://github.com/nymtech/nym?branch=master#00d47958a7181d0c2ddb0ccb01340bbe216e3b5e" +dependencies = [ + "futures", + "getrandom 0.2.12", + "gloo-net", + "gloo-utils", + "js-sys", + "tungstenite", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wasmtimer" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f656cd8858a5164932d8a90f936700860976ec21eb00e0fe2aa8cab13f6b4cf" +dependencies = [ + "futures", + "js-sys", + "parking_lot 0.12.1", + "pin-utils", + "slab", + "wasm-bindgen", +] + +[[package]] +name = "web-sys" +version = "0.3.67" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "58cd2333b6e0be7a39605f0e255892fd7418a682d8da8fe042fe25128794d2ed" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki" +version = "0.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e38c0608262c46d4a56202ebabdeb094cef7e560ca7a226c6bf055188aa4ea" +dependencies = [ + "ring 0.16.20", + "untrusted 0.7.1", +] + +[[package]] +name = "webpki" +version = "0.22.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed63aea5ce73d0ff405984102c42de94fc55a6b75765d621c65262469b3c9b53" +dependencies = [ + "ring 0.17.7", + "untrusted 0.9.0", +] + +[[package]] +name = "webpki-roots" +version = "0.21.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aabe153544e473b775453675851ecc86863d2a81d786d741f6b76778f2a48940" +dependencies = [ + "webpki 0.21.4", +] + +[[package]] +name = "webpki-roots" +version = "0.22.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87" +dependencies = [ + "webpki 0.22.4", +] + +[[package]] +name = "weedle2" +version = "4.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e79c5206e1f43a2306fd64bdb95025ee4228960f2e6c5a8b173f3caaf807741" +dependencies = [ + "nom", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.0", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" +dependencies = [ + "windows_aarch64_gnullvm 0.52.0", + "windows_aarch64_msvc 0.52.0", + "windows_i686_gnu 0.52.0", + "windows_i686_msvc 0.52.0", + "windows_x86_64_gnu 0.52.0", + "windows_x86_64_gnullvm 0.52.0", + "windows_x86_64_msvc 0.52.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "winnow" +version = "0.5.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7cf47b659b318dccbd69cc4797a39ae128f533dce7902a1096044d1967b9c16" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a0c105152107e3b96f6a00a65e86ce82d9b125230e1c4302940eca58ff71f4f" +dependencies = [ + "curve25519-dalek 3.2.0", + "rand_core 0.5.1", + "zeroize", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb66477291e7e8d2b0ff1bcb900bf29489a9692816d79874bea351e7a8b6de96" +dependencies = [ + "curve25519-dalek 4.1.1", + "rand_core 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] + +[[package]] +name = "zeroize" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.48", +] diff --git a/sdk/ffi/shared/Cargo.toml b/sdk/ffi/shared/Cargo.toml new file mode 100644 index 0000000000..861c8cde16 --- /dev/null +++ b/sdk/ffi/shared/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "nym-ffi-shared" +version = "0.1.0" +edition = "2021" + +# TODO change to load relative + remove this from the workspace exclude list +[dependencies] +# Async runtime +tokio = { version = "1", features = ["full"] } +# Nym clients, addressing, packet format, common tools (logging) +nym-sdk = { git = "https://github.com/nymtech/nym", branch = "master" } +nym-bin-common = { git = "https://github.com/nymtech/nym", branch = "master" } +nym-sphinx-anonymous-replies = { git = "https://github.com/nymtech/nym", branch = "master" } +# static var macro +lazy_static = "1.4.0" +# error handling +anyhow = "1.0.75" +# base58 en/decoding +bs58 = "0.5.0" +# UDL test +uniffi = { version = "0.25.2", features = ["cli"] } + +[build-dependencies] +uniffi = { version = "0.25.2", features = ["build" ] } +uniffi_build = { version = "0.25.2", features=["builtin-bindgen"] } + + diff --git a/sdk/ffi/shared/README.md b/sdk/ffi/shared/README.md new file mode 100644 index 0000000000..bb0dd2e374 --- /dev/null +++ b/sdk/ffi/shared/README.md @@ -0,0 +1,8 @@ +# FFI Shared ()s +This repo contains internal functions and runtime handling to be used by the C/C++ and Go FFI bindings. + +## Usage +Import the library as you would usually - see `../cpp/src/lib.rs` and `../go/src/lib.rs` for example usage. + + + diff --git a/sdk/ffi/shared/src/lib.rs b/sdk/ffi/shared/src/lib.rs new file mode 100644 index 0000000000..98165be276 --- /dev/null +++ b/sdk/ffi/shared/src/lib.rs @@ -0,0 +1,120 @@ +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use anyhow::{anyhow, bail}; +use lazy_static::lazy_static; +use nym_sdk::mixnet::{MixnetClient, MixnetMessageSender, ReconstructedMessage, Recipient}; +use nym_sphinx_anonymous_replies::requests::AnonymousSenderTag; + + +use std::sync::{Arc, Mutex}; +use tokio::runtime::Runtime; + +// NYM_CLIENT: Static reference (only init-ed once) to: +// - Arc: share ownership +// - Mutex: thread-safe way to share data between threads +// - Option: init-ed or not +// RUNTIME: Tokio runtime: no need to pass back to C and deal with raw pointers as it was previously +lazy_static! { + static ref NYM_CLIENT: Arc<Mutex<Option<MixnetClient>>> = Arc::new(Mutex::new(None)); + static ref RUNTIME: Runtime = Runtime::new().unwrap(); +} + +pub fn init_ephemeral_internal() -> anyhow::Result<(), anyhow::Error> { + if NYM_CLIENT.lock().unwrap().as_ref().is_some() { + bail!("client already exists"); + } else { + RUNTIME.block_on(async move { + let init_client = MixnetClient::connect_new().await?; + let mut client = NYM_CLIENT.try_lock(); + if let Ok(ref mut client) = client { + **client = Some(init_client); + } else { + anyhow!("couldnt lock NYM_CLIENT"); + } + Ok::<(), anyhow::Error>(()) + })?; + } + Ok(()) +} + +pub fn get_self_address_internal() -> anyhow::Result<String, anyhow::Error> { + let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); + if client.is_none() { + bail!("Client is not yet initialised"); + } + let nym_client = client + .as_ref() + .ok_or_else(|| anyhow!("could not get client as_ref()"))?; + + Ok(nym_client.nym_address().to_string()) +} + +pub fn send_message_internal( + recipient: Recipient, + message: &str, +) -> anyhow::Result<(), anyhow::Error> { + let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); + if client.is_none() { + bail!("Client is not yet initialised"); + } + let nym_client = client + .as_ref() + .ok_or_else(|| anyhow!("could not get client as_ref()"))?; + + // send message + RUNTIME.block_on(async move { + nym_client.send_plain_message(recipient, message).await?; + Ok::<(), anyhow::Error>(()) + })?; + Ok(()) +} + +pub fn reply_internal( + recipient: AnonymousSenderTag, + message: &str, +) -> anyhow::Result<(), anyhow::Error> { + let client = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); + if client.is_none() { + bail!("Client is not yet initialised"); + } + let nym_client = client + .as_ref() + .ok_or_else(|| anyhow!("could not get client as_ref()"))?; + + RUNTIME.block_on(async move { + nym_client.send_reply(recipient, message).await?; + Ok::<(), anyhow::Error>(()) + })?; + Ok(()) +} + +pub fn listen_for_incoming_internal() -> anyhow::Result<ReconstructedMessage, anyhow::Error> { + let mut binding = NYM_CLIENT.lock().expect("could not lock NYM_CLIENT"); + if binding.is_none() { + bail!("recipient is null"); + } + let client = binding + .as_mut() + .ok_or_else(|| anyhow!("could not get client as_ref()"))?; + + let message = RUNTIME.block_on(async move { + let received = wait_for_non_empty_message(client).await?; + Ok::<ReconstructedMessage, anyhow::Error>(ReconstructedMessage {message: received.message, sender_tag: received.sender_tag}) + })?; + + Ok(message) +} + +pub async fn wait_for_non_empty_message( + client: &mut MixnetClient, +) -> anyhow::Result<ReconstructedMessage> { + while let Some(mut new_message) = client.wait_for_messages().await { + if !new_message.is_empty() { + return new_message + .pop() + .ok_or_else(|| anyhow!("could not get non empty message")); + } + } + bail!("(Rust) did not receive any non-empty message") +} diff --git a/sdk/ffi/shared/uniffi-bindgen.rs b/sdk/ffi/shared/uniffi-bindgen.rs new file mode 100644 index 0000000000..d96eac70f9 --- /dev/null +++ b/sdk/ffi/shared/uniffi-bindgen.rs @@ -0,0 +1,3 @@ +fn main() { + uniffi::uniffi_bindgen_main() +} \ No newline at end of file From 1ebb0c7daa8d6fc53b282ada84b076b24949b90b Mon Sep 17 00:00:00 2001 From: Sachin Kamath <github@skamath.me> Date: Mon, 18 Mar 2024 20:26:56 +0530 Subject: [PATCH 221/394] don't use bigdecimal --- Cargo.lock | 14 ----------- common/commands/Cargo.toml | 1 - .../delegate_to_multiple_mixnodes.rs | 25 ++++++------------- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e9d127ddc5..7dcb192b24 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -646,19 +646,6 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" -[[package]] -name = "bigdecimal" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06619be423ea5bb86c95f087d5707942791a08a85530df0db2209a3ecfb8bc9" -dependencies = [ - "autocfg 1.1.0", - "libm", - "num-bigint", - "num-integer", - "num-traits", -] - [[package]] name = "binascii" version = "0.1.4" @@ -5114,7 +5101,6 @@ version = "1.0.0" dependencies = [ "anyhow", "base64 0.13.1", - "bigdecimal", "bip39", "bs58 0.5.0", "cfg-if", diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 83c1d45fc4..b2ef8bc3ea 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -8,7 +8,6 @@ license.workspace = true [dependencies] anyhow = { workspace = true } base64 = "0.13.0" -bigdecimal = "0.4.2" bip39 = { workspace = true } bs58 = { workspace = true } comfy-table = "6.0.0" diff --git a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs index 3488824052..068b24c5d2 100644 --- a/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs +++ b/common/commands/src/validator/mixnet/delegators/delegate_to_multiple_mixnodes.rs @@ -1,7 +1,6 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use bigdecimal::{BigDecimal, FromPrimitive, ToPrimitive}; use std::cmp::Ordering; use std::collections::{HashMap, HashSet}; use std::fs; @@ -10,7 +9,7 @@ use std::fs::OpenOptions; use clap::Parser; use comfy_table::Table; use csv::WriterBuilder; -use log::{info, warn}; +use log::info; use nym_mixnet_contract_common::ExecuteMsg; use nym_mixnet_contract_common::ExecuteMsg::{DelegateToMixnode, UndelegateFromMixnode}; @@ -65,20 +64,12 @@ impl InputFileReader { anyhow::bail!("Incorrect format: {}", line); } let mix_id = tokens[0].trim().to_string(); - let input_amount = BigDecimal::parse_bytes(tokens[1].trim().as_bytes(), 10) - .ok_or_else(|| anyhow::anyhow!("Invalid number format"))?; - let scaled_amount = input_amount.with_scale(6); + let input_amount = tokens[1] + .trim() + .parse::<u128>() + .map_err(|_| anyhow::anyhow!("'{}' has an invalid amount", line))?; - if scaled_amount > BigDecimal::from(1_000_000) { - warn!("Delegation amount is high. Please make sure your input is in NYM and not unym denomination"); - } - - let smallest_unit_multiplier = BigDecimal::from_u64(1_000_000).unwrap(); // For 6 decimal places - let amount_in_smallest_unit = scaled_amount * smallest_unit_multiplier; - - let amount = amount_in_smallest_unit.to_u128().ok_or_else(|| { - anyhow::anyhow!("Amount after scaling cannot be represented in u128") - })?; + let micro_nym_amount = input_amount * 1_000_000; if !mix_id_set.insert(mix_id.clone()) { anyhow::bail!("Duplicate mix_id found: {}", mix_id); @@ -87,7 +78,7 @@ impl InputFileReader { rows.push(InputFileRow { mix_id, amount: Coin { - amount, + amount: micro_nym_amount, denom: "unym".to_string(), }, }); @@ -337,7 +328,7 @@ pub async fn delegate_to_multiple_mixnodes(args: Args, client: SigningClient) { delegation_msgs, None, format!( - "Delegatations to {} nodes via nym-cli", + "Delegatation to {} nodes via nym-cli", undelegation_msgs.len() ), ) From 682db85268cc7c27899d9c460825b90cf6b4a6be Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 19 Mar 2024 12:46:17 +0000 Subject: [PATCH 222/394] try to fix rpc endpoint --- explorer/src/components/Delegations/DelegateModal.tsx | 2 +- explorer/src/context/cosmos-kit.tsx | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx index 9ebf719661..3fb9a34ec7 100644 --- a/explorer/src/components/Delegations/DelegateModal.tsx +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -73,7 +73,7 @@ export const DelegateModal: FCWithChildren<{ const tx = await handleDelegate(delegationMixId, delegationAmount); return tx; } catch (e) { - console.error('Failed to delegateToMixnode', e); + console.error('Failed to delegate to mixnode', e); throw e; } }; diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 4e002ea379..56d0bad63d 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -47,6 +47,13 @@ const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( projectId: WALLET_CONNECT_PROJECT_ID, }, }} + endpointOptions={{ + endpoints: { + nyx: { + rpc: ['https://rpc.nyx.nodes.guru'], + }, + }, + }} > {children} </ChainProvider> From b6cd9b2bae4619ea9602a81a6979c147814a7741 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 19 Mar 2024 14:37:10 +0000 Subject: [PATCH 223/394] add leap wallet --- explorer/package.json | 1 + explorer/src/context/cosmos-kit.tsx | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/explorer/package.json b/explorer/package.json index cccb3bc8a6..896094c0d9 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -30,6 +30,7 @@ "@cosmos-kit/core": "^2.8.9", "@cosmos-kit/cosmostation": "^2.6.10", "@cosmos-kit/keplr": "^2.6.9", + "@cosmos-kit/leap": "^2.6.12", "@cosmos-kit/ledger": "^2.6.9", "@cosmos-kit/react": "^2.10.10", "@emotion/react": "^11.4.1", diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 56d0bad63d..5a6399ce19 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -3,6 +3,7 @@ import { ChainProvider } from '@cosmos-kit/react'; import { wallets as keplr } from '@cosmos-kit/keplr'; import { wallets as ledger } from '@cosmos-kit/ledger'; import { wallets as cosmosstation } from '@cosmos-kit/cosmostation'; +import { wallets as leap } from '@cosmos-kit/leap'; import { assets, chains } from 'chain-registry'; import { Chain, AssetList } from '@chain-registry/types'; import { WALLET_CONNECT_PROJECT_ID } from '@src/api/constants'; @@ -41,7 +42,7 @@ const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( <ChainProvider chains={[...chains, nymSandbox]} assetLists={[...assets, nymSandboxAssets]} - wallets={[...keplr, ...ledger, ...cosmosstation]} + wallets={[...keplr, ...ledger, ...cosmosstation, ...leap]} walletConnectOptions={{ signClient: { projectId: WALLET_CONNECT_PROJECT_ID, From 5f98364e6f1d76db90bd0764d2c84e4d9df6441b Mon Sep 17 00:00:00 2001 From: Drazen Urch <drazen@urch.eu> Date: Tue, 19 Mar 2024 17:02:55 +0100 Subject: [PATCH 224/394] Add Gateways to prom-targets (#4483) --- scripts/prom_targets.py | 83 +++++++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/scripts/prom_targets.py b/scripts/prom_targets.py index 5c76c9d0d6..e7887e1ed1 100644 --- a/scripts/prom_targets.py +++ b/scripts/prom_targets.py @@ -7,13 +7,58 @@ from collections import namedtuple Config = namedtuple("Config", ["port", "outfile", "outlink", "env"]) +def gateway_targets(entry): + targets = [ + # Config( + # None, + # "/tmp/temp_targets_gateway.json", + # f"/tmp/prom_targets_gateway_{entry['env']}.json", + # entry["env"], + # ), + Config( + 9100, + "/tmp/temp_targets_gateway_node.json", + f"/tmp/prom_targets_gateway_node_{entry['env']}.json", + entry["env"], + ), + ] + + gateways = requests.get(f"{entry['nym_api']}/api/v1/gateways").json() + + for config in targets: + config_to_targets(config, gateways, {"kind": "gateway"}) + + +def mixnode_targets(entry): + targets = [ + Config( + None, + "/tmp/temp_targets_mix.json", + f"/tmp/prom_targets_mix_{entry['env']}.json", + entry["env"], + ), + Config( + 9100, + "/tmp/temp_targets_node.json", + f"/tmp/prom_targets_node_{entry['env']}.json", + entry["env"], + ), + ] + + mixnodes = requests.get(f"{entry['nym_api']}/api/v1/mixnodes").json() + + for config in targets: + config_to_targets(config, mixnodes, {"kind": "mixnode"}) + + def validate_config_entry(entry): return entry.get("nym_api") and entry.get("env") -def config_to_targets(config, mixnodes): +def config_to_targets(config, mixnodes, labels=None): prom_targets = [ - make_prom_target(config.env, mixnode, config.port) for mixnode in mixnodes + make_prom_target(config.env, mixnode, config.port, labels) + for mixnode in mixnodes ] with open(config.outfile, "w") as f: json.dump(prom_targets, f) @@ -25,7 +70,7 @@ def config_to_targets(config, mixnodes): print(f"Prometheus -> {len(prom_targets)} targets written to {config.outlink}") -def make_prom_target(env, mixnode, port=None): +def make_prom_target(env, mixnode, port=None, labels=None): bond_info = mixnode.get("bond_information", {}) mix_node = bond_info.get("mix_node", {}) host = mix_node.get("host", None) @@ -33,7 +78,7 @@ def make_prom_target(env, mixnode, port=None): if host is None or port is None: return None - return { + target = { "targets": [f"{host}:{port}"], "labels": { "mix_node_host": host, @@ -44,6 +89,11 @@ def make_prom_target(env, mixnode, port=None): }, } + for k, v in labels.items(): + target["labels"][k] = v + + return target + if __name__ == "__main__": parser = argparse.ArgumentParser( @@ -62,27 +112,6 @@ if __name__ == "__main__": config = json.load(f) for entry in config: + mixnode_targets(entry) - if not validate_config_entry(entry): - print(f"Invalid config entry: {entry}") - continue - - targets = [ - Config( - None, - "/tmp/temp_targets_mix.json", - f"/tmp/prom_targets_mix_{entry['env']}.json", - entry["env"], - ), - Config( - 9100, - "/tmp/temp_targets_node.json", - f"/tmp/prom_targets_node_{entry['env']}.json", - entry["env"], - ), - ] - - mixnodes = requests.get(f"{entry['nym_api']}/api/v1/mixnodes").json() - - for config in targets: - config_to_targets(config, mixnodes) + gateway_targets(entry) From 2195310d06c5b16c8c9d9e9e5621ea4dd626e1c7 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 19 Mar 2024 15:22:39 +0000 Subject: [PATCH 225/394] remove walletconnect (for now) --- explorer/package.json | 6 +- explorer/src/context/cosmos-kit.tsx | 14 +- yarn.lock | 427 ++-------------------------- 3 files changed, 37 insertions(+), 410 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index 896094c0d9..377c5d1c4e 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -28,9 +28,9 @@ "@cosmjs/stargate": "^0.32.0", "@cosmjs/tendermint-rpc": "^0.32.0", "@cosmos-kit/core": "^2.8.9", - "@cosmos-kit/cosmostation": "^2.6.10", - "@cosmos-kit/keplr": "^2.6.9", - "@cosmos-kit/leap": "^2.6.12", + "@cosmos-kit/cosmostation-extension": "^2.7.10", + "@cosmos-kit/keplr-extension": "^2.7.9", + "@cosmos-kit/leap-extension": "^2.7.10", "@cosmos-kit/ledger": "^2.6.9", "@cosmos-kit/react": "^2.10.10", "@emotion/react": "^11.4.1", diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 5a6399ce19..3069882fa5 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -1,12 +1,11 @@ import React from 'react'; import { ChainProvider } from '@cosmos-kit/react'; -import { wallets as keplr } from '@cosmos-kit/keplr'; +import { wallets as keplr } from '@cosmos-kit/keplr-extension'; import { wallets as ledger } from '@cosmos-kit/ledger'; -import { wallets as cosmosstation } from '@cosmos-kit/cosmostation'; -import { wallets as leap } from '@cosmos-kit/leap'; +import { wallets as cosmosstation } from '@cosmos-kit/cosmostation-extension'; +import { wallets as leap } from '@cosmos-kit/leap-extension'; import { assets, chains } from 'chain-registry'; import { Chain, AssetList } from '@chain-registry/types'; -import { WALLET_CONNECT_PROJECT_ID } from '@src/api/constants'; const nymSandbox: Chain = { chain_name: 'sandbox', @@ -43,15 +42,10 @@ const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( chains={[...chains, nymSandbox]} assetLists={[...assets, nymSandboxAssets]} wallets={[...keplr, ...ledger, ...cosmosstation, ...leap]} - walletConnectOptions={{ - signClient: { - projectId: WALLET_CONNECT_PROJECT_ID, - }, - }} endpointOptions={{ endpoints: { nyx: { - rpc: ['https://rpc.nyx.nodes.guru'], + rpc: ['https://rpc.nymtech.net'], }, }, }} diff --git a/yarn.lock b/yarn.lock index 9051f41ec8..7a0aa40538 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,16 +1267,6 @@ bfs-path "^1.0.2" cross-fetch "^3.1.5" -"@chain-registry/cosmostation@1.26.0": - version "1.26.0" - resolved "https://registry.yarnpkg.com/@chain-registry/cosmostation/-/cosmostation-1.26.0.tgz#0d3967b8d320168a5c9c7b56b3352dcf3f2945b0" - integrity sha512-MmjThpQ0U0EJF66UJzPy67iKC9hY7ljrpGtQOPfeYGB/lUlKZTsE/mgF2XkKGUf7wJK8LugOqU5Zul7C1/ZA4Q== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.17.0" - "@chain-registry/utils" "^1.15.0" - "@cosmostation/extension-client" "0.1.15" - "@chain-registry/cosmostation@^1.26.0": version "1.32.1" resolved "https://registry.yarnpkg.com/@chain-registry/cosmostation/-/cosmostation-1.32.1.tgz#bdf079a4f45b5c884a33c48fb0b8d4eeaa26a743" @@ -1319,16 +1309,6 @@ dependencies: "@babel/runtime" "^7.21.0" -"@chain-registry/utils@^1.15.0", "@chain-registry/utils@^1.18.2": - version "1.18.2" - resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.2.tgz#fa67e8179afad45011c031a1181824133412e6c6" - integrity sha512-X1vBFxdMVRGFW/6fLUQgJ4aG/2RaDYDDEeDA5/x/MlssGtdSBEyytd7M9zO0uS51QYy1ysIhkG3OyZLoyGdurg== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.18.1" - bignumber.js "9.1.1" - sha.js "^2.4.11" - "@chain-registry/utils@^1.18.0": version "1.18.0" resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.0.tgz#d711efc2660b3b65077a5bee90b45ddc6af2194f" @@ -1339,6 +1319,16 @@ bignumber.js "9.1.1" sha.js "^2.4.11" +"@chain-registry/utils@^1.18.2": + version "1.18.2" + resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.2.tgz#fa67e8179afad45011c031a1181824133412e6c6" + integrity sha512-X1vBFxdMVRGFW/6fLUQgJ4aG/2RaDYDDEeDA5/x/MlssGtdSBEyytd7M9zO0uS51QYy1ysIhkG3OyZLoyGdurg== + dependencies: + "@babel/runtime" "^7.21.0" + "@chain-registry/types" "^0.18.1" + bignumber.js "9.1.1" + sha.js "^2.4.11" + "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1650,18 +1640,6 @@ dependencies: bn.js "^5.2.0" -"@cosmjs/proto-signing@0.32.2", "@cosmjs/proto-signing@^0.32.2": - version "0.32.2" - resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.2.tgz#26ed2675978ce24078981f4c15a06c5d6b808f44" - integrity sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw== - dependencies: - "@cosmjs/amino" "^0.32.2" - "@cosmjs/crypto" "^0.32.2" - "@cosmjs/encoding" "^0.32.2" - "@cosmjs/math" "^0.32.2" - "@cosmjs/utils" "^0.32.2" - cosmjs-types "^0.9.0" - "@cosmjs/proto-signing@^0.25.5", "@cosmjs/proto-signing@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.25.6.tgz#d9fc57b8e0a46cda97e192bd0435157b24949ff8" @@ -1696,6 +1674,18 @@ "@cosmjs/utils" "^0.32.1" cosmjs-types "^0.9.0" +"@cosmjs/proto-signing@^0.32.2": + version "0.32.2" + resolved "https://registry.yarnpkg.com/@cosmjs/proto-signing/-/proto-signing-0.32.2.tgz#26ed2675978ce24078981f4c15a06c5d6b808f44" + integrity sha512-UV4WwkE3W3G3s7wwU9rizNcUEz2g0W8jQZS5J6/3fiN0mRPwtPKQ6EinPN9ASqcAJ7/VQH4/9EPOw7d6XQGnqw== + dependencies: + "@cosmjs/amino" "^0.32.2" + "@cosmjs/crypto" "^0.32.2" + "@cosmjs/encoding" "^0.32.2" + "@cosmjs/math" "^0.32.2" + "@cosmjs/utils" "^0.32.2" + cosmjs-types "^0.9.0" + "@cosmjs/socket@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/socket/-/socket-0.25.6.tgz#7876bc24e1f16315fbb9e97bd63dea65ba90647d" @@ -1939,23 +1929,6 @@ "@cosmos-kit/core" "^2.8.9" cosmjs-types "^0.9.0" -"@cosmos-kit/cosmostation-mobile@^2.6.9": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation-mobile/-/cosmostation-mobile-2.6.9.tgz#1c304ac12cccc05de93c9ed927243d51087426f6" - integrity sha512-GjZetNMFrz2oLisdp14ahxftkwPz5v1OYRGvD4MLTdMSA71JUTzX8A4At4uo4M7nwG09H1yQ2/CLQy9XGVRinA== - dependencies: - "@chain-registry/cosmostation" "1.26.0" - "@cosmos-kit/core" "^2.8.9" - "@cosmos-kit/walletconnect" "^2.5.9" - -"@cosmos-kit/cosmostation@^2.6.10": - version "2.6.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation/-/cosmostation-2.6.10.tgz#406d93a29c154e988f4d60425d8edbba4f0cd455" - integrity sha512-DWR28fnkv04yr5Eyo/CS7yOiYr3cwld9lE/F2qGIYGb2Tw/eUWhKSl05+2ly8S15xoKOXT7wxXOsFIXYYUQ8/g== - dependencies: - "@cosmos-kit/cosmostation-extension" "^2.7.10" - "@cosmos-kit/cosmostation-mobile" "^2.6.9" - "@cosmos-kit/keplr-extension@^2.7.9": version "2.7.9" resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.7.9.tgz#16586c94452a5e65713cdead07446447c511fa0e" @@ -1965,22 +1938,13 @@ "@cosmos-kit/core" "^2.8.9" "@keplr-wallet/types" "^0.12.58" -"@cosmos-kit/keplr-mobile@^2.6.9": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-mobile/-/keplr-mobile-2.6.9.tgz#28fcdffc8da11c34a2ece2bbef58e29dc68d0df3" - integrity sha512-kw0g/TOBKMJMDiIld2wZ7Id47hUA7G3tauijSwbMC+scXnnmOCKZ1x0lRUvW13onV7SiRT21sOm7msl8XwUlgQ== +"@cosmos-kit/leap-extension@^2.7.10": + version "2.7.10" + resolved "https://registry.yarnpkg.com/@cosmos-kit/leap-extension/-/leap-extension-2.7.10.tgz#ff109ead4358f9cbe0b5a727733689d2bea3a60a" + integrity sha512-vVMkF+64oMFLbrw244AxoUR4vrFSKlOHhFHw7wOEHfeTSdvX4mcCsU8CC1LtVV5Bc0msVdkNWVbE04VEump8rg== dependencies: "@chain-registry/keplr" "1.28.0" "@cosmos-kit/core" "^2.8.9" - "@cosmos-kit/walletconnect" "^2.5.9" - -"@cosmos-kit/keplr@^2.6.9": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr/-/keplr-2.6.9.tgz#d861f8ea4471fc72f54c19e287623341e586e8a2" - integrity sha512-HW+WhELS1dHokSq58NDNCIQaA0xRrg293uKM989XQgDOgD/xsEaRrwwTaj3guOXxVm8BE51PLTFbZesHhflmaQ== - dependencies: - "@cosmos-kit/keplr-extension" "^2.7.9" - "@cosmos-kit/keplr-mobile" "^2.6.9" "@cosmos-kit/ledger@^2.6.9": version "2.6.9" @@ -2010,17 +1974,6 @@ "@cosmos-kit/react-lite" "^2.6.9" "@react-icons/all-files" "^4.1.0" -"@cosmos-kit/walletconnect@^2.5.9": - version "2.5.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/walletconnect/-/walletconnect-2.5.9.tgz#10c9b6f0077801e39eedf89092deb6310b47d746" - integrity sha512-wQ3qR75Q5ZpUZMO96FwBVSuLme4z4mZ8OD8fFgs1QM16Kn81+oQ00kXDT/MkokDAVCdz91qS4XHxQEAvxSm0qw== - dependencies: - "@cosmjs/proto-signing" "0.32.2" - "@cosmos-kit/core" "^2.8.9" - "@walletconnect/sign-client" "^2.9.0" - "@walletconnect/utils" "^2.9.0" - events "3.3.0" - "@cosmostation/extension-client@0.1.15": version "0.1.15" resolved "https://registry.yarnpkg.com/@cosmostation/extension-client/-/extension-client-0.1.15.tgz#cdc6d8fce42217704c1c0d5814f0ee7ce27e8dab" @@ -4993,140 +4946,6 @@ dependencies: "@sinonjs/commons" "^1.7.0" -"@stablelib/aead@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" - integrity sha512-q39ik6sxGHewqtO0nP4BuSe3db5G1fEJE8ukvngS2gLkBXyy6E7pLubhbYgnkDFv6V8cWaxcE4Xn0t6LWcJkyg== - -"@stablelib/binary@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/binary/-/binary-1.0.1.tgz#c5900b94368baf00f811da5bdb1610963dfddf7f" - integrity sha512-ClJWvmL6UBM/wjkvv/7m5VP3GMr9t0osr4yVgLZsLCOz4hGN9gIAFEqnJ0TsSMAN+n840nf2cHZnA5/KFqHC7Q== - dependencies: - "@stablelib/int" "^1.0.1" - -"@stablelib/bytes@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/bytes/-/bytes-1.0.1.tgz#0f4aa7b03df3080b878c7dea927d01f42d6a20d8" - integrity sha512-Kre4Y4kdwuqL8BR2E9hV/R5sOrUj6NanZaZis0V6lX5yzqC3hBuVSDXUIBqQv/sCpmuWRiHLwqiT1pqqjuBXoQ== - -"@stablelib/chacha20poly1305@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha20poly1305/-/chacha20poly1305-1.0.1.tgz#de6b18e283a9cb9b7530d8767f99cde1fec4c2ee" - integrity sha512-MmViqnqHd1ymwjOQfghRKw2R/jMIGT3wySN7cthjXCBdO+qErNPUBnRzqNpnvIwg7JBCg3LdeCZZO4de/yEhVA== - dependencies: - "@stablelib/aead" "^1.0.1" - "@stablelib/binary" "^1.0.1" - "@stablelib/chacha" "^1.0.1" - "@stablelib/constant-time" "^1.0.1" - "@stablelib/poly1305" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/chacha@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/chacha/-/chacha-1.0.1.tgz#deccfac95083e30600c3f92803a3a1a4fa761371" - integrity sha512-Pmlrswzr0pBzDofdFuVe1q7KdsHKhhU24e8gkEwnTGOmlC7PADzLVxGdn2PoNVBBabdg0l/IfLKg6sHAbTQugg== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/constant-time@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/constant-time/-/constant-time-1.0.1.tgz#bde361465e1cf7b9753061b77e376b0ca4c77e35" - integrity sha512-tNOs3uD0vSJcK6z1fvef4Y+buN7DXhzHDPqRLSXUel1UfqMB1PWNsnnAezrKfEwTLpN0cGH2p9NNjs6IqeD0eg== - -"@stablelib/ed25519@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/ed25519/-/ed25519-1.0.3.tgz#f8fdeb6f77114897c887bb6a3138d659d3f35996" - integrity sha512-puIMWaX9QlRsbhxfDc5i+mNPMY+0TmQEskunY1rZEBPi1acBCVQAhnsk/1Hk50DGPtVsZtAWQg4NHGlVaO9Hqg== - dependencies: - "@stablelib/random" "^1.0.2" - "@stablelib/sha512" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/hash@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hash/-/hash-1.0.1.tgz#3c944403ff2239fad8ebb9015e33e98444058bc5" - integrity sha512-eTPJc/stDkdtOcrNMZ6mcMK1e6yBbqRBaNW55XA1jU8w/7QdnCF0CmMmOD1m7VSkBR44PWrMHU2l6r8YEQHMgg== - -"@stablelib/hkdf@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hkdf/-/hkdf-1.0.1.tgz#b4efd47fd56fb43c6a13e8775a54b354f028d98d" - integrity sha512-SBEHYE16ZXlHuaW5RcGk533YlBj4grMeg5TooN80W3NpcHRtLZLLXvKyX0qcRFxf+BGDobJLnwkvgEwHIDBR6g== - dependencies: - "@stablelib/hash" "^1.0.1" - "@stablelib/hmac" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/hmac@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/hmac/-/hmac-1.0.1.tgz#3d4c1b8cf194cb05d28155f0eed8a299620a07ec" - integrity sha512-V2APD9NSnhVpV/QMYgCVMIYKiYG6LSqw1S65wxVoirhU/51ACio6D4yDVSwMzuTJXWZoVHbDdINioBwKy5kVmA== - dependencies: - "@stablelib/constant-time" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/int@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/int/-/int-1.0.1.tgz#75928cc25d59d73d75ae361f02128588c15fd008" - integrity sha512-byr69X/sDtDiIjIV6m4roLVWnNNlRGzsvxw+agj8CIEazqWGOQp2dTYgQhtyVXV9wpO6WyXRQUzLV/JRNumT2w== - -"@stablelib/keyagreement@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/keyagreement/-/keyagreement-1.0.1.tgz#4612efb0a30989deb437cd352cee637ca41fc50f" - integrity sha512-VKL6xBwgJnI6l1jKrBAfn265cspaWBPAPEc62VBQrWHLqVgNRE09gQ/AnOEyKUWrrqfD+xSQ3u42gJjLDdMDQg== - dependencies: - "@stablelib/bytes" "^1.0.1" - -"@stablelib/poly1305@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/poly1305/-/poly1305-1.0.1.tgz#93bfb836c9384685d33d70080718deae4ddef1dc" - integrity sha512-1HlG3oTSuQDOhSnLwJRKeTRSAdFNVB/1djy2ZbS35rBSJ/PFqx9cf9qatinWghC2UbfOYD8AcrtbUQl8WoxabA== - dependencies: - "@stablelib/constant-time" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/random@^1.0.1", "@stablelib/random@^1.0.2": - version "1.0.2" - resolved "https://registry.yarnpkg.com/@stablelib/random/-/random-1.0.2.tgz#2dece393636489bf7e19c51229dd7900eddf742c" - integrity sha512-rIsE83Xpb7clHPVRlBj8qNe5L8ISQOzjghYQm/dZ7VaM2KHYwMW5adjQjrzTZCchFnNCNhkwtnOBa9HTMJCI8w== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/sha256@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha256/-/sha256-1.0.1.tgz#77b6675b67f9b0ea081d2e31bda4866297a3ae4f" - integrity sha512-GIIH3e6KH+91FqGV42Kcj71Uefd/QEe7Dy42sBTeqppXV95ggCcxLTk39bEr+lZfJmp+ghsR07J++ORkRELsBQ== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/sha512@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/sha512/-/sha512-1.0.1.tgz#6da700c901c2c0ceacbd3ae122a38ac57c72145f" - integrity sha512-13gl/iawHV9zvDKciLo1fQ8Bgn2Pvf7OV6amaRVKiq3pjQ3UmEpXxWiAfV8tYjUpeZroBxtyrwtdooQT/i3hzw== - dependencies: - "@stablelib/binary" "^1.0.1" - "@stablelib/hash" "^1.0.1" - "@stablelib/wipe" "^1.0.1" - -"@stablelib/wipe@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@stablelib/wipe/-/wipe-1.0.1.tgz#d21401f1d59ade56a62e139462a97f104ed19a36" - integrity sha512-WfqfX/eXGiAd3RJe4VU2snh/ZPwtSjLG4ynQ/vYzvghTh7dHFcI1wl+nrkWG6lGhukOxOsUHfv8dUXr58D0ayg== - -"@stablelib/x25519@^1.0.3": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@stablelib/x25519/-/x25519-1.0.3.tgz#13c8174f774ea9f3e5e42213cbf9fc68a3c7b7fd" - integrity sha512-KnTbKmUhPhHavzobclVJQG5kuivH+qDLpe84iRqX3CLrKp881cF160JvXJ+hjn1aMyCwYOKeIZefIH/P5cJoRw== - dependencies: - "@stablelib/keyagreement" "^1.0.1" - "@stablelib/random" "^1.0.2" - "@stablelib/wipe" "^1.0.1" - "@storybook/addon-actions@6.5.16", "@storybook/addon-actions@^6.5.8": version "6.5.16" resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.16.tgz#2d7679f64899bef165a338582cb928102a09e364" @@ -7329,35 +7148,6 @@ loupe "^2.3.6" pretty-format "^29.5.0" -"@walletconnect/core@2.10.6": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.10.6.tgz#786b0d2e2045c210c917e29bfa0498bbc210be20" - integrity sha512-Z4vh4ZdfcoQjgPEOxeuF9HUZCVLtV3MgRbS/awLIj/omDrFnOwlBhxi5Syr4Y8muVGC0ocRetQYHae0/gX5crQ== - dependencies: - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-provider" "1.0.13" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/jsonrpc-ws-connection" "1.0.14" - "@walletconnect/keyvaluestorage" "^1.1.1" - "@walletconnect/logger" "^2.0.1" - "@walletconnect/relay-api" "^1.0.9" - "@walletconnect/relay-auth" "^1.0.4" - "@walletconnect/safe-json" "^1.0.2" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/utils" "2.10.6" - events "^3.3.0" - lodash.isequal "4.5.0" - uint8arrays "^3.1.0" - -"@walletconnect/environment@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" - integrity sha512-T426LLZtHj8e8rYnKfzsw1aG6+M0BT1ZxayMdv/p8yM0MU+eJDISqNY3/bccxRr4LrF9csq02Rhqt08Ibl0VRg== - dependencies: - tslib "1.14.1" - "@walletconnect/events@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/events/-/events-1.0.1.tgz#2b5f9c7202019e229d7ccae1369a9e86bda7816c" @@ -7375,16 +7165,7 @@ "@walletconnect/time" "^1.0.2" tslib "1.14.1" -"@walletconnect/jsonrpc-provider@1.0.13": - version "1.0.13" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-provider/-/jsonrpc-provider-1.0.13.tgz#9a74da648d015e1fffc745f0c7d629457f53648b" - integrity sha512-K73EpThqHnSR26gOyNEL+acEex3P7VWZe6KE12ZwKzAt2H4e5gldZHbjsu2QR9cLeJ8AXuO7kEMOIcRv1QEc7g== - dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.8" - "@walletconnect/safe-json" "^1.0.2" - tslib "1.14.1" - -"@walletconnect/jsonrpc-types@1.0.3", "@walletconnect/jsonrpc-types@^1.0.2", "@walletconnect/jsonrpc-types@^1.0.3": +"@walletconnect/jsonrpc-types@1.0.3": version "1.0.3" resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-types/-/jsonrpc-types-1.0.3.tgz#65e3b77046f1a7fa8347ae02bc1b841abe6f290c" integrity sha512-iIQ8hboBl3o5ufmJ8cuduGad0CQm3ZlsHtujv9Eu16xq89q+BG7Nh5VLxxUgmtpnrePgFkTwXirCTkwJH1v+Yw== @@ -7392,25 +7173,6 @@ keyvaluestorage-interface "^1.0.0" tslib "1.14.1" -"@walletconnect/jsonrpc-utils@1.0.8", "@walletconnect/jsonrpc-utils@^1.0.6", "@walletconnect/jsonrpc-utils@^1.0.8": - version "1.0.8" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-utils/-/jsonrpc-utils-1.0.8.tgz#82d0cc6a5d6ff0ecc277cb35f71402c91ad48d72" - integrity sha512-vdeb03bD8VzJUL6ZtzRYsFMq1eZQcM3EAzT0a3st59dyLfJ0wq+tKMpmGH7HlB7waD858UWgfIcudbPFsbzVdw== - dependencies: - "@walletconnect/environment" "^1.0.1" - "@walletconnect/jsonrpc-types" "^1.0.3" - tslib "1.14.1" - -"@walletconnect/jsonrpc-ws-connection@1.0.14": - version "1.0.14" - resolved "https://registry.yarnpkg.com/@walletconnect/jsonrpc-ws-connection/-/jsonrpc-ws-connection-1.0.14.tgz#eec700e74766c7887de2bd76c91a0206628732aa" - integrity sha512-Jsl6fC55AYcbkNVkwNM6Jo+ufsuCQRqViOQ8ZBPH9pRREHH9welbBiszuTLqEJiQcO/6XfFDl6bzCJIkrEi8XA== - dependencies: - "@walletconnect/jsonrpc-utils" "^1.0.6" - "@walletconnect/safe-json" "^1.0.2" - events "^3.3.0" - ws "^7.5.1" - "@walletconnect/keyvaluestorage@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@walletconnect/keyvaluestorage/-/keyvaluestorage-1.1.1.tgz#dd2caddabfbaf80f6b8993a0704d8b83115a1842" @@ -7428,48 +7190,13 @@ pino "7.11.0" tslib "1.14.1" -"@walletconnect/relay-api@^1.0.9": - version "1.0.9" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-api/-/relay-api-1.0.9.tgz#f8c2c3993dddaa9f33ed42197fc9bfebd790ecaf" - integrity sha512-Q3+rylJOqRkO1D9Su0DPE3mmznbAalYapJ9qmzDgK28mYF9alcP3UwG/og5V7l7CFOqzCLi7B8BvcBUrpDj0Rg== - dependencies: - "@walletconnect/jsonrpc-types" "^1.0.2" - tslib "1.14.1" - -"@walletconnect/relay-auth@^1.0.4": - version "1.0.4" - resolved "https://registry.yarnpkg.com/@walletconnect/relay-auth/-/relay-auth-1.0.4.tgz#0b5c55c9aa3b0ef61f526ce679f3ff8a5c4c2c7c" - integrity sha512-kKJcS6+WxYq5kshpPaxGHdwf5y98ZwbfuS4EE/NkQzqrDFm5Cj+dP8LofzWvjrrLkZq7Afy7WrQMXdLy8Sx7HQ== - dependencies: - "@stablelib/ed25519" "^1.0.2" - "@stablelib/random" "^1.0.1" - "@walletconnect/safe-json" "^1.0.1" - "@walletconnect/time" "^1.0.2" - tslib "1.14.1" - uint8arrays "^3.0.0" - -"@walletconnect/safe-json@^1.0.1", "@walletconnect/safe-json@^1.0.2": +"@walletconnect/safe-json@^1.0.1": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/safe-json/-/safe-json-1.0.2.tgz#7237e5ca48046e4476154e503c6d3c914126fa77" integrity sha512-Ogb7I27kZ3LPC3ibn8ldyUr5544t3/STow9+lzz7Sfo808YD7SBWk7SAsdBFlYgP2zDRy2hS3sKRcuSRM0OTmA== dependencies: tslib "1.14.1" -"@walletconnect/sign-client@^2.9.0": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.10.6.tgz#722d2c2844565e2826dce6a6d3a36c9b3ca1ea91" - integrity sha512-EvUWjaZBQu2yKnH5/5F2qzbuiIuUN9ZgrNKgvXkw5z1Dq5RJCks0S9/MFlKH/ZSGqXnLl7uAzBXtoX4sMgbCMA== - dependencies: - "@walletconnect/core" "2.10.6" - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-utils" "1.0.8" - "@walletconnect/logger" "^2.0.1" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/utils" "2.10.6" - events "^3.3.0" - "@walletconnect/time@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" @@ -7477,18 +7204,6 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.10.6": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.10.6.tgz#d9920ed4fd0113e0addbda8e7e73a5176a3163fd" - integrity sha512-WgHfiTG1yakmxheaBRiXhUdEmgxwrvsAdOIWaMf/spvrzVKYh6sHI3oyEEky5qj5jjiMiyQBeB57QamzCotbcQ== - dependencies: - "@walletconnect/events" "^1.0.1" - "@walletconnect/heartbeat" "1.2.1" - "@walletconnect/jsonrpc-types" "1.0.3" - "@walletconnect/keyvaluestorage" "^1.1.1" - "@walletconnect/logger" "^2.0.1" - events "^3.3.0" - "@walletconnect/types@2.11.0": version "2.11.0" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.0.tgz#474a009c56faa9ef4063b76ed84415c801dc9f1e" @@ -7501,41 +7216,6 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" -"@walletconnect/utils@2.10.6", "@walletconnect/utils@^2.9.0": - version "2.10.6" - resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.10.6.tgz#749b37d14e291e346862e7027ec7548463350226" - integrity sha512-oRsWWhN2+hi3aiDXrQEOfysz6FHQJGXLsNQPVt+WIBJplO6Szmdau9dbleD88u1iiT4GKPqE0R9FOYvvPm1H/w== - dependencies: - "@stablelib/chacha20poly1305" "1.0.1" - "@stablelib/hkdf" "1.0.1" - "@stablelib/random" "^1.0.2" - "@stablelib/sha256" "1.0.1" - "@stablelib/x25519" "^1.0.3" - "@walletconnect/relay-api" "^1.0.9" - "@walletconnect/safe-json" "^1.0.2" - "@walletconnect/time" "^1.0.2" - "@walletconnect/types" "2.10.6" - "@walletconnect/window-getters" "^1.0.1" - "@walletconnect/window-metadata" "^1.0.1" - detect-browser "5.3.0" - query-string "7.1.3" - uint8arrays "^3.1.0" - -"@walletconnect/window-getters@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-getters/-/window-getters-1.0.1.tgz#f36d1c72558a7f6b87ecc4451fc8bd44f63cbbdc" - integrity sha512-vHp+HqzGxORPAN8gY03qnbTMnhqIwjeRJNOMOAzePRg4xVEEE2WvYsI9G2NMjOknA8hnuYbU3/hwLcKbjhc8+Q== - dependencies: - tslib "1.14.1" - -"@walletconnect/window-metadata@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@walletconnect/window-metadata/-/window-metadata-1.0.1.tgz#2124f75447b7e989e4e4e1581d55d25bc75f7be5" - integrity sha512-9koTqyGrM2cqFRW517BPY/iEtUDx2r1+Pwwu5m7sJ7ka79wi3EyqhqcICk/yDmv6jAS1rjKgTKXlEhanYjijcA== - dependencies: - "@walletconnect/window-getters" "^1.0.1" - tslib "1.14.1" - "@webassemblyjs/ast@1.11.6", "@webassemblyjs/ast@^1.11.5": version "1.11.6" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.11.6.tgz#db046555d3c413f8966ca50a95176a0e2c642e24" @@ -10671,7 +10351,7 @@ decode-named-character-reference@^1.0.0: dependencies: character-entities "^2.0.0" -decode-uri-component@^0.2.0, decode-uri-component@^0.2.2: +decode-uri-component@^0.2.0: version "0.2.2" resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.2.tgz#e69dbe25d37941171dd540e024c444cd5188e1e9" integrity sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ== @@ -10883,11 +10563,6 @@ detab@2.0.4: dependencies: repeat-string "^1.5.4" -detect-browser@5.3.0: - version "5.3.0" - resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" - integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== - detect-indent@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d" @@ -12320,11 +11995,6 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -filter-obj@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/filter-obj/-/filter-obj-1.1.0.tgz#9b311112bc6c6127a16e016c6c5d7f19e0805c5b" - integrity sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ== - finalhandler@1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" @@ -15661,11 +15331,6 @@ lodash.isarguments@^3.1.0: resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" integrity sha512-chi4NHZlZqZD18a0imDHnZPrDeBbTtVN7GXMwuGdRH9qotxAjYs3aVLKc7zNOG9eddR5Ksd8rvFEBc9SsggPpg== -lodash.isequal@4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" - integrity sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ== - lodash.ismatch@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz#756cb5150ca3ba6f11085a78849645f188f85f37" @@ -16913,11 +16578,6 @@ multicast-dns@^7.2.5: dns-packet "^5.2.2" thunky "^1.0.2" -multiformats@^9.4.2: - version "9.9.0" - resolved "https://registry.yarnpkg.com/multiformats/-/multiformats-9.9.0.tgz#c68354e7d21037a8f1f8833c8ccd68618e8f1d37" - integrity sha512-HoMUjhH9T8DDBNT+6xzkrd9ga/XiBI4xLr58LJACwK6G3HTOPeMz4nB4KJs33L2BelrIJa7P0VuNaVF3hMYfjg== - multimatch@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-5.0.0.tgz#932b800963cea7a31a033328fa1e0c3a1874dbe6" @@ -18896,16 +18556,6 @@ qs@^6.10.0, qs@^6.11.2: dependencies: side-channel "^1.0.4" -query-string@7.1.3: - version "7.1.3" - resolved "https://registry.yarnpkg.com/query-string/-/query-string-7.1.3.tgz#a1cf90e994abb113a325804a972d98276fe02328" - integrity sha512-hh2WYhq4fi8+b+/2Kg9CEge4fDPvHS534aOOvOZeQ3+Vf2mCFsaFBYj0i+iXcAq6I9Vzp5fjMFBlONvayDC1qg== - dependencies: - decode-uri-component "^0.2.2" - filter-obj "^1.1.0" - split-on-first "^1.0.0" - strict-uri-encode "^2.0.0" - querystring-es3@^0.2.0: version "0.2.1" resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" @@ -20584,11 +20234,6 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -split-on-first@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" - integrity sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw== - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -20750,11 +20395,6 @@ streamx@^2.15.0: fast-fifo "^1.1.0" queue-tick "^1.0.1" -strict-uri-encode@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" - integrity sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ== - string-length@^4.0.1: version "4.0.2" resolved "https://registry.yarnpkg.com/string-length/-/string-length-4.0.2.tgz#a8a8dc7bd5c1a82b9b3c8b87e125f66871b6e57a" @@ -21818,13 +21458,6 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== -uint8arrays@^3.0.0, uint8arrays@^3.1.0: - version "3.1.1" - resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" - integrity sha512-+QJa8QRnbdXVpHYjLoTpJIdCTiw9Ir62nocClWuXIq2JIh4Uta0cQsTSpFL678p2CN8B+XSApwcU+pQEqVpKWg== - dependencies: - multiformats "^9.4.2" - unbox-primitive@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" @@ -22999,7 +22632,7 @@ write-pkg@4.0.0: type-fest "^0.4.1" write-json-file "^3.2.0" -ws@^7, ws@^7.4.6, ws@^7.5.1: +ws@^7, ws@^7.4.6: version "7.5.9" resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== From 01e4abc95f6fdd0445b53ab4d1d4c4d66babfce9 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 19 Mar 2024 21:03:11 +0000 Subject: [PATCH 226/394] Update width of confirmation modal --- explorer/src/pages/Delegations/index.tsx | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx index 6ae159b02b..3305b542df 100644 --- a/explorer/src/pages/Delegations/index.tsx +++ b/explorer/src/pages/Delegations/index.tsx @@ -184,6 +184,12 @@ const DelegationsPage = () => { } setConfirmationModalProps(undefined); }} + sx={{ + width: { + xs: '90%', + sm: 600, + }, + }} /> )} <Box display="flex" justifyContent="space-between" alignItems="center"> From 70d37576f40e4408fa6b18f45bc6bdd8c7b1cb87 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 20 Mar 2024 10:49:24 +0100 Subject: [PATCH 227/394] Add new constructor methods to IPR request/responses (#4486) * Add function to create ping request * Add more constructor methods --- common/ip-packet-requests/src/request.rs | 28 ++++++++++++++++++++++ common/ip-packet-requests/src/response.rs | 29 +++++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/common/ip-packet-requests/src/request.rs b/common/ip-packet-requests/src/request.rs index 9f59b8ba0e..3bf1cd5d98 100644 --- a/common/ip-packet-requests/src/request.rs +++ b/common/ip-packet-requests/src/request.rs @@ -83,6 +83,34 @@ impl IpPacketRequest { } } + pub fn new_ping(reply_to: Recipient) -> (Self, u64) { + let request_id = generate_random(); + ( + Self { + version: CURRENT_VERSION, + data: IpPacketRequestData::Ping(PingRequest { + request_id, + reply_to, + }), + }, + request_id, + ) + } + + pub fn new_health_request(reply_to: Recipient) -> (Self, u64) { + let request_id = generate_random(); + ( + Self { + version: CURRENT_VERSION, + data: IpPacketRequestData::Health(HealthRequest { + request_id, + reply_to, + }), + }, + request_id, + ) + } + pub fn id(&self) -> Option<u64> { match &self.data { IpPacketRequestData::StaticConnect(request) => Some(request.request_id), diff --git a/common/ip-packet-requests/src/response.rs b/common/ip-packet-requests/src/response.rs index d2baf16f6e..c788a8974e 100644 --- a/common/ip-packet-requests/src/response.rs +++ b/common/ip-packet-requests/src/response.rs @@ -144,6 +144,35 @@ impl IpPacketResponse { } } + pub fn new_pong(request_id: u64, reply_to: Recipient) -> Self { + Self { + version: CURRENT_VERSION, + data: IpPacketResponseData::Pong(PongResponse { + request_id, + reply_to, + }), + } + } + + pub fn new_health_response( + request_id: u64, + reply_to: Recipient, + build_info: nym_bin_common::build_information::BinaryBuildInformationOwned, + routable: Option<bool>, + ) -> Self { + Self { + version: CURRENT_VERSION, + data: IpPacketResponseData::Health(HealthResponse { + request_id, + reply_to, + reply: HealthResponseReply { + build_info, + routable, + }, + }), + } + } + pub fn id(&self) -> Option<u64> { match &self.data { IpPacketResponseData::StaticConnect(response) => Some(response.request_id), From c89273ab3732dcf0d2459f409c17e305b0a2ad10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Wed, 20 Mar 2024 10:53:09 +0100 Subject: [PATCH 228/394] Update nym-wallet Cargo.lock --- nym-connect/desktop/Cargo.lock | 30 +++++++++++++++--------------- nym-wallet/Cargo.lock | 30 +++++++++++++++--------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index f5236af60d..abe59e81ac 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2833,20 +2833,6 @@ dependencies = [ "itoa 1.0.9", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -4104,6 +4090,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-mixnet-contract-common" version = "0.6.0" @@ -4507,7 +4507,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools", "log", "nym-api-requests", @@ -4518,6 +4517,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 5fc7e020bd..14883122c9 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -2389,20 +2389,6 @@ dependencies = [ "itoa 1.0.9", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -3273,6 +3259,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-mixnet-contract-common" version = "0.6.0" @@ -3439,7 +3439,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools 0.10.5", "log", "nym-api-requests", @@ -3450,6 +3449,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", From 7cbba823f8139a49a03401a7200c1b03e82b3ab3 Mon Sep 17 00:00:00 2001 From: Drazen <drazen@urch.eu> Date: Mon, 18 Mar 2024 20:14:59 +0100 Subject: [PATCH 229/394] metrics macros --- common/nym-metrics/src/lib.rs | 14 ++++++++++++++ mixnode/src/node/http/legacy/stats.rs | 6 +++--- mixnode/src/node/node_statistics.rs | 13 +++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index d67aae7b94..a878deaad3 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -7,6 +7,20 @@ pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; +#[macro_export] +macro_rules! count { + ($name:literal, $x:expr) => { + $crate::REGISTRY.inc_by($name, $x); + }; +} + +#[macro_export] +macro_rules! metrics { + () => { + $crate::REGISTRY.to_string(); + }; +} + #[macro_export] macro_rules! nanos { ( $name:literal, $x:expr ) => {{ diff --git a/mixnode/src/node/http/legacy/stats.rs b/mixnode/src/node/http/legacy/stats.rs index 1bbc6eea21..c986acee2b 100644 --- a/mixnode/src/node/http/legacy/stats.rs +++ b/mixnode/src/node/http/legacy/stats.rs @@ -7,7 +7,7 @@ use axum::{ extract::{Query, State}, http::HeaderMap, }; -use nym_metrics::REGISTRY; +use nym_metrics::metrics; use nym_node::http::api::{FormattedResponse, Output}; use serde::{Deserialize, Serialize}; @@ -24,7 +24,7 @@ pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: Heade if let Some(metrics_key) = state.metrics_key { if let Some(auth) = headers.get("Authorization") { if auth.to_str().unwrap_or_default() == format!("Bearer {}", metrics_key) { - REGISTRY.to_string() + metrics!() } else { "Unauthorized".to_string() } @@ -50,7 +50,7 @@ pub(crate) async fn stats( async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse { let snapshot_data = stats.clone_data().await; if full { - NodeStatsResponse::Full(REGISTRY.to_string()) + NodeStatsResponse::Full(metrics!()) } else { NodeStatsResponse::Simple(snapshot_data.simplify()) } diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 935ce6f3df..116bfd0a4a 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use nym_metrics::REGISTRY; +use nym_metrics::count; use super::TaskClient; use futures::channel::mpsc; @@ -65,11 +65,11 @@ impl SharedNodeStats { guard.packets_dropped_since_startup_all += count; } - REGISTRY.inc_by("packets_received_since_startup", new_received); - REGISTRY.inc_by("packets_sent_since_startup_all", new_sent.values().sum()); - REGISTRY.inc_by( + count!("packets_received_since_startup", new_received); + count!("packets_sent_since_startup_all", new_sent.values().sum()); + count!( "packets_dropped_since_startup_all", - new_dropped.values().sum(), + new_dropped.values().sum() ); guard.packets_received_since_last_update = new_received; @@ -509,6 +509,7 @@ impl Controller { #[cfg(test)] mod tests { use super::*; + use nym_metrics::metrics; use nym_task::TaskManager; #[tokio::test] @@ -538,6 +539,6 @@ mod tests { assert_eq!(&stats.packets_sent_since_last_update.len(), &1); assert_eq!(&stats.packets_received_since_startup, &0.); assert_eq!(&stats.packets_dropped_since_startup_all, &0.); - assert_eq!(REGISTRY.to_string(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") + assert_eq!(metrics!(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") } } From 5753c309735e75fd59c589debef1d16ad4f10818 Mon Sep 17 00:00:00 2001 From: Drazen <drazen@urch.eu> Date: Mon, 18 Mar 2024 20:43:33 +0100 Subject: [PATCH 230/394] Instrument client-core --- Cargo.lock | 1 + common/client-core/Cargo.toml | 1 + .../src/client/packet_statistics_control.rs | 19 ++++++ common/nym-metrics/src/lib.rs | 68 ++++++++++++++++--- mixnode/src/node/node_statistics.rs | 13 ++-- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06ff9e5780..07760e7212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5201,6 +5201,7 @@ dependencies = [ "nym-explorer-client", "nym-gateway-client", "nym-gateway-requests", + "nym-metrics", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index dc6c9bba2b..4179195c97 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -38,6 +38,7 @@ nym-crypto = { path = "../crypto" } nym-explorer-client = { path = "../../explorer-api/explorer-client" } nym-gateway-client = { path = "../client-libs/gateway-client" } nym-gateway-requests = { path = "../../gateway/gateway-requests" } +nym-metrics = { path = "../nym-metrics" } nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" } nym-sphinx = { path = "../nymsphinx" } nym-pemstore = { path = "../pemstore" } diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index a50e0c596c..81cd3034a0 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,6 +3,7 @@ use std::{ time::{Duration, Instant}, }; +use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; use crate::spawn_future; @@ -53,42 +54,60 @@ impl PacketStatistics { PacketStatisticsEvent::RealPacketSent(packet_size) => { self.real_packets_sent += 1; self.real_packets_sent_size += packet_size; + inc!("real_packets_sent"); + inc_by!("real_packets_sent_size", packet_size); } PacketStatisticsEvent::CoverPacketSent(packet_size) => { self.cover_packets_sent += 1; self.cover_packets_sent_size += packet_size; + inc!("cover_packets_sent"); + inc_by!("cover_packets_sent_size", packet_size); } PacketStatisticsEvent::RealPacketReceived(packet_size) => { self.real_packets_received += 1; self.real_packets_received_size += packet_size; + inc!("real_packets_received"); + inc_by!("real_packets_received_size", packet_size); } PacketStatisticsEvent::CoverPacketReceived(packet_size) => { self.cover_packets_received += 1; self.cover_packets_received_size += packet_size; + inc!("cover_packets_received"); + inc_by!("cover_packets_received_size", packet_size); } PacketStatisticsEvent::AckReceived(packet_size) => { self.total_acks_received += 1; self.total_acks_received_size += packet_size; + inc!("total_acks_received"); + inc_by!("total_acks_received_size", packet_size); } PacketStatisticsEvent::RealAckReceived(packet_size) => { self.real_acks_received += 1; self.real_acks_received_size += packet_size; + inc!("real_acks_received"); + inc_by!("real_acks_received_size", packet_size); } PacketStatisticsEvent::CoverAckReceived(packet_size) => { self.cover_acks_received += 1; self.cover_acks_received_size += packet_size; + inc!("cover_acks_received"); + inc_by!("cover_acks_received_size", packet_size); } PacketStatisticsEvent::RealPacketQueued => { self.real_packets_queued += 1; + inc!("real_packets_queued"); } PacketStatisticsEvent::RetransmissionQueued => { self.retransmissions_queued += 1; + inc!("retransmissions_queued"); } PacketStatisticsEvent::ReplySurbRequestQueued => { self.reply_surbs_queued += 1; + inc!("reply_surbs_queued"); } PacketStatisticsEvent::AdditionalReplySurbRequestQueued => { self.additional_reply_surbs_queued += 1; + inc!("additional_reply_surbs_queued"); } } } diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index a878deaad3..6df54bb8e4 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -8,9 +8,16 @@ pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; #[macro_export] -macro_rules! count { +macro_rules! inc_by { ($name:literal, $x:expr) => { - $crate::REGISTRY.inc_by($name, $x); + $crate::REGISTRY.inc_by($name, $x as f64); + }; +} + +#[macro_export] +macro_rules! inc { + ($name:literal) => { + $crate::REGISTRY.inc($name); }; } @@ -57,6 +64,7 @@ fn fq_name(c: &dyn Collector) -> String { } impl Metric { + #[inline(always)] fn fq_name(&self) -> String { match self { Metric::C(c) => fq_name(c.as_ref()), @@ -64,6 +72,15 @@ impl Metric { } } + #[inline(always)] + fn inc(&self) { + match self { + Metric::C(c) => c.inc(), + Metric::G(g) => g.inc(), + } + } + + #[inline(always)] fn inc_by(&self, value: f64) { match self { Metric::C(c) => c.inc_by(value), @@ -71,6 +88,7 @@ impl Metric { } } + #[inline(always)] fn set(&self, value: f64) { match self { Metric::C(_c) => { @@ -83,14 +101,8 @@ impl Metric { impl fmt::Display for MetricsController { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = vec![]; - let encoder = TextEncoder::new(); - let metrics = self.registry.gather(); - match encoder.encode(&metrics, &mut buffer) { - Ok(_) => {} - Err(e) => return write!(f, "Error encoding metrics to buffer: {}", e), - } - let output = match String::from_utf8(buffer) { + let metrics = self.gather(); + let output = match String::from_utf8(metrics) { Ok(output) => output, Err(e) => return write!(f, "Error decoding metrics to String: {}", e), }; @@ -99,6 +111,26 @@ impl fmt::Display for MetricsController { } impl MetricsController { + #[inline(always)] + pub fn gather(&self) -> Vec<u8> { + let mut buffer = vec![]; + let encoder = TextEncoder::new(); + let metrics = self.registry.gather(); + match encoder.encode(&metrics, &mut buffer) { + Ok(_) => {} + Err(e) => error!("Error encoding metrics to buffer: {}", e), + } + buffer + } + + pub fn to_writer(&self, writer: &mut dyn std::io::Write) { + let metrics = self.gather(); + match writer.write_all(&metrics) { + Ok(_) => {} + Err(e) => error!("Error writing metrics to writer: {}", e), + } + } + pub fn set(&self, name: &str, value: f64) { if let Some(metric) = self.registry_index.get(name) { metric.set(value); @@ -115,6 +147,22 @@ impl MetricsController { } } + pub fn inc(&self, name: &str) { + if let Some(metric) = self.registry_index.get(name) { + metric.inc(); + } else { + let counter = match Counter::new(sanitize_metric_name(name), name) { + Ok(c) => c, + Err(e) => { + debug!("Failed to create counter {:?}:\n{}", name, e); + return; + } + }; + self.register_counter(Box::new(counter)); + self.inc(name) + } + } + pub fn inc_by(&self, name: &str, value: f64) { if let Some(metric) = self.registry_index.get(name) { metric.inc_by(value); diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 116bfd0a4a..9ac08b2f0e 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use nym_metrics::count; +use nym_metrics::inc_by; use super::TaskClient; use futures::channel::mpsc; @@ -65,11 +65,14 @@ impl SharedNodeStats { guard.packets_dropped_since_startup_all += count; } - count!("packets_received_since_startup", new_received); - count!("packets_sent_since_startup_all", new_sent.values().sum()); - count!( + inc_by!("packets_received_since_startup", new_received); + inc_by!( + "packets_sent_since_startup_all", + new_sent.values().sum::<f64>() + ); + inc_by!( "packets_dropped_since_startup_all", - new_dropped.values().sum() + new_dropped.values().sum::<f64>() ); guard.packets_received_since_last_update = new_received; From 72cffc71cc9dbcfcdce814a623feab7c8ab48477 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 10:22:20 +0100 Subject: [PATCH 231/394] Light server to statistics control --- Cargo.lock | 171 ++++++++++++++---- common/client-core/Cargo.toml | 15 +- .../src/client/packet_statistics_control.rs | 40 ++++ 3 files changed, 186 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07760e7212..48c5ae1753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -557,9 +557,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "itoa", "matchit", "memchr", @@ -587,8 +587,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "mime", "rustversion", "tower-layer", @@ -3011,7 +3011,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 0.2.9", "js-sys", "pin-project", "serde", @@ -3080,7 +3080,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.9", "indexmap 1.9.3", "slab", "tokio", @@ -3088,6 +3088,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", + "indexmap 2.0.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "1.8.2" @@ -3290,6 +3309,17 @@ 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-api-client" version = "0.1.0" @@ -3311,7 +3341,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.9", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite 0.2.13", ] @@ -3378,9 +3431,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -3392,6 +3445,27 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.3", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite 0.2.13", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -3399,8 +3473,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", @@ -3412,12 +3486,32 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.27", "pin-project-lite 0.2.13", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite 0.2.13", + "socket2 0.5.4", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -3742,7 +3836,7 @@ dependencies = [ "curl-sys", "event-listener", "futures-lite", - "http", + "http 0.2.9", "log", "once_cell", "polling", @@ -4555,7 +4649,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.9", "httparse", "log", "memchr", @@ -5192,7 +5286,10 @@ dependencies = [ "dirs 4.0.0", "futures", "gloo-timers", + "http-body-util", "humantime-serde", + "hyper 1.2.0", + "hyper-util", "log", "nym-bandwidth-controller", "nym-config", @@ -5515,7 +5612,7 @@ dependencies = [ "dotenvy", "futures", "humantime-serde", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "log", "nym-api-requests", @@ -5951,7 +6048,7 @@ dependencies = [ "dashmap", "fastrand 2.0.1", "hmac 0.12.1", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "mime", "nym-config", @@ -6104,7 +6201,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http", + "http 0.2.9", "httpcodec", "libp2p", "log", @@ -6844,7 +6941,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906" dependencies = [ "async-trait", "bytes", - "http", + "http 0.2.9", "isahc", "opentelemetry_api", ] @@ -6858,7 +6955,7 @@ dependencies = [ "async-trait", "futures", "futures-executor", - "http", + "http 0.2.9", "isahc", "once_cell", "opentelemetry", @@ -8038,10 +8135,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "ipnet", "js-sys", @@ -8200,7 +8297,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ - "http", + "http 0.2.9", "log", "regex", "rocket", @@ -8220,8 +8317,8 @@ dependencies = [ "cookie", "either", "futures", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "indexmap 2.0.2", "log", "memchr", @@ -9025,9 +9122,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "snafu" @@ -9978,10 +10075,10 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-timeout", "percent-encoding", "pin-project", @@ -10024,8 +10121,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "http-range-header", "httpdate", "mime", @@ -10303,7 +10400,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.9", "httparse", "log", "rand 0.8.5", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 4179195c97..607ca15c36 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -27,10 +27,15 @@ tap = "1.0.1" thiserror = { workspace = true } url = { workspace = true, features = ["serde"] } tungstenite = { workspace = true, default-features = false } -tokio = { workspace = true, features = ["macros"]} +tokio = { workspace = true, features = ["macros"] } time = "0.3.17" zeroize = { workspace = true } +# For serving metrics +hyper = { version = "1", features = ["full"] } +http-body-util = "0.1" +hyper-util = { version = "0.1", features = ["full"] } + # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } @@ -92,11 +97,15 @@ tempfile = "3.1.0" [build-dependencies] tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } +sqlx = { workspace = true, features = [ + "runtime-tokio-rustls", + "sqlite", + "macros", + "migrate", +] } [features] default = [] cli = ["clap"] fs-surb-storage = ["sqlx"] wasm = ["nym-gateway-client/wasm"] - diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 81cd3034a0..27fc90f0e4 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,9 +3,21 @@ use std::{ time::{Duration, Instant}, }; +use log::warn; use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; +// Metrics server +use http_body_util::Full; +use hyper::body::Bytes; +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Request, Response}; +use hyper_util::rt::TokioIo; +use std::convert::Infallible; +use std::net::SocketAddr; +use tokio::net::TcpListener; + use crate::spawn_future; // Time interval between reporting packet statistics @@ -484,6 +496,12 @@ impl PacketStatisticsControl { let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS); let mut snapshot_interval = tokio::time::interval(snapshot_interval); + let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener = TcpListener::bind(addr) + .await + .expect(&format!("Cannot bind metrics server to {metrics_port}!")); + loop { tokio::select! { stats_event = self.stats_rx.recv() => match stats_event { @@ -496,6 +514,22 @@ impl PacketStatisticsControl { break; } }, + result = listener.accept() => { + if let Ok((stream, _)) = result { + let io = TokioIo::new(stream); + + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(serve_metrics)) + .await + { + warn!("Error serving connection: {:?}", err); + } + }); + } else { + warn!("Error accepting connection"); + } + } _ = snapshot_interval.tick() => { self.update_history(); self.update_rates(); @@ -520,3 +554,9 @@ impl PacketStatisticsControl { }) } } + +async fn serve_metrics( + _: Request<hyper::body::Incoming>, +) -> Result<Response<Full<Bytes>>, Infallible> { + Ok(Response::new(Full::new(Bytes::from(metrics!())))) +} From 27978908d015e4a1c2d4e9232deb42d8c39dac08 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 12:41:35 +0100 Subject: [PATCH 232/394] Disable metrics server for wasm --- Cargo.lock | 31 ++----------------- common/client-core/Cargo.toml | 18 ++++++++--- .../src/client/packet_statistics_control.rs | 29 +++++++++++++---- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48c5ae1753..d7ab5721bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3088,25 +3088,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "h2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.0.2", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "1.8.2" @@ -3431,7 +3412,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "httparse", @@ -3454,7 +3435,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.3", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -3463,7 +3443,6 @@ dependencies = [ "pin-project-lite 0.2.13", "smallvec", "tokio", - "want", ] [[package]] @@ -3499,7 +3478,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", - "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", @@ -3507,9 +3485,6 @@ dependencies = [ "pin-project-lite 0.2.13", "socket2 0.5.4", "tokio", - "tower", - "tower-service", - "tracing", ] [[package]] @@ -8135,7 +8110,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -10075,7 +10050,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 607ca15c36..013efbeef5 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -31,11 +31,6 @@ tokio = { workspace = true, features = ["macros"] } time = "0.3.17" zeroize = { workspace = true } -# For serving metrics -hyper = { version = "1", features = ["full"] } -http-body-util = "0.1" -hyper-util = { version = "0.1", features = ["full"] } - # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } @@ -54,6 +49,19 @@ nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } si-scale = "0.2.2" +### For serving prometheus metrics +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] +version = "1.2" +features = ["server", "http1"] + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util] +version = "0.1" + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper-util] +version = "0.1" +features = ["tokio"] +### + [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" features = ["time"] diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 27fc90f0e4..f05054f73b 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -8,14 +8,23 @@ use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; // Metrics server +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use http_body_util::Full; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::body::Bytes; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::server::conn::http1; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::service::service_fn; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::{Request, Response}; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper_util::rt::TokioIo; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::convert::Infallible; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::net::SocketAddr; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use tokio::net::TcpListener; use crate::spawn_future; @@ -496,11 +505,18 @@ impl PacketStatisticsControl { let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS); let mut snapshot_interval = tokio::time::interval(snapshot_interval); - let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); - let listener = TcpListener::bind(addr) - .await - .expect(&format!("Cannot bind metrics server to {metrics_port}!")); + cfg_if::cfg_if! { + if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { + log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); + let listener = None; + } else { + let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener = Some(TcpListener::bind(addr) + .await + .unwrap_or_else(|_ | panic!("Cannot bind metrics server to {metrics_port}!"))); + } + } loop { tokio::select! { @@ -514,7 +530,8 @@ impl PacketStatisticsControl { break; } }, - result = listener.accept() => { + // conditional will disable the branch if we're in wasm32-unknown-unknown + result = listener.as_ref().unwrap().accept(), if listener.is_some() => { if let Ok((stream, _)) = result { let io = TokioIo::new(stream); From af68da940643d2d4e0cc702e5c954edf05a07953 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 15:26:40 +0100 Subject: [PATCH 233/394] Dont panic on error --- .../src/client/packet_statistics_control.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index f05054f73b..27c7c7f48b 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -512,9 +512,13 @@ impl PacketStatisticsControl { } else { let metrics_port = 18000; let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); - let listener = Some(TcpListener::bind(addr) - .await - .unwrap_or_else(|_ | panic!("Cannot bind metrics server to {metrics_port}!"))); + let listener = match TcpListener::bind(addr).await { + Ok(listener) => Some(listener), + Err(err) => { + log::error!("Failed to bind metrics server: {:?}", err); + None + } + }; } } From 46a319bd7a3acb9354bbf0741ebd2486bac326cd Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:36:47 +0100 Subject: [PATCH 234/394] Randomize port assignemnt --- .../src/client/packet_statistics_control.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 27c7c7f48b..7119687809 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,7 +3,7 @@ use std::{ time::{Duration, Instant}, }; -use log::warn; +use log::{info, warn}; use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; @@ -510,10 +510,16 @@ impl PacketStatisticsControl { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); let listener = None; } else { - let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + // let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], 0)); + let listener = match TcpListener::bind(addr).await { - Ok(listener) => Some(listener), + Ok(listener) => { + info!("###############################"); + info!("Metrics endpoint is at: {:?}", listener.local_addr()); + info!("###############################"); + Some(listener) + }, Err(err) => { log::error!("Failed to bind metrics server: {:?}", err); None From 0b82109e3c25991523af2191b9e0f73de72b91dd Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:53:47 +0100 Subject: [PATCH 235/394] Predictable IP range --- .../src/client/packet_statistics_control.rs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 7119687809..287dc944c9 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -510,21 +510,25 @@ impl PacketStatisticsControl { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); let listener = None; } else { - // let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], 0)); + let mut metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener: Option<TcpListener>; + loop { + match TcpListener::bind(addr).await { + Ok(l) => { + info!("###############################"); + info!("Metrics endpoint is at: {:?}", l.local_addr()); + info!("###############################"); + listener = Some(l); + break; + }, + Err(err) => { + log::warn!("Failed to bind metrics server: {:?}", err); + metrics_port += 1; + } + }; + } - let listener = match TcpListener::bind(addr).await { - Ok(listener) => { - info!("###############################"); - info!("Metrics endpoint is at: {:?}", listener.local_addr()); - info!("###############################"); - Some(listener) - }, - Err(err) => { - log::error!("Failed to bind metrics server: {:?}", err); - None - } - }; } } From 7ecac4a7b432a1e61e40172117779b5b94471582 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 16:58:30 +0100 Subject: [PATCH 236/394] Fix predictable port range :) --- common/client-core/src/client/packet_statistics_control.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 287dc944c9..124688a10d 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -511,9 +511,9 @@ impl PacketStatisticsControl { let listener = None; } else { let mut metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); let listener: Option<TcpListener>; loop { + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); match TcpListener::bind(addr).await { Ok(l) => { info!("###############################"); From e2aa7aa31cc924117e20b54220522918d1bda042 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 19:49:44 +0100 Subject: [PATCH 237/394] Relax hyper dependency --- common/client-core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 013efbeef5..fdc6a39b7a 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -51,7 +51,7 @@ si-scale = "0.2.2" ### For serving prometheus metrics [target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] -version = "1.2" +version = "1" features = ["server", "http1"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util] From e67d3d816ccdda8e57df6154c286c8cbedf4a5c1 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Tue, 19 Mar 2024 20:50:46 +0100 Subject: [PATCH 238/394] Push package name to metrics --- Cargo.lock | 1 - common/nym-metrics/Cargo.toml | 1 - common/nym-metrics/src/lib.rs | 50 +++++++++++++++++++++++++---- mixnode/src/node/node_statistics.rs | 2 +- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7ab5721bc..95685f31c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5792,7 +5792,6 @@ dependencies = [ "lazy_static", "log", "prometheus", - "regex", ] [[package]] diff --git a/common/nym-metrics/Cargo.toml b/common/nym-metrics/Cargo.toml index 0b49297719..537a69a142 100644 --- a/common/nym-metrics/Cargo.toml +++ b/common/nym-metrics/Cargo.toml @@ -14,5 +14,4 @@ license.workspace = true prometheus = { workspace = true } log = { workspace = true } dashmap = { workspace = true } -regex = "1.1" lazy_static = "1.4" diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index 6df54bb8e4..a9e22909d3 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -1,23 +1,37 @@ use dashmap::DashMap; pub use log::error; use log::{debug, warn}; -use regex::Regex; use std::fmt; pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; +#[macro_export] +macro_rules! prepend_package_name { + ($name: literal) => { + &format!( + "{}_{}", + std::module_path!() + .split("::") + .next() + .unwrap_or("x") + .to_string(), + $name + ) + }; +} + #[macro_export] macro_rules! inc_by { ($name:literal, $x:expr) => { - $crate::REGISTRY.inc_by($name, $x as f64); + $crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as f64); }; } #[macro_export] macro_rules! inc { ($name:literal) => { - $crate::REGISTRY.inc($name); + $crate::REGISTRY.inc($crate::prepend_package_name!($name)); }; } @@ -35,13 +49,13 @@ macro_rules! nanos { // if the block needs to return something, we can return it let r = $x; let duration = start.elapsed().as_nanos() as f64; + let name = $crate::prepend_package_name!($name); $crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration); r }}; } lazy_static::lazy_static! { - pub static ref RE: Regex = Regex::new(r"[^a-zA-Z0-9_]").unwrap(); pub static ref REGISTRY: MetricsController = MetricsController::default(); } @@ -223,9 +237,31 @@ impl MetricsController { } } -#[inline(always)] fn sanitize_metric_name(name: &str) -> String { - RE.replace_all(name, "_").to_string() + // The first character must be [a-zA-Z_:], and all subsequent characters must be [a-zA-Z0-9_:]. + let mut out = String::with_capacity(name.len()); + let mut is_invalid: fn(char) -> bool = invalid_metric_name_start_character; + for c in name.chars() { + if is_invalid(c) { + out.push('_'); + } else { + out.push(c); + } + is_invalid = invalid_metric_name_character; + } + out +} + +#[inline] +fn invalid_metric_name_start_character(c: char) -> bool { + // Essentially, needs to match the regex pattern of [a-zA-Z_:]. + !(c.is_ascii_alphabetic() || c == '_' || c == ':') +} + +#[inline] +fn invalid_metric_name_character(c: char) -> bool { + // Essentially, needs to match the regex pattern of [a-zA-Z0-9_:]. + !(c.is_ascii_alphanumeric() || c == '_' || c == ':') } #[cfg(test)] @@ -236,7 +272,7 @@ mod tests { fn test_sanitization() { assert_eq!( sanitize_metric_name("packets_sent_34.242.65.133:1789"), - "packets_sent_34_242_65_133_1789" + "packets_sent_34_242_65_133:1789" ) } } diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 9ac08b2f0e..aaabbb7a30 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -542,6 +542,6 @@ mod tests { assert_eq!(&stats.packets_sent_since_last_update.len(), &1); assert_eq!(&stats.packets_received_since_startup, &0.); assert_eq!(&stats.packets_dropped_since_startup_all, &0.); - assert_eq!(metrics!(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") + assert_eq!(metrics!(), "# HELP nym_mixnode_packets_dropped_since_startup_all nym_mixnode_packets_dropped_since_startup_all\n# TYPE nym_mixnode_packets_dropped_since_startup_all counter\nnym_mixnode_packets_dropped_since_startup_all 0\n# HELP nym_mixnode_packets_received_since_startup nym_mixnode_packets_received_since_startup\n# TYPE nym_mixnode_packets_received_since_startup counter\nnym_mixnode_packets_received_since_startup 0\n# HELP nym_mixnode_packets_sent_since_startup_all nym_mixnode_packets_sent_since_startup_all\n# TYPE nym_mixnode_packets_sent_since_startup_all counter\nnym_mixnode_packets_sent_since_startup_all 2\n") } } From 7ccba11d82766cc49b5fe4d60251775505977748 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Wed, 20 Mar 2024 12:57:08 +0100 Subject: [PATCH 239/394] Static targets script --- scripts/static_prom_targets.py | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 scripts/static_prom_targets.py diff --git a/scripts/static_prom_targets.py b/scripts/static_prom_targets.py new file mode 100644 index 0000000000..e3490ea089 --- /dev/null +++ b/scripts/static_prom_targets.py @@ -0,0 +1,43 @@ +import json +import os + + +ips = [ + "2.221.182.179", + "54.232.20.104", + "15.237.112.155", + "54.93.108.209", + "13.38.74.100", + "15.237.93.154", + "18.156.175.57", + "3.76.123.170", +] + +port_range = range(18000, 18999) + + +def make_prom_target(ip, port, env): + return { + "targets": [f"{ip}:{port}"], + "labels": { + "mixnet_env": env, + }, + } + + +if __name__ == "__main__": + outfile = "/tmp/tmp_static_prom_tragets.json" + outlink = "/tmp/static_prom_tragets.json" + targets = [] + for ip in ips: + for port in port_range: + targets.append(make_prom_target(ip, port, "performance")) + + with open(outfile, "w") as f: + json.dump(targets, f) + + os.chmod(outfile, 0o777) + os.rename(outfile, outlink) + os.chmod(outlink, 0o777) + + print(f"Prometheus -> {len(targets)} targets written to {outlink}") From 9a5d6103d691ed1865cfb508e4b02da61d573190 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:25:26 +0100 Subject: [PATCH 240/394] Fix gateway target generation --- scripts/prom_targets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/prom_targets.py b/scripts/prom_targets.py index e7887e1ed1..44ea2a3c83 100644 --- a/scripts/prom_targets.py +++ b/scripts/prom_targets.py @@ -72,7 +72,9 @@ def config_to_targets(config, mixnodes, labels=None): def make_prom_target(env, mixnode, port=None, labels=None): bond_info = mixnode.get("bond_information", {}) - mix_node = bond_info.get("mix_node", {}) + mix_node = bond_info.get("mix_node") + if mix_node is None: + mix_node = mixnode.get("gateway") host = mix_node.get("host", None) port = port if port else mix_node.get("http_api_port", None) if host is None or port is None: From eb914463dcf5678d5f731e78404cf581b9aa77e0 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Wed, 20 Mar 2024 13:27:58 +0100 Subject: [PATCH 241/394] Fix wasm build --- .../src/client/packet_statistics_control.rs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 124688a10d..8f5aaf434d 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -546,19 +546,23 @@ impl PacketStatisticsControl { }, // conditional will disable the branch if we're in wasm32-unknown-unknown result = listener.as_ref().unwrap().accept(), if listener.is_some() => { - if let Ok((stream, _)) = result { - let io = TokioIo::new(stream); + cfg_if::cfg_if! { + if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] { + if let Ok((stream, _)) = result { + let io = TokioIo::new(stream); - tokio::task::spawn(async move { - if let Err(err) = http1::Builder::new() - .serve_connection(io, service_fn(serve_metrics)) - .await - { - warn!("Error serving connection: {:?}", err); + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(serve_metrics)) + .await + { + warn!("Error serving connection: {:?}", err); + } + }); + } else { + warn!("Error accepting connection"); } - }); - } else { - warn!("Error accepting connection"); + } } } _ = snapshot_interval.tick() => { From 78b00302c812f5ff3a161d84523f7f534a5938d5 Mon Sep 17 00:00:00 2001 From: Sachin Kamath <github@skamath.me> Date: Wed, 20 Mar 2024 18:07:02 +0530 Subject: [PATCH 242/394] docs: add websocket reverse proxy example (#4452) * docs: add websocket reverse proxy example * docs: add a line about reverse proxy * remove note about nym-api not released --- documentation/operators/src/nodes/maintenance.md | 10 ++++++++++ documentation/operators/src/nodes/nym-api.md | 4 ---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/documentation/operators/src/nodes/maintenance.md b/documentation/operators/src/nodes/maintenance.md index 284f1e085b..af3c0c7b97 100644 --- a/documentation/operators/src/nodes/maintenance.md +++ b/documentation/operators/src/nodes/maintenance.md @@ -682,6 +682,8 @@ Which should return: Proxying various full node services through port 80 can then be done by creating a file with the following at `/etc/nginx/sites-enabled/nyxd-webrequests.conf`: +Setting up a reverse proxy using a webserver such as Nginx allows you to easily configure SSL certificates for the endpoints. When running on mainnet, it is recommended to encrypt all web traffic to your node. + ```sh ### To expose RPC server server { @@ -695,6 +697,14 @@ server { proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } + + location /websocket { + proxy_pass http://127.0.0.1:26657; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } } ### To expose Cosmos API server diff --git a/documentation/operators/src/nodes/nym-api.md b/documentation/operators/src/nodes/nym-api.md index 2e3327f174..3753d2e80c 100644 --- a/documentation/operators/src/nodes/nym-api.md +++ b/documentation/operators/src/nodes/nym-api.md @@ -2,10 +2,6 @@ [//]: # (> The nym-api binary was built in the [building nym](../binaries/building-nym.md) section. If you haven't yet built Nym and want to run the code, go there first. You can build just the API with `cargo build --release --bin nym-api`.) -> The `nym-api` binary will be released in the immediate future - we're releasing this document beforehand so that validators have information as soon as possible and get an idea of what to expect. This doc will be expanded over time as we release the API binary itself as well as start enabling functionality. -> -> You can build the API with `cargo build --release --bin nym-api`. - > Any syntax in `<>` brackets is a user's unique variable. Exchange with a corresponding name without the `<>` brackets. ## What is the Nym API? From e699f1ad7932497f32dd2065667093595f0d431f Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Tue, 19 Mar 2024 21:20:57 +0000 Subject: [PATCH 243/394] explorer env configuration updates --- explorer/.env.dev | 1 - explorer/.env.prod | 3 +- explorer/package.json | 2 +- explorer/src/api/constants.ts | 2 +- explorer/src/context/cosmos-kit.tsx | 47 +++++++++++++++++++--------- explorer/src/context/delegations.tsx | 2 +- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/explorer/.env.dev b/explorer/.env.dev index d8c4d4547b..013d526f82 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -9,4 +9,3 @@ BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx NYM_MIXNET_CONTRACT=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr -COSMOS_KIT_USE_CHAIN=nyx diff --git a/explorer/.env.prod b/explorer/.env.prod index e71e710e15..2e927b2947 100644 --- a/explorer/.env.prod +++ b/explorer/.env.prod @@ -3,5 +3,4 @@ NYM_API_URL=https://validator.nymtech.net VALIDATOR_URL=https://rpc.nymtech.net BIG_DIPPER_URL=https://blocks.nymtech.net CURRENCY_DENOM=unym -CURRENCY_STAKING_DENOM=unyx -COSMOS_KIT_USE_CHAIN=nyx \ No newline at end of file +CURRENCY_STAKING_DENOM=unyx \ No newline at end of file diff --git a/explorer/package.json b/explorer/package.json index 377c5d1c4e..9079de0104 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -52,6 +52,7 @@ "bs58": "^5.0.0", "buffer": "^6.0.3", "chain-registry": "^1.29.1", + "@chain-registry/types": "^0.18.1", "cosmjs-types": "^0.9.0", "d3-scale": "^4.0.0", "date-fns": "^2.24.0", @@ -70,7 +71,6 @@ }, "devDependencies": { "@babel/core": "^7.15.0", - "@chain-registry/types": "^0.18.1", "@nymproject/eslint-config-react-typescript": "^1.0.0", "@pmmmwh/react-refresh-webpack-plugin": "^0.5.4", "@storybook/addon-actions": "^6.5.8", diff --git a/explorer/src/api/constants.ts b/explorer/src/api/constants.ts index 372708f9cc..fbb8c18d6b 100644 --- a/explorer/src/api/constants.ts +++ b/explorer/src/api/constants.ts @@ -1,7 +1,7 @@ // master APIs export const API_BASE_URL = process.env.EXPLORER_API_URL; export const NYM_API_BASE_URL = process.env.NYM_API_URL; -export const VALIDATOR_BASE_URL = process.env.VALIDATOR_URL; +export const VALIDATOR_BASE_URL = process.env.VALIDATOR_URL || 'https://rpc.nymtech.net'; export const BIG_DIPPER = process.env.BIG_DIPPER_URL; // specific API routes diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 3069882fa5..8fa164bf00 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -6,6 +6,7 @@ import { wallets as cosmosstation } from '@cosmos-kit/cosmostation-extension'; import { wallets as leap } from '@cosmos-kit/leap-extension'; import { assets, chains } from 'chain-registry'; import { Chain, AssetList } from '@chain-registry/types'; +import { VALIDATOR_BASE_URL } from '@src/api/constants'; const nymSandbox: Chain = { chain_name: 'sandbox', @@ -37,21 +38,37 @@ const nymSandboxAssets: AssetList = { ], }; -const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => ( - <ChainProvider - chains={[...chains, nymSandbox]} - assetLists={[...assets, nymSandboxAssets]} - wallets={[...keplr, ...ledger, ...cosmosstation, ...leap]} - endpointOptions={{ - endpoints: { - nyx: { - rpc: ['https://rpc.nymtech.net'], +const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => { + // Only use the nyx chains + const chainsFixedUp = React.useMemo(() => { + const nyx = chains.find((chain) => chain.chain_id === 'nyx'); + + return nyx ? [nymSandbox, nyx] : [nymSandbox]; + }, [chains]); + + // Only use the nyx assets + const assetsFixedUp = React.useMemo(() => { + const nyx = assets.find((asset) => asset.chain_name === 'nyx'); + + return nyx ? [nymSandboxAssets, nyx] : [nymSandboxAssets]; + }, [assets]); + + return ( + <ChainProvider + chains={chainsFixedUp} + assetLists={assetsFixedUp} + wallets={[...keplr, ...ledger, ...cosmosstation, ...leap]} + endpointOptions={{ + endpoints: { + nyx: { + rpc: [VALIDATOR_BASE_URL], + }, }, - }, - }} - > - {children} - </ChainProvider> -); + }} + > + {children} + </ChainProvider> + ); +}; export default CosmosKitProvider; diff --git a/explorer/src/context/delegations.tsx b/explorer/src/context/delegations.tsx index ecb15b686d..28a50345e0 100644 --- a/explorer/src/context/delegations.tsx +++ b/explorer/src/context/delegations.tsx @@ -173,7 +173,7 @@ export const DelegationsProvider = ({ children }: { children: React.ReactNode }) }; const handleUndelegate = async (mixId: number) => { - const tx = await nymClient?.undelegateFromMixnode({ mixId }, fee); + const tx = await nymClient?.undelegateFromMixnode({ mixId }, fee, 'Undelegation from Nym Explorer'); return tx as unknown as ExecuteResult; }; From 480799bad1fc4d40994fe663e95bdc1b2ba71f1d Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:28:25 +0000 Subject: [PATCH 244/394] Change to using github action reference --- .github/workflows/release-calculate-hash.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/release-calculate-hash.yml b/.github/workflows/release-calculate-hash.yml index 00d253908a..a68a60b431 100644 --- a/.github/workflows/release-calculate-hash.yml +++ b/.github/workflows/release-calculate-hash.yml @@ -24,10 +24,7 @@ jobs: - uses: actions/setup-node@v3 with: node-version: 18 - - name: Install packages - run: cd ./.github/actions/nym-hash-releases && npm i - - - uses: ./.github/actions/nym-hash-releases + - uses: nymtech/nym/.github/actions/nym-hash-releases@develop env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: From 3c8c51e1c9695a4975d1096251f046d0f6a29167 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <14054343+mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 14:29:50 +0000 Subject: [PATCH 245/394] Update release-calculate-hash.yml --- .github/workflows/release-calculate-hash.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release-calculate-hash.yml b/.github/workflows/release-calculate-hash.yml index a68a60b431..fb493b8541 100644 --- a/.github/workflows/release-calculate-hash.yml +++ b/.github/workflows/release-calculate-hash.yml @@ -8,8 +8,8 @@ on: required: true type: string workflow_dispatch: - release_tag: - tag: + inputs: + release_tag: description: 'Release tag' required: true type: string From efe952fdf29add4d30599ac8753e24f04eda71a3 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Wed, 20 Mar 2024 15:48:17 +0000 Subject: [PATCH 246/394] explorer package updates --- explorer/.env.dev | 4 +- explorer/src/pages/Delegations/index.tsx | 5 +- explorer/src/pages/Mixnodes/index.tsx | 6 ++ .../packages/validator-client/package.json | 4 +- yarn.lock | 66 +++++++++---------- 5 files changed, 46 insertions(+), 39 deletions(-) diff --git a/explorer/.env.dev b/explorer/.env.dev index 013d526f82..3cc86ae00c 100644 --- a/explorer/.env.dev +++ b/explorer/.env.dev @@ -1,11 +1,9 @@ # When running the explorer API locally #EXPLORER_API_URL=http://localhost:8000/v1 -# EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1 -EXPLORER_API_URL=https://explorer.nymtech.net/api/v1 +EXPLORER_API_URL=https://sandbox-explorer.nymtech.net/api/v1 NYM_API_URL=https://sandbox-nym-api1.nymtech.net VALIDATOR_URL=https://rpc.sandbox.nymtech.net BIG_DIPPER_URL=https://sandbox-blocks.nymtech.net CURRENCY_DENOM=unym CURRENCY_STAKING_DENOM=unyx -NYM_MIXNET_CONTRACT=n17srjznxl9dvzdkpwpw24gg668wc73val88a6m5ajg6ankwvz9wtst0cznr diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx index 3305b542df..6aabec5f51 100644 --- a/explorer/src/pages/Delegations/index.tsx +++ b/explorer/src/pages/Delegations/index.tsx @@ -12,6 +12,7 @@ import { PendingEvent, useDelegationsContext, } from '@src/context/delegations'; +import { urls } from '@src/utils'; const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) => ({ identity: delegation.identityKey, @@ -80,7 +81,9 @@ const DelegationsPage = () => { setConfirmationModalProps({ status: 'success', message: 'Undelegation successful', - transactions: [{ url: `${tx.transactionHash}`, hash: tx.transactionHash }], + transactions: [ + { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash }, + ], }); } } catch (error) { diff --git a/explorer/src/pages/Mixnodes/index.tsx b/explorer/src/pages/Mixnodes/index.tsx index 5e5caf9d2f..79a88f7053 100644 --- a/explorer/src/pages/Mixnodes/index.tsx +++ b/explorer/src/pages/Mixnodes/index.tsx @@ -414,6 +414,12 @@ export const PageMixnodes: FCWithChildren = () => { navigate('/delegations'); } }} + sx={{ + width: { + xs: '90%', + sm: 600, + }, + }} /> )} </DelegationsProvider> diff --git a/sdk/typescript/packages/validator-client/package.json b/sdk/typescript/packages/validator-client/package.json index 4a9ff69810..2b91e92a5e 100644 --- a/sdk/typescript/packages/validator-client/package.json +++ b/sdk/typescript/packages/validator-client/package.json @@ -27,12 +27,12 @@ "tsc": "tsc --noEmit" }, "devDependencies": { - "@cosmjs/cosmwasm-stargate": "0.29.5", + "@cosmjs/cosmwasm-stargate": "^0.29.5", "@cosmjs/crypto": "^0.29.5", "@cosmjs/math": "^0.29.5", "@cosmjs/proto-signing": "^0.29.5", "@cosmjs/stargate": "^0.29.5", - "@cosmjs/tendermint-rpc": "0.29.5", + "@cosmjs/tendermint-rpc": "^0.29.5", "@favware/rollup-type-bundler": "^2.0.0", "@nymproject/types": "^1.0.0", "@rollup/plugin-commonjs": "^24.0.1", diff --git a/yarn.lock b/yarn.lock index 7a0aa40538..8cf3d3c6ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1402,23 +1402,6 @@ "@cosmjs/utils" "^0.25.6" pako "^2.0.2" -"@cosmjs/cosmwasm-stargate@0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" - integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== - dependencies: - "@cosmjs/amino" "^0.29.5" - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/proto-signing" "^0.29.5" - "@cosmjs/stargate" "^0.29.5" - "@cosmjs/tendermint-rpc" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - cosmjs-types "^0.5.2" - long "^4.0.0" - pako "^2.0.2" - "@cosmjs/cosmwasm-stargate@^0.25.5": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.25.6.tgz#26a788213833aaffc4bc1a87df650741e0b8fd63" @@ -1437,6 +1420,23 @@ pako "^2.0.2" protobufjs "~6.10.2" +"@cosmjs/cosmwasm-stargate@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.29.5.tgz#3f257da682658833e0f4eb9e8ff758e4d927663a" + integrity sha512-TNdSvm2tEE3XMCuxHxquzls56t40hC8qnLeYJWHsY2ECZmRK3KrnpRReEr7N7bLtODToK7X/riYrV0JaYxjrYA== + dependencies: + "@cosmjs/amino" "^0.29.5" + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/proto-signing" "^0.29.5" + "@cosmjs/stargate" "^0.29.5" + "@cosmjs/tendermint-rpc" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + cosmjs-types "^0.5.2" + long "^4.0.0" + pako "^2.0.2" + "@cosmjs/cosmwasm-stargate@^0.32.0": version "0.32.1" resolved "https://registry.yarnpkg.com/@cosmjs/cosmwasm-stargate/-/cosmwasm-stargate-0.32.1.tgz#2210007320c3f68a73e8cf8b9344a9dc6d4729b7" @@ -1820,22 +1820,6 @@ dependencies: xstream "^11.14.0" -"@cosmjs/tendermint-rpc@0.29.5", "@cosmjs/tendermint-rpc@^0.29.5": - version "0.29.5" - resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" - integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== - dependencies: - "@cosmjs/crypto" "^0.29.5" - "@cosmjs/encoding" "^0.29.5" - "@cosmjs/json-rpc" "^0.29.5" - "@cosmjs/math" "^0.29.5" - "@cosmjs/socket" "^0.29.5" - "@cosmjs/stream" "^0.29.5" - "@cosmjs/utils" "^0.29.5" - axios "^0.21.2" - readonly-date "^1.0.0" - xstream "^11.14.0" - "@cosmjs/tendermint-rpc@^0.25.6": version "0.25.6" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.25.6.tgz#8198a08b0d0e1d6580618f3f22db83366329c9c3" @@ -1851,6 +1835,22 @@ readonly-date "^1.0.0" xstream "^11.14.0" +"@cosmjs/tendermint-rpc@^0.29.5": + version "0.29.5" + resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.29.5.tgz#f205c10464212bdf843f91bb2e4a093b618cb5c2" + integrity sha512-ar80twieuAxsy0x2za/aO3kBr2DFPAXDmk2ikDbmkda+qqfXgl35l9CVAAjKRqd9d+cRvbQyb5M4wy6XQpEV6w== + dependencies: + "@cosmjs/crypto" "^0.29.5" + "@cosmjs/encoding" "^0.29.5" + "@cosmjs/json-rpc" "^0.29.5" + "@cosmjs/math" "^0.29.5" + "@cosmjs/socket" "^0.29.5" + "@cosmjs/stream" "^0.29.5" + "@cosmjs/utils" "^0.29.5" + axios "^0.21.2" + readonly-date "^1.0.0" + xstream "^11.14.0" + "@cosmjs/tendermint-rpc@^0.32.0", "@cosmjs/tendermint-rpc@^0.32.1": version "0.32.1" resolved "https://registry.yarnpkg.com/@cosmjs/tendermint-rpc/-/tendermint-rpc-0.32.1.tgz#f7f8929619648fb0520047c6d930dc65588345d2" From ef22cb9fcd3ecf48fac7cb482d44eafa62823c92 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 17:55:17 +0000 Subject: [PATCH 247/394] GitHub Actions: nym-hash-release --- .github/actions/nym-hash-releases/dist/index.js | 13 +++++++------ .../actions/nym-hash-releases/src/create-hashes.mjs | 3 ++- .github/actions/nym-hash-releases/src/run-local.mjs | 13 +++++++++---- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js index 6759b28f93..9d1c0ec1e0 100644 --- a/.github/actions/nym-hash-releases/dist/index.js +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -24002,7 +24002,7 @@ async function run(assets, algorithm, filename, cache) { let sig = null; // cache in `${WORKING_DIR}/.tmp/` - const cacheFilename = external_path_.resolve(`.tmp/${asset.name}`); + const cacheFilename = __nccwpck_require__.ab + ".tmp/" + asset.name; if(!external_fs_.existsSync(cacheFilename)) { console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); @@ -24122,8 +24122,8 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo let releases; if(cache) { - const cacheFilename = external_path_.resolve(`.tmp/releases.json`); - if(!external_fs_.existsSync(cacheFilename)) { + const cacheFilename = __nccwpck_require__.ab + "releases.json"; + if(!external_fs_.existsSync(__nccwpck_require__.ab + "releases.json")) { releases = await octokit.paginate( octokit.rest.repos.listReleases, { @@ -24133,10 +24133,10 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo }, (response) => response.data ); - external_fs_.writeFileSync(cacheFilename, JSON.stringify(releases, null, 2)); + external_fs_.writeFileSync(__nccwpck_require__.ab + "releases.json", JSON.stringify(releases, null, 2)); } else { console.log('Loading releases from cache...'); - releases = JSON.parse(external_fs_.readFileSync(cacheFilename)); + releases = JSON.parse(external_fs_.readFileSync(__nccwpck_require__.ab + "releases.json")); } } else { releases = await octokit.paginate( @@ -24172,9 +24172,10 @@ async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrId, algo releasesToProcess.forEach(release => { const {tag_name, name} = release; - const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/); + const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+(\.\S+)?)/); if(!matches || matches.length < 2) { + console.warn('Could not match version structure in tag name = ', tag_name); return; } diff --git a/.github/actions/nym-hash-releases/src/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs index 584d364a4c..410910f08a 100644 --- a/.github/actions/nym-hash-releases/src/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -210,9 +210,10 @@ export async function createHashesFromReleaseTagOrNameOrId({ releaseTagOrNameOrI releasesToProcess.forEach(release => { const {tag_name, name} = release; - const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+\.\S+)/); + const matches = tag_name.match(/(\S+)-v([0-9]+\.[0-9]+(\.\S+)?)/); if(!matches || matches.length < 2) { + console.warn('Could not match version structure in tag name = ', tag_name); return; } diff --git a/.github/actions/nym-hash-releases/src/run-local.mjs b/.github/actions/nym-hash-releases/src/run-local.mjs index f2fc6addb8..f0998580ae 100644 --- a/.github/actions/nym-hash-releases/src/run-local.mjs +++ b/.github/actions/nym-hash-releases/src/run-local.mjs @@ -1,6 +1,11 @@ import {createHashesFromReleaseTagOrNameOrId} from './create-hashes.mjs'; -await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false}); -await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false}); -await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false}); -await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false}); +const cache = true; + +await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-binaries-v2024.1-marabou', cache, upload: false}); +await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-vpn-desktop-v0.0.8', cache, upload: false, repo: 'nym-vpn-client'}); + +// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 119065724, cache: true, upload: false}); +// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: '119065724', cache: true, upload: false}); +// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'nym-connect-v1.1.19-snickers', cache: true, upload: false}); +// await createHashesFromReleaseTagOrNameOrId({releaseTagOrNameOrId: 'Nym Connect v1.1.19-snickers', cache: true, upload: false}); From 467dc6cf4aa599529b2c7f8e4d633b97b82463e9 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:10:36 +0000 Subject: [PATCH 248/394] GitHub Actions: nym-hash-release: better handling of temp directory --- .github/actions/nym-hash-releases/dist/index.js | 6 ++++-- .github/actions/nym-hash-releases/src/create-hashes.mjs | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js index 9d1c0ec1e0..eee76c7505 100644 --- a/.github/actions/nym-hash-releases/dist/index.js +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -23986,8 +23986,10 @@ async function run(assets, algorithm, filename, cache) { console.warn("cache is set to 'false', but we we no longer support it") } + const directory = external_path_.resolve(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + try { - external_fs_.mkdirSync('.tmp'); + external_fs_.mkdirSync(directory, { recursive: true }); } catch(e) { // ignore } @@ -24002,7 +24004,7 @@ async function run(assets, algorithm, filename, cache) { let sig = null; // cache in `${WORKING_DIR}/.tmp/` - const cacheFilename = __nccwpck_require__.ab + ".tmp/" + asset.name; + const cacheFilename = __nccwpck_require__.ab + "src/" + directory + '/' + asset.name; if(!external_fs_.existsSync(cacheFilename)) { console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); diff --git a/.github/actions/nym-hash-releases/src/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs index 410910f08a..115267d9f2 100644 --- a/.github/actions/nym-hash-releases/src/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -24,8 +24,10 @@ async function run(assets, algorithm, filename, cache) { console.warn("cache is set to 'false', but we we no longer support it") } + const directory = path.resolve(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + try { - fs.mkdirSync('.tmp'); + fs.mkdirSync(directory, { recursive: true }); } catch(e) { // ignore } @@ -40,7 +42,7 @@ async function run(assets, algorithm, filename, cache) { let sig = null; // cache in `${WORKING_DIR}/.tmp/` - const cacheFilename = path.resolve(`.tmp/${asset.name}`); + const cacheFilename = path.resolve(directory, `${asset.name}`); if(!fs.existsSync(cacheFilename)) { console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); From bad74928a1ec522afea5ce66674c42e548e8e340 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:15:36 +0000 Subject: [PATCH 249/394] GitHub Actions: nym-hash-release: resolve temp directory correctly --- .github/actions/nym-hash-releases/dist/index.js | 5 +++-- .github/actions/nym-hash-releases/src/create-hashes.mjs | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js index eee76c7505..69215b67df 100644 --- a/.github/actions/nym-hash-releases/dist/index.js +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -23986,7 +23986,8 @@ async function run(assets, algorithm, filename, cache) { console.warn("cache is set to 'false', but we we no longer support it") } - const directory = external_path_.resolve(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + const directory = external_path_.join(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + console.log('Temporary directory: ', directory); try { external_fs_.mkdirSync(directory, { recursive: true }); @@ -24004,7 +24005,7 @@ async function run(assets, algorithm, filename, cache) { let sig = null; // cache in `${WORKING_DIR}/.tmp/` - const cacheFilename = __nccwpck_require__.ab + "src/" + directory + '/' + asset.name; + const cacheFilename = external_path_.join(directory, `${asset.name}`); if(!external_fs_.existsSync(cacheFilename)) { console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); diff --git a/.github/actions/nym-hash-releases/src/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs index 115267d9f2..b52e93ec60 100644 --- a/.github/actions/nym-hash-releases/src/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -24,7 +24,8 @@ async function run(assets, algorithm, filename, cache) { console.warn("cache is set to 'false', but we we no longer support it") } - const directory = path.resolve(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + const directory = path.join(process.env.RUNNER_TEMP || '.tmp', process.env.GITHUB_RUN_ID || ''); + console.log('Temporary directory: ', directory); try { fs.mkdirSync(directory, { recursive: true }); @@ -42,7 +43,7 @@ async function run(assets, algorithm, filename, cache) { let sig = null; // cache in `${WORKING_DIR}/.tmp/` - const cacheFilename = path.resolve(directory, `${asset.name}`); + const cacheFilename = path.join(directory, `${asset.name}`); if(!fs.existsSync(cacheFilename)) { console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); From e51283f9d3613360c4015e7f298c874f2129b65a Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:30:09 +0000 Subject: [PATCH 250/394] GitHub Actions: nym-hash-release: output more feedback --- .github/actions/nym-hash-releases/dist/index.js | 11 ++++++++--- .../actions/nym-hash-releases/src/create-hashes.mjs | 11 ++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js index 69215b67df..170849c6ed 100644 --- a/.github/actions/nym-hash-releases/dist/index.js +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -23973,10 +23973,14 @@ function getBinInfo(path) { let mode = external_fs_.statSync(path).mode external_fs_.chmodSync(path, mode | 0o111) - const raw = (0,external_child_process_namespaceObject.execSync)(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" }); + const cmd = `${path} build-info --output=json`; + console.log(`🚚 Running ${cmd}...`); + const raw = (0,external_child_process_namespaceObject.execSync)(cmd, { stdio: 'pipe', encoding: "utf8" }); const parsed = JSON.parse(raw) + console.log(` ✅ ok`); return parsed } catch (_) { + console.log(` ❌ failed`); return undefined } } @@ -24007,11 +24011,11 @@ async function run(assets, algorithm, filename, cache) { // cache in `${WORKING_DIR}/.tmp/` const cacheFilename = external_path_.join(directory, `${asset.name}`); if(!external_fs_.existsSync(cacheFilename)) { - console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); + console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); external_fs_.writeFileSync(cacheFilename, buffer); } else { - console.log(`Loading from ${cacheFilename}`); + console.log(`💾 Loading from ${cacheFilename}`); buffer = Buffer.from(external_fs_.readFileSync(cacheFilename)); // console.log('Reading signature from content'); @@ -24096,6 +24100,7 @@ async function run(assets, algorithm, filename, cache) { } } } + console.log(`Completed hashing ${assets.length} files`); return hashes; } diff --git a/.github/actions/nym-hash-releases/src/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs index b52e93ec60..a0c34602d5 100644 --- a/.github/actions/nym-hash-releases/src/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -11,10 +11,14 @@ function getBinInfo(path) { let mode = fs.statSync(path).mode fs.chmodSync(path, mode | 0o111) - const raw = execSync(`${path} build-info --output=json`, { stdio: 'pipe', encoding: "utf8" }); + const cmd = `${path} build-info --output=json`; + console.log(`🚚 Running ${cmd}...`); + const raw = execSync(cmd, { stdio: 'pipe', encoding: "utf8" }); const parsed = JSON.parse(raw) + console.log(` ✅ ok`); return parsed } catch (_) { + console.log(` ❌ failed`); return undefined } } @@ -45,11 +49,11 @@ async function run(assets, algorithm, filename, cache) { // cache in `${WORKING_DIR}/.tmp/` const cacheFilename = path.join(directory, `${asset.name}`); if(!fs.existsSync(cacheFilename)) { - console.log(`Downloading ${asset.browser_download_url}... to ${cacheFilename}`); + console.log(`⬇️ Downloading ${asset.browser_download_url}... to ${cacheFilename} [${numAwaiting} of ${assets.length}]`); buffer = Buffer.from(await fetch(asset.browser_download_url).then(res => res.arrayBuffer())); fs.writeFileSync(cacheFilename, buffer); } else { - console.log(`Loading from ${cacheFilename}`); + console.log(`💾 Loading from ${cacheFilename}`); buffer = Buffer.from(fs.readFileSync(cacheFilename)); // console.log('Reading signature from content'); @@ -134,6 +138,7 @@ async function run(assets, algorithm, filename, cache) { } } } + console.log(`Completed hashing ${assets.length} files`); return hashes; } From 6ebe71c8a25dc180c4815e504dfb4aee61182170 Mon Sep 17 00:00:00 2001 From: Mark Sinclair <mmsinclair@users.noreply.github.com> Date: Wed, 20 Mar 2024 18:52:48 +0000 Subject: [PATCH 251/394] GitHub Actions: nym-hash-release: terminate get build info shell after 3 secs --- .github/actions/nym-hash-releases/dist/index.js | 4 ++-- .github/actions/nym-hash-releases/src/create-hashes.mjs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/actions/nym-hash-releases/dist/index.js b/.github/actions/nym-hash-releases/dist/index.js index 170849c6ed..bd9ba671a3 100644 --- a/.github/actions/nym-hash-releases/dist/index.js +++ b/.github/actions/nym-hash-releases/dist/index.js @@ -23974,8 +23974,8 @@ function getBinInfo(path) { external_fs_.chmodSync(path, mode | 0o111) const cmd = `${path} build-info --output=json`; - console.log(`🚚 Running ${cmd}...`); - const raw = (0,external_child_process_namespaceObject.execSync)(cmd, { stdio: 'pipe', encoding: "utf8" }); + console.log(`🚚 Running ${cmd}... (for max of 3 seconds, then SIGTERM)`); + const raw = (0,external_child_process_namespaceObject.execSync)(cmd, { stdio: 'pipe', encoding: "utf8", timeout: 3000 }); const parsed = JSON.parse(raw) console.log(` ✅ ok`); return parsed diff --git a/.github/actions/nym-hash-releases/src/create-hashes.mjs b/.github/actions/nym-hash-releases/src/create-hashes.mjs index a0c34602d5..6cf4d137cc 100644 --- a/.github/actions/nym-hash-releases/src/create-hashes.mjs +++ b/.github/actions/nym-hash-releases/src/create-hashes.mjs @@ -12,8 +12,8 @@ function getBinInfo(path) { fs.chmodSync(path, mode | 0o111) const cmd = `${path} build-info --output=json`; - console.log(`🚚 Running ${cmd}...`); - const raw = execSync(cmd, { stdio: 'pipe', encoding: "utf8" }); + console.log(`🚚 Running ${cmd}... (for max of 3 seconds, then SIGTERM)`); + const raw = execSync(cmd, { stdio: 'pipe', encoding: "utf8", timeout: 3000 }); const parsed = JSON.parse(raw) console.log(` ✅ ok`); return parsed From c1e67cdc15caa14d440a72a808871c41e268ccfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bogdan-=C8=98tefan=20Neac=C5=9Fu?= <bogdan@nymtech.net> Date: Thu, 21 Mar 2024 13:18:43 +0200 Subject: [PATCH 252/394] Increase subnet range for IPPR (#4487) * Increase subnet range for IPPR * Fix for IPv6 * Fix range * Add unit test * Bump version --- common/ip-packet-requests/src/lib.rs | 3 +- .../ip-packet-router/src/constants.rs | 4 +- .../src/util/generate_new_ip.rs | 38 +++++++++++++++---- 3 files changed, 34 insertions(+), 11 deletions(-) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index d0357d0aa4..6991567d7a 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -9,7 +9,8 @@ pub mod response; // version 3: initial version // version 4: IPv6 support // version 5: Add severity level to info response -pub const CURRENT_VERSION: u8 = 5; +// version 6: Increase the available IPs +pub const CURRENT_VERSION: u8 = 6; #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] pub struct IpPair { diff --git a/service-providers/ip-packet-router/src/constants.rs b/service-providers/ip-packet-router/src/constants.rs index eb7874f902..311087ad2a 100644 --- a/service-providers/ip-packet-router/src/constants.rs +++ b/service-providers/ip-packet-router/src/constants.rs @@ -4,10 +4,10 @@ use std::time::Duration; // The interface used to route traffic pub const TUN_BASE_NAME: &str = "nymtun"; pub const TUN_DEVICE_ADDRESS_V4: Ipv4Addr = Ipv4Addr::new(10, 0, 0, 1); -pub const TUN_DEVICE_NETMASK_V4: Ipv4Addr = Ipv4Addr::new(255, 255, 255, 0); +pub const TUN_DEVICE_NETMASK_V4: Ipv4Addr = Ipv4Addr::new(255, 255, 0, 0); pub const TUN_DEVICE_ADDRESS_V6: Ipv6Addr = Ipv6Addr::new(0x2001, 0xdb8, 0xa160, 0, 0, 0, 0, 0x1); // 2001:db8:a160::1 -pub const TUN_DEVICE_NETMASK_V6: &str = "120"; +pub const TUN_DEVICE_NETMASK_V6: &str = "112"; // We routinely check if any clients needs to be disconnected at this interval pub(crate) const DISCONNECT_TIMER_INTERVAL: Duration = Duration::from_secs(10); diff --git a/service-providers/ip-packet-router/src/util/generate_new_ip.rs b/service-providers/ip-packet-router/src/util/generate_new_ip.rs index 71809cac00..2d2848d821 100644 --- a/service-providers/ip-packet-router/src/util/generate_new_ip.rs +++ b/service-providers/ip-packet-router/src/util/generate_new_ip.rs @@ -6,12 +6,13 @@ use crate::constants::{TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6}; // Find an available IP address in self.connected_clients // TODO: make this nicer -fn generate_random_ips_within_subnet() -> IpPair { - let mut rng = rand::thread_rng(); - // Generate a random number in the range 1-254 - let last_octet = rand::Rng::gen_range(&mut rng, 1..=254); - let ipv4 = Ipv4Addr::new(10, 0, 0, last_octet); - let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_octet as u16); +fn generate_random_ips_within_subnet<R: rand::Rng>(rng: &mut R) -> IpPair { + // Generate a random number in the range 2-65535 + let last_bytes: u16 = rand::Rng::gen_range(rng, 2..=65534); + let before_last_byte = (last_bytes >> 8) as u8; + let last_byte = (last_bytes & 255) as u8; + let ipv4 = Ipv4Addr::new(10, 0, before_last_byte, last_byte); + let ipv6 = Ipv6Addr::new(0x2001, 0x0db8, 0xa160, 0, 0, 0, 0, last_bytes); IpPair::new(ipv4, ipv6) } @@ -32,7 +33,8 @@ pub(crate) fn find_new_ips<T>( connected_clients_ipv4: &HashMap<Ipv4Addr, T>, connected_clients_ipv6: &HashMap<Ipv6Addr, T>, ) -> Option<IpPair> { - let mut new_ips = generate_random_ips_within_subnet(); + let mut rng = rand::thread_rng(); + let mut new_ips = generate_random_ips_within_subnet(&mut rng); let mut tries = 0; let tun_ips = IpPair::new(TUN_DEVICE_ADDRESS_V4, TUN_DEVICE_ADDRESS_V6); @@ -42,7 +44,7 @@ pub(crate) fn find_new_ips<T>( tun_ips, new_ips, ) { - new_ips = generate_random_ips_within_subnet(); + new_ips = generate_random_ips_within_subnet(&mut rng); tries += 1; if tries > 100 { return None; @@ -50,3 +52,23 @@ pub(crate) fn find_new_ips<T>( } Some(new_ips) } + +#[cfg(test)] +mod tests { + use super::*; + use std::collections::HashSet; + + #[test] + fn verify_ip_generation() { + let mut map = HashSet::with_capacity(65533); + let mut rng = rand::rngs::mock::StepRng::new(0, 65540); + for _ in 2..65535 { + let pair = generate_random_ips_within_subnet(&mut rng); + println!("{:?}", pair); + assert!(!map.contains(&pair)); + map.insert(pair); + } + let pair = generate_random_ips_within_subnet(&mut rng); + assert!(map.contains(&pair)); + } +} From cf201cba5364a61cb9a0a27431136648de534e77 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Thu, 21 Mar 2024 14:27:16 +0000 Subject: [PATCH 253/394] only use keplr wallet + add info banner --- explorer/package.json | 3 --- explorer/src/context/cosmos-kit.tsx | 5 +---- explorer/src/pages/Delegations/index.tsx | 13 ++++++++++++- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index 9079de0104..97b7c03b76 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -28,10 +28,7 @@ "@cosmjs/stargate": "^0.32.0", "@cosmjs/tendermint-rpc": "^0.32.0", "@cosmos-kit/core": "^2.8.9", - "@cosmos-kit/cosmostation-extension": "^2.7.10", "@cosmos-kit/keplr-extension": "^2.7.9", - "@cosmos-kit/leap-extension": "^2.7.10", - "@cosmos-kit/ledger": "^2.6.9", "@cosmos-kit/react": "^2.10.10", "@emotion/react": "^11.4.1", "@emotion/styled": "^11.3.0", diff --git a/explorer/src/context/cosmos-kit.tsx b/explorer/src/context/cosmos-kit.tsx index 8fa164bf00..aa497e508a 100644 --- a/explorer/src/context/cosmos-kit.tsx +++ b/explorer/src/context/cosmos-kit.tsx @@ -1,9 +1,6 @@ import React from 'react'; import { ChainProvider } from '@cosmos-kit/react'; import { wallets as keplr } from '@cosmos-kit/keplr-extension'; -import { wallets as ledger } from '@cosmos-kit/ledger'; -import { wallets as cosmosstation } from '@cosmos-kit/cosmostation-extension'; -import { wallets as leap } from '@cosmos-kit/leap-extension'; import { assets, chains } from 'chain-registry'; import { Chain, AssetList } from '@chain-registry/types'; import { VALIDATOR_BASE_URL } from '@src/api/constants'; @@ -57,7 +54,7 @@ const CosmosKitProvider = ({ children }: { children: React.ReactNode }) => { <ChainProvider chains={chainsFixedUp} assetLists={assetsFixedUp} - wallets={[...keplr, ...ledger, ...cosmosstation, ...leap]} + wallets={[...keplr]} endpointOptions={{ endpoints: { nyx: { diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx index 6aabec5f51..9e5d1f6516 100644 --- a/explorer/src/pages/Delegations/index.tsx +++ b/explorer/src/pages/Delegations/index.tsx @@ -1,5 +1,5 @@ import React, { useEffect } from 'react'; -import { Box, Button, Card, Chip, Tooltip, Typography } from '@mui/material'; +import { Alert, Box, Button, Card, Chip, Tooltip, Typography } from '@mui/material'; import { Link, useNavigate } from 'react-router-dom'; import { DelegationModal, DelegationModalProps, Title, UniversalDataGrid } from '@src/components'; import { useWalletContext } from '@src/context/wallet'; @@ -13,6 +13,7 @@ import { useDelegationsContext, } from '@src/context/delegations'; import { urls } from '@src/utils'; +import { Link as NymLink } from '@nymproject/react/link/Link'; const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) => ({ identity: delegation.identityKey, @@ -195,6 +196,15 @@ const DelegationsPage = () => { }} /> )} + + <Alert severity="info" sx={{ mb: 3, fontSize: 'medium' }}> + This is a beta release for mobile delegation via the Nym explorer. If you have any feedback or feature + suggestions reach out to us{' '} + <NymLink underline="always" href="mailto:support@nymte.ch?subject=explorer delegation feedback / request"> + here + </NymLink> + . + </Alert> <Box display="flex" justifyContent="space-between" alignItems="center"> <Title text="Your Delegations" /> <Button variant="contained" color="primary" component={Link} to="/network-components/mixnodes"> @@ -209,6 +219,7 @@ const DelegationsPage = () => { <ConnectKeplrWallet /> </Box> ) : null} + <Card sx={{ mt: 2, From 68e0dd1f29656525efa7c521b41df09da609de2a Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Thu, 21 Mar 2024 14:57:12 +0000 Subject: [PATCH 254/394] update success tx wording --- explorer/src/components/Delegations/DelegateModal.tsx | 2 +- explorer/src/components/Delegations/DelegationModal.tsx | 7 ++++++- explorer/src/pages/Delegations/index.tsx | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/explorer/src/components/Delegations/DelegateModal.tsx b/explorer/src/components/Delegations/DelegateModal.tsx index 3fb9a34ec7..f5c27adccb 100644 --- a/explorer/src/components/Delegations/DelegateModal.tsx +++ b/explorer/src/components/Delegations/DelegateModal.tsx @@ -99,7 +99,7 @@ export const DelegateModal: FCWithChildren<{ onOk({ status: 'success', - message: 'This operation can take up to one hour to process', + message: 'Delegation can take up to one hour to process', transactions: [ { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash }, ], diff --git a/explorer/src/components/Delegations/DelegationModal.tsx b/explorer/src/components/Delegations/DelegationModal.tsx index 6e00092eac..db5b51aefe 100644 --- a/explorer/src/components/Delegations/DelegationModal.tsx +++ b/explorer/src/components/Delegations/DelegationModal.tsx @@ -42,7 +42,12 @@ export const DelegationModal: FCWithChildren< } return ( - <ConfirmationModal open={open} onConfirm={onClose || (() => {})} title="Delegation successful" confirmButton="Done"> + <ConfirmationModal + open={open} + onConfirm={onClose || (() => {})} + title="Transaction successful" + confirmButton="Done" + > <Stack alignItems="center" spacing={2} mb={0}> {message && <Typography>{message}</Typography>} {transactions?.length === 1 && ( diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx index 9e5d1f6516..f4a8e901de 100644 --- a/explorer/src/pages/Delegations/index.tsx +++ b/explorer/src/pages/Delegations/index.tsx @@ -81,7 +81,7 @@ const DelegationsPage = () => { if (tx) { setConfirmationModalProps({ status: 'success', - message: 'Undelegation successful', + message: 'Undelegation can take up to one hour to process', transactions: [ { url: `${urls('MAINNET').blockExplorer}/transaction/${tx.transactionHash}`, hash: tx.transactionHash }, ], From 821865cb6238a851d548d5b99f245497a0faa1c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Thu, 21 Mar 2024 16:56:10 +0100 Subject: [PATCH 255/394] Explictly add rustls to gateway-client (#4471) * Explictly add rustls to gateway-client * fix wasm * formatting --- Cargo.lock | 1 + common/client-core/Cargo.toml | 1 + common/client-libs/gateway-client/Cargo.toml | 7 +++++++ nym-connect/desktop/Cargo.lock | 2 ++ 4 files changed, 11 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index 95685f31c6..05526b9890 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9947,6 +9947,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", + "rustls 0.21.10", "tokio", "tungstenite", ] diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index fdc6a39b7a..775e1e45d9 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -72,6 +72,7 @@ features = ["time"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite] version = "0.20.1" +features = ["rustls"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] workspace = true diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 44b9a58e82..1ded45c46a 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -49,6 +49,13 @@ workspace = true # the choice of this particular tls feature was arbitrary; # if you reckon a different one would be more appropriate, feel free to change it # features = ["native-tls"] +# NOTE: when testing I've run into cases where it's needed to add +# rustls-tls-*-roots feature flags, otherwise we get errors claiming TLS not +# compiled in. However the current setup works fine when connecting to the +# latest gateway version, so let's not force a decision for native vs webpki +# here. +# features = ["rustls", "rustls-tls-native-roots"] +features = ["rustls"] # wasm-only dependencies [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen] diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index f5236af60d..485839a685 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -7273,6 +7273,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", + "rustls 0.21.7", "tokio", "tungstenite", ] @@ -7454,6 +7455,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", + "rustls 0.21.7", "sha1", "thiserror", "url", From f66132fcef8f121946293001f70af4fd8650ce8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Thu, 21 Mar 2024 21:43:55 +0100 Subject: [PATCH 256/394] Use rustls-tls-native-roots by default in gateway-client and client-core --- Cargo.lock | 2 ++ common/client-core/Cargo.toml | 2 +- common/client-libs/gateway-client/Cargo.toml | 8 +------- common/client-libs/gateway-client/src/socket_state.rs | 4 +--- 4 files changed, 5 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 05526b9890..02a9e4886e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9948,7 +9948,9 @@ dependencies = [ "futures-util", "log", "rustls 0.21.10", + "rustls-native-certs", "tokio", + "tokio-rustls 0.24.1", "tungstenite", ] diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 775e1e45d9..124611d348 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -72,7 +72,7 @@ features = ["time"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-tungstenite] version = "0.20.1" -features = ["rustls"] +features = ["rustls-tls-native-roots"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] workspace = true diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 1ded45c46a..218a7894b1 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -49,13 +49,7 @@ workspace = true # the choice of this particular tls feature was arbitrary; # if you reckon a different one would be more appropriate, feel free to change it # features = ["native-tls"] -# NOTE: when testing I've run into cases where it's needed to add -# rustls-tls-*-roots feature flags, otherwise we get errors claiming TLS not -# compiled in. However the current setup works fine when connecting to the -# latest gateway version, so let's not force a decision for native vs webpki -# here. -# features = ["rustls", "rustls-tls-native-roots"] -features = ["rustls"] +features = ["rustls-tls-native-roots"] # wasm-only dependencies [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen] diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index afc50c7233..e834fe3eee 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -44,9 +44,7 @@ pub(crate) fn ws_fd(_conn: &WsConn) -> Option<RawFd> { #[cfg(unix)] match _conn.get_ref() { MaybeTlsStream::Plain(stream) => Some(stream.as_raw_fd()), - &_ => unreachable!( - "If tls features are enabled, the inner stream needs to be unpacked into raw fd" - ), + &_ => None, } #[cfg(not(unix))] None From d020fb0a0bcd0eea7afaa7ac5f8b04d4ccbbb178 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Thu, 21 Mar 2024 21:48:13 +0100 Subject: [PATCH 257/394] Inconsequential typo in Cargo.toml --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 45afdbdb2c..6e322cc32a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -172,7 +172,7 @@ log = "0.4" once_cell = "1.7.2" parking_lot = "0.12.1" rand = "0.8.5" -reqwest = { version = "0.11.22", default_features = false } +reqwest = { version = "0.11.22", default-features = false } schemars = "0.8.1" serde = "1.0.152" serde_json = "1.0.91" From fb5d775857855247ed7a8ae9c7195216e02d3a14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Thu, 21 Mar 2024 22:20:43 +0100 Subject: [PATCH 258/394] Fix warnings for rustc 1.77 --- .../client-core/src/client/key_manager/mod.rs | 2 +- common/dkg/src/bte/proof_chunking.rs | 2 +- nym-connect/desktop/Cargo.lock | 139 +++++++++++++++--- .../nym-sdk/examples/libp2p_shared/queue.rs | 4 +- 4 files changed, 124 insertions(+), 23 deletions(-) diff --git a/common/client-core/src/client/key_manager/mod.rs b/common/client-core/src/client/key_manager/mod.rs index 6fb3858eb7..f01f8e2fbb 100644 --- a/common/client-core/src/client/key_manager/mod.rs +++ b/common/client-core/src/client/key_manager/mod.rs @@ -300,7 +300,7 @@ impl KeyManager { /// Gets an atomically reference counted pointer to [`SharedKey`]. pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { - self.gateway_shared_key.as_ref().map(Arc::clone) + self.gateway_shared_key.clone() } pub fn remove_gateway_key(self) -> KeyManagerBuilder { diff --git a/common/dkg/src/bte/proof_chunking.rs b/common/dkg/src/bte/proof_chunking.rs index 0cbadf5249..d438793275 100644 --- a/common/dkg/src/bte/proof_chunking.rs +++ b/common/dkg/src/bte/proof_chunking.rs @@ -837,7 +837,7 @@ mod tests { let share3 = chunks3.clone().try_into().unwrap(); let shares = vec![share1, share2, share3]; - let chunks = vec![chunks1, chunks2, chunks3]; + let chunks = &[chunks1, chunks2, chunks3]; for (i, pk_i) in pks.iter().enumerate() { let mut ciphertext_chunk_i = Vec::with_capacity(NUM_CHUNKS); diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 485839a685..4d3504d267 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2529,7 +2529,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 0.2.9", "js-sys", "pin-project", "serde", @@ -2664,7 +2664,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.9", "indexmap 1.9.3", "slab", "tokio", @@ -2833,6 +2833,17 @@ dependencies = [ "itoa 1.0.9", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa 1.0.9", +] + [[package]] name = "http-api-client" version = "0.1.0" @@ -2854,7 +2865,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.9", + "pin-project-lite", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite", ] @@ -2912,8 +2946,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "httparse", "httpdate", "itoa 1.0.9", @@ -2925,6 +2959,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa 1.0.9", + "pin-project-lite", + "smallvec", + "tokio", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -2932,8 +2985,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "rustls 0.21.7", "tokio", "tokio-rustls 0.24.1", @@ -2946,12 +2999,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905" dependencies = [ "bytes", - "hyper", + "hyper 0.14.27", "native-tls", "tokio", "tokio-native-tls", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite", + "socket2 0.5.5", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -3754,7 +3823,10 @@ dependencies = [ "dirs 4.0.0", "futures", "gloo-timers", + "http-body-util", "humantime-serde", + "hyper 1.2.0", + "hyper-util", "log", "nym-bandwidth-controller", "nym-config", @@ -3763,6 +3835,7 @@ dependencies = [ "nym-explorer-client", "nym-gateway-client", "nym-gateway-requests", + "nym-metrics", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", @@ -4104,6 +4177,16 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-metrics" +version = "0.1.0" +dependencies = [ + "dashmap", + "lazy_static", + "log", + "prometheus", +] + [[package]] name = "nym-mixnet-contract-common" version = "0.6.0" @@ -5206,6 +5289,21 @@ dependencies = [ "unicode-ident", ] +[[package]] +name = "prometheus" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "449811d15fbdf5ceb5c1144416066429cf82316e2ec8ce0c1f6f8a02e7bbcf8c" +dependencies = [ + "cfg-if", + "fnv", + "lazy_static", + "memchr", + "parking_lot 0.12.1", + "protobuf", + "thiserror", +] + [[package]] name = "prost" version = "0.12.1" @@ -5238,6 +5336,12 @@ dependencies = [ "prost", ] +[[package]] +name = "protobuf" +version = "2.28.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" + [[package]] name = "quick-error" version = "1.2.3" @@ -5487,9 +5591,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "hyper-tls", "ipnet", @@ -6309,9 +6413,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -6787,7 +6891,7 @@ dependencies = [ "glob", "gtk", "heck 0.4.1", - "http", + "http 0.2.9", "ignore", "minisign-verify", "notify-rust", @@ -6887,7 +6991,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "108683199cb18f96d2d4134187bb789964143c845d2d154848dda209191fd769" dependencies = [ "gtk", - "http", + "http 0.2.9", "http-range", "rand 0.8.5", "raw-window-handle", @@ -7451,11 +7555,10 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.9", "httparse", "log", "rand 0.8.5", - "rustls 0.21.7", "sha1", "thiserror", "url", @@ -8265,7 +8368,7 @@ dependencies = [ "glib", "gtk", "html5ever", - "http", + "http 0.2.9", "kuchiki", "libc", "log", diff --git a/sdk/rust/nym-sdk/examples/libp2p_shared/queue.rs b/sdk/rust/nym-sdk/examples/libp2p_shared/queue.rs index 2b59c82877..694b26c65f 100644 --- a/sdk/rust/nym-sdk/examples/libp2p_shared/queue.rs +++ b/sdk/rust/nym-sdk/examples/libp2p_shared/queue.rs @@ -76,9 +76,7 @@ impl MessageQueue { } pub(crate) fn pop(&mut self) -> Option<TransportMessage> { - let Some(head) = self.queue.first() else { - return None; - }; + let head = self.queue.first()?; if head.nonce == self.next_expected_nonce { self.next_expected_nonce = self.next_expected_nonce.wrapping_add(1); From 635ae1118afd19d6e1621da0f67463ef11f9b5cd Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Fri, 22 Mar 2024 11:52:18 +0000 Subject: [PATCH 259/394] Add mobile delegations beta banner --- explorer/src/pages/Delegations/index.tsx | 45 +++++++++++++++++------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/explorer/src/pages/Delegations/index.tsx b/explorer/src/pages/Delegations/index.tsx index f4a8e901de..32e178f2fc 100644 --- a/explorer/src/pages/Delegations/index.tsx +++ b/explorer/src/pages/Delegations/index.tsx @@ -1,9 +1,8 @@ import React, { useEffect } from 'react'; -import { Alert, Box, Button, Card, Chip, Tooltip, Typography } from '@mui/material'; +import { Alert, AlertTitle, Box, Button, Card, Chip, IconButton, Tooltip, Typography } from '@mui/material'; import { Link, useNavigate } from 'react-router-dom'; import { DelegationModal, DelegationModalProps, Title, UniversalDataGrid } from '@src/components'; import { useWalletContext } from '@src/context/wallet'; -import { ConnectKeplrWallet } from '@src/components/Wallet/ConnectKeplrWallet'; import { GridColDef } from '@mui/x-data-grid'; import { unymToNym } from '@src/utils/currency'; import { @@ -13,7 +12,8 @@ import { useDelegationsContext, } from '@src/context/delegations'; import { urls } from '@src/utils'; -import { Link as NymLink } from '@nymproject/react/link/Link'; +import { useClipboard } from 'use-clipboard-copy'; +import { Close } from '@mui/icons-material'; const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) => ({ identity: delegation.identityKey, @@ -24,9 +24,37 @@ const mapToDelegationsRow = (delegation: DelegationWithRewards, index: number) = pending: delegation.pending, }); +const Banner = ({ onClose }: { onClose: () => void }) => { + const { copy } = useClipboard(); + + return ( + <Alert + severity="info" + sx={{ mb: 3, fontSize: 'medium', width: '100%' }} + action={ + <IconButton size="small" onClick={onClose}> + <Close fontSize="small" /> + </IconButton> + } + > + <AlertTitle> Mobile Delegations Beta</AlertTitle> + <Box> + <Typography> + This is a beta release for mobile delegations If you have any feedback or feature suggestions contact us at + support@nymte.ch + <Button size="small" onClick={() => copy('support@nymte.ch')} sx={{ display: 'inline-block' }}> + Copy + </Button> + </Typography> + </Box> + </Alert> + ); +}; + const DelegationsPage = () => { const [confirmationModalProps, setConfirmationModalProps] = React.useState<DelegationModalProps | undefined>(); const [isLoading, setIsLoading] = React.useState(false); + const [showBanner, setShowBanner] = React.useState(true); const { isWalletConnected } = useWalletContext(); const { handleGetDelegations, handleUndelegate, delegations } = useDelegationsContext(); @@ -196,15 +224,7 @@ const DelegationsPage = () => { }} /> )} - - <Alert severity="info" sx={{ mb: 3, fontSize: 'medium' }}> - This is a beta release for mobile delegation via the Nym explorer. If you have any feedback or feature - suggestions reach out to us{' '} - <NymLink underline="always" href="mailto:support@nymte.ch?subject=explorer delegation feedback / request"> - here - </NymLink> - . - </Alert> + {showBanner && <Banner onClose={() => setShowBanner(false)} />} <Box display="flex" justifyContent="space-between" alignItems="center"> <Title text="Your Delegations" /> <Button variant="contained" color="primary" component={Link} to="/network-components/mixnodes"> @@ -216,7 +236,6 @@ const DelegationsPage = () => { <Typography mb={2} variant="h6"> Connect your wallet to view your delegations. </Typography> - <ConnectKeplrWallet /> </Box> ) : null} From bda9f03b21ce3f7cb8831d2dc8e05a59f493d0e2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sat, 23 Mar 2024 03:50:24 +0000 Subject: [PATCH 260/394] Bump webpack-dev-middleware Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.1 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.1...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- .../js-examples/websocket/package-lock.json | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 99ca088e7e..c3ae8a30a0 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -1705,9 +1705,9 @@ } }, "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.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "node_modules/fs.realpath": { @@ -2430,12 +2430,12 @@ } }, "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "dependencies": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" }, "engines": { "node": ">= 4.0.0" @@ -4047,13 +4047,13 @@ } }, "node_modules/webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "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==", "dev": true, "dependencies": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" @@ -5818,9 +5818,9 @@ "dev": true }, "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.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "fs.realpath": { @@ -6346,12 +6346,12 @@ "dev": true }, "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", "dev": true, "requires": { - "fs-monkey": "1.0.3" + "fs-monkey": "^1.0.4" } }, "merge-descriptors": { @@ -7547,13 +7547,13 @@ } }, "webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "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==", "dev": true, "requires": { "colorette": "^2.0.10", - "memfs": "^3.4.1", + "memfs": "^3.4.3", "mime-types": "^2.1.31", "range-parser": "^1.2.1", "schema-utils": "^4.0.0" From f3be91741a5f56a208ea274ed03e4fe25bdea521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 25 Mar 2024 07:26:21 +0100 Subject: [PATCH 261/394] Add ability to create a single bundles IP packet directly --- common/ip-packet-requests/src/codec.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/common/ip-packet-requests/src/codec.rs b/common/ip-packet-requests/src/codec.rs index 86df1ce8f7..4047fec8e7 100644 --- a/common/ip-packet-requests/src/codec.rs +++ b/common/ip-packet-requests/src/codec.rs @@ -34,6 +34,13 @@ impl MultiIpPacketCodec { } } + pub fn bundle_one_packet(packet: Bytes) -> Bytes { + let mut bundled_packets = BytesMut::new(); + bundled_packets.extend_from_slice(&(packet.len() as u16).to_be_bytes()); + bundled_packets.extend_from_slice(&packet); + bundled_packets.freeze() + } + // Append a packet to the buffer and return the buffer if it's full pub fn append_packet(&mut self, packet: Bytes) -> Option<Bytes> { let mut bundled_packets = BytesMut::new(); @@ -47,7 +54,7 @@ impl MultiIpPacketCodec { } // Flush the current buffer and return it. - fn flush_current_buffer(&mut self) -> Bytes { + pub fn flush_current_buffer(&mut self) -> Bytes { let mut output_buffer = BytesMut::new(); std::mem::swap(&mut output_buffer, &mut self.buffer); output_buffer.freeze() From 2fae46d19e352ec61f525b527d2a19e8f7fc3f84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 25 Mar 2024 10:23:06 +0100 Subject: [PATCH 262/394] MixnetClientSender derive Clone --- sdk/rust/nym-sdk/src/mixnet/native_client.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/rust/nym-sdk/src/mixnet/native_client.rs b/sdk/rust/nym-sdk/src/mixnet/native_client.rs index e00322ec71..c4e4c13739 100644 --- a/sdk/rust/nym-sdk/src/mixnet/native_client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/native_client.rs @@ -174,6 +174,7 @@ impl MixnetClient { } } +#[derive(Clone)] pub struct MixnetClientSender { client_input: ClientInput, packet_type: Option<PacketType>, From 9bc3a1d4310f3e422d94412d970f0e620c5bdbe2 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Mon, 25 Mar 2024 10:07:26 +0000 Subject: [PATCH 263/394] Bonding validation update Update operator cost and profit margin validation to previous values (min 40 and min 4) --- .../components/Bonding/forms/mixnodeValidationSchema.ts | 8 ++++---- .../src/components/Bonding/modals/BondMixnodeModal.tsx | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts b/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts index 9d742573aa..4ba393db38 100644 --- a/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts +++ b/nym-wallet/src/components/Bonding/forms/mixnodeValidationSchema.ts @@ -42,17 +42,17 @@ export const mixnodeValidationSchema = Yup.object().shape({ }); const operatingCostAndPmValidation = { - profitMargin: Yup.number().required('Profit Percentage is required').min(7).max(80), + profitMargin: Yup.number().required('Profit Percentage is required').min(4).max(80), operatorCost: Yup.object().shape({ amount: Yup.string() .required('An operating cost is required') // eslint-disable-next-line prefer-arrow-callback .test( 'valid-operating-cost', - 'A valid amount is required (min 500 - max 2000)', + 'A valid amount is required (min 40 - max 2000)', async function isValidAmount(this, value) { - if (value && (!Number(value) || isLessThan(+value, 500) || isGreaterThan(+value, 2000))) { - return this.createError({ message: 'A valid amount is required (min 500 - max 2000)' }); + if (value && (!Number(value) || isLessThan(+value, 40) || isGreaterThan(+value, 2000))) { + return this.createError({ message: 'A valid amount is required (min 40 - max 2000)' }); } return true; }, diff --git a/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx b/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx index 4cfcdfcceb..4e4c39f9cf 100644 --- a/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx +++ b/nym-wallet/src/components/Bonding/modals/BondMixnodeModal.tsx @@ -26,7 +26,7 @@ const defaultMixnodeValues: MixnodeData = { const defaultAmountValues = (denom: CurrencyDenom) => ({ amount: { amount: '100', denom }, - operatorCost: { amount: '500', denom }, + operatorCost: { amount: '40', denom }, profitMargin: '10', tokenPool: 'balance', }); From e352c25b32a9f5fffdb48b5734b02211c46a02cd Mon Sep 17 00:00:00 2001 From: Simon Wicky <simon@nymtech.net> Date: Mon, 25 Mar 2024 11:31:52 +0100 Subject: [PATCH 264/394] mark packet_router's shutdown as success before drop (#4491) --- common/client-libs/gateway-client/src/packet_router.rs | 4 ++++ common/client-libs/gateway-client/src/socket_state.rs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/client-libs/gateway-client/src/packet_router.rs b/common/client-libs/gateway-client/src/packet_router.rs index bf73ecb8ca..cd3cc23d51 100644 --- a/common/client-libs/gateway-client/src/packet_router.rs +++ b/common/client-libs/gateway-client/src/packet_router.rs @@ -69,6 +69,10 @@ impl PacketRouter { } Ok(()) } + + pub fn mark_as_success(&mut self) { + self.shutdown.mark_as_success(); + } } impl GatewayPacketRouter for PacketRouter { diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index e834fe3eee..e58ebbcabd 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -97,7 +97,7 @@ impl PartiallyDelegated { pub(crate) fn split_and_listen_for_mixnet_messages( conn: WsConn, - packet_router: PacketRouter, + mut packet_router: PacketRouter, shared_key: Arc<SharedKeys>, mut shutdown: TaskClient, ) -> Self { @@ -140,6 +140,7 @@ impl PartiallyDelegated { if match ret_err { Err(err) => stream_sender.send(Err(err)), Ok(_) => { + packet_router.mark_as_success(); shutdown.mark_as_success(); stream_sender.send(Ok(stream)) } From 3082cd5d32e56f6721575255b87a0889a1f4e3d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Tue, 26 Mar 2024 11:41:59 +0100 Subject: [PATCH 265/394] Cargo.lock --- Cargo.lock | 80 +++++++++++++++++----------------- nym-connect/desktop/Cargo.lock | 33 +++++++------- 2 files changed, 58 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 02a9e4886e..28efbd69ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,16 +389,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-file-watcher" -version = "0.1.0" -dependencies = [ - "futures", - "log", - "notify", - "tokio", -] - [[package]] name = "async-io" version = "1.13.0" @@ -3301,20 +3291,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -3943,17 +3919,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "ledger" -version = "0.1.0" -dependencies = [ - "bip32", - "k256", - "ledger-transport", - "ledger-transport-hid", - "thiserror", -] - [[package]] name = "ledger-apdu" version = "0.10.0" @@ -4596,9 +4561,9 @@ version = "1.2.4-rc.2" dependencies = [ "async-trait", "futures", - "http-api-client", "js-sys", "nym-bin-common", + "nym-http-api-client", "nym-ordered-buffer", "nym-service-providers-common", "nym-socks5-requests", @@ -5073,6 +5038,16 @@ dependencies = [ "ts-rs", ] +[[package]] +name = "nym-async-file-watcher" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "notify", + "tokio", +] + [[package]] name = "nym-bandwidth-controller" version = "0.1.0" @@ -5695,6 +5670,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-id" version = "0.1.0" @@ -5784,6 +5773,17 @@ dependencies = [ "url", ] +[[package]] +name = "nym-ledger" +version = "0.1.0" +dependencies = [ + "bip32", + "k256", + "ledger-transport", + "ledger-transport-hid", + "thiserror", +] + [[package]] name = "nym-metrics" version = "0.1.0" @@ -5948,7 +5948,6 @@ version = "1.1.33" dependencies = [ "addr", "anyhow", - "async-file-watcher", "async-trait", "bs58 0.5.0", "clap 4.4.7", @@ -5957,6 +5956,7 @@ dependencies = [ "humantime-serde", "ipnetwork 0.20.0", "log", + "nym-async-file-watcher", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", @@ -6051,10 +6051,10 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.4", - "http-api-client", "nym-bin-common", "nym-crypto", "nym-exit-policy", + "nym-http-api-client", "nym-wireguard-types", "schemars", "serde", @@ -6632,7 +6632,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools 0.10.5", "log", "nym-api-requests", @@ -6643,6 +6642,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -6768,7 +6768,6 @@ name = "nymvisor" version = "0.1.0" dependencies = [ "anyhow", - "async-file-watcher", "bytes", "clap 4.4.7", "dotenvy", @@ -6778,6 +6777,7 @@ dependencies = [ "humantime 2.1.0", "humantime-serde", "nix 0.27.1", + "nym-async-file-watcher", "nym-bin-common", "nym-config", "nym-task", diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 4d3504d267..8a87804f61 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2844,20 +2844,6 @@ dependencies = [ "itoa 1.0.9", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -4177,6 +4163,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-metrics" version = "0.1.0" @@ -4590,7 +4590,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools", "log", "nym-api-requests", @@ -4601,6 +4600,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -7378,7 +7378,9 @@ dependencies = [ "futures-util", "log", "rustls 0.21.7", + "rustls-native-certs", "tokio", + "tokio-rustls 0.24.1", "tungstenite", ] @@ -7559,6 +7561,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", + "rustls 0.21.7", "sha1", "thiserror", "url", From 7ea139b6241ce81f1552d8983965cad74b451a03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Tue, 26 Mar 2024 12:03:05 +0100 Subject: [PATCH 266/394] Move request response to version dir (#4501) --- common/ip-packet-requests/src/lib.rs | 11 +++++++++-- common/ip-packet-requests/src/v6/mod.rs | 2 ++ common/ip-packet-requests/src/{ => v6}/request.rs | 0 common/ip-packet-requests/src/{ => v6}/response.rs | 0 4 files changed, 11 insertions(+), 2 deletions(-) create mode 100644 common/ip-packet-requests/src/v6/mod.rs rename common/ip-packet-requests/src/{ => v6}/request.rs (100%) rename common/ip-packet-requests/src/{ => v6}/response.rs (100%) diff --git a/common/ip-packet-requests/src/lib.rs b/common/ip-packet-requests/src/lib.rs index 6991567d7a..e4d555bcf7 100644 --- a/common/ip-packet-requests/src/lib.rs +++ b/common/ip-packet-requests/src/lib.rs @@ -2,9 +2,16 @@ use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::net::{Ipv4Addr, Ipv6Addr}; +// The current version of the protocol. +// The idea here is that we add new request response types at least one version before we start +// using them. +// Also, depending on the version in the client connect message the IPR could respond with a +// matching older version. +pub use v6::request; +pub use v6::response; + pub mod codec; -pub mod request; -pub mod response; +pub mod v6; // version 3: initial version // version 4: IPv6 support diff --git a/common/ip-packet-requests/src/v6/mod.rs b/common/ip-packet-requests/src/v6/mod.rs new file mode 100644 index 0000000000..e0062185c4 --- /dev/null +++ b/common/ip-packet-requests/src/v6/mod.rs @@ -0,0 +1,2 @@ +pub mod request; +pub mod response; diff --git a/common/ip-packet-requests/src/request.rs b/common/ip-packet-requests/src/v6/request.rs similarity index 100% rename from common/ip-packet-requests/src/request.rs rename to common/ip-packet-requests/src/v6/request.rs diff --git a/common/ip-packet-requests/src/response.rs b/common/ip-packet-requests/src/v6/response.rs similarity index 100% rename from common/ip-packet-requests/src/response.rs rename to common/ip-packet-requests/src/v6/response.rs From b73cc165ae32b7c15342a353a09dcd950605bca8 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 09:45:55 +0000 Subject: [PATCH 267/394] Bump follow-redirects in /clients/native/examples/js-examples/websocket Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6. - [Release notes](https://github.com/follow-redirects/follow-redirects/releases) - [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6) --- updated-dependencies: - dependency-name: follow-redirects dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- .../examples/js-examples/websocket/package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index c3ae8a30a0..021a1a0de2 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -1667,9 +1667,9 @@ } }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true, "funding": [ { @@ -5800,9 +5800,9 @@ } }, "follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "dev": true }, "forwarded": { From 658b635509cb20676ffaa8df9fbebe6166c5411b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 09:46:12 +0000 Subject: [PATCH 268/394] Bump express from 4.18.2 to 4.19.2 Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> --- yarn.lock | 40 ++++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/yarn.lock b/yarn.lock index 3ab8f0a0d7..390ec2e7df 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6464,13 +6464,13 @@ bn.js@^5.0.0, bn.js@^5.2.0, bn.js@^5.2.1: resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" @@ -6478,7 +6478,7 @@ body-parser@1.20.1: iconv-lite "0.4.24" on-finished "2.4.1" qs "6.11.0" - raw-body "2.5.1" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -7484,7 +7484,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -7572,10 +7572,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== copy-concurrently@^1.0.0: version "1.0.5" @@ -9535,16 +9535,16 @@ exponential-backoff@^3.1.1: integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== express@^4.17.1, express@^4.17.3, express@^4.18.2: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -16164,10 +16164,10 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" http-errors "2.0.0" From 5b4daa23b6d1eb4b8a902ba19794becee7a21e7d Mon Sep 17 00:00:00 2001 From: Tommy Verrall <tommy@nymtech.net> Date: Wed, 27 Mar 2024 11:20:37 +0100 Subject: [PATCH 269/394] adding recovery docs --- .../WALLET_RECOVERY.md | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md diff --git a/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md b/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md new file mode 100644 index 0000000000..2798d955c8 --- /dev/null +++ b/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md @@ -0,0 +1,55 @@ +# Wallet CLI Recovery Tool Guide + +This guide provides instructions on how to use the Wallet CLI recovery tool to recover your mnemonic phrase using your password, especially useful if you're unable to access your wallet in the usual way. + +## Step 1: Install the CLI Tool + +1. Change directory `cd /nym-wallet/nym-wallet-recovery-cli` from root Nym repository +2. Have rust installed `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh` +3. Once the installation is complete run `cargo build --release` +4. The binary should live here: `nym/nym-wallet/nym-wallet-recovery-cli)` + +## Step 2: Prepare Your Command + +The tool requires specific command-line arguments to specify the password(s) and the file path to your wallet file. The basic structure of the command is as follows: + +```plaintext +nym-recovery-cli --password <YOUR_PASSWORD> --file <PATH_TO_YOUR_WALLET_FILE> [OPTIONS] +``` + +- Replace `<YOUR_PASSWORD>` with your wallet password. +- Replace `<PATH_TO_YOUR_WALLET_FILE>` with the path to your wallet file, where your encrypted mnemonic is stored. + +## Step 3: Running the Tool + +1. Open your terminal or command prompt. +2. Navigate to the directory where the `nym-recovery-cli` tool is located. +3. Execute the command prepared in Step 2. + +Example: + +```bash +./nym-recovery-cli --password "mySecurePassword123" --file "/path/to/mywallet.json" +``` + +To try multiple passwords: + +```bash +./nym-recovery-cli --password "myFirstPassword" --password "mySecondPassword" --file "/path/to/mywallet.json" +``` + +## Step 4: Understanding the Output + +The tool will attempt to decrypt the wallet file. If successful, it will print the decrypted content, including your mnemonic phrase. + +## Step 5: If You Encounter Issues + +- Verify the accuracy of the passwords and file path. +- Ensure there are no typos in the command. +- Make sure the wallet file's path is correctly specified. + +## Additional Options + +- `--raw`: Skips trying to parse the decrypted content, showing raw output instead. + +This guide should help you safely recover your mnemonic phrase. Remember to keep it secure once retrieved. From a04c5c7e920043ad93f765318cad923e2bb5343a Mon Sep 17 00:00:00 2001 From: Tommy Verrall <tommyvez@protonmail.com> Date: Wed, 27 Mar 2024 11:25:57 +0100 Subject: [PATCH 270/394] typos --- nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md b/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md index 2798d955c8..0fa2a6bd0e 100644 --- a/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md +++ b/nym-wallet/nym-wallet-recovery-cli/WALLET_RECOVERY.md @@ -13,7 +13,7 @@ This guide provides instructions on how to use the Wallet CLI recovery tool to r The tool requires specific command-line arguments to specify the password(s) and the file path to your wallet file. The basic structure of the command is as follows: -```plaintext +``` nym-recovery-cli --password <YOUR_PASSWORD> --file <PATH_TO_YOUR_WALLET_FILE> [OPTIONS] ``` @@ -28,13 +28,13 @@ nym-recovery-cli --password <YOUR_PASSWORD> --file <PATH_TO_YOUR_WALLET_FILE> [O Example: -```bash +``` ./nym-recovery-cli --password "mySecurePassword123" --file "/path/to/mywallet.json" ``` To try multiple passwords: -```bash +``` ./nym-recovery-cli --password "myFirstPassword" --password "mySecondPassword" --file "/path/to/mywallet.json" ``` From 400f248e83ccbb40b9630a3651e775d855a3ce2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 11:55:28 +0000 Subject: [PATCH 271/394] cherry-pick 80066d330527b7993cc85833b1b3ae96cc487bb9 to fix wasm build --- .../src/client/packet_statistics_control.rs | 31 +++++++++++++------ 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 8f5aaf434d..a1173bec66 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,8 +3,7 @@ use std::{ time::{Duration, Instant}, }; -use log::{info, warn}; -use nym_metrics::{inc, inc_by, metrics}; +use nym_metrics::{inc, inc_by}; use si_scale::helpers::bibytes2; // Metrics server @@ -508,7 +507,7 @@ impl PacketStatisticsControl { cfg_if::cfg_if! { if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); - let listener = None; + let listener: Option<WasmEmpty> = None; } else { let mut metrics_port = 18000; let listener: Option<TcpListener>; @@ -516,9 +515,9 @@ impl PacketStatisticsControl { let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); match TcpListener::bind(addr).await { Ok(l) => { - info!("###############################"); - info!("Metrics endpoint is at: {:?}", l.local_addr()); - info!("###############################"); + log::info!("###############################"); + log::info!("Metrics endpoint is at: {:?}", l.local_addr()); + log::info!("###############################"); listener = Some(l); break; }, @@ -545,10 +544,11 @@ impl PacketStatisticsControl { } }, // conditional will disable the branch if we're in wasm32-unknown-unknown - result = listener.as_ref().unwrap().accept(), if listener.is_some() => { + // use `_` to calm down clippy when running for wasm + _result = listener.as_ref().unwrap().accept(), if listener.is_some() => { cfg_if::cfg_if! { if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] { - if let Ok((stream, _)) = result { + if let Ok((stream, _)) = _result { let io = TokioIo::new(stream); tokio::task::spawn(async move { @@ -556,11 +556,11 @@ impl PacketStatisticsControl { .serve_connection(io, service_fn(serve_metrics)) .await { - warn!("Error serving connection: {:?}", err); + log::warn!("Error serving connection: {:?}", err); } }); } else { - warn!("Error accepting connection"); + log::warn!("Error accepting connection"); } } } @@ -590,8 +590,19 @@ impl PacketStatisticsControl { } } +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] async fn serve_metrics( _: Request<hyper::body::Incoming>, ) -> Result<Response<Full<Bytes>>, Infallible> { + use nym_metrics::metrics; + Ok(Response::new(Full::new(Bytes::from(metrics!())))) } + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +struct WasmEmpty; + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +impl WasmEmpty { + async fn accept(&self) {} +} From fa1a05886fcf5282067198851c9717ef18f6f036 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 10:28:48 +0000 Subject: [PATCH 272/394] Bump webpack-dev-middleware in /wasm/mix-fetch/internal-dev Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/mix-fetch/internal-dev/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock index f8529616d9..f11847d0ee 100644 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ b/wasm/mix-fetch/internal-dev/yarn.lock @@ -2060,9 +2060,9 @@ webpack-cli@^4.9.2: webpack-merge "^5.7.3" webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + version "5.3.4" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== dependencies: colorette "^2.0.10" memfs "^3.4.3" From 089143cb3ebd2f978e082dedef8e6d822b9b7746 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 27 Mar 2024 12:06:12 +0000 Subject: [PATCH 273/394] Bump webpack-dev-middleware in /wasm/node-tester/internal-dev Bumps [webpack-dev-middleware](https://github.com/webpack/webpack-dev-middleware) from 5.3.3 to 5.3.4. - [Release notes](https://github.com/webpack/webpack-dev-middleware/releases) - [Changelog](https://github.com/webpack/webpack-dev-middleware/blob/v5.3.4/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-middleware/compare/v5.3.3...v5.3.4) --- updated-dependencies: - dependency-name: webpack-dev-middleware dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/node-tester/internal-dev/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/node-tester/internal-dev/yarn.lock b/wasm/node-tester/internal-dev/yarn.lock index 1befaf7e6c..8b6306ff36 100644 --- a/wasm/node-tester/internal-dev/yarn.lock +++ b/wasm/node-tester/internal-dev/yarn.lock @@ -2057,9 +2057,9 @@ webpack-cli@^4.9.2: webpack-merge "^5.7.3" webpack-dev-middleware@^5.3.1: - version "5.3.3" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" - integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + version "5.3.4" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.4.tgz#eb7b39281cbce10e104eb2b8bf2b63fce49a3517" + integrity sha512-BVdTqhhs+0IfoeAf7EoH5WE+exCmqGerHfDM0IL096Px60Tq2Mn9MAbnaGUe6HiMa41KMCYF19gyzZmBcq/o4Q== dependencies: colorette "^2.0.10" memfs "^3.4.3" From d2f482c7430a76cab8057bd5fb815d211c462890 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Thu, 21 Mar 2024 13:51:41 +0100 Subject: [PATCH 274/394] Feature gate metrics-server --- common/client-core/Cargo.toml | 1 + .../client-core/src/client/packet_statistics_control.rs | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 124611d348..ae452c3e9b 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -118,3 +118,4 @@ default = [] cli = ["clap"] fs-surb-storage = ["sqlx"] wasm = ["nym-gateway-client/wasm"] +metrics-server = [] diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index a1173bec66..63c081a509 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -22,6 +22,7 @@ use hyper_util::rt::TokioIo; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::convert::Infallible; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] +#[cfg(feature = "metrics-server")] use std::net::SocketAddr; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use tokio::net::TcpListener; @@ -507,8 +508,8 @@ impl PacketStatisticsControl { cfg_if::cfg_if! { if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); - let listener: Option<WasmEmpty> = None; - } else { + let listener = None; + } else if #[cfg(feature = "metrics-server")] { let mut metrics_port = 18000; let listener: Option<TcpListener>; loop { @@ -527,7 +528,9 @@ impl PacketStatisticsControl { } }; } - + } else { + log::info!("Metrics server is disabled!"); + let listener: Option<TcpListener> = None; } } From 90ff36afe8ae41f6944fc5a3c713fc2e5006ae97 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:08:22 +0100 Subject: [PATCH 275/394] Fix wasm --- .../src/client/packet_statistics_control.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 63c081a509..8e2e16a692 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -27,6 +27,16 @@ use std::net::SocketAddr; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use tokio::net::TcpListener; +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +struct DummyListener; + +#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] +impl DummyListener { + async fn accept(&self) { + log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); + } +} + use crate::spawn_future; // Time interval between reporting packet statistics @@ -508,7 +518,7 @@ impl PacketStatisticsControl { cfg_if::cfg_if! { if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); - let listener = None; + let listener: Option<DummyListener> = None; } else if #[cfg(feature = "metrics-server")] { let mut metrics_port = 18000; let listener: Option<TcpListener>; From 8d46bba8eb775a28e394870d18bcc639f1568d1c Mon Sep 17 00:00:00 2001 From: Drazen <drazen@urch.eu> Date: Wed, 27 Mar 2024 13:34:30 +0100 Subject: [PATCH 276/394] Switch to IntCounter and Gauge --- common/nym-metrics/src/lib.rs | 30 ++++++------ mixnode/src/node/node_statistics.rs | 72 ++++++++++++++--------------- 2 files changed, 50 insertions(+), 52 deletions(-) diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index a9e22909d3..565d62cd5f 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -4,7 +4,7 @@ use log::{debug, warn}; use std::fmt; pub use std::time::Instant; -use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; +use prometheus::{core::Collector, Encoder as _, IntCounter, IntGauge, Registry, TextEncoder}; #[macro_export] macro_rules! prepend_package_name { @@ -24,7 +24,7 @@ macro_rules! prepend_package_name { #[macro_export] macro_rules! inc_by { ($name:literal, $x:expr) => { - $crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as f64); + $crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as i64); }; } @@ -48,7 +48,7 @@ macro_rules! nanos { let start = $crate::Instant::now(); // if the block needs to return something, we can return it let r = $x; - let duration = start.elapsed().as_nanos() as f64; + let duration = start.elapsed().as_nanos() as i64; let name = $crate::prepend_package_name!($name); $crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration); r @@ -66,8 +66,8 @@ pub struct MetricsController { } enum Metric { - C(Box<Counter>), - G(Box<Gauge>), + C(Box<IntCounter>), + G(Box<IntGauge>), } fn fq_name(c: &dyn Collector) -> String { @@ -95,15 +95,15 @@ impl Metric { } #[inline(always)] - fn inc_by(&self, value: f64) { + fn inc_by(&self, value: i64) { match self { - Metric::C(c) => c.inc_by(value), + Metric::C(c) => c.inc_by(value as u64), Metric::G(g) => g.add(value), } } #[inline(always)] - fn set(&self, value: f64) { + fn set(&self, value: i64) { match self { Metric::C(_c) => { warn!("Cannot set value for counter {:?}", self.fq_name()); @@ -145,11 +145,11 @@ impl MetricsController { } } - pub fn set(&self, name: &str, value: f64) { + pub fn set(&self, name: &str, value: i64) { if let Some(metric) = self.registry_index.get(name) { metric.set(value); } else { - let gauge = match Gauge::new(sanitize_metric_name(name), name) { + let gauge = match IntGauge::new(sanitize_metric_name(name), name) { Ok(g) => g, Err(e) => { debug!("Failed to create gauge {:?}:\n{}", name, e); @@ -165,7 +165,7 @@ impl MetricsController { if let Some(metric) = self.registry_index.get(name) { metric.inc(); } else { - let counter = match Counter::new(sanitize_metric_name(name), name) { + let counter = match IntCounter::new(sanitize_metric_name(name), name) { Ok(c) => c, Err(e) => { debug!("Failed to create counter {:?}:\n{}", name, e); @@ -177,11 +177,11 @@ impl MetricsController { } } - pub fn inc_by(&self, name: &str, value: f64) { + pub fn inc_by(&self, name: &str, value: i64) { if let Some(metric) = self.registry_index.get(name) { metric.inc_by(value); } else { - let counter = match Counter::new(sanitize_metric_name(name), name) { + let counter = match IntCounter::new(sanitize_metric_name(name), name) { Ok(c) => c, Err(e) => { debug!("Failed to create counter {:?}:\n{}", name, e); @@ -193,7 +193,7 @@ impl MetricsController { } } - fn register_gauge(&self, metric: Box<Gauge>) { + fn register_gauge(&self, metric: Box<IntGauge>) { let fq_name = metric .desc() .first() @@ -215,7 +215,7 @@ impl MetricsController { } } - fn register_counter(&self, metric: Box<Counter>) { + fn register_counter(&self, metric: Box<IntCounter>) { let fq_name = metric .desc() .first() diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index aaabbb7a30..9ee8d6b850 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -17,7 +17,7 @@ use std::time::{Duration, SystemTime}; use tokio::sync::{RwLock, RwLockReadGuard}; // convenience aliases -type PacketsMap = HashMap<String, f64>; +type PacketsMap = HashMap<String, u64>; type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>; type PacketDataSender = mpsc::UnboundedSender<PacketEvent>; @@ -34,10 +34,10 @@ impl SharedNodeStats { inner: Arc::new(RwLock::new(NodeStats { update_time: now, previous_update_time: now, - packets_received_since_startup: 0., - packets_sent_since_startup_all: 0., - packets_dropped_since_startup_all: 0., - packets_received_since_last_update: 0., + packets_received_since_startup: 0, + packets_sent_since_startup_all: 0, + packets_dropped_since_startup_all: 0, + packets_received_since_last_update: 0, packets_sent_since_last_update: HashMap::new(), packets_explicitly_dropped_since_last_update: HashMap::new(), })), @@ -46,7 +46,7 @@ impl SharedNodeStats { pub(crate) async fn update( &self, - new_received: f64, + new_received: u64, new_sent: PacketsMap, new_dropped: PacketsMap, ) { @@ -68,11 +68,11 @@ impl SharedNodeStats { inc_by!("packets_received_since_startup", new_received); inc_by!( "packets_sent_since_startup_all", - new_sent.values().sum::<f64>() + new_sent.values().sum::<u64>() ); inc_by!( "packets_dropped_since_startup_all", - new_dropped.values().sum::<f64>() + new_dropped.values().sum::<u64>() ); guard.packets_received_since_last_update = new_received; @@ -95,10 +95,10 @@ pub struct NodeStats { previous_update_time: SystemTime, - packets_received_since_startup: f64, - packets_sent_since_startup_all: f64, - packets_dropped_since_startup_all: f64, - packets_received_since_last_update: f64, + packets_received_since_startup: u64, + packets_sent_since_startup_all: u64, + packets_dropped_since_startup_all: u64, + packets_received_since_last_update: u64, // note: sent does not imply forwarded. We don't know if it was delivered successfully packets_sent_since_last_update: PacketsMap, // we know for sure we dropped packets to those destinations @@ -110,10 +110,10 @@ impl Default for NodeStats { NodeStats { update_time: SystemTime::UNIX_EPOCH, previous_update_time: SystemTime::UNIX_EPOCH, - packets_received_since_startup: 0., - packets_sent_since_startup_all: 0., - packets_dropped_since_startup_all: 0., - packets_received_since_last_update: 0., + packets_received_since_startup: 0, + packets_sent_since_startup_all: 0, + packets_dropped_since_startup_all: 0, + packets_received_since_last_update: 0, packets_sent_since_last_update: Default::default(), packets_explicitly_dropped_since_last_update: Default::default(), } @@ -146,21 +146,21 @@ pub struct NodeStatsSimple { #[serde(serialize_with = "humantime_serde::serialize")] previous_update_time: SystemTime, - packets_received_since_startup: f64, + packets_received_since_startup: u64, // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_startup: f64, + packets_sent_since_startup: u64, // we know for sure we dropped those packets - packets_explicitly_dropped_since_startup: f64, + packets_explicitly_dropped_since_startup: u64, - packets_received_since_last_update: f64, + packets_received_since_last_update: u64, // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_last_update: f64, + packets_sent_since_last_update: u64, // we know for sure we dropped those packets - packets_explicitly_dropped_since_last_update: f64, + packets_explicitly_dropped_since_last_update: u64, } pub(crate) enum PacketEvent { @@ -198,14 +198,14 @@ impl CurrentPacketData { async fn increment_sent(&self, destination: String) { let mut unlocked = self.inner.sent.lock().await; - let receiver_count = unlocked.entry(destination).or_insert(0.); - *receiver_count += 1.; + let receiver_count = unlocked.entry(destination).or_insert(0); + *receiver_count += 1; } async fn increment_dropped(&self, destination: String) { let mut unlocked = self.inner.dropped.lock().await; - let dropped_count = unlocked.entry(destination).or_insert(0.); - *dropped_count += 1.; + let dropped_count = unlocked.entry(destination).or_insert(0); + *dropped_count += 1; } async fn acquire_and_reset(&self) -> (u64, PacketsMap, PacketsMap) { @@ -327,9 +327,7 @@ impl StatsUpdater { async fn update_stats(&self) { // grab new data since last update let (received, sent, dropped) = self.current_packet_data.acquire_and_reset().await; - self.current_stats - .update(received as f64, sent, dropped) - .await; + self.current_stats.update(received, sent, dropped).await; } async fn run(&mut self) { @@ -374,17 +372,17 @@ impl PacketStatsConsoleLogger { info!( "Since startup mixed {} packets! ({} in last {} seconds)", stats.packets_sent_since_startup_all, - stats.packets_sent_since_last_update.values().sum::<f64>(), + stats.packets_sent_since_last_update.values().sum::<u64>(), difference_secs, ); - if stats.packets_dropped_since_startup_all > 0. { + if stats.packets_dropped_since_startup_all > 0 { info!( "Since startup dropped {} packets! ({} in last {} seconds)", stats.packets_dropped_since_startup_all, stats .packets_explicitly_dropped_since_last_update .values() - .sum::<f64>(), + .sum::<u64>(), difference_secs, ); } @@ -406,7 +404,7 @@ impl PacketStatsConsoleLogger { "Since startup mixed {} packets!", stats.packets_sent_since_startup_all, ); - if stats.packets_dropped_since_startup_all > 0. { + if stats.packets_dropped_since_startup_all > 0 { info!( "Since startup dropped {} packets!", stats.packets_dropped_since_startup_all, @@ -537,11 +535,11 @@ mod tests { // Get output (stats) let stats = node_stats_pointer.read().await; - assert_eq!(&stats.packets_sent_since_startup_all, &2.); - assert_eq!(&stats.packets_sent_since_last_update.get("foo"), &Some(&2.)); + assert_eq!(&stats.packets_sent_since_startup_all, &2); + assert_eq!(&stats.packets_sent_since_last_update.get("foo"), &Some(&2)); assert_eq!(&stats.packets_sent_since_last_update.len(), &1); - assert_eq!(&stats.packets_received_since_startup, &0.); - assert_eq!(&stats.packets_dropped_since_startup_all, &0.); + assert_eq!(&stats.packets_received_since_startup, &0); + assert_eq!(&stats.packets_dropped_since_startup_all, &0); assert_eq!(metrics!(), "# HELP nym_mixnode_packets_dropped_since_startup_all nym_mixnode_packets_dropped_since_startup_all\n# TYPE nym_mixnode_packets_dropped_since_startup_all counter\nnym_mixnode_packets_dropped_since_startup_all 0\n# HELP nym_mixnode_packets_received_since_startup nym_mixnode_packets_received_since_startup\n# TYPE nym_mixnode_packets_received_since_startup counter\nnym_mixnode_packets_received_since_startup 0\n# HELP nym_mixnode_packets_sent_since_startup_all nym_mixnode_packets_sent_since_startup_all\n# TYPE nym_mixnode_packets_sent_since_startup_all counter\nnym_mixnode_packets_sent_since_startup_all 2\n") } } From 5fe6a2c63dbd61a575b1099c67626e73c7464344 Mon Sep 17 00:00:00 2001 From: durch <durch@users.noreply.github.com> Date: Wed, 27 Mar 2024 16:31:26 +0100 Subject: [PATCH 277/394] Undo duplication --- .../src/client/packet_statistics_control.rs | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 8e2e16a692..630da1b8d7 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -27,16 +27,6 @@ use std::net::SocketAddr; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use tokio::net::TcpListener; -#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] -struct DummyListener; - -#[cfg(all(target_arch = "wasm32", target_os = "unknown"))] -impl DummyListener { - async fn accept(&self) { - log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); - } -} - use crate::spawn_future; // Time interval between reporting packet statistics @@ -518,7 +508,7 @@ impl PacketStatisticsControl { cfg_if::cfg_if! { if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); - let listener: Option<DummyListener> = None; + let listener: Option<WasmEmpty> = None; } else if #[cfg(feature = "metrics-server")] { let mut metrics_port = 18000; let listener: Option<TcpListener>; From 7e6feb0cd2765b024e97e32e20f6d1170ebe96bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 27 Mar 2024 15:41:28 +0000 Subject: [PATCH 278/394] fixed beta clippy: lints + updated cosmwasm to 1.4 --- Cargo.lock | 48 +- Cargo.toml | 18 +- clients/native/Cargo.toml | 2 +- clients/native/src/commands/mod.rs | 1 - .../native/websocket-requests/src/requests.rs | 2 +- .../websocket-requests/src/responses.rs | 2 +- clients/native/websocket-requests/src/text.rs | 2 +- clients/socks5/Cargo.toml | 2 +- clients/socks5/src/commands/mod.rs | 1 - .../src/client/transmission_buffer.rs | 2 + .../client-libs/gateway-client/src/client.rs | 2 +- .../gateway-client/src/socket_state.rs | 2 - .../client_traits/query_client.rs | 2 +- .../client_traits/signing_client.rs | 3 +- .../src/nyxd/cosmwasm_client/types.rs | 2 +- .../src/signing/direct_wallet.rs | 2 +- .../src/validator/account/send_multiple.rs | 3 +- .../mixnet-contract/src/events.rs | 7 +- .../src/rewarding/simulator/mod.rs | 7 +- common/crypto/src/hmac.rs | 1 - common/dkg/src/bte/proof_chunking.rs | 1 - common/exit-policy/src/lib.rs | 2 +- .../src/packet_processor/processor.rs | 2 +- common/mixnode-common/src/verloc/packet.rs | 2 +- common/nymcoconut/src/elgamal.rs | 4 +- common/nymcoconut/src/proofs/mod.rs | 2 +- common/nymcoconut/src/scheme/aggregation.rs | 1 - common/nymcoconut/src/scheme/double_use.rs | 4 +- common/nymcoconut/src/scheme/issuance.rs | 4 +- common/nymcoconut/src/scheme/keygen.rs | 4 +- common/nymcoconut/src/scheme/mod.rs | 4 +- common/nymcoconut/src/scheme/verification.rs | 4 +- common/nymcoconut/src/tests/helpers.rs | 1 - common/nymcoconut/src/traits.rs | 2 +- common/nymcoconut/src/utils.rs | 2 +- .../acknowledgements/src/surb_ack.rs | 2 +- common/nymsphinx/addressing/src/nodes.rs | 2 +- .../anonymous-replies/src/reply_surb.rs | 2 +- common/nymsphinx/chunking/src/fragment.rs | 2 +- common/nymsphinx/cover/src/lib.rs | 2 +- common/nymsphinx/forwarding/src/packet.rs | 2 +- common/nymsphinx/framing/src/codec.rs | 3 +- common/nymsphinx/framing/src/packet.rs | 2 +- common/nymsphinx/params/src/packet_sizes.rs | 2 +- common/nymsphinx/params/src/packet_types.rs | 2 +- common/nymsphinx/src/preparer/mod.rs | 2 +- common/pemstore/src/lib.rs | 2 +- common/socks5-client-core/src/socks/client.rs | 2 +- common/socks5-client-core/src/socks/mod.rs | 2 +- common/socks5/requests/src/request.rs | 2 +- common/topology/src/gateway.rs | 2 +- common/topology/src/lib.rs | 6 +- common/topology/src/mix.rs | 2 +- common/topology/src/serde.rs | 7 + common/types/src/currency.rs | 6 +- .../wasm/client-core/src/config/override.rs | 6 + contracts/Cargo.lock | 576 +++++++----------- contracts/Cargo.toml | 23 +- .../coconut-bandwidth/src/transactions.rs | 2 +- .../coconut-dkg/src/dealings/transactions.rs | 2 - .../coconut-dkg/src/epoch_state/queries.rs | 2 +- .../src/epoch_state/transactions/mod.rs | 1 - .../coconut-dkg/src/epoch_state/utils.rs | 2 +- .../verification_key_shares/transactions.rs | 2 +- contracts/mixnet/src/families/transactions.rs | 7 +- contracts/mixnet/src/gateways/transactions.rs | 9 +- .../mixnet/src/interval/pending_events.rs | 5 +- contracts/mixnet/src/interval/storage.rs | 7 +- contracts/mixnet/src/interval/transactions.rs | 4 +- .../mixnet_contract_settings/transactions.rs | 5 +- contracts/mixnet/src/mixnodes/transactions.rs | 10 +- contracts/mixnet/src/rewards/queries.rs | 5 +- contracts/mixnet/src/rewards/transactions.rs | 6 +- contracts/mixnet/src/support/helpers.rs | 1 + contracts/name-service/src/contract.rs | 2 +- contracts/name-service/src/state/names.rs | 9 +- .../src/contract.rs | 2 +- .../src/state/services.rs | 9 +- contracts/vesting/src/vesting/account/mod.rs | 2 + .../src/vesting/account/vesting_account.rs | 2 +- explorer-api/src/cache/mod.rs | 12 +- gateway/Cargo.toml | 2 +- .../src/registration/handshake/state.rs | 2 +- gateway/gateway-requests/src/types.rs | 2 +- gateway/src/commands/mod.rs | 1 - .../connection_handler/authenticated.rs | 2 +- .../websocket/connection_handler/fresh.rs | 2 +- mixnode/Cargo.toml | 2 +- mixnode/src/commands/mod.rs | 1 - mixnode/src/commands/sign.rs | 2 +- nym-api/Cargo.toml | 2 +- nym-api/src/coconut/client.rs | 3 + nym-api/src/coconut/deposit.rs | 1 - nym-api/src/coconut/dkg/dealing.rs | 2 +- nym-api/src/coconut/dkg/key_validation.rs | 2 +- nym-api/src/coconut/storage/manager.rs | 28 - nym-api/src/coconut/storage/mod.rs | 1 + .../src/coconut/tests/issued_credentials.rs | 2 +- nym-api/src/coconut/tests/mod.rs | 3 +- .../src/network_monitor/monitor/preparer.rs | 2 +- .../src/node_status_api/cache/node_sets.rs | 2 +- nym-api/src/node_status_api/models.rs | 2 +- nym-api/src/node_status_api/utils.rs | 2 +- nym-api/src/support/storage/manager.rs | 2 +- nym-connect/desktop/Cargo.lock | 362 ++++------- nym-connect/desktop/src-tauri/src/menu.rs | 1 + .../src-tauri/src/operations/help/storage.rs | 6 - nym-outfox/src/format.rs | 6 +- nym-outfox/src/packet.rs | 2 - nym-outfox/tests/unittests.rs | 2 - nym-validator-rewarder/src/cli/mod.rs | 1 - nym-wallet/Cargo.lock | 356 ++++------- nym-wallet/src-tauri/src/coin.rs | 4 +- nym-wallet/src-tauri/src/menu.rs | 1 + .../src/operations/mixnet/account.rs | 5 +- .../src-tauri/src/wallet_storage/mod.rs | 2 +- sdk/lib/socks5-listener/src/lib.rs | 1 - .../examples/libp2p_shared/connection.rs | 2 +- .../examples/libp2p_shared/transport.rs | 2 +- .../network-requester/Cargo.toml | 2 +- .../network-requester/src/cli/mod.rs | 1 - .../src/request_filter/allowed_hosts/group.rs | 2 +- tools/nymvisor/src/cli/init.rs | 4 +- tools/nymvisor/src/env.rs | 6 +- wasm/client/src/client.rs | 6 + wasm/client/src/config.rs | 6 + wasm/client/src/encoded_payload_helper.rs | 7 +- wasm/client/src/helpers.rs | 20 +- wasm/mix-fetch/src/config.rs | 5 + wasm/mix-fetch/src/fetch.rs | 6 + wasm/mix-fetch/src/go_bridge.rs | 1 - wasm/node-tester/src/tester.rs | 5 + 132 files changed, 661 insertions(+), 1150 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 28efbd69ef..aeef9d78ec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -798,9 +798,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "bs58" @@ -1355,11 +1355,12 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a6fb22494cf7d23d0c348740e06e5c742070b2991fd41db77bba0bcfbae1a723" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", + "ecdsa 0.16.8", "ed25519-zebra", "k256", "rand_core 0.6.4", @@ -1368,18 +1369,18 @@ dependencies = [ [[package]] name = "cosmwasm-derive" -version = "1.4.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e199424486ea97d6b211db6387fd72e26b4a439d40cc23140b2d8305728055b" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +checksum = "11ae2e971fb831d0c4fa3c8c3d2291cdbdd73786a73d65196dbf983d9b2468af" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1390,9 +1391,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +checksum = "0cadc57fd0825b85bc2f9b972c17da718b9efb4bc17e5935cc2d6036324f853d" dependencies = [ "proc-macro2", "quote", @@ -1401,11 +1402,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +checksum = "e98e19fae6c3f468412f731274b0f9434602722009d6a77432d39c7c4bb09202" dependencies = [ - "base64 0.13.1", + "base64 0.21.4", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -1797,9 +1798,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -1823,23 +1824,24 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver 1.0.20", "serde", "thiserror", ] [[package]] name = "cw20" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1850,9 +1852,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1865,9 +1867,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", diff --git a/Cargo.toml b/Cargo.toml index 6e322cc32a..0c28c45480 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -202,19 +202,19 @@ ff = "0.13.0" # cosmwasm-related -cosmwasm-derive = "=1.3.0" -cosmwasm-schema = "=1.3.0" -cosmwasm-std = "=1.3.0" -# use 0.5.0 as that's the version used by cosmwasm-std 1.3.0 +cosmwasm-derive = "=1.4.3" +cosmwasm-schema = "=1.4.3" +cosmwasm-std = "=1.4.3" +# use 0.5.0 as that's the version used by cosmwasm-std 1.4.3 # (and ideally we don't want to pull the same dependency twice) serde-json-wasm = "=0.5.0" -cosmwasm-storage = "=1.3.0" +cosmwasm-storage = "=1.4.3" # same version as used by cosmwasm cw-utils = "=1.0.1" -cw-storage-plus = "=1.1.0" -cw2 = { version = "=1.1.0" } -cw3 = { version = "=1.1.0" } -cw4 = { version = "=1.1.0" } +cw-storage-plus = "=1.2.0" +cw2 = { version = "=1.1.2" } +cw3 = { version = "=1.1.2" } +cw4 = { version = "=1.1.2" } cw-controllers = { version = "=1.1.0" } # cosmrs-related diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index a85b73e5a4..0da4860a7e 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -4,7 +4,7 @@ version = "1.1.33" authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"] description = "Implementation of the Nym Client" edition = "2021" -rust-version = "1.65" +rust-version = "1.70" license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index ff1b8087fd..907869c72d 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -247,7 +247,6 @@ fn try_load_current_config(id: &str) -> Result<Config, ClientError> { #[cfg(test)] mod tests { use super::*; - use clap::CommandFactory; #[test] fn verify_cli() { diff --git a/clients/native/websocket-requests/src/requests.rs b/clients/native/websocket-requests/src/requests.rs index 645f2edf9c..ba364df7d3 100644 --- a/clients/native/websocket-requests/src/requests.rs +++ b/clients/native/websocket-requests/src/requests.rs @@ -8,7 +8,7 @@ use crate::error::{self, ErrorKind}; use crate::text::ClientRequestText; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE}; -use std::convert::{TryFrom, TryInto}; + use std::mem::size_of; #[repr(u8)] diff --git a/clients/native/websocket-requests/src/responses.rs b/clients/native/websocket-requests/src/responses.rs index f3ac08a4bd..5917203fe3 100644 --- a/clients/native/websocket-requests/src/responses.rs +++ b/clients/native/websocket-requests/src/responses.rs @@ -9,7 +9,7 @@ use crate::text::ServerResponseText; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::{AnonymousSenderTag, SENDER_TAG_SIZE}; use nym_sphinx::receiver::ReconstructedMessage; -use std::convert::TryInto; + use std::mem::size_of; #[repr(u8)] diff --git a/clients/native/websocket-requests/src/text.rs b/clients/native/websocket-requests/src/text.rs index a87a0fb32d..faa0706a55 100644 --- a/clients/native/websocket-requests/src/text.rs +++ b/clients/native/websocket-requests/src/text.rs @@ -7,7 +7,7 @@ use crate::responses::ServerResponse; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use serde::{Deserialize, Serialize}; -use std::convert::{TryFrom, TryInto}; + // local text equivalent of `ClientRequest` for easier serialization + deserialization with serde // TODO: figure out if there's an easy way to avoid defining it diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 2665f6355c..7be3a3e876 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -4,7 +4,7 @@ version = "1.1.33" authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" -rust-version = "1.56" +rust-version = "1.70" license.workspace = true [dependencies] diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index da3166fd7e..63e656faea 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -313,7 +313,6 @@ fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> { #[cfg(test)] mod tests { use super::*; - use clap::CommandFactory; #[test] fn verify_cli() { diff --git a/common/client-core/src/client/transmission_buffer.rs b/common/client-core/src/client/transmission_buffer.rs index 326cfa7f53..d6ee86e861 100644 --- a/common/client-core/src/client/transmission_buffer.rs +++ b/common/client-core/src/client/transmission_buffer.rs @@ -16,6 +16,8 @@ const OLDEST_LANE_SET_SIZE: usize = 4; // As a way of prune connections we also check for timeouts. const MSG_CONSIDERED_STALE_AFTER_SECS: u64 = 10 * 60; +// this trait is apparently not used in wasm +#[allow(dead_code)] pub(crate) trait SizedData { fn data_size(&self) -> usize; } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 77d28ca2a7..fac2f92f45 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -28,7 +28,7 @@ use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; use rand::rngs::OsRng; -use std::convert::TryFrom; + use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index e58ebbcabd..44396a9dd3 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -22,8 +22,6 @@ use tokio::net::TcpStream; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen_futures; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs index 7d389adafb..f63399ce18 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/query_client.rs @@ -32,7 +32,7 @@ use cosmrs::{AccountId, Coin as CosmosCoin, Tx}; use log::trace; use prost::Message; use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; + use std::time::Duration; use tendermint_rpc::{ endpoint::{block::Response as BlockResponse, broadcast, tx::Response as TxResponse}, diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs index d5baa96499..59f510df22 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/client_traits/signing_client.rs @@ -12,7 +12,6 @@ use crate::signing::signer::OfflineSigner; use crate::signing::tx_signer::TxSigner; use crate::signing::SignerData; use async_trait::async_trait; -use cosmrs::abci::GasInfo; use cosmrs::bank::MsgSend; use cosmrs::distribution::MsgWithdrawDelegatorReward; use cosmrs::feegrant::{ @@ -26,7 +25,7 @@ use log::debug; use serde::Serialize; use sha2::Digest; use sha2::Sha256; -use std::convert::TryInto; + use std::time::SystemTime; use tendermint_rpc::endpoint::broadcast; diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs index 757c8ed201..b1e91efa39 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs @@ -28,7 +28,7 @@ use cosmrs::vesting::{ use cosmrs::{AccountId, Any, Coin as CosmosCoin}; use prost::Message; use serde::Serialize; -use std::convert::{TryFrom, TryInto}; + pub use cosmrs::abci::GasInfo; diff --git a/common/client-libs/validator-client/src/signing/direct_wallet.rs b/common/client-libs/validator-client/src/signing/direct_wallet.rs index 3de09502ae..daeb4bc447 100644 --- a/common/client-libs/validator-client/src/signing/direct_wallet.rs +++ b/common/client-libs/validator-client/src/signing/direct_wallet.rs @@ -6,8 +6,8 @@ use crate::signing::{AccountData, Secp256k1Derivation}; use cosmrs::bip32::{DerivationPath, XPrv}; use cosmrs::crypto::secp256k1::SigningKey; use cosmrs::crypto::PublicKey; +use cosmrs::tx; use cosmrs::tx::SignDoc; -use cosmrs::{bip32, tx}; use nym_config::defaults; use thiserror::Error; use zeroize::{Zeroize, ZeroizeOnDrop}; diff --git a/common/commands/src/validator/account/send_multiple.rs b/common/commands/src/validator/account/send_multiple.rs index 9bac94f070..f19b1b6760 100644 --- a/common/commands/src/validator/account/send_multiple.rs +++ b/common/commands/src/validator/account/send_multiple.rs @@ -191,8 +191,7 @@ impl InputFileReader { #[cfg(test)] mod test_multiple_send_input_csv { use super::*; - use nym_validator_client::nyxd::AccountId; - use std::str::FromStr; + #[test] fn works_on_happy_path() { let input_csv = InputFileReader::new("fixtures/test_send_multiple.csv").unwrap(); diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs index 67b4ffd96d..444bfc31d7 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs @@ -8,6 +8,7 @@ use crate::rewarding::RewardDistribution; use crate::{BlockHeight, ContractStateParams, IdentityKeyRef, Interval, Layer, MixId}; pub use contracts_common::events::*; use cosmwasm_std::{Addr, Coin, Decimal, Event}; +use std::fmt::Display; pub const EVENT_VERSION_PREFIX: &str = "v2_"; @@ -54,8 +55,8 @@ impl From<MixnetEventType> for String { } } -impl ToString for MixnetEventType { - fn to_string(&self) -> String { +impl Display for MixnetEventType { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { let event_name = match self { MixnetEventType::MixnodeBonding => "mixnode_bonding", MixnetEventType::PendingPledgeIncrease => "pending_pledge_increase", @@ -95,7 +96,7 @@ impl ToString for MixnetEventType { MixnetEventType::GatewayConfigUpdate => "gateway_config_update", }; - format!("{EVENT_VERSION_PREFIX}{event_name}") + write!(f,"{EVENT_VERSION_PREFIX}{event_name}") } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs index c6575661fd..e723988c91 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs @@ -226,13 +226,8 @@ mod tests { #[cfg(test)] mod single_node_case { use super::*; - use crate::helpers::compare_decimals; - use crate::reward_params::IntervalRewardParams; use crate::rewarding::helpers::truncate_reward_amount; - use crate::Percent; use cosmwasm_std::coin; - use cosmwasm_std::testing::mock_env; - use std::time::Duration; // explicitly marking this as part of #[allow(clippy::unwrap_used)] until // https://github.com/rust-lang/rust-clippy/pull/9686 @@ -599,8 +594,8 @@ mod tests { } #[test] + #[allow(clippy::inconsistent_digit_grouping)] fn multiple_nodes_against_known_values() { - #![allow(clippy::inconsistent_digit_grouping)] // TODO: this test can be further improved by checking values after EVERY interval // rather than just checking the final results diff --git a/common/crypto/src/hmac.rs b/common/crypto/src/hmac.rs index a997b56359..c2678eb0bd 100644 --- a/common/crypto/src/hmac.rs +++ b/common/crypto/src/hmac.rs @@ -52,7 +52,6 @@ where #[cfg(test)] mod tests { use super::*; - use crate::blake3; // TODO: is it somehow possible to make the test not depend on blake3 specifically and // make it more generic? diff --git a/common/dkg/src/bte/proof_chunking.rs b/common/dkg/src/bte/proof_chunking.rs index d438793275..27bc04894a 100644 --- a/common/dkg/src/bte/proof_chunking.rs +++ b/common/dkg/src/bte/proof_chunking.rs @@ -641,7 +641,6 @@ impl ProofOfChunking { #[cfg(test)] mod tests { use super::*; - use crate::bte::Share; use crate::ChunkedShare; // limit number of nodes to some reasonable-ish value, as it significantly affects diff --git a/common/exit-policy/src/lib.rs b/common/exit-policy/src/lib.rs index 4c54e575b9..ebd236deec 100644 --- a/common/exit-policy/src/lib.rs +++ b/common/exit-policy/src/lib.rs @@ -63,7 +63,7 @@ fn parse_address_policy_rule(rule: &str) -> Result<AddressPolicyRule, PolicyErro mod tests { use super::*; use crate::policy::AddressPolicyAction::{Accept, Accept6, Reject, Reject6}; - use crate::policy::{AddressPortPattern, IpPattern, PortRange}; + use crate::policy::IpPattern; #[test] fn parsing_policy() { diff --git a/common/mixnode-common/src/packet_processor/processor.rs b/common/mixnode-common/src/packet_processor/processor.rs index b2fe24a1e9..03a8f37880 100644 --- a/common/mixnode-common/src/packet_processor/processor.rs +++ b/common/mixnode-common/src/packet_processor/processor.rs @@ -13,7 +13,7 @@ use nym_sphinx_types::{ Delay as SphinxDelay, DestinationAddressBytes, NodeAddressBytes, NymPacket, NymProcessedPacket, PrivateKey, ProcessedPacket, }; -use std::convert::TryFrom; + use std::sync::Arc; type ForwardAck = MixPacket; diff --git a/common/mixnode-common/src/verloc/packet.rs b/common/mixnode-common/src/verloc/packet.rs index 3951a7f6b0..77b112836e 100644 --- a/common/mixnode-common/src/verloc/packet.rs +++ b/common/mixnode-common/src/verloc/packet.rs @@ -3,7 +3,7 @@ use crate::verloc::error::RttError; use nym_crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; -use std::convert::TryInto; + pub(crate) struct EchoPacket { sequence_number: u64, diff --git a/common/nymcoconut/src/elgamal.rs b/common/nymcoconut/src/elgamal.rs index 3a1d473b2e..923ffd8be6 100644 --- a/common/nymcoconut/src/elgamal.rs +++ b/common/nymcoconut/src/elgamal.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use core::ops::{Deref, Mul}; -use std::convert::TryFrom; -use std::convert::TryInto; + + use bls12_381::{G1Projective, Scalar}; use group::Curve; diff --git a/common/nymcoconut/src/proofs/mod.rs b/common/nymcoconut/src/proofs/mod.rs index a7a5a97f79..6de4992fd1 100644 --- a/common/nymcoconut/src/proofs/mod.rs +++ b/common/nymcoconut/src/proofs/mod.rs @@ -4,7 +4,7 @@ // TODO: look at https://crates.io/crates/merlin to perhaps use it instead? use std::borrow::Borrow; -use std::convert::TryInto; + use bls12_381::{G1Projective, G2Projective, Scalar}; use digest::generic_array::typenum::Unsigned; diff --git a/common/nymcoconut/src/scheme/aggregation.rs b/common/nymcoconut/src/scheme/aggregation.rs index 3ff5f93bc2..12f0b0cfad 100644 --- a/common/nymcoconut/src/scheme/aggregation.rs +++ b/common/nymcoconut/src/scheme/aggregation.rs @@ -140,7 +140,6 @@ pub fn aggregate_signature_shares( mod tests { use crate::scheme::issuance::sign; use crate::scheme::keygen::ttp_keygen; - use crate::scheme::setup::Parameters; use crate::scheme::verification::verify; use crate::tests::helpers::random_scalars_refs; use bls12_381::G1Projective; diff --git a/common/nymcoconut/src/scheme/double_use.rs b/common/nymcoconut/src/scheme/double_use.rs index c8f89820b4..8817514040 100644 --- a/common/nymcoconut/src/scheme/double_use.rs +++ b/common/nymcoconut/src/scheme/double_use.rs @@ -6,8 +6,8 @@ use crate::traits::{Base58, Bytable}; use crate::utils::try_deserialize_g2_projective; use bls12_381::{G2Affine, G2Projective}; use group::Curve; -use std::convert::TryFrom; -use std::convert::TryInto; + + use std::fmt::{Debug, Formatter}; use std::ops::Deref; diff --git a/common/nymcoconut/src/scheme/issuance.rs b/common/nymcoconut/src/scheme/issuance.rs index 1126e24d98..3c562d4ec3 100644 --- a/common/nymcoconut/src/scheme/issuance.rs +++ b/common/nymcoconut/src/scheme/issuance.rs @@ -1,8 +1,8 @@ // Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use std::convert::TryFrom; -use std::convert::TryInto; + + use std::ops::Neg; use bls12_381::{multi_miller_loop, G1Affine, G1Projective, G2Prepared, Scalar}; diff --git a/common/nymcoconut/src/scheme/keygen.rs b/common/nymcoconut/src/scheme/keygen.rs index 50d735ef92..823bc65759 100644 --- a/common/nymcoconut/src/scheme/keygen.rs +++ b/common/nymcoconut/src/scheme/keygen.rs @@ -4,8 +4,8 @@ use core::borrow::Borrow; use core::iter::Sum; use core::ops::{Add, Mul}; -use std::convert::TryFrom; -use std::convert::TryInto; + + use bls12_381::{G1Projective, G2Projective, Scalar}; use group::Curve; diff --git a/common/nymcoconut/src/scheme/mod.rs b/common/nymcoconut/src/scheme/mod.rs index 58c1ca0f5e..4ccec89b18 100644 --- a/common/nymcoconut/src/scheme/mod.rs +++ b/common/nymcoconut/src/scheme/mod.rs @@ -3,8 +3,8 @@ // TODO: implement https://crates.io/crates/signature traits? -use std::convert::TryFrom; -use std::convert::TryInto; + + use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar}; use group::Curve; diff --git a/common/nymcoconut/src/scheme/verification.rs b/common/nymcoconut/src/scheme/verification.rs index 652a02a04e..ee389deb62 100644 --- a/common/nymcoconut/src/scheme/verification.rs +++ b/common/nymcoconut/src/scheme/verification.rs @@ -12,8 +12,8 @@ use crate::Attribute; use bls12_381::{multi_miller_loop, G1Affine, G2Prepared, G2Projective, Scalar}; use core::ops::Neg; use group::{Curve, Group}; -use std::convert::TryFrom; -use std::convert::TryInto; + + pub use crate::scheme::double_use::BlindedSerialNumber; diff --git a/common/nymcoconut/src/tests/helpers.rs b/common/nymcoconut/src/tests/helpers.rs index 9b3b16d44c..b8bcb6893d 100644 --- a/common/nymcoconut/src/tests/helpers.rs +++ b/common/nymcoconut/src/tests/helpers.rs @@ -122,7 +122,6 @@ pub use random_scalars_refs; #[cfg(test)] pub mod tests { use super::*; - use crate::{KeyPair, Parameters, SecretKey}; use bls12_381::Scalar; use nym_dkg::{bte::decrypt_share, combine_shares, Dealing, NodeIndex}; use rand_chacha::rand_core::SeedableRng; diff --git a/common/nymcoconut/src/traits.rs b/common/nymcoconut/src/traits.rs index d521b133ac..bfeec703ec 100644 --- a/common/nymcoconut/src/traits.rs +++ b/common/nymcoconut/src/traits.rs @@ -7,7 +7,7 @@ use crate::CoconutError; use bls12_381::{G1Affine, G1Projective, Scalar}; use group::GroupEncoding; -use std::convert::TryInto; + pub trait Bytable where diff --git a/common/nymcoconut/src/utils.rs b/common/nymcoconut/src/utils.rs index c2fcd4da3f..fe4a288087 100644 --- a/common/nymcoconut/src/utils.rs +++ b/common/nymcoconut/src/utils.rs @@ -3,7 +3,7 @@ use core::iter::Sum; use core::ops::Mul; -use std::convert::TryInto; + use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField}; use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar}; diff --git a/common/nymsphinx/acknowledgements/src/surb_ack.rs b/common/nymsphinx/acknowledgements/src/surb_ack.rs index 732f84b9ba..a9311be597 100644 --- a/common/nymsphinx/acknowledgements/src/surb_ack.rs +++ b/common/nymsphinx/acknowledgements/src/surb_ack.rs @@ -13,7 +13,7 @@ use nym_sphinx_types::delays::Delay; use nym_sphinx_types::{NymPacket, NymPacketError, MIN_PACKET_SIZE}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; -use std::convert::TryFrom; + use std::time; use thiserror::Error; diff --git a/common/nymsphinx/addressing/src/nodes.rs b/common/nymsphinx/addressing/src/nodes.rs index d1ed9d1790..9569d4bbc8 100644 --- a/common/nymsphinx/addressing/src/nodes.rs +++ b/common/nymsphinx/addressing/src/nodes.rs @@ -3,7 +3,7 @@ use nym_crypto::asymmetric::identity; use nym_sphinx_types::{NodeAddressBytes, NODE_ADDRESS_LENGTH}; -use std::convert::{TryFrom, TryInto}; + use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr}; use thiserror::Error; diff --git a/common/nymsphinx/anonymous-replies/src/reply_surb.rs b/common/nymsphinx/anonymous-replies/src/reply_surb.rs index d38b16fc13..deac5f532d 100644 --- a/common/nymsphinx/anonymous-replies/src/reply_surb.rs +++ b/common/nymsphinx/anonymous-replies/src/reply_surb.rs @@ -12,7 +12,7 @@ use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; use serde::de::{Error as SerdeError, Visitor}; use serde::{Deserialize, Deserializer, Serialize, Serializer}; -use std::convert::TryFrom; + use std::fmt::{self, Formatter}; use std::time; use thiserror::Error; diff --git a/common/nymsphinx/chunking/src/fragment.rs b/common/nymsphinx/chunking/src/fragment.rs index 6dccfa053a..b112bdb47f 100644 --- a/common/nymsphinx/chunking/src/fragment.rs +++ b/common/nymsphinx/chunking/src/fragment.rs @@ -3,7 +3,7 @@ use crate::ChunkingError; use nym_sphinx_params::{SerializedFragmentIdentifier, FRAG_ID_LEN}; -use std::convert::TryInto; + use std::fmt::{self, Debug, Formatter}; // Personal reflection: In hindsight I've spent too much time on relatively too little diff --git a/common/nymsphinx/cover/src/lib.rs b/common/nymsphinx/cover/src/lib.rs index 66142a4cee..23c83c3ed1 100644 --- a/common/nymsphinx/cover/src/lib.rs +++ b/common/nymsphinx/cover/src/lib.rs @@ -16,7 +16,7 @@ use nym_sphinx_params::{ use nym_sphinx_types::NymPacket; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, RngCore}; -use std::convert::TryFrom; + use std::time; use thiserror::Error; diff --git a/common/nymsphinx/forwarding/src/packet.rs b/common/nymsphinx/forwarding/src/packet.rs index 13026a3aaf..97b1419aa1 100644 --- a/common/nymsphinx/forwarding/src/packet.rs +++ b/common/nymsphinx/forwarding/src/packet.rs @@ -4,7 +4,7 @@ use nym_sphinx_addressing::nodes::{NymNodeRoutingAddress, NymNodeRoutingAddressError}; use nym_sphinx_params::{PacketSize, PacketType}; use nym_sphinx_types::{NymPacket, NymPacketError}; -use std::convert::TryFrom; + use std::fmt::{self, Debug, Formatter}; use thiserror::Error; diff --git a/common/nymsphinx/framing/src/codec.rs b/common/nymsphinx/framing/src/codec.rs index c579bc2491..ef7b412fbc 100644 --- a/common/nymsphinx/framing/src/codec.rs +++ b/common/nymsphinx/framing/src/codec.rs @@ -241,8 +241,7 @@ mod packet_encoding { mod decode_will_allocate_enough_bytes_for_next_call { use super::*; use nym_sphinx_params::packet_version::PacketVersion; - use nym_sphinx_params::PacketType; - + #[test] fn for_empty_bytes() { // empty bytes should allocate for header + ack packet diff --git a/common/nymsphinx/framing/src/packet.rs b/common/nymsphinx/framing/src/packet.rs index 3f6953566b..aaae18252e 100644 --- a/common/nymsphinx/framing/src/packet.rs +++ b/common/nymsphinx/framing/src/packet.rs @@ -7,7 +7,7 @@ use nym_sphinx_params::packet_sizes::PacketSize; use nym_sphinx_params::packet_version::PacketVersion; use nym_sphinx_params::PacketType; use nym_sphinx_types::NymPacket; -use std::convert::TryFrom; + #[derive(Debug)] pub struct FramedNymPacket { diff --git a/common/nymsphinx/params/src/packet_sizes.rs b/common/nymsphinx/params/src/packet_sizes.rs index aabfbc26f8..17d85a4efa 100644 --- a/common/nymsphinx/params/src/packet_sizes.rs +++ b/common/nymsphinx/params/src/packet_sizes.rs @@ -8,7 +8,7 @@ use nym_sphinx_types::{header::HEADER_SIZE, PAYLOAD_OVERHEAD_SIZE}; use nym_sphinx_types::{MIN_PACKET_SIZE, MIX_PARAMS_LEN, OUTFOX_PACKET_OVERHEAD}; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; -use std::convert::TryFrom; + use std::fmt::{Debug, Display, Formatter}; use std::str::FromStr; use thiserror::Error; diff --git a/common/nymsphinx/params/src/packet_types.rs b/common/nymsphinx/params/src/packet_types.rs index 6e6925fc68..9d85b0dbfd 100644 --- a/common/nymsphinx/params/src/packet_types.rs +++ b/common/nymsphinx/params/src/packet_types.rs @@ -6,7 +6,7 @@ use crate::PacketSize; use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; + use std::fmt; use thiserror::Error; diff --git a/common/nymsphinx/src/preparer/mod.rs b/common/nymsphinx/src/preparer/mod.rs index f6e19dec7d..b116cdadf9 100644 --- a/common/nymsphinx/src/preparer/mod.rs +++ b/common/nymsphinx/src/preparer/mod.rs @@ -17,7 +17,7 @@ use nym_sphinx_params::{PacketType, ReplySurbKeyDigestAlgorithm, DEFAULT_NUM_MIX use nym_sphinx_types::{Delay, NymPacket}; use nym_topology::{NymTopology, NymTopologyError}; use rand::{CryptoRng, Rng}; -use std::convert::TryFrom; + use std::time::Duration; pub(crate) mod payload; diff --git a/common/pemstore/src/lib.rs b/common/pemstore/src/lib.rs index e883ed60c0..a89bc628c5 100644 --- a/common/pemstore/src/lib.rs +++ b/common/pemstore/src/lib.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::traits::{PemStorableKey, PemStorableKeyPair}; -use pem::{self, Pem}; +use pem::Pem; use std::fs::File; use std::io::{self, Read, Write}; use std::path::{Path, PathBuf}; diff --git a/common/socks5-client-core/src/socks/client.rs b/common/socks5-client-core/src/socks/client.rs index eb1e2db2f6..cca9cd6b53 100644 --- a/common/socks5-client-core/src/socks/client.rs +++ b/common/socks5-client-core/src/socks/client.rs @@ -28,7 +28,7 @@ use std::io; use std::net::SocketAddr; use std::pin::Pin; use tokio::io::{AsyncRead, AsyncReadExt, AsyncWrite, AsyncWriteExt, ReadBuf}; -use tokio::{self, net::TcpStream}; +use tokio::net::TcpStream; #[pin_project(project = StateProject)] enum StreamState { diff --git a/common/socks5-client-core/src/socks/mod.rs b/common/socks5-client-core/src/socks/mod.rs index 36cc580480..4b6cc169f0 100644 --- a/common/socks5-client-core/src/socks/mod.rs +++ b/common/socks5-client-core/src/socks/mod.rs @@ -1,6 +1,6 @@ #![forbid(unsafe_code)] -use std::convert::TryFrom; + use self::types::SocksProxyError; diff --git a/common/socks5/requests/src/request.rs b/common/socks5/requests/src/request.rs index 72241f7ef2..23e844db87 100644 --- a/common/socks5/requests/src/request.rs +++ b/common/socks5/requests/src/request.rs @@ -8,7 +8,7 @@ use crate::{ use nym_service_providers_common::interface::{Serializable, ServiceProviderRequest}; use nym_sphinx_addressing::clients::{Recipient, RecipientFormattingError}; use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; + use std::fmt::{Debug, Formatter}; use tap::TapFallible; use thiserror::Error; diff --git a/common/topology/src/gateway.rs b/common/topology/src/gateway.rs index 9d10b8d2a0..e8b61eedf6 100644 --- a/common/topology/src/gateway.rs +++ b/common/topology/src/gateway.rs @@ -7,7 +7,7 @@ use nym_crypto::asymmetric::{encryption, identity}; use nym_mixnet_contract_common::GatewayBond; use nym_sphinx_addressing::nodes::{NodeIdentity, NymNodeRoutingAddress}; use nym_sphinx_types::Node as SphinxNode; -use std::convert::{TryFrom, TryInto}; + use std::fmt; use std::fmt::Formatter; use std::io; diff --git a/common/topology/src/lib.rs b/common/topology/src/lib.rs index 039e30eb94..54791b26ea 100644 --- a/common/topology/src/lib.rs +++ b/common/topology/src/lib.rs @@ -1,6 +1,9 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::to_string_trait_impl is not on stable as of 1.77 + use crate::filter::VersionFilterable; pub use error::NymTopologyError; use log::warn; @@ -11,7 +14,7 @@ use nym_sphinx_types::Node as SphinxNode; use rand::prelude::SliceRandom; use rand::{CryptoRng, Rng}; use std::collections::BTreeMap; -use std::convert::TryInto; + use std::fmt::{self, Display, Formatter}; use std::io; use std::net::{IpAddr, SocketAddr, ToSocketAddrs}; @@ -51,6 +54,7 @@ pub enum NodeVersion { // this is only implemented for backwards compatibility so we wouldn't need to change everything at once // (also I intentionally implemented `ToString` as opposed to `Display`) +#[allow(clippy::to_string_trait_impl)] impl ToString for NodeVersion { fn to_string(&self) -> String { match self { diff --git a/common/topology/src/mix.rs b/common/topology/src/mix.rs index 0481d5bc16..a4311b1205 100644 --- a/common/topology/src/mix.rs +++ b/common/topology/src/mix.rs @@ -7,7 +7,7 @@ pub use nym_mixnet_contract_common::Layer; use nym_mixnet_contract_common::{MixId, MixNodeBond}; use nym_sphinx_addressing::nodes::NymNodeRoutingAddress; use nym_sphinx_types::Node as SphinxNode; -use std::convert::{TryFrom, TryInto}; + use std::fmt::Formatter; use std::io; use std::net::SocketAddr; diff --git a/common/topology/src/serde.rs b/common/topology/src/serde.rs index 84770a4868..78990d2f11 100644 --- a/common/topology/src/serde.rs +++ b/common/topology/src/serde.rs @@ -1,6 +1,12 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use crate::gateway::GatewayConversionError; use crate::mix::MixnodeConversionError; use crate::{gateway, mix, MixLayer, NymTopology}; @@ -11,6 +17,7 @@ use std::collections::BTreeMap; use std::net::{IpAddr, SocketAddr}; use thiserror::Error; + #[cfg(feature = "wasm-serde-types")] use tsify::Tsify; diff --git a/common/types/src/currency.rs b/common/types/src/currency.rs index 4d381bc10c..1e9cceb521 100644 --- a/common/types/src/currency.rs +++ b/common/types/src/currency.rs @@ -7,7 +7,7 @@ use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::cmp::Ordering; use std::collections::HashMap; -use std::convert::TryFrom; + use std::fmt::{Display, Formatter}; use strum::{Display, EnumString, EnumVariantNames}; @@ -396,9 +396,7 @@ impl TryFrom<DecCoin> for Coin { #[cfg(test)] mod test { use super::*; - use std::convert::TryFrom; - use std::string::ToString; - + #[test] fn dec_value_scale_down() { let dec = DecCoin { diff --git a/common/wasm/client-core/src/config/override.rs b/common/wasm/client-core/src/config/override.rs index e8d66169cf..ed89174539 100644 --- a/common/wasm/client-core/src/config/override.rs +++ b/common/wasm/client-core/src/config/override.rs @@ -1,6 +1,12 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use super::{ AcknowledgementsWasm, CoverTrafficWasm, DebugWasm, GatewayConnectionWasm, ReplySurbsWasm, TopologyWasm, TrafficWasm, diff --git a/contracts/Cargo.lock b/contracts/Cargo.lock index 1b7383f41f..026e514e9c 100644 --- a/contracts/Cargo.lock +++ b/contracts/Cargo.lock @@ -50,6 +50,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.13.1" @@ -106,9 +112,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "bs58" @@ -118,9 +124,9 @@ checksum = "771fe0050b883fcc3ea2359b1a96bcfbc090b7116eae7c3c512c7a083fdf23d3" [[package]] name = "bs58" -version = "0.5.0" +version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5353f36341f7451062466f0b755b96ac3a9547e4d7f6b70d603fc721a7d7896" +checksum = "bf88ba1141d185c399bee5288d850d63b8369520c1eafc32a0430b5b6c287bf4" dependencies = [ "tinyvec", ] @@ -219,31 +225,31 @@ checksum = "520fbf3c07483f94e3e3ca9d0cfd913d7718ef2483d2cfd91c0d9e91474ab913" [[package]] name = "cosmwasm-crypto" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d076a08ec01ed23c4396aca98ec73a38fa1fee5f310465add52b4108181c7a8" +checksum = "c533b66e502ecab30fec23d03eb54ab1d3ce120645a00493459f8510b7a9736f" dependencies = [ "digest 0.10.7", "ed25519-zebra", - "k256", + "k256 0.13.2", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dec361f3c09d7b41221948fc17be9b3c96cb58e55a02f82da36f888a651f2584" +checksum = "d7a2c11de93c565a993b2b687469789146808970b6cfabcd0d44a8915f96da67" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +checksum = "11ae2e971fb831d0c4fa3c8c3d2291cdbdd73786a73d65196dbf983d9b2468af" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -254,9 +260,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +checksum = "0cadc57fd0825b85bc2f9b972c17da718b9efb4bc17e5935cc2d6036324f853d" dependencies = [ "proc-macro2", "quote", @@ -265,11 +271,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +checksum = "e98e19fae6c3f468412f731274b0f9434602722009d6a77432d39c7c4bb09202" dependencies = [ - "base64 0.13.1", + "base64 0.21.0", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -285,9 +291,9 @@ dependencies = [ [[package]] name = "cosmwasm-storage" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ade8cae79dc08a06bcf119c0854ffaed11bd8cb1013c6b04abfe1f51f36211e" +checksum = "8935079712688b8d8d4c036378b38b49d13692621c6fcba96700fadfd5126a18" dependencies = [ "cosmwasm-std", "serde", @@ -314,6 +320,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-common" version = "0.1.6" @@ -393,7 +411,7 @@ dependencies = [ "cw-utils", "derivative", "itertools", - "k256", + "k256 0.11.6", "prost", "schemars", "serde", @@ -402,9 +420,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -428,23 +446,24 @@ dependencies = [ [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver", "serde", "thiserror", ] [[package]] name = "cw20" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -473,9 +492,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -488,9 +507,9 @@ dependencies = [ [[package]] name = "cw3-fixed-multisig" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "705875c68f95870e9707e7b72b50631ddc58c07517d6cc43758306e38921118e" +checksum = "58d7480e78644625c38bb082bfe9a27b01ca58bfcb785690ef43363fd40acf51" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -525,9 +544,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -563,6 +582,16 @@ dependencies = [ "zeroize", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "deranged" version = "0.3.9" @@ -608,6 +637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", + "const-oid", "crypto-common", "subtle 2.4.1", ] @@ -624,10 +654,24 @@ version = "0.14.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" dependencies = [ - "der", - "elliptic-curve", - "rfc6979", - "signature", + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der 0.7.8", + "digest 0.10.7", + "elliptic-curve 0.13.7", + "rfc6979 0.4.0", + "signature 2.2.0", + "spki 0.7.3", ] [[package]] @@ -636,7 +680,7 @@ version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "91cff35c70bba8a626e3185d8cd48cc11b5437e1a5bcd15b9b5fa3c64b6dfee7" dependencies = [ - "signature", + "signature 1.6.4", ] [[package]] @@ -680,16 +724,35 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" dependencies = [ - "base16ct", - "crypto-bigint", - "der", + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", "digest 0.10.7", - "ff", + "ff 0.12.1", "generic-array 0.14.7", - "group", - "pkcs8", + "group 0.12.1", + "pkcs8 0.9.0", "rand_core 0.6.4", - "sec1", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "elliptic-curve" +version = "0.13.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9775b22bc152ad86a0cf23f0f348b884b26add12bf741e7ffc4d4ab2ab4d205" +dependencies = [ + "base16ct 0.2.0", + "crypto-bigint 0.5.5", + "digest 0.10.7", + "ff 0.13.0", + "generic-array 0.14.7", + "group 0.13.0", + "pkcs8 0.10.2", + "rand_core 0.6.4", + "sec1 0.7.3", "subtle 2.4.1", "zeroize", ] @@ -714,36 +777,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "errno" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" -dependencies = [ - "errno-dragonfly", - "libc", - "windows-sys 0.48.0", -] - -[[package]] -name = "errno-dragonfly" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf" -dependencies = [ - "cc", - "libc", -] - -[[package]] -name = "fastrand" -version = "1.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be" -dependencies = [ - "instant", -] - [[package]] name = "ff" version = "0.12.1" @@ -755,10 +788,14 @@ dependencies = [ ] [[package]] -name = "fnv" -version = "1.0.7" +name = "ff" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] [[package]] name = "form_urlencoded" @@ -887,6 +924,7 @@ checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", + "zeroize", ] [[package]] @@ -944,7 +982,18 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" dependencies = [ - "ff", + "ff 0.12.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff 0.13.0", "rand_core 0.6.4", "subtle 2.4.1", ] @@ -958,12 +1007,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hermit-abi" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286" - [[package]] name = "hex" version = "0.4.3" @@ -1025,26 +1068,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "instant" -version = "0.1.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "io-lifetimes" -version = "1.0.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220" -dependencies = [ - "hermit-abi", - "libc", - "windows-sys 0.48.0", -] - [[package]] name = "itertools" version = "0.10.5" @@ -1085,23 +1108,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", "sha2 0.10.6", ] +[[package]] +name = "k256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f01b677d82ef7a676aa37e099defd83a28e15687112cafdd112d60236b6115b" +dependencies = [ + "cfg-if", + "ecdsa 0.16.9", + "elliptic-curve 0.13.7", + "once_cell", + "sha2 0.10.6", + "signature 2.2.0", +] + [[package]] name = "keystream" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c33070833c9ee02266356de0c43f723152bd38bd96ddf52c82b3af10c9138b28" -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - [[package]] name = "libc" version = "0.2.146" @@ -1138,12 +1169,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f" - [[package]] name = "lioness" version = "0.1.2" @@ -1259,7 +1284,7 @@ dependencies = [ name = "nym-contracts-common" version = "0.5.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.5.1", "cosmwasm-schema", "cosmwasm-std", "schemars", @@ -1271,7 +1296,7 @@ dependencies = [ name = "nym-crypto" version = "0.4.0" dependencies = [ - "bs58 0.5.0", + "bs58 0.5.1", "ed25519-dalek", "nym-pemstore", "nym-sphinx-types", @@ -1282,36 +1307,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "nym-ephemera" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cosmwasm-storage", - "cw-controllers", - "cw-multi-test", - "cw-storage-plus", - "cw4", - "cw4-group", - "lazy_static", - "nym-ephemera-common", - "nym-group-contract-common", - "rusty-fork", - "serde", - "thiserror", -] - -[[package]] -name = "nym-ephemera-common" -version = "0.1.0" -dependencies = [ - "cosmwasm-schema", - "cosmwasm-std", - "cw-utils", - "nym-contracts-common", -] - [[package]] name = "nym-group-contract-common" version = "0.1.0" @@ -1520,9 +1515,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" +checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" [[package]] name = "opaque-debug" @@ -1571,8 +1566,18 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" dependencies = [ - "der", - "spki", + "der 0.6.1", + "spki 0.6.0", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der 0.7.8", + "spki 0.7.3", ] [[package]] @@ -1649,12 +1654,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "quick-error" -version = "1.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" - [[package]] name = "quote" version = "1.0.35" @@ -1745,15 +1744,6 @@ dependencies = [ "rand_core 0.5.1", ] -[[package]] -name = "redox_syscall" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" version = "1.8.1" @@ -1775,11 +1765,21 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" dependencies = [ - "crypto-bigint", + "crypto-bigint 0.4.9", "hmac 0.12.1", "zeroize", ] +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac 0.12.1", + "subtle 2.4.1", +] + [[package]] name = "rstest" version = "0.17.0" @@ -1815,38 +1815,12 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.37.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d" -dependencies = [ - "bitflags", - "errno", - "io-lifetimes", - "libc", - "linux-raw-sys", - "windows-sys 0.48.0", -] - [[package]] name = "rustversion" version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4f3208ce4d8448b3f3e7d168a73f5e0c43a61e32930de3bceeccedb388b6bf06" -[[package]] -name = "rusty-fork" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f" -dependencies = [ - "fnv", - "quick-error", - "tempfile", - "wait-timeout", -] - [[package]] name = "ryu" version = "1.0.13" @@ -1855,9 +1829,9 @@ checksum = "f91339c0467de62360649f8d3e185ca8de4224ff281f66000de5eb2a77a79041" [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "schemars_derive", @@ -1867,9 +1841,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -1883,10 +1857,24 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" dependencies = [ - "base16ct", - "der", + "base16ct 0.1.1", + "der 0.6.1", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct 0.2.0", + "der 0.7.8", + "generic-array 0.14.7", + "pkcs8 0.10.2", "subtle 2.4.1", "zeroize", ] @@ -1993,6 +1981,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] + [[package]] name = "slab" version = "0.4.8" @@ -2033,7 +2031,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" dependencies = [ "base64ct", - "der", + "der 0.6.1", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der 0.7.8", ] [[package]] @@ -2079,33 +2087,20 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9fbec84f381d5795b08656e4912bec604d162bff9291d6189a78f4c8ab87998" -dependencies = [ - "cfg-if", - "fastrand", - "redox_syscall", - "rustix", - "windows-sys 0.45.0", -] - [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", @@ -2223,15 +2218,6 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" -[[package]] -name = "wait-timeout" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" -dependencies = [ - "libc", -] - [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -2298,138 +2284,6 @@ version = "0.2.84" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0046fef7e28c3804e5e38bfa31ea2a0f73905319b677e57ebe37e49358989b5d" -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - -[[package]] -name = "windows-sys" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" -dependencies = [ - "windows-targets 0.48.0", -] - -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - -[[package]] -name = "windows-targets" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5" -dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" - -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - -[[package]] -name = "windows_i686_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" - -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - -[[package]] -name = "windows_i686_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.48.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" - [[package]] name = "x25519-dalek" version = "1.1.1" diff --git a/contracts/Cargo.toml b/contracts/Cargo.toml index 74e6e4bb07..245c083ae4 100644 --- a/contracts/Cargo.toml +++ b/contracts/Cargo.toml @@ -4,7 +4,6 @@ members = [ "coconut-bandwidth", "coconut-dkg", "coconut-test", - "ephemera", "mixnet", "mixnet-vesting-integration-tests", "multisig/cw3-flex-multisig", @@ -35,20 +34,20 @@ overflow-checks = true [workspace.dependencies] bs58 = "0.4.0" -cosmwasm-crypto = "=1.3.0" -cosmwasm-derive = "=1.3.0" -cosmwasm-schema = "=1.3.0" -cosmwasm-std = "=1.3.0" -cosmwasm-storage = "=1.3.0" +cosmwasm-crypto = "=1.4.3" +cosmwasm-derive = "=1.4.3" +cosmwasm-schema = "=1.4.3" +cosmwasm-std = "=1.4.3" +cosmwasm-storage = "=1.4.3" cw-controllers = "=1.1.0" cw-multi-test = "=0.16.4" -cw-storage-plus = "=1.1.0" +cw-storage-plus = "=1.2.0" cw-utils = "=1.0.1" -cw2 = "=1.1.0" -cw3 = "=1.1.0" -cw3-fixed-multisig = "=1.1.0" -cw4 = "=1.1.0" -cw20 = "=1.1.0" +cw2 = "=1.1.2" +cw3 = "=1.1.2" +cw3-fixed-multisig = "=1.1.2" +cw4 = "=1.1.2" +cw20 = "=1.1.2" semver = "1.0.21" serde = "1.0.196" diff --git a/contracts/coconut-bandwidth/src/transactions.rs b/contracts/coconut-bandwidth/src/transactions.rs index ecfc524773..8a55ec832f 100644 --- a/contracts/coconut-bandwidth/src/transactions.rs +++ b/contracts/coconut-bandwidth/src/transactions.rs @@ -114,7 +114,7 @@ mod tests { use crate::support::tests::fixtures::spend_credential_data_fixture; use crate::support::tests::helpers::{self, MULTISIG_CONTRACT, POOL_CONTRACT}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::{from_binary, Coin, CosmosMsg, WasmMsg}; + use cosmwasm_std::{from_binary, CosmosMsg, WasmMsg}; use cw_controllers::AdminError; use nym_coconut_bandwidth_contract_common::msg::ExecuteMsg; use nym_multisig_contract_common::msg::ExecuteMsg as MultisigExecuteMsg; diff --git a/contracts/coconut-dkg/src/dealings/transactions.rs b/contracts/coconut-dkg/src/dealings/transactions.rs index 0780f1cfd1..694ce7f3f7 100644 --- a/contracts/coconut-dkg/src/dealings/transactions.rs +++ b/contracts/coconut-dkg/src/dealings/transactions.rs @@ -206,13 +206,11 @@ pub fn try_commit_dealings_chunk( #[cfg(test)] pub(crate) mod tests { use super::*; - use crate::epoch_state::storage::CURRENT_EPOCH; use crate::epoch_state::transactions::{try_advance_epoch_state, try_initiate_dkg}; use crate::support::tests::fixtures::{dealing_metadata_fixture, partial_dealing_fixture}; use crate::support::tests::helpers; use crate::support::tests::helpers::{add_current_dealer, re_register_dealer, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; - use cosmwasm_std::Addr; use nym_coconut_dkg_common::dealer::DealerDetails; use nym_coconut_dkg_common::types::{ContractSafeBytes, TimeConfiguration}; diff --git a/contracts/coconut-dkg/src/epoch_state/queries.rs b/contracts/coconut-dkg/src/epoch_state/queries.rs index 45eb3bcaf5..e15dcc34bf 100644 --- a/contracts/coconut-dkg/src/epoch_state/queries.rs +++ b/contracts/coconut-dkg/src/epoch_state/queries.rs @@ -51,7 +51,7 @@ pub(crate) mod test { use crate::epoch_state::transactions::try_initiate_dkg; use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; - use nym_coconut_dkg_common::types::{EpochState, TimeConfiguration}; + use nym_coconut_dkg_common::types::TimeConfiguration; #[test] fn query_state() { diff --git a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs index 2409ae558c..8922abc1ca 100644 --- a/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs +++ b/contracts/coconut-dkg/src/epoch_state/transactions/mod.rs @@ -92,7 +92,6 @@ pub(crate) mod tests { use crate::support::tests::helpers::{init_contract, ADMIN_ADDRESS}; use cosmwasm_std::testing::{mock_env, mock_info}; use cw_controllers::AdminError; - use nym_coconut_dkg_common::types::EpochState; #[test] fn initialising_dkg() { diff --git a/contracts/coconut-dkg/src/epoch_state/utils.rs b/contracts/coconut-dkg/src/epoch_state/utils.rs index 46fa44a885..c468e2af8b 100644 --- a/contracts/coconut-dkg/src/epoch_state/utils.rs +++ b/contracts/coconut-dkg/src/epoch_state/utils.rs @@ -69,7 +69,7 @@ pub(crate) mod test { use crate::support::tests::helpers::init_contract; use cosmwasm_std::testing::mock_env; use cosmwasm_std::Timestamp; - use nym_coconut_dkg_common::types::{Epoch, TimeConfiguration}; + use nym_coconut_dkg_common::types::TimeConfiguration; #[test] fn checking_state_completion() { diff --git a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs index 9d65e11a89..f8f4534a60 100644 --- a/contracts/coconut-dkg/src/verification_key_shares/transactions.rs +++ b/contracts/coconut-dkg/src/verification_key_shares/transactions.rs @@ -110,7 +110,7 @@ mod tests { use cosmwasm_std::Addr; use cw_controllers::AdminError; use nym_coconut_dkg_common::dealer::DealerDetails; - use nym_coconut_dkg_common::types::{EpochState, TimeConfiguration}; + use nym_coconut_dkg_common::types::TimeConfiguration; #[test] fn current_epoch_id() { diff --git a/contracts/mixnet/src/families/transactions.rs b/contracts/mixnet/src/families/transactions.rs index 912cbc7146..732acddb43 100644 --- a/contracts/mixnet/src/families/transactions.rs +++ b/contracts/mixnet/src/families/transactions.rs @@ -236,8 +236,7 @@ fn _try_head_kick_member( #[cfg(test)] mod test { use super::*; - use crate::families::queries::{get_family_by_head, get_family_by_label}; - use crate::families::storage::is_family_member; + use crate::families::queries::get_family_by_head; use crate::mixnet_contract_settings::storage::minimum_mixnode_pledge; use crate::support::tests::fixtures; use crate::support::tests::test_helpers::TestSetup; @@ -378,7 +377,6 @@ mod test { #[cfg(test)] mod creating_family { use super::*; - use crate::support::tests::test_helpers::TestSetup; #[test] fn fails_for_illegal_proxy() { @@ -412,7 +410,6 @@ mod test { #[cfg(test)] mod joining_family { use super::*; - use crate::support::tests::test_helpers::TestSetup; #[test] fn fails_for_illegal_proxy() { @@ -458,7 +455,6 @@ mod test { #[cfg(test)] mod leaving_family { use super::*; - use crate::support::tests::test_helpers::TestSetup; #[test] fn fails_for_illegal_proxy() { @@ -512,7 +508,6 @@ mod test { #[cfg(test)] mod kicking_family_member { use super::*; - use crate::support::tests::test_helpers::TestSetup; #[test] fn fails_for_illegal_proxy() { diff --git a/contracts/mixnet/src/gateways/transactions.rs b/contracts/mixnet/src/gateways/transactions.rs index bc5a90494e..f747c4c7ba 100644 --- a/contracts/mixnet/src/gateways/transactions.rs +++ b/contracts/mixnet/src/gateways/transactions.rs @@ -250,10 +250,6 @@ pub mod tests { use super::*; use crate::contract::execute; use crate::gateways::queries; - use crate::gateways::transactions::{ - try_add_gateway, try_add_gateway_on_behalf, try_remove_gateway_on_behalf, - try_update_gateway_config, try_update_gateway_config_on_behalf, - }; use crate::interval::pending_events; use crate::mixnet_contract_settings::storage::minimum_gateway_pledge; use crate::support::tests; @@ -261,10 +257,7 @@ pub mod tests { use crate::support::tests::fixtures::{good_gateway_pledge, good_mixnode_pledge}; use crate::support::tests::test_helpers::TestSetup; use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{Addr, BankMsg, Response, Uint128}; - use mixnet_contract_common::error::MixnetContractError; - use mixnet_contract_common::events::new_gateway_unbonding_event; - use mixnet_contract_common::gateway::GatewayConfigUpdate; + use cosmwasm_std::Uint128; use mixnet_contract_common::ExecuteMsg; #[test] diff --git a/contracts/mixnet/src/interval/pending_events.rs b/contracts/mixnet/src/interval/pending_events.rs index 03e0ea2c46..6ba77faa6d 100644 --- a/contracts/mixnet/src/interval/pending_events.rs +++ b/contracts/mixnet/src/interval/pending_events.rs @@ -490,7 +490,7 @@ mod tests { #[cfg(test)] mod delegating { use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{coin, to_binary, CosmosMsg, Decimal, WasmMsg}; + use cosmwasm_std::{coin, to_binary, CosmosMsg, WasmMsg}; use mixnet_contract_common::rewarding::helpers::truncate_reward_amount; @@ -1984,9 +1984,6 @@ mod tests { #[cfg(test)] mod changing_mix_cost_params { use cosmwasm_std::coin; - - use mixnet_contract_common::Percent; - use crate::support::tests::fixtures::TEST_COIN_DENOM; use super::*; diff --git a/contracts/mixnet/src/interval/storage.rs b/contracts/mixnet/src/interval/storage.rs index 04f3aa999a..24666db431 100644 --- a/contracts/mixnet/src/interval/storage.rs +++ b/contracts/mixnet/src/interval/storage.rs @@ -173,7 +173,6 @@ mod tests { use crate::support::tests::fixtures; use crate::support::tests::test_helpers::TestSetup; use cosmwasm_std::testing::mock_dependencies; - use cosmwasm_std::Order; use rand_chacha::rand_core::RngCore; fn read_entire_set(storage: &dyn Storage) -> HashMap<MixId, RewardedSetNodeStatus> { @@ -202,7 +201,7 @@ mod tests { assert_eq!(standby, current_set.get(&7).unwrap()); assert_eq!(standby, current_set.get(&4).unwrap()); assert_eq!(standby, current_set.get(&1).unwrap()); - assert!(current_set.get(&42).is_none()); + assert!(!current_set.contains_key(&42)); update_rewarded_set(store, 2, vec![2, 5, 6, 3, 4]).unwrap(); let current_set = read_entire_set(store); @@ -213,8 +212,8 @@ mod tests { assert_eq!(standby, current_set.get(&3).unwrap()); assert_eq!(standby, current_set.get(&4).unwrap()); // those no longer are in the rewarded set - assert!(current_set.get(&7).is_none()); - assert!(current_set.get(&1).is_none()); + assert!(!current_set.contains_key(&7)); + assert!(!current_set.contains_key(&1)); } #[test] diff --git a/contracts/mixnet/src/interval/transactions.rs b/contracts/mixnet/src/interval/transactions.rs index 0392368389..0eae4fed7b 100644 --- a/contracts/mixnet/src/interval/transactions.rs +++ b/contracts/mixnet/src/interval/transactions.rs @@ -406,12 +406,11 @@ mod tests { mod performing_pending_epoch_actions { use super::*; use crate::support::tests::fixtures::TEST_COIN_DENOM; - use cosmwasm_std::{coin, coins, wasm_execute, Addr, BankMsg, Empty, SubMsg}; + use cosmwasm_std::{coin, coins, wasm_execute, BankMsg, Empty, SubMsg}; use mixnet_contract_common::events::{ new_active_set_update_event, new_delegation_on_unbonded_node_event, new_undelegation_event, }; - use mixnet_contract_common::pending_events::PendingEpochEventKind; #[test] fn without_limit_executes_all_actions() { @@ -1009,7 +1008,6 @@ mod tests { use mixnet_contract_common::events::{ new_delegation_on_unbonded_node_event, new_rewarding_params_update_event, }; - use mixnet_contract_common::pending_events::PendingEpochEventKind; use mixnet_contract_common::reward_params::IntervalRewardingParamsUpdate; #[test] diff --git a/contracts/mixnet/src/mixnet_contract_settings/transactions.rs b/contracts/mixnet/src/mixnet_contract_settings/transactions.rs index 72f5226e1f..5aed1d45ea 100644 --- a/contracts/mixnet/src/mixnet_contract_settings/transactions.rs +++ b/contracts/mixnet/src/mixnet_contract_settings/transactions.rs @@ -62,12 +62,9 @@ pub mod tests { use crate::constants::{INITIAL_GATEWAY_PLEDGE_AMOUNT, INITIAL_MIXNODE_PLEDGE_AMOUNT}; use crate::mixnet_contract_settings::queries::query_rewarding_validator_address; use crate::mixnet_contract_settings::storage::rewarding_denom; - use crate::mixnet_contract_settings::transactions::try_update_contract_settings; use crate::support::tests::test_helpers; use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{Addr, Coin, Response, Uint128}; - use mixnet_contract_common::error::MixnetContractError; - use mixnet_contract_common::ContractStateParams; + use cosmwasm_std::{Addr, Coin, Uint128}; #[test] fn update_contract_rewarding_validtor_address() { diff --git a/contracts/mixnet/src/mixnodes/transactions.rs b/contracts/mixnet/src/mixnodes/transactions.rs index bfd1508cf7..00b000a43e 100644 --- a/contracts/mixnet/src/mixnodes/transactions.rs +++ b/contracts/mixnet/src/mixnodes/transactions.rs @@ -501,7 +501,7 @@ pub mod tests { use mixnet_contract_common::mixnode::PendingMixNodeChanges; use mixnet_contract_common::{ - EpochState, EpochStatus, ExecuteMsg, Layer, LayerDistribution, Percent, + EpochState, EpochStatus, ExecuteMsg, LayerDistribution, Percent, }; use crate::contract::execute; @@ -1188,13 +1188,9 @@ pub mod tests { #[cfg(test)] mod increasing_mixnode_pledge { - use mixnet_contract_common::mixnode::PendingMixNodeChanges; - use mixnet_contract_common::{EpochState, EpochStatus}; - use crate::mixnodes::helpers::tests::{ setup_mix_combinations, OWNER_UNBONDED, OWNER_UNBONDED_LEFTOVER, OWNER_UNBONDING, }; - use crate::support::tests::test_helpers::TestSetup; use super::*; @@ -1496,13 +1492,9 @@ pub mod tests { #[cfg(test)] mod decreasing_mixnode_pledge { - use mixnet_contract_common::mixnode::PendingMixNodeChanges; - use mixnet_contract_common::{EpochState, EpochStatus}; - use crate::mixnodes::helpers::tests::{ setup_mix_combinations, OWNER_UNBONDED, OWNER_UNBONDED_LEFTOVER, OWNER_UNBONDING, }; - use crate::support::tests::test_helpers::TestSetup; use super::*; diff --git a/contracts/mixnet/src/rewards/queries.rs b/contracts/mixnet/src/rewards/queries.rs index 8b7ae13b4e..59f3799b56 100644 --- a/contracts/mixnet/src/rewards/queries.rs +++ b/contracts/mixnet/src/rewards/queries.rs @@ -251,8 +251,6 @@ mod tests { use crate::mixnodes::transactions::try_remove_mixnode; use crate::support::tests::fixtures::TEST_COIN_DENOM; use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{coin, Decimal}; - use mixnet_contract_common::rewarding::helpers::truncate_reward; #[test] fn for_non_existent_node() { @@ -412,8 +410,7 @@ mod tests { use crate::support::tests::fixtures::TEST_COIN_DENOM; use crate::support::tests::test_helpers::get_bank_send_msg; use cosmwasm_std::testing::mock_info; - use cosmwasm_std::{coin, Decimal}; - use mixnet_contract_common::rewarding::helpers::truncate_reward; + #[test] fn for_non_existent_delegation() { diff --git a/contracts/mixnet/src/rewards/transactions.rs b/contracts/mixnet/src/rewards/transactions.rs index 19ca0e8c83..9aa417ae7c 100644 --- a/contracts/mixnet/src/rewards/transactions.rs +++ b/contracts/mixnet/src/rewards/transactions.rs @@ -404,8 +404,6 @@ pub mod tests { #[cfg(test)] mod epoch_state_is_correctly_updated { - use mixnet_contract_common::EpochState; - use super::*; #[test] @@ -1950,7 +1948,7 @@ pub mod tests { #[cfg(test)] mod updating_active_set { - use mixnet_contract_common::{EpochState, EpochStatus}; + use mixnet_contract_common::EpochStatus; use crate::support::tests::test_helpers::TestSetup; @@ -2157,7 +2155,7 @@ pub mod tests { mod updating_rewarding_params { use cosmwasm_std::Decimal; - use mixnet_contract_common::{EpochState, EpochStatus}; + use mixnet_contract_common::EpochStatus; use crate::support::tests::test_helpers::{assert_decimals, TestSetup}; diff --git a/contracts/mixnet/src/support/helpers.rs b/contracts/mixnet/src/support/helpers.rs index 094d96eaba..12c02a675a 100644 --- a/contracts/mixnet/src/support/helpers.rs +++ b/contracts/mixnet/src/support/helpers.rs @@ -11,6 +11,7 @@ use mixnet_contract_common::{EpochState, EpochStatus, IdentityKeyRef, MixId, Mix use vesting_contract_common::messages::ExecuteMsg as VestingContractExecuteMsg; // helper trait to attach `Msg` to a response if it's provided +#[allow(dead_code)] pub(crate) trait AttachOptionalMessage<T> { fn add_optional_message(self, msg: Option<impl Into<CosmosMsg<T>>>) -> Self; } diff --git a/contracts/name-service/src/contract.rs b/contracts/name-service/src/contract.rs index 35294382c8..43a560450b 100644 --- a/contracts/name-service/src/contract.rs +++ b/contracts/name-service/src/contract.rs @@ -120,7 +120,7 @@ mod tests { testing::{mock_dependencies, mock_env, mock_info}, Addr, Coin, }; - use nym_name_service_common::{msg::ExecuteMsg, NameId, RegisteredName}; + use nym_name_service_common::{NameId, RegisteredName}; const DENOM: &str = "unym"; diff --git a/contracts/name-service/src/state/names.rs b/contracts/name-service/src/state/names.rs index 813a2fe85e..8d552a8626 100644 --- a/contracts/name-service/src/state/names.rs +++ b/contracts/name-service/src/state/names.rs @@ -159,12 +159,9 @@ mod tests { }; use rstest::rstest; - use crate::{ - test_helpers::{ - fixture::{name_fixture, name_fixture_full}, - transactions::instantiate_test_contract, - }, - NameServiceError, + use crate::test_helpers::{ + fixture::{name_fixture, name_fixture_full}, + transactions::instantiate_test_contract, }; use super::*; diff --git a/contracts/service-provider-directory/src/contract.rs b/contracts/service-provider-directory/src/contract.rs index 9a760c7788..886ea79826 100644 --- a/contracts/service-provider-directory/src/contract.rs +++ b/contracts/service-provider-directory/src/contract.rs @@ -125,7 +125,7 @@ mod tests { testing::{mock_dependencies, mock_env, mock_info}, Addr, Coin, }; - use nym_service_provider_directory_common::{msg::ExecuteMsg, Service, ServiceId}; + use nym_service_provider_directory_common::{Service, ServiceId}; const DENOM: &str = "unym"; diff --git a/contracts/service-provider-directory/src/state/services.rs b/contracts/service-provider-directory/src/state/services.rs index d88ebf6722..f7c4697b45 100644 --- a/contracts/service-provider-directory/src/state/services.rs +++ b/contracts/service-provider-directory/src/state/services.rs @@ -127,12 +127,9 @@ mod tests { }; use rstest::rstest; - use crate::{ - test_helpers::{ - fixture::{service_fixture, service_fixture_with_address}, - transactions::instantiate_test_contract, - }, - SpContractError, + use crate::test_helpers::{ + fixture::{service_fixture, service_fixture_with_address}, + transactions::instantiate_test_contract, }; use super::*; diff --git a/contracts/vesting/src/vesting/account/mod.rs b/contracts/vesting/src/vesting/account/mod.rs index 7d016fd130..c09b6057b5 100644 --- a/contracts/vesting/src/vesting/account/mod.rs +++ b/contracts/vesting/src/vesting/account/mod.rs @@ -162,6 +162,7 @@ pub(crate) trait StorableVestingAccountExt: VestingAccount { storage: &mut dyn Storage, ) -> Result<(), VestingContractError>; + #[allow(dead_code)] fn total_delegations_for_mix( &self, mix_id: MixId, @@ -182,6 +183,7 @@ pub(crate) trait StorableVestingAccountExt: VestingAccount { Ok(amount) } + #[allow(dead_code)] fn total_delegations_at_timestamp( &self, storage: &dyn Storage, diff --git a/contracts/vesting/src/vesting/account/vesting_account.rs b/contracts/vesting/src/vesting/account/vesting_account.rs index 1cb51aae19..6406df460d 100644 --- a/contracts/vesting/src/vesting/account/vesting_account.rs +++ b/contracts/vesting/src/vesting/account/vesting_account.rs @@ -149,7 +149,7 @@ impl VestingAccount for Account { storage: &mut dyn Storage, ) -> Result<(), VestingContractError> { delete_account(self.owner_address(), storage)?; - self.owner_address = to_address.to_owned(); + to_address.clone_into(&mut self.owner_address); save_account(self, storage)?; Ok(()) } diff --git a/explorer-api/src/cache/mod.rs b/explorer-api/src/cache/mod.rs index 74448f4417..b951073ed1 100644 --- a/explorer-api/src/cache/mod.rs +++ b/explorer-api/src/cache/mod.rs @@ -41,10 +41,10 @@ where .collect() } - pub(crate) fn get<Q: ?Sized>(&self, key: &Q) -> Option<V> + pub(crate) fn get<Q>(&self, key: &Q) -> Option<V> where K: Borrow<Q>, - Q: Hash + Eq, + Q: ?Sized + Hash + Eq, { self.inner .get(key) @@ -63,19 +63,19 @@ where } #[allow(unused)] - pub(crate) fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> + pub(crate) fn remove<Q>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, - Q: Hash + Eq, + Q: ?Sized + Hash + Eq, { self.inner.remove(key).map(|item| item.value) } #[allow(unused)] - pub(crate) fn remove_if_expired<Q: ?Sized>(&mut self, key: &Q) -> Option<V> + pub(crate) fn remove_if_expired<Q>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, - Q: Hash + Eq, + Q: ?Sized + Hash + Eq, { if self.inner.get(key)?.has_expired() { self.remove(key) diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 90ef9195ca..01d1aaf9c8 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -11,7 +11,7 @@ authors = [ ] description = "Implementation of the Nym Mixnet Gateway" edition = "2021" -rust-version = "1.56" +rust-version = "1.70" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/gateway/gateway-requests/src/registration/handshake/state.rs b/gateway/gateway-requests/src/registration/handshake/state.rs index 046f523f76..6212a919b5 100644 --- a/gateway/gateway-requests/src/registration/handshake/state.rs +++ b/gateway/gateway-requests/src/registration/handshake/state.rs @@ -15,7 +15,7 @@ use nym_crypto::{ }; use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewaySharedKeyHkdfAlgorithm}; use rand::{CryptoRng, RngCore}; -use std::convert::TryInto; + use std::str::FromStr; use std::time::Duration; use tungstenite::Message as WsMessage; diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 58e82c0221..04fcb0c8a8 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -18,7 +18,7 @@ use nym_sphinx::params::packet_sizes::PacketSize; use nym_sphinx::params::{GatewayEncryptionAlgorithm, GatewayIntegrityHmacAlgorithm}; use nym_sphinx::DestinationAddressBytes; use serde::{Deserialize, Serialize}; -use std::convert::{TryFrom, TryInto}; + use std::str::FromStr; use std::string::FromUtf8Error; use thiserror::Error; diff --git a/gateway/src/commands/mod.rs b/gateway/src/commands/mod.rs index f3b1adac7c..4f9d46d7df 100644 --- a/gateway/src/commands/mod.rs +++ b/gateway/src/commands/mod.rs @@ -69,7 +69,6 @@ pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { #[cfg(test)] mod tests { use super::*; - use clap::CommandFactory; #[test] fn verify_cli() { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 7a06f36697..24e0393f9d 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -32,7 +32,7 @@ use nym_sphinx::forwarding::packet::MixPacket; use nym_task::TaskClient; use nym_validator_client::coconut::CoconutApiError; use rand::{CryptoRng, Rng}; -use std::{convert::TryFrom, process, time::Duration}; +use std::{process, time::Duration}; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 93ef0508fd..539026ad5a 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -20,7 +20,7 @@ use nym_gateway_requests::{ use nym_mixnet_client::forwarder::MixForwardingSender; use nym_sphinx::DestinationAddressBytes; use rand::{CryptoRng, Rng}; -use std::{convert::TryFrom, sync::Arc, time::Duration}; +use std::{sync::Arc, time::Duration}; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index db0b3786db..af2442fd02 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -12,7 +12,7 @@ authors = [ ] description = "Implementation of a Loopix-based Mixnode" edition = "2021" -rust-version = "1.58.1" +rust-version = "1.70" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/mixnode/src/commands/mod.rs b/mixnode/src/commands/mod.rs index 706bbab77d..34b75e701a 100644 --- a/mixnode/src/commands/mod.rs +++ b/mixnode/src/commands/mod.rs @@ -152,7 +152,6 @@ fn try_load_current_config(id: &str) -> Result<Config, MixnodeError> { #[cfg(test)] mod tests { use super::*; - use clap::CommandFactory; #[test] fn verify_cli() { diff --git a/mixnode/src/commands/sign.rs b/mixnode/src/commands/sign.rs index 2604a72d1c..8225649707 100644 --- a/mixnode/src/commands/sign.rs +++ b/mixnode/src/commands/sign.rs @@ -10,7 +10,7 @@ use nym_bin_common::output_format::OutputFormat; use nym_crypto::asymmetric::identity; use nym_types::helpers::ConsoleSigningOutput; use nym_validator_client::nyxd; -use std::convert::TryFrom; + use super::version_check; diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 10baf737d5..68b94fdc0a 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -11,7 +11,7 @@ authors = [ "Drazen Urch <durch@users.noreply.github.com>", ] edition = "2021" -rust-version = "1.56" +rust-version = "1.70.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index 45ebe7758e..3b65d83649 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -65,6 +65,7 @@ pub trait Client { dealer: String, ) -> Result<DealerDealingsStatusResponse>; + #[allow(dead_code)] async fn get_dealing_status( &self, epoch_id: EpochId, @@ -72,8 +73,10 @@ pub trait Client { dealing_index: DealingIndex, ) -> Result<DealingStatusResponse>; + async fn get_current_dealers(&self) -> Result<Vec<DealerDetails>>; + #[allow(dead_code)] async fn get_dealing_metadata( &self, epoch_id: EpochId, diff --git a/nym-api/src/coconut/deposit.rs b/nym-api/src/coconut/deposit.rs index 8448342c08..985e9fadaa 100644 --- a/nym-api/src/coconut/deposit.rs +++ b/nym-api/src/coconut/deposit.rs @@ -75,7 +75,6 @@ mod test { use super::*; use crate::coconut::tests::{tx_entry_fixture, voucher_fixture}; use cosmwasm_std::coin; - use nym_api_requests::coconut::BlindSignRequestBody; use nym_coconut::BlindSignRequest; use nym_coconut_bandwidth_contract_common::events::DEPOSITED_FUNDS_EVENT_TYPE; use nym_credentials::coconut::bandwidth::CredentialType; diff --git a/nym-api/src/coconut/dkg/dealing.rs b/nym-api/src/coconut/dkg/dealing.rs index 6c4074af72..7cbd4fa80f 100644 --- a/nym-api/src/coconut/dkg/dealing.rs +++ b/nym-api/src/coconut/dkg/dealing.rs @@ -125,7 +125,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> { // update the state with the dealing information self.state .dealing_exchange_state_mut(epoch_id)? - .generated_dealings = dealings.clone(); + .generated_dealings.clone_from(&dealings); Ok(dealings) } diff --git a/nym-api/src/coconut/dkg/key_validation.rs b/nym-api/src/coconut/dkg/key_validation.rs index 68068d30b6..4daa0da601 100644 --- a/nym-api/src/coconut/dkg/key_validation.rs +++ b/nym-api/src/coconut/dkg/key_validation.rs @@ -234,7 +234,7 @@ impl<R: RngCore + CryptoRng> DkgController<R> { } let votes = self.generate_votes(epoch_id).await?; - self.state.key_validation_state_mut(epoch_id)?.votes = votes.clone(); + self.state.key_validation_state_mut(epoch_id)?.votes.clone_from(&votes); // send the votes for (proposal, vote) in votes { diff --git a/nym-api/src/coconut/storage/manager.rs b/nym-api/src/coconut/storage/manager.rs index 313a2db047..8cea9ef898 100644 --- a/nym-api/src/coconut/storage/manager.rs +++ b/nym-api/src/coconut/storage/manager.rs @@ -8,34 +8,6 @@ use thiserror::Error; #[async_trait] pub trait CoconutStorageManagerExt { - /// Creates new encrypted blinded signature response entry for a given deposit tx hash. - /// - /// # Arguments - /// - /// * `tx_hash`: hash of the deposit transaction. - /// * `blinded_signature_response`: the encrypted blinded signature response. - #[deprecated] - async fn insert_blinded_signature_response( - &self, - _tx_hash: &str, - _blinded_signature_response: &str, - ) -> Result<(), sqlx::Error> { - Ok(()) - } - - /// Tries to obtain encrypted blinded signature response for a given transaction hash. - /// - /// # Arguments - /// - /// * `tx_hash`: transaction hash of the deposit. - #[deprecated] - async fn get_blinded_signature_response( - &self, - _tx_hash: &str, - ) -> Result<Option<String>, sqlx::Error> { - Ok(None) - } - /// Gets the information about all issued partial credentials in this (coconut) epoch. /// /// # Arguments diff --git a/nym-api/src/coconut/storage/mod.rs b/nym-api/src/coconut/storage/mod.rs index 45cecf1f23..1b29f51b43 100644 --- a/nym-api/src/coconut/storage/mod.rs +++ b/nym-api/src/coconut/storage/mod.rs @@ -23,6 +23,7 @@ pub trait CoconutStorageExt { epoch_id: EpochId, ) -> Result<Option<EpochCredentials>, NymApiStorageError>; + #[allow(dead_code)] async fn create_epoch_credentials_entry( &self, epoch_id: EpochId, diff --git a/nym-api/src/coconut/tests/issued_credentials.rs b/nym-api/src/coconut/tests/issued_credentials.rs index ef64c38da8..fadfdad4e8 100644 --- a/nym-api/src/coconut/tests/issued_credentials.rs +++ b/nym-api/src/coconut/tests/issued_credentials.rs @@ -209,7 +209,7 @@ async fn issued_credentials() { let parsed_response: IssuedCredentialsResponse = serde_json::from_str(&response.into_string().await.unwrap()).unwrap(); assert_eq!(parsed_response.credentials[&5], issued5); - assert!(parsed_response.credentials.get(&13).is_none()); + assert!(!parsed_response.credentials.contains_key(&13)); let response = test_fixture .rocket diff --git a/nym-api/src/coconut/tests/mod.rs b/nym-api/src/coconut/tests/mod.rs index 0cdb60a1b5..c89d30ee3d 100644 --- a/nym-api/src/coconut/tests/mod.rs +++ b/nym-api/src/coconut/tests/mod.rs @@ -943,8 +943,7 @@ impl super::client::Client for DummyClient { if chain .multisig_contract .votes - .get(&(voter.clone(), proposal_id)) - .is_some() + .contains_key(&(voter.clone(), proposal_id)) { todo!("already voted"); } diff --git a/nym-api/src/network_monitor/monitor/preparer.rs b/nym-api/src/network_monitor/monitor/preparer.rs index b9a585033b..4e9cfda0fd 100644 --- a/nym-api/src/network_monitor/monitor/preparer.rs +++ b/nym-api/src/network_monitor/monitor/preparer.rs @@ -16,7 +16,7 @@ use nym_sphinx::params::{PacketSize, PacketType}; use nym_topology::{gateway, mix}; use rand_07::{rngs::ThreadRng, seq::SliceRandom, thread_rng, Rng}; use std::collections::{HashMap, HashSet}; -use std::convert::TryInto; + use std::fmt::{self, Display, Formatter}; use std::sync::Arc; use std::time::Duration; diff --git a/nym-api/src/node_status_api/cache/node_sets.rs b/nym-api/src/node_status_api/cache/node_sets.rs index ed20298887..872b532d2a 100644 --- a/nym-api/src/node_status_api/cache/node_sets.rs +++ b/nym-api/src/node_status_api/cache/node_sets.rs @@ -135,7 +135,7 @@ pub(super) async fn annotate_nodes_with_details( compute_apy_from_reward(&mixnode, reward_estimate, current_interval); let family = mix_to_family - .get(&mixnode.bond_information.identity().to_string()) + .get(mixnode.bond_information.identity()) .cloned(); annotated.push(MixNodeBondAnnotated { diff --git a/nym-api/src/node_status_api/models.rs b/nym-api/src/node_status_api/models.rs index ca5e4fd6d1..7d13d81522 100644 --- a/nym-api/src/node_status_api/models.rs +++ b/nym-api/src/node_status_api/models.rs @@ -21,7 +21,7 @@ use schemars::gen::SchemaGenerator; use schemars::schema::{InstanceType, Schema}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; + use thiserror::Error; use time::OffsetDateTime; diff --git a/nym-api/src/node_status_api/utils.rs b/nym-api/src/node_status_api/utils.rs index 54d5b50d9a..598fba5679 100644 --- a/nym-api/src/node_status_api/utils.rs +++ b/nym-api/src/node_status_api/utils.rs @@ -6,7 +6,7 @@ use crate::node_status_api::{FIFTEEN_MINUTES, ONE_HOUR}; use crate::storage::models::NodeStatus; use log::warn; use nym_mixnet_contract_common::MixId; -use std::convert::TryInto; + use time::OffsetDateTime; // A temporary helper structs used to produce reports for active nodes. diff --git a/nym-api/src/support/storage/manager.rs b/nym-api/src/support/storage/manager.rs index 298f0c04a2..953483d9c1 100644 --- a/nym-api/src/support/storage/manager.rs +++ b/nym-api/src/support/storage/manager.rs @@ -7,7 +7,7 @@ use crate::support::storage::models::{ ActiveGateway, ActiveMixnode, NodeStatus, RewardingReport, TestingRoute, }; use nym_mixnet_contract_common::{EpochId, IdentityKey, MixId}; -use std::convert::TryFrom; + #[derive(Clone)] pub(crate) struct StorageManager { diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 8a87804f61..dd19626732 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -301,7 +301,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -318,7 +318,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -392,12 +392,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -439,7 +433,7 @@ checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58 0.5.0", "hmac 0.12.1", - "k256 0.13.1", + "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -564,8 +558,8 @@ version = "0.8.0" source = "git+https://github.com/jstuczyn/bls12_381?branch=feature/gt-serialization-0.8.0#c4543fde7d02efea6ecfcf22e14476ddb516b483" dependencies = [ "digest 0.9.0", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "pairing", "rand_core 0.6.4", "subtle 2.4.1", @@ -574,9 +568,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "brotli" @@ -860,7 +854,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1034,9 +1028,9 @@ source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-valida dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa 0.16.8", + "ecdsa", "eyre", - "k256 0.13.1", + "k256", "rand_core 0.6.4", "serde", "serde_json", @@ -1049,31 +1043,32 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.3.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e272708a9745dad8b591ef8a718571512130f2b39b33e3d7a27c558e3069394" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", + "ecdsa", "ed25519-zebra", - "k256 0.11.6", + "k256", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.3.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "296db6a3caca5283425ae0cf347f4e46999ba3f6620dbea8939a0e00347831ce" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +checksum = "11ae2e971fb831d0c4fa3c8c3d2291cdbdd73786a73d65196dbf983d9b2468af" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1084,9 +1079,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +checksum = "0cadc57fd0825b85bc2f9b972c17da718b9efb4bc17e5935cc2d6036324f853d" dependencies = [ "proc-macro2", "quote", @@ -1095,11 +1090,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +checksum = "e98e19fae6c3f468412f731274b0f9434602722009d6a77432d39c7c4bb09202" dependencies = [ - "base64 0.13.1", + "base64 0.21.4", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -1199,18 +1194,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.2" @@ -1278,7 +1261,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1347,7 +1330,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1380,9 +1363,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -1399,30 +1382,31 @@ dependencies = [ "cosmwasm-std", "cw2", "schemars", - "semver 1.0.18", + "semver 1.0.22", "serde", "thiserror", ] [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver 1.0.22", "serde", "thiserror", ] [[package]] name = "cw20" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1433,9 +1417,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1448,9 +1432,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1480,7 +1464,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1491,7 +1475,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1523,16 +1507,6 @@ dependencies = [ "uuid 1.4.1", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "der" version = "0.7.8" @@ -1708,31 +1682,19 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ - "der 0.7.8", + "der", "digest 0.10.7", - "elliptic-curve 0.13.5", - "rfc6979 0.4.0", + "elliptic-curve", + "rfc6979", "serdect", "signature 2.1.0", - "spki 0.7.2", + "spki", ] [[package]] @@ -1751,7 +1713,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ - "pkcs8 0.10.2", + "pkcs8", "signature 2.1.0", ] @@ -1804,41 +1766,21 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array 0.14.7", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.2", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array 0.14.7", - "group 0.13.0", - "pkcs8 0.10.2", + "group", + "pkcs8", "rand_core 0.6.4", - "sec1 0.7.3", + "sec1", "serdect", "subtle 2.4.1", "zeroize", @@ -1890,7 +1832,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1983,16 +1925,6 @@ dependencies = [ "log", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "ff" version = "0.13.0" @@ -2219,7 +2151,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -2576,24 +2508,13 @@ dependencies = [ "system-deps 6.1.1", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", "subtle 2.4.1", ] @@ -3254,18 +3175,6 @@ dependencies = [ "treediff", ] -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - [[package]] name = "k256" version = "0.13.1" @@ -3273,9 +3182,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.8", - "elliptic-curve 0.13.5", + "ecdsa", + "elliptic-curve", + "once_cell", "sha2 0.10.8", + "signature 2.1.0", ] [[package]] @@ -3751,7 +3662,7 @@ dependencies = [ "bs58 0.5.0", "cosmrs", "cosmwasm-std", - "ecdsa 0.16.8", + "ecdsa", "getset", "nym-credentials-interface", "nym-crypto", @@ -3858,9 +3769,9 @@ dependencies = [ "bls12_381", "bs58 0.5.0", "digest 0.9.0", - "ff 0.13.0", + "ff", "getrandom 0.2.10", - "group 0.13.0", + "group", "itertools", "nym-dkg", "nym-pemstore", @@ -4041,8 +3952,8 @@ dependencies = [ "bitvec", "bls12_381", "bs58 0.5.0", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "lazy_static", "nym-pemstore", "rand 0.8.5", @@ -4744,7 +4655,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4804,7 +4715,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group 0.13.0", + "group", ] [[package]] @@ -4982,7 +4893,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5111,7 +5022,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5126,24 +5037,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.2", + "der", + "spki", ] [[package]] @@ -5282,9 +5183,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -5324,7 +5225,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5374,9 +5275,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -5625,17 +5526,6 @@ dependencies = [ "winreg 0.50.0", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac 0.12.1", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -5714,7 +5604,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.28", + "syn 2.0.55", "walkdir", ] @@ -5741,7 +5631,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.22", ] [[package]] @@ -5864,9 +5754,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -5877,9 +5767,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -5909,30 +5799,16 @@ dependencies = [ "untrusted", ] -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array 0.14.7", - "pkcs8 0.9.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.8", + "base16ct", + "der", "generic-array 0.14.7", - "pkcs8 0.10.2", + "pkcs8", "serdect", "subtle 2.4.1", "zeroize", @@ -5992,9 +5868,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] @@ -6140,9 +6016,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.190" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -6167,13 +6043,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.190" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -6206,7 +6082,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -6256,7 +6132,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -6265,7 +6141,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct 0.2.0", + "base16ct", "serde", ] @@ -6375,10 +6251,6 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] [[package]] name = "signature" @@ -6504,16 +6376,6 @@ dependencies = [ "lock_api", ] -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.2" @@ -6521,7 +6383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der 0.7.8", + "der", ] [[package]] @@ -6733,9 +6595,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -6904,7 +6766,7 @@ dependencies = [ "regex", "reqwest", "rfd", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "serde_repr", @@ -6937,7 +6799,7 @@ dependencies = [ "cargo_toml", "heck 0.4.1", "json-patch", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "tauri-utils", @@ -6959,7 +6821,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "sha2 0.10.8", @@ -7044,7 +6906,7 @@ dependencies = [ "phf 0.10.1", "proc-macro2", "quote", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "serde_with", @@ -7099,7 +6961,7 @@ dependencies = [ "ed25519-consensus", "flex-error", "futures", - "k256 0.13.1", + "k256", "num-traits", "once_cell", "prost", @@ -7164,7 +7026,7 @@ dependencies = [ "peg", "pin-project", "reqwest", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_bytes", "serde_json", @@ -7210,22 +7072,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -7311,7 +7173,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -7468,7 +7330,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -7544,7 +7406,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "termcolor", ] @@ -7842,7 +7704,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "wasm-bindgen-shared", ] @@ -7876,7 +7738,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8557,7 +8419,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] diff --git a/nym-connect/desktop/src-tauri/src/menu.rs b/nym-connect/desktop/src-tauri/src/menu.rs index 0bc007838b..f98c01debb 100644 --- a/nym-connect/desktop/src-tauri/src/menu.rs +++ b/nym-connect/desktop/src-tauri/src/menu.rs @@ -9,6 +9,7 @@ pub const SHOW_LOG_WINDOW: &str = "show_log_window"; pub const CLEAR_STORAGE: &str = "clear_storage"; pub trait AddDefaultSubmenus { + #[allow(dead_code)] fn add_default_app_submenus(self) -> Self; } diff --git a/nym-connect/desktop/src-tauri/src/operations/help/storage.rs b/nym-connect/desktop/src-tauri/src/operations/help/storage.rs index 7e7ca7e3d9..e6b349cacb 100644 --- a/nym-connect/desktop/src-tauri/src/operations/help/storage.rs +++ b/nym-connect/desktop/src-tauri/src/operations/help/storage.rs @@ -1,15 +1,9 @@ use std::sync::Arc; use crate::{error::BackendError, state::State}; -use serde::Serialize; use tauri::Manager; use tokio::sync::RwLock; -#[derive(Debug, Serialize, Clone)] -struct ClearStorageEvent { - kind: String, -} - #[tauri::command] pub fn help_clear_storage(app_handle: tauri::AppHandle) -> Result<(), BackendError> { log::info!("Clearing user data"); diff --git a/nym-outfox/src/format.rs b/nym-outfox/src/format.rs index 1d0a3681c5..86ac52305d 100644 --- a/nym-outfox/src/format.rs +++ b/nym-outfox/src/format.rs @@ -63,7 +63,7 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; -use std::convert::TryInto; + use std::ops::Range; use std::u8; @@ -78,7 +78,7 @@ use crate::constants::ROUTING_INFORMATION_LENGTH_BY_STAGE; use crate::constants::TAGBYTES; use crate::error::OutfoxError; use crate::lion::*; -use std::convert::TryFrom; + /// A structure that holds mix packet construction parameters. These incluse the length /// of the routing information at each hop, the number of hops, and the payload length. @@ -317,7 +317,7 @@ impl MixStageParameters { #[cfg(test)] mod test { use super::MixCreationParameters; - use std::convert::TryFrom; + #[test] fn test_to_bytes() { diff --git a/nym-outfox/src/packet.rs b/nym-outfox/src/packet.rs index ed0b16ad33..48fbb6728c 100644 --- a/nym-outfox/src/packet.rs +++ b/nym-outfox/src/packet.rs @@ -1,8 +1,6 @@ use std::{ array::TryFromSliceError, collections::VecDeque, - convert::{TryFrom, TryInto}, - iter::FromIterator, ops::Range, }; diff --git a/nym-outfox/tests/unittests.rs b/nym-outfox/tests/unittests.rs index 02851b881a..d89f6f85fe 100644 --- a/nym-outfox/tests/unittests.rs +++ b/nym-outfox/tests/unittests.rs @@ -18,8 +18,6 @@ mod tests { use sphinx_packet::route::DestinationAddressBytes; use sphinx_packet::route::Node; use sphinx_packet::route::NodeAddressBytes; - use std::convert::TryFrom; - use std::convert::TryInto; use nym_outfox::format::*; use nym_outfox::lion::*; diff --git a/nym-validator-rewarder/src/cli/mod.rs b/nym-validator-rewarder/src/cli/mod.rs index f9572442e1..9a68701f7a 100644 --- a/nym-validator-rewarder/src/cli/mod.rs +++ b/nym-validator-rewarder/src/cli/mod.rs @@ -4,7 +4,6 @@ use crate::config::Config; use crate::error::NymRewarderError; use clap::{Parser, Subcommand}; -use humantime_serde::re::humantime; use nym_bin_common::bin_info; use nym_validator_client::nyxd::Coin; use std::path::PathBuf; diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index 14883122c9..c93b176e63 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -186,7 +186,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -261,12 +261,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base16ct" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" - [[package]] name = "base16ct" version = "0.2.0" @@ -299,7 +293,7 @@ checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58 0.5.0", "hmac 0.12.1", - "k256 0.13.1", + "k256", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -404,8 +398,8 @@ version = "0.8.0" source = "git+https://github.com/jstuczyn/bls12_381?branch=feature/gt-serialization-0.8.0#c4543fde7d02efea6ecfcf22e14476ddb516b483" dependencies = [ "digest 0.9.0", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "pairing", "rand_core 0.6.4", "subtle 2.4.1", @@ -414,9 +408,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.7.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" +checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" [[package]] name = "brotli" @@ -661,7 +655,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -832,9 +826,9 @@ checksum = "47126f5364df9387b9d8559dcef62e99010e1d4098f39eb3f7ee4b5c254e40ea" dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (registry+https://github.com/rust-lang/crates.io-index)", - "ecdsa 0.16.8", + "ecdsa", "eyre", - "k256 0.13.1", + "k256", "rand_core 0.6.4", "serde", "serde_json", @@ -851,9 +845,9 @@ source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-valida dependencies = [ "bip32", "cosmos-sdk-proto 0.20.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", - "ecdsa 0.16.8", + "ecdsa", "eyre", - "k256 0.13.1", + "k256", "rand_core 0.6.4", "serde", "serde_json", @@ -866,31 +860,32 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.3.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e272708a9745dad8b591ef8a718571512130f2b39b33e3d7a27c558e3069394" +checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" dependencies = [ "digest 0.10.7", + "ecdsa", "ed25519-zebra", - "k256 0.11.6", + "k256", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.3.1" +version = "1.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "296db6a3caca5283425ae0cf347f4e46999ba3f6620dbea8939a0e00347831ce" +checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" +checksum = "11ae2e971fb831d0c4fa3c8c3d2291cdbdd73786a73d65196dbf983d9b2468af" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -901,9 +896,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" +checksum = "0cadc57fd0825b85bc2f9b972c17da718b9efb4bc17e5935cc2d6036324f853d" dependencies = [ "proc-macro2", "quote", @@ -912,11 +907,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.3.0" +version = "1.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" +checksum = "e98e19fae6c3f468412f731274b0f9434602722009d6a77432d39c7c4bb09202" dependencies = [ - "base64 0.13.1", + "base64 0.21.4", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -967,18 +962,6 @@ dependencies = [ "cfg-if", ] -[[package]] -name = "crypto-bigint" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" -dependencies = [ - "generic-array 0.14.7", - "rand_core 0.6.4", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "crypto-bigint" version = "0.5.2" @@ -1046,7 +1029,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1115,7 +1098,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -1148,9 +1131,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.1.0" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" +checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" dependencies = [ "cosmwasm-std", "schemars", @@ -1167,30 +1150,31 @@ dependencies = [ "cosmwasm-std", "cw2", "schemars", - "semver 1.0.18", + "semver 1.0.22", "serde", "thiserror", ] [[package]] name = "cw2" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" +checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", + "semver 1.0.22", "serde", "thiserror", ] [[package]] name = "cw20" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" +checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1201,9 +1185,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" +checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1216,9 +1200,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.0" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" +checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1275,16 +1259,6 @@ dependencies = [ "parking_lot_core", ] -[[package]] -name = "der" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" -dependencies = [ - "const-oid", - "zeroize", -] - [[package]] name = "der" version = "0.7.8" @@ -1459,31 +1433,19 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" -[[package]] -name = "ecdsa" -version = "0.14.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" -dependencies = [ - "der 0.6.1", - "elliptic-curve 0.12.3", - "rfc6979 0.3.1", - "signature 1.6.4", -] - [[package]] name = "ecdsa" version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ - "der 0.7.8", + "der", "digest 0.10.7", - "elliptic-curve 0.13.5", - "rfc6979 0.4.0", + "elliptic-curve", + "rfc6979", "serdect", "signature 2.1.0", - "spki 0.7.2", + "spki", ] [[package]] @@ -1502,7 +1464,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ - "pkcs8 0.10.2", + "pkcs8", "signature 2.1.0", ] @@ -1555,41 +1517,21 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" -[[package]] -name = "elliptic-curve" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" -dependencies = [ - "base16ct 0.1.1", - "crypto-bigint 0.4.9", - "der 0.6.1", - "digest 0.10.7", - "ff 0.12.1", - "generic-array 0.14.7", - "group 0.12.1", - "pkcs8 0.9.0", - "rand_core 0.6.4", - "sec1 0.3.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "elliptic-curve" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ - "base16ct 0.2.0", - "crypto-bigint 0.5.2", + "base16ct", + "crypto-bigint", "digest 0.10.7", - "ff 0.13.0", + "ff", "generic-array 0.14.7", - "group 0.13.0", - "pkcs8 0.10.2", + "group", + "pkcs8", "rand_core 0.6.4", - "sec1 0.7.3", + "sec1", "serdect", "subtle 2.4.1", "zeroize", @@ -1685,16 +1627,6 @@ dependencies = [ "log", ] -[[package]] -name = "ff" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" -dependencies = [ - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "ff" version = "0.13.0" @@ -1862,7 +1794,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -2168,24 +2100,13 @@ dependencies = [ "system-deps 6.1.1", ] -[[package]] -name = "group" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" -dependencies = [ - "ff 0.12.1", - "rand_core 0.6.4", - "subtle 2.4.1", -] - [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff 0.13.0", + "ff", "rand_core 0.6.4", "subtle 2.4.1", ] @@ -2714,18 +2635,6 @@ dependencies = [ "treediff", ] -[[package]] -name = "k256" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" -dependencies = [ - "cfg-if", - "ecdsa 0.14.8", - "elliptic-curve 0.12.3", - "sha2 0.10.8", -] - [[package]] name = "k256" version = "0.13.1" @@ -2733,8 +2642,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.8", - "elliptic-curve 0.13.5", + "ecdsa", + "elliptic-curve", "once_cell", "sha2 0.10.8", "signature 2.1.0", @@ -3086,7 +2995,7 @@ dependencies = [ "bs58 0.5.0", "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", "cosmwasm-std", - "ecdsa 0.16.8", + "ecdsa", "getset", "nym-credentials-interface", "nym-crypto", @@ -3121,9 +3030,9 @@ dependencies = [ "bls12_381", "bs58 0.5.0", "digest 0.9.0", - "ff 0.13.0", + "ff", "getrandom 0.2.10", - "group 0.13.0", + "group", "itertools 0.10.5", "nym-dkg", "nym-pemstore", @@ -3215,8 +3124,8 @@ dependencies = [ "bitvec", "bls12_381", "bs58 0.5.0", - "ff 0.13.0", - "group 0.13.0", + "ff", + "group", "lazy_static", "nym-pemstore", "rand 0.8.5", @@ -3545,7 +3454,7 @@ dependencies = [ "fern", "futures", "itertools 0.10.5", - "k256 0.13.1", + "k256", "log", "nym-config", "nym-contracts-common", @@ -3677,7 +3586,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -3716,7 +3625,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group 0.13.0", + "group", ] [[package]] @@ -3874,7 +3783,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4003,7 +3912,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4018,24 +3927,14 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs8" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" -dependencies = [ - "der 0.6.1", - "spki 0.6.0", -] - [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der 0.7.8", - "spki 0.7.2", + "der", + "spki", ] [[package]] @@ -4159,9 +4058,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.66" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -4186,7 +4085,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4221,9 +4120,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -4447,17 +4346,6 @@ dependencies = [ "winreg", ] -[[package]] -name = "rfc6979" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" -dependencies = [ - "crypto-bigint 0.4.9", - "hmac 0.12.1", - "zeroize", -] - [[package]] name = "rfc6979" version = "0.4.0" @@ -4527,7 +4415,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.18", + "semver 1.0.22", ] [[package]] @@ -4624,9 +4512,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" +checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -4637,9 +4525,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.12" +version = "0.8.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" +checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" dependencies = [ "proc-macro2", "quote", @@ -4669,30 +4557,16 @@ dependencies = [ "untrusted", ] -[[package]] -name = "sec1" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" -dependencies = [ - "base16ct 0.1.1", - "der 0.6.1", - "generic-array 0.14.7", - "pkcs8 0.9.0", - "subtle 2.4.1", - "zeroize", -] - [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct 0.2.0", - "der 0.7.8", + "base16ct", + "der", "generic-array 0.14.7", - "pkcs8 0.10.2", + "pkcs8", "serdect", "subtle 2.4.1", "zeroize", @@ -4752,9 +4626,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.18" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" dependencies = [ "serde", ] @@ -4770,9 +4644,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.192" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -4797,13 +4671,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.192" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4836,7 +4710,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -4888,7 +4762,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct 0.2.0", + "base16ct", "serde", ] @@ -4971,10 +4845,6 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" -dependencies = [ - "digest 0.10.7", - "rand_core 0.6.4", -] [[package]] name = "signature" @@ -5091,16 +4961,6 @@ version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" -[[package]] -name = "spki" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" -dependencies = [ - "base64ct", - "der 0.6.1", -] - [[package]] name = "spki" version = "0.7.2" @@ -5108,7 +4968,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der 0.7.8", + "der", ] [[package]] @@ -5199,7 +5059,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5242,9 +5102,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.55" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" dependencies = [ "proc-macro2", "quote", @@ -5397,7 +5257,7 @@ dependencies = [ "raw-window-handle", "regex", "rfd", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "serde_repr", @@ -5430,7 +5290,7 @@ dependencies = [ "cargo_toml", "heck 0.4.1", "json-patch", - "semver 1.0.18", + "semver 1.0.22", "serde_json", "tauri-utils", "winres", @@ -5451,7 +5311,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "sha2 0.10.8", @@ -5534,7 +5394,7 @@ dependencies = [ "phf 0.10.1", "proc-macro2", "quote", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_json", "serde_with", @@ -5569,7 +5429,7 @@ dependencies = [ "ed25519-consensus", "flex-error", "futures", - "k256 0.13.1", + "k256", "num-traits", "once_cell", "prost", @@ -5634,7 +5494,7 @@ dependencies = [ "peg", "pin-project", "reqwest", - "semver 1.0.18", + "semver 1.0.22", "serde", "serde_bytes", "serde_json", @@ -5680,22 +5540,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" +checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.48" +version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" +checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5781,7 +5641,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5887,7 +5747,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] @@ -5963,7 +5823,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "termcolor", ] @@ -6155,7 +6015,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "wasm-bindgen-shared", ] @@ -6189,7 +6049,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -6738,7 +6598,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.55", ] [[package]] diff --git a/nym-wallet/src-tauri/src/coin.rs b/nym-wallet/src-tauri/src/coin.rs index 8c3ab07ee5..40c0b54000 100644 --- a/nym-wallet/src-tauri/src/coin.rs +++ b/nym-wallet/src-tauri/src/coin.rs @@ -3,7 +3,7 @@ use crate::error::BackendError; use crate::network::Network; use serde::{Deserialize, Serialize}; -use std::convert::TryFrom; + use std::str::FromStr; use strum::IntoEnumIterator; use nym_validator_client::nyxd::CosmosCoin; @@ -161,7 +161,7 @@ mod test { use super::*; use crate::error::BackendError; use serde_json::json; - use std::convert::TryFrom; + use std::str::FromStr; #[test] diff --git a/nym-wallet/src-tauri/src/menu.rs b/nym-wallet/src-tauri/src/menu.rs index 1aaa78c7fe..b38e73a639 100644 --- a/nym-wallet/src-tauri/src/menu.rs +++ b/nym-wallet/src-tauri/src/menu.rs @@ -8,6 +8,7 @@ pub trait AddDefaultSubmenus { } impl AddDefaultSubmenus for Menu { + #[allow(dead_code)] fn add_default_app_submenus(self) -> Self { if ::std::env::var("NYM_WALLET_ENABLE_LOG").is_ok() { let submenu = Submenu::new( diff --git a/nym-wallet/src-tauri/src/operations/mixnet/account.rs b/nym-wallet/src-tauri/src/operations/mixnet/account.rs index 6704009cb3..3750e21aee 100644 --- a/nym-wallet/src-tauri/src/operations/mixnet/account.rs +++ b/nym-wallet/src-tauri/src/operations/mixnet/account.rs @@ -640,10 +640,7 @@ mod tests { use std::path::PathBuf; use std::str::FromStr; - use crate::wallet_storage::{ - self, - account_data::{MnemonicAccount, WalletAccount}, - }; + use crate::wallet_storage::account_data::{MnemonicAccount, WalletAccount}; use super::*; diff --git a/nym-wallet/src-tauri/src/wallet_storage/mod.rs b/nym-wallet/src-tauri/src/wallet_storage/mod.rs index ba6e5e7172..01b2461982 100644 --- a/nym-wallet/src-tauri/src/wallet_storage/mod.rs +++ b/nym-wallet/src-tauri/src/wallet_storage/mod.rs @@ -470,7 +470,7 @@ fn rename_account_in_login_at_file( #[cfg(test)] mod tests { - use crate::wallet_storage::account_data::{MnemonicAccount, WalletAccount}; + use crate::wallet_storage::account_data::WalletAccount; use super::*; use nym_config::defaults::COSMOS_DERIVATION_PATH; diff --git a/sdk/lib/socks5-listener/src/lib.rs b/sdk/lib/socks5-listener/src/lib.rs index 0c9e2f7771..4f36f53f86 100644 --- a/sdk/lib/socks5-listener/src/lib.rs +++ b/sdk/lib/socks5-listener/src/lib.rs @@ -14,7 +14,6 @@ use nym_config_common::defaults::setup_env; use nym_socks5_client_core::NymClient as Socks5NymClient; use rand::rngs::OsRng; use safer_ffi::char_p::char_p_boxed; -use std::marker::Send; use std::path::PathBuf; use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; diff --git a/sdk/rust/nym-sdk/examples/libp2p_shared/connection.rs b/sdk/rust/nym-sdk/examples/libp2p_shared/connection.rs index 04c166ce59..d562d634de 100644 --- a/sdk/rust/nym-sdk/examples/libp2p_shared/connection.rs +++ b/sdk/rust/nym-sdk/examples/libp2p_shared/connection.rs @@ -123,7 +123,7 @@ impl Connection { // creates a new substream instance with the given ID. fn new_substream(&mut self, id: SubstreamId) -> Result<Substream, Error> { // check we don't already have a substream with this ID - if self.substream_inbound_txs.get(&id).is_some() { + if self.substream_inbound_txs.contains_key(&id) { return Err(Error::SubstreamIdExists(id)); } diff --git a/sdk/rust/nym-sdk/examples/libp2p_shared/transport.rs b/sdk/rust/nym-sdk/examples/libp2p_shared/transport.rs index 6fde934bf8..938acd68e1 100644 --- a/sdk/rust/nym-sdk/examples/libp2p_shared/transport.rs +++ b/sdk/rust/nym-sdk/examples/libp2p_shared/transport.rs @@ -227,7 +227,7 @@ impl NymTransport { } // ensure we don't already have a conn with the same id - if self.connections.get(&msg.id).is_some() { + if self.connections.contains_key(&msg.id) { return Err(Error::ConnectionIDExists); } diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 03923f46ad..968dc79b5f 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -7,7 +7,7 @@ license = "GPL-3.0" version = "1.1.33" authors.workspace = true edition.workspace = true -rust-version = "1.65" +rust-version = "1.70" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index cd5e84071e..6e1851f188 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -325,7 +325,6 @@ fn version_check(cfg: &Config) -> bool { #[cfg(test)] mod tests { use super::*; - use clap::CommandFactory; #[test] fn verify_cli() { diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs index 099d46cdf2..2c2da2732a 100644 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs +++ b/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs @@ -34,7 +34,7 @@ impl HostsGroup { } pub(crate) fn contains_domain(&self, host: &str) -> bool { - self.domains.contains(&host.to_string()) + self.domains.contains(host) } pub(super) fn contains_ip_address(&self, address: IpAddr) -> bool { diff --git a/tools/nymvisor/src/cli/init.rs b/tools/nymvisor/src/cli/init.rs index 40003eff36..1382a6d1b3 100644 --- a/tools/nymvisor/src/cli/init.rs +++ b/tools/nymvisor/src/cli/init.rs @@ -133,7 +133,7 @@ pub(crate) struct Args { impl Args { pub(crate) fn override_config(&self, config: &mut Config) { if let Some(nymvisor_id) = &self.id { - config.nymvisor.id = nymvisor_id.clone(); + config.nymvisor.id.clone_from(nymvisor_id); } if let Some(upstream) = &self.upstream_base_upgrade_url { config.nymvisor.debug.upstream_base_upgrade_url = upstream.clone() @@ -149,7 +149,7 @@ impl Args { Some(nymvisor_upgrade_data_directory.clone()); } if let Some(daemon_home) = &self.daemon_home { - config.daemon.home = daemon_home.clone(); + config.daemon.home.clone_from(daemon_home); } if let Some(upstream) = &self.daemon_absolute_upstream_upgrade_url { config.daemon.debug.absolute_upstream_upgrade_url = Some(upstream.clone()) diff --git a/tools/nymvisor/src/env.rs b/tools/nymvisor/src/env.rs index 24357e13ae..dc9bf65c7e 100644 --- a/tools/nymvisor/src/env.rs +++ b/tools/nymvisor/src/env.rs @@ -68,7 +68,7 @@ pub(crate) struct Env { impl Env { pub(crate) fn override_config(&self, config: &mut Config) { if let Some(nymvisor_id) = &self.nymvisor_id { - config.nymvisor.id = nymvisor_id.clone(); + config.nymvisor.id.clone_from(nymvisor_id); } if let Some(upstream) = &self.nymvisor_upstream_base_upgrade_url { config.nymvisor.debug.upstream_base_upgrade_url = upstream.clone() @@ -84,10 +84,10 @@ impl Env { Some(nymvisor_upgrade_data_directory.clone()); } if let Some(daemon_name) = &self.daemon_name { - config.daemon.name = daemon_name.clone(); + config.daemon.name.clone_from(daemon_name); } if let Some(daemon_home) = &self.daemon_home { - config.daemon.home = daemon_home.clone(); + config.daemon.home.clone_from(daemon_home); } if let Some(upstream) = &self.daemon_absolute_upstream_upgrade_url { config.daemon.debug.absolute_upstream_upgrade_url = Some(upstream.clone()) diff --git a/wasm/client/src/client.rs b/wasm/client/src/client.rs index 0db708d074..ad54cb5e6f 100644 --- a/wasm/client/src/client.rs +++ b/wasm/client/src/client.rs @@ -1,6 +1,12 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use crate::config::{ClientConfig, ClientConfigOpts}; use crate::error::WasmClientError; use crate::helpers::{InputSender, WasmTopologyExt}; diff --git a/wasm/client/src/config.rs b/wasm/client/src/config.rs index da33746d34..3efe9bb2e5 100644 --- a/wasm/client/src/config.rs +++ b/wasm/client/src/config.rs @@ -1,6 +1,12 @@ // Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use crate::error::WasmClientError; use serde::{Deserialize, Serialize}; use tsify::Tsify; diff --git a/wasm/client/src/encoded_payload_helper.rs b/wasm/client/src/encoded_payload_helper.rs index b39e578c46..71600ed5ce 100644 --- a/wasm/client/src/encoded_payload_helper.rs +++ b/wasm/client/src/encoded_payload_helper.rs @@ -1,10 +1,15 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by wasm_bindgen +#![allow(clippy::empty_docs)] + use anyhow::bail; use serde::{Deserialize, Serialize}; use wasm_bindgen::prelude::*; -use wasm_bindgen::JsCast; #[wasm_bindgen(typescript_custom_section)] const TS_DEFS: &'static str = r#" diff --git a/wasm/client/src/helpers.rs b/wasm/client/src/helpers.rs index 16650294c7..e8570d02b9 100644 --- a/wasm/client/src/helpers.rs +++ b/wasm/client/src/helpers.rs @@ -9,7 +9,7 @@ use wasm_client_core::client::base_client::{ClientInput, ClientState}; use wasm_client_core::client::inbound_messages::InputMessage; use wasm_client_core::error::WasmCoreError; use wasm_client_core::topology::SerializableNymTopology; -use wasm_client_core::{MixLayer, NymTopology}; +use wasm_client_core::NymTopology; use wasm_utils::error::simple_js_error; use wasm_utils::{check_promise_result, console_log}; @@ -82,9 +82,6 @@ pub(crate) trait WasmTopologyExt { /// Returns the current network topology. fn current_topology(&self) -> Promise; - - /// Checks whether the provided node exists in the known network topology and if so, returns its layer. - fn check_for_mixnode_existence(&self, mixnode_identity: String) -> Promise; } #[cfg(feature = "node-tester")] @@ -124,21 +121,6 @@ impl WasmTopologyExt for Arc<ClientState> { } }) } - - /// Checks whether the target mixnode exists in the known network topology and returns its layer. - fn check_for_mixnode_existence(&self, mixnode_identity: String) -> Promise { - let this = Arc::clone(self); - future_to_promise(async move { - let Some(current_topology) = this.topology_accessor.current_topology().await else { - return Err(WasmCoreError::UnavailableNetworkTopology.into()); - }; - - match current_topology.find_mix_by_identity(&mixnode_identity) { - None => Err(WasmCoreError::NonExistentMixnode { mixnode_identity }.into()), - Some(node) => Ok(JsValue::from(MixLayer::from(node.layer))), - } - }) - } } #[cfg(feature = "node-tester")] diff --git a/wasm/mix-fetch/src/config.rs b/wasm/mix-fetch/src/config.rs index 3d8087e169..621e041913 100644 --- a/wasm/mix-fetch/src/config.rs +++ b/wasm/mix-fetch/src/config.rs @@ -1,8 +1,13 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + // due to expansion of #[wasm_bindgen] macro on `MixFetch` Config struct #![allow(clippy::drop_non_drop)] +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] use crate::error::MixFetchError; use serde::{Deserialize, Serialize}; diff --git a/wasm/mix-fetch/src/fetch.rs b/wasm/mix-fetch/src/fetch.rs index 2fd8da80dc..459270e621 100644 --- a/wasm/mix-fetch/src/fetch.rs +++ b/wasm/mix-fetch/src/fetch.rs @@ -1,6 +1,12 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 + +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use crate::client::MixFetchClient; use crate::config::{MixFetchConfig, MixFetchConfigOpts, MixFetchDebugOverride}; use crate::error::MixFetchError; diff --git a/wasm/mix-fetch/src/go_bridge.rs b/wasm/mix-fetch/src/go_bridge.rs index 2069572b8e..6ea8f0704d 100644 --- a/wasm/mix-fetch/src/go_bridge.rs +++ b/wasm/mix-fetch/src/go_bridge.rs @@ -5,7 +5,6 @@ use crate::error::MixFetchError; use crate::mix_fetch_client; use js_sys::Promise; use wasm_bindgen::prelude::*; -use wasm_bindgen::JsValue; use wasm_bindgen_futures::future_to_promise; use wasm_utils::error::{simple_rejected_promise, PromisableResult}; diff --git a/wasm/node-tester/src/tester.rs b/wasm/node-tester/src/tester.rs index 1da2ee7a4f..4a6694e46b 100644 --- a/wasm/node-tester/src/tester.rs +++ b/wasm/node-tester/src/tester.rs @@ -1,6 +1,11 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![allow(unknown_lints)] +// clippy::empty_docs is not on stable as of 1.77 +// due to the code generated by Tsify +#![allow(clippy::empty_docs)] + use crate::ephemeral_receiver::EphemeralTestReceiver; use crate::error::NodeTesterError; use crate::helpers::{GatewayReconnection, ReceivedReceiverWrapper, TestMarker}; From 297cde513bb288e4534f7fe4bddb5d798b062fb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 27 Mar 2024 16:11:14 +0000 Subject: [PATCH 279/394] turns out 'make' doesn't run cargo fmt --- clients/native/websocket-requests/src/text.rs | 1 - .../validator-client/src/nyxd/cosmwasm_client/types.rs | 1 - .../cosmwasm-smart-contracts/mixnet-contract/src/events.rs | 2 +- .../mixnet-contract/src/rewarding/simulator/mod.rs | 1 - common/mixnode-common/src/verloc/packet.rs | 1 - common/nymcoconut/src/elgamal.rs | 2 -- common/nymcoconut/src/proofs/mod.rs | 1 - common/nymcoconut/src/scheme/double_use.rs | 1 - common/nymcoconut/src/scheme/issuance.rs | 2 -- common/nymcoconut/src/scheme/keygen.rs | 2 -- common/nymcoconut/src/scheme/mod.rs | 3 --- common/nymcoconut/src/scheme/verification.rs | 2 -- common/nymcoconut/src/traits.rs | 1 - common/nymcoconut/src/utils.rs | 1 - common/nymsphinx/framing/src/codec.rs | 2 +- common/nymsphinx/framing/src/packet.rs | 1 - common/socks5-client-core/src/socks/mod.rs | 2 -- common/topology/src/serde.rs | 1 - common/types/src/currency.rs | 2 +- contracts/mixnet/src/interval/pending_events.rs | 2 +- contracts/mixnet/src/mixnodes/transactions.rs | 4 +--- contracts/mixnet/src/rewards/queries.rs | 1 - mixnode/src/commands/sign.rs | 1 - nym-api/src/coconut/client.rs | 1 - nym-api/src/coconut/dkg/dealing.rs | 3 ++- nym-api/src/coconut/dkg/key_validation.rs | 5 ++++- nym-api/src/support/storage/manager.rs | 1 - nym-outfox/src/format.rs | 4 ---- nym-outfox/src/packet.rs | 6 +----- 29 files changed, 12 insertions(+), 45 deletions(-) diff --git a/clients/native/websocket-requests/src/text.rs b/clients/native/websocket-requests/src/text.rs index faa0706a55..231fb52229 100644 --- a/clients/native/websocket-requests/src/text.rs +++ b/clients/native/websocket-requests/src/text.rs @@ -8,7 +8,6 @@ use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::anonymous_replies::requests::AnonymousSenderTag; use serde::{Deserialize, Serialize}; - // local text equivalent of `ClientRequest` for easier serialization + deserialization with serde // TODO: figure out if there's an easy way to avoid defining it diff --git a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs index b1e91efa39..ceeae0f54e 100644 --- a/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs +++ b/common/client-libs/validator-client/src/nyxd/cosmwasm_client/types.rs @@ -29,7 +29,6 @@ use cosmrs::{AccountId, Any, Coin as CosmosCoin}; use prost::Message; use serde::Serialize; - pub use cosmrs::abci::GasInfo; pub type ContractCodeId = u64; diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs index 444bfc31d7..365adf9df3 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/events.rs @@ -96,7 +96,7 @@ impl Display for MixnetEventType { MixnetEventType::GatewayConfigUpdate => "gateway_config_update", }; - write!(f,"{EVENT_VERSION_PREFIX}{event_name}") + write!(f, "{EVENT_VERSION_PREFIX}{event_name}") } } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs index e723988c91..0cc4d06dee 100644 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/rewarding/simulator/mod.rs @@ -596,7 +596,6 @@ mod tests { #[test] #[allow(clippy::inconsistent_digit_grouping)] fn multiple_nodes_against_known_values() { - // TODO: this test can be further improved by checking values after EVERY interval // rather than just checking the final results diff --git a/common/mixnode-common/src/verloc/packet.rs b/common/mixnode-common/src/verloc/packet.rs index 77b112836e..c5729904b7 100644 --- a/common/mixnode-common/src/verloc/packet.rs +++ b/common/mixnode-common/src/verloc/packet.rs @@ -4,7 +4,6 @@ use crate::verloc::error::RttError; use nym_crypto::asymmetric::identity::{self, PUBLIC_KEY_LENGTH, SIGNATURE_LENGTH}; - pub(crate) struct EchoPacket { sequence_number: u64, sender: identity::PublicKey, diff --git a/common/nymcoconut/src/elgamal.rs b/common/nymcoconut/src/elgamal.rs index 923ffd8be6..55db7dcdd2 100644 --- a/common/nymcoconut/src/elgamal.rs +++ b/common/nymcoconut/src/elgamal.rs @@ -3,8 +3,6 @@ use core::ops::{Deref, Mul}; - - use bls12_381::{G1Projective, Scalar}; use group::Curve; use serde_derive::{Deserialize, Serialize}; diff --git a/common/nymcoconut/src/proofs/mod.rs b/common/nymcoconut/src/proofs/mod.rs index 6de4992fd1..17a8416c59 100644 --- a/common/nymcoconut/src/proofs/mod.rs +++ b/common/nymcoconut/src/proofs/mod.rs @@ -5,7 +5,6 @@ use std::borrow::Borrow; - use bls12_381::{G1Projective, G2Projective, Scalar}; use digest::generic_array::typenum::Unsigned; use digest::Digest; diff --git a/common/nymcoconut/src/scheme/double_use.rs b/common/nymcoconut/src/scheme/double_use.rs index 8817514040..f0a6a1eed3 100644 --- a/common/nymcoconut/src/scheme/double_use.rs +++ b/common/nymcoconut/src/scheme/double_use.rs @@ -7,7 +7,6 @@ use crate::utils::try_deserialize_g2_projective; use bls12_381::{G2Affine, G2Projective}; use group::Curve; - use std::fmt::{Debug, Formatter}; use std::ops::Deref; diff --git a/common/nymcoconut/src/scheme/issuance.rs b/common/nymcoconut/src/scheme/issuance.rs index 3c562d4ec3..088f691f32 100644 --- a/common/nymcoconut/src/scheme/issuance.rs +++ b/common/nymcoconut/src/scheme/issuance.rs @@ -1,8 +1,6 @@ // Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 - - use std::ops::Neg; use bls12_381::{multi_miller_loop, G1Affine, G1Projective, G2Prepared, Scalar}; diff --git a/common/nymcoconut/src/scheme/keygen.rs b/common/nymcoconut/src/scheme/keygen.rs index 823bc65759..c587ad8fd9 100644 --- a/common/nymcoconut/src/scheme/keygen.rs +++ b/common/nymcoconut/src/scheme/keygen.rs @@ -5,8 +5,6 @@ use core::borrow::Borrow; use core::iter::Sum; use core::ops::{Add, Mul}; - - use bls12_381::{G1Projective, G2Projective, Scalar}; use group::Curve; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; diff --git a/common/nymcoconut/src/scheme/mod.rs b/common/nymcoconut/src/scheme/mod.rs index 4ccec89b18..00adef8826 100644 --- a/common/nymcoconut/src/scheme/mod.rs +++ b/common/nymcoconut/src/scheme/mod.rs @@ -3,9 +3,6 @@ // TODO: implement https://crates.io/crates/signature traits? - - - use bls12_381::{G1Projective, G2Prepared, G2Projective, Scalar}; use group::Curve; diff --git a/common/nymcoconut/src/scheme/verification.rs b/common/nymcoconut/src/scheme/verification.rs index ee389deb62..8e4aa2d508 100644 --- a/common/nymcoconut/src/scheme/verification.rs +++ b/common/nymcoconut/src/scheme/verification.rs @@ -13,8 +13,6 @@ use bls12_381::{multi_miller_loop, G1Affine, G2Prepared, G2Projective, Scalar}; use core::ops::Neg; use group::{Curve, Group}; - - pub use crate::scheme::double_use::BlindedSerialNumber; // TODO NAMING: this whole thing diff --git a/common/nymcoconut/src/traits.rs b/common/nymcoconut/src/traits.rs index bfeec703ec..b2aa13944c 100644 --- a/common/nymcoconut/src/traits.rs +++ b/common/nymcoconut/src/traits.rs @@ -8,7 +8,6 @@ use crate::CoconutError; use bls12_381::{G1Affine, G1Projective, Scalar}; use group::GroupEncoding; - pub trait Bytable where Self: Sized, diff --git a/common/nymcoconut/src/utils.rs b/common/nymcoconut/src/utils.rs index fe4a288087..819156cb23 100644 --- a/common/nymcoconut/src/utils.rs +++ b/common/nymcoconut/src/utils.rs @@ -4,7 +4,6 @@ use core::iter::Sum; use core::ops::Mul; - use bls12_381::hash_to_curve::{ExpandMsgXmd, HashToCurve, HashToField}; use bls12_381::{G1Affine, G1Projective, G2Affine, G2Projective, Scalar}; use ff::Field; diff --git a/common/nymsphinx/framing/src/codec.rs b/common/nymsphinx/framing/src/codec.rs index ef7b412fbc..2abc29f91e 100644 --- a/common/nymsphinx/framing/src/codec.rs +++ b/common/nymsphinx/framing/src/codec.rs @@ -241,7 +241,7 @@ mod packet_encoding { mod decode_will_allocate_enough_bytes_for_next_call { use super::*; use nym_sphinx_params::packet_version::PacketVersion; - + #[test] fn for_empty_bytes() { // empty bytes should allocate for header + ack packet diff --git a/common/nymsphinx/framing/src/packet.rs b/common/nymsphinx/framing/src/packet.rs index aaae18252e..7d6dfcfa01 100644 --- a/common/nymsphinx/framing/src/packet.rs +++ b/common/nymsphinx/framing/src/packet.rs @@ -8,7 +8,6 @@ use nym_sphinx_params::packet_version::PacketVersion; use nym_sphinx_params::PacketType; use nym_sphinx_types::NymPacket; - #[derive(Debug)] pub struct FramedNymPacket { /// Contains any metadata helping receiver to handle the underlying packet. diff --git a/common/socks5-client-core/src/socks/mod.rs b/common/socks5-client-core/src/socks/mod.rs index 4b6cc169f0..3ec1129c92 100644 --- a/common/socks5-client-core/src/socks/mod.rs +++ b/common/socks5-client-core/src/socks/mod.rs @@ -1,7 +1,5 @@ #![forbid(unsafe_code)] - - use self::types::SocksProxyError; pub mod authentication; diff --git a/common/topology/src/serde.rs b/common/topology/src/serde.rs index 78990d2f11..e5536e1b2e 100644 --- a/common/topology/src/serde.rs +++ b/common/topology/src/serde.rs @@ -17,7 +17,6 @@ use std::collections::BTreeMap; use std::net::{IpAddr, SocketAddr}; use thiserror::Error; - #[cfg(feature = "wasm-serde-types")] use tsify::Tsify; diff --git a/common/types/src/currency.rs b/common/types/src/currency.rs index 1e9cceb521..2e32b4288d 100644 --- a/common/types/src/currency.rs +++ b/common/types/src/currency.rs @@ -396,7 +396,7 @@ impl TryFrom<DecCoin> for Coin { #[cfg(test)] mod test { use super::*; - + #[test] fn dec_value_scale_down() { let dec = DecCoin { diff --git a/contracts/mixnet/src/interval/pending_events.rs b/contracts/mixnet/src/interval/pending_events.rs index 6ba77faa6d..e0c5077a8f 100644 --- a/contracts/mixnet/src/interval/pending_events.rs +++ b/contracts/mixnet/src/interval/pending_events.rs @@ -1983,8 +1983,8 @@ mod tests { #[cfg(test)] mod changing_mix_cost_params { - use cosmwasm_std::coin; use crate::support::tests::fixtures::TEST_COIN_DENOM; + use cosmwasm_std::coin; use super::*; diff --git a/contracts/mixnet/src/mixnodes/transactions.rs b/contracts/mixnet/src/mixnodes/transactions.rs index 00b000a43e..032ef29bc9 100644 --- a/contracts/mixnet/src/mixnodes/transactions.rs +++ b/contracts/mixnet/src/mixnodes/transactions.rs @@ -500,9 +500,7 @@ pub mod tests { use cosmwasm_std::{Order, StdResult, Uint128}; use mixnet_contract_common::mixnode::PendingMixNodeChanges; - use mixnet_contract_common::{ - EpochState, EpochStatus, ExecuteMsg, LayerDistribution, Percent, - }; + use mixnet_contract_common::{EpochState, EpochStatus, ExecuteMsg, LayerDistribution, Percent}; use crate::contract::execute; use crate::mixnet_contract_settings::storage::minimum_mixnode_pledge; diff --git a/contracts/mixnet/src/rewards/queries.rs b/contracts/mixnet/src/rewards/queries.rs index 59f3799b56..87df0f9fc8 100644 --- a/contracts/mixnet/src/rewards/queries.rs +++ b/contracts/mixnet/src/rewards/queries.rs @@ -411,7 +411,6 @@ mod tests { use crate::support::tests::test_helpers::get_bank_send_msg; use cosmwasm_std::testing::mock_info; - #[test] fn for_non_existent_delegation() { let test = TestSetup::new(); diff --git a/mixnode/src/commands/sign.rs b/mixnode/src/commands/sign.rs index 8225649707..b178718fc1 100644 --- a/mixnode/src/commands/sign.rs +++ b/mixnode/src/commands/sign.rs @@ -11,7 +11,6 @@ use nym_crypto::asymmetric::identity; use nym_types::helpers::ConsoleSigningOutput; use nym_validator_client::nyxd; - use super::version_check; #[derive(Args, Clone)] diff --git a/nym-api/src/coconut/client.rs b/nym-api/src/coconut/client.rs index 3b65d83649..d009989996 100644 --- a/nym-api/src/coconut/client.rs +++ b/nym-api/src/coconut/client.rs @@ -73,7 +73,6 @@ pub trait Client { dealing_index: DealingIndex, ) -> Result<DealingStatusResponse>; - async fn get_current_dealers(&self) -> Result<Vec<DealerDetails>>; #[allow(dead_code)] diff --git a/nym-api/src/coconut/dkg/dealing.rs b/nym-api/src/coconut/dkg/dealing.rs index 7cbd4fa80f..21b5803854 100644 --- a/nym-api/src/coconut/dkg/dealing.rs +++ b/nym-api/src/coconut/dkg/dealing.rs @@ -125,7 +125,8 @@ impl<R: RngCore + CryptoRng> DkgController<R> { // update the state with the dealing information self.state .dealing_exchange_state_mut(epoch_id)? - .generated_dealings.clone_from(&dealings); + .generated_dealings + .clone_from(&dealings); Ok(dealings) } diff --git a/nym-api/src/coconut/dkg/key_validation.rs b/nym-api/src/coconut/dkg/key_validation.rs index 4daa0da601..ada4f72898 100644 --- a/nym-api/src/coconut/dkg/key_validation.rs +++ b/nym-api/src/coconut/dkg/key_validation.rs @@ -234,7 +234,10 @@ impl<R: RngCore + CryptoRng> DkgController<R> { } let votes = self.generate_votes(epoch_id).await?; - self.state.key_validation_state_mut(epoch_id)?.votes.clone_from(&votes); + self.state + .key_validation_state_mut(epoch_id)? + .votes + .clone_from(&votes); // send the votes for (proposal, vote) in votes { diff --git a/nym-api/src/support/storage/manager.rs b/nym-api/src/support/storage/manager.rs index 953483d9c1..cf0ec15f79 100644 --- a/nym-api/src/support/storage/manager.rs +++ b/nym-api/src/support/storage/manager.rs @@ -8,7 +8,6 @@ use crate::support::storage::models::{ }; use nym_mixnet_contract_common::{EpochId, IdentityKey, MixId}; - #[derive(Clone)] pub(crate) struct StorageManager { pub(crate) connection_pool: sqlx::SqlitePool, diff --git a/nym-outfox/src/format.rs b/nym-outfox/src/format.rs index 86ac52305d..4a9261bd3f 100644 --- a/nym-outfox/src/format.rs +++ b/nym-outfox/src/format.rs @@ -63,8 +63,6 @@ use curve25519_dalek::constants::ED25519_BASEPOINT_TABLE; use curve25519_dalek::montgomery::MontgomeryPoint; use curve25519_dalek::scalar::Scalar; - - use std::ops::Range; use std::u8; @@ -79,7 +77,6 @@ use crate::constants::TAGBYTES; use crate::error::OutfoxError; use crate::lion::*; - /// A structure that holds mix packet construction parameters. These incluse the length /// of the routing information at each hop, the number of hops, and the payload length. #[derive(Eq, PartialEq, Debug)] @@ -318,7 +315,6 @@ impl MixStageParameters { mod test { use super::MixCreationParameters; - #[test] fn test_to_bytes() { let mix_params = MixCreationParameters::new(1024); diff --git a/nym-outfox/src/packet.rs b/nym-outfox/src/packet.rs index 48fbb6728c..0b0208703b 100644 --- a/nym-outfox/src/packet.rs +++ b/nym-outfox/src/packet.rs @@ -1,8 +1,4 @@ -use std::{ - array::TryFromSliceError, - collections::VecDeque, - ops::Range, -}; +use std::{array::TryFromSliceError, collections::VecDeque, ops::Range}; use crate::{ constants::{DEFAULT_HOPS, MAGIC_SLICE, MIN_PACKET_SIZE, MIX_PARAMS_LEN}, From f0072ce828c59d51922254178455a3b7d5a40cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 4 Mar 2024 12:12:27 +0000 Subject: [PATCH 280/394] moved reply surb storage to separate subcrate --- Cargo.lock | 17 +++++ Cargo.toml | 1 + common/client-core/Cargo.toml | 24 ++----- common/client-core/src/client/replies/mod.rs | 4 +- common/client-core/surb-storage/Cargo.toml | 30 +++++++++ .../client-core/{ => surb-storage}/build.rs | 0 .../20221130120000_create_initial_tables.sql | 0 .../src}/backend/browser_backend.rs | 4 +- .../src}/backend/fs_backend/error.rs | 0 .../src}/backend/fs_backend/manager.rs | 58 ++++++++--------- .../src}/backend/fs_backend/mod.rs | 8 +-- .../src}/backend/fs_backend/models.rs | 48 +++++++------- .../src}/backend/mod.rs | 2 +- .../src}/combined.rs | 4 +- .../src}/key_storage.rs | 26 +++++--- .../mod.rs => surb-storage/src/lib.rs} | 8 +-- .../src}/surb_storage.rs | 63 +++++++++---------- .../src}/tag_storage.rs | 20 +++--- 18 files changed, 177 insertions(+), 140 deletions(-) create mode 100644 common/client-core/surb-storage/Cargo.toml rename common/client-core/{ => surb-storage}/build.rs (100%) rename common/client-core/{ => surb-storage}/fs_surbs_migrations/20221130120000_create_initial_tables.sql (100%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/browser_backend.rs (88%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/fs_backend/error.rs (100%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/fs_backend/manager.rs (77%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/fs_backend/mod.rs (97%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/fs_backend/models.rs (79%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/backend/mod.rs (97%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/combined.rs (90%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/key_storage.rs (72%) rename common/client-core/{src/client/replies/reply_storage/mod.rs => surb-storage/src/lib.rs} (85%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/surb_storage.rs (77%) rename common/client-core/{src/client/replies/reply_storage => surb-storage/src}/tag_storage.rs (68%) diff --git a/Cargo.lock b/Cargo.lock index 28efbd69ef..89f8e79715 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5242,6 +5242,7 @@ dependencies = [ "hyper-util", "log", "nym-bandwidth-controller", + "nym-client-core-surb-storage", "nym-config", "nym-credential-storage", "nym-crypto", @@ -5279,6 +5280,22 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-client-core-surb-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "dashmap", + "log", + "nym-crypto", + "nym-sphinx", + "nym-task", + "sqlx", + "thiserror", + "time", + "tokio", +] + [[package]] name = "nym-client-wasm" version = "1.2.4-rc.2" diff --git a/Cargo.toml b/Cargo.toml index 6e322cc32a..13359ec2db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = [ "common/bandwidth-controller", "common/bin-common", "common/client-core", + "common/client-core/surb-storage", "common/client-libs/gateway-client", "common/client-libs/mixnet-client", "common/client-libs/validator-client", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index ae452c3e9b..9052001f15 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -13,22 +13,20 @@ async-trait = { workspace = true } base64 = "0.21.2" cfg-if = "1.0.0" clap = { workspace = true, optional = true } -dashmap = { workspace = true } -dirs = "4.0" futures = { workspace = true } humantime-serde = "1.0" log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } -reqwest = { workspace = true } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } sha2 = "0.10.6" +si-scale = "0.2.2" tap = "1.0.1" thiserror = { workspace = true } url = { workspace = true, features = ["serde"] } tungstenite = { workspace = true, default-features = false } tokio = { workspace = true, features = ["macros"] } -time = "0.3.17" +time = { workspace = true } zeroize = { workspace = true } # internal @@ -47,7 +45,7 @@ nym-validator-client = { path = "../client-libs/validator-client", default-featu nym-task = { path = "../task" } nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } -si-scale = "0.2.2" +nym-client-core-surb-storage = { path = "./surb-storage" } ### For serving prometheus metrics [target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] @@ -74,11 +72,6 @@ features = ["time"] version = "0.20.1" features = ["rustls-tls-native-roots"] -[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] -workspace = true -features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] -optional = true - [target."cfg(target_arch = \"wasm32\")".dependencies.wasm-bindgen-futures] workspace = true @@ -104,18 +97,9 @@ features = ["wasm-bindgen"] [dev-dependencies] tempfile = "3.1.0" -[build-dependencies] -tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -sqlx = { workspace = true, features = [ - "runtime-tokio-rustls", - "sqlite", - "macros", - "migrate", -] } - [features] default = [] cli = ["clap"] -fs-surb-storage = ["sqlx"] +fs-surb-storage = ["nym-client-core-surb-storage/fs-surb-storage"] wasm = ["nym-gateway-client/wasm"] metrics-server = [] diff --git a/common/client-core/src/client/replies/mod.rs b/common/client-core/src/client/replies/mod.rs index 61b5f19abf..7f425dbd38 100644 --- a/common/client-core/src/client/replies/mod.rs +++ b/common/client-core/src/client/replies/mod.rs @@ -2,4 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 pub mod reply_controller; -pub mod reply_storage; + +// re-export it under the old name to preserve import paths +pub use nym_client_core_surb_storage as reply_storage; diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml new file mode 100644 index 0000000000..24f466e1e3 --- /dev/null +++ b/common/client-core/surb-storage/Cargo.toml @@ -0,0 +1,30 @@ +[package] +name = "nym-client-core-surb-storage" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait.workspace = true +dashmap.workspace = true +log.workspace = true +thiserror.workspace = true +time.workspace = true + +nym-crypto = { path = "../../crypto", optional = true, default-features = false } +nym-sphinx = { path = "../../nymsphinx" } +nym-task = { path = "../../task" } + + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] +workspace = true +features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] +optional = true + +[build-dependencies] +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } + +[features] +fs-surb-storage = ["sqlx", "nym-crypto", "nym-crypto/hashing"] diff --git a/common/client-core/build.rs b/common/client-core/surb-storage/build.rs similarity index 100% rename from common/client-core/build.rs rename to common/client-core/surb-storage/build.rs diff --git a/common/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql b/common/client-core/surb-storage/fs_surbs_migrations/20221130120000_create_initial_tables.sql similarity index 100% rename from common/client-core/fs_surbs_migrations/20221130120000_create_initial_tables.sql rename to common/client-core/surb-storage/fs_surbs_migrations/20221130120000_create_initial_tables.sql diff --git a/common/client-core/src/client/replies/reply_storage/backend/browser_backend.rs b/common/client-core/surb-storage/src/backend/browser_backend.rs similarity index 88% rename from common/client-core/src/client/replies/reply_storage/backend/browser_backend.rs rename to common/client-core/surb-storage/src/backend/browser_backend.rs index ff2da4ab72..de39fd49b6 100644 --- a/common/client-core/src/client/replies/reply_storage/backend/browser_backend.rs +++ b/common/client-core/surb-storage/src/backend/browser_backend.rs @@ -1,8 +1,8 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::backend::Empty; -use crate::client::replies::reply_storage::{CombinedReplyStorage, ReplyStorageBackend}; +use crate::backend::Empty; +use crate::{CombinedReplyStorage, ReplyStorageBackend}; use async_trait::async_trait; // well, right now we don't have the browser storage : ( diff --git a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs b/common/client-core/surb-storage/src/backend/fs_backend/error.rs similarity index 100% rename from common/client-core/src/client/replies/reply_storage/backend/fs_backend/error.rs rename to common/client-core/surb-storage/src/backend/fs_backend/error.rs diff --git a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs similarity index 77% rename from common/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs rename to common/client-core/surb-storage/src/backend/fs_backend/manager.rs index 40c4da18fa..8b663b5c9a 100644 --- a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/manager.rs +++ b/common/client-core/surb-storage/src/backend/fs_backend/manager.rs @@ -1,8 +1,8 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError; -use crate::client::replies::reply_storage::backend::fs_backend::models::{ +use crate::backend::fs_backend::error::StorageError; +use crate::backend::fs_backend::models::{ ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, }; use log::{error, info}; @@ -10,16 +10,13 @@ use sqlx::ConnectOptions; use std::path::Path; #[derive(Debug, Clone)] -pub(crate) struct StorageManager { - pub(crate) connection_pool: sqlx::SqlitePool, +pub struct StorageManager { + pub connection_pool: sqlx::SqlitePool, } // all SQL goes here impl StorageManager { - pub(crate) async fn init<P: AsRef<Path>>( - database_path: P, - fresh: bool, - ) -> Result<Self, StorageError> { + pub async fn init<P: AsRef<Path>>(database_path: P, fresh: bool) -> Result<Self, StorageError> { // ensure the whole directory structure exists if let Some(parent_dir) = database_path.as_ref().parent() { std::fs::create_dir_all(parent_dir).map_err(|source| { @@ -57,45 +54,42 @@ impl StorageManager { } #[allow(dead_code)] - pub(crate) async fn status_table_exists(&self) -> Result<bool, sqlx::Error> { + pub async fn status_table_exists(&self) -> Result<bool, sqlx::Error> { sqlx::query!("SELECT name FROM sqlite_master WHERE type='table' AND name='status'") .fetch_optional(&self.connection_pool) .await .map(|r| r.is_some()) } - pub(crate) async fn create_status_table(&self) -> Result<(), sqlx::Error> { + pub async fn create_status_table(&self) -> Result<(), sqlx::Error> { sqlx::query!("INSERT INTO status(flush_in_progress, previous_flush_timestamp, client_in_use) VALUES (0, 0, 1)") .execute(&self.connection_pool) .await?; Ok(()) } - pub(crate) async fn get_flush_status(&self) -> Result<bool, sqlx::Error> { + pub async fn get_flush_status(&self) -> Result<bool, sqlx::Error> { sqlx::query!("SELECT flush_in_progress FROM status;") .fetch_one(&self.connection_pool) .await .map(|r| r.flush_in_progress > 0) } - pub(crate) async fn set_previous_flush_timestamp( - &self, - timestamp: i64, - ) -> Result<(), sqlx::Error> { + pub async fn set_previous_flush_timestamp(&self, timestamp: i64) -> Result<(), sqlx::Error> { sqlx::query!("UPDATE status SET previous_flush_timestamp = ?", timestamp) .execute(&self.connection_pool) .await?; Ok(()) } - pub(crate) async fn get_previous_flush_timestamp(&self) -> Result<i64, sqlx::Error> { + pub async fn get_previous_flush_timestamp(&self) -> Result<i64, sqlx::Error> { sqlx::query!("SELECT previous_flush_timestamp FROM status;") .fetch_one(&self.connection_pool) .await .map(|r| r.previous_flush_timestamp) } - pub(crate) async fn set_flush_status(&self, in_progress: bool) -> Result<(), sqlx::Error> { + pub async fn set_flush_status(&self, in_progress: bool) -> Result<(), sqlx::Error> { let in_progress_int = i64::from(in_progress); sqlx::query!("UPDATE status SET flush_in_progress = ?", in_progress_int) .execute(&self.connection_pool) @@ -103,14 +97,14 @@ impl StorageManager { Ok(()) } - pub(crate) async fn get_client_in_use_status(&self) -> Result<bool, sqlx::Error> { + pub async fn get_client_in_use_status(&self) -> Result<bool, sqlx::Error> { sqlx::query!("SELECT client_in_use FROM status;") .fetch_one(&self.connection_pool) .await .map(|r| r.client_in_use > 0) } - pub(crate) async fn set_client_in_use_status(&self, in_use: bool) -> Result<(), sqlx::Error> { + pub async fn set_client_in_use_status(&self, in_use: bool) -> Result<(), sqlx::Error> { let in_use_int = i64::from(in_use); sqlx::query!("UPDATE status SET client_in_use = ?", in_use_int) .execute(&self.connection_pool) @@ -118,20 +112,20 @@ impl StorageManager { Ok(()) } - pub(crate) async fn delete_all_tags(&self) -> Result<(), sqlx::Error> { + pub async fn delete_all_tags(&self) -> Result<(), sqlx::Error> { sqlx::query!("DELETE FROM sender_tag;") .execute(&self.connection_pool) .await?; Ok(()) } - pub(crate) async fn get_tags(&self) -> Result<Vec<StoredSenderTag>, sqlx::Error> { + pub async fn get_tags(&self) -> Result<Vec<StoredSenderTag>, sqlx::Error> { sqlx::query_as!(StoredSenderTag, "SELECT * FROM sender_tag;",) .fetch_all(&self.connection_pool) .await } - pub(crate) async fn insert_tag(&self, stored_tag: StoredSenderTag) -> Result<(), sqlx::Error> { + pub async fn insert_tag(&self, stored_tag: StoredSenderTag) -> Result<(), sqlx::Error> { sqlx::query!( r#" INSERT INTO sender_tag(recipient, tag) VALUES (?, ?); @@ -144,20 +138,20 @@ impl StorageManager { Ok(()) } - pub(crate) async fn delete_all_reply_keys(&self) -> Result<(), sqlx::Error> { + pub async fn delete_all_reply_keys(&self) -> Result<(), sqlx::Error> { sqlx::query!("DELETE FROM reply_key;") .execute(&self.connection_pool) .await?; Ok(()) } - pub(crate) async fn get_reply_keys(&self) -> Result<Vec<StoredReplyKey>, sqlx::Error> { + pub async fn get_reply_keys(&self) -> Result<Vec<StoredReplyKey>, sqlx::Error> { sqlx::query_as!(StoredReplyKey, "SELECT * FROM reply_key;",) .fetch_all(&self.connection_pool) .await } - pub(crate) async fn insert_reply_key( + pub async fn insert_reply_key( &self, stored_reply_key: StoredReplyKey, ) -> Result<(), sqlx::Error> { @@ -174,13 +168,13 @@ impl StorageManager { Ok(()) } - pub(crate) async fn get_surb_senders(&self) -> Result<Vec<StoredSurbSender>, sqlx::Error> { + pub async fn get_surb_senders(&self) -> Result<Vec<StoredSurbSender>, sqlx::Error> { sqlx::query_as!(StoredSurbSender, "SELECT * FROM reply_surb_sender;",) .fetch_all(&self.connection_pool) .await } - pub(crate) async fn insert_surb_sender( + pub async fn insert_surb_sender( &self, stored_surb_sender: StoredSurbSender, ) -> Result<i64, sqlx::Error> { @@ -197,7 +191,7 @@ impl StorageManager { Ok(id) } - pub(crate) async fn get_reply_surbs( + pub async fn get_reply_surbs( &self, sender_id: i64, ) -> Result<Vec<StoredReplySurb>, sqlx::Error> { @@ -210,7 +204,7 @@ impl StorageManager { .await } - pub(crate) async fn delete_all_reply_surb_data(&self) -> Result<(), sqlx::Error> { + pub async fn delete_all_reply_surb_data(&self) -> Result<(), sqlx::Error> { sqlx::query!("DELETE FROM reply_surb;") .execute(&self.connection_pool) .await?; @@ -222,7 +216,7 @@ impl StorageManager { Ok(()) } - pub(crate) async fn insert_reply_surb( + pub async fn insert_reply_surb( &self, stored_reply_surb: StoredReplySurb, ) -> Result<(), sqlx::Error> { @@ -238,7 +232,7 @@ impl StorageManager { Ok(()) } - pub(crate) async fn get_reply_surb_storage_metadata( + pub async fn get_reply_surb_storage_metadata( &self, ) -> Result<ReplySurbStorageMetadata, sqlx::Error> { sqlx::query_as!( @@ -251,7 +245,7 @@ impl StorageManager { .await } - pub(crate) async fn insert_reply_surb_storage_metadata( + pub async fn insert_reply_surb_storage_metadata( &self, metadata: ReplySurbStorageMetadata, ) -> Result<(), sqlx::Error> { diff --git a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs similarity index 97% rename from common/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs rename to common/client-core/surb-storage/src/backend/fs_backend/mod.rs index 4800634563..6f68c59201 100644 --- a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/mod.rs +++ b/common/client-core/surb-storage/src/backend/fs_backend/mod.rs @@ -1,12 +1,12 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::backend::fs_backend::manager::StorageManager; -use crate::client::replies::reply_storage::backend::fs_backend::models::{ +use crate::backend::fs_backend::manager::StorageManager; +use crate::backend::fs_backend::models::{ ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, }; -use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbs; -use crate::client::replies::reply_storage::{ +use crate::surb_storage::ReceivedReplySurbs; +use crate::{ CombinedReplyStorage, ReceivedReplySurbsMap, ReplyStorageBackend, SentReplyKeys, UsedSenderTags, }; use async_trait::async_trait; diff --git a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs b/common/client-core/surb-storage/src/backend/fs_backend/models.rs similarity index 79% rename from common/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs rename to common/client-core/surb-storage/src/backend/fs_backend/models.rs index c7b5196654..8acf83f676 100644 --- a/common/client-core/src/client/replies/reply_storage/backend/fs_backend/models.rs +++ b/common/client-core/surb-storage/src/backend/fs_backend/models.rs @@ -1,8 +1,8 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::backend::fs_backend::error::StorageError; -use crate::client::replies::reply_storage::key_storage::UsedReplyKey; +use crate::backend::fs_backend::error::StorageError; +use crate::key_storage::UsedReplyKey; use nym_crypto::generic_array::typenum::Unsigned; use nym_crypto::Digest; use nym_sphinx::addressing::clients::{Recipient, RecipientBytes}; @@ -12,13 +12,13 @@ use nym_sphinx::anonymous_replies::{ReplySurb, SurbEncryptionKey, SurbEncryption use nym_sphinx::params::ReplySurbKeyDigestAlgorithm; #[derive(Debug, Clone)] -pub(crate) struct StoredSenderTag { - pub(crate) recipient: Vec<u8>, - pub(crate) tag: Vec<u8>, +pub struct StoredSenderTag { + pub recipient: Vec<u8>, + pub tag: Vec<u8>, } impl StoredSenderTag { - pub(crate) fn new(recipient: RecipientBytes, tag: AnonymousSenderTag) -> StoredSenderTag { + pub fn new(recipient: RecipientBytes, tag: AnonymousSenderTag) -> StoredSenderTag { StoredSenderTag { recipient: recipient.to_vec(), tag: tag.to_bytes().to_vec(), @@ -57,14 +57,14 @@ impl TryFrom<StoredSenderTag> for (RecipientBytes, AnonymousSenderTag) { } #[derive(Debug, Clone)] -pub(crate) struct StoredReplyKey { - pub(crate) key_digest: Vec<u8>, - pub(crate) reply_key: Vec<u8>, - pub(crate) sent_at_timestamp: i64, +pub struct StoredReplyKey { + pub key_digest: Vec<u8>, + pub reply_key: Vec<u8>, + pub sent_at_timestamp: i64, } impl StoredReplyKey { - pub(crate) fn new(key_digest: EncryptionKeyDigest, reply_key: UsedReplyKey) -> StoredReplyKey { + pub fn new(key_digest: EncryptionKeyDigest, reply_key: UsedReplyKey) -> StoredReplyKey { StoredReplyKey { key_digest: key_digest.to_vec(), reply_key: (*reply_key).to_bytes(), @@ -105,14 +105,14 @@ impl TryFrom<StoredReplyKey> for (EncryptionKeyDigest, UsedReplyKey) { } } -pub(crate) struct StoredSurbSender { - pub(crate) id: i64, - pub(crate) tag: Vec<u8>, - pub(crate) last_sent_timestamp: i64, +pub struct StoredSurbSender { + pub id: i64, + pub tag: Vec<u8>, + pub last_sent_timestamp: i64, } impl StoredSurbSender { - pub(crate) fn new(tag: AnonymousSenderTag, last_sent_timestamp: i64) -> Self { + pub fn new(tag: AnonymousSenderTag, last_sent_timestamp: i64) -> Self { StoredSurbSender { // for the purposes of STORING data, // we ignore that field anyway @@ -143,13 +143,13 @@ impl TryFrom<StoredSurbSender> for (AnonymousSenderTag, i64) { } } -pub(crate) struct StoredReplySurb { - pub(crate) reply_surb_sender_id: i64, - pub(crate) reply_surb: Vec<u8>, +pub struct StoredReplySurb { + pub reply_surb_sender_id: i64, + pub reply_surb: Vec<u8>, } impl StoredReplySurb { - pub(crate) fn new(reply_surb_sender_id: i64, reply_surb: &ReplySurb) -> Self { + pub fn new(reply_surb_sender_id: i64, reply_surb: &ReplySurb) -> Self { StoredReplySurb { reply_surb_sender_id, reply_surb: reply_surb.to_bytes(), @@ -168,13 +168,13 @@ impl TryFrom<StoredReplySurb> for ReplySurb { } #[derive(Copy, Clone)] -pub(crate) struct ReplySurbStorageMetadata { - pub(crate) min_reply_surb_threshold: u32, - pub(crate) max_reply_surb_threshold: u32, +pub struct ReplySurbStorageMetadata { + pub min_reply_surb_threshold: u32, + pub max_reply_surb_threshold: u32, } impl ReplySurbStorageMetadata { - pub(crate) fn new(min_reply_surb_threshold: usize, max_reply_surb_threshold: usize) -> Self { + pub fn new(min_reply_surb_threshold: usize, max_reply_surb_threshold: usize) -> Self { Self { min_reply_surb_threshold: min_reply_surb_threshold as u32, max_reply_surb_threshold: max_reply_surb_threshold as u32, diff --git a/common/client-core/src/client/replies/reply_storage/backend/mod.rs b/common/client-core/surb-storage/src/backend/mod.rs similarity index 97% rename from common/client-core/src/client/replies/reply_storage/backend/mod.rs rename to common/client-core/surb-storage/src/backend/mod.rs index 557346a2da..e195051e4e 100644 --- a/common/client-core/src/client/replies/reply_storage/backend/mod.rs +++ b/common/client-core/surb-storage/src/backend/mod.rs @@ -1,7 +1,7 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::CombinedReplyStorage; +use crate::CombinedReplyStorage; use async_trait::async_trait; use std::error::Error; use thiserror::Error; diff --git a/common/client-core/src/client/replies/reply_storage/combined.rs b/common/client-core/surb-storage/src/combined.rs similarity index 90% rename from common/client-core/src/client/replies/reply_storage/combined.rs rename to common/client-core/surb-storage/src/combined.rs index c9fb9e4a5c..9d44e53923 100644 --- a/common/client-core/src/client/replies/reply_storage/combined.rs +++ b/common/client-core/surb-storage/src/combined.rs @@ -1,7 +1,7 @@ -// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::replies::reply_storage::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags}; +use crate::{ReceivedReplySurbsMap, SentReplyKeys, UsedSenderTags}; #[derive(Debug, Clone)] pub struct CombinedReplyStorage { diff --git a/common/client-core/src/client/replies/reply_storage/key_storage.rs b/common/client-core/surb-storage/src/key_storage.rs similarity index 72% rename from common/client-core/src/client/replies/reply_storage/key_storage.rs rename to common/client-core/surb-storage/src/key_storage.rs index 310a44e0eb..61a474ad5c 100644 --- a/common/client-core/src/client/replies/reply_storage/key_storage.rs +++ b/common/client-core/surb-storage/src/key_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use dashmap::iter::Iter; @@ -14,13 +14,19 @@ pub struct SentReplyKeys { inner: Arc<SentReplyKeysInner>, } +impl Default for SentReplyKeys { + fn default() -> Self { + SentReplyKeys::new() + } +} + #[derive(Debug)] struct SentReplyKeysInner { data: DashMap<EncryptionKeyDigest, UsedReplyKey>, } impl SentReplyKeys { - pub(crate) fn new() -> SentReplyKeys { + pub fn new() -> SentReplyKeys { SentReplyKeys { inner: Arc::new(SentReplyKeysInner { data: DashMap::new(), @@ -29,7 +35,7 @@ impl SentReplyKeys { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn from_raw(raw: Vec<(EncryptionKeyDigest, UsedReplyKey)>) -> SentReplyKeys { + pub fn from_raw(raw: Vec<(EncryptionKeyDigest, UsedReplyKey)>) -> SentReplyKeys { SentReplyKeys { inner: Arc::new(SentReplyKeysInner { data: raw.into_iter().collect(), @@ -37,35 +43,35 @@ impl SentReplyKeys { } } - pub(crate) fn as_raw_iter(&self) -> Iter<'_, EncryptionKeyDigest, UsedReplyKey> { + pub fn as_raw_iter(&self) -> Iter<'_, EncryptionKeyDigest, UsedReplyKey> { self.inner.data.iter() } - pub(crate) fn insert_multiple(&self, keys: Vec<SurbEncryptionKey>) { + pub fn insert_multiple(&self, keys: Vec<SurbEncryptionKey>) { let now = OffsetDateTime::now_utc().unix_timestamp(); for key in keys { self.insert(UsedReplyKey::new(key, now)) } } - pub(crate) fn insert(&self, key: UsedReplyKey) { + pub fn insert(&self, key: UsedReplyKey) { self.inner.data.insert(key.compute_digest(), key); } - pub(crate) fn try_pop(&self, digest: EncryptionKeyDigest) -> Option<UsedReplyKey> { + pub fn try_pop(&self, digest: EncryptionKeyDigest) -> Option<UsedReplyKey> { self.inner.data.remove(&digest).map(|(_k, v)| v) } - pub(crate) fn remove(&self, digest: EncryptionKeyDigest) { + pub fn remove(&self, digest: EncryptionKeyDigest) { self.inner.data.remove(&digest); } } #[derive(Debug, Copy, Clone)] -pub(crate) struct UsedReplyKey { +pub struct UsedReplyKey { key: SurbEncryptionKey, // the purpose of this field is to perform invalidation at relatively very long intervals - pub(crate) sent_at_timestamp: i64, + pub sent_at_timestamp: i64, } impl UsedReplyKey { diff --git a/common/client-core/src/client/replies/reply_storage/mod.rs b/common/client-core/surb-storage/src/lib.rs similarity index 85% rename from common/client-core/src/client/replies/reply_storage/mod.rs rename to common/client-core/surb-storage/src/lib.rs index 16a0a36cd4..9e0ba14b34 100644 --- a/common/client-core/src/client/replies/reply_storage/mod.rs +++ b/common/client-core/surb-storage/src/lib.rs @@ -1,11 +1,11 @@ // Copyright 2022 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -pub use crate::client::replies::reply_storage::combined::CombinedReplyStorage; -pub use crate::client::replies::reply_storage::key_storage::SentReplyKeys; -pub use crate::client::replies::reply_storage::surb_storage::ReceivedReplySurbsMap; -pub use crate::client::replies::reply_storage::tag_storage::UsedSenderTags; pub use backend::*; +pub use combined::CombinedReplyStorage; +pub use key_storage::SentReplyKeys; +pub use surb_storage::ReceivedReplySurbsMap; +pub use tag_storage::UsedSenderTags; mod backend; mod combined; diff --git a/common/client-core/src/client/replies/reply_storage/surb_storage.rs b/common/client-core/surb-storage/src/surb_storage.rs similarity index 77% rename from common/client-core/src/client/replies/reply_storage/surb_storage.rs rename to common/client-core/surb-storage/src/surb_storage.rs index cb88e30a90..92050c0104 100644 --- a/common/client-core/src/client/replies/reply_storage/surb_storage.rs +++ b/common/client-core/surb-storage/src/surb_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use dashmap::iter::Iter; @@ -28,10 +28,7 @@ struct ReceivedReplySurbsMapInner { } impl ReceivedReplySurbsMap { - pub(crate) fn new( - min_surb_threshold: usize, - max_surb_threshold: usize, - ) -> ReceivedReplySurbsMap { + pub fn new(min_surb_threshold: usize, max_surb_threshold: usize) -> ReceivedReplySurbsMap { ReceivedReplySurbsMap { inner: Arc::new(ReceivedReplySurbsMapInner { data: DashMap::new(), @@ -42,7 +39,7 @@ impl ReceivedReplySurbsMap { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn from_raw( + pub fn from_raw( min_surb_threshold: usize, max_surb_threshold: usize, raw: Vec<(AnonymousSenderTag, ReceivedReplySurbs)>, @@ -56,28 +53,28 @@ impl ReceivedReplySurbsMap { } } - pub(crate) fn as_raw_iter(&self) -> Iter<'_, AnonymousSenderTag, ReceivedReplySurbs> { + pub fn as_raw_iter(&self) -> Iter<'_, AnonymousSenderTag, ReceivedReplySurbs> { self.inner.data.iter() } - pub(crate) fn remove(&self, target: &AnonymousSenderTag) { + pub fn remove(&self, target: &AnonymousSenderTag) { self.inner.data.remove(target); } - pub(crate) fn reset_surbs_last_received_at(&self, target: &AnonymousSenderTag) { + pub fn reset_surbs_last_received_at(&self, target: &AnonymousSenderTag) { if let Some(mut entry) = self.inner.data.get_mut(target) { entry.surbs_last_received_at_timestamp = OffsetDateTime::now_utc().unix_timestamp(); } } - pub(crate) fn surbs_last_received_at(&self, target: &AnonymousSenderTag) -> Option<i64> { + pub fn surbs_last_received_at(&self, target: &AnonymousSenderTag) -> Option<i64> { self.inner .data .get(target) .map(|e| e.surbs_last_received_at()) } - pub(crate) fn pending_reception(&self, target: &AnonymousSenderTag) -> u32 { + pub fn pending_reception(&self, target: &AnonymousSenderTag) -> u32 { self.inner .data .get(target) @@ -85,7 +82,7 @@ impl ReceivedReplySurbsMap { .unwrap_or_default() } - pub(crate) fn increment_pending_reception( + pub fn increment_pending_reception( &self, target: &AnonymousSenderTag, amount: u32, @@ -96,7 +93,7 @@ impl ReceivedReplySurbsMap { .map(|mut e| e.increment_pending_reception(amount)) } - pub(crate) fn decrement_pending_reception( + pub fn decrement_pending_reception( &self, target: &AnonymousSenderTag, amount: u32, @@ -107,21 +104,21 @@ impl ReceivedReplySurbsMap { .map(|mut e| e.decrement_pending_reception(amount)) } - pub(crate) fn reset_pending_reception(&self, target: &AnonymousSenderTag) { + pub fn reset_pending_reception(&self, target: &AnonymousSenderTag) { if let Some(mut e) = self.inner.data.get_mut(target) { e.reset_pending_reception() } } - pub(crate) fn min_surb_threshold(&self) -> usize { + pub fn min_surb_threshold(&self) -> usize { self.inner.min_surb_threshold.load(Ordering::Relaxed) } - pub(crate) fn max_surb_threshold(&self) -> usize { + pub fn max_surb_threshold(&self) -> usize { self.inner.max_surb_threshold.load(Ordering::Relaxed) } - pub(crate) fn available_surbs(&self, target: &AnonymousSenderTag) -> usize { + pub fn available_surbs(&self, target: &AnonymousSenderTag) -> usize { self.inner .data .get(target) @@ -129,11 +126,11 @@ impl ReceivedReplySurbsMap { .unwrap_or_default() } - pub(crate) fn contains_surbs_for(&self, target: &AnonymousSenderTag) -> bool { + pub fn contains_surbs_for(&self, target: &AnonymousSenderTag) -> bool { self.inner.data.contains_key(target) } - pub(crate) fn get_reply_surbs( + pub fn get_reply_surbs( &self, target: &AnonymousSenderTag, amount: usize, @@ -150,7 +147,7 @@ impl ReceivedReplySurbsMap { } } - pub(crate) fn get_reply_surb_ignoring_threshold( + pub fn get_reply_surb_ignoring_threshold( &self, target: &AnonymousSenderTag, ) -> Option<(Option<ReplySurb>, usize)> { @@ -160,7 +157,7 @@ impl ReceivedReplySurbsMap { .map(|mut s| s.get_reply_surb()) } - pub(crate) fn get_reply_surb( + pub fn get_reply_surb( &self, target: &AnonymousSenderTag, ) -> Option<(Option<ReplySurb>, usize)> { @@ -174,7 +171,7 @@ impl ReceivedReplySurbsMap { }) } - pub(crate) fn insert_surbs<I: IntoIterator<Item = ReplySurb>>( + pub fn insert_surbs<I: IntoIterator<Item = ReplySurb>>( &self, target: &AnonymousSenderTag, surbs: I, @@ -189,7 +186,7 @@ impl ReceivedReplySurbsMap { } #[derive(Debug)] -pub(crate) struct ReceivedReplySurbs { +pub struct ReceivedReplySurbs { // in the future we'd probably want to put extra data here to indicate when the SURBs got received // so we could invalidate entries from the previous key rotations data: VecDeque<ReplySurb>, @@ -208,7 +205,7 @@ impl ReceivedReplySurbs { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn new_retrieved( + pub fn new_retrieved( surbs: Vec<ReplySurb>, surbs_last_received_at_timestamp: i64, ) -> ReceivedReplySurbs { @@ -220,33 +217,33 @@ impl ReceivedReplySurbs { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn surbs_ref(&self) -> &VecDeque<ReplySurb> { + pub fn surbs_ref(&self) -> &VecDeque<ReplySurb> { &self.data } - pub(crate) fn surbs_last_received_at(&self) -> i64 { + pub fn surbs_last_received_at(&self) -> i64 { self.surbs_last_received_at_timestamp } - pub(crate) fn pending_reception(&self) -> u32 { + pub fn pending_reception(&self) -> u32 { self.pending_reception } - pub(crate) fn increment_pending_reception(&mut self, amount: u32) -> u32 { + pub fn increment_pending_reception(&mut self, amount: u32) -> u32 { self.pending_reception += amount; self.pending_reception } - pub(crate) fn decrement_pending_reception(&mut self, amount: u32) -> u32 { + pub fn decrement_pending_reception(&mut self, amount: u32) -> u32 { self.pending_reception = self.pending_reception.saturating_sub(amount); self.pending_reception } - pub(crate) fn reset_pending_reception(&mut self) { + pub fn reset_pending_reception(&mut self) { self.pending_reception = 0; } - pub(crate) fn get_reply_surbs(&mut self, amount: usize) -> (Option<Vec<ReplySurb>>, usize) { + pub fn get_reply_surbs(&mut self, amount: usize) -> (Option<Vec<ReplySurb>>, usize) { if self.items_left() < amount { (None, self.items_left()) } else { @@ -255,7 +252,7 @@ impl ReceivedReplySurbs { } } - pub(crate) fn get_reply_surb(&mut self) -> (Option<ReplySurb>, usize) { + pub fn get_reply_surb(&mut self) -> (Option<ReplySurb>, usize) { (self.pop_surb(), self.items_left()) } @@ -268,7 +265,7 @@ impl ReceivedReplySurbs { } // realistically we're always going to be getting multiple surbs at once - pub(crate) fn insert_reply_surbs<I: IntoIterator<Item = ReplySurb>>(&mut self, surbs: I) { + pub fn insert_reply_surbs<I: IntoIterator<Item = ReplySurb>>(&mut self, surbs: I) { let mut v = surbs.into_iter().collect::<VecDeque<_>>(); trace!("storing {} surbs in the storage", v.len()); self.data.append(&mut v); diff --git a/common/client-core/src/client/replies/reply_storage/tag_storage.rs b/common/client-core/surb-storage/src/tag_storage.rs similarity index 68% rename from common/client-core/src/client/replies/reply_storage/tag_storage.rs rename to common/client-core/surb-storage/src/tag_storage.rs index 892018b6fc..8c72daffea 100644 --- a/common/client-core/src/client/replies/reply_storage/tag_storage.rs +++ b/common/client-core/surb-storage/src/tag_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use dashmap::DashMap; @@ -14,13 +14,19 @@ pub struct UsedSenderTags { inner: Arc<UsedSenderTagsInner>, } +impl Default for UsedSenderTags { + fn default() -> Self { + UsedSenderTags::new() + } +} + #[derive(Debug)] struct UsedSenderTagsInner { data: DashMap<RecipientBytes, AnonymousSenderTag>, } impl UsedSenderTags { - pub(crate) fn new() -> UsedSenderTags { + pub fn new() -> UsedSenderTags { UsedSenderTags { inner: Arc::new(UsedSenderTagsInner { data: DashMap::new(), @@ -29,7 +35,7 @@ impl UsedSenderTags { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn from_raw(raw: Vec<(RecipientBytes, AnonymousSenderTag)>) -> UsedSenderTags { + pub fn from_raw(raw: Vec<(RecipientBytes, AnonymousSenderTag)>) -> UsedSenderTags { UsedSenderTags { inner: Arc::new(UsedSenderTagsInner { data: raw.into_iter().collect(), @@ -38,22 +44,22 @@ impl UsedSenderTags { } #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] - pub(crate) fn as_raw_iter(&self) -> Iter<'_, RecipientBytes, AnonymousSenderTag> { + pub fn as_raw_iter(&self) -> Iter<'_, RecipientBytes, AnonymousSenderTag> { self.inner.data.iter() } - pub(crate) fn insert_new(&self, recipient: &Recipient, tag: AnonymousSenderTag) { + pub fn insert_new(&self, recipient: &Recipient, tag: AnonymousSenderTag) { self.inner.data.insert(recipient.to_bytes(), tag); } - pub(crate) fn try_get_existing(&self, recipient: &Recipient) -> Option<AnonymousSenderTag> { + pub fn try_get_existing(&self, recipient: &Recipient) -> Option<AnonymousSenderTag> { self.inner .data .get(&recipient.to_bytes()) .map(|r| *r.value()) } - pub(crate) fn exists(&self, recipient: &Recipient) -> bool { + pub fn exists(&self, recipient: &Recipient) -> bool { self.inner.data.contains_key(&recipient.to_bytes()) } } From f7edc223e9bca83871566036a7800862eb05ce7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 4 Mar 2024 13:04:35 +0000 Subject: [PATCH 281/394] initial db schema --- .../client-core/gateways-storage/Cargo.toml | 23 ++++++++++++++ common/client-core/gateways-storage/build.rs | 31 +++++++++++++++++++ .../20240304120000_create_initial_tables.sql | 31 +++++++++++++++++++ .../client-core/gateways-storage/src/lib.rs | 14 +++++++++ 4 files changed, 99 insertions(+) create mode 100644 common/client-core/gateways-storage/Cargo.toml create mode 100644 common/client-core/gateways-storage/build.rs create mode 100644 common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql create mode 100644 common/client-core/gateways-storage/src/lib.rs diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml new file mode 100644 index 0000000000..f51396a354 --- /dev/null +++ b/common/client-core/gateways-storage/Cargo.toml @@ -0,0 +1,23 @@ +[package] +name = "nym-client-core-gateways-storage" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +async-trait.workspace = true +log.workspace = true +thiserror.workspace = true + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] +workspace = true +features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] +optional = true + +[build-dependencies] +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } +sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } + +[features] +fs-gateways-storage = ["sqlx"] \ No newline at end of file diff --git a/common/client-core/gateways-storage/build.rs b/common/client-core/gateways-storage/build.rs new file mode 100644 index 0000000000..f8b85cbb4a --- /dev/null +++ b/common/client-core/gateways-storage/build.rs @@ -0,0 +1,31 @@ +// Copyright 2022 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +#[tokio::main] +async fn main() { + #[cfg(feature = "fs-gateways-storage")] + { + use sqlx::{Connection, SqliteConnection}; + use std::env; + + let out_dir = env::var("OUT_DIR").unwrap(); + let database_path = format!("{out_dir}/gateways-storage-example.sqlite"); + + let mut conn = SqliteConnection::connect(&format!("sqlite://{database_path}?mode=rwc")) + .await + .expect("Failed to create SQLx database connection"); + + sqlx::migrate!("./fs_gateways_migrations") + .run(&mut conn) + .await + .expect("Failed to perform SQLx migrations"); + + #[cfg(target_family = "unix")] + println!("cargo:rustc-env=DATABASE_URL=sqlite://{}", &database_path); + + #[cfg(target_family = "windows")] + // for some strange reason we need to add a leading `/` to the windows path even though it's + // not a valid windows path... but hey, it works... + println!("cargo:rustc-env=DATABASE_URL=sqlite:///{}", &database_path); + } +} diff --git a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql new file mode 100644 index 0000000000..95f347024c --- /dev/null +++ b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql @@ -0,0 +1,31 @@ +/* + * Copyright 2024 - Nym Technologies SA <contact@nymtech.net> + * SPDX-License-Identifier: Apache-2.0 + */ + +CREATE TABLE active_gateway +( + id INTEGER PRIMARY KEY CHECK (id = 0), + active_gateway_id_bs58 TEXT REFERENCES registered_gateway (gateway_id_bs58) +); + +CREATE TABLE registered_gateway +( + gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY, + gateway_type TEXT CHECK ( gateway_type IN ('remote', 'custom') ) NOT NULL DEFAULT 'remote' +); + +CREATE TABLE remote_gateway_details +( + gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY REFERENCES registered_gateway (gateway_id_bs58), + derived_aes128_ctr_blake3_hmac_keys_bs58 TEXT NOT NULL, + gateway_owner_address TEXT NOT NULL, + gateway_listener TEXT NOT NULL +); + +CREATE TABLE custom_gateway_details +( + gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY REFERENCES registered_gateway (gateway_id_bs58), + data BLOB +); + diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs new file mode 100644 index 0000000000..7d12d9af81 --- /dev/null +++ b/common/client-core/gateways-storage/src/lib.rs @@ -0,0 +1,14 @@ +pub fn add(left: usize, right: usize) -> usize { + left + right +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn it_works() { + let result = add(2, 2); + assert_eq!(result, 4); + } +} From 4c9de843c556190483cf905f768aed6bc94244b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 4 Mar 2024 14:56:56 +0000 Subject: [PATCH 282/394] types --- Cargo.lock | 22 ++- Cargo.toml | 1 + common/client-core/Cargo.toml | 1 + .../client-core/gateways-storage/Cargo.toml | 7 + .../client-core/gateways-storage/src/error.rs | 50 +++++ .../client-core/gateways-storage/src/lib.rs | 32 ++-- .../gateways-storage/src/models.rs | 172 ++++++++++++++++++ .../src/registration/handshake/shared_key.rs | 2 +- 8 files changed, 271 insertions(+), 16 deletions(-) create mode 100644 common/client-core/gateways-storage/src/error.rs create mode 100644 common/client-core/gateways-storage/src/models.rs diff --git a/Cargo.lock b/Cargo.lock index 89f8e79715..b61fc7884b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5232,8 +5232,6 @@ dependencies = [ "base64 0.21.4", "cfg-if", "clap 4.4.7", - "dashmap", - "dirs 4.0.0", "futures", "gloo-timers", "http-body-util", @@ -5242,6 +5240,7 @@ dependencies = [ "hyper-util", "log", "nym-bandwidth-controller", + "nym-client-core-gateways-storage", "nym-client-core-surb-storage", "nym-config", "nym-credential-storage", @@ -5258,12 +5257,10 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", - "reqwest", "serde", "serde_json", "sha2 0.10.8", "si-scale", - "sqlx", "tap", "tempfile", "thiserror", @@ -5280,6 +5277,23 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-client-core-gateways-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "cosmrs 0.15.0 (git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-validator-features)", + "log", + "nym-crypto", + "nym-gateway-requests", + "serde", + "sqlx", + "thiserror", + "tokio", + "url", + "zeroize", +] + [[package]] name = "nym-client-core-surb-storage" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index 13359ec2db..f7a7982019 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ members = [ "common/bin-common", "common/client-core", "common/client-core/surb-storage", + "common/client-core/gateways-storage", "common/client-libs/gateway-client", "common/client-libs/mixnet-client", "common/client-libs/validator-client", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 9052001f15..b2643888c5 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -46,6 +46,7 @@ nym-task = { path = "../task" } nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } nym-client-core-surb-storage = { path = "./surb-storage" } +nym-client-core-gateways-storage = { path = "./gateways-storage" } ### For serving prometheus metrics [target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml index f51396a354..04f6146f09 100644 --- a/common/client-core/gateways-storage/Cargo.toml +++ b/common/client-core/gateways-storage/Cargo.toml @@ -7,8 +7,15 @@ edition = "2021" [dependencies] async-trait.workspace = true +cosmrs.workspace = true log.workspace = true +serde = { workspace = true, features = ["derive"] } thiserror.workspace = true +url.workspace = true +zeroize = { workspace = true, features = ["zeroize_derive"] } + +nym-crypto = { path = "../../crypto", features = ["asymmetric"] } +nym-gateway-requests = { path = "../../../gateway/gateway-requests" } [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] workspace = true diff --git a/common/client-core/gateways-storage/src/error.rs b/common/client-core/gateways-storage/src/error.rs new file mode 100644 index 0000000000..287ffb4567 --- /dev/null +++ b/common/client-core/gateways-storage/src/error.rs @@ -0,0 +1,50 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_crypto::asymmetric::identity::Ed25519RecoveryError; +use nym_gateway_requests::registration::handshake::shared_key::SharedKeyConversionError; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum GatewaysStorageError { + #[error("{typ} is not a valid gateway type")] + InvalidGatewayType { typ: String }, + + #[error("the provided gateway identity {gateway_id} is malformed: {source}")] + MalformedGatewayIdentity { + gateway_id: String, + + #[source] + source: Ed25519RecoveryError, + }, + + #[error("the account owner of gateway {gateway_id} ({raw_owner}) is malformed: {source}")] + MalformedGatewayOwnerAccountAddress { + gateway_id: String, + + raw_owner: String, + + #[source] + source: cosmrs::ErrorReport, + }, + + #[error("the shared keys provided for gateway {gateway_id} are malformed: {source}")] + MalformedSharedKeys { + gateway_id: String, + + #[source] + source: SharedKeyConversionError, + }, + + #[error( + "the listening address of gateway {gateway_id} ({raw_listener}) is malformed: {source}" + )] + MalformedListener { + gateway_id: String, + + raw_listener: String, + + #[source] + source: url::ParseError, + }, +} diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 7d12d9af81..358a293930 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -1,14 +1,24 @@ -pub fn add(left: usize, right: usize) -> usize { - left + right -} +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 -#[cfg(test)] -mod tests { - use super::*; +use async_trait::async_trait; +use std::error::Error; - #[test] - fn it_works() { - let result = add(2, 2); - assert_eq!(result, 4); - } +pub mod error; +pub mod models; + +pub use error::GatewaysStorageError; + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait GatewayDetailsStore { + type StorageError: Error; + + async fn active_gateway(&self) -> Result<Option<()>, Self::StorageError>; + + async fn all_gateways(&self) -> Result<Vec<()>, Self::StorageError>; + + async fn load_gateway_details(&self) -> Result<(), Self::StorageError>; + + async fn store_gateway_details(&self) -> Result<(), Self::StorageError>; } diff --git a/common/client-core/gateways-storage/src/models.rs b/common/client-core/gateways-storage/src/models.rs new file mode 100644 index 0000000000..c78156ef73 --- /dev/null +++ b/common/client-core/gateways-storage/src/models.rs @@ -0,0 +1,172 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::GatewaysStorageError; +use cosmrs::AccountId; +use nym_crypto::asymmetric::identity; +use nym_gateway_requests::registration::handshake::SharedKeys; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; +use std::str::FromStr; +use url::Url; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +pub const REMOTE_GATEWAY_TYPE: &str = "remote"; +pub const CUSTOM_GATEWAY_TYPE: &str = "custom"; + +#[derive(Debug, Copy, Clone, Default)] +pub enum GatewayType { + #[default] + Remote, + + Custom, +} + +impl FromStr for GatewayType { + type Err = GatewaysStorageError; + + fn from_str(s: &str) -> Result<Self, Self::Err> { + match s { + REMOTE_GATEWAY_TYPE => Ok(GatewayType::Remote), + CUSTOM_GATEWAY_TYPE => Ok(GatewayType::Custom), + other => Err(GatewaysStorageError::InvalidGatewayType { + typ: other.to_string(), + }), + } + } +} + +impl Display for GatewayType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + GatewayType::Remote => REMOTE_GATEWAY_TYPE.fmt(f), + GatewayType::Custom => CUSTOM_GATEWAY_TYPE.fmt(f), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +pub struct RawRegisteredGateway { + pub gateway_id_bs58: String, + pub gateway_type: String, +} + +#[derive(Debug, Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] +#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +pub struct RawRemoteGatewayDetails { + pub gateway_id_bs58: String, + pub derived_aes128_ctr_blake3_hmac_keys_bs58: String, + pub gateway_owner_address: String, + pub gateway_listener: String, +} + +impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { + type Error = GatewaysStorageError; + + fn try_from(value: RawRemoteGatewayDetails) -> Result<Self, Self::Error> { + let gateway_id = + identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { + GatewaysStorageError::MalformedGatewayIdentity { + gateway_id: value.gateway_id_bs58.clone(), + source, + } + })?; + + let derived_aes128_ctr_blake3_hmac_keys = + SharedKeys::try_from_base58_string(&value.derived_aes128_ctr_blake3_hmac_keys_bs58) + .map_err(|source| GatewaysStorageError::MalformedSharedKeys { + gateway_id: value.gateway_id_bs58.clone(), + source, + })?; + + let gateway_owner_address = + AccountId::from_str(&value.gateway_owner_address).map_err(|source| { + GatewaysStorageError::MalformedGatewayOwnerAccountAddress { + gateway_id: value.gateway_id_bs58.clone(), + raw_owner: value.gateway_owner_address.clone(), + source, + } + })?; + + let gateway_listener = Url::parse(&value.gateway_listener).map_err(|source| { + GatewaysStorageError::MalformedListener { + gateway_id: value.gateway_id_bs58.clone(), + raw_listener: value.gateway_listener.clone(), + source, + } + })?; + + Ok(RemoteGatewayDetails { + gateway_id, + derived_aes128_ctr_blake3_hmac_keys, + gateway_owner_address, + gateway_listener, + }) + } +} + +impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { + fn from(value: RemoteGatewayDetails) -> Self { + RawRemoteGatewayDetails { + gateway_id_bs58: value.gateway_id.to_base58_string(), + derived_aes128_ctr_blake3_hmac_keys_bs58: value + .derived_aes128_ctr_blake3_hmac_keys + .to_base58_string(), + gateway_owner_address: value.gateway_owner_address.to_string(), + gateway_listener: value.gateway_listener.to_string(), + } + } +} + +#[derive(Debug, Zeroize, ZeroizeOnDrop)] +pub struct RemoteGatewayDetails { + #[zeroize(skip)] + pub gateway_id: identity::PublicKey, + pub derived_aes128_ctr_blake3_hmac_keys: SharedKeys, + #[zeroize(skip)] + pub gateway_owner_address: AccountId, + #[zeroize(skip)] + pub gateway_listener: Url, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +pub struct RawCustomGatewayDetails { + pub gateway_id_bs58: String, + pub data: Option<Vec<u8>>, +} + +impl TryFrom<RawCustomGatewayDetails> for CustomGatewayDetails { + type Error = GatewaysStorageError; + + fn try_from(value: RawCustomGatewayDetails) -> Result<Self, Self::Error> { + let gateway_id = + identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { + GatewaysStorageError::MalformedGatewayIdentity { + gateway_id: value.gateway_id_bs58.clone(), + source, + } + })?; + + Ok(CustomGatewayDetails { + gateway_id, + data: value.data, + }) + } +} + +impl From<CustomGatewayDetails> for RawCustomGatewayDetails { + fn from(value: CustomGatewayDetails) -> Self { + RawCustomGatewayDetails { + gateway_id_bs58: value.gateway_id.to_base58_string(), + data: value.data, + } + } +} + +#[derive(Debug)] +pub struct CustomGatewayDetails { + pub gateway_id: identity::PublicKey, + pub data: Option<Vec<u8>>, +} diff --git a/gateway/gateway-requests/src/registration/handshake/shared_key.rs b/gateway/gateway-requests/src/registration/handshake/shared_key.rs index d3101017a4..4d4dce6e7f 100644 --- a/gateway/gateway-requests/src/registration/handshake/shared_key.rs +++ b/gateway/gateway-requests/src/registration/handshake/shared_key.rs @@ -30,7 +30,7 @@ pub struct SharedKeys { mac_key: MacKey, } -#[derive(Debug, Error)] +#[derive(Debug, Clone, Copy, Error)] pub enum SharedKeyConversionError { #[error("the string representation of the shared keys was malformed - {0}")] DecodeError(#[from] bs58::decode::Error), From 84a36c00b4a3387973fe0f122383b2e146c0dd1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 5 Mar 2024 09:35:47 +0000 Subject: [PATCH 283/394] added registration timestamp --- common/client-core/gateways-storage/Cargo.toml | 1 + .../20240304120000_create_initial_tables.sql | 5 +++-- common/client-core/gateways-storage/src/lib.rs | 4 ++++ common/client-core/gateways-storage/src/models.rs | 5 +++++ 4 files changed, 13 insertions(+), 2 deletions(-) diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml index 04f6146f09..a4c3f44fa4 100644 --- a/common/client-core/gateways-storage/Cargo.toml +++ b/common/client-core/gateways-storage/Cargo.toml @@ -11,6 +11,7 @@ cosmrs.workspace = true log.workspace = true serde = { workspace = true, features = ["derive"] } thiserror.workspace = true +time.workspace = true url.workspace = true zeroize = { workspace = true, features = ["zeroize_derive"] } diff --git a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql index 95f347024c..6df9d40a1a 100644 --- a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql +++ b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql @@ -11,8 +11,9 @@ CREATE TABLE active_gateway CREATE TABLE registered_gateway ( - gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY, - gateway_type TEXT CHECK ( gateway_type IN ('remote', 'custom') ) NOT NULL DEFAULT 'remote' + gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY, + registration_timestamp TIMESTAMP WITHOUT TIME ZONE NOT NULL, + gateway_type TEXT CHECK ( gateway_type IN ('remote', 'custom') ) NOT NULL DEFAULT 'remote' ); CREATE TABLE remote_gateway_details diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 358a293930..adda95c055 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -14,11 +14,15 @@ pub use error::GatewaysStorageError; pub trait GatewayDetailsStore { type StorageError: Error; + /// Returns details of the currently active gateway, if available. async fn active_gateway(&self) -> Result<Option<()>, Self::StorageError>; + /// Returns details of all registered gateways. async fn all_gateways(&self) -> Result<Vec<()>, Self::StorageError>; + /// Returns details of the particular gateway. async fn load_gateway_details(&self) -> Result<(), Self::StorageError>; + /// Store the provided gateway details. async fn store_gateway_details(&self) -> Result<(), Self::StorageError>; } diff --git a/common/client-core/gateways-storage/src/models.rs b/common/client-core/gateways-storage/src/models.rs index c78156ef73..ac8f884dd5 100644 --- a/common/client-core/gateways-storage/src/models.rs +++ b/common/client-core/gateways-storage/src/models.rs @@ -8,6 +8,7 @@ use nym_gateway_requests::registration::handshake::SharedKeys; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::str::FromStr; +use time::OffsetDateTime; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -49,6 +50,10 @@ impl Display for GatewayType { #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct RawRegisteredGateway { pub gateway_id_bs58: String, + + // not necessarily needed but is nice for display purposes + pub registration_timestamp: OffsetDateTime, + pub gateway_type: String, } From fe2edd56a8b1fbd73bf81d647b833c2409faf01b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 5 Mar 2024 15:39:56 +0000 Subject: [PATCH 284/394] adjusting the trait --- .../client-core/gateways-storage/Cargo.toml | 1 + .../src/backend/fs_backend/error.rs | 38 +++++++++ .../src/backend/fs_backend/manager.rs | 53 +++++++++++++ .../src/backend/fs_backend/mod.rs | 46 +++++++++++ .../src/backend/fs_backend/models.rs | 2 + .../src/backend/mem_backend.rs | 69 ++++++++++++++++ .../gateways-storage/src/backend/mod.rs | 7 ++ .../client-core/gateways-storage/src/error.rs | 2 +- .../client-core/gateways-storage/src/lib.rs | 28 +++++-- .../src/{models.rs => types.rs} | 78 +++++++++++++++---- .../src/backend/fs_backend/error.rs | 2 +- 11 files changed, 300 insertions(+), 26 deletions(-) create mode 100644 common/client-core/gateways-storage/src/backend/fs_backend/error.rs create mode 100644 common/client-core/gateways-storage/src/backend/fs_backend/manager.rs create mode 100644 common/client-core/gateways-storage/src/backend/fs_backend/mod.rs create mode 100644 common/client-core/gateways-storage/src/backend/fs_backend/models.rs create mode 100644 common/client-core/gateways-storage/src/backend/mem_backend.rs create mode 100644 common/client-core/gateways-storage/src/backend/mod.rs rename common/client-core/gateways-storage/src/{models.rs => types.rs} (72%) diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml index a4c3f44fa4..3968df079e 100644 --- a/common/client-core/gateways-storage/Cargo.toml +++ b/common/client-core/gateways-storage/Cargo.toml @@ -12,6 +12,7 @@ log.workspace = true serde = { workspace = true, features = ["derive"] } thiserror.workspace = true time.workspace = true +tokio = { workspace = true, features = ["sync"] } url.workspace = true zeroize = { workspace = true, features = ["zeroize_derive"] } diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs new file mode 100644 index 0000000000..0a39dbbe06 --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs @@ -0,0 +1,38 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use std::io; +use std::path::PathBuf; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum StorageError { + #[error("the provided database path doesn't have a filename defined")] + DatabasePathWithoutFilename { provided_path: PathBuf }, + + #[error("unable to create the directory for the database at {}: {source}", provided_path.display())] + DatabasePathUnableToCreateParentDirectory { + provided_path: PathBuf, + source: io::Error, + }, + + #[error("failed to perform sqlx migration: {source}")] + MigrationError { + #[source] + #[from] + source: sqlx::migrate::MigrateError, + }, + + #[error("failed to connect to the underlying connection pool: {source}")] + DatabaseConnectionError { + #[source] + source: sqlx::error::Error, + }, + + #[error("failed to run the SQL query: {source}")] + QueryError { + #[source] + #[from] + source: sqlx::error::Error, + }, +} diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs new file mode 100644 index 0000000000..299b16ea8b --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -0,0 +1,53 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::backend::fs_backend::error::StorageError; +use crate::backend::fs_backend::models::{ + ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, +}; +use log::{error, info}; +use sqlx::ConnectOptions; +use std::path::Path; + +#[derive(Debug, Clone)] +pub struct StorageManager { + pub connection_pool: sqlx::SqlitePool, +} + +// all SQL goes here +impl StorageManager { + pub async fn init<P: AsRef<Path>>(database_path: P, fresh: bool) -> Result<Self, StorageError> { + // ensure the whole directory structure exists + if let Some(parent_dir) = database_path.as_ref().parent() { + std::fs::create_dir_all(parent_dir).map_err(|source| { + StorageError::DatabasePathUnableToCreateParentDirectory { + provided_path: database_path.as_ref().to_path_buf(), + source, + } + })?; + } + + let mut opts = sqlx::sqlite::SqliteConnectOptions::new() + .filename(database_path) + .create_if_missing(fresh); + + opts.disable_statement_logging(); + + let connection_pool = sqlx::SqlitePool::connect_with(opts) + .await + .map_err(|source| { + error!("Failed to connect to SQLx database: {err}"); + StorageError::DatabaseConnectionError { source } + })?; + + sqlx::migrate!("./fs_gateways_migrations") + .run(&connection_pool) + .await + .inspect_err(|err| { + error!("Failed to initialize SQLx database: {err}"); + })?; + + info!("Database migration finished!"); + Ok(StorageManager { connection_pool }) + } +} diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs new file mode 100644 index 0000000000..e8ddc05d83 --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -0,0 +1,46 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::types::GatewayDetails; +use crate::GatewayDetailsStore; +use async_trait::async_trait; +use manager::StorageManager; + +mod error; +mod manager; +mod models; + +pub struct OnDiskGatewayDetails { + manager: StorageManager, +} + +#[async_trait] +impl GatewayDetailsStore for OnDiskGatewayDetails { + type StorageError = error::StorageError; + + async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { + todo!() + } + + async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { + todo!() + } + + async fn load_gateway_details( + &self, + gateway_id: &str, + ) -> Result<GatewayDetails, Self::StorageError> { + todo!() + } + + async fn store_gateway_details( + &self, + details: GatewayDetails, + ) -> Result<(), Self::StorageError> { + todo!() + } + + async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + todo!() + } +} diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/models.rs b/common/client-core/gateways-storage/src/backend/fs_backend/models.rs new file mode 100644 index 0000000000..755fb6cc8b --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/fs_backend/models.rs @@ -0,0 +1,2 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs new file mode 100644 index 0000000000..53afb6007b --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -0,0 +1,69 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::types::GatewayDetails; +use crate::{BadGateway, GatewayDetailsStore}; +use async_trait::async_trait; +use std::collections::HashMap; +use std::sync::Arc; +use thiserror::Error; +use tokio::sync::RwLock; + +#[derive(Debug, Error)] +pub enum InMemStorageError { + #[error("gateway {gateway_id} does not exist")] + GatewayDoesNotExist { gateway_id: String }, + + #[error(transparent)] + MalformedGateway(#[from] BadGateway), +} + +pub struct InMemStorage { + inner: Arc<RwLock<InMemStorageInner>>, +} + +struct InMemStorageInner { + active_gateway: Option<String>, + gateways: HashMap<String, GatewayDetails>, +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl GatewayDetailsStore for InMemStorage { + type StorageError = InMemStorageError; + + async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { + // let guard = self.inner.read().await; + // + // let foo = guard.active_gateway.map(|id| { + // // SAFETY: if particular gateway is set as active, its details MUST exist + // #[allow(clippy::unwrap_used)] + // guard.gateways.get(&id).unwrap() + // }); + + todo!() + // foo.cloned() + } + + async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { + todo!() + } + + async fn load_gateway_details( + &self, + gateway_id: &str, + ) -> Result<GatewayDetails, Self::StorageError> { + todo!() + } + + async fn store_gateway_details( + &self, + details: GatewayDetails, + ) -> Result<(), Self::StorageError> { + todo!() + } + + async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + todo!() + } +} diff --git a/common/client-core/gateways-storage/src/backend/mod.rs b/common/client-core/gateways-storage/src/backend/mod.rs new file mode 100644 index 0000000000..9414bb4f14 --- /dev/null +++ b/common/client-core/gateways-storage/src/backend/mod.rs @@ -0,0 +1,7 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] +pub mod fs_backend; + +pub mod mem_backend; diff --git a/common/client-core/gateways-storage/src/error.rs b/common/client-core/gateways-storage/src/error.rs index 287ffb4567..f547164022 100644 --- a/common/client-core/gateways-storage/src/error.rs +++ b/common/client-core/gateways-storage/src/error.rs @@ -6,7 +6,7 @@ use nym_gateway_requests::registration::handshake::shared_key::SharedKeyConversi use thiserror::Error; #[derive(Debug, Error)] -pub enum GatewaysStorageError { +pub enum BadGateway { #[error("{typ} is not a valid gateway type")] InvalidGatewayType { typ: String }, diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index adda95c055..393e6438ff 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -1,28 +1,42 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + use async_trait::async_trait; use std::error::Error; +mod backend; pub mod error; -pub mod models; +pub mod types; -pub use error::GatewaysStorageError; +use crate::types::GatewayDetails; +pub use error::BadGateway; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] pub trait GatewayDetailsStore { - type StorageError: Error; + type StorageError: Error + From<error::BadGateway>; /// Returns details of the currently active gateway, if available. - async fn active_gateway(&self) -> Result<Option<()>, Self::StorageError>; + async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError>; /// Returns details of all registered gateways. - async fn all_gateways(&self) -> Result<Vec<()>, Self::StorageError>; + async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError>; /// Returns details of the particular gateway. - async fn load_gateway_details(&self) -> Result<(), Self::StorageError>; + async fn load_gateway_details( + &self, + gateway_id: &str, + ) -> Result<GatewayDetails, Self::StorageError>; /// Store the provided gateway details. - async fn store_gateway_details(&self) -> Result<(), Self::StorageError>; + async fn store_gateway_details( + &self, + details: GatewayDetails, + ) -> Result<(), Self::StorageError>; + + /// Remove given gateway details from the underlying store. + async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError>; } diff --git a/common/client-core/gateways-storage/src/models.rs b/common/client-core/gateways-storage/src/types.rs similarity index 72% rename from common/client-core/gateways-storage/src/models.rs rename to common/client-core/gateways-storage/src/types.rs index ac8f884dd5..383500284f 100644 --- a/common/client-core/gateways-storage/src/models.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -1,13 +1,14 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::GatewaysStorageError; +use crate::BadGateway; use cosmrs::AccountId; use nym_crypto::asymmetric::identity; use nym_gateway_requests::registration::handshake::SharedKeys; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::str::FromStr; +use std::sync::Arc; use time::OffsetDateTime; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -15,6 +16,37 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub const REMOTE_GATEWAY_TYPE: &str = "remote"; pub const CUSTOM_GATEWAY_TYPE: &str = "custom"; +#[derive(Debug)] +pub struct GatewayRegistration { + pub details: GatewayDetails, + pub registration_timestamp: OffsetDateTime, +} + +#[derive(Debug)] +pub enum GatewayDetails { + /// Standard details of a remote gateway + Remote(RemoteGatewayDetails), + + /// Custom gateway setup, such as for a client embedded inside gateway itself + Custom(CustomGatewayDetails), +} + +impl GatewayDetails { + pub fn gateway_id(&self) -> identity::PublicKey { + match self { + GatewayDetails::Remote(details) => details.gateway_id, + GatewayDetails::Custom(details) => details.gateway_id, + } + } + + pub fn shared_key(&self) -> Option<&SharedKeys> { + match self { + GatewayDetails::Remote(details) => Some(&details.derived_aes128_ctr_blake3_hmac_keys), + GatewayDetails::Custom(_) => None, + } + } +} + #[derive(Debug, Copy, Clone, Default)] pub enum GatewayType { #[default] @@ -24,13 +56,13 @@ pub enum GatewayType { } impl FromStr for GatewayType { - type Err = GatewaysStorageError; + type Err = BadGateway; fn from_str(s: &str) -> Result<Self, Self::Err> { match s { REMOTE_GATEWAY_TYPE => Ok(GatewayType::Remote), CUSTOM_GATEWAY_TYPE => Ok(GatewayType::Custom), - other => Err(GatewaysStorageError::InvalidGatewayType { + other => Err(BadGateway::InvalidGatewayType { typ: other.to_string(), }), } @@ -57,6 +89,15 @@ pub struct RawRegisteredGateway { pub gateway_type: String, } +#[derive(Debug, Clone, Copy)] +pub struct RegisteredGateway { + pub gateway_id: identity::PublicKey, + + pub registration_timestamp: OffsetDateTime, + + pub gateway_type: GatewayType, +} + #[derive(Debug, Zeroize, ZeroizeOnDrop, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct RawRemoteGatewayDetails { @@ -67,27 +108,28 @@ pub struct RawRemoteGatewayDetails { } impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { - type Error = GatewaysStorageError; + type Error = BadGateway; fn try_from(value: RawRemoteGatewayDetails) -> Result<Self, Self::Error> { let gateway_id = identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { - GatewaysStorageError::MalformedGatewayIdentity { + BadGateway::MalformedGatewayIdentity { gateway_id: value.gateway_id_bs58.clone(), source, } })?; - let derived_aes128_ctr_blake3_hmac_keys = + let derived_aes128_ctr_blake3_hmac_keys = Arc::new( SharedKeys::try_from_base58_string(&value.derived_aes128_ctr_blake3_hmac_keys_bs58) - .map_err(|source| GatewaysStorageError::MalformedSharedKeys { + .map_err(|source| BadGateway::MalformedSharedKeys { gateway_id: value.gateway_id_bs58.clone(), source, - })?; + })?, + ); let gateway_owner_address = AccountId::from_str(&value.gateway_owner_address).map_err(|source| { - GatewaysStorageError::MalformedGatewayOwnerAccountAddress { + BadGateway::MalformedGatewayOwnerAccountAddress { gateway_id: value.gateway_id_bs58.clone(), raw_owner: value.gateway_owner_address.clone(), source, @@ -95,7 +137,7 @@ impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { })?; let gateway_listener = Url::parse(&value.gateway_listener).map_err(|source| { - GatewaysStorageError::MalformedListener { + BadGateway::MalformedListener { gateway_id: value.gateway_id_bs58.clone(), raw_listener: value.gateway_listener.clone(), source, @@ -124,14 +166,16 @@ impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { } } -#[derive(Debug, Zeroize, ZeroizeOnDrop)] +#[derive(Debug)] pub struct RemoteGatewayDetails { - #[zeroize(skip)] pub gateway_id: identity::PublicKey, - pub derived_aes128_ctr_blake3_hmac_keys: SharedKeys, - #[zeroize(skip)] + + // note: `SharedKeys` implement ZeroizeOnDrop, meaning when `RemoteGatewayDetails` is dropped, + // the keys will be zeroized + pub derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>, + pub gateway_owner_address: AccountId, - #[zeroize(skip)] + pub gateway_listener: Url, } @@ -143,12 +187,12 @@ pub struct RawCustomGatewayDetails { } impl TryFrom<RawCustomGatewayDetails> for CustomGatewayDetails { - type Error = GatewaysStorageError; + type Error = BadGateway; fn try_from(value: RawCustomGatewayDetails) -> Result<Self, Self::Error> { let gateway_id = identity::PublicKey::from_base58_string(&value.gateway_id_bs58).map_err(|source| { - GatewaysStorageError::MalformedGatewayIdentity { + BadGateway::MalformedGatewayIdentity { gateway_id: value.gateway_id_bs58.clone(), source, } diff --git a/common/client-core/surb-storage/src/backend/fs_backend/error.rs b/common/client-core/surb-storage/src/backend/fs_backend/error.rs index 84cac2f7ec..02742758ae 100644 --- a/common/client-core/surb-storage/src/backend/fs_backend/error.rs +++ b/common/client-core/surb-storage/src/backend/fs_backend/error.rs @@ -10,7 +10,7 @@ pub enum StorageError { #[error("the provided database path doesn't have a filename defined")] DatabasePathWithoutFilename { provided_path: PathBuf }, - #[error("unable to create the directory for the database")] + #[error("unable to create the directory for the database at {}: {source}", provided_path.display())] DatabasePathUnableToCreateParentDirectory { provided_path: PathBuf, source: io::Error, From c80c0b88bf3e08130811cc676ddc38352312df56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 5 Mar 2024 16:59:54 +0000 Subject: [PATCH 285/394] starting to weave in new storage trait --- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- common/client-core/Cargo.toml | 1 + .../src/backend/fs_backend/error.rs | 4 + .../src/backend/fs_backend/manager.rs | 9 +- .../src/backend/fs_backend/mod.rs | 17 +- .../src/backend/mem_backend.rs | 8 +- .../client-core/gateways-storage/src/lib.rs | 11 +- .../src/cli_helpers/client_init.rs | 162 +++++++++--------- .../client-core/src/client/base_client/mod.rs | 14 +- .../client/base_client/non_wasm_helpers.rs | 12 ++ .../src/client/base_client/storage/mod.rs | 65 ++++--- .../src/config/disk_persistence/mod.rs | 7 + .../config/disk_persistence/old_v1_1_20_2.rs | 13 +- .../config/disk_persistence/old_v1_1_33.rs | 2 + common/client-core/src/init/mod.rs | 50 +++--- common/client-core/src/init/types.rs | 42 ++--- common/client-core/src/lib.rs | 6 +- common/socks5-client-core/Cargo.toml | 2 +- common/socks5-client-core/src/lib.rs | 4 +- .../src/storage/core_client_traits.rs | 4 +- sdk/lib/socks5-listener/src/persistence.rs | 4 +- sdk/rust/nym-sdk/Cargo.toml | 2 +- .../examples/manually_handle_storage.rs | 4 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 4 +- 25 files changed, 266 insertions(+), 185 deletions(-) create mode 100644 common/client-core/src/config/disk_persistence/old_v1_1_33.rs diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index a85b73e5a4..2e49dd8261 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -38,7 +38,7 @@ zeroize = { workspace = true } ## internal nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } -nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } +nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] } nym-config = { path = "../../common/config" } nym-credential-storage = { path = "../../common/credential-storage" } nym-credentials = { path = "../../common/credentials" } diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 2665f6355c..66fbc64e5a 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -23,7 +23,7 @@ zeroize = { workspace = true } # internal nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } -nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "cli"] } +nym-client-core = { path = "../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage", "cli"] } nym-config = { path = "../../common/config" } nym-credentials = { path = "../../common/credentials" } nym-crypto = { path = "../../common/crypto" } diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index b2643888c5..f144aa4373 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -102,5 +102,6 @@ tempfile = "3.1.0" default = [] cli = ["clap"] fs-surb-storage = ["nym-client-core-surb-storage/fs-surb-storage"] +fs-gateways-storage = ["nym-client-core-gateways-storage/fs-gateways-storage"] wasm = ["nym-gateway-client/wasm"] metrics-server = [] diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs index 0a39dbbe06..44cab38a8c 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs @@ -1,6 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::BadGateway; use std::io; use std::path::PathBuf; use thiserror::Error; @@ -35,4 +36,7 @@ pub enum StorageError { #[from] source: sqlx::error::Error, }, + + #[error(transparent)] + MalformedGateway(#[from] BadGateway), } diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 299b16ea8b..5447c6c9ab 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -2,9 +2,6 @@ // SPDX-License-Identifier: Apache-2.0 use crate::backend::fs_backend::error::StorageError; -use crate::backend::fs_backend::models::{ - ReplySurbStorageMetadata, StoredReplyKey, StoredReplySurb, StoredSenderTag, StoredSurbSender, -}; use log::{error, info}; use sqlx::ConnectOptions; use std::path::Path; @@ -16,7 +13,7 @@ pub struct StorageManager { // all SQL goes here impl StorageManager { - pub async fn init<P: AsRef<Path>>(database_path: P, fresh: bool) -> Result<Self, StorageError> { + pub async fn init<P: AsRef<Path>>(database_path: P) -> Result<Self, StorageError> { // ensure the whole directory structure exists if let Some(parent_dir) = database_path.as_ref().parent() { std::fs::create_dir_all(parent_dir).map_err(|source| { @@ -29,14 +26,14 @@ impl StorageManager { let mut opts = sqlx::sqlite::SqliteConnectOptions::new() .filename(database_path) - .create_if_missing(fresh); + .create_if_missing(true); opts.disable_statement_logging(); let connection_pool = sqlx::SqlitePool::connect_with(opts) .await .map_err(|source| { - error!("Failed to connect to SQLx database: {err}"); + error!("Failed to connect to SQLx database: {source}"); StorageError::DatabaseConnectionError { source } })?; diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index e8ddc05d83..76d21c177b 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -2,20 +2,29 @@ // SPDX-License-Identifier: Apache-2.0 use crate::types::GatewayDetails; -use crate::GatewayDetailsStore; +use crate::{GatewaysDetailsStore, StorageError}; use async_trait::async_trait; use manager::StorageManager; +use std::path::Path; -mod error; +pub mod error; mod manager; mod models; -pub struct OnDiskGatewayDetails { +pub struct OnDiskGatewaysDetails { manager: StorageManager, } +impl OnDiskGatewaysDetails { + pub async fn init<P: AsRef<Path>>(database_path: P) -> Result<Self, StorageError> { + Ok(OnDiskGatewaysDetails { + manager: StorageManager::init(database_path).await?, + }) + } +} + #[async_trait] -impl GatewayDetailsStore for OnDiskGatewayDetails { +impl GatewaysDetailsStore for OnDiskGatewaysDetails { type StorageError = error::StorageError; async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 53afb6007b..986ffef2de 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::types::GatewayDetails; -use crate::{BadGateway, GatewayDetailsStore}; +use crate::{BadGateway, GatewaysDetailsStore}; use async_trait::async_trait; use std::collections::HashMap; use std::sync::Arc; @@ -18,10 +18,12 @@ pub enum InMemStorageError { MalformedGateway(#[from] BadGateway), } -pub struct InMemStorage { +#[derive(Debug, Default)] +pub struct InMemGatewaysDetails { inner: Arc<RwLock<InMemStorageInner>>, } +#[derive(Debug, Default)] struct InMemStorageInner { active_gateway: Option<String>, gateways: HashMap<String, GatewayDetails>, @@ -29,7 +31,7 @@ struct InMemStorageInner { #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GatewayDetailsStore for InMemStorage { +impl GatewaysDetailsStore for InMemGatewaysDetails { type StorageError = InMemStorageError; async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 393e6438ff..17c3f60dd8 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -7,16 +7,21 @@ use async_trait::async_trait; use std::error::Error; -mod backend; +pub mod backend; pub mod error; pub mod types; -use crate::types::GatewayDetails; +// todo: export port types +pub use crate::types::GatewayDetails; +pub use backend::mem_backend::{InMemGatewaysDetails, InMemStorageError}; pub use error::BadGateway; +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] +pub use backend::fs_backend::{error::StorageError, OnDiskGatewaysDetails}; + #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait GatewayDetailsStore { +pub trait GatewaysDetailsStore { type StorageError: Error + From<error::BadGateway>; /// Returns details of the currently active gateway, if available. diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 9550cffdb2..e7fb8e6ba0 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -5,7 +5,7 @@ use crate::config::disk_persistence::CommonClientPaths; use crate::error::ClientCoreError; use crate::{ client::{ - base_client::storage::gateway_details::OnDiskGatewayDetails, + base_client::non_wasm_helpers::setup_fs_gateways_storage, key_manager::persistence::OnDiskKeys, }, init::types::{GatewayDetails, GatewaySelectionSpecification, GatewaySetup, InitResults}, @@ -144,84 +144,86 @@ where let user_chosen_gateway_id = common_args.gateway; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); - let selection_spec = GatewaySelectionSpecification::new( - user_chosen_gateway_id.map(|id| id.to_base58_string()), - Some(common_args.latency_based_selection), - false, - ); - log::debug!("Gateway selection specification: {selection_spec:?}"); + todo!() - // Load and potentially override config - log::debug!("Init arguments: {init_args:#?}"); - let config = C::construct_config(&init_args); - log::debug!("Constructed config: {config:#?}"); - let paths = config.common_paths(); - let core = config.core_config(); - - log::info!( - "Using nym-api: {}", - core.client - .nym_api_urls - .iter() - .map(|url| url.as_str()) - .collect::<Vec<&str>>() - .join(",") - ); - - // Setup gateway by either registering a new one, or creating a new config from the selected - // one but with keys kept, or reusing the gateway configuration. - let key_store = OnDiskKeys::new(paths.keys.clone()); - let details_store = OnDiskGatewayDetails::new(&paths.gateway_details); - - let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { - let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { - ClientCoreError::CustomTopologyLoadFailure { - file_path: custom_mixnet.clone(), - source, - } - })?; - hardcoded_topology.get_gateways() - } else { - let mut rng = rand::thread_rng(); - crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? - }; - - let gateway_setup = GatewaySetup::New { - specification: selection_spec, - available_gateways, - overwrite_data: register_gateway, - }; - - let init_details = - crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; - - // TODO: ask the service provider we specified for its interface version and set it in the config - - let config_save_location = config.default_store_location(); - if let Err(err) = config.save_to(&config_save_location) { - return Err(ClientCoreError::ConfigSaveFailure { - typ: C::NAME.to_string(), - id: id.to_string(), - path: config_save_location, - source: err, - } - .into()); - } - - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); - - let address = init_details.client_address()?; - - let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else { - return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; - }; - let init_results = InitResults::new(config.core_config(), address, &gateway_details); - - Ok(InitResultsWithConfig { - config, - init_results, - }) + // let selection_spec = GatewaySelectionSpecification::new( + // user_chosen_gateway_id.map(|id| id.to_base58_string()), + // Some(common_args.latency_based_selection), + // false, + // ); + // log::debug!("Gateway selection specification: {selection_spec:?}"); + // + // // Load and potentially override config + // log::debug!("Init arguments: {init_args:#?}"); + // let config = C::construct_config(&init_args); + // log::debug!("Constructed config: {config:#?}"); + // let paths = config.common_paths(); + // let core = config.core_config(); + // + // log::info!( + // "Using nym-api: {}", + // core.client + // .nym_api_urls + // .iter() + // .map(|url| url.as_str()) + // .collect::<Vec<&str>>() + // .join(",") + // ); + // + // // Setup gateway by either registering a new one, or creating a new config from the selected + // // one but with keys kept, or reusing the gateway configuration. + // let key_store = OnDiskKeys::new(paths.keys.clone()); + // let details_store = setup_fs_gateways_storage(&paths.gateway_details).await?; + // + // let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { + // let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { + // ClientCoreError::CustomTopologyLoadFailure { + // file_path: custom_mixnet.clone(), + // source, + // } + // })?; + // hardcoded_topology.get_gateways() + // } else { + // let mut rng = rand::thread_rng(); + // crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? + // }; + // + // let gateway_setup = GatewaySetup::New { + // specification: selection_spec, + // available_gateways, + // overwrite_data: register_gateway, + // }; + // + // let init_details = + // crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; + // + // // TODO: ask the service provider we specified for its interface version and set it in the config + // + // let config_save_location = config.default_store_location(); + // if let Err(err) = config.save_to(&config_save_location) { + // return Err(ClientCoreError::ConfigSaveFailure { + // typ: C::NAME.to_string(), + // id: id.to_string(), + // path: config_save_location, + // source: err, + // } + // .into()); + // } + // + // eprintln!( + // "Saved configuration file to {}", + // config_save_location.display() + // ); + // + // let address = init_details.client_address()?; + // + // let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else { + // return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; + // }; + // let init_results = InitResults::new(config.core_config(), address, &gateway_details); + // + // Ok(InitResultsWithConfig { + // config, + // init_results, + // }) } diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index c2632f73ad..41c9a3f01b 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -4,7 +4,6 @@ use super::packet_statistics_control::PacketStatisticsReporter; use super::received_buffer::ReceivedBufferMessage; use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider; -use crate::client::base_client::storage::gateway_details::GatewayDetailsStore; use crate::client::base_client::storage::MixnetClientStorage; use crate::client::cover_traffic_stream::LoopCoverTrafficStream; use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender}; @@ -36,6 +35,7 @@ use crate::{config, spawn_future}; use futures::channel::mpsc; use log::{debug, error, info}; use nym_bandwidth_controller::BandwidthController; +use nym_client_core_gateways_storage::GatewaysDetailsStore; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_crypto::asymmetric::encryption; use nym_gateway_client::{ @@ -57,7 +57,11 @@ use std::path::Path; use std::sync::Arc; use url::Url; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] pub mod non_wasm_helpers; pub mod helpers; @@ -569,11 +573,11 @@ where async fn initialise_keys_and_gateway( setup_method: GatewaySetup, key_store: &S::KeyStore, - details_store: &S::GatewayDetailsStore, + details_store: &S::GatewaysDetailsStore, ) -> Result<InitialisationResult, ClientCoreError> where <S::KeyStore as KeyStore>::StorageError: Sync + Send, - <S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send, + <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Sync + Send, { setup_gateway(setup_method, key_store, details_store).await } @@ -584,7 +588,7 @@ where <S::KeyStore as KeyStore>::StorageError: Send + Sync, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static, - <S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send, + <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Sync + Send, { info!("Starting nym client"); diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index d0d2d5a058..70ad8358e6 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -9,6 +9,7 @@ use crate::config::Config; use crate::error::ClientCoreError; use log::{error, info}; use nym_bandwidth_controller::BandwidthController; +use nym_client_core_gateways_storage::OnDiskGatewaysDetails; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_validator_client::nyxd; use nym_validator_client::QueryHttpRpcNyxdClient; @@ -101,6 +102,17 @@ pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>( } } +pub async fn setup_fs_gateways_storage<P: AsRef<Path>>( + db_path: P, +) -> Result<OnDiskGatewaysDetails, ClientCoreError> { + info!("setting up gateways details storage"); + OnDiskGatewaysDetails::init(db_path) + .await + .map_err(|source| ClientCoreError::GatewayDetailsStoreError { + source: Box::new(source), + }) +} + pub fn create_bandwidth_controller<St: CredentialStorage>( config: &Config, storage: St, diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 60e3ff9a73..969b60d617 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -4,20 +4,24 @@ // TODO: combine those more closely. Perhaps into a single underlying store. // Like for persistent, on-disk, storage, what's the point of having 3 different databases? -use crate::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, InMemGatewayDetails, -}; +// use crate::client::base_client::storage::gateway_details::{ +// GatewayDetailsStore, InMemGatewayDetails, +// }; use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::replies::reply_storage; use crate::client::replies::reply_storage::ReplyStorageBackend; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] use crate::client::base_client::non_wasm_helpers; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] -use crate::client::base_client::storage::gateway_details::OnDiskGatewayDetails; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +// #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +// use crate::client::base_client::storage::gateway_details::OnDiskGatewayDetails; +#[cfg(not(target_arch = "wasm32"))] use crate::client::key_manager::persistence::OnDiskKeys; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use crate::client::replies::reply_storage::fs_backend; @@ -28,22 +32,30 @@ use crate::error::ClientCoreError; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; +// fs-gateways + +#[deprecated] pub mod gateway_details; +pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; + +#[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] +pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; + // TODO: ideally this should be changed into // `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewayDetailsStore` pub trait MixnetClientStorage { type KeyStore: KeyStore; type ReplyStore: ReplyStorageBackend; type CredentialStore: CredentialStorage; - type GatewayDetailsStore: GatewayDetailsStore; + type GatewaysDetailsStore: GatewaysDetailsStore; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore); fn key_store(&self) -> &Self::KeyStore; fn reply_store(&self) -> &Self::ReplyStore; fn credential_store(&self) -> &Self::CredentialStore; - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore; + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore; } #[derive(Default)] @@ -51,7 +63,7 @@ pub struct Ephemeral { key_store: InMemEphemeralKeys, reply_store: reply_storage::Empty, credential_store: EphemeralCredentialStorage, - gateway_details_store: InMemGatewayDetails, + gateway_details_store: InMemGatewaysDetails, } impl Ephemeral { @@ -64,7 +76,7 @@ impl MixnetClientStorage for Ephemeral { type KeyStore = InMemEphemeralKeys; type ReplyStore = reply_storage::Empty; type CredentialStore = EphemeralCredentialStorage; - type GatewayDetailsStore = InMemGatewayDetails; + type GatewaysDetailsStore = InMemGatewaysDetails; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_store, self.credential_store) @@ -82,26 +94,34 @@ impl MixnetClientStorage for Ephemeral { &self.credential_store } - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore { + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore { &self.gateway_details_store } } -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] pub struct OnDiskPersistent { pub(crate) key_store: OnDiskKeys, pub(crate) reply_store: fs_backend::Backend, pub(crate) credential_store: PersistentCredentialStorage, - pub(crate) gateway_details_store: OnDiskGatewayDetails, + pub(crate) gateway_details_store: OnDiskGatewaysDetails, } -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] impl OnDiskPersistent { pub fn new( key_store: OnDiskKeys, reply_store: fs_backend::Backend, credential_store: PersistentCredentialStorage, - gateway_details_store: OnDiskGatewayDetails, + gateway_details_store: OnDiskGatewaysDetails, ) -> Self { Self { key_store, @@ -126,7 +146,8 @@ impl OnDiskPersistent { let credential_store = nym_credential_storage::initialise_persistent_storage(paths.credentials_database).await; - let gateway_details_store = OnDiskGatewayDetails::new(paths.gateway_details); + let gateway_details_store = + non_wasm_helpers::setup_fs_gateways_storage(paths.gateway_registrations).await?; Ok(OnDiskPersistent { key_store, @@ -137,12 +158,16 @@ impl OnDiskPersistent { } } -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] impl MixnetClientStorage for OnDiskPersistent { type KeyStore = OnDiskKeys; type ReplyStore = fs_backend::Backend; type CredentialStore = PersistentCredentialStorage; - type GatewayDetailsStore = OnDiskGatewayDetails; + type GatewaysDetailsStore = OnDiskGatewaysDetails; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_store, self.credential_store) @@ -160,7 +185,7 @@ impl MixnetClientStorage for OnDiskPersistent { &self.credential_store } - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore { + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore { &self.gateway_details_store } } diff --git a/common/client-core/src/config/disk_persistence/mod.rs b/common/client-core/src/config/disk_persistence/mod.rs index b323d059dc..7272f9edaf 100644 --- a/common/client-core/src/config/disk_persistence/mod.rs +++ b/common/client-core/src/config/disk_persistence/mod.rs @@ -7,10 +7,12 @@ use std::path::{Path, PathBuf}; pub mod keys_paths; pub mod old_v1_1_20_2; +mod old_v1_1_33; pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json"; pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite"; pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db"; +pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.db"; #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] @@ -19,8 +21,12 @@ pub struct CommonClientPaths { /// Path to the file containing information about gateway used by this client, /// i.e. details such as its public key, owner address or the network information. + #[deprecated] pub gateway_details: PathBuf, + // TODO: + pub gateway_registrations: PathBuf, + /// Path to the database containing bandwidth credentials of this client. pub credentials_database: PathBuf, @@ -36,6 +42,7 @@ impl CommonClientPaths { credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME), reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME), gateway_details: base_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), + gateway_registrations: base_dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), keys: ClientKeysPaths::new_base(base_data_directory), } } diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs b/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs index d26cf1461c..24496f1497 100644 --- a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs +++ b/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs @@ -22,11 +22,12 @@ impl CommonClientPathsV1_1_20_2 { new_version: "1.1.20-2".to_string(), } })?; - Ok(CommonClientPaths { - keys: self.keys, - gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), - credentials_database: self.credentials_database, - reply_surb_database: self.reply_surb_database, - }) + todo!() + // Ok(CommonClientPaths { + // keys: self.keys, + // gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), + // credentials_database: self.credentials_database, + // reply_surb_database: self.reply_surb_database, + // }) } } diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_33.rs b/common/client-core/src/config/disk_persistence/old_v1_1_33.rs new file mode 100644 index 0000000000..755fb6cc8b --- /dev/null +++ b/common/client-core/src/config/disk_persistence/old_v1_1_33.rs @@ -0,0 +1,2 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 13129bf5f5..7765c09f0c 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -3,9 +3,7 @@ //! Collection of initialization steps used by client implementations -use crate::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, PersistedGatewayDetails, -}; +use crate::client::base_client::storage::gateway_details::PersistedGatewayDetails; use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::ManagedKeys; use crate::config::GatewayEndpointConfig; @@ -17,6 +15,7 @@ use crate::init::types::{ CustomGatewayDetails, GatewayDetails, GatewaySelectionSpecification, GatewaySetup, InitialisationResult, }; +use nym_client_core_gateways_storage::GatewaysDetailsStore; use nym_gateway_client::client::InitGatewayClient; use nym_topology::gateway; use rand::rngs::OsRng; @@ -33,32 +32,34 @@ async fn _store_gateway_details<T, D>( details: &PersistedGatewayDetails<T>, ) -> Result<(), ClientCoreError> where - D: GatewayDetailsStore<T>, + D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, T: Serialize + Send + Sync, { - details_store - .store_gateway_details(details) - .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) + todo!() + // details_store + // .store_gateway_details(details) + // .await + // .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + // source: Box::new(source), + // }) } async fn _load_gateway_details<T, D>( details_store: &D, ) -> Result<PersistedGatewayDetails<T>, ClientCoreError> where - D: GatewayDetailsStore<T>, + D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Send + Sync, { - details_store - .load_gateway_details() - .await - .map_err(|source| ClientCoreError::UnavailableGatewayDetails { - source: Box::new(source), - }) + todo!() + // details_store + // .load_gateway_details() + // .await + // .map_err(|source| ClientCoreError::UnavailableGatewayDetails { + // source: Box::new(source), + // }) } async fn _load_managed_keys<K>(key_store: &K) -> Result<ManagedKeys, ClientCoreError> @@ -89,7 +90,7 @@ async fn setup_new_gateway<T, K, D>( ) -> Result<InitialisationResult<T>, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore<T>, + D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Serialize + Send + Sync, @@ -98,9 +99,12 @@ where // if we're setting up new gateway, failing to load existing information is fine. // as a matter of fact, it's only potentially a problem if we DO succeed - if _load_gateway_details(details_store).await.is_ok() && !overwrite_data { - return Err(ClientCoreError::ForbiddenKeyOverwrite); - } + + todo!("check gateway details (maybe not even needed anymore, idk)"); + // if _load_gateway_details(details_store).await.is_ok() && !overwrite_data { + // return Err(ClientCoreError::ForbiddenKeyOverwrite); + // } + if _load_managed_keys(key_store).await.is_ok() && !overwrite_data { return Err(ClientCoreError::ForbiddenKeyOverwrite); } @@ -171,7 +175,7 @@ async fn use_loaded_gateway_details<T, K, D>( ) -> Result<InitialisationResult<T>, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore<T>, + D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Send + Sync, @@ -207,7 +211,7 @@ pub async fn setup_gateway<T, K, D>( ) -> Result<InitialisationResult<T>, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore<T>, + D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Serialize + Send + Sync, diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 141bf8dd2d..4d90cd1f53 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -56,25 +56,26 @@ impl<T> InitialisationResult<T> { D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Send + Sync, { - let loaded_details = _load_gateway_details(details_store).await?; - let loaded_keys = _load_managed_keys(key_store).await?; - - match &loaded_details { - PersistedGatewayDetails::Default(loaded_default) => { - if !loaded_default.verify(&loaded_keys.must_get_gateway_shared_key()) { - return Err(ClientCoreError::MismatchedGatewayDetails { - gateway_id: loaded_default.details.gateway_id.clone(), - }); - } - } - PersistedGatewayDetails::Custom(_) => {} - } - - Ok(InitialisationResult { - gateway_details: loaded_details.into(), - managed_keys: loaded_keys, - authenticated_ephemeral_client: None, - }) + todo!() + // let loaded_details = _load_gateway_details(details_store).await?; + // let loaded_keys = _load_managed_keys(key_store).await?; + // + // match &loaded_details { + // PersistedGatewayDetails::Default(loaded_default) => { + // if !loaded_default.verify(&loaded_keys.must_get_gateway_shared_key()) { + // return Err(ClientCoreError::MismatchedGatewayDetails { + // gateway_id: loaded_default.details.gateway_id.clone(), + // }); + // } + // } + // PersistedGatewayDetails::Custom(_) => {} + // } + // + // Ok(InitialisationResult { + // gateway_details: loaded_details.into(), + // managed_keys: loaded_keys, + // authenticated_ephemeral_client: None, + // }) } pub fn client_address(&self) -> Result<Recipient, ClientCoreError> { @@ -281,7 +282,8 @@ impl<T> GatewaySetup<T> { D::StorageError: Send + Sync + 'static, T: DeserializeOwned + Serialize + Send + Sync, { - setup_gateway(self, key_store, details_store).await + todo!() + // setup_gateway(self, key_store, details_store).await } pub fn is_must_load(&self) -> bool { diff --git a/common/client-core/src/lib.rs b/common/client-core/src/lib.rs index 0b401f4e02..1eb90ddcf7 100644 --- a/common/client-core/src/lib.rs +++ b/common/client-core/src/lib.rs @@ -1,6 +1,10 @@ use std::future::Future; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] pub mod cli_helpers; pub mod client; pub mod config; diff --git a/common/socks5-client-core/Cargo.toml b/common/socks5-client-core/Cargo.toml index 80aefcf934..52fc4d6d0b 100644 --- a/common/socks5-client-core/Cargo.toml +++ b/common/socks5-client-core/Cargo.toml @@ -22,7 +22,7 @@ tokio = { version = "1.24.1", features = ["rt-multi-thread", "net", "signal"] } url = { workspace = true } nym-bandwidth-controller = { path = "../../common/bandwidth-controller" } -nym-client-core = { path = "../client-core", features = ["fs-surb-storage"] } +nym-client-core = { path = "../client-core", features = ["fs-surb-storage", "fs-gateways-storage"] } nym-config = { path = "../config" } nym-contracts-common = { path = "../cosmwasm-smart-contracts/contracts-common" } nym-credential-storage = { path = "../credential-storage" } diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index ecef31354f..d9d036d1a8 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -11,7 +11,7 @@ use futures::channel::mpsc; use futures::StreamExt; use log::*; use nym_client_core::client::base_client::non_wasm_helpers::default_query_dkg_client_from_config; -use nym_client_core::client::base_client::storage::gateway_details::GatewayDetailsStore; +use nym_client_core::client::base_client::storage::GatewaysDetailsStore; use nym_client_core::client::base_client::storage::MixnetClientStorage; use nym_client_core::client::base_client::{ BaseClientBuilder, ClientInput, ClientOutput, ClientState, @@ -71,7 +71,7 @@ where S::ReplyStore: Send + Sync, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, - <S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Sync + Send, + <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Sync + Send, <S::KeyStore as KeyStore>::StorageError: Send + Sync, { pub fn new(config: Config, storage: S, custom_mixnet: Option<PathBuf>) -> Self { diff --git a/common/wasm/client-core/src/storage/core_client_traits.rs b/common/wasm/client-core/src/storage/core_client_traits.rs index b017bb3914..7e4ae13e03 100644 --- a/common/wasm/client-core/src/storage/core_client_traits.rs +++ b/common/wasm/client-core/src/storage/core_client_traits.rs @@ -41,7 +41,7 @@ impl MixnetClientStorage for FullWasmClientStorage { type ReplyStore = browser_backend::Backend; type CredentialStore = EphemeralCredentialStorage; - type GatewayDetailsStore = ClientStorage; + type GatewaysDetailsStore = ClientStorage; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_storage, self.credential_storage) @@ -59,7 +59,7 @@ impl MixnetClientStorage for FullWasmClientStorage { &self.credential_storage } - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore { + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore { &self.keys_and_gateway_store } } diff --git a/sdk/lib/socks5-listener/src/persistence.rs b/sdk/lib/socks5-listener/src/persistence.rs index 68455fad27..93916feb42 100644 --- a/sdk/lib/socks5-listener/src/persistence.rs +++ b/sdk/lib/socks5-listener/src/persistence.rs @@ -21,7 +21,7 @@ impl MixnetClientStorage for MobileClientStorage { type KeyStore = InMemEphemeralKeys; type ReplyStore = reply_storage::Empty; type CredentialStore = EphemeralCredentialStorage; - type GatewayDetailsStore = InMemGatewayDetails; + type GatewaysDetailsStore = InMemGatewayDetails; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_store, self.credential_store) @@ -39,7 +39,7 @@ impl MixnetClientStorage for MobileClientStorage { &self.credential_store } - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore { + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore { &self.gateway_details_store } } diff --git a/sdk/rust/nym-sdk/Cargo.toml b/sdk/rust/nym-sdk/Cargo.toml index c0a0960f79..4948f230f5 100644 --- a/sdk/rust/nym-sdk/Cargo.toml +++ b/sdk/rust/nym-sdk/Cargo.toml @@ -9,7 +9,7 @@ license.workspace = true [dependencies] async-trait = { workspace = true } bip39 = { workspace = true } -nym-client-core = { path = "../../../common/client-core", features = ["fs-surb-storage"]} +nym-client-core = { path = "../../../common/client-core", features = ["fs-surb-storage", "fs-gateways-storage"]} nym-crypto = { path = "../../../common/crypto" } nym-gateway-requests = { path = "../../../gateway/gateway-requests" } nym-bandwidth-controller = { path = "../../../common/bandwidth-controller" } diff --git a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs index dd650b1e2a..b4844005bf 100644 --- a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs +++ b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs @@ -64,7 +64,7 @@ impl MixnetClientStorage for MockClientStorage { type KeyStore = MockKeyStore; type ReplyStore = EmptyReplyStorage; type CredentialStore = EphemeralCredentialStorage; - type GatewayDetailsStore = MockGatewayDetailsStore; + type GatewaysDetailsStore = MockGatewayDetailsStore; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_store, self.credential_store) @@ -82,7 +82,7 @@ impl MixnetClientStorage for MockClientStorage { &self.credential_store } - fn gateway_details_store(&self) -> &Self::GatewayDetailsStore { + fn gateway_details_store(&self) -> &Self::GatewaysDetailsStore { &self.gateway_details_store } } diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 69995214b8..942e192882 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -104,7 +104,7 @@ where <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, - <S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, + <S::GatewaysDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, { /// Creates a client builder with the provided client storage implementation. #[must_use] @@ -309,7 +309,7 @@ where <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, - <S::GatewayDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, + <S::GatewaysDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, { /// Create a new mixnet client in a disconnected state. The default configuration, /// creates a new mainnet client with ephemeral keys stored in RAM, which will be discarded at From 6915fef99f190adf3572f54b054105e5da52b9f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 09:07:10 +0000 Subject: [PATCH 286/394] removing generics from 'GatewaySelectionSpecification' --- Cargo.lock | 1 + .../base_client/storage/gateway_details.rs | 51 ++++------- .../src/config/disk_persistence/mod.rs | 2 +- common/client-core/src/init/mod.rs | 39 ++++---- common/client-core/src/init/types.rs | 67 ++++++-------- gateway/src/commands/helpers.rs | 7 +- nym-connect/desktop/Cargo.lock | 40 +++++++- sdk/rust/nym-sdk/src/mixnet/client.rs | 91 ++++++++++--------- sdk/rust/nym-sdk/src/mixnet/paths.rs | 18 +++- .../network-requester/Cargo.toml | 2 +- .../network-requester/src/lib.rs | 5 +- 11 files changed, 172 insertions(+), 151 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b61fc7884b..d136c0c614 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5289,6 +5289,7 @@ dependencies = [ "serde", "sqlx", "thiserror", + "time", "tokio", "url", "zeroize", diff --git a/common/client-core/src/client/base_client/storage/gateway_details.rs b/common/client-core/src/client/base_client/storage/gateway_details.rs index d9eaddfa87..152ef96283 100644 --- a/common/client-core/src/client/base_client/storage/gateway_details.rs +++ b/common/client-core/src/client/base_client/storage/gateway_details.rs @@ -3,7 +3,7 @@ use crate::config::GatewayEndpointConfig; use crate::error::ClientCoreError; -use crate::init::types::{EmptyCustomDetails, GatewayDetails}; +use crate::init::types::GatewayDetails; use async_trait::async_trait; use log::error; use nym_gateway_requests::registration::handshake::SharedKeys; @@ -17,32 +17,28 @@ use zeroize::Zeroizing; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait GatewayDetailsStore<T = EmptyCustomDetails> { +pub trait GatewayDetailsStore { type StorageError: Error; - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails<T>, Self::StorageError> - where - T: DeserializeOwned + Send + Sync; + async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError>; async fn store_gateway_details( &self, - details: &PersistedGatewayDetails<T>, - ) -> Result<(), Self::StorageError> - where - T: Serialize + Send + Sync; + details: &PersistedGatewayDetails, + ) -> Result<(), Self::StorageError>; } #[derive(Debug, Clone, Serialize, Deserialize)] #[serde(untagged)] -pub enum PersistedGatewayDetails<T = EmptyCustomDetails> { +pub enum PersistedGatewayDetails { /// Standard details of a remote gateway Default(PersistedGatewayConfig), /// Custom gateway setup, such as for a client embedded inside gateway itself - Custom(PersistedCustomGatewayDetails<T>), + Custom(PersistedCustomGatewayDetails), } -impl<T> PersistedGatewayDetails<T> { +impl PersistedGatewayDetails { // TODO: this should probably allow for custom verification over T pub fn validate(&self, shared_key: Option<&SharedKeys>) -> Result<(), ClientCoreError> { match self { @@ -81,12 +77,12 @@ pub struct PersistedGatewayConfig { } #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PersistedCustomGatewayDetails<T> { +pub struct PersistedCustomGatewayDetails { // whatever custom method is used, gateway's identity must be known pub gateway_id: String, #[serde(flatten)] - pub additional_data: T, + pub additional_data: Vec<u8>, } impl PersistedGatewayConfig { @@ -111,9 +107,9 @@ impl PersistedGatewayConfig { } } -impl<T> PersistedGatewayDetails<T> { +impl PersistedGatewayDetails { pub fn new( - details: GatewayDetails<T>, + details: GatewayDetails, shared_key: Option<&SharedKeys>, ) -> Result<Self, ClientCoreError> { match details { @@ -131,10 +127,7 @@ impl<T> PersistedGatewayDetails<T> { matches!(self, PersistedGatewayDetails::Custom(..)) } - pub fn matches(&self, other: &GatewayDetails<T>) -> bool - where - T: PartialEq, - { + pub fn matches(&self, other: &GatewayDetails) -> bool { match self { PersistedGatewayDetails::Default(default) => { if let GatewayDetails::Configured(other_configured) = other { @@ -205,10 +198,7 @@ impl OnDiskGatewayDetails { } } - pub fn load_from_disk<T>(&self) -> Result<PersistedGatewayDetails<T>, OnDiskGatewayDetailsError> - where - T: DeserializeOwned, - { + pub fn load_from_disk(&self) -> Result<PersistedGatewayDetails, OnDiskGatewayDetailsError> { let file = std::fs::File::open(&self.file_location).map_err(|err| { OnDiskGatewayDetailsError::LoadFailure { path: self.file_location.display().to_string(), @@ -219,13 +209,10 @@ impl OnDiskGatewayDetails { Ok(serde_json::from_reader(file)?) } - pub fn store_to_disk<T>( + pub fn store_to_disk( &self, - details: &PersistedGatewayDetails<T>, - ) -> Result<(), OnDiskGatewayDetailsError> - where - T: Serialize, - { + details: &PersistedGatewayDetails, + ) -> Result<(), OnDiskGatewayDetailsError> { // ensure the whole directory structure exists if let Some(parent_dir) = &self.file_location.parent() { std::fs::create_dir_all(parent_dir).map_err(|err| { @@ -265,8 +252,8 @@ impl GatewayDetailsStore for OnDiskGatewayDetails { } #[derive(Default)] -pub struct InMemGatewayDetails<T = EmptyCustomDetails> { - details: Mutex<Option<PersistedGatewayDetails<T>>>, +pub struct InMemGatewayDetails { + details: Mutex<Option<PersistedGatewayDetails>>, } #[derive(Debug, thiserror::Error)] diff --git a/common/client-core/src/config/disk_persistence/mod.rs b/common/client-core/src/config/disk_persistence/mod.rs index 7272f9edaf..b52b261bff 100644 --- a/common/client-core/src/config/disk_persistence/mod.rs +++ b/common/client-core/src/config/disk_persistence/mod.rs @@ -12,7 +12,7 @@ mod old_v1_1_33; pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json"; pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite"; pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db"; -pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.db"; +pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.sqlite"; #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 7765c09f0c..72b6f67996 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -27,14 +27,13 @@ pub mod helpers; pub mod types; // helpers for error wrapping -async fn _store_gateway_details<T, D>( +async fn _store_gateway_details<D>( details_store: &D, - details: &PersistedGatewayDetails<T>, + details: &PersistedGatewayDetails, ) -> Result<(), ClientCoreError> where D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, - T: Serialize + Send + Sync, { todo!() // details_store @@ -45,13 +44,12 @@ where // }) } -async fn _load_gateway_details<T, D>( +async fn _load_gateway_details<D>( details_store: &D, -) -> Result<PersistedGatewayDetails<T>, ClientCoreError> +) -> Result<PersistedGatewayDetails, ClientCoreError> where D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Send + Sync, { todo!() // details_store @@ -74,26 +72,25 @@ where }) } -fn ensure_valid_details<T>( - details: &PersistedGatewayDetails<T>, +fn ensure_valid_details( + details: &PersistedGatewayDetails, loaded_keys: &ManagedKeys, ) -> Result<(), ClientCoreError> { details.validate(loaded_keys.gateway_shared_key().as_deref()) } -async fn setup_new_gateway<T, K, D>( +async fn setup_new_gateway<K, D>( key_store: &K, details_store: &D, overwrite_data: bool, - selection_specification: GatewaySelectionSpecification<T>, + selection_specification: GatewaySelectionSpecification, available_gateways: Vec<gateway::Node>, -) -> Result<InitialisationResult<T>, ClientCoreError> +) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Serialize + Send + Sync, { log::trace!("Setting up new gateway"); @@ -169,16 +166,15 @@ where }) } -async fn use_loaded_gateway_details<T, K, D>( +async fn use_loaded_gateway_details<K, D>( key_store: &K, details_store: &D, -) -> Result<InitialisationResult<T>, ClientCoreError> +) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Send + Sync, { let loaded_details = _load_gateway_details(details_store).await?; let loaded_keys = _load_managed_keys(key_store).await?; @@ -192,11 +188,11 @@ where )) } -fn reuse_gateway_connection<T>( +fn reuse_gateway_connection( authenticated_ephemeral_client: InitGatewayClient, - gateway_details: GatewayDetails<T>, + gateway_details: GatewayDetails, managed_keys: ManagedKeys, -) -> InitialisationResult<T> { +) -> InitialisationResult { InitialisationResult { gateway_details, managed_keys, @@ -204,17 +200,16 @@ fn reuse_gateway_connection<T>( } } -pub async fn setup_gateway<T, K, D>( - setup: GatewaySetup<T>, +pub async fn setup_gateway<K, D>( + setup: GatewaySetup, key_store: &K, details_store: &D, -) -> Result<InitialisationResult<T>, ClientCoreError> +) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Serialize + Send + Sync, { log::debug!("Setting up gateway"); match setup { diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 4d90cd1f53..9863fc7c07 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -33,14 +33,14 @@ pub struct RegistrationResult { /// - all loaded (or derived) keys /// - an optional authenticated handle of an ephemeral gateway handle created for the purposes of registration, /// if this was the first time this client registered -pub struct InitialisationResult<T = EmptyCustomDetails> { - pub gateway_details: GatewayDetails<T>, +pub struct InitialisationResult { + pub gateway_details: GatewayDetails, pub managed_keys: ManagedKeys, pub authenticated_ephemeral_client: Option<InitGatewayClient>, } -impl<T> InitialisationResult<T> { - pub fn new_loaded(gateway_details: GatewayDetails<T>, managed_keys: ManagedKeys) -> Self { +impl InitialisationResult { + pub fn new_loaded(gateway_details: GatewayDetails, managed_keys: ManagedKeys) -> Self { InitialisationResult { gateway_details, managed_keys, @@ -51,10 +51,9 @@ impl<T> InitialisationResult<T> { pub async fn try_load<K, D>(key_store: &K, details_store: &D) -> Result<Self, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore<T>, + D: GatewayDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Send + Sync, { todo!() // let loaded_details = _load_gateway_details(details_store).await?; @@ -93,29 +92,24 @@ impl<T> InitialisationResult<T> { /// Details of particular gateway client got registered with #[derive(Debug, Clone)] -pub enum GatewayDetails<T = EmptyCustomDetails> { +pub enum GatewayDetails { /// Standard details of a remote gateway Configured(GatewayEndpointConfig), /// Custom gateway setup, such as for a client embedded inside gateway itself - Custom(CustomGatewayDetails<T>), + Custom(CustomGatewayDetails), } -#[derive(Debug, Default, Copy, Clone, Serialize, Deserialize, Eq, PartialEq)] -#[serde(rename_all = "snake_case")] -pub struct EmptyCustomDetails {} - #[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CustomGatewayDetails<T = EmptyCustomDetails> { +pub struct CustomGatewayDetails { // whatever custom method is used, gateway's identity must be known pub gateway_id: String, - #[serde(flatten)] - pub additional_data: T, + pub additional_data: Vec<u8>, } -impl<T> CustomGatewayDetails<T> { - pub fn new(gateway_id: String, additional_data: T) -> Self { +impl CustomGatewayDetails { + pub fn new(gateway_id: String, additional_data: Vec<u8>) -> Self { Self { gateway_id, additional_data, @@ -123,7 +117,7 @@ impl<T> CustomGatewayDetails<T> { } } -impl<T> GatewayDetails<T> { +impl GatewayDetails { pub fn try_get_configured_endpoint(&self) -> Option<&GatewayEndpointConfig> { if let GatewayDetails::Configured(endpoint) = &self { Some(endpoint) @@ -150,8 +144,8 @@ impl From<GatewayEndpointConfig> for GatewayDetails { } } -impl<T> From<PersistedCustomGatewayDetails<T>> for CustomGatewayDetails<T> { - fn from(value: PersistedCustomGatewayDetails<T>) -> Self { +impl From<PersistedCustomGatewayDetails> for CustomGatewayDetails { + fn from(value: PersistedCustomGatewayDetails) -> Self { CustomGatewayDetails { gateway_id: value.gateway_id, additional_data: value.additional_data, @@ -159,8 +153,8 @@ impl<T> From<PersistedCustomGatewayDetails<T>> for CustomGatewayDetails<T> { } } -impl<T> From<CustomGatewayDetails<T>> for PersistedCustomGatewayDetails<T> { - fn from(value: CustomGatewayDetails<T>) -> Self { +impl From<CustomGatewayDetails> for PersistedCustomGatewayDetails { + fn from(value: CustomGatewayDetails) -> Self { PersistedCustomGatewayDetails { gateway_id: value.gateway_id, additional_data: value.additional_data, @@ -168,8 +162,8 @@ impl<T> From<CustomGatewayDetails<T>> for PersistedCustomGatewayDetails<T> { } } -impl<T> From<PersistedGatewayDetails<T>> for GatewayDetails<T> { - fn from(value: PersistedGatewayDetails<T>) -> Self { +impl From<PersistedGatewayDetails> for GatewayDetails { + fn from(value: PersistedGatewayDetails) -> Self { match value { PersistedGatewayDetails::Default(default) => { GatewayDetails::Configured(default.details) @@ -180,7 +174,7 @@ impl<T> From<PersistedGatewayDetails<T>> for GatewayDetails<T> { } #[derive(Clone, Debug)] -pub enum GatewaySelectionSpecification<T = EmptyCustomDetails> { +pub enum GatewaySelectionSpecification { /// Uniformly choose a random remote gateway. UniformRemote { must_use_tls: bool }, @@ -198,11 +192,11 @@ pub enum GatewaySelectionSpecification<T = EmptyCustomDetails> { /// This client has handled the selection by itself Custom { gateway_identity: String, - additional_data: T, + additional_data: Vec<u8>, }, } -impl<T> Default for GatewaySelectionSpecification<T> { +impl Default for GatewaySelectionSpecification { fn default() -> Self { GatewaySelectionSpecification::UniformRemote { must_use_tls: false, @@ -210,7 +204,7 @@ impl<T> Default for GatewaySelectionSpecification<T> { } } -impl<T> GatewaySelectionSpecification<T> { +impl GatewaySelectionSpecification { pub fn new( gateway_identity: Option<String>, latency_based_selection: Option<bool>, @@ -229,13 +223,13 @@ impl<T> GatewaySelectionSpecification<T> { } } -pub enum GatewaySetup<T = EmptyCustomDetails> { +pub enum GatewaySetup { /// The gateway specification (details + keys) MUST BE loaded from the underlying storage. MustLoad, /// Specifies usage of a new gateway New { - specification: GatewaySelectionSpecification<T>, + specification: GatewaySelectionSpecification, // TODO: seems to be a bit inefficient to pass them by value available_gateways: Vec<gateway::Node>, @@ -249,16 +243,14 @@ pub enum GatewaySetup<T = EmptyCustomDetails> { authenticated_ephemeral_client: InitGatewayClient, // Details of this pre-initialised client (i.e. gateway and keys) - gateway_details: GatewayDetails<T>, + gateway_details: GatewayDetails, managed_keys: ManagedKeys, }, } -impl<T> GatewaySetup<T> { - pub fn try_reuse_connection( - init_res: InitialisationResult<T>, - ) -> Result<Self, ClientCoreError> { +impl GatewaySetup { + pub fn try_reuse_connection(init_res: InitialisationResult) -> Result<Self, ClientCoreError> { if let Some(authenticated_ephemeral_client) = init_res.authenticated_ephemeral_client { Ok(GatewaySetup::ReuseConnection { authenticated_ephemeral_client, @@ -274,13 +266,12 @@ impl<T> GatewaySetup<T> { self, key_store: &K, details_store: &D, - ) -> Result<InitialisationResult<T>, ClientCoreError> + ) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore<T>, + D: GatewayDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, - T: DeserializeOwned + Serialize + Send + Sync, { todo!() // setup_gateway(self, key_store, details_store).await diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 043288db42..956c78834f 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -17,7 +17,8 @@ use nym_network_defaults::var_names::NYXD; use nym_network_defaults::var_names::{BECH32_PREFIX, NYM_API, STATISTICS_SERVICE_DOMAIN_ADDRESS}; use nym_network_requester::config::BaseClientConfig; use nym_network_requester::{ - setup_gateway, GatewaySelectionSpecification, GatewaySetup, OnDiskGatewayDetails, OnDiskKeys, + setup_fs_gateways_storage, setup_gateway, GatewaySelectionSpecification, GatewaySetup, + OnDiskKeys, }; use nym_types::gateway::{GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails}; use nym_validator_client::nyxd::AccountId; @@ -275,7 +276,7 @@ pub(crate) async fn initialise_local_network_requester( let key_store = OnDiskKeys::new(nr_cfg.storage_paths.common_paths.keys.clone()); let details_store = - OnDiskGatewayDetails::new(&nr_cfg.storage_paths.common_paths.gateway_details); + setup_fs_gateways_storage(&nr_cfg.storage_paths.common_paths.gateway_registrations).await?; // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( @@ -348,7 +349,7 @@ pub(crate) async fn initialise_local_ip_packet_router( let key_store = OnDiskKeys::new(ip_cfg.storage_paths.common_paths.keys.clone()); let details_store = - OnDiskGatewayDetails::new(&ip_cfg.storage_paths.common_paths.gateway_details); + setup_fs_gateways_storage(&ip_cfg.storage_paths.common_paths.gateway_registrations).await?; // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 8a87804f61..86afcd16e4 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -3805,8 +3805,6 @@ dependencies = [ "async-trait", "base64 0.21.4", "cfg-if", - "dashmap", - "dirs 4.0.0", "futures", "gloo-timers", "http-body-util", @@ -3815,6 +3813,8 @@ dependencies = [ "hyper-util", "log", "nym-bandwidth-controller", + "nym-client-core-gateways-storage", + "nym-client-core-surb-storage", "nym-config", "nym-credential-storage", "nym-crypto", @@ -3830,12 +3830,10 @@ dependencies = [ "nym-topology", "nym-validator-client", "rand 0.7.3", - "reqwest", "serde", "serde_json", "sha2 0.10.8", "si-scale", - "sqlx", "tap", "thiserror", "time", @@ -3851,6 +3849,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-client-core-gateways-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "cosmrs", + "log", + "nym-crypto", + "nym-gateway-requests", + "serde", + "sqlx", + "thiserror", + "time", + "tokio", + "url", + "zeroize", +] + +[[package]] +name = "nym-client-core-surb-storage" +version = "0.1.0" +dependencies = [ + "async-trait", + "dashmap", + "log", + "nym-crypto", + "nym-sphinx", + "nym-task", + "sqlx", + "thiserror", + "time", + "tokio", +] + [[package]] name = "nym-coconut" version = "0.5.0" diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 942e192882..c075acdfef 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -15,7 +15,7 @@ use nym_client_core::client::base_client::storage::gateway_details::{ GatewayDetailsStore, PersistedGatewayDetails, }; use nym_client_core::client::base_client::storage::{ - Ephemeral, MixnetClientStorage, OnDiskPersistent, + Ephemeral, GatewaysDetailsStore, MixnetClientStorage, OnDiskPersistent, }; use nym_client_core::client::base_client::BaseClient; use nym_client_core::client::key_manager::persistence::KeyStore; @@ -104,7 +104,7 @@ where <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, - <S::GatewaysDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, + <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Send + Sync, { /// Creates a client builder with the provided client storage implementation. #[must_use] @@ -309,7 +309,7 @@ where <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, - <S::GatewaysDetailsStore as GatewayDetailsStore>::StorageError: Send + Sync, + <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Send + Sync, { /// Create a new mixnet client in a disconnected state. The default configuration, /// creates a new mainnet client with ephemeral keys stored in RAM, which will be discarded at @@ -426,25 +426,27 @@ where } }; - let gateway_details = match self - .storage - .gateway_details_store() - .load_gateway_details() - .await - { - Ok(details) => details, - Err(err) => { - warn!("failed to load stored gateway details: {err}"); - return false; - } - }; + todo!() - if let Err(err) = gateway_details.validate(keys.gateway_shared_key().as_deref()) { - warn!("stored key verification failure: {err}"); - return false; - } - - true + // let gateway_details = match self + // .storage + // .gateway_details_store() + // .load_gateway_details() + // .await + // { + // Ok(details) => details, + // Err(err) => { + // warn!("failed to load stored gateway details: {err}"); + // return false; + // } + // }; + // + // if let Err(err) = gateway_details.validate(keys.gateway_shared_key().as_deref()) { + // warn!("stored key verification failure: {err}"); + // return false; + // } + // + // true } /// Register with a gateway. If a gateway is provided in the config then that will try to be @@ -552,29 +554,30 @@ where .with_wait_for_gateway(self.wait_for_gateway) .with_gateway_setup(setup) } else if self.wireguard_mode { - if let Ok(PersistedGatewayDetails::Default(mut config)) = self - .storage - .gateway_details_store() - .load_gateway_details() - .await - { - config.details.gateway_listener = format!( - "ws://{}:{}", - WG_TUN_DEVICE_ADDRESS, DEFAULT_CLIENT_LISTENING_PORT - ); - if let Err(e) = self - .storage - .gateway_details_store() - .store_gateway_details(&PersistedGatewayDetails::Default(config)) - .await - { - warn!("Could not switch to using wireguard mode - {:?}", e); - } - } else { - warn!("Storage type not supported with wireguard mode"); - } - BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) - .with_wait_for_gateway(self.wait_for_gateway) + todo!() + // if let Ok(PersistedGatewayDetails::Default(mut config)) = self + // .storage + // .gateway_details_store() + // .load_gateway_details() + // .await + // { + // config.details.gateway_listener = format!( + // "ws://{}:{}", + // WG_TUN_DEVICE_ADDRESS, DEFAULT_CLIENT_LISTENING_PORT + // ); + // if let Err(e) = self + // .storage + // .gateway_details_store() + // .store_gateway_details(&PersistedGatewayDetails::Default(config)) + // .await + // { + // warn!("Could not switch to using wireguard mode - {:?}", e); + // } + // } else { + // warn!("Storage type not supported with wireguard mode"); + // } + // BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + // .with_wait_for_gateway(self.wait_for_gateway) } else { BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) .with_wait_for_gateway(self.wait_for_gateway) diff --git a/sdk/rust/nym-sdk/src/mixnet/paths.rs b/sdk/rust/nym-sdk/src/mixnet/paths.rs index 288218f5c5..88ae655d6a 100644 --- a/sdk/rust/nym-sdk/src/mixnet/paths.rs +++ b/sdk/rust/nym-sdk/src/mixnet/paths.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::{Error, Result}; -use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails; +use nym_client_core::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; use nym_client_core::client::base_client::{non_wasm_helpers, storage}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::client::replies::reply_storage::fs_backend; @@ -32,6 +33,7 @@ pub struct StoragePaths { pub ack_key: PathBuf, /// Key setup after authenticating with a gateway + #[deprecated] pub gateway_shared_key: PathBuf, /// The database containing credentials @@ -41,7 +43,10 @@ pub struct StoragePaths { pub reply_surb_database_path: PathBuf, /// Details of the used gateway + #[deprecated] pub gateway_details_path: PathBuf, + + pub gateway_registrations: PathBuf, } impl StoragePaths { @@ -67,6 +72,7 @@ impl StoragePaths { credential_database_path: dir.join("db.sqlite"), reply_surb_database_path: dir.join("persistent_reply_store.sqlite"), gateway_details_path: dir.join("gateway_details.json"), + gateway_registrations: dir.join("gateways_registrations.sqlite"), }) } @@ -78,7 +84,7 @@ impl StoragePaths { self.on_disk_key_storage_spec(), self.default_persistent_fs_reply_backend().await?, self.persistent_credential_storage().await?, - self.on_disk_gateway_details_storage(), + self.on_disk_gateway_details_storage().await?, )) } @@ -92,7 +98,7 @@ impl StoragePaths { self.persistent_fs_reply_backend(&config.reply_surbs) .await?, self.persistent_credential_storage().await?, - self.on_disk_gateway_details_storage(), + self.on_disk_gateway_details_storage().await?, )) } @@ -129,8 +135,8 @@ impl StoragePaths { OnDiskKeys::new(self.client_keys_paths()) } - pub fn on_disk_gateway_details_storage(&self) -> OnDiskGatewayDetails { - OnDiskGatewayDetails::new(&self.gateway_details_path) + pub async fn on_disk_gateway_details_storage(&self) -> Result<OnDiskGatewaysDetails, Error> { + Ok(non_wasm_helpers::setup_fs_gateways_storage(&self.gateway_registrations).await?) } fn client_keys_paths(&self) -> ClientKeysPaths { @@ -157,6 +163,7 @@ impl From<StoragePaths> for CommonClientPaths { ack_key_file: value.ack_key, }, gateway_details: value.gateway_details_path, + gateway_registrations: value.gateway_registrations, credentials_database: value.credential_database_path, reply_surb_database: value.reply_surb_database_path, } @@ -175,6 +182,7 @@ impl From<CommonClientPaths> for StoragePaths { credential_database_path: value.credentials_database, reply_surb_database_path: value.reply_surb_database, gateway_details_path: value.gateway_details, + gateway_registrations: value.gateway_registrations, } } } diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 03923f46ad..e0aa58d955 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -44,7 +44,7 @@ zeroize = "1.6.0" # internal nym-async-file-watcher = { path = "../../common/async-file-watcher" } nym-bin-common = { path = "../../common/bin-common", features = ["output_format"] } -nym-client-core = { path = "../../common/client-core", features = ["cli"] } +nym-client-core = { path = "../../common/client-core", features = ["cli", "fs-gateways-storage", "fs-surb-storage"] } nym-client-websocket-requests = { path = "../../clients/native/websocket-requests" } nym-config = { path = "../../common/config" } nym-credentials = { path = "../../common/credentials" } diff --git a/service-providers/network-requester/src/lib.rs b/service-providers/network-requester/src/lib.rs index a8e54ad19f..f8d783b13d 100644 --- a/service-providers/network-requester/src/lib.rs +++ b/service-providers/network-requester/src/lib.rs @@ -13,7 +13,10 @@ pub use crate::core::{NRServiceProvider, NRServiceProviderBuilder}; pub use config::Config; pub use nym_client_core::{ client::{ - base_client::storage::{gateway_details::OnDiskGatewayDetails, OnDiskPersistent}, + base_client::{ + non_wasm_helpers::{setup_fs_gateways_storage, setup_fs_reply_surb_backend}, + storage::{GatewaysDetailsStore, OnDiskGatewaysDetails, OnDiskPersistent}, + }, key_manager::persistence::OnDiskKeys, mix_traffic::transceiver::*, }, From bf4f16c7b919bb5ee67693dab6370ceb9398e916 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 09:29:07 +0000 Subject: [PATCH 287/394] adding additional methods to the trait --- .../src/backend/fs_backend/mod.rs | 4 + .../src/backend/mem_backend.rs | 4 + .../client-core/gateways-storage/src/lib.rs | 3 + .../src/cli_helpers/client_init.rs | 172 +++++++++--------- 4 files changed, 102 insertions(+), 81 deletions(-) diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 76d21c177b..6364bd376b 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -31,6 +31,10 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { todo!() } + async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + todo!() + } + async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 986ffef2de..2d955f6c20 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -47,6 +47,10 @@ impl GatewaysDetailsStore for InMemGatewaysDetails { // foo.cloned() } + async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + todo!() + } + async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 17c3f60dd8..4a64ab354c 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -27,6 +27,9 @@ pub trait GatewaysDetailsStore { /// Returns details of the currently active gateway, if available. async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError>; + /// Set the provided gateway as the currently active gateway. + async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError>; + /// Returns details of all registered gateways. async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError>; diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index e7fb8e6ba0..e147dd632c 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -51,6 +51,10 @@ pub struct CommonClientInitArgs { #[cfg_attr(feature = "cli", clap(long))] pub gateway: Option<identity::PublicKey>, + /// Specifies whether the client will attempt to enforce tls connection to the desired gateway. + #[cfg_attr(feature = "cli", clap(long))] + pub force_tls_gateway: bool, + /// Specifies whether the new gateway should be determined based by latency as opposed to being chosen /// uniformly. #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))] @@ -61,6 +65,11 @@ pub struct CommonClientInitArgs { #[cfg_attr(feature = "cli", clap(long))] pub force_register_gateway: bool, + /// If the registration is happening against new gateway, + /// specify whether it should be set as the currently active gateway + #[cfg_attr(feature = "cli", clap(long, default_value_t = true))] + pub set_active: bool, + /// Comma separated list of rest endpoints of the nyxd validators #[cfg_attr( feature = "cli", @@ -135,6 +144,9 @@ where eprintln!("Instructed to force registering gateway. This might overwrite keys!"); } + // TODO: look at the registration logic due to being able to store multiple gws now + let unused_variable = 42; + // If the client was already initialized, don't generate new keys and don't re-register with // the gateway (because this would create a new shared key). // Unless the user really wants to. @@ -144,86 +156,84 @@ where let user_chosen_gateway_id = common_args.gateway; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); - todo!() + let selection_spec = GatewaySelectionSpecification::new( + user_chosen_gateway_id.map(|id| id.to_base58_string()), + Some(common_args.latency_based_selection), + common_args.force_tls_gateway, + ); + log::debug!("Gateway selection specification: {selection_spec:?}"); - // let selection_spec = GatewaySelectionSpecification::new( - // user_chosen_gateway_id.map(|id| id.to_base58_string()), - // Some(common_args.latency_based_selection), - // false, - // ); - // log::debug!("Gateway selection specification: {selection_spec:?}"); - // - // // Load and potentially override config - // log::debug!("Init arguments: {init_args:#?}"); - // let config = C::construct_config(&init_args); - // log::debug!("Constructed config: {config:#?}"); - // let paths = config.common_paths(); - // let core = config.core_config(); - // - // log::info!( - // "Using nym-api: {}", - // core.client - // .nym_api_urls - // .iter() - // .map(|url| url.as_str()) - // .collect::<Vec<&str>>() - // .join(",") - // ); - // - // // Setup gateway by either registering a new one, or creating a new config from the selected - // // one but with keys kept, or reusing the gateway configuration. - // let key_store = OnDiskKeys::new(paths.keys.clone()); - // let details_store = setup_fs_gateways_storage(&paths.gateway_details).await?; - // - // let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { - // let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { - // ClientCoreError::CustomTopologyLoadFailure { - // file_path: custom_mixnet.clone(), - // source, - // } - // })?; - // hardcoded_topology.get_gateways() - // } else { - // let mut rng = rand::thread_rng(); - // crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? - // }; - // - // let gateway_setup = GatewaySetup::New { - // specification: selection_spec, - // available_gateways, - // overwrite_data: register_gateway, - // }; - // - // let init_details = - // crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; - // - // // TODO: ask the service provider we specified for its interface version and set it in the config - // - // let config_save_location = config.default_store_location(); - // if let Err(err) = config.save_to(&config_save_location) { - // return Err(ClientCoreError::ConfigSaveFailure { - // typ: C::NAME.to_string(), - // id: id.to_string(), - // path: config_save_location, - // source: err, - // } - // .into()); - // } - // - // eprintln!( - // "Saved configuration file to {}", - // config_save_location.display() - // ); - // - // let address = init_details.client_address()?; - // - // let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else { - // return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; - // }; - // let init_results = InitResults::new(config.core_config(), address, &gateway_details); - // - // Ok(InitResultsWithConfig { - // config, - // init_results, - // }) + // Load and potentially override config + log::debug!("Init arguments: {init_args:#?}"); + let config = C::construct_config(&init_args); + log::debug!("Constructed config: {config:#?}"); + let paths = config.common_paths(); + let core = config.core_config(); + + log::info!( + "Using nym-api: {}", + core.client + .nym_api_urls + .iter() + .map(|url| url.as_str()) + .collect::<Vec<&str>>() + .join(",") + ); + + // Setup gateway by either registering a new one, or creating a new config from the selected + // one but with keys kept, or reusing the gateway configuration. + let key_store = OnDiskKeys::new(paths.keys.clone()); + let details_store = setup_fs_gateways_storage(&paths.gateway_details).await?; + + let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { + let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { + ClientCoreError::CustomTopologyLoadFailure { + file_path: custom_mixnet.clone(), + source, + } + })?; + hardcoded_topology.get_gateways() + } else { + let mut rng = rand::thread_rng(); + crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? + }; + + let gateway_setup = GatewaySetup::New { + specification: selection_spec, + available_gateways, + overwrite_data: register_gateway, + }; + + let init_details = + crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; + + // TODO: ask the service provider we specified for its interface version and set it in the config + + let config_save_location = config.default_store_location(); + if let Err(err) = config.save_to(&config_save_location) { + return Err(ClientCoreError::ConfigSaveFailure { + typ: C::NAME.to_string(), + id: id.to_string(), + path: config_save_location, + source: err, + } + .into()); + } + + eprintln!( + "Saved configuration file to {}", + config_save_location.display() + ); + + let address = init_details.client_address()?; + + let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else { + return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; + }; + let init_results = InitResults::new(config.core_config(), address, &gateway_details); + + Ok(InitResultsWithConfig { + config, + init_results, + }) } From 0e09826140d5a8636cb3fe59d9b2c5bc3c1ea750 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 11:12:43 +0000 Subject: [PATCH 288/394] initial work on client config migration --- clients/native/src/client/config/mod.rs | 1 + .../src/client/config/old_config_v1_1_20.rs | 4 +- .../src/client/config/old_config_v1_1_20_2.rs | 25 +- .../src/client/config/old_config_v1_1_33.rs | 99 ++++ .../native/src/client/config/persistence.rs | 2 + clients/native/src/commands/mod.rs | 85 +++- .../20240304120000_create_initial_tables.sql | 3 + .../src/cli_helpers/client_init.rs | 2 +- .../src/client/key_manager/persistence.rs | 21 +- .../src/config/disk_persistence/keys_paths.rs | 16 - .../src/config/disk_persistence/mod.rs | 12 +- .../config/disk_persistence/old_v1_1_20_2.rs | 26 +- .../config/disk_persistence/old_v1_1_33.rs | 78 +++ common/client-core/src/config/mod.rs | 1 + .../src/config/old_config_v1_1_30.rs | 42 +- .../src/config/old_config_v1_1_33.rs | 478 ++++++++++++++++++ common/client-core/src/error.rs | 3 + 17 files changed, 782 insertions(+), 116 deletions(-) create mode 100644 clients/native/src/client/config/old_config_v1_1_33.rs create mode 100644 common/client-core/src/config/old_config_v1_1_33.rs diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index 7fa28c8ab4..5c0d156bd5 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -24,6 +24,7 @@ pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig}; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; +pub mod old_config_v1_1_33; mod persistence; mod template; diff --git a/clients/native/src/client/config/old_config_v1_1_20.rs b/clients/native/src/client/config/old_config_v1_1_20.rs index 8c2452d3e1..77ca8f5ca1 100644 --- a/clients/native/src/client/config/old_config_v1_1_20.rs +++ b/clients/native/src/client/config/old_config_v1_1_20.rs @@ -5,8 +5,8 @@ use crate::client::config::old_config_v1_1_20_2::{ ClientPathsV1_1_20_2, ConfigV1_1_20_2, SocketTypeV1_1_20_2, SocketV1_1_20_2, }; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; use nym_client_core::config::old_config_v1_1_20_2::{ ClientV1_1_20_2, ConfigV1_1_20_2 as BaseConfigV1_1_20_2, @@ -60,7 +60,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { socket: value.socket.into(), storage_paths: ClientPathsV1_1_20_2 { common_paths: CommonClientPathsV1_1_20_2 { - keys: ClientKeysPaths { + keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, public_identity_key_file: value.base.client.public_identity_key_file, private_encryption_key_file: value.base.client.private_encryption_key_file, diff --git a/clients/native/src/client/config/old_config_v1_1_20_2.rs b/clients/native/src/client/config/old_config_v1_1_20_2.rs index 8e50fe0047..b6d9703a92 100644 --- a/clients/native/src/client/config/old_config_v1_1_20_2.rs +++ b/clients/native/src/client/config/old_config_v1_1_20_2.rs @@ -1,13 +1,10 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::{ - client::config::{ - default_config_filepath, persistence::ClientPaths, Config, Socket, SocketType, - }, - error::ClientError, +use crate::client::config::old_config_v1_1_33::{ + ClientPathsV1_1_33, ConfigV1_1_33, SocketTypeV1_1_33, SocketV1_1_33, }; - +use crate::{client::config::default_config_filepath, error::ClientError}; use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseConfigV1_1_20_2; @@ -49,12 +46,12 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig), ClientError> { + pub fn upgrade(self) -> Result<(ConfigV1_1_33, GatewayEndpointConfig), ClientError> { let gateway_details = self.base.client.gateway_endpoint.clone().into(); - let config = Config { + let config = ConfigV1_1_33 { base: BaseConfigV1_1_30::from(self.base).into(), socket: self.socket.into(), - storage_paths: ClientPaths { + storage_paths: ClientPathsV1_1_33 { common_paths: self.storage_paths.common_paths.upgrade_default()?, }, logging: self.logging, @@ -71,11 +68,11 @@ pub enum SocketTypeV1_1_20_2 { None, } -impl From<SocketTypeV1_1_20_2> for SocketType { +impl From<SocketTypeV1_1_20_2> for SocketTypeV1_1_33 { fn from(value: SocketTypeV1_1_20_2) -> Self { match value { - SocketTypeV1_1_20_2::WebSocket => SocketType::WebSocket, - SocketTypeV1_1_20_2::None => SocketType::None, + SocketTypeV1_1_20_2::WebSocket => SocketTypeV1_1_33::WebSocket, + SocketTypeV1_1_20_2::None => SocketTypeV1_1_33::None, } } } @@ -88,9 +85,9 @@ pub struct SocketV1_1_20_2 { pub listening_port: u16, } -impl From<SocketV1_1_20_2> for Socket { +impl From<SocketV1_1_20_2> for SocketV1_1_33 { fn from(value: SocketV1_1_20_2) -> Self { - Socket { + SocketV1_1_33 { socket_type: value.socket_type.into(), host: value.host, listening_port: value.listening_port, diff --git a/clients/native/src/client/config/old_config_v1_1_33.rs b/clients/native/src/client/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..02ed7218d1 --- /dev/null +++ b/clients/native/src/client/config/old_config_v1_1_33.rs @@ -0,0 +1,99 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::config::persistence::ClientPaths; +use crate::client::config::{default_config_filepath, Config, Socket, SocketType}; +use crate::error::ClientError; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_network_defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; +use serde::{Deserialize, Serialize}; +use std::io; +use std::net::{IpAddr, Ipv4Addr}; +use std::path::Path; + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct ClientPathsV1_1_33 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +pub struct ConfigV1_1_33 { + #[serde(flatten)] + pub base: BaseConfigV1_1_33, + + pub socket: SocketV1_1_33, + + // \/ CHANGED + pub storage_paths: ClientPathsV1_1_33, + // /\ CHANGED + pub logging: LoggingSettings, +} + +impl ConfigV1_1_33 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result<Config, ClientError> { + Ok(Config { + base: self.base.into(), + socket: self.socket.into(), + storage_paths: ClientPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + }, + logging: self.logging, + }) + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone, Copy)] +#[serde(deny_unknown_fields)] +pub enum SocketTypeV1_1_33 { + WebSocket, + None, +} + +impl From<SocketTypeV1_1_33> for SocketType { + fn from(value: SocketTypeV1_1_33) -> Self { + match value { + SocketTypeV1_1_33::WebSocket => SocketType::WebSocket, + SocketTypeV1_1_33::None => SocketType::None, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct SocketV1_1_33 { + pub socket_type: SocketTypeV1_1_33, + pub host: IpAddr, + pub listening_port: u16, +} + +impl From<SocketV1_1_33> for Socket { + fn from(value: SocketV1_1_33) -> Self { + Socket { + socket_type: value.socket_type.into(), + host: value.host, + listening_port: value.listening_port, + } + } +} + +impl Default for SocketV1_1_33 { + fn default() -> Self { + SocketV1_1_33 { + socket_type: SocketTypeV1_1_33::WebSocket, + host: IpAddr::V4(Ipv4Addr::LOCALHOST), + listening_port: DEFAULT_WEBSOCKET_LISTENING_PORT, + } + } +} diff --git a/clients/native/src/client/config/persistence.rs b/clients/native/src/client/config/persistence.rs index a61913a2f7..bdd3cd6a65 100644 --- a/clients/native/src/client/config/persistence.rs +++ b/clients/native/src/client/config/persistence.rs @@ -5,6 +5,8 @@ use nym_client_core::config::disk_persistence::CommonClientPaths; use serde::{Deserialize, Serialize}; use std::path::Path; + + #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] pub struct ClientPaths { #[serde(flatten)] diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index ff1b8087fd..39ab24913f 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -4,6 +4,7 @@ use crate::client::config::old_config_v1_1_13::OldConfigV1_1_13; use crate::client::config::old_config_v1_1_20::ConfigV1_1_20; use crate::client::config::old_config_v1_1_20_2::ConfigV1_1_20_2; +use crate::client::config::old_config_v1_1_33::ConfigV1_1_33; use crate::client::config::{BaseClientConfig, Config}; use crate::error::ClientError; use clap::CommandFactory; @@ -14,6 +15,7 @@ use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_client_core::client::base_client::storage::gateway_details::{ OnDiskGatewayDetails, PersistedGatewayDetails, }; +use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; @@ -126,22 +128,34 @@ fn persist_gateway_details( config: &Config, details: GatewayEndpointConfig, ) -> Result<(), ClientError> { - let details_store = - OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - source: Box::new(source), - }) - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| { - ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) - }) + todo!() + // let details_store = + // OnDiskGatewaysDetails::new(&config.storage_paths.common_paths.gateway_details); + // let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); + // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { + // ClientError::ClientCoreError(ClientCoreError::KeyStoreError { + // source: Box::new(source), + // }) + // })?; + // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; + // details_store + // .store_to_disk(&persisted_details) + // .map_err(|source| { + // ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + // source: Box::new(source), + // }) + // }) +} + +fn migrate_gateway_details( + config: &Config, + old_details: Option<GatewayEndpointConfig>, +) -> Result<(), ClientError> { + todo!() +} + +fn extract_gateway_details(config: &ConfigV1_1_33) -> Result<(), ClientError> { + todo!() } fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> { @@ -158,8 +172,10 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); - let (updated, gateway_config) = updated_step2.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let updated = updated_step3.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; updated.save_to_default_location()?; Ok(true) @@ -178,8 +194,10 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> { info!("It is going to get updated to the current specification."); let updated_step1: ConfigV1_1_20_2 = old_config.into(); - let (updated, gateway_config) = updated_step1.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let updated = updated_step2.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; updated.save_to_default_location()?; Ok(true) @@ -195,8 +213,28 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> { info!("It seems the client is using <= v1.1.20_2 config template."); info!("It is going to get updated to the current specification."); - let (updated, gateway_config) = old_config.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step1, gateway_config) = old_config.upgrade()?; + let updated = updated_step1.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; + + updated.save_to_default_location()?; + Ok(true) +} + +fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let updated = old_config.try_upgrade()?; + + migrate_gateway_details(&updated, None)?; updated.save_to_default_location()?; Ok(true) @@ -212,6 +250,9 @@ fn try_upgrade_config(id: &str) -> Result<(), ClientError> { if try_upgrade_v1_1_20_2_config(id)? { return Ok(()); } + if try_upgrade_v1_1_33_config(id)? { + return Ok(()); + } Ok(()) } diff --git a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql index 6df9d40a1a..bb4d59f7a1 100644 --- a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql +++ b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql @@ -16,6 +16,9 @@ CREATE TABLE registered_gateway gateway_type TEXT CHECK ( gateway_type IN ('remote', 'custom') ) NOT NULL DEFAULT 'remote' ); +-- TODO: perhaps keep additional metadata such as bandwidth, credential usage, etc + + CREATE TABLE remote_gateway_details ( gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY REFERENCES registered_gateway (gateway_id_bs58), diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index e147dd632c..3317aa4df7 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -183,7 +183,7 @@ where // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. let key_store = OnDiskKeys::new(paths.keys.clone()); - let details_store = setup_fs_gateways_storage(&paths.gateway_details).await?; + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { diff --git a/common/client-core/src/client/key_manager/persistence.rs b/common/client-core/src/client/key_manager/persistence.rs index 984019eb93..00041206db 100644 --- a/common/client-core/src/client/key_manager/persistence.rs +++ b/common/client-core/src/client/key_manager/persistence.rs @@ -84,14 +84,6 @@ impl OnDiskKeys { OnDiskKeys { paths } } - #[doc(hidden)] - pub fn ephemeral_load_gateway_keys( - &self, - ) -> Result<zeroize::Zeroizing<SharedKeys>, OnDiskKeysError> { - self.load_key(self.paths.gateway_shared_key(), "gateway shared") - .map(zeroize::Zeroizing::new) - } - #[doc(hidden)] pub fn load_encryption_keypair(&self) -> Result<encryption::KeyPair, OnDiskKeysError> { let encryption_paths = self.paths.encryption_key_pair_path(); @@ -161,14 +153,11 @@ impl OnDiskKeys { let encryption_keypair = self.load_encryption_keypair()?; let ack_key: AckKey = self.load_key(self.paths.ack_key(), "ack key")?; - let gateway_shared_key: Option<SharedKeys> = self - .load_key(self.paths.gateway_shared_key(), "gateway shared keys") - .ok(); Ok(KeyManager::from_keys( identity_keypair, encryption_keypair, - gateway_shared_key, + None, ack_key, )) } @@ -192,14 +181,6 @@ impl OnDiskKeys { self.store_key(keys.ack_key.as_ref(), self.paths.ack_key(), "ack key")?; - if let Some(shared_keys) = &keys.gateway_shared_key { - self.store_key( - shared_keys.deref(), - self.paths.gateway_shared_key(), - "gateway shared keys", - )?; - } - Ok(()) } } diff --git a/common/client-core/src/config/disk_persistence/keys_paths.rs b/common/client-core/src/config/disk_persistence/keys_paths.rs index aeab0359ea..cdffebe1e2 100644 --- a/common/client-core/src/config/disk_persistence/keys_paths.rs +++ b/common/client-core/src/config/disk_persistence/keys_paths.rs @@ -8,7 +8,6 @@ pub const DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME: &str = "private_identity.pem"; pub const DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME: &str = "public_identity.pem"; pub const DEFAULT_PRIVATE_ENCRYPTION_KEY_FILENAME: &str = "private_encryption.pem"; pub const DEFAULT_PUBLIC_ENCRYPTION_KEY_FILENAME: &str = "public_encryption.pem"; -pub const DEFAULT_GATEWAY_SHARED_KEY_FILENAME: &str = "gateway_shared.pem"; pub const DEFAULT_ACK_KEY_FILENAME: &str = "ack_key.pem"; #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] @@ -25,10 +24,6 @@ pub struct ClientKeysPaths { /// Path to file containing public encryption key. pub public_encryption_key_file: PathBuf, - /// Path to file containing shared key derived with the specified gateway that is used - /// for all communication with it. - pub gateway_shared_key_file: PathBuf, - /// Path to file containing key used for encrypting and decrypting the content of an /// acknowledgement so that nobody besides the client knows which packet it refers to. pub ack_key_file: PathBuf, @@ -43,7 +38,6 @@ impl ClientKeysPaths { public_identity_key_file: base_dir.join(DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME), private_encryption_key_file: base_dir.join(DEFAULT_PRIVATE_ENCRYPTION_KEY_FILENAME), public_encryption_key_file: base_dir.join(DEFAULT_PUBLIC_ENCRYPTION_KEY_FILENAME), - gateway_shared_key_file: base_dir.join(DEFAULT_GATEWAY_SHARED_KEY_FILENAME), ack_key_file: base_dir.join(DEFAULT_ACK_KEY_FILENAME), } } @@ -67,7 +61,6 @@ impl ClientKeysPaths { || matches!(self.private_identity_key_file.try_exists(), Ok(true)) || matches!(self.public_encryption_key_file.try_exists(), Ok(true)) || matches!(self.private_encryption_key_file.try_exists(), Ok(true)) - || matches!(self.gateway_shared_key_file.try_exists(), Ok(true)) || matches!(self.ack_key_file.try_exists(), Ok(true)) } @@ -76,14 +69,9 @@ impl ClientKeysPaths { .or_else(|| file_exists(&self.private_identity_key_file)) .or_else(|| file_exists(&self.public_encryption_key_file)) .or_else(|| file_exists(&self.private_encryption_key_file)) - .or_else(|| file_exists(&self.gateway_shared_key_file)) .or_else(|| file_exists(&self.ack_key_file)) } - pub fn gateway_key_file_exists(&self) -> bool { - matches!(self.gateway_shared_key_file.try_exists(), Ok(true)) - } - pub fn private_identity_key(&self) -> &Path { &self.private_identity_key_file } @@ -100,10 +88,6 @@ impl ClientKeysPaths { &self.public_encryption_key_file } - pub fn gateway_shared_key(&self) -> &Path { - &self.gateway_shared_key_file - } - pub fn ack_key(&self) -> &Path { &self.ack_key_file } diff --git a/common/client-core/src/config/disk_persistence/mod.rs b/common/client-core/src/config/disk_persistence/mod.rs index b52b261bff..c086696a4b 100644 --- a/common/client-core/src/config/disk_persistence/mod.rs +++ b/common/client-core/src/config/disk_persistence/mod.rs @@ -7,9 +7,8 @@ use std::path::{Path, PathBuf}; pub mod keys_paths; pub mod old_v1_1_20_2; -mod old_v1_1_33; +pub mod old_v1_1_33; -pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json"; pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite"; pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db"; pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.sqlite"; @@ -19,12 +18,8 @@ pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.s pub struct CommonClientPaths { pub keys: ClientKeysPaths, - /// Path to the file containing information about gateway used by this client, - /// i.e. details such as its public key, owner address or the network information. - #[deprecated] - pub gateway_details: PathBuf, - - // TODO: + /// Path to the file containing information about gateways used by this client, + /// i.e. details such as their public keys, owner addresses or the network information. pub gateway_registrations: PathBuf, /// Path to the database containing bandwidth credentials of this client. @@ -41,7 +36,6 @@ impl CommonClientPaths { CommonClientPaths { credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME), reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME), - gateway_details: base_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), gateway_registrations: base_dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), keys: ClientKeysPaths::new_base(base_data_directory), } diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs b/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs index 24496f1497..e1863bb567 100644 --- a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs +++ b/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs @@ -1,8 +1,9 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::disk_persistence::keys_paths::ClientKeysPaths; -use crate::config::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAY_DETAILS_FILENAME}; +use crate::config::disk_persistence::old_v1_1_33::{ + ClientKeysPathsV1_1_33, CommonClientPathsV1_1_33, DEFAULT_GATEWAY_DETAILS_FILENAME, +}; use crate::error::ClientCoreError; use serde::{Deserialize, Serialize}; use std::path::PathBuf; @@ -10,24 +11,23 @@ use std::path::PathBuf; #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] pub struct CommonClientPathsV1_1_20_2 { - pub keys: ClientKeysPaths, + pub keys: ClientKeysPathsV1_1_33, pub credentials_database: PathBuf, pub reply_surb_database: PathBuf, } impl CommonClientPathsV1_1_20_2 { - pub fn upgrade_default(self) -> Result<CommonClientPaths, ClientCoreError> { + pub fn upgrade_default(self) -> Result<CommonClientPathsV1_1_33, ClientCoreError> { let data_dir = self.reply_surb_database.parent().ok_or_else(|| { - ClientCoreError::UnableToUpgradeConfigFile { - new_version: "1.1.20-2".to_string(), + ClientCoreError::ConfigFileUpgradeFailure { + current_version: "1.1.20-2".to_string(), } })?; - todo!() - // Ok(CommonClientPaths { - // keys: self.keys, - // gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), - // credentials_database: self.credentials_database, - // reply_surb_database: self.reply_surb_database, - // }) + Ok(CommonClientPathsV1_1_33 { + keys: self.keys, + gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), + credentials_database: self.credentials_database, + reply_surb_database: self.reply_surb_database, + }) } } diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_33.rs b/common/client-core/src/config/disk_persistence/old_v1_1_33.rs index 755fb6cc8b..f453b5e01a 100644 --- a/common/client-core/src/config/disk_persistence/old_v1_1_33.rs +++ b/common/client-core/src/config/disk_persistence/old_v1_1_33.rs @@ -1,2 +1,80 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 + +use crate::config::disk_persistence::keys_paths::ClientKeysPaths; +use crate::config::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAYS_DETAILS_DB_FILENAME}; +use crate::error::ClientCoreError; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json"; + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +pub struct ClientKeysPathsV1_1_33 { + /// Path to file containing private identity key. + pub private_identity_key_file: PathBuf, + + /// Path to file containing public identity key. + pub public_identity_key_file: PathBuf, + + /// Path to file containing private encryption key. + pub private_encryption_key_file: PathBuf, + + /// Path to file containing public encryption key. + pub public_encryption_key_file: PathBuf, + + /// Path to file containing shared key derived with the specified gateway that is used + /// for all communication with it. + pub gateway_shared_key_file: PathBuf, + + /// Path to file containing key used for encrypting and decrypting the content of an + /// acknowledgement so that nobody besides the client knows which packet it refers to. + pub ack_key_file: PathBuf, +} + +impl ClientKeysPathsV1_1_33 { + pub fn upgrade(self) -> ClientKeysPaths { + ClientKeysPaths { + private_identity_key_file: self.private_identity_key_file, + public_identity_key_file: self.public_identity_key_file, + private_encryption_key_file: self.private_encryption_key_file, + public_encryption_key_file: self.public_encryption_key_file, + ack_key_file: self.ack_key_file, + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct CommonClientPathsV1_1_33 { + pub keys: ClientKeysPathsV1_1_33, + + /// Path to the file containing information about gateway used by this client, + /// i.e. details such as its public key, owner address or the network information. + pub gateway_details: PathBuf, + + /// Path to the database containing bandwidth credentials of this client. + pub credentials_database: PathBuf, + + /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + pub reply_surb_database: PathBuf, +} + +impl CommonClientPathsV1_1_33 { + // note that during the upgrade process, the caller will need to extract the key and gateway details + // manually and resave them in the new database + pub fn upgrade_default(self) -> Result<CommonClientPaths, ClientCoreError> { + let data_dir = self.gateway_details.parent().ok_or_else(|| { + ClientCoreError::ConfigFileUpgradeFailure { + current_version: "1.1.33".to_string(), + } + })?; + + Ok(CommonClientPaths { + keys: self.keys.upgrade(), + gateway_registrations: data_dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), + credentials_database: self.credentials_database, + reply_surb_database: self.reply_surb_database, + }) + } +} diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 3f4bbb4efe..96615d3be4 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -21,6 +21,7 @@ pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; pub mod old_config_v1_1_30; +pub mod old_config_v1_1_33; // 'DEBUG' const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5; diff --git a/common/client-core/src/config/old_config_v1_1_30.rs b/common/client-core/src/config/old_config_v1_1_30.rs index 87dae0eb3f..17aeba6bfd 100644 --- a/common/client-core/src/config/old_config_v1_1_30.rs +++ b/common/client-core/src/config/old_config_v1_1_30.rs @@ -2,9 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::topology_control::geo_aware_provider::CountryGroup; -use crate::config::{ - Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, GroupBy, - ReplySurbs, Topology, TopologyStructure, Traffic, +use crate::config::old_config_v1_1_33::{ + AcknowledgementsV1_1_33, ClientV1_1_33, ConfigV1_1_33, CoverTrafficV1_1_33, DebugConfigV1_1_33, + GatewayConnectionV1_1_33, GroupByV1_1_33, ReplySurbsV1_1_33, TopologyStructureV1_1_33, + TopologyV1_1_33, TrafficV1_1_33, }; use nym_sphinx::{ addressing::clients::Recipient, @@ -64,18 +65,18 @@ pub struct ConfigV1_1_30 { pub debug: DebugConfigV1_1_30, } -impl From<ConfigV1_1_30> for Config { +impl From<ConfigV1_1_30> for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { - client: Client { + ConfigV1_1_33 { + client: ClientV1_1_33 { version: value.client.version, id: value.client.id, disabled_credentials_mode: value.client.disabled_credentials_mode, nyxd_urls: value.client.nyxd_urls, nym_api_urls: value.client.nym_api_urls, }, - debug: DebugConfig { - traffic: Traffic { + debug: DebugConfigV1_1_33 { + traffic: TrafficV1_1_33 { average_packet_delay: value.debug.traffic.average_packet_delay, message_sending_average_delay: value .debug @@ -89,7 +90,7 @@ impl From<ConfigV1_1_30> for Config { secondary_packet_size: value.debug.traffic.secondary_packet_size, packet_type: value.debug.traffic.packet_type, }, - cover_traffic: CoverTraffic { + cover_traffic: CoverTrafficV1_1_33 { loop_cover_traffic_average_delay: value .debug .cover_traffic @@ -103,18 +104,18 @@ impl From<ConfigV1_1_30> for Config { .cover_traffic .disable_loop_cover_traffic_stream, }, - gateway_connection: GatewayConnection { + gateway_connection: GatewayConnectionV1_1_33 { gateway_response_timeout: value .debug .gateway_connection .gateway_response_timeout, }, - acknowledgements: Acknowledgements { + acknowledgements: AcknowledgementsV1_1_33 { average_ack_delay: value.debug.acknowledgements.average_ack_delay, ack_wait_multiplier: value.debug.acknowledgements.ack_wait_multiplier, ack_wait_addition: value.debug.acknowledgements.ack_wait_addition, }, - topology: Topology { + topology: TopologyV1_1_33 { topology_refresh_rate: value.debug.topology.topology_refresh_rate, topology_resolution_timeout: value.debug.topology.topology_resolution_timeout, disable_refreshing: value.debug.topology.disable_refreshing, @@ -124,7 +125,7 @@ impl From<ConfigV1_1_30> for Config { .max_startup_gateway_waiting_period, topology_structure: value.debug.topology.topology_structure.into(), }, - reply_surbs: ReplySurbs { + reply_surbs: ReplySurbsV1_1_33 { minimum_reply_surb_storage_threshold: value .debug .reply_surbs @@ -155,7 +156,10 @@ impl From<ConfigV1_1_30> for Config { .maximum_reply_surb_drop_waiting_period, maximum_reply_surb_age: value.debug.reply_surbs.maximum_reply_surb_age, maximum_reply_key_age: value.debug.reply_surbs.maximum_reply_key_age, + + // \/ ADDED surb_mix_hops: None, + // /\ ADDED }, }, } @@ -345,12 +349,12 @@ pub enum TopologyStructureV1_1_30 { GeoAware(GroupByV1_1_30), } -impl From<TopologyStructureV1_1_30> for TopologyStructure { +impl From<TopologyStructureV1_1_30> for TopologyStructureV1_1_33 { fn from(value: TopologyStructureV1_1_30) -> Self { match value { - TopologyStructureV1_1_30::NymApi => TopologyStructure::NymApi, + TopologyStructureV1_1_30::NymApi => TopologyStructureV1_1_33::NymApi, TopologyStructureV1_1_30::GeoAware(group_by) => { - TopologyStructure::GeoAware(group_by.into()) + TopologyStructureV1_1_33::GeoAware(group_by.into()) } } } @@ -363,11 +367,11 @@ pub enum GroupByV1_1_30 { NymAddress(Recipient), } -impl From<GroupByV1_1_30> for GroupBy { +impl From<GroupByV1_1_30> for GroupByV1_1_33 { fn from(value: GroupByV1_1_30) -> Self { match value { - GroupByV1_1_30::CountryGroup(country) => GroupBy::CountryGroup(country), - GroupByV1_1_30::NymAddress(addr) => GroupBy::NymAddress(addr), + GroupByV1_1_30::CountryGroup(country) => GroupByV1_1_33::CountryGroup(country), + GroupByV1_1_30::NymAddress(addr) => GroupByV1_1_33::NymAddress(addr), } } } diff --git a/common/client-core/src/config/old_config_v1_1_33.rs b/common/client-core/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..0d47b95361 --- /dev/null +++ b/common/client-core/src/config/old_config_v1_1_33.rs @@ -0,0 +1,478 @@ +// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::topology_control::geo_aware_provider::CountryGroup; +use crate::config::{ + Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, GroupBy, + ReplySurbs, Topology, TopologyStructure, Traffic, +}; +use nym_sphinx::{ + addressing::clients::Recipient, + params::{PacketSize, PacketType}, +}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; +use url::Url; + +// 'DEBUG' +const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5; + +const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500); +const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200); +const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20); +const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50); +const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min +const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000); +const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead + +// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause +// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the +// bandwidth bridging protocol, we can come back to a smaller timeout value +const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60); + +const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70; + +// reply-surbs related: + +// define when to request +// clients/client-core/src/client/replies/reply_storage/surb_storage.rs +const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200; + +// define how much to request at once +// clients/client-core/src/client/replies/reply_controller.rs +const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100; + +const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500; + +const DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD: Duration = Duration::from_secs(10); +const DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD: Duration = Duration::from_secs(5 * 60); + +// 12 hours +const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60); + +// 24 hours +const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + pub client: ClientV1_1_33, + + #[serde(default)] + pub debug: DebugConfigV1_1_33, +} + +impl From<ConfigV1_1_33> for Config { + fn from(value: ConfigV1_1_33) -> Self { + Config { + client: Client { + version: value.client.version, + id: value.client.id, + disabled_credentials_mode: value.client.disabled_credentials_mode, + nyxd_urls: value.client.nyxd_urls, + nym_api_urls: value.client.nym_api_urls, + }, + debug: DebugConfig { + traffic: Traffic { + average_packet_delay: value.debug.traffic.average_packet_delay, + message_sending_average_delay: value + .debug + .traffic + .message_sending_average_delay, + disable_main_poisson_packet_distribution: value + .debug + .traffic + .disable_main_poisson_packet_distribution, + primary_packet_size: value.debug.traffic.primary_packet_size, + secondary_packet_size: value.debug.traffic.secondary_packet_size, + packet_type: value.debug.traffic.packet_type, + }, + cover_traffic: CoverTraffic { + loop_cover_traffic_average_delay: value + .debug + .cover_traffic + .loop_cover_traffic_average_delay, + cover_traffic_primary_size_ratio: value + .debug + .cover_traffic + .cover_traffic_primary_size_ratio, + disable_loop_cover_traffic_stream: value + .debug + .cover_traffic + .disable_loop_cover_traffic_stream, + }, + gateway_connection: GatewayConnection { + gateway_response_timeout: value + .debug + .gateway_connection + .gateway_response_timeout, + }, + acknowledgements: Acknowledgements { + average_ack_delay: value.debug.acknowledgements.average_ack_delay, + ack_wait_multiplier: value.debug.acknowledgements.ack_wait_multiplier, + ack_wait_addition: value.debug.acknowledgements.ack_wait_addition, + }, + topology: Topology { + topology_refresh_rate: value.debug.topology.topology_refresh_rate, + topology_resolution_timeout: value.debug.topology.topology_resolution_timeout, + disable_refreshing: value.debug.topology.disable_refreshing, + max_startup_gateway_waiting_period: value + .debug + .topology + .max_startup_gateway_waiting_period, + topology_structure: value.debug.topology.topology_structure.into(), + }, + reply_surbs: ReplySurbs { + minimum_reply_surb_storage_threshold: value + .debug + .reply_surbs + .minimum_reply_surb_storage_threshold, + maximum_reply_surb_storage_threshold: value + .debug + .reply_surbs + .maximum_reply_surb_storage_threshold, + minimum_reply_surb_request_size: value + .debug + .reply_surbs + .minimum_reply_surb_request_size, + maximum_reply_surb_request_size: value + .debug + .reply_surbs + .maximum_reply_surb_request_size, + maximum_allowed_reply_surb_request_size: value + .debug + .reply_surbs + .maximum_allowed_reply_surb_request_size, + maximum_reply_surb_rerequest_waiting_period: value + .debug + .reply_surbs + .maximum_reply_surb_rerequest_waiting_period, + maximum_reply_surb_drop_waiting_period: value + .debug + .reply_surbs + .maximum_reply_surb_drop_waiting_period, + maximum_reply_surb_age: value.debug.reply_surbs.maximum_reply_surb_age, + maximum_reply_key_age: value.debug.reply_surbs.maximum_reply_key_age, + surb_mix_hops: value.debug.reply_surbs.surb_mix_hops, + }, + }, + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +// note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 +#[serde(deny_unknown_fields)] +pub struct ClientV1_1_33 { + /// Version of the client for which this configuration was created. + pub version: String, + + /// ID specifies the human readable ID of this particular client. + pub id: String, + + /// Indicates whether this client is running in a disabled credentials mode, thus attempting + /// to claim bandwidth without presenting bandwidth credentials. + // TODO: this should be moved to `debug.gateway_connection` + #[serde(default)] + pub disabled_credentials_mode: bool, + + /// Addresses to nyxd validators via which the client can communicate with the chain. + #[serde(alias = "validator_urls")] + pub nyxd_urls: Vec<Url>, + + /// Addresses to APIs running on validator from which the client gets the view of the network. + #[serde(alias = "validator_api_urls")] + pub nym_api_urls: Vec<Url>, +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct TrafficV1_1_33 { + /// The parameter of Poisson distribution determining how long, on average, + /// sent packet is going to be delayed at any given mix node. + /// So for a packet going through three mix nodes, on average, it will take three times this value + /// until the packet reaches its destination. + #[serde(with = "humantime_serde")] + pub average_packet_delay: Duration, + + /// The parameter of Poisson distribution determining how long, on average, + /// it is going to take another 'real traffic stream' message to be sent. + /// If no real packets are available and cover traffic is enabled, + /// a loop cover message is sent instead in order to preserve the rate. + #[serde(with = "humantime_serde")] + pub message_sending_average_delay: Duration, + + /// Controls whether the main packet stream constantly produces packets according to the predefined + /// poisson distribution. + pub disable_main_poisson_packet_distribution: bool, + + /// Specifies the packet size used for sent messages. + /// Do not override it unless you understand the consequences of that change. + pub primary_packet_size: PacketSize, + + /// Specifies the optional auxiliary packet size for optimizing message streams. + /// Note that its use decreases overall anonymity. + /// Do not set it it unless you understand the consequences of that change. + pub secondary_packet_size: Option<PacketSize>, + + pub packet_type: PacketType, +} + +impl Default for TrafficV1_1_33 { + fn default() -> Self { + TrafficV1_1_33 { + average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, + message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, + disable_main_poisson_packet_distribution: false, + primary_packet_size: PacketSize::RegularPacket, + secondary_packet_size: None, + packet_type: PacketType::Mix, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct CoverTrafficV1_1_33 { + /// The parameter of Poisson distribution determining how long, on average, + /// it is going to take for another loop cover traffic message to be sent. + #[serde(with = "humantime_serde")] + pub loop_cover_traffic_average_delay: Duration, + + /// Specifies the ratio of `primary_packet_size` to `secondary_packet_size` used in cover traffic. + /// Only applicable if `secondary_packet_size` is enabled. + pub cover_traffic_primary_size_ratio: f64, + + /// Controls whether the dedicated loop cover traffic stream should be enabled. + /// (and sending packets, on average, every [Self::loop_cover_traffic_average_delay]) + pub disable_loop_cover_traffic_stream: bool, +} + +impl Default for CoverTrafficV1_1_33 { + fn default() -> Self { + CoverTrafficV1_1_33 { + loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, + cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, + disable_loop_cover_traffic_stream: false, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct GatewayConnectionV1_1_33 { + /// How long we're willing to wait for a response to a message sent to the gateway, + /// before giving up on it. + #[serde(with = "humantime_serde")] + pub gateway_response_timeout: Duration, +} + +impl Default for GatewayConnectionV1_1_33 { + fn default() -> Self { + GatewayConnectionV1_1_33 { + gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct AcknowledgementsV1_1_33 { + /// The parameter of Poisson distribution determining how long, on average, + /// sent acknowledgement is going to be delayed at any given mix node. + /// So for an ack going through three mix nodes, on average, it will take three times this value + /// until the packet reaches its destination. + #[serde(with = "humantime_serde")] + pub average_ack_delay: Duration, + + /// Value multiplied with the expected round trip time of an acknowledgement packet before + /// it is assumed it was lost and retransmission of the data packet happens. + /// In an ideal network with 0 latency, this value would have been 1. + pub ack_wait_multiplier: f64, + + /// Value added to the expected round trip time of an acknowledgement packet before + /// it is assumed it was lost and retransmission of the data packet happens. + /// In an ideal network with 0 latency, this value would have been 0. + #[serde(with = "humantime_serde")] + pub ack_wait_addition: Duration, +} + +impl Default for AcknowledgementsV1_1_33 { + fn default() -> Self { + AcknowledgementsV1_1_33 { + average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, + ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, + ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct TopologyV1_1_33 { + /// The uniform delay every which clients are querying the directory server + /// to try to obtain a compatible network topology to send sphinx packets through. + #[serde(with = "humantime_serde")] + pub topology_refresh_rate: Duration, + + /// During topology refresh, test packets are sent through every single possible network + /// path. This timeout determines waiting period until it is decided that the packet + /// did not reach its destination. + #[serde(with = "humantime_serde")] + pub topology_resolution_timeout: Duration, + + /// Specifies whether the client should not refresh the network topology after obtaining + /// the first valid instance. + /// Supersedes `topology_refresh_rate_ms`. + pub disable_refreshing: bool, + + /// Defines how long the client is going to wait on startup for its gateway to come online, + /// before abandoning the procedure. + #[serde(with = "humantime_serde")] + pub max_startup_gateway_waiting_period: Duration, + + /// Specifies the mixnode topology to be used for sending packets. + pub topology_structure: TopologyStructureV1_1_33, +} + +#[allow(clippy::large_enum_variant)] +#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum TopologyStructureV1_1_33 { + #[default] + NymApi, + GeoAware(GroupByV1_1_33), +} + +impl From<TopologyStructureV1_1_33> for TopologyStructure { + fn from(value: TopologyStructureV1_1_33) -> Self { + match value { + TopologyStructureV1_1_33::NymApi => TopologyStructure::NymApi, + TopologyStructureV1_1_33::GeoAware(group_by) => { + TopologyStructure::GeoAware(group_by.into()) + } + } + } +} + +#[allow(clippy::large_enum_variant)] +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum GroupByV1_1_33 { + CountryGroup(CountryGroup), + NymAddress(Recipient), +} + +impl From<GroupByV1_1_33> for GroupBy { + fn from(value: GroupByV1_1_33) -> Self { + match value { + GroupByV1_1_33::CountryGroup(country) => GroupBy::CountryGroup(country), + GroupByV1_1_33::NymAddress(addr) => GroupBy::NymAddress(addr), + } + } +} + +impl std::fmt::Display for GroupByV1_1_33 { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GroupByV1_1_33::CountryGroup(group) => write!(f, "group: {}", group), + GroupByV1_1_33::NymAddress(address) => write!(f, "address: {}", address), + } + } +} + +impl Default for TopologyV1_1_33 { + fn default() -> Self { + TopologyV1_1_33 { + topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, + topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, + disable_refreshing: false, + max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, + topology_structure: TopologyStructureV1_1_33::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct ReplySurbsV1_1_33 { + /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. + /// It can only allow to go below that value if its to request additional reply surbs. + pub minimum_reply_surb_storage_threshold: usize, + + /// Defines the maximum number of reply surbs the client wants to keep in its storage at any times. + pub maximum_reply_surb_storage_threshold: usize, + + /// Defines the minimum number of reply surbs the client would request. + pub minimum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs the client would request. + pub maximum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. + pub maximum_allowed_reply_surb_request_size: u32, + + /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking + /// for more even though in theory they wouldn't need to. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_rerequest_waiting_period: Duration, + + /// Defines maximum amount of time the client is going to wait for reply surbs before + /// deciding it's never going to get them and would drop all pending messages + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_drop_waiting_period: Duration, + + /// Defines maximum amount of time given reply surb is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_age: Duration, + + /// Defines maximum amount of time given reply key is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_key_age: Duration, + + /// Specifies the number of mixnet hops the packet should go through. If not specified, then + /// the default value is used. + pub surb_mix_hops: Option<u8>, +} + +impl Default for ReplySurbsV1_1_33 { + fn default() -> Self { + ReplySurbsV1_1_33 { + minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, + maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, + minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, + maximum_reply_surb_rerequest_waiting_period: + DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD, + maximum_reply_surb_drop_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD, + maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE, + maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE, + surb_mix_hops: None, + } + } +} + +#[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct DebugConfigV1_1_33 { + /// Defines all configuration options related to traffic streams. + pub traffic: TrafficV1_1_33, + + /// Defines all configuration options related to cover traffic stream(s). + pub cover_traffic: CoverTrafficV1_1_33, + + /// Defines all configuration options related to the gateway connection. + pub gateway_connection: GatewayConnectionV1_1_33, + + /// Defines all configuration options related to acknowledgements, such as delays or wait timeouts. + pub acknowledgements: AcknowledgementsV1_1_33, + + /// Defines all configuration options related topology, such as refresh rates or timeouts. + pub topology: TopologyV1_1_33, + + /// Defines all configuration options related to reply SURBs. + pub reply_surbs: ReplySurbsV1_1_33, +} diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index e4496e461a..3d931bf3ce 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -113,6 +113,9 @@ pub enum ClientCoreError { #[error("the provided gateway details (for gateway {gateway_id}) do not correspond to the shared keys")] MismatchedGatewayDetails { gateway_id: String }, + #[error("unable to upgrade config file from `{current_version}`")] + ConfigFileUpgradeFailure { current_version: String }, + #[error("unable to upgrade config file to `{new_version}`")] UnableToUpgradeConfigFile { new_version: String }, From a3132b907ada02c7c8d470a174cf400102df7964 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 16:12:03 +0000 Subject: [PATCH 289/394] further propagation of new gateway/key types --- .../src/backend/fs_backend/mod.rs | 12 +- .../src/backend/mem_backend.rs | 12 +- .../client-core/gateways-storage/src/lib.rs | 14 +- .../client-core/gateways-storage/src/types.rs | 31 ++ .../src/cli_helpers/client_init.rs | 40 +- .../client-core/src/client/base_client/mod.rs | 46 +- .../base_client/storage/gateway_details.rs | 77 ++- .../src/client/base_client/storage/mod.rs | 3 +- .../client-core/src/client/key_manager/mod.rs | 500 +++++++++--------- .../src/client/key_manager/persistence.rs | 4 - common/client-core/src/config/mod.rs | 3 + common/client-core/src/error.rs | 41 +- common/client-core/src/init/helpers.rs | 15 +- common/client-core/src/init/mod.rs | 206 +++++--- common/client-core/src/init/types.rs | 346 +++++++----- .../client-libs/gateway-client/src/client.rs | 25 +- .../crypto/src/asymmetric/encryption/mod.rs | 15 + common/crypto/src/asymmetric/identity/mod.rs | 15 + common/nymsphinx/acknowledgements/src/key.rs | 15 + 19 files changed, 858 insertions(+), 562 deletions(-) diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 6364bd376b..8aa5c3ff9d 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::GatewayDetails; +use crate::types::{GatewayDetails, GatewayRegistration}; use crate::{GatewaysDetailsStore, StorageError}; use async_trait::async_trait; use manager::StorageManager; @@ -26,8 +26,10 @@ impl OnDiskGatewaysDetails { #[async_trait] impl GatewaysDetailsStore for OnDiskGatewaysDetails { type StorageError = error::StorageError; - - async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { + todo!() + } + async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { todo!() } @@ -35,14 +37,14 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { todo!() } - async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { + async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { todo!() } async fn load_gateway_details( &self, gateway_id: &str, - ) -> Result<GatewayDetails, Self::StorageError> { + ) -> Result<GatewayRegistration, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 2d955f6c20..003284622e 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::GatewayDetails; +use crate::types::{GatewayDetails, GatewayRegistration}; use crate::{BadGateway, GatewaysDetailsStore}; use async_trait::async_trait; use std::collections::HashMap; @@ -33,8 +33,10 @@ struct InMemStorageInner { #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GatewaysDetailsStore for InMemGatewaysDetails { type StorageError = InMemStorageError; - - async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError> { + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { + todo!() + } + async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { // let guard = self.inner.read().await; // // let foo = guard.active_gateway.map(|id| { @@ -51,14 +53,14 @@ impl GatewaysDetailsStore for InMemGatewaysDetails { todo!() } - async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError> { + async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { todo!() } async fn load_gateway_details( &self, gateway_id: &str, - ) -> Result<GatewayDetails, Self::StorageError> { + ) -> Result<GatewayRegistration, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 4a64ab354c..0c11b51f52 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -12,7 +12,10 @@ pub mod error; pub mod types; // todo: export port types -pub use crate::types::GatewayDetails; +pub use crate::types::{ + CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, RegisteredGateway, + RemoteGatewayDetails, +}; pub use backend::mem_backend::{InMemGatewaysDetails, InMemStorageError}; pub use error::BadGateway; @@ -25,19 +28,22 @@ pub trait GatewaysDetailsStore { type StorageError: Error + From<error::BadGateway>; /// Returns details of the currently active gateway, if available. - async fn active_gateway(&self) -> Result<Option<GatewayDetails>, Self::StorageError>; + async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError>; /// Set the provided gateway as the currently active gateway. async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError>; /// Returns details of all registered gateways. - async fn all_gateways(&self) -> Result<Vec<GatewayDetails>, Self::StorageError>; + async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError>; + + /// Check if the gateway with the provided id already exists in the store. + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError>; /// Returns details of the particular gateway. async fn load_gateway_details( &self, gateway_id: &str, - ) -> Result<GatewayDetails, Self::StorageError>; + ) -> Result<GatewayRegistration, Self::StorageError>; /// Store the provided gateway details. async fn store_gateway_details( diff --git a/common/client-core/gateways-storage/src/types.rs b/common/client-core/gateways-storage/src/types.rs index 383500284f..abb20708a3 100644 --- a/common/client-core/gateways-storage/src/types.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -31,7 +31,34 @@ pub enum GatewayDetails { Custom(CustomGatewayDetails), } +impl From<GatewayDetails> for GatewayRegistration { + fn from(details: GatewayDetails) -> Self { + GatewayRegistration { + details, + registration_timestamp: OffsetDateTime::now_utc(), + } + } +} + impl GatewayDetails { + pub fn new_remote( + gateway_id: identity::PublicKey, + derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>, + gateway_owner_address: AccountId, + gateway_listener: Url, + ) -> Self { + GatewayDetails::Remote(RemoteGatewayDetails { + gateway_id, + derived_aes128_ctr_blake3_hmac_keys, + gateway_owner_address, + gateway_listener, + }) + } + + pub fn new_custom(gateway_id: identity::PublicKey, data: Option<Vec<u8>>) -> Self { + GatewayDetails::Custom(CustomGatewayDetails { gateway_id, data }) + } + pub fn gateway_id(&self) -> identity::PublicKey { match self { GatewayDetails::Remote(details) => details.gateway_id, @@ -45,6 +72,10 @@ impl GatewayDetails { GatewayDetails::Custom(_) => None, } } + + pub fn is_custom(&self) -> bool { + matches!(self, GatewayDetails::Custom(..)) + } } #[derive(Debug, Copy, Clone, Default)] diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 3317aa4df7..9c93cd1729 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -8,11 +8,13 @@ use crate::{ base_client::non_wasm_helpers::setup_fs_gateways_storage, key_manager::persistence::OnDiskKeys, }, - init::types::{GatewayDetails, GatewaySelectionSpecification, GatewaySetup, InitResults}, + init::types::{GatewaySelectionSpecification, GatewaySetup, InitResults}, }; use log::info; +use nym_client_core_gateways_storage::GatewayDetails; use nym_crypto::asymmetric::identity; use nym_topology::NymTopology; +use rand::rngs::OsRng; use std::path::{Path, PathBuf}; pub trait InitialisableClient { @@ -133,6 +135,10 @@ where eprintln!("{} client \"{id}\" was already initialised before", C::NAME); true } else { + info!( + "{} client {id:?} hasn't been initialised before - new keys are going to be generated", + C::NAME + ); C::initialise_storage_paths(id)?; false }; @@ -144,14 +150,6 @@ where eprintln!("Instructed to force registering gateway. This might overwrite keys!"); } - // TODO: look at the registration logic due to being able to store multiple gws now - let unused_variable = 42; - - // If the client was already initialized, don't generate new keys and don't re-register with - // the gateway (because this would create a new shared key). - // Unless the user really wants to. - let register_gateway = !already_init || user_wants_force_register; - // Attempt to use a user-provided gateway, if possible let user_chosen_gateway_id = common_args.gateway; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); @@ -180,9 +178,16 @@ where .join(",") ); + let key_store = OnDiskKeys::new(paths.keys.clone()); + + // if this is a first time client with this particular id is initialised, generated long-term keys + if !already_init { + let mut rng = OsRng; + crate::init::generate_new_client_keys(&mut rng, &key_store).await?; + } + // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. - let key_store = OnDiskKeys::new(paths.keys.clone()); let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { @@ -198,10 +203,12 @@ where crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? }; + todo!("remove registered gateways from the list"); + let gateway_setup = GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: register_gateway, + overwrite_data: common_args.force_register_gateway, }; let init_details = @@ -225,12 +232,17 @@ where config_save_location.display() ); - let address = init_details.client_address()?; + let address = init_details.client_address(); - let GatewayDetails::Configured(gateway_details) = init_details.gateway_details else { + let GatewayDetails::Remote(gateway_details) = init_details.gateway_registration.details else { return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; }; - let init_results = InitResults::new(config.core_config(), address, &gateway_details); + let init_results = InitResults::new( + config.core_config(), + address, + &gateway_details, + init_details.gateway_registration.registration_timestamp, + ); Ok(InitResultsWithConfig { config, diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 41c9a3f01b..c2400a7dc5 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -29,17 +29,17 @@ use crate::config::{Config, DebugConfig}; use crate::error::ClientCoreError; use crate::init::{ setup_gateway, - types::{GatewayDetails, GatewaySetup, InitialisationResult}, + types::{GatewaySetup, InitialisationResult}, }; use crate::{config, spawn_future}; use futures::channel::mpsc; use log::{debug, error, info}; use nym_bandwidth_controller::BandwidthController; -use nym_client_core_gateways_storage::GatewaysDetailsStore; +use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore}; use nym_credential_storage::storage::Storage as CredentialStorage; use nym_crypto::asymmetric::encryption; use nym_gateway_client::{ - AcknowledgementReceiver, GatewayClient, MixnetMessageReceiver, PacketRouter, + AcknowledgementReceiver, GatewayClient, GatewayConfig, MixnetMessageReceiver, PacketRouter, }; use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::addressing::clients::Recipient; @@ -201,7 +201,7 @@ where custom_topology_provider: None, custom_gateway_transceiver: None, shutdown: None, - setup_method: GatewaySetup::MustLoad, + setup_method: GatewaySetup::MustLoad { gateway_id: None }, } } @@ -250,13 +250,7 @@ where // note: do **NOT** make this method public as its only valid usage is from within `start_base` // because it relies on the crypto keys being already loaded fn mix_address(details: &InitialisationResult) -> Recipient { - Recipient::new( - *details.managed_keys.identity_public_key(), - *details.managed_keys.encryption_public_key(), - // TODO: below only works under assumption that gateway address == gateway id - // (which currently is true) - NodeIdentity::from_base58_string(details.gateway_details.gateway_id()).unwrap(), - ) + details.client_address() } // future constantly pumping loop cover traffic at some specified average rate @@ -355,8 +349,8 @@ where <S::KeyStore as KeyStore>::StorageError: Send + Sync + 'static, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync + 'static, { - let managed_keys = initialisation_result.managed_keys; - let GatewayDetails::Configured(gateway_config) = initialisation_result.gateway_details + let managed_keys = initialisation_result.client_keys; + let GatewayDetails::Remote(details) = initialisation_result.gateway_registration.details else { return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails); }; @@ -365,11 +359,15 @@ where if let Some(existing_client) = initialisation_result.authenticated_ephemeral_client { existing_client.upgrade(packet_router, bandwidth_controller, shutdown) } else { - let cfg = gateway_config.try_into()?; + let cfg = GatewayConfig::new( + details.gateway_id, + Some(details.gateway_owner_address.to_string()), + details.gateway_listener.to_string(), + ); GatewayClient::new( cfg, managed_keys.identity_keypair(), - Some(managed_keys.must_get_gateway_shared_key()), + Some(details.derived_aes128_ctr_blake3_hmac_keys), packet_router, bandwidth_controller, shutdown, @@ -378,21 +376,17 @@ where .with_response_timeout(config.debug.gateway_connection.gateway_response_timeout) }; - let gateway_id = gateway_client.gateway_identity(); - - let shared_key = gateway_client + gateway_client .authenticate_and_start() .await .map_err(|err| { log::error!("Could not authenticate and start up the gateway connection - {err}"); ClientCoreError::GatewayClientError { - gateway_id: gateway_id.to_base58_string(), + gateway_id: details.gateway_id.to_base58_string(), source: err, } })?; - managed_keys.ensure_gateway_key(Some(shared_key)); - Ok(gateway_client) } @@ -410,7 +404,11 @@ where { // if we have setup custom gateway sender and persisted details agree with it, return it if let Some(mut custom_gateway_transceiver) = custom_gateway_transceiver { - return if !initialisation_result.gateway_details.is_custom() { + return if !initialisation_result + .gateway_registration + .details + .is_custom() + { Err(ClientCoreError::CustomGatewaySelectionExpected) } else { // and make sure to invalidate the task client so we wouldn't cause premature shutdown @@ -633,8 +631,8 @@ where reply_controller::requests::new_control_channels(); let self_address = Self::mix_address(&init_res); - let ack_key = init_res.managed_keys.ack_key(); - let encryption_keys = init_res.managed_keys.encryption_keypair(); + let ack_key = init_res.client_keys.ack_key(); + let encryption_keys = init_res.client_keys.encryption_keypair(); // the components are started in very specific order. Unless you know what you are doing, // do not change that. diff --git a/common/client-core/src/client/base_client/storage/gateway_details.rs b/common/client-core/src/client/base_client/storage/gateway_details.rs index 152ef96283..552de2dbbd 100644 --- a/common/client-core/src/client/base_client/storage/gateway_details.rs +++ b/common/client-core/src/client/base_client/storage/gateway_details.rs @@ -3,7 +3,6 @@ use crate::config::GatewayEndpointConfig; use crate::error::ClientCoreError; -use crate::init::types::GatewayDetails; use async_trait::async_trait; use log::error; use nym_gateway_requests::registration::handshake::SharedKeys; @@ -108,44 +107,44 @@ impl PersistedGatewayConfig { } impl PersistedGatewayDetails { - pub fn new( - details: GatewayDetails, - shared_key: Option<&SharedKeys>, - ) -> Result<Self, ClientCoreError> { - match details { - GatewayDetails::Configured(cfg) => { - let shared_key = shared_key.ok_or(ClientCoreError::UnavailableSharedKey)?; - Ok(PersistedGatewayDetails::Default( - PersistedGatewayConfig::new(cfg, shared_key), - )) - } - GatewayDetails::Custom(custom) => Ok(PersistedGatewayDetails::Custom(custom.into())), - } - } - - pub fn is_custom(&self) -> bool { - matches!(self, PersistedGatewayDetails::Custom(..)) - } - - pub fn matches(&self, other: &GatewayDetails) -> bool { - match self { - PersistedGatewayDetails::Default(default) => { - if let GatewayDetails::Configured(other_configured) = other { - &default.details == other_configured - } else { - false - } - } - PersistedGatewayDetails::Custom(custom) => { - if let GatewayDetails::Custom(other_custom) = other { - custom.gateway_id == other_custom.gateway_id - && custom.additional_data == other_custom.additional_data - } else { - false - } - } - } - } + // pub fn new( + // details: GatewayDetails, + // shared_key: Option<&SharedKeys>, + // ) -> Result<Self, ClientCoreError> { + // match details { + // GatewayDetails::Configured(cfg) => { + // let shared_key = shared_key.ok_or(ClientCoreError::UnavailableSharedKey)?; + // Ok(PersistedGatewayDetails::Default( + // PersistedGatewayConfig::new(cfg, shared_key), + // )) + // } + // GatewayDetails::Custom(custom) => Ok(PersistedGatewayDetails::Custom(custom.into())), + // } + // } + // + // pub fn is_custom(&self) -> bool { + // matches!(self, PersistedGatewayDetails::Custom(..)) + // } + // + // pub fn matches(&self, other: &GatewayDetails) -> bool { + // match self { + // PersistedGatewayDetails::Default(default) => { + // if let GatewayDetails::Configured(other_configured) = other { + // &default.details == other_configured + // } else { + // false + // } + // } + // PersistedGatewayDetails::Custom(custom) => { + // if let GatewayDetails::Custom(other_custom) = other { + // custom.gateway_id == other_custom.gateway_id + // && custom.additional_data == other_custom.additional_data + // } else { + // false + // } + // } + // } + // } } // helper to make Vec<u8> serialization use base64 representation to make it human readable diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 969b60d617..86180b99eb 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -10,6 +10,7 @@ use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::replies::reply_storage; use crate::client::replies::reply_storage::ReplyStorageBackend; +use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; @@ -37,8 +38,6 @@ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentC #[deprecated] pub mod gateway_details; -pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; - #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; diff --git a/common/client-core/src/client/key_manager/mod.rs b/common/client-core/src/client/key_manager/mod.rs index f01f8e2fbb..b15ca52f44 100644 --- a/common/client-core/src/client/key_manager/mod.rs +++ b/common/client-core/src/client/key_manager/mod.rs @@ -12,218 +12,223 @@ use zeroize::ZeroizeOnDrop; pub mod persistence; -pub enum ManagedKeys { - Initial(KeyManagerBuilder), - FullyDerived(KeyManager), - - // I really hate the existence of this variant, but I couldn't come up with a better way to handle - // `Self::deal_with_gateway_key` otherwise. - Invalidated, +pub struct ManagedKeys { + client_keys: KeyManager, + active_gateway_keys: Option<Arc<SharedKeys>>, } - -impl Debug for ManagedKeys { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - match self { - ManagedKeys::Initial(_) => write!(f, "initial"), - ManagedKeys::FullyDerived(_) => write!(f, "fully derived"), - ManagedKeys::Invalidated => write!(f, "invalidated"), - } - } -} - -impl From<KeyManagerBuilder> for ManagedKeys { - fn from(value: KeyManagerBuilder) -> Self { - ManagedKeys::Initial(value) - } -} - -impl From<KeyManager> for ManagedKeys { - fn from(value: KeyManager) -> Self { - ManagedKeys::FullyDerived(value) - } -} - +// +// pub enum ManagedKeys { +// Initial(KeyManagerBuilder), +// FullyDerived(KeyManager), +// +// // I really hate the existence of this variant, but I couldn't come up with a better way to handle +// // `Self::deal_with_gateway_key` otherwise. +// Invalidated, +// } +// +// impl Debug for ManagedKeys { +// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +// match self { +// ManagedKeys::Initial(_) => write!(f, "initial"), +// ManagedKeys::FullyDerived(_) => write!(f, "fully derived"), +// ManagedKeys::Invalidated => write!(f, "invalidated"), +// } +// } +// } +// +// impl From<KeyManagerBuilder> for ManagedKeys { +// fn from(value: KeyManagerBuilder) -> Self { +// ManagedKeys::Initial(value) +// } +// } +// +// impl From<KeyManager> for ManagedKeys { +// fn from(value: KeyManager) -> Self { +// ManagedKeys::FullyDerived(value) +// } +// } +// impl ManagedKeys { - pub fn is_valid(&self) -> bool { - !matches!(self, ManagedKeys::Invalidated) - } - - pub async fn try_load<S: KeyStore>(key_store: &S) -> Result<Self, S::StorageError> { - Ok(ManagedKeys::FullyDerived( - KeyManager::load_keys(key_store).await?, - )) - } - - pub fn generate_new<R>(rng: &mut R) -> Self - where - R: RngCore + CryptoRng, - { - ManagedKeys::Initial(KeyManagerBuilder::new(rng)) - } - - pub async fn load_or_generate<R, S>(rng: &mut R, key_store: &S) -> Self - where - R: RngCore + CryptoRng, - S: KeyStore, - { - Self::try_load(key_store) - .await - .unwrap_or_else(|_| Self::generate_new(rng)) - } - - pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { - match self { - ManagedKeys::Initial(keys) => keys.identity_keypair(), - ManagedKeys::FullyDerived(keys) => keys.identity_keypair(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { - match self { - ManagedKeys::Initial(keys) => keys.encryption_keypair(), - ManagedKeys::FullyDerived(keys) => keys.encryption_keypair(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn ack_key(&self) -> Arc<AckKey> { - match self { - ManagedKeys::Initial(keys) => keys.ack_key(), - ManagedKeys::FullyDerived(keys) => keys.ack_key(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn must_get_gateway_shared_key(&self) -> Arc<SharedKeys> { - self.gateway_shared_key() - .expect("failed to extract gateway shared key") - } - - pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { - match self { - ManagedKeys::Initial(_) => None, - ManagedKeys::FullyDerived(keys) => keys.gateway_shared_key(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn identity_public_key(&self) -> &identity::PublicKey { - match self { - ManagedKeys::Initial(keys) => keys.identity_keypair.public_key(), - ManagedKeys::FullyDerived(keys) => keys.identity_keypair.public_key(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn encryption_public_key(&self) -> &encryption::PublicKey { - match self { - ManagedKeys::Initial(keys) => keys.encryption_keypair.public_key(), - ManagedKeys::FullyDerived(keys) => keys.encryption_keypair.public_key(), - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - } - } - - pub fn ensure_gateway_key(&self, gateway_shared_key: Option<Arc<SharedKeys>>) { - if let ManagedKeys::FullyDerived(key_manager) = &self { - if self.gateway_shared_key().is_none() && gateway_shared_key.is_none() { - // the key doesn't exist in either state - return; - } - - if gateway_shared_key.is_some() && self.gateway_shared_key().is_none() - || gateway_shared_key.is_none() && self.gateway_shared_key().is_some() - { - // if one is provided whilst the other is not... - // TODO: should this actually panic or return an error? would this branch be possible - // under normal operation? - panic!("inconsistent re-derived gateway key") - } - - // here we know both keys MUST exist - let provided = gateway_shared_key.unwrap(); - if !Arc::ptr_eq(key_manager.must_get_gateway_shared_key(), &provided) - || *key_manager.must_get_gateway_shared_key() != provided - { - // this should NEVER happen thus panic here - panic!("derived fresh gateway shared key whilst already holding one!") - } - } - } - - pub async fn deal_with_gateway_key<S: KeyStore>( - &mut self, - gateway_shared_key: Option<Arc<SharedKeys>>, - key_store: &S, - ) -> Result<(), S::StorageError> { - let key_manager = match std::mem::replace(self, ManagedKeys::Invalidated) { - ManagedKeys::Initial(keys) => { - let key_manager = keys.insert_maybe_gateway_shared_key(gateway_shared_key); - key_manager.persist_keys(key_store).await?; - key_manager - } - ManagedKeys::FullyDerived(key_manager) => { - self.ensure_gateway_key(gateway_shared_key); - key_manager - } - ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - }; - - *self = ManagedKeys::FullyDerived(key_manager); - Ok(()) - } -} - -// all of the keys really shouldn't be wrapped in `Arc`, but due to how the gateway client is currently -// constructed, changing that would require more work than what it's worth -pub struct KeyManagerBuilder { - /// identity key associated with the client instance. - identity_keypair: Arc<identity::KeyPair>, - - /// encryption key associated with the client instance. - encryption_keypair: Arc<encryption::KeyPair>, - - /// key used for producing and processing acknowledgement packets. - ack_key: Arc<AckKey>, -} - -impl KeyManagerBuilder { - /// Creates new instance of a [`KeyManager`] - pub fn new<R>(rng: &mut R) -> Self - where - R: RngCore + CryptoRng, - { - KeyManagerBuilder { - identity_keypair: Arc::new(identity::KeyPair::new(rng)), - encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), - ack_key: Arc::new(AckKey::new(rng)), - } - } - - pub fn insert_maybe_gateway_shared_key( - self, - gateway_shared_key: Option<Arc<SharedKeys>>, - ) -> KeyManager { - KeyManager { - identity_keypair: self.identity_keypair, - encryption_keypair: self.encryption_keypair, - gateway_shared_key, - ack_key: self.ack_key, - } - } - - pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { - Arc::clone(&self.identity_keypair) - } - - pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { - Arc::clone(&self.encryption_keypair) - } - - pub fn ack_key(&self) -> Arc<AckKey> { - Arc::clone(&self.ack_key) - } + // pub fn is_valid(&self) -> bool { + // !matches!(self, ManagedKeys::Invalidated) + // } + // + // pub async fn try_load<S: KeyStore>(key_store: &S) -> Result<Self, S::StorageError> { + // Ok(ManagedKeys::FullyDerived( + // KeyManager::load_keys(key_store).await?, + // )) + // } + // + // pub fn generate_new<R>(rng: &mut R) -> Self + // where + // R: RngCore + CryptoRng, + // { + // ManagedKeys::Initial(KeyManagerBuilder::new(rng)) + // } + // + // pub async fn load_or_generate<R, S>(rng: &mut R, key_store: &S) -> Self + // where + // R: RngCore + CryptoRng, + // S: KeyStore, + // { + // Self::try_load(key_store) + // .await + // .unwrap_or_else(|_| Self::generate_new(rng)) + // } + // + // pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { + // match self { + // ManagedKeys::Initial(keys) => keys.identity_keypair(), + // ManagedKeys::FullyDerived(keys) => keys.identity_keypair(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { + // match self { + // ManagedKeys::Initial(keys) => keys.encryption_keypair(), + // ManagedKeys::FullyDerived(keys) => keys.encryption_keypair(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn ack_key(&self) -> Arc<AckKey> { + // match self { + // ManagedKeys::Initial(keys) => keys.ack_key(), + // ManagedKeys::FullyDerived(keys) => keys.ack_key(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn must_get_gateway_shared_key(&self) -> Arc<SharedKeys> { + // self.gateway_shared_key() + // .expect("failed to extract gateway shared key") + // } + // + // pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { + // match self { + // ManagedKeys::Initial(_) => None, + // ManagedKeys::FullyDerived(keys) => keys.gateway_shared_key(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn identity_public_key(&self) -> &identity::PublicKey { + // match self { + // ManagedKeys::Initial(keys) => keys.identity_keypair.public_key(), + // ManagedKeys::FullyDerived(keys) => keys.identity_keypair.public_key(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn encryption_public_key(&self) -> &encryption::PublicKey { + // match self { + // ManagedKeys::Initial(keys) => keys.encryption_keypair.public_key(), + // ManagedKeys::FullyDerived(keys) => keys.encryption_keypair.public_key(), + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // } + // } + // + // pub fn ensure_gateway_key(&self, gateway_shared_key: Option<Arc<SharedKeys>>) { + // if let ManagedKeys::FullyDerived(key_manager) = &self { + // if self.gateway_shared_key().is_none() && gateway_shared_key.is_none() { + // // the key doesn't exist in either state + // return; + // } + // + // if gateway_shared_key.is_some() && self.gateway_shared_key().is_none() + // || gateway_shared_key.is_none() && self.gateway_shared_key().is_some() + // { + // // if one is provided whilst the other is not... + // // TODO: should this actually panic or return an error? would this branch be possible + // // under normal operation? + // panic!("inconsistent re-derived gateway key") + // } + // + // // here we know both keys MUST exist + // let provided = gateway_shared_key.unwrap(); + // if !Arc::ptr_eq(key_manager.must_get_gateway_shared_key(), &provided) + // || *key_manager.must_get_gateway_shared_key() != provided + // { + // // this should NEVER happen thus panic here + // panic!("derived fresh gateway shared key whilst already holding one!") + // } + // } + // } + // + // pub async fn deal_with_gateway_key<S: KeyStore>( + // &mut self, + // gateway_shared_key: Option<Arc<SharedKeys>>, + // key_store: &S, + // ) -> Result<(), S::StorageError> { + // let key_manager = match std::mem::replace(self, ManagedKeys::Invalidated) { + // ManagedKeys::Initial(keys) => { + // let key_manager = keys.insert_maybe_gateway_shared_key(gateway_shared_key); + // key_manager.persist_keys(key_store).await?; + // key_manager + // } + // ManagedKeys::FullyDerived(key_manager) => { + // self.ensure_gateway_key(gateway_shared_key); + // key_manager + // } + // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), + // }; + // + // *self = ManagedKeys::FullyDerived(key_manager); + // Ok(()) + // } } +// +// // all of the keys really shouldn't be wrapped in `Arc`, but due to how the gateway client is currently +// // constructed, changing that would require more work than what it's worth +// pub struct KeyManagerBuilder { +// /// identity key associated with the client instance. +// identity_keypair: Arc<identity::KeyPair>, +// +// /// encryption key associated with the client instance. +// encryption_keypair: Arc<encryption::KeyPair>, +// +// /// key used for producing and processing acknowledgement packets. +// ack_key: Arc<AckKey>, +// } +// +// impl KeyManagerBuilder { +// /// Creates new instance of a [`KeyManager`] +// pub fn new<R>(rng: &mut R) -> Self +// where +// R: RngCore + CryptoRng, +// { +// KeyManagerBuilder { +// identity_keypair: Arc::new(identity::KeyPair::new(rng)), +// encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), +// ack_key: Arc::new(AckKey::new(rng)), +// } +// } +// +// pub fn insert_maybe_gateway_shared_key( +// self, +// gateway_shared_key: Option<Arc<SharedKeys>>, +// ) -> KeyManager { +// KeyManager { +// identity_keypair: self.identity_keypair, +// encryption_keypair: self.encryption_keypair, +// gateway_shared_key, +// ack_key: self.ack_key, +// } +// } +// +// pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { +// Arc::clone(&self.identity_keypair) +// } +// +// pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { +// Arc::clone(&self.encryption_keypair) +// } +// +// pub fn ack_key(&self) -> Arc<AckKey> { +// Arc::clone(&self.ack_key) +// } +// } // Note: to support key rotation in the future, all keys will require adding an extra smart pointer, // most likely an AtomicCell, or if it doesn't work as I think it does, a Mutex. Although I think @@ -240,28 +245,39 @@ pub struct KeyManager { /// encryption key associated with the client instance. encryption_keypair: Arc<encryption::KeyPair>, - /// shared key derived with the gateway during "registration handshake" - // I'm not a fan of how we broke the nice transition of `KeyManagerBuilder` -> `KeyManager` - // by making this field optional. - // However, it has to be optional for when we use embedded NR inside a gateway, - // since it won't have a shared key (because why would it?) - gateway_shared_key: Option<Arc<SharedKeys>>, - + // /// shared key derived with the gateway during "registration handshake" + // // I'm not a fan of how we broke the nice transition of `KeyManagerBuilder` -> `KeyManager` + // // by making this field optional. + // // However, it has to be optional for when we use embedded NR inside a gateway, + // // since it won't have a shared key (because why would it?) + // gateway_shared_key: Option<Arc<SharedKeys>>, /// key used for producing and processing acknowledgement packets. ack_key: Arc<AckKey>, } impl KeyManager { + /// Creates new instance of a [`KeyManager`] + pub fn generate_new<R>(rng: &mut R) -> Self + where + R: RngCore + CryptoRng, + { + KeyManager { + identity_keypair: Arc::new(identity::KeyPair::new(rng)), + encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), + ack_key: Arc::new(AckKey::new(rng)), + } + } + pub fn from_keys( id_keypair: identity::KeyPair, enc_keypair: encryption::KeyPair, - gateway_shared_key: Option<SharedKeys>, + // gateway_shared_key: Option<SharedKeys>, ack_key: AckKey, ) -> Self { Self { identity_keypair: Arc::new(id_keypair), encryption_keypair: Arc::new(enc_keypair), - gateway_shared_key: gateway_shared_key.map(Arc::new), + // gateway_shared_key: gateway_shared_key.map(Arc::new), ack_key: Arc::new(ack_key), } } @@ -288,31 +304,31 @@ impl KeyManager { Arc::clone(&self.ack_key) } - fn must_get_gateway_shared_key(&self) -> &Arc<SharedKeys> { - self.gateway_shared_key - .as_ref() - .expect("gateway shared key is unavailable") - } + // fn must_get_gateway_shared_key(&self) -> &Arc<SharedKeys> { + // self.gateway_shared_key + // .as_ref() + // .expect("gateway shared key is unavailable") + // } + // + // pub fn uses_custom_gateway(&self) -> bool { + // self.gateway_shared_key.is_none() + // } + // + // /// Gets an atomically reference counted pointer to [`SharedKey`]. + // pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { + // self.gateway_shared_key.as_ref().map(Arc::clone) + // } - pub fn uses_custom_gateway(&self) -> bool { - self.gateway_shared_key.is_none() - } - - /// Gets an atomically reference counted pointer to [`SharedKey`]. - pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { - self.gateway_shared_key.clone() - } - - pub fn remove_gateway_key(self) -> KeyManagerBuilder { - if Arc::strong_count(self.must_get_gateway_shared_key()) > 1 { - panic!("attempted to remove gateway key whilst still holding multiple references!") - } - KeyManagerBuilder { - identity_keypair: self.identity_keypair, - encryption_keypair: self.encryption_keypair, - ack_key: self.ack_key, - } - } + // pub fn remove_gateway_key(self) -> KeyManagerBuilder { + // if Arc::strong_count(self.must_get_gateway_shared_key()) > 1 { + // panic!("attempted to remove gateway key whilst still holding multiple references!") + // } + // KeyManagerBuilder { + // identity_keypair: self.identity_keypair, + // encryption_keypair: self.encryption_keypair, + // ack_key: self.ack_key, + // } + // } } fn _assert_keys_zeroize_on_drop() { diff --git a/common/client-core/src/client/key_manager/persistence.rs b/common/client-core/src/client/key_manager/persistence.rs index 00041206db..a7a4196d30 100644 --- a/common/client-core/src/client/key_manager/persistence.rs +++ b/common/client-core/src/client/key_manager/persistence.rs @@ -151,20 +151,16 @@ impl OnDiskKeys { fn load_keys(&self) -> Result<KeyManager, OnDiskKeysError> { let identity_keypair = self.load_identity_keypair()?; let encryption_keypair = self.load_encryption_keypair()?; - let ack_key: AckKey = self.load_key(self.paths.ack_key(), "ack key")?; Ok(KeyManager::from_keys( identity_keypair, encryption_keypair, - None, ack_key, )) } fn store_keys(&self, keys: &KeyManager) -> Result<(), OnDiskKeysError> { - use std::ops::Deref; - let identity_paths = self.paths.identity_key_pair_path(); let encryption_paths = self.paths.encryption_key_pair_path(); diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 96615d3be4..1fd2cf26f3 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -232,6 +232,7 @@ impl Config { } } +#[deprecated] #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] #[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] pub struct GatewayEndpointConfig { @@ -259,6 +260,7 @@ impl TryFrom<GatewayEndpointConfig> for GatewayConfig { } } +#[deprecated] #[cfg_attr(target_arch = "wasm32", wasm_bindgen)] impl GatewayEndpointConfig { #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] @@ -276,6 +278,7 @@ impl GatewayEndpointConfig { } // separate block so it wouldn't be exported via wasm bindgen +#[deprecated] impl GatewayEndpointConfig { pub fn try_get_gateway_identity_key(&self) -> Result<identity::PublicKey, ClientCoreError> { identity::PublicKey::from_base58_string(&self.gateway_id) diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 3d931bf3ce..72fcf7762e 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -4,6 +4,7 @@ use crate::client::mix_traffic::transceiver::ErasedGatewayError; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_gateway_client::error::GatewayClientError; +use nym_gateway_requests::registration::handshake::shared_key::SharedKeyConversionError; use nym_topology::gateway::GatewayConversionError; use nym_topology::NymTopologyError; use nym_validator_client::ValidatorClientError; @@ -94,13 +95,21 @@ pub enum ClientCoreError { #[error("unexpected exit")] UnexpectedExit, + #[error("this operation would have resulted in the gateway {gateway_id:?} key being overwritten without permission")] + ForbiddenGatewayKeyOverwrite { gateway_id: String }, + #[error( "this operation would have resulted in clients keys being overwritten without permission" )] ForbiddenKeyOverwrite, - #[error("gateway details are unavailable")] + #[error("the client doesn't have any gateway set as active")] + NoActiveGatewaySet, + + #[error("gateway details for gateway {gateway_id:?} are unavailable")] UnavailableGatewayDetails { + gateway_id: String, + #[source] source: Box<dyn Error + Send + Sync>, }, @@ -156,6 +165,36 @@ pub enum ClientCoreError { #[source] source: std::io::Error, }, + + #[error("the provided gateway identity {gateway_id} is malformed: {source}")] + MalformedGatewayIdentity { + gateway_id: String, + + #[source] + source: Ed25519RecoveryError, + }, + + #[error("the account owner of gateway {gateway_id} ({raw_owner}) is malformed: {err}")] + MalformedGatewayOwnerAccountAddress { + gateway_id: String, + + raw_owner: String, + + // just use the string formatting as opposed to underlying type to avoid having to import cosmrs + err: String, + }, + + #[error( + "the listening address of gateway {gateway_id} ({raw_listener}) is malformed: {source}" + )] + MalformedListener { + gateway_id: String, + + raw_listener: String, + + #[source] + source: url::ParseError, + }, } /// Set of messages that the client can send to listeners via the task manager diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index 06c5c8ef59..a0c7c6c8de 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -25,6 +25,7 @@ use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; #[cfg(not(target_arch = "wasm32"))] type WsConn = WebSocketStream<MaybeTlsStream<TcpStream>>; use nym_validator_client::client::IdentityKeyRef; +use nym_validator_client::nyxd::AccountId; #[cfg(not(target_arch = "wasm32"))] use tokio::time::sleep; @@ -278,16 +279,17 @@ pub(super) fn get_specified_gateway( } pub(super) async fn register_with_gateway( - gateway: &GatewayEndpointConfig, + gateway_id: identity::PublicKey, + gateway_listener: Url, our_identity: Arc<identity::KeyPair>, ) -> Result<RegistrationResult, ClientCoreError> { let mut gateway_client = - GatewayClient::new_init(gateway.to_owned().try_into()?, our_identity.clone()); + GatewayClient::new_init(gateway_listener, gateway_id, our_identity.clone()); gateway_client.establish_connection().await.map_err(|err| { log::warn!("Failed to establish connection with gateway!"); ClientCoreError::GatewayClientError { - gateway_id: gateway.gateway_id.clone(), + gateway_id: gateway_id.to_base58_string(), source: err, } })?; @@ -295,12 +297,9 @@ pub(super) async fn register_with_gateway( .perform_initial_authentication() .await .map_err(|err| { - log::warn!( - "Failed to register with the gateway {}!", - gateway.gateway_id - ); + log::warn!("Failed to register with the gateway {gateway_id}: {err}"); ClientCoreError::GatewayClientError { - gateway_id: gateway.gateway_id.clone(), + gateway_id: gateway_id.to_base58_string(), source: err, } })?; diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 72b6f67996..38b5c398ab 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -1,25 +1,23 @@ -// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 //! Collection of initialization steps used by client implementations -use crate::client::base_client::storage::gateway_details::PersistedGatewayDetails; use crate::client::key_manager::persistence::KeyStore; -use crate::client::key_manager::ManagedKeys; -use crate::config::GatewayEndpointConfig; +use crate::client::key_manager::KeyManager; use crate::error::ClientCoreError; use crate::init::helpers::{ choose_gateway_by_latency, get_specified_gateway, uniformly_random_gateway, }; use crate::init::types::{ - CustomGatewayDetails, GatewayDetails, GatewaySelectionSpecification, GatewaySetup, - InitialisationResult, + GatewaySelectionSpecification, GatewaySetup, InitialisationResult, SelectedGateway, }; use nym_client_core_gateways_storage::GatewaysDetailsStore; +use nym_client_core_gateways_storage::{GatewayDetails, GatewayRegistration}; use nym_gateway_client::client::InitGatewayClient; use nym_topology::gateway; use rand::rngs::OsRng; -use serde::de::DeserializeOwned; +use rand::{CryptoRng, RngCore}; use serde::Serialize; use std::sync::Arc; @@ -29,7 +27,7 @@ pub mod types; // helpers for error wrapping async fn _store_gateway_details<D>( details_store: &D, - details: &PersistedGatewayDetails, + details: &GatewayDetails, ) -> Result<(), ClientCoreError> where D: GatewaysDetailsStore, @@ -44,41 +42,91 @@ where // }) } -async fn _load_gateway_details<D>( +async fn _load_active_gateway_details<D>( details_store: &D, -) -> Result<PersistedGatewayDetails, ClientCoreError> +) -> Result<GatewayRegistration, ClientCoreError> where D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, { - todo!() - // details_store - // .load_gateway_details() - // .await - // .map_err(|source| ClientCoreError::UnavailableGatewayDetails { - // source: Box::new(source), - // }) + details_store + .active_gateway() + .await + .map_err(|source| ClientCoreError::GatewayDetailsStoreError { + source: Box::new(source), + })? + .ok_or(ClientCoreError::NoActiveGatewaySet) } -async fn _load_managed_keys<K>(key_store: &K) -> Result<ManagedKeys, ClientCoreError> +async fn _load_gateway_details<D>( + details_store: &D, + gateway_id: &str, +) -> Result<GatewayRegistration, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .load_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::UnavailableGatewayDetails { + gateway_id: gateway_id.to_string(), + source: Box::new(source), + }) +} + +async fn _has_gateway_details<D>( + details_store: &D, + gateway_id: &str, +) -> Result<bool, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .has_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::GatewayDetailsStoreError { + source: Box::new(source), + }) +} + +async fn _load_client_keys<K>(key_store: &K) -> Result<KeyManager, ClientCoreError> where K: KeyStore, K::StorageError: Send + Sync + 'static, { - ManagedKeys::try_load(key_store) + KeyManager::load_keys(key_store) .await .map_err(|source| ClientCoreError::KeyStoreError { source: Box::new(source), }) } -fn ensure_valid_details( - details: &PersistedGatewayDetails, - loaded_keys: &ManagedKeys, -) -> Result<(), ClientCoreError> { - details.validate(loaded_keys.gateway_shared_key().as_deref()) +pub async fn generate_new_client_keys<K, R>( + rng: &mut R, + key_store: &K, +) -> Result<(), ClientCoreError> +where + R: RngCore + CryptoRng, + K: KeyStore, + K::StorageError: Send + Sync + 'static, +{ + KeyManager::generate_new(rng) + .persist_keys(key_store) + .await + .map_err(|source| ClientCoreError::KeyStoreError { + source: Box::new(source), + }) } +// fn ensure_valid_details( +// details: &PersistedGatewayDetails, +// loaded_keys: &ManagedKeys, +// ) -> Result<(), ClientCoreError> { +// details.validate(loaded_keys.gateway_shared_key().as_deref()) +// } + async fn setup_new_gateway<K, D>( key_store: &K, details_store: &D, @@ -94,6 +142,9 @@ where { log::trace!("Setting up new gateway"); + // if we're setting up new gateway, we must have had generated long-term client keys before + let client_keys = _load_client_keys(key_store).await?; + // if we're setting up new gateway, failing to load existing information is fine. // as a matter of fact, it's only potentially a problem if we DO succeed @@ -102,73 +153,83 @@ where // return Err(ClientCoreError::ForbiddenKeyOverwrite); // } - if _load_managed_keys(key_store).await.is_ok() && !overwrite_data { - return Err(ClientCoreError::ForbiddenKeyOverwrite); - } - let mut rng = OsRng; - let mut new_keys = ManagedKeys::generate_new(&mut rng); - let gateway_details = match selection_specification { + let selected_gateway = match selection_specification { GatewaySelectionSpecification::UniformRemote { must_use_tls } => { let gateway = uniformly_random_gateway(&mut rng, &available_gateways, must_use_tls)?; - GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls)?) + SelectedGateway::from_topology_node(gateway, must_use_tls)? } GatewaySelectionSpecification::RemoteByLatency { must_use_tls } => { let gateway = choose_gateway_by_latency(&mut rng, &available_gateways, must_use_tls).await?; - GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls)?) + SelectedGateway::from_topology_node(gateway, must_use_tls)? } GatewaySelectionSpecification::Specified { must_use_tls, identity, } => { let gateway = get_specified_gateway(&identity, &available_gateways, must_use_tls)?; - GatewayDetails::Configured(GatewayEndpointConfig::from_node(gateway, must_use_tls)?) + SelectedGateway::from_topology_node(gateway, must_use_tls)? } GatewaySelectionSpecification::Custom { gateway_identity, additional_data, - } => GatewayDetails::Custom(CustomGatewayDetails::new(gateway_identity, additional_data)), + } => SelectedGateway::custom(gateway_identity, additional_data)?, }; - let registration_result = if let GatewayDetails::Configured(gateway_cfg) = &gateway_details { - // if we're using a 'normal' gateway setup, do register - let our_identity = new_keys.identity_keypair(); - Some(helpers::register_with_gateway(gateway_cfg, our_identity).await?) - } else { - None + // check if we already have details associated with this particular gateway + // and if so, see if we can overwrite it + let selected_id = selected_gateway.gateway_id().to_base58_string(); + if _has_gateway_details(details_store, &selected_id).await? && !overwrite_data { + return Err(ClientCoreError::ForbiddenGatewayKeyOverwrite { + gateway_id: selected_id, + }); + } + + let (gateway_details, client) = match selected_gateway { + SelectedGateway::Remote { + gateway_id, + gateway_owner_address, + gateway_listener, + } => { + // if we're using a 'normal' gateway setup, do register + let our_identity = client_keys.identity_keypair(); + let registration = + helpers::register_with_gateway(gateway_id, gateway_listener, our_identity).await?; + ( + GatewayDetails::new_remote( + gateway_id, + registration.shared_keys, + gateway_owner_address, + gateway_listener, + ), + Some(registration.authenticated_ephemeral_client), + ) + } + SelectedGateway::Custom { + gateway_id, + additional_data, + } => ( + GatewayDetails::new_custom(gateway_id, additional_data), + None, + ), }; - let maybe_shared_keys = registration_result - .as_ref() - .map(|r| Arc::clone(&r.shared_keys)); - - let persisted_details = - PersistedGatewayDetails::new(gateway_details, maybe_shared_keys.as_deref())?; - - // persist the keys - new_keys - .deal_with_gateway_key(maybe_shared_keys, key_store) - .await - .map_err(|source| ClientCoreError::KeyStoreError { - source: Box::new(source), - })?; - - // persist gateway configs - _store_gateway_details(details_store, &persisted_details).await?; + // persist gateway details + _store_gateway_details(details_store, &gateway_details).await?; Ok(InitialisationResult { - gateway_details: persisted_details.into(), - managed_keys: new_keys, - authenticated_ephemeral_client: registration_result - .map(|r| r.authenticated_ephemeral_client), + gateway_registration: gateway_details.into(), + client_keys, + authenticated_ephemeral_client: client, }) } async fn use_loaded_gateway_details<K, D>( key_store: &K, details_store: &D, + gateway_id: Option<String>, ) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, @@ -176,26 +237,29 @@ where K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { - let loaded_details = _load_gateway_details(details_store).await?; - let loaded_keys = _load_managed_keys(key_store).await?; + let loaded_details = if let Some(gateway_id) = gateway_id { + _load_gateway_details(details_store, &gateway_id).await? + } else { + _load_active_gateway_details(details_store).await? + }; - ensure_valid_details(&loaded_details, &loaded_keys)?; + let loaded_keys = _load_client_keys(key_store).await?; // no need to persist anything as we got everything from the storage Ok(InitialisationResult::new_loaded( - loaded_details.into(), + loaded_details, loaded_keys, )) } fn reuse_gateway_connection( authenticated_ephemeral_client: InitGatewayClient, - gateway_details: GatewayDetails, - managed_keys: ManagedKeys, + gateway_registration: GatewayRegistration, + client_keys: KeyManager, ) -> InitialisationResult { InitialisationResult { - gateway_details, - managed_keys, + gateway_registration, + client_keys, authenticated_ephemeral_client: Some(authenticated_ephemeral_client), } } @@ -213,7 +277,9 @@ where { log::debug!("Setting up gateway"); match setup { - GatewaySetup::MustLoad => use_loaded_gateway_details(key_store, details_store).await, + GatewaySetup::MustLoad { gateway_id } => { + use_loaded_gateway_details(key_store, details_store, gateway_id).await + } GatewaySetup::New { specification, available_gateways, diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 9863fc7c07..563205eb22 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -1,24 +1,100 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, PersistedCustomGatewayDetails, PersistedGatewayDetails, -}; use crate::client::key_manager::persistence::KeyStore; -use crate::client::key_manager::ManagedKeys; +use crate::client::key_manager::{KeyManager, ManagedKeys}; use crate::config::{Config, GatewayEndpointConfig}; use crate::error::ClientCoreError; -use crate::init::{_load_gateway_details, _load_managed_keys, setup_gateway}; +use crate::init::{setup_gateway, use_loaded_gateway_details}; +use nym_client_core_gateways_storage::{ + BadGateway, GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails, +}; +use nym_crypto::asymmetric::identity; use nym_gateway_client::client::InitGatewayClient; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::nodes::NodeIdentity; use nym_topology::gateway; use nym_validator_client::client::IdentityKey; +use nym_validator_client::nyxd::AccountId; use serde::de::DeserializeOwned; use serde::{Deserialize, Serialize}; use std::fmt::Display; +use std::str::FromStr; use std::sync::Arc; +use time::OffsetDateTime; +use url::Url; + +pub enum SelectedGateway { + Remote { + gateway_id: identity::PublicKey, + + gateway_owner_address: AccountId, + + gateway_listener: Url, + }, + Custom { + gateway_id: identity::PublicKey, + additional_data: Option<Vec<u8>>, + }, +} + +impl SelectedGateway { + pub fn from_topology_node( + node: gateway::Node, + must_use_tls: bool, + ) -> Result<Self, ClientCoreError> { + let gateway_listener = if must_use_tls { + node.clients_address_tls() + .ok_or(ClientCoreError::UnsupportedWssProtocol { + gateway: node.identity_key.to_base58_string(), + })? + } else { + node.clients_address() + }; + + let gateway_owner_address = AccountId::from_str(&node.owner).map_err(|source| { + ClientCoreError::MalformedGatewayOwnerAccountAddress { + gateway_id: node.identity_key.to_base58_string(), + raw_owner: node.owner, + err: source.to_string(), + } + })?; + + let gateway_listener = + Url::parse(&gateway_listener).map_err(|source| ClientCoreError::MalformedListener { + gateway_id: node.identity_key.to_base58_string(), + raw_listener: gateway_listener, + source, + })?; + + Ok(SelectedGateway::Remote { + gateway_id: node.identity_key, + gateway_owner_address, + gateway_listener, + }) + } + + pub fn custom( + gateway_id: String, + additional_data: Option<Vec<u8>>, + ) -> Result<Self, ClientCoreError> { + let gateway_id = identity::PublicKey::from_base58_string(&gateway_id) + .map_err(|source| ClientCoreError::MalformedGatewayIdentity { gateway_id, source })?; + + Ok(SelectedGateway::Custom { + gateway_id, + additional_data, + }) + } + + pub fn gateway_id(&self) -> &identity::PublicKey { + match self { + SelectedGateway::Remote { gateway_id, .. } => gateway_id, + SelectedGateway::Custom { gateway_id, .. } => gateway_id, + } + } +} /// Result of registering with a gateway: /// - shared keys derived between ourselves and the node @@ -34,16 +110,16 @@ pub struct RegistrationResult { /// - an optional authenticated handle of an ephemeral gateway handle created for the purposes of registration, /// if this was the first time this client registered pub struct InitialisationResult { - pub gateway_details: GatewayDetails, - pub managed_keys: ManagedKeys, + pub gateway_registration: GatewayRegistration, + pub client_keys: KeyManager, pub authenticated_ephemeral_client: Option<InitGatewayClient>, } impl InitialisationResult { - pub fn new_loaded(gateway_details: GatewayDetails, managed_keys: ManagedKeys) -> Self { + pub fn new_loaded(gateway_registration: GatewayRegistration, client_keys: KeyManager) -> Self { InitialisationResult { - gateway_details, - managed_keys, + gateway_registration, + client_keys, authenticated_ephemeral_client: None, } } @@ -51,127 +127,106 @@ impl InitialisationResult { pub async fn try_load<K, D>(key_store: &K, details_store: &D) -> Result<Self, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore, + D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { - todo!() - // let loaded_details = _load_gateway_details(details_store).await?; - // let loaded_keys = _load_managed_keys(key_store).await?; - // - // match &loaded_details { - // PersistedGatewayDetails::Default(loaded_default) => { - // if !loaded_default.verify(&loaded_keys.must_get_gateway_shared_key()) { - // return Err(ClientCoreError::MismatchedGatewayDetails { - // gateway_id: loaded_default.details.gateway_id.clone(), - // }); - // } - // } - // PersistedGatewayDetails::Custom(_) => {} - // } - // - // Ok(InitialisationResult { - // gateway_details: loaded_details.into(), - // managed_keys: loaded_keys, - // authenticated_ephemeral_client: None, - // }) + use_loaded_gateway_details(key_store, details_store, None).await } - pub fn client_address(&self) -> Result<Recipient, ClientCoreError> { - let client_recipient = Recipient::new( - *self.managed_keys.identity_public_key(), - *self.managed_keys.encryption_public_key(), + pub fn client_address(&self) -> Recipient { + Recipient::new( + *self.client_keys.identity_keypair().public_key(), + *self.client_keys.encryption_keypair().public_key(), // TODO: below only works under assumption that gateway address == gateway id // (which currently is true) - NodeIdentity::from_base58_string(self.gateway_details.gateway_id())?, - ); - - Ok(client_recipient) - } -} - -/// Details of particular gateway client got registered with -#[derive(Debug, Clone)] -pub enum GatewayDetails { - /// Standard details of a remote gateway - Configured(GatewayEndpointConfig), - - /// Custom gateway setup, such as for a client embedded inside gateway itself - Custom(CustomGatewayDetails), -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct CustomGatewayDetails { - // whatever custom method is used, gateway's identity must be known - pub gateway_id: String, - - pub additional_data: Vec<u8>, -} - -impl CustomGatewayDetails { - pub fn new(gateway_id: String, additional_data: Vec<u8>) -> Self { - Self { - gateway_id, - additional_data, - } - } -} - -impl GatewayDetails { - pub fn try_get_configured_endpoint(&self) -> Option<&GatewayEndpointConfig> { - if let GatewayDetails::Configured(endpoint) = &self { - Some(endpoint) - } else { - None - } - } - - pub fn is_custom(&self) -> bool { - matches!(self, GatewayDetails::Custom(_)) - } - - pub fn gateway_id(&self) -> &str { - match self { - GatewayDetails::Configured(cfg) => &cfg.gateway_id, - GatewayDetails::Custom(custom) => &custom.gateway_id, - } - } -} - -impl From<GatewayEndpointConfig> for GatewayDetails { - fn from(value: GatewayEndpointConfig) -> Self { - GatewayDetails::Configured(value) - } -} - -impl From<PersistedCustomGatewayDetails> for CustomGatewayDetails { - fn from(value: PersistedCustomGatewayDetails) -> Self { - CustomGatewayDetails { - gateway_id: value.gateway_id, - additional_data: value.additional_data, - } - } -} - -impl From<CustomGatewayDetails> for PersistedCustomGatewayDetails { - fn from(value: CustomGatewayDetails) -> Self { - PersistedCustomGatewayDetails { - gateway_id: value.gateway_id, - additional_data: value.additional_data, - } - } -} - -impl From<PersistedGatewayDetails> for GatewayDetails { - fn from(value: PersistedGatewayDetails) -> Self { - match value { - PersistedGatewayDetails::Default(default) => { - GatewayDetails::Configured(default.details) - } - PersistedGatewayDetails::Custom(custom) => GatewayDetails::Custom(custom.into()), - } + self.gateway_registration.details.gateway_id(), + ) } } +// +// /// Details of particular gateway client got registered with +// #[derive(Debug, Clone)] +// pub enum GatewayDetails { +// /// Standard details of a remote gateway +// Configured(GatewayEndpointConfig), +// +// /// Custom gateway setup, such as for a client embedded inside gateway itself +// Custom(CustomGatewayDetails), +// } +// +// #[derive(Debug, Clone, Serialize, Deserialize)] +// pub struct CustomGatewayDetails { +// // whatever custom method is used, gateway's identity must be known +// pub gateway_id: String, +// +// pub additional_data: Vec<u8>, +// } +// +// impl CustomGatewayDetails { +// pub fn new(gateway_id: String, additional_data: Vec<u8>) -> Self { +// Self { +// gateway_id, +// additional_data, +// } +// } +// } +// +// impl GatewayDetails { +// pub fn try_get_configured_endpoint(&self) -> Option<&GatewayEndpointConfig> { +// if let GatewayDetails::Configured(endpoint) = &self { +// Some(endpoint) +// } else { +// None +// } +// } +// +// pub fn is_custom(&self) -> bool { +// matches!(self, GatewayDetails::Custom(_)) +// } +// +// pub fn gateway_id(&self) -> &str { +// match self { +// GatewayDetails::Configured(cfg) => &cfg.gateway_id, +// GatewayDetails::Custom(custom) => &custom.gateway_id, +// } +// } +// } +// +// impl From<GatewayEndpointConfig> for GatewayDetails { +// fn from(value: GatewayEndpointConfig) -> Self { +// GatewayDetails::Configured(value) +// } +// } +// +// impl From<PersistedCustomGatewayDetails> for CustomGatewayDetails { +// fn from(value: PersistedCustomGatewayDetails) -> Self { +// CustomGatewayDetails { +// gateway_id: value.gateway_id, +// additional_data: value.additional_data, +// } +// } +// } +// +// impl From<CustomGatewayDetails> for PersistedCustomGatewayDetails { +// fn from(value: CustomGatewayDetails) -> Self { +// PersistedCustomGatewayDetails { +// gateway_id: value.gateway_id, +// additional_data: value.additional_data, +// } +// } +// } +// +// impl From<PersistedGatewayDetails> for GatewayDetails { +// fn from(value: PersistedGatewayDetails) -> Self { +// match value { +// PersistedGatewayDetails::Default(default) => { +// GatewayDetails::Configured(default.details) +// } +// PersistedGatewayDetails::Custom(custom) => GatewayDetails::Custom(custom.into()), +// } +// } +// } #[derive(Clone, Debug)] pub enum GatewaySelectionSpecification { @@ -192,7 +247,7 @@ pub enum GatewaySelectionSpecification { /// This client has handled the selection by itself Custom { gateway_identity: String, - additional_data: Vec<u8>, + additional_data: Option<Vec<u8>>, }, } @@ -225,7 +280,10 @@ impl GatewaySelectionSpecification { pub enum GatewaySetup { /// The gateway specification (details + keys) MUST BE loaded from the underlying storage. - MustLoad, + MustLoad { + /// Optionally specify concrete gateway id. If none is selected, the current active gateway will be used. + gateway_id: Option<String>, + }, /// Specifies usage of a new gateway New { @@ -243,23 +301,24 @@ pub enum GatewaySetup { authenticated_ephemeral_client: InitGatewayClient, // Details of this pre-initialised client (i.e. gateway and keys) - gateway_details: GatewayDetails, + gateway_details: GatewayRegistration, - managed_keys: ManagedKeys, + managed_keys: KeyManager, }, } impl GatewaySetup { pub fn try_reuse_connection(init_res: InitialisationResult) -> Result<Self, ClientCoreError> { - if let Some(authenticated_ephemeral_client) = init_res.authenticated_ephemeral_client { - Ok(GatewaySetup::ReuseConnection { - authenticated_ephemeral_client, - gateway_details: init_res.gateway_details, - managed_keys: init_res.managed_keys, - }) - } else { - Err(ClientCoreError::NoInitClientPresent) - } + todo!() + // if let Some(authenticated_ephemeral_client) = init_res.authenticated_ephemeral_client { + // Ok(GatewaySetup::ReuseConnection { + // authenticated_ephemeral_client, + // gateway_details: init_res.gateway_details, + // managed_keys: init_res.managed_keys, + // }) + // } else { + // Err(ClientCoreError::NoInitClientPresent) + // } } pub async fn try_setup<K, D>( @@ -269,7 +328,7 @@ impl GatewaySetup { ) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, - D: GatewayDetailsStore, + D: GatewaysDetailsStore, K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { @@ -278,7 +337,7 @@ impl GatewaySetup { } pub fn is_must_load(&self) -> bool { - matches!(self, GatewaySetup::MustLoad) + matches!(self, GatewaySetup::MustLoad { .. }) } pub fn has_full_details(&self) -> bool { @@ -299,14 +358,19 @@ pub struct InitResults { } impl InitResults { - pub fn new(config: &Config, address: Recipient, gateway: &GatewayEndpointConfig) -> Self { + pub fn new( + config: &Config, + address: Recipient, + gateway: &RemoteGatewayDetails, + registration: OffsetDateTime, + ) -> Self { Self { version: config.client.version.clone(), id: config.client.id.clone(), identity_key: address.identity().to_base58_string(), encryption_key: address.encryption_key().to_base58_string(), - gateway_id: gateway.gateway_id.clone(), - gateway_listener: gateway.gateway_listener.clone(), + gateway_id: gateway.gateway_id.to_base58_string(), + gateway_listener: gateway.gateway_listener.to_string(), address, } } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 77d28ca2a7..2d7d4b9b57 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -32,6 +32,7 @@ use std::convert::TryFrom; use std::sync::Arc; use std::time::Duration; use tungstenite::protocol::Message; +use url::Url; #[cfg(unix)] use std::os::fd::RawFd; @@ -63,6 +64,20 @@ pub struct GatewayConfig { pub gateway_listener: String, } +impl GatewayConfig { + pub fn new( + gateway_identity: identity::PublicKey, + gateway_owner: Option<String>, + gateway_listener: String, + ) -> Self { + GatewayConfig { + gateway_identity, + gateway_owner, + gateway_listener, + } + } +} + // TODO: this should be refactored into a state machine that keeps track of its authentication state pub struct GatewayClient<C, St = EphemeralCredentialStorage> { authenticated: bool, @@ -836,7 +851,11 @@ pub struct InitOnly; impl GatewayClient<InitOnly, EphemeralCredentialStorage> { // for initialisation we do not need credential storage. Though it's still a bit weird we have to set the generic... - pub fn new_init(config: GatewayConfig, local_identity: Arc<identity::KeyPair>) -> Self { + pub fn new_init( + gateway_listener: Url, + gateway_identity: identity::PublicKey, + local_identity: Arc<identity::KeyPair>, + ) -> Self { log::trace!("Initialising gateway client"); use futures::channel::mpsc; @@ -851,8 +870,8 @@ impl GatewayClient<InitOnly, EphemeralCredentialStorage> { authenticated: false, disabled_credentials_mode: true, bandwidth_remaining: 0, - gateway_address: config.gateway_listener, - gateway_identity: config.gateway_identity, + gateway_address: gateway_listener.to_string(), + gateway_identity, local_identity, shared_key: None, connection: SocketState::NotConnected, diff --git a/common/crypto/src/asymmetric/encryption/mod.rs b/common/crypto/src/asymmetric/encryption/mod.rs index bc97f67df4..5e095beeab 100644 --- a/common/crypto/src/asymmetric/encryption/mod.rs +++ b/common/crypto/src/asymmetric/encryption/mod.rs @@ -381,3 +381,18 @@ mod sphinx_key_conversion { } } } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} + + fn assert_zeroize<T: Zeroize>() {} + + #[test] + fn private_key_is_zeroized() { + assert_zeroize::<PrivateKey>(); + assert_zeroize_on_drop::<PrivateKey>(); + } +} diff --git a/common/crypto/src/asymmetric/identity/mod.rs b/common/crypto/src/asymmetric/identity/mod.rs index ffbcac88ac..7d1db5a8c1 100644 --- a/common/crypto/src/asymmetric/identity/mod.rs +++ b/common/crypto/src/asymmetric/identity/mod.rs @@ -359,3 +359,18 @@ impl<'d> Deserialize<'d> for Signature { Signature::from_bytes(bytes.as_ref()).map_err(SerdeError::custom) } } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} + + fn assert_zeroize<T: Zeroize>() {} + + #[test] + fn private_key_is_zeroized() { + assert_zeroize::<PrivateKey>(); + assert_zeroize_on_drop::<PrivateKey>(); + } +} diff --git a/common/nymsphinx/acknowledgements/src/key.rs b/common/nymsphinx/acknowledgements/src/key.rs index d3615c3718..869f713657 100644 --- a/common/nymsphinx/acknowledgements/src/key.rs +++ b/common/nymsphinx/acknowledgements/src/key.rs @@ -77,3 +77,18 @@ impl PemStorableKey for AckKey { Self::try_from_bytes(bytes) } } + +#[cfg(test)] +mod tests { + use super::*; + + fn assert_zeroize_on_drop<T: ZeroizeOnDrop>() {} + + fn assert_zeroize<T: Zeroize>() {} + + #[test] + fn ack_key_is_zeroized() { + assert_zeroize::<AckKey>(); + assert_zeroize_on_drop::<AckKey>(); + } +} From 1916adedcc73af0d9797767d586dfbcd59e744b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 16:53:27 +0000 Subject: [PATCH 290/394] socks5 client compiling but definitely not working yet --- clients/socks5/src/commands/init.rs | 2 +- clients/socks5/src/commands/mod.rs | 83 ++++++++++---- clients/socks5/src/config/mod.rs | 1 + .../socks5/src/config/old_config_v1_1_20.rs | 4 +- .../socks5/src/config/old_config_v1_1_20_2.rs | 3 +- .../socks5/src/config/old_config_v1_1_30.rs | 11 +- .../socks5/src/config/old_config_v1_1_33.rs | 49 ++++++++ .../src/client/base_client/storage/mod.rs | 2 +- common/socks5-client-core/src/config/mod.rs | 9 +- .../src/config/old_config_v1_1_30.rs | 16 +-- .../src/config/old_config_v1_1_33.rs | 107 ++++++++++++++++++ common/socks5-client-core/src/lib.rs | 4 +- 12 files changed, 243 insertions(+), 48 deletions(-) create mode 100644 clients/socks5/src/config/old_config_v1_1_33.rs create mode 100644 common/socks5-client-core/src/config/old_config_v1_1_33.rs diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index ce13a1b7cc..3bc5cd098a 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -118,7 +118,7 @@ impl InitResults { Self { client_address: res.init_results.address.to_string(), client_core: res.init_results, - socks5_listening_address: res.config.core.socks5.bind_adddress, + socks5_listening_address: res.config.core.socks5.bind_address, } } } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index da3166fd7e..24a1112781 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -5,6 +5,7 @@ use crate::config::old_config_v1_1_13::OldConfigV1_1_13; use crate::config::old_config_v1_1_20::ConfigV1_1_20; use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; use crate::config::old_config_v1_1_30::ConfigV1_1_30; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; use crate::config::{BaseClientConfig, Config, SocksClientPaths}; use crate::error::Socks5ClientError; use clap::CommandFactory; @@ -172,21 +173,29 @@ fn persist_gateway_details( storage_paths: &SocksClientPaths, details: GatewayEndpointConfig, ) -> Result<(), Socks5ClientError> { - let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - source: Box::new(source), - }) - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| { - Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) - }) + todo!() + // let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); + // let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); + // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { + // Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError { + // source: Box::new(source), + // }) + // })?; + // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; + // details_store + // .store_to_disk(&persisted_details) + // .map_err(|source| { + // Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + // source: Box::new(source), + // }) + // }) +} + +fn migrate_gateway_details( + config: &Config, + old_details: Option<GatewayEndpointConfig>, +) -> Result<(), Socks5ClientError> { + todo!() } fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> { @@ -204,9 +213,11 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; - persist_gateway_details(&updated_step3.storage_paths, gateway_config)?; + let updated_step4: ConfigV1_1_33 = updated_step3.into(); + let updated = updated_step4.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step3.into(); updated.save_to_default_location()?; Ok(true) } @@ -225,9 +236,11 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; - persist_gateway_details(&updated_step2.storage_paths, gateway_config)?; + let updated_step3: ConfigV1_1_33 = updated_step2.into(); + let updated = updated_step3.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step2.into(); updated.save_to_default_location()?; Ok(true) } @@ -243,9 +256,11 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; - persist_gateway_details(&updated_step1.storage_paths, gateway_config)?; + let updated_step2: ConfigV1_1_33 = updated_step1.into(); + let updated = updated_step2.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; - let updated: Config = updated_step1.into(); updated.save_to_default_location()?; Ok(true) } @@ -260,7 +275,28 @@ fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool, Socks5ClientError> { info!("It seems the client is using <= v1.1.30 config template."); info!("It is going to get updated to the current specification."); - let updated: Config = old_config.into(); + let updated_step1: ConfigV1_1_33 = old_config.into(); + let updated = updated_step1.try_upgrade()?; + migrate_gateway_details(&updated, None)?; + + updated.save_to_default_location()?; + Ok(true) +} + +fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, Socks5ClientError> { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let updated = old_config.try_upgrade()?; + + migrate_gateway_details(&updated, None)?; + updated.save_to_default_location()?; Ok(true) } @@ -278,6 +314,9 @@ fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> { if try_upgrade_v1_1_30_config(id)? { return Ok(()); } + if try_upgrade_v1_1_33_config(id)? { + return Ok(()); + } Ok(()) } diff --git a/clients/socks5/src/config/mod.rs b/clients/socks5/src/config/mod.rs index 9df903e64b..2a04d6d66d 100644 --- a/clients/socks5/src/config/mod.rs +++ b/clients/socks5/src/config/mod.rs @@ -24,6 +24,7 @@ pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; pub mod old_config_v1_1_30; +pub mod old_config_v1_1_33; mod persistence; mod template; diff --git a/clients/socks5/src/config/old_config_v1_1_20.rs b/clients/socks5/src/config/old_config_v1_1_20.rs index 4acc4fccbd..fbad434c68 100644 --- a/clients/socks5/src/config/old_config_v1_1_20.rs +++ b/clients/socks5/src/config/old_config_v1_1_20.rs @@ -5,8 +5,8 @@ use crate::config::old_config_v1_1_20_2::{ ConfigV1_1_20_2, CoreConfigV1_1_20_2, SocksClientPathsV1_1_20_2, }; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; use nym_client_core::config::old_config_v1_1_20_2::ClientV1_1_20_2; use nym_config::legacy_helpers::nym_config::MigrationNymConfig; @@ -50,7 +50,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { }, storage_paths: SocksClientPathsV1_1_20_2 { common_paths: CommonClientPathsV1_1_20_2 { - keys: ClientKeysPaths { + keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, public_identity_key_file: value.base.client.public_identity_key_file, private_encryption_key_file: value.base.client.private_encryption_key_file, diff --git a/clients/socks5/src/config/old_config_v1_1_20_2.rs b/clients/socks5/src/config/old_config_v1_1_20_2.rs index 4668e3ea9d..d396082e68 100644 --- a/clients/socks5/src/config/old_config_v1_1_20_2.rs +++ b/clients/socks5/src/config/old_config_v1_1_20_2.rs @@ -14,6 +14,7 @@ use serde::{Deserialize, Serialize}; use std::io; use std::path::Path; +use crate::config::old_config_v1_1_33::SocksClientPathsV1_1_33; pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2; #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] @@ -47,7 +48,7 @@ impl ConfigV1_1_20_2 { let gateway_details = self.core.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_30 { core: self.core.into(), - storage_paths: SocksClientPaths { + storage_paths: SocksClientPathsV1_1_33 { common_paths: self.storage_paths.common_paths.upgrade_default()?, }, logging: self.logging, diff --git a/clients/socks5/src/config/old_config_v1_1_30.rs b/clients/socks5/src/config/old_config_v1_1_30.rs index cd7a5ab9e4..7395891dc3 100644 --- a/clients/socks5/src/config/old_config_v1_1_30.rs +++ b/clients/socks5/src/config/old_config_v1_1_30.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::persistence::SocksClientPaths; +use crate::config::old_config_v1_1_33::{ConfigV1_1_33, SocksClientPathsV1_1_33}; use crate::config::{default_config_filepath, Config}; use nym_bin_common::logging::LoggingSettings; use nym_config::read_config_from_toml_file; @@ -15,17 +15,14 @@ use std::path::Path; pub struct ConfigV1_1_30 { pub core: CoreConfigV1_1_30, - // I'm leaving a landmine here for when the paths actually do change the next time, - // but propagating the change right now (in ALL clients) would be such a hassle..., - // so sorry for the next person looking at it : ) - pub storage_paths: SocksClientPaths, + pub storage_paths: SocksClientPathsV1_1_33, pub logging: LoggingSettings, } -impl From<ConfigV1_1_30> for Config { +impl From<ConfigV1_1_30> for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { + ConfigV1_1_33 { core: value.core.into(), storage_paths: value.storage_paths, logging: LoggingSettings::default(), diff --git a/clients/socks5/src/config/old_config_v1_1_33.rs b/clients/socks5/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..fb14259bf4 --- /dev/null +++ b/clients/socks5/src/config/old_config_v1_1_33.rs @@ -0,0 +1,49 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::{default_config_filepath, Config, SocksClientPaths}; +use crate::error::Socks5ClientError; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_socks5_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as CoreConfigV1_1_33; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::Path; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct SocksClientPathsV1_1_33 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + pub core: CoreConfigV1_1_33, + + // \/ CHANGED + pub storage_paths: SocksClientPathsV1_1_33, + // /\ CHANGED + pub logging: LoggingSettings, +} + +impl ConfigV1_1_33 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result<Config, Socks5ClientError> { + Ok(Config { + core: self.core.into(), + storage_paths: SocksClientPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + }, + logging: self.logging, + }) + } +} diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 86180b99eb..f31370a30d 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -10,7 +10,6 @@ use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::replies::reply_storage; use crate::client::replies::reply_storage::ReplyStorageBackend; -use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use nym_credential_storage::storage::Storage as CredentialStorage; @@ -34,6 +33,7 @@ use crate::error::ClientCoreError; use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; // fs-gateways +pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; #[deprecated] pub mod gateway_details; diff --git a/common/socks5-client-core/src/config/mod.rs b/common/socks5-client-core/src/config/mod.rs index 8c5c722093..e4b3a8b623 100644 --- a/common/socks5-client-core/src/config/mod.rs +++ b/common/socks5-client-core/src/config/mod.rs @@ -12,6 +12,7 @@ use std::str::FromStr; pub mod old_config_v1_1_20_2; pub mod old_config_v1_1_30; +pub mod old_config_v1_1_33; pub use nym_service_providers_common::interface::ProviderInterfaceVersion; pub use nym_socks5_requests::Socks5ProtocolVersion; @@ -47,13 +48,13 @@ impl Config { #[must_use] pub fn with_port(mut self, port: u16) -> Self { - self.socks5.bind_adddress = SocketAddr::new(self.socks5.bind_adddress.ip(), port); + self.socks5.bind_address = SocketAddr::new(self.socks5.bind_address.ip(), port); self } #[must_use] pub fn with_ip(mut self, ip: IpAddr) -> Self { - self.socks5.bind_adddress = SocketAddr::new(ip, self.socks5.bind_adddress.port()); + self.socks5.bind_address = SocketAddr::new(ip, self.socks5.bind_address.port()); self } @@ -112,7 +113,7 @@ impl Config { pub struct Socks5 { /// The address on which the client will be listening for incoming requests /// (default: 127.0.0.1:1080) - pub bind_adddress: SocketAddr, + pub bind_address: SocketAddr, /// The mix address of the provider to which all requests are going to be sent. pub provider_mix_address: String, @@ -141,7 +142,7 @@ pub struct Socks5 { impl Socks5 { pub fn new<S: Into<String>>(provider_mix_address: S) -> Self { Socks5 { - bind_adddress: SocketAddr::new( + bind_address: SocketAddr::new( IpAddr::V4(Ipv4Addr::LOCALHOST), DEFAULT_SOCKS5_LISTENING_PORT, ), diff --git a/common/socks5-client-core/src/config/old_config_v1_1_30.rs b/common/socks5-client-core/src/config/old_config_v1_1_30.rs index 3f3f877797..13591f7d9a 100644 --- a/common/socks5-client-core/src/config/old_config_v1_1_30.rs +++ b/common/socks5-client-core/src/config/old_config_v1_1_30.rs @@ -1,7 +1,7 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use super::{Config, Socks5, Socks5Debug}; +use super::old_config_v1_1_33::{ConfigV1_1_33, Socks5DebugV1_1_33, Socks5V1_1_33}; pub use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseClientConfigV1_1_30; use serde::{Deserialize, Serialize}; use std::fmt::Debug; @@ -23,9 +23,9 @@ pub struct ConfigV1_1_30 { pub socks5: Socks5V1_1_30, } -impl From<ConfigV1_1_30> for Config { +impl From<ConfigV1_1_30> for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { + ConfigV1_1_33 { base: value.base.into(), socks5: value.socks5.into(), } @@ -62,11 +62,11 @@ pub struct Socks5V1_1_30 { pub socks5_debug: Socks5DebugV1_1_30, } -impl From<Socks5V1_1_30> for Socks5 { +impl From<Socks5V1_1_30> for Socks5V1_1_33 { fn from(value: Socks5V1_1_30) -> Self { - Socks5 { + Socks5V1_1_33 { // in <= 1.1.30 the address was hardcoded to 127.0.0.1 - bind_adddress: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), value.listening_port), + bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), value.listening_port), provider_mix_address: value.provider_mix_address, provider_interface_version: value.provider_interface_version, socks5_protocol_version: value.socks5_protocol_version, @@ -86,9 +86,9 @@ pub struct Socks5DebugV1_1_30 { pub per_request_surbs: u32, } -impl From<Socks5DebugV1_1_30> for Socks5Debug { +impl From<Socks5DebugV1_1_30> for Socks5DebugV1_1_33 { fn from(value: Socks5DebugV1_1_30) -> Self { - Socks5Debug { + Socks5DebugV1_1_33 { connection_start_surbs: value.connection_start_surbs, per_request_surbs: value.per_request_surbs, } diff --git a/common/socks5-client-core/src/config/old_config_v1_1_33.rs b/common/socks5-client-core/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..c306d42888 --- /dev/null +++ b/common/socks5-client-core/src/config/old_config_v1_1_33.rs @@ -0,0 +1,107 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use super::{Config, Socks5, Socks5Debug}; +pub use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseClientConfigV1_1_33; +use serde::{Deserialize, Serialize}; +use std::fmt::Debug; +use std::net::SocketAddr; + +// TODO: those should really be redefined here in case we change them... +use nym_service_providers_common::interface::ProviderInterfaceVersion; +use nym_socks5_requests::Socks5ProtocolVersion; + +const DEFAULT_CONNECTION_START_SURBS: u32 = 20; +const DEFAULT_PER_REQUEST_SURBS: u32 = 3; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + #[serde(flatten)] + pub base: BaseClientConfigV1_1_33, + + pub socks5: Socks5V1_1_33, +} + +impl From<ConfigV1_1_33> for Config { + fn from(value: ConfigV1_1_33) -> Self { + Config { + base: value.base.into(), + socks5: value.socks5.into(), + } + } +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Socks5V1_1_33 { + /// The address on which the client will be listening for incoming requests + /// (default: 127.0.0.1:1080) + // there was a typo in here, so accept the wrong name for the purposes of backwards compatibility + #[serde(alias = "bind_adddress")] + pub bind_address: SocketAddr, + + /// The mix address of the provider to which all requests are going to be sent. + pub provider_mix_address: String, + + /// The version of the 'service provider' this client is going to use in its communication with the + /// specified socks5 provider. + // if in doubt, use the legacy version as initially nobody will be using the updated binaries + #[serde(default)] + pub provider_interface_version: ProviderInterfaceVersion, + + #[serde(default)] + pub socks5_protocol_version: Socks5ProtocolVersion, + + /// Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. + /// While this is going to hide its actual address information, it will make the actual communication + /// slower and consume nearly double the bandwidth as it will require sending reply SURBs. + /// + /// Note that some service providers might not support this. + #[serde(default)] + pub send_anonymously: bool, + + #[serde(default)] + pub socks5_debug: Socks5DebugV1_1_33, +} + +impl From<Socks5V1_1_33> for Socks5 { + fn from(value: Socks5V1_1_33) -> Self { + Socks5 { + bind_address: value.bind_address, + provider_mix_address: value.provider_mix_address, + provider_interface_version: value.provider_interface_version, + socks5_protocol_version: value.socks5_protocol_version, + send_anonymously: value.send_anonymously, + socks5_debug: value.socks5_debug.into(), + } + } +} + +#[derive(Clone, Copy, Debug, Deserialize, PartialEq, Eq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct Socks5DebugV1_1_33 { + /// Number of reply SURBs attached to each `Request::Connect` message. + pub connection_start_surbs: u32, + + /// Number of reply SURBs attached to each `Request::Send` message. + pub per_request_surbs: u32, +} + +impl From<Socks5DebugV1_1_33> for Socks5Debug { + fn from(value: Socks5DebugV1_1_33) -> Self { + Socks5Debug { + connection_start_surbs: value.connection_start_surbs, + per_request_surbs: value.per_request_surbs, + } + } +} + +impl Default for Socks5DebugV1_1_33 { + fn default() -> Self { + Socks5DebugV1_1_33 { + connection_start_surbs: DEFAULT_CONNECTION_START_SURBS, + per_request_surbs: DEFAULT_PER_REQUEST_SURBS, + } + } +} diff --git a/common/socks5-client-core/src/lib.rs b/common/socks5-client-core/src/lib.rs index d9d036d1a8..41a7105dad 100644 --- a/common/socks5-client-core/src/lib.rs +++ b/common/socks5-client-core/src/lib.rs @@ -78,7 +78,7 @@ where NymClient { config, storage, - setup_method: GatewaySetup::MustLoad, + setup_method: GatewaySetup::MustLoad { gateway_id: None }, custom_mixnet, } } @@ -124,7 +124,7 @@ where let authenticator = Authenticator::new(auth_methods, allowed_users); let mut sphinx_socks = NymSocksServer::new( - socks5_config.bind_adddress, + socks5_config.bind_address, authenticator, socks5_config.get_provider_mix_address(), self_address, From cdc49e074981ffed415b67a65621bd0e57f0eead Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 16:57:51 +0000 Subject: [PATCH 291/394] ibid for rust sdk --- sdk/rust/nym-sdk/src/mixnet/client.rs | 4 ++-- sdk/rust/nym-sdk/src/mixnet/paths.rs | 19 ++----------------- sdk/rust/nym-sdk/src/mixnet/socks5_client.rs | 2 +- 3 files changed, 5 insertions(+), 20 deletions(-) diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index c075acdfef..bba70e96a1 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -414,7 +414,7 @@ where } /// Client keys are generated at client creation if none were found. The gateway shared - /// key, however, is created during the gateway registration handshake so it might not + /// key, however, is created during the gateway registration handshake, so it might not /// necessarily be available. /// Furthermore, it has to be coupled with particular gateway's config. async fn has_valid_gateway_info(&self) -> bool { @@ -466,7 +466,7 @@ where let api_endpoints = self.get_api_endpoints(); let gateway_setup = if self.has_valid_gateway_info().await { - GatewaySetup::MustLoad + GatewaySetup::MustLoad { gateway_id: None } } else { let selection_spec = GatewaySelectionSpecification::new( self.config.user_chosen_gateway.clone(), diff --git a/sdk/rust/nym-sdk/src/mixnet/paths.rs b/sdk/rust/nym-sdk/src/mixnet/paths.rs index 88ae655d6a..8051b49350 100644 --- a/sdk/rust/nym-sdk/src/mixnet/paths.rs +++ b/sdk/rust/nym-sdk/src/mixnet/paths.rs @@ -1,8 +1,7 @@ -// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use crate::error::{Error, Result}; -use nym_client_core::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; use nym_client_core::client::base_client::{non_wasm_helpers, storage}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; @@ -32,20 +31,13 @@ pub struct StoragePaths { /// Key for handling acks pub ack_key: PathBuf, - /// Key setup after authenticating with a gateway - #[deprecated] - pub gateway_shared_key: PathBuf, - /// The database containing credentials pub credential_database_path: PathBuf, /// The database storing reply surbs in-between sessions pub reply_surb_database_path: PathBuf, - /// Details of the used gateway - #[deprecated] - pub gateway_details_path: PathBuf, - + /// Details of the used gateways pub gateway_registrations: PathBuf, } @@ -68,10 +60,8 @@ impl StoragePaths { private_encryption: dir.join("private_encryption.pem"), public_encryption: dir.join("public_encryption.pem"), ack_key: dir.join("ack_key.pem"), - gateway_shared_key: dir.join("gateway_shared.pem"), credential_database_path: dir.join("db.sqlite"), reply_surb_database_path: dir.join("persistent_reply_store.sqlite"), - gateway_details_path: dir.join("gateway_details.json"), gateway_registrations: dir.join("gateways_registrations.sqlite"), }) } @@ -145,7 +135,6 @@ impl StoragePaths { public_identity_key_file: self.public_identity.clone(), private_encryption_key_file: self.private_encryption.clone(), public_encryption_key_file: self.public_encryption.clone(), - gateway_shared_key_file: self.gateway_shared_key.clone(), ack_key_file: self.ack_key.clone(), } } @@ -159,10 +148,8 @@ impl From<StoragePaths> for CommonClientPaths { public_identity_key_file: value.public_identity, private_encryption_key_file: value.private_encryption, public_encryption_key_file: value.public_encryption, - gateway_shared_key_file: value.gateway_shared_key, ack_key_file: value.ack_key, }, - gateway_details: value.gateway_details_path, gateway_registrations: value.gateway_registrations, credentials_database: value.credential_database_path, reply_surb_database: value.reply_surb_database_path, @@ -178,10 +165,8 @@ impl From<CommonClientPaths> for StoragePaths { private_encryption: value.keys.private_encryption_key_file, public_encryption: value.keys.public_encryption_key_file, ack_key: value.keys.ack_key_file, - gateway_shared_key: value.keys.gateway_shared_key_file, credential_database_path: value.credentials_database, reply_surb_database_path: value.reply_surb_database, - gateway_details_path: value.gateway_details, gateway_registrations: value.gateway_registrations, } } diff --git a/sdk/rust/nym-sdk/src/mixnet/socks5_client.rs b/sdk/rust/nym-sdk/src/mixnet/socks5_client.rs index ab340447f9..6bc2a46a06 100644 --- a/sdk/rust/nym-sdk/src/mixnet/socks5_client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/socks5_client.rs @@ -56,7 +56,7 @@ impl Socks5MixnetClient { /// Get the SOCKS5 proxy URL that a HTTP(S) client can connect to. pub fn socks5_url(&self) -> String { - format!("socks5h://{}", self.socks5_config.bind_adddress) + format!("socks5h://{}", self.socks5_config.bind_address) } /// Get a shallow clone of [`LaneQueueLengths`]. This is useful to manually implement some form From 337d53b2ecc41badb94893aee31230726122fb19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 17:18:38 +0000 Subject: [PATCH 292/394] ibid for network requester --- .../network-requester/src/cli/mod.rs | 84 ++++++++--- .../network-requester/src/config/mod.rs | 1 + .../src/config/old_config_v1_1_20.rs | 3 +- .../src/config/old_config_v1_1_20_2.rs | 24 ++- .../src/config/old_config_v1_1_33.rs | 139 ++++++++++++++++++ .../src/config/persistence.rs | 2 - .../network-requester/src/lib.rs | 5 +- 7 files changed, 215 insertions(+), 43 deletions(-) create mode 100644 service-providers/network-requester/src/config/old_config_v1_1_33.rs diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index cd5e84071e..fb0b8699f3 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -4,6 +4,7 @@ use crate::config::old_config_v1_1_13::OldConfigV1_1_13; use crate::config::old_config_v1_1_20::ConfigV1_1_20; use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; use crate::{ config::{BaseClientConfig, Config}, error::NetworkRequesterError, @@ -170,22 +171,34 @@ fn persist_gateway_details( config: &Config, details: GatewayEndpointConfig, ) -> Result<(), NetworkRequesterError> { - let details_store = - OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - NetworkRequesterError::ClientCoreError(ClientCoreError::KeyStoreError { - source: Box::new(source), - }) - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| { - NetworkRequesterError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) - }) + todo!() + // let details_store = + // OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); + // let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); + // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { + // NetworkRequesterError::ClientCoreError(ClientCoreError::KeyStoreError { + // source: Box::new(source), + // }) + // })?; + // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; + // details_store + // .store_to_disk(&persisted_details) + // .map_err(|source| { + // NetworkRequesterError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + // source: Box::new(source), + // }) + // }) +} + +fn migrate_gateway_details( + config: &Config, + old_details: Option<GatewayEndpointConfig>, +) -> Result<(), NetworkRequesterError> { + todo!() +} + +fn extract_gateway_details(config: &ConfigV1_1_33) -> Result<(), NetworkRequesterError> { + todo!() } fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { @@ -203,8 +216,10 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); - let (updated, gateway_config) = updated_step2.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let updated = updated_step3.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; updated.save_to_default_location()?; Ok(true) @@ -225,8 +240,10 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> { info!("It is going to get updated to the current specification."); let updated_step1: ConfigV1_1_20_2 = old_config.into(); - let (updated, gateway_config) = updated_step1.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let updated = updated_step2.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; updated.save_to_default_location()?; Ok(true) @@ -244,8 +261,28 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError> info!("It seems the client is using <= v1.1.20_2 config template."); info!("It is going to get updated to the current specification."); - let (updated, gateway_config) = old_config.upgrade()?; - persist_gateway_details(&updated, gateway_config)?; + let (updated_step1, gateway_config) = old_config.upgrade()?; + let updated = updated_step1.try_upgrade()?; + + migrate_gateway_details(&updated, Some(gateway_config))?; + + updated.save_to_default_location()?; + Ok(true) +} + +fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, NetworkRequesterError> { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let updated = old_config.try_upgrade()?; + + migrate_gateway_details(&updated, None)?; updated.save_to_default_location()?; Ok(true) @@ -262,6 +299,9 @@ fn try_upgrade_config(id: &str) -> Result<(), NetworkRequesterError> { if try_upgrade_v1_1_20_2_config(id)? { return Ok(()); } + if try_upgrade_v1_1_33_config(id)? { + return Ok(()); + } Ok(()) } diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index bce2d5effa..72a51d6edc 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -28,6 +28,7 @@ pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; mod persistence; mod template; +pub mod old_config_v1_1_33; const DEFAULT_NETWORK_REQUESTERS_DIR: &str = "network-requester"; diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20.rs b/service-providers/network-requester/src/config/old_config_v1_1_20.rs index a3ab8c6610..42d82646fa 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20.rs @@ -6,6 +6,7 @@ use crate::config::old_config_v1_1_20_2::{ }; use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; use nym_client_core::config::old_config_v1_1_20_2::{ ClientV1_1_20_2, ConfigV1_1_20_2 as BaseClientConfigV1_1_20_2, @@ -47,7 +48,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { network_requester: Default::default(), storage_paths: NetworkRequesterPathsV1_1_20_2 { common_paths: CommonClientPathsV1_1_20_2 { - keys: ClientKeysPaths { + keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, public_identity_key_file: value.base.client.public_identity_key_file, private_encryption_key_file: value.base.client.private_encryption_key_file, diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs index 2263bfd42a..6c9d3e0255 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs @@ -1,14 +1,10 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::{ - config::{ - default_config_filepath, persistence::NetworkRequesterPaths, Config, Debug, - NetworkRequester, - }, - error::NetworkRequesterError, +use super::old_config_v1_1_33::{ + ConfigV1_1_33, DebugV1_1_33, NetworkRequesterPathsV1_1_33, NetworkRequesterV1_1_33, }; - +use crate::{config::default_config_filepath, error::NetworkRequesterError}; use log::trace; use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; @@ -65,7 +61,7 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(Config, GatewayEndpointConfig), NetworkRequesterError> { + pub fn upgrade(self) -> Result<(ConfigV1_1_33, GatewayEndpointConfig), NetworkRequesterError> { trace!("Upgrading from v1.1.20_2"); let gateway_details = self.base.client.gateway_endpoint.clone().into(); let nr_description = self @@ -76,9 +72,9 @@ impl ConfigV1_1_20_2 { .parent() .expect("config paths upgrade failure") .join(DEFAULT_DESCRIPTION_FILENAME); - let config = Config { + let config = ConfigV1_1_33 { base: BaseConfigV1_1_30::from(self.base).into(), - storage_paths: NetworkRequesterPaths { + storage_paths: NetworkRequesterPathsV1_1_33 { common_paths: self.storage_paths.common_paths.upgrade_default()?, allowed_list_location: self.storage_paths.allowed_list_location, unknown_list_location: self.storage_paths.unknown_list_location, @@ -97,9 +93,9 @@ impl ConfigV1_1_20_2 { #[serde(default, deny_unknown_fields)] pub struct NetworkRequesterV1_1_20_2 {} -impl From<NetworkRequesterV1_1_20_2> for NetworkRequester { +impl From<NetworkRequesterV1_1_20_2> for NetworkRequesterV1_1_33 { fn from(_value: NetworkRequesterV1_1_20_2) -> Self { - NetworkRequester::default() + NetworkRequesterV1_1_33::default() } } @@ -111,9 +107,9 @@ pub struct DebugV1_1_20_2 { pub standard_list_update_interval: Duration, } -impl From<DebugV1_1_20_2> for Debug { +impl From<DebugV1_1_20_2> for DebugV1_1_33 { fn from(value: DebugV1_1_20_2) -> Self { - Debug { + DebugV1_1_33 { standard_list_update_interval: value.standard_list_update_interval, } } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_33.rs b/service-providers/network-requester/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..b49bb514d1 --- /dev/null +++ b/service-providers/network-requester/src/config/old_config_v1_1_33.rs @@ -0,0 +1,139 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::persistence::NetworkRequesterPaths; +use crate::config::Config; +use crate::config::{default_config_filepath, Debug, NetworkRequester}; +use crate::error::NetworkRequesterError; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_config::serde_helpers::de_maybe_stringified; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::{Path, PathBuf}; +use std::time::Duration; +use url::Url; + +pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct NetworkRequesterPathsV1_1_33 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, + + /// Location of the file containing our allow.list + pub allowed_list_location: PathBuf, + + /// Location of the file containing our unknown.list + pub unknown_list_location: PathBuf, + + #[serde(default)] + pub nr_description: PathBuf, +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + pub base: BaseConfigV1_1_33, + + #[serde(default)] + pub network_requester: NetworkRequesterV1_1_33, + + pub storage_paths: NetworkRequesterPathsV1_1_33, + + #[serde(default)] + pub network_requester_debug: DebugV1_1_33, + + pub logging: LoggingSettings, +} + +impl ConfigV1_1_33 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result<Config, NetworkRequesterError> { + Ok(Config { + base: self.base.into(), + network_requester: self.network_requester.into(), + storage_paths: NetworkRequesterPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + allowed_list_location: self.storage_paths.allowed_list_location, + unknown_list_location: self.storage_paths.unknown_list_location, + nr_description: self.storage_paths.nr_description, + }, + network_requester_debug: self.network_requester_debug.into(), + logging: self.logging, + }) + } +} + +#[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct NetworkRequesterV1_1_33 { + /// specifies whether this network requester should run in 'open-proxy' mode + /// and thus would attempt to resolve **ANY** request it receives. + pub open_proxy: bool, + + /// specifies whether this network requester would send anonymized statistics to a statistics aggregator server + pub enabled_statistics: bool, + + /// in case of enabled statistics, specifies mixnet client address where a statistics aggregator is running + pub statistics_recipient: Option<String>, + + /// Disable Poisson sending rate. + /// This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true, + pub disable_poisson_rate: bool, + + /// Specifies whether this network requester should be using the deprecated allow-list, + /// as opposed to the new ExitPolicy. + /// Note: this field will be removed in a near future. + pub use_deprecated_allow_list: bool, + + /// Specifies the url for an upstream source of the exit policy used by this node. + #[serde(deserialize_with = "de_maybe_stringified")] + pub upstream_exit_policy_url: Option<Url>, +} + +impl From<NetworkRequesterV1_1_33> for NetworkRequester { + fn from(value: NetworkRequesterV1_1_33) -> Self { + NetworkRequester { + open_proxy: value.open_proxy, + enabled_statistics: value.enabled_statistics, + statistics_recipient: value.statistics_recipient, + disable_poisson_rate: value.disable_poisson_rate, + use_deprecated_allow_list: value.use_deprecated_allow_list, + upstream_exit_policy_url: value.upstream_exit_policy_url, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct DebugV1_1_33 { + /// Defines how often the standard allow list should get updated + #[serde(with = "humantime_serde")] + pub standard_list_update_interval: Duration, +} + +impl From<DebugV1_1_33> for Debug { + fn from(value: DebugV1_1_33) -> Self { + Debug { + standard_list_update_interval: value.standard_list_update_interval, + } + } +} + +impl Default for DebugV1_1_33 { + fn default() -> Self { + DebugV1_1_33 { + standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, + } + } +} diff --git a/service-providers/network-requester/src/config/persistence.rs b/service-providers/network-requester/src/config/persistence.rs index 242562c1c7..cc3d4378ba 100644 --- a/service-providers/network-requester/src/config/persistence.rs +++ b/service-providers/network-requester/src/config/persistence.rs @@ -23,8 +23,6 @@ pub struct NetworkRequesterPaths { pub unknown_list_location: PathBuf, /// Location of the file containing our description - // For upgrade use default if missing. On next config upgrade iteration, remove the serde(default) - #[serde(default)] pub nr_description: PathBuf, } diff --git a/service-providers/network-requester/src/lib.rs b/service-providers/network-requester/src/lib.rs index f8d783b13d..01bdaf3a42 100644 --- a/service-providers/network-requester/src/lib.rs +++ b/service-providers/network-requester/src/lib.rs @@ -22,10 +22,7 @@ pub use nym_client_core::{ }, init::{ setup_gateway, - types::{ - CustomGatewayDetails, GatewayDetails, GatewaySelectionSpecification, GatewaySetup, - InitResults, InitialisationResult, - }, + types::{GatewaySelectionSpecification, GatewaySetup, InitResults, InitialisationResult}, }, }; pub use request_filter::RequestFilter; From daa5f016832d40fd4ce22d81c9b77ba7ab2513d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 6 Mar 2024 17:24:49 +0000 Subject: [PATCH 293/394] further compilation fixes --- common/client-core/src/lib.rs | 5 +++++ gateway/src/commands/helpers.rs | 4 ++-- sdk/lib/socks5-listener/src/persistence.rs | 7 +++---- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/common/client-core/src/lib.rs b/common/client-core/src/lib.rs index 1eb90ddcf7..8c84737049 100644 --- a/common/client-core/src/lib.rs +++ b/common/client-core/src/lib.rs @@ -32,3 +32,8 @@ where { tokio::spawn(future); } + +fn unused_function() { + let with_unused_variable = 42; + todo!("update all client config templates after changes stabilise") +} diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 956c78834f..8ea29169f2 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -293,7 +293,7 @@ pub(crate) async fn initialise_local_network_requester( ) .await?; - let address = init_res.client_address()?; + let address = init_res.client_address(); if let Err(err) = save_formatted_config_to_file(&nr_cfg, nr_cfg_path) { log::error!("Failed to save the network requester config file: {err}"); @@ -366,7 +366,7 @@ pub(crate) async fn initialise_local_ip_packet_router( ) .await?; - let address = init_res.client_address()?; + let address = init_res.client_address(); if let Err(err) = save_formatted_config_to_file(&ip_cfg, ip_cfg_path) { log::error!("Failed to save the ip packet router config file: {err}"); diff --git a/sdk/lib/socks5-listener/src/persistence.rs b/sdk/lib/socks5-listener/src/persistence.rs index 93916feb42..9ee4990e6c 100644 --- a/sdk/lib/socks5-listener/src/persistence.rs +++ b/sdk/lib/socks5-listener/src/persistence.rs @@ -2,8 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::Config; -use nym_client_core::client::base_client::storage::gateway_details::InMemGatewayDetails; -use nym_client_core::client::base_client::storage::MixnetClientStorage; +use nym_client_core::client::base_client::storage::{InMemGatewaysDetails, MixnetClientStorage}; use nym_client_core::client::key_manager::persistence::InMemEphemeralKeys; use nym_client_core::client::replies::reply_storage; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; @@ -11,7 +10,7 @@ use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCred pub struct MobileClientStorage { // the key storage is now useless without gateway details store. so use ephemeral for everything. key_store: InMemEphemeralKeys, - gateway_details_store: InMemGatewayDetails, + gateway_details_store: InMemGatewaysDetails, reply_store: reply_storage::Empty, credential_store: EphemeralCredentialStorage, @@ -21,7 +20,7 @@ impl MixnetClientStorage for MobileClientStorage { type KeyStore = InMemEphemeralKeys; type ReplyStore = reply_storage::Empty; type CredentialStore = EphemeralCredentialStorage; - type GatewaysDetailsStore = InMemGatewayDetails; + type GatewaysDetailsStore = InMemGatewaysDetails; fn into_runtime_stores(self) -> (Self::ReplyStore, Self::CredentialStore) { (self.reply_store, self.credential_store) From c0ae924c585be158bd2af4101a53928fc0f2a868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 10:10:40 +0000 Subject: [PATCH 294/394] move storage helpers --- .../src/backend/fs_backend/mod.rs | 2 +- .../src/backend/mem_backend.rs | 2 +- .../client-core/gateways-storage/src/lib.rs | 2 +- .../src/cli_helpers/client_init.rs | 42 ++++--- .../client/base_client/non_wasm_helpers.rs | 2 +- .../src/client/base_client/storage/helpers.rs | 101 ++++++++++++++++ .../src/client/base_client/storage/mod.rs | 1 + common/client-core/src/error.rs | 4 +- common/client-core/src/init/mod.rs | 113 +++--------------- .../desktop/src-tauri/src/config/upgrade.rs | 2 +- .../ip-packet-router/src/cli/mod.rs | 2 +- 11 files changed, 154 insertions(+), 119 deletions(-) create mode 100644 common/client-core/src/client/base_client/storage/helpers.rs diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 8aa5c3ff9d..c447d407e2 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -50,7 +50,7 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 003284622e..092772c9f0 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -66,7 +66,7 @@ impl GatewaysDetailsStore for InMemGatewaysDetails { async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 0c11b51f52..7416abfc90 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -48,7 +48,7 @@ pub trait GatewaysDetailsStore { /// Store the provided gateway details. async fn store_gateway_details( &self, - details: GatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError>; /// Remove given gateway details from the underlying store. diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 9c93cd1729..a75573b3eb 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -5,7 +5,9 @@ use crate::config::disk_persistence::CommonClientPaths; use crate::error::ClientCoreError; use crate::{ client::{ - base_client::non_wasm_helpers::setup_fs_gateways_storage, + base_client::{ + non_wasm_helpers::setup_fs_gateways_storage, storage::helpers::set_active_gateway, + }, key_manager::persistence::OnDiskKeys, }, init::types::{GatewaySelectionSpecification, GatewaySetup, InitResults}, @@ -203,7 +205,8 @@ where crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? }; - todo!("remove registered gateways from the list"); + let unused_variable = 42; + // todo!("remove registered gateways from the list"); let gateway_setup = GatewaySetup::New { specification: selection_spec, @@ -216,27 +219,30 @@ where // TODO: ask the service provider we specified for its interface version and set it in the config - let config_save_location = config.default_store_location(); - if let Err(err) = config.save_to(&config_save_location) { - return Err(ClientCoreError::ConfigSaveFailure { - typ: C::NAME.to_string(), - id: id.to_string(), - path: config_save_location, - source: err, + if !already_init { + let config_save_location = config.default_store_location(); + if let Err(err) = config.save_to(&config_save_location) { + return Err(ClientCoreError::ConfigSaveFailure { + typ: C::NAME.to_string(), + id: id.to_string(), + path: config_save_location, + source: err, + } + .into()); } - .into()); - } - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); + eprintln!( + "Saved configuration file to {}", + config_save_location.display() + ); + } let address = init_details.client_address(); let GatewayDetails::Remote(gateway_details) = init_details.gateway_registration.details else { return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; }; + let init_results = InitResults::new( config.core_config(), address, @@ -244,6 +250,12 @@ where init_details.gateway_registration.registration_timestamp, ); + if init_args.as_ref().set_active { + set_active_gateway(&init_results.gateway_id, &details_store).await?; + } else { + info!("registered with new gateway {} (under address {address}), but this will not be our default address", init_results.gateway_id); + } + Ok(InitResultsWithConfig { config, init_results, diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 70ad8358e6..740e75bb33 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -108,7 +108,7 @@ pub async fn setup_fs_gateways_storage<P: AsRef<Path>>( info!("setting up gateways details storage"); OnDiskGatewaysDetails::init(db_path) .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }) } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs new file mode 100644 index 0000000000..54535a918e --- /dev/null +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -0,0 +1,101 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::client::key_manager::persistence::KeyStore; +use crate::client::key_manager::KeyManager; +use crate::error::ClientCoreError; +use nym_client_core_gateways_storage::{GatewayRegistration, GatewaysDetailsStore}; + +// helpers for error wrapping +pub async fn set_active_gateway<D>( + gateway_id: &str, + details_store: &D, +) -> Result<(), ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .set_active_gateway(gateway_id) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn store_gateway_details<D>( + details_store: &D, + details: &GatewayRegistration, +) -> Result<(), ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .store_gateway_details(details) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn load_active_gateway_details<D>( + details_store: &D, +) -> Result<GatewayRegistration, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .active_gateway() + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + })? + .ok_or(ClientCoreError::NoActiveGatewaySet) +} + +pub async fn load_gateway_details<D>( + details_store: &D, + gateway_id: &str, +) -> Result<GatewayRegistration, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .load_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::UnavailableGatewayDetails { + gateway_id: gateway_id.to_string(), + source: Box::new(source), + }) +} + +pub async fn has_gateway_details<D>( + details_store: &D, + gateway_id: &str, +) -> Result<bool, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .has_gateway_details(gateway_id) + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + +pub async fn load_client_keys<K>(key_store: &K) -> Result<KeyManager, ClientCoreError> +where + K: KeyStore, + K::StorageError: Send + Sync + 'static, +{ + KeyManager::load_keys(key_store) + .await + .map_err(|source| ClientCoreError::KeyStoreError { + source: Box::new(source), + }) +} diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index f31370a30d..55bfb12e36 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -37,6 +37,7 @@ pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDe #[deprecated] pub mod gateway_details; +pub mod helpers; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 72fcf7762e..9fa43c8ef2 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -56,8 +56,8 @@ pub enum ClientCoreError { source: Box<dyn Error + Send + Sync>, }, - #[error("experienced a failure with our gateway details storage: {source}")] - GatewayDetailsStoreError { + #[error("experienced a failure with our gateways details storage: {source}")] + GatewaysDetailsStoreError { source: Box<dyn Error + Send + Sync>, }, diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 38b5c398ab..7dce228834 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -3,6 +3,10 @@ //! Collection of initialization steps used by client implementations +use crate::client::base_client::storage::helpers::{ + has_gateway_details, load_active_gateway_details, load_client_keys, load_gateway_details, + store_gateway_details, +}; use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::KeyManager; use crate::error::ClientCoreError; @@ -19,89 +23,11 @@ use nym_topology::gateway; use rand::rngs::OsRng; use rand::{CryptoRng, RngCore}; use serde::Serialize; -use std::sync::Arc; pub mod helpers; pub mod types; // helpers for error wrapping -async fn _store_gateway_details<D>( - details_store: &D, - details: &GatewayDetails, -) -> Result<(), ClientCoreError> -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - todo!() - // details_store - // .store_gateway_details(details) - // .await - // .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { - // source: Box::new(source), - // }) -} - -async fn _load_active_gateway_details<D>( - details_store: &D, -) -> Result<GatewayRegistration, ClientCoreError> -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .active_gateway() - .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - })? - .ok_or(ClientCoreError::NoActiveGatewaySet) -} - -async fn _load_gateway_details<D>( - details_store: &D, - gateway_id: &str, -) -> Result<GatewayRegistration, ClientCoreError> -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .load_gateway_details(gateway_id) - .await - .map_err(|source| ClientCoreError::UnavailableGatewayDetails { - gateway_id: gateway_id.to_string(), - source: Box::new(source), - }) -} - -async fn _has_gateway_details<D>( - details_store: &D, - gateway_id: &str, -) -> Result<bool, ClientCoreError> -where - D: GatewaysDetailsStore, - D::StorageError: Send + Sync + 'static, -{ - details_store - .has_gateway_details(gateway_id) - .await - .map_err(|source| ClientCoreError::GatewayDetailsStoreError { - source: Box::new(source), - }) -} - -async fn _load_client_keys<K>(key_store: &K) -> Result<KeyManager, ClientCoreError> -where - K: KeyStore, - K::StorageError: Send + Sync + 'static, -{ - KeyManager::load_keys(key_store) - .await - .map_err(|source| ClientCoreError::KeyStoreError { - source: Box::new(source), - }) -} pub async fn generate_new_client_keys<K, R>( rng: &mut R, @@ -143,15 +69,7 @@ where log::trace!("Setting up new gateway"); // if we're setting up new gateway, we must have had generated long-term client keys before - let client_keys = _load_client_keys(key_store).await?; - - // if we're setting up new gateway, failing to load existing information is fine. - // as a matter of fact, it's only potentially a problem if we DO succeed - - todo!("check gateway details (maybe not even needed anymore, idk)"); - // if _load_gateway_details(details_store).await.is_ok() && !overwrite_data { - // return Err(ClientCoreError::ForbiddenKeyOverwrite); - // } + let client_keys = load_client_keys(key_store).await?; let mut rng = OsRng; @@ -181,13 +99,13 @@ where // check if we already have details associated with this particular gateway // and if so, see if we can overwrite it let selected_id = selected_gateway.gateway_id().to_base58_string(); - if _has_gateway_details(details_store, &selected_id).await? && !overwrite_data { + if has_gateway_details(details_store, &selected_id).await? && !overwrite_data { return Err(ClientCoreError::ForbiddenGatewayKeyOverwrite { gateway_id: selected_id, }); } - let (gateway_details, client) = match selected_gateway { + let (gateway_details, authenticated_ephemeral_client) = match selected_gateway { SelectedGateway::Remote { gateway_id, gateway_owner_address, @@ -196,7 +114,8 @@ where // if we're using a 'normal' gateway setup, do register let our_identity = client_keys.identity_keypair(); let registration = - helpers::register_with_gateway(gateway_id, gateway_listener, our_identity).await?; + helpers::register_with_gateway(gateway_id, gateway_listener.clone(), our_identity) + .await?; ( GatewayDetails::new_remote( gateway_id, @@ -216,13 +135,15 @@ where ), }; + let gateway_registration = gateway_details.into(); + // persist gateway details - _store_gateway_details(details_store, &gateway_details).await?; + store_gateway_details(details_store, &gateway_registration).await?; Ok(InitialisationResult { - gateway_registration: gateway_details.into(), + gateway_registration, client_keys, - authenticated_ephemeral_client: client, + authenticated_ephemeral_client, }) } @@ -238,12 +159,12 @@ where D::StorageError: Send + Sync + 'static, { let loaded_details = if let Some(gateway_id) = gateway_id { - _load_gateway_details(details_store, &gateway_id).await? + load_gateway_details(details_store, &gateway_id).await? } else { - _load_active_gateway_details(details_store).await? + load_active_gateway_details(details_store).await? }; - let loaded_keys = _load_client_keys(key_store).await?; + let loaded_keys = load_client_keys(key_store).await?; // no need to persist anything as we got everything from the storage Ok(InitialisationResult::new_loaded( diff --git a/nym-connect/desktop/src-tauri/src/config/upgrade.rs b/nym-connect/desktop/src-tauri/src/config/upgrade.rs index 5ec509e733..2c7118196e 100644 --- a/nym-connect/desktop/src-tauri/src/config/upgrade.rs +++ b/nym-connect/desktop/src-tauri/src/config/upgrade.rs @@ -37,7 +37,7 @@ fn persist_gateway_details( details_store .store_to_disk(&persisted_details) .map_err(|source| BackendError::ClientCoreError { - source: ClientCoreError::GatewayDetailsStoreError { + source: ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }, }) diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index eda51a5554..44b6901438 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -126,7 +126,7 @@ fn persist_gateway_details( details_store .store_to_disk(&persisted_details) .map_err(|source| { - IpPacketRouterError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { + IpPacketRouterError::ClientCoreError(ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), }) }) From 5bb96bf42cccac1b881a4cc8b28752ff6b2060ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 14:58:06 +0000 Subject: [PATCH 295/394] additional fixes to key creation --- clients/native/src/commands/mod.rs | 3 - clients/socks5/src/commands/mod.rs | 3 - .../src/backend/fs_backend/mod.rs | 3 +- .../src/backend/mem_backend.rs | 67 +++-- .../client-core/gateways-storage/src/types.rs | 8 +- .../client-core/src/client/base_client/mod.rs | 11 + .../base_client/storage/gateway_details.rs | 282 ------------------ .../src/client/base_client/storage/helpers.rs | 18 +- .../src/client/base_client/storage/mod.rs | 29 +- .../client-core/src/client/key_manager/mod.rs | 261 +--------------- .../src/client/key_manager/persistence.rs | 22 +- common/client-core/src/init/helpers.rs | 1 - common/client-core/src/init/mod.rs | 10 +- common/client-core/src/init/types.rs | 123 ++------ .../src/storage/core_client_traits.rs | 11 +- .../src-tauri/src/operations/export.rs | 4 +- sdk/rust/nym-sdk/examples/change_gateway.rs | 9 + .../examples/manually_handle_storage.rs | 9 +- sdk/rust/nym-sdk/examples/simple.rs | 2 +- sdk/rust/nym-sdk/src/mixnet.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 3 - .../ip-packet-router/src/cli/mod.rs | 3 - .../network-requester/src/cli/mod.rs | 3 - 23 files changed, 148 insertions(+), 739 deletions(-) delete mode 100644 common/client-core/src/client/base_client/storage/gateway_details.rs create mode 100644 sdk/rust/nym-sdk/examples/change_gateway.rs diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 39ab24913f..2c9dfde3cc 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -12,9 +12,6 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_client_core::client::base_client::storage::gateway_details::{ - OnDiskGatewayDetails, PersistedGatewayDetails, -}; use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 24a1112781..47de0929ef 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -13,9 +13,6 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_client_core::client::base_client::storage::gateway_details::{ - OnDiskGatewayDetails, PersistedGatewayDetails, -}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; use nym_client_core::config::{GatewayEndpointConfig, GroupBy, TopologyStructure}; diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index c447d407e2..4b759c0e5f 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::{GatewayDetails, GatewayRegistration}; +use crate::types::GatewayRegistration; use crate::{GatewaysDetailsStore, StorageError}; use async_trait::async_trait; use manager::StorageManager; @@ -26,6 +26,7 @@ impl OnDiskGatewaysDetails { #[async_trait] impl GatewaysDetailsStore for OnDiskGatewaysDetails { type StorageError = error::StorageError; + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 092772c9f0..01385342bb 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -26,52 +26,81 @@ pub struct InMemGatewaysDetails { #[derive(Debug, Default)] struct InMemStorageInner { active_gateway: Option<String>, - gateways: HashMap<String, GatewayDetails>, + gateways: HashMap<String, GatewayRegistration>, } #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] impl GatewaysDetailsStore for InMemGatewaysDetails { type StorageError = InMemStorageError; - async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { - todo!() - } - async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { - // let guard = self.inner.read().await; - // - // let foo = guard.active_gateway.map(|id| { - // // SAFETY: if particular gateway is set as active, its details MUST exist - // #[allow(clippy::unwrap_used)] - // guard.gateways.get(&id).unwrap() - // }); - todo!() - // foo.cloned() + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { + Ok(self.inner.read().await.gateways.contains_key(gateway_id)) + } + + async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { + let guard = self.inner.read().await; + + Ok(guard.active_gateway.as_ref().map(|id| { + // SAFETY: if particular gateway is set as active, its details MUST exist + #[allow(clippy::unwrap_used)] + guard.gateways.get(id).unwrap().clone() + })) } async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { - todo!() + // ensure the gateway with provided id exists + let mut guard = self.inner.write().await; + + if !guard.gateways.contains_key(gateway_id) { + return Err(InMemStorageError::GatewayDoesNotExist { + gateway_id: gateway_id.to_string(), + }); + } + + guard.active_gateway = Some(gateway_id.to_string()); + Ok(()) } async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { - todo!() + Ok(self.inner.read().await.gateways.values().cloned().collect()) } async fn load_gateway_details( &self, gateway_id: &str, ) -> Result<GatewayRegistration, Self::StorageError> { - todo!() + self.inner + .read() + .await + .gateways + .get(gateway_id) + .cloned() + .ok_or(InMemStorageError::GatewayDoesNotExist { + gateway_id: gateway_id.to_string(), + }) } async fn store_gateway_details( &self, details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { - todo!() + self.inner.write().await.gateways.insert( + details.details.gateway_id().to_base58_string(), + details.clone(), + ); + Ok(()) } async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError> { - todo!() + let mut guard = self.inner.write().await; + if let Some(active) = guard.active_gateway.as_ref() { + if active == gateway_id { + guard.active_gateway = None + } + } + guard.gateways.remove(gateway_id); + + Ok(()) } } diff --git a/common/client-core/gateways-storage/src/types.rs b/common/client-core/gateways-storage/src/types.rs index abb20708a3..c165147bba 100644 --- a/common/client-core/gateways-storage/src/types.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -16,13 +16,13 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub const REMOTE_GATEWAY_TYPE: &str = "remote"; pub const CUSTOM_GATEWAY_TYPE: &str = "custom"; -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct GatewayRegistration { pub details: GatewayDetails, pub registration_timestamp: OffsetDateTime, } -#[derive(Debug)] +#[derive(Debug, Clone)] pub enum GatewayDetails { /// Standard details of a remote gateway Remote(RemoteGatewayDetails), @@ -197,7 +197,7 @@ impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct RemoteGatewayDetails { pub gateway_id: identity::PublicKey, @@ -245,7 +245,7 @@ impl From<CustomGatewayDetails> for RawCustomGatewayDetails { } } -#[derive(Debug)] +#[derive(Debug, Clone)] pub struct CustomGatewayDetails { pub gateway_id: identity::PublicKey, pub data: Option<Vec<u8>>, diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index c2400a7dc5..7870c5cc39 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -4,10 +4,12 @@ use super::packet_statistics_control::PacketStatisticsReporter; use super::received_buffer::ReceivedBufferMessage; use super::topology_control::geo_aware_provider::GeoAwareTopologyProvider; +use crate::client::base_client::storage::helpers::store_client_keys; use crate::client::base_client::storage::MixnetClientStorage; use crate::client::cover_traffic_stream::LoopCoverTrafficStream; use crate::client::inbound_messages::{InputMessage, InputMessageReceiver, InputMessageSender}; use crate::client::key_manager::persistence::KeyStore; +use crate::client::key_manager::ClientKeys; use crate::client::mix_traffic::transceiver::{GatewayReceiver, GatewayTransceiver, RemoteGateway}; use crate::client::mix_traffic::{BatchMixMessageSender, MixTrafficController}; use crate::client::packet_statistics_control::PacketStatisticsControl; @@ -51,6 +53,7 @@ use nym_task::{TaskClient, TaskHandle}; use nym_topology::provider_trait::TopologyProvider; use nym_topology::HardcodedTopologyProvider; use nym_validator_client::nyxd::contract_traits::DkgQueryClient; +use rand::rngs::OsRng; use std::fmt::Debug; use std::os::raw::c_int as RawFd; use std::path::Path; @@ -577,6 +580,14 @@ where <S::KeyStore as KeyStore>::StorageError: Sync + Send, <S::GatewaysDetailsStore as GatewaysDetailsStore>::StorageError: Sync + Send, { + // if client keys do not exist already, create and persist them + if key_store.load_keys().await.is_err() { + info!("could not find valid client keys - a new set will be generated"); + let mut rng = OsRng; + let keys = ClientKeys::generate_new(&mut rng); + store_client_keys(keys, key_store).await?; + } + setup_gateway(setup_method, key_store, details_store).await } diff --git a/common/client-core/src/client/base_client/storage/gateway_details.rs b/common/client-core/src/client/base_client/storage/gateway_details.rs deleted file mode 100644 index 552de2dbbd..0000000000 --- a/common/client-core/src/client/base_client/storage/gateway_details.rs +++ /dev/null @@ -1,282 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: Apache-2.0 - -use crate::config::GatewayEndpointConfig; -use crate::error::ClientCoreError; -use async_trait::async_trait; -use log::error; -use nym_gateway_requests::registration::handshake::SharedKeys; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use sha2::{Digest, Sha256}; -use std::error::Error; -use std::ops::Deref; -use tokio::sync::Mutex; -use zeroize::Zeroizing; - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait GatewayDetailsStore { - type StorageError: Error; - - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError>; - - async fn store_gateway_details( - &self, - details: &PersistedGatewayDetails, - ) -> Result<(), Self::StorageError>; -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -#[serde(untagged)] -pub enum PersistedGatewayDetails { - /// Standard details of a remote gateway - Default(PersistedGatewayConfig), - - /// Custom gateway setup, such as for a client embedded inside gateway itself - Custom(PersistedCustomGatewayDetails), -} - -impl PersistedGatewayDetails { - // TODO: this should probably allow for custom verification over T - pub fn validate(&self, shared_key: Option<&SharedKeys>) -> Result<(), ClientCoreError> { - match self { - PersistedGatewayDetails::Default(details) => { - if !details.verify(shared_key.ok_or(ClientCoreError::UnavailableSharedKey)?) { - Err(ClientCoreError::MismatchedGatewayDetails { - gateway_id: details.details.gateway_id.clone(), - }) - } else { - Ok(()) - } - } - PersistedGatewayDetails::Custom(_) => { - if shared_key.is_some() { - error!("using custom persisted gateway setup with shared key present - are you sure that's what you want?"); - // but technically we could still continue. just ignore the key - } - Ok(()) - } - } - } -} - -#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] -pub struct PersistedGatewayConfig { - // TODO: should we also verify correctness of the details themselves? - // i.e. we could include a checksum or tag (via the shared keys) - // counterargument: if we wanted to modify, say, the host information in the stored file on disk, - // in order to actually use it, we'd have to recompute the whole checksum which would be a huge pain. - /// The hash of the shared keys to ensure the correct ones are used with those gateway details. - #[serde(with = "base64")] - key_hash: Vec<u8>, - - /// Actual gateway details being persisted. - pub details: GatewayEndpointConfig, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct PersistedCustomGatewayDetails { - // whatever custom method is used, gateway's identity must be known - pub gateway_id: String, - - #[serde(flatten)] - pub additional_data: Vec<u8>, -} - -impl PersistedGatewayConfig { - pub fn new(details: GatewayEndpointConfig, shared_key: &SharedKeys) -> Self { - let key_bytes = Zeroizing::new(shared_key.to_bytes()); - - let mut key_hasher = Sha256::new(); - key_hasher.update(&key_bytes); - let key_hash = key_hasher.finalize().to_vec(); - - PersistedGatewayConfig { key_hash, details } - } - - pub fn verify(&self, shared_key: &SharedKeys) -> bool { - let key_bytes = Zeroizing::new(shared_key.to_bytes()); - - let mut key_hasher = Sha256::new(); - key_hasher.update(&key_bytes); - let key_hash = key_hasher.finalize(); - - self.key_hash == key_hash.deref() - } -} - -impl PersistedGatewayDetails { - // pub fn new( - // details: GatewayDetails, - // shared_key: Option<&SharedKeys>, - // ) -> Result<Self, ClientCoreError> { - // match details { - // GatewayDetails::Configured(cfg) => { - // let shared_key = shared_key.ok_or(ClientCoreError::UnavailableSharedKey)?; - // Ok(PersistedGatewayDetails::Default( - // PersistedGatewayConfig::new(cfg, shared_key), - // )) - // } - // GatewayDetails::Custom(custom) => Ok(PersistedGatewayDetails::Custom(custom.into())), - // } - // } - // - // pub fn is_custom(&self) -> bool { - // matches!(self, PersistedGatewayDetails::Custom(..)) - // } - // - // pub fn matches(&self, other: &GatewayDetails) -> bool { - // match self { - // PersistedGatewayDetails::Default(default) => { - // if let GatewayDetails::Configured(other_configured) = other { - // &default.details == other_configured - // } else { - // false - // } - // } - // PersistedGatewayDetails::Custom(custom) => { - // if let GatewayDetails::Custom(other_custom) = other { - // custom.gateway_id == other_custom.gateway_id - // && custom.additional_data == other_custom.additional_data - // } else { - // false - // } - // } - // } - // } -} - -// helper to make Vec<u8> serialization use base64 representation to make it human readable -// so that it would be easier for users to copy contents from the disk if they wanted to use it elsewhere -mod base64 { - use base64::{engine::general_purpose::STANDARD, Engine as _}; - use serde::{Deserialize, Deserializer, Serializer}; - - pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> { - serializer.serialize_str(&STANDARD.encode(bytes)) - } - - pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<Vec<u8>, D::Error> { - let s = <String>::deserialize(deserializer)?; - STANDARD.decode(s).map_err(serde::de::Error::custom) - } -} - -#[cfg(not(target_arch = "wasm32"))] -#[derive(Debug, thiserror::Error)] -pub enum OnDiskGatewayDetailsError { - #[error("JSON failure: {0}")] - SerializationFailure(#[from] serde_json::Error), - - #[error("failed to store gateway details to {path}: {err}")] - StoreFailure { - path: String, - #[source] - err: std::io::Error, - }, - - #[error("failed to load gateway details from {path}: {err}")] - LoadFailure { - path: String, - #[source] - err: std::io::Error, - }, -} - -#[cfg(not(target_arch = "wasm32"))] -pub struct OnDiskGatewayDetails { - file_location: std::path::PathBuf, -} - -#[cfg(not(target_arch = "wasm32"))] -impl OnDiskGatewayDetails { - pub fn new<P: AsRef<std::path::Path>>(path: P) -> Self { - OnDiskGatewayDetails { - file_location: path.as_ref().to_owned(), - } - } - - pub fn load_from_disk(&self) -> Result<PersistedGatewayDetails, OnDiskGatewayDetailsError> { - let file = std::fs::File::open(&self.file_location).map_err(|err| { - OnDiskGatewayDetailsError::LoadFailure { - path: self.file_location.display().to_string(), - err, - } - })?; - - Ok(serde_json::from_reader(file)?) - } - - pub fn store_to_disk( - &self, - details: &PersistedGatewayDetails, - ) -> Result<(), OnDiskGatewayDetailsError> { - // ensure the whole directory structure exists - if let Some(parent_dir) = &self.file_location.parent() { - std::fs::create_dir_all(parent_dir).map_err(|err| { - OnDiskGatewayDetailsError::StoreFailure { - path: self.file_location.display().to_string(), - err, - } - })? - } - - let file = std::fs::File::create(&self.file_location).map_err(|err| { - OnDiskGatewayDetailsError::StoreFailure { - path: self.file_location.display().to_string(), - err, - } - })?; - - Ok(serde_json::to_writer_pretty(file, details)?) - } -} - -#[cfg(not(target_arch = "wasm32"))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GatewayDetailsStore for OnDiskGatewayDetails { - type StorageError = OnDiskGatewayDetailsError; - - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> { - self.load_from_disk() - } - - async fn store_gateway_details( - &self, - gateway_details: &PersistedGatewayDetails, - ) -> Result<(), Self::StorageError> { - self.store_to_disk(gateway_details) - } -} - -#[derive(Default)] -pub struct InMemGatewayDetails { - details: Mutex<Option<PersistedGatewayDetails>>, -} - -#[derive(Debug, thiserror::Error)] -#[error("old ephemeral gateway details can't be loaded from storage")] -pub struct EphemeralGatewayDetailsError; - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl GatewayDetailsStore for InMemGatewayDetails { - type StorageError = EphemeralGatewayDetailsError; - - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> { - self.details - .lock() - .await - .clone() - .ok_or(EphemeralGatewayDetailsError) - } - - async fn store_gateway_details( - &self, - gateway_details: &PersistedGatewayDetails, - ) -> Result<(), Self::StorageError> { - *self.details.lock().await = Some(gateway_details.clone()); - Ok(()) - } -} diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index 54535a918e..628942902c 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::key_manager::persistence::KeyStore; -use crate::client::key_manager::KeyManager; +use crate::client::key_manager::ClientKeys; use crate::error::ClientCoreError; use nym_client_core_gateways_storage::{GatewayRegistration, GatewaysDetailsStore}; @@ -88,12 +88,24 @@ where }) } -pub async fn load_client_keys<K>(key_store: &K) -> Result<KeyManager, ClientCoreError> +pub async fn load_client_keys<K>(key_store: &K) -> Result<ClientKeys, ClientCoreError> where K: KeyStore, K::StorageError: Send + Sync + 'static, { - KeyManager::load_keys(key_store) + ClientKeys::load_keys(key_store) + .await + .map_err(|source| ClientCoreError::KeyStoreError { + source: Box::new(source), + }) +} + +pub async fn store_client_keys<K>(keys: ClientKeys, key_store: &K) -> Result<(), ClientCoreError> +where + K: KeyStore, + K::StorageError: Send + Sync + 'static, +{ + keys.persist_keys(key_store) .await .map_err(|source| ClientCoreError::KeyStoreError { source: Box::new(source), diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 55bfb12e36..8a674e80aa 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -4,9 +4,6 @@ // TODO: combine those more closely. Perhaps into a single underlying store. // Like for persistent, on-disk, storage, what's the point of having 3 different databases? -// use crate::client::base_client::storage::gateway_details::{ -// GatewayDetailsStore, InMemGatewayDetails, -// }; use crate::client::key_manager::persistence::{InMemEphemeralKeys, KeyStore}; use crate::client::replies::reply_storage; use crate::client::replies::reply_storage::ReplyStorageBackend; @@ -18,30 +15,24 @@ use nym_credential_storage::storage::Storage as CredentialStorage; feature = "fs-surb-storage", feature = "fs-gateways-storage" ))] -use crate::client::base_client::non_wasm_helpers; -// #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] -// use crate::client::base_client::storage::gateway_details::OnDiskGatewayDetails; -#[cfg(not(target_arch = "wasm32"))] -use crate::client::key_manager::persistence::OnDiskKeys; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] -use crate::client::replies::reply_storage::fs_backend; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] -use crate::config::{self, disk_persistence::CommonClientPaths}; -#[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] -use crate::error::ClientCoreError; +use crate::{ + client::{ + base_client::non_wasm_helpers, key_manager::persistence::OnDiskKeys, + replies::reply_storage::fs_backend, + }, + config::{self, disk_persistence::CommonClientPaths}, + error::ClientCoreError, +}; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; -// fs-gateways pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; -#[deprecated] -pub mod gateway_details; -pub mod helpers; - #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; +pub mod helpers; + // TODO: ideally this should be changed into // `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewayDetailsStore` pub trait MixnetClientStorage { diff --git a/common/client-core/src/client/key_manager/mod.rs b/common/client-core/src/client/key_manager/mod.rs index b15ca52f44..095980e753 100644 --- a/common/client-core/src/client/key_manager/mod.rs +++ b/common/client-core/src/client/key_manager/mod.rs @@ -6,230 +6,11 @@ use nym_crypto::asymmetric::{encryption, identity}; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::acknowledgements::AckKey; use rand::{CryptoRng, RngCore}; -use std::fmt::{Debug, Formatter}; use std::sync::Arc; use zeroize::ZeroizeOnDrop; pub mod persistence; -pub struct ManagedKeys { - client_keys: KeyManager, - active_gateway_keys: Option<Arc<SharedKeys>>, -} -// -// pub enum ManagedKeys { -// Initial(KeyManagerBuilder), -// FullyDerived(KeyManager), -// -// // I really hate the existence of this variant, but I couldn't come up with a better way to handle -// // `Self::deal_with_gateway_key` otherwise. -// Invalidated, -// } -// -// impl Debug for ManagedKeys { -// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { -// match self { -// ManagedKeys::Initial(_) => write!(f, "initial"), -// ManagedKeys::FullyDerived(_) => write!(f, "fully derived"), -// ManagedKeys::Invalidated => write!(f, "invalidated"), -// } -// } -// } -// -// impl From<KeyManagerBuilder> for ManagedKeys { -// fn from(value: KeyManagerBuilder) -> Self { -// ManagedKeys::Initial(value) -// } -// } -// -// impl From<KeyManager> for ManagedKeys { -// fn from(value: KeyManager) -> Self { -// ManagedKeys::FullyDerived(value) -// } -// } -// -impl ManagedKeys { - // pub fn is_valid(&self) -> bool { - // !matches!(self, ManagedKeys::Invalidated) - // } - // - // pub async fn try_load<S: KeyStore>(key_store: &S) -> Result<Self, S::StorageError> { - // Ok(ManagedKeys::FullyDerived( - // KeyManager::load_keys(key_store).await?, - // )) - // } - // - // pub fn generate_new<R>(rng: &mut R) -> Self - // where - // R: RngCore + CryptoRng, - // { - // ManagedKeys::Initial(KeyManagerBuilder::new(rng)) - // } - // - // pub async fn load_or_generate<R, S>(rng: &mut R, key_store: &S) -> Self - // where - // R: RngCore + CryptoRng, - // S: KeyStore, - // { - // Self::try_load(key_store) - // .await - // .unwrap_or_else(|_| Self::generate_new(rng)) - // } - // - // pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { - // match self { - // ManagedKeys::Initial(keys) => keys.identity_keypair(), - // ManagedKeys::FullyDerived(keys) => keys.identity_keypair(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { - // match self { - // ManagedKeys::Initial(keys) => keys.encryption_keypair(), - // ManagedKeys::FullyDerived(keys) => keys.encryption_keypair(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn ack_key(&self) -> Arc<AckKey> { - // match self { - // ManagedKeys::Initial(keys) => keys.ack_key(), - // ManagedKeys::FullyDerived(keys) => keys.ack_key(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn must_get_gateway_shared_key(&self) -> Arc<SharedKeys> { - // self.gateway_shared_key() - // .expect("failed to extract gateway shared key") - // } - // - // pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { - // match self { - // ManagedKeys::Initial(_) => None, - // ManagedKeys::FullyDerived(keys) => keys.gateway_shared_key(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn identity_public_key(&self) -> &identity::PublicKey { - // match self { - // ManagedKeys::Initial(keys) => keys.identity_keypair.public_key(), - // ManagedKeys::FullyDerived(keys) => keys.identity_keypair.public_key(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn encryption_public_key(&self) -> &encryption::PublicKey { - // match self { - // ManagedKeys::Initial(keys) => keys.encryption_keypair.public_key(), - // ManagedKeys::FullyDerived(keys) => keys.encryption_keypair.public_key(), - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // } - // } - // - // pub fn ensure_gateway_key(&self, gateway_shared_key: Option<Arc<SharedKeys>>) { - // if let ManagedKeys::FullyDerived(key_manager) = &self { - // if self.gateway_shared_key().is_none() && gateway_shared_key.is_none() { - // // the key doesn't exist in either state - // return; - // } - // - // if gateway_shared_key.is_some() && self.gateway_shared_key().is_none() - // || gateway_shared_key.is_none() && self.gateway_shared_key().is_some() - // { - // // if one is provided whilst the other is not... - // // TODO: should this actually panic or return an error? would this branch be possible - // // under normal operation? - // panic!("inconsistent re-derived gateway key") - // } - // - // // here we know both keys MUST exist - // let provided = gateway_shared_key.unwrap(); - // if !Arc::ptr_eq(key_manager.must_get_gateway_shared_key(), &provided) - // || *key_manager.must_get_gateway_shared_key() != provided - // { - // // this should NEVER happen thus panic here - // panic!("derived fresh gateway shared key whilst already holding one!") - // } - // } - // } - // - // pub async fn deal_with_gateway_key<S: KeyStore>( - // &mut self, - // gateway_shared_key: Option<Arc<SharedKeys>>, - // key_store: &S, - // ) -> Result<(), S::StorageError> { - // let key_manager = match std::mem::replace(self, ManagedKeys::Invalidated) { - // ManagedKeys::Initial(keys) => { - // let key_manager = keys.insert_maybe_gateway_shared_key(gateway_shared_key); - // key_manager.persist_keys(key_store).await?; - // key_manager - // } - // ManagedKeys::FullyDerived(key_manager) => { - // self.ensure_gateway_key(gateway_shared_key); - // key_manager - // } - // ManagedKeys::Invalidated => unreachable!("the managed keys got invalidated"), - // }; - // - // *self = ManagedKeys::FullyDerived(key_manager); - // Ok(()) - // } -} -// -// // all of the keys really shouldn't be wrapped in `Arc`, but due to how the gateway client is currently -// // constructed, changing that would require more work than what it's worth -// pub struct KeyManagerBuilder { -// /// identity key associated with the client instance. -// identity_keypair: Arc<identity::KeyPair>, -// -// /// encryption key associated with the client instance. -// encryption_keypair: Arc<encryption::KeyPair>, -// -// /// key used for producing and processing acknowledgement packets. -// ack_key: Arc<AckKey>, -// } -// -// impl KeyManagerBuilder { -// /// Creates new instance of a [`KeyManager`] -// pub fn new<R>(rng: &mut R) -> Self -// where -// R: RngCore + CryptoRng, -// { -// KeyManagerBuilder { -// identity_keypair: Arc::new(identity::KeyPair::new(rng)), -// encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), -// ack_key: Arc::new(AckKey::new(rng)), -// } -// } -// -// pub fn insert_maybe_gateway_shared_key( -// self, -// gateway_shared_key: Option<Arc<SharedKeys>>, -// ) -> KeyManager { -// KeyManager { -// identity_keypair: self.identity_keypair, -// encryption_keypair: self.encryption_keypair, -// gateway_shared_key, -// ack_key: self.ack_key, -// } -// } -// -// pub fn identity_keypair(&self) -> Arc<identity::KeyPair> { -// Arc::clone(&self.identity_keypair) -// } -// -// pub fn encryption_keypair(&self) -> Arc<encryption::KeyPair> { -// Arc::clone(&self.encryption_keypair) -// } -// -// pub fn ack_key(&self) -> Arc<AckKey> { -// Arc::clone(&self.ack_key) -// } -// } - // Note: to support key rotation in the future, all keys will require adding an extra smart pointer, // most likely an AtomicCell, or if it doesn't work as I think it does, a Mutex. Although I think // AtomicCell includes a Mutex implicitly if the underlying type does not work atomically. @@ -238,30 +19,24 @@ impl ManagedKeys { // Remember that Arc<T> has Deref implementation for T #[derive(Clone)] -pub struct KeyManager { +pub struct ClientKeys { /// identity key associated with the client instance. identity_keypair: Arc<identity::KeyPair>, /// encryption key associated with the client instance. encryption_keypair: Arc<encryption::KeyPair>, - // /// shared key derived with the gateway during "registration handshake" - // // I'm not a fan of how we broke the nice transition of `KeyManagerBuilder` -> `KeyManager` - // // by making this field optional. - // // However, it has to be optional for when we use embedded NR inside a gateway, - // // since it won't have a shared key (because why would it?) - // gateway_shared_key: Option<Arc<SharedKeys>>, /// key used for producing and processing acknowledgement packets. ack_key: Arc<AckKey>, } -impl KeyManager { - /// Creates new instance of a [`KeyManager`] +impl ClientKeys { + /// Creates new instance of a [`ClientKeys`] pub fn generate_new<R>(rng: &mut R) -> Self where R: RngCore + CryptoRng, { - KeyManager { + ClientKeys { identity_keypair: Arc::new(identity::KeyPair::new(rng)), encryption_keypair: Arc::new(encryption::KeyPair::new(rng)), ack_key: Arc::new(AckKey::new(rng)), @@ -271,13 +46,11 @@ impl KeyManager { pub fn from_keys( id_keypair: identity::KeyPair, enc_keypair: encryption::KeyPair, - // gateway_shared_key: Option<SharedKeys>, ack_key: AckKey, ) -> Self { Self { identity_keypair: Arc::new(id_keypair), encryption_keypair: Arc::new(enc_keypair), - // gateway_shared_key: gateway_shared_key.map(Arc::new), ack_key: Arc::new(ack_key), } } @@ -303,32 +76,6 @@ impl KeyManager { pub fn ack_key(&self) -> Arc<AckKey> { Arc::clone(&self.ack_key) } - - // fn must_get_gateway_shared_key(&self) -> &Arc<SharedKeys> { - // self.gateway_shared_key - // .as_ref() - // .expect("gateway shared key is unavailable") - // } - // - // pub fn uses_custom_gateway(&self) -> bool { - // self.gateway_shared_key.is_none() - // } - // - // /// Gets an atomically reference counted pointer to [`SharedKey`]. - // pub fn gateway_shared_key(&self) -> Option<Arc<SharedKeys>> { - // self.gateway_shared_key.as_ref().map(Arc::clone) - // } - - // pub fn remove_gateway_key(self) -> KeyManagerBuilder { - // if Arc::strong_count(self.must_get_gateway_shared_key()) > 1 { - // panic!("attempted to remove gateway key whilst still holding multiple references!") - // } - // KeyManagerBuilder { - // identity_keypair: self.identity_keypair, - // encryption_keypair: self.encryption_keypair, - // ack_key: self.ack_key, - // } - // } } fn _assert_keys_zeroize_on_drop() { diff --git a/common/client-core/src/client/key_manager/persistence.rs b/common/client-core/src/client/key_manager/persistence.rs index a7a4196d30..e2312194b0 100644 --- a/common/client-core/src/client/key_manager/persistence.rs +++ b/common/client-core/src/client/key_manager/persistence.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::key_manager::KeyManager; +use crate::client::key_manager::ClientKeys; use async_trait::async_trait; use std::error::Error; use tokio::sync::Mutex; @@ -25,9 +25,9 @@ use nym_sphinx::acknowledgements::AckKey; pub trait KeyStore { type StorageError: Error; - async fn load_keys(&self) -> Result<KeyManager, Self::StorageError>; + async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError>; - async fn store_keys(&self, keys: &KeyManager) -> Result<(), Self::StorageError>; + async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError>; } #[cfg(not(target_arch = "wasm32"))] @@ -148,19 +148,19 @@ impl OnDiskKeys { }) } - fn load_keys(&self) -> Result<KeyManager, OnDiskKeysError> { + fn load_keys(&self) -> Result<ClientKeys, OnDiskKeysError> { let identity_keypair = self.load_identity_keypair()?; let encryption_keypair = self.load_encryption_keypair()?; let ack_key: AckKey = self.load_key(self.paths.ack_key(), "ack key")?; - Ok(KeyManager::from_keys( + Ok(ClientKeys::from_keys( identity_keypair, encryption_keypair, ack_key, )) } - fn store_keys(&self, keys: &KeyManager) -> Result<(), OnDiskKeysError> { + fn store_keys(&self, keys: &ClientKeys) -> Result<(), OnDiskKeysError> { let identity_paths = self.paths.identity_key_pair_path(); let encryption_paths = self.paths.encryption_key_pair_path(); @@ -186,18 +186,18 @@ impl OnDiskKeys { impl KeyStore for OnDiskKeys { type StorageError = OnDiskKeysError; - async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> { + async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> { self.load_keys() } - async fn store_keys(&self, keys: &KeyManager) -> Result<(), Self::StorageError> { + async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError> { self.store_keys(keys) } } #[derive(Default)] pub struct InMemEphemeralKeys { - keys: Mutex<Option<KeyManager>>, + keys: Mutex<Option<ClientKeys>>, } #[derive(Debug, thiserror::Error)] @@ -209,11 +209,11 @@ pub struct EphemeralKeysError; impl KeyStore for InMemEphemeralKeys { type StorageError = EphemeralKeysError; - async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> { + async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> { self.keys.lock().await.clone().ok_or(EphemeralKeysError) } - async fn store_keys(&self, keys: &KeyManager) -> Result<(), Self::StorageError> { + async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError> { *self.keys.lock().await = Some(keys.clone()); Ok(()) } diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index a0c7c6c8de..a5cd4a4a43 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -1,7 +1,6 @@ // Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::GatewayEndpointConfig; use crate::error::ClientCoreError; use crate::init::types::RegistrationResult; use futures::{SinkExt, StreamExt}; diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 7dce228834..d82faaba69 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -8,7 +8,7 @@ use crate::client::base_client::storage::helpers::{ store_gateway_details, }; use crate::client::key_manager::persistence::KeyStore; -use crate::client::key_manager::KeyManager; +use crate::client::key_manager::ClientKeys; use crate::error::ClientCoreError; use crate::init::helpers::{ choose_gateway_by_latency, get_specified_gateway, uniformly_random_gateway, @@ -38,7 +38,7 @@ where K: KeyStore, K::StorageError: Send + Sync + 'static, { - KeyManager::generate_new(rng) + ClientKeys::generate_new(rng) .persist_keys(key_store) .await .map_err(|source| ClientCoreError::KeyStoreError { @@ -176,7 +176,7 @@ where fn reuse_gateway_connection( authenticated_ephemeral_client: InitGatewayClient, gateway_registration: GatewayRegistration, - client_keys: KeyManager, + client_keys: ClientKeys, ) -> InitialisationResult { InitialisationResult { gateway_registration, @@ -218,10 +218,10 @@ where GatewaySetup::ReuseConnection { authenticated_ephemeral_client, gateway_details, - managed_keys, + client_keys: managed_keys, } => Ok(reuse_gateway_connection( authenticated_ephemeral_client, - gateway_details, + *gateway_details, managed_keys, )), } diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 563205eb22..7c0f1ae71b 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -2,23 +2,21 @@ // SPDX-License-Identifier: Apache-2.0 use crate::client::key_manager::persistence::KeyStore; -use crate::client::key_manager::{KeyManager, ManagedKeys}; -use crate::config::{Config, GatewayEndpointConfig}; +use crate::client::key_manager::ClientKeys; +use crate::config::Config; use crate::error::ClientCoreError; use crate::init::{setup_gateway, use_loaded_gateway_details}; use nym_client_core_gateways_storage::{ - BadGateway, GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails, + GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails, }; use nym_crypto::asymmetric::identity; use nym_gateway_client::client::InitGatewayClient; use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::addressing::clients::Recipient; -use nym_sphinx::addressing::nodes::NodeIdentity; use nym_topology::gateway; use nym_validator_client::client::IdentityKey; use nym_validator_client::nyxd::AccountId; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; +use serde::Serialize; use std::fmt::Display; use std::str::FromStr; use std::sync::Arc; @@ -111,12 +109,12 @@ pub struct RegistrationResult { /// if this was the first time this client registered pub struct InitialisationResult { pub gateway_registration: GatewayRegistration, - pub client_keys: KeyManager, + pub client_keys: ClientKeys, pub authenticated_ephemeral_client: Option<InitGatewayClient>, } impl InitialisationResult { - pub fn new_loaded(gateway_registration: GatewayRegistration, client_keys: KeyManager) -> Self { + pub fn new_loaded(gateway_registration: GatewayRegistration, client_keys: ClientKeys) -> Self { InitialisationResult { gateway_registration, client_keys, @@ -144,89 +142,6 @@ impl InitialisationResult { ) } } -// -// /// Details of particular gateway client got registered with -// #[derive(Debug, Clone)] -// pub enum GatewayDetails { -// /// Standard details of a remote gateway -// Configured(GatewayEndpointConfig), -// -// /// Custom gateway setup, such as for a client embedded inside gateway itself -// Custom(CustomGatewayDetails), -// } -// -// #[derive(Debug, Clone, Serialize, Deserialize)] -// pub struct CustomGatewayDetails { -// // whatever custom method is used, gateway's identity must be known -// pub gateway_id: String, -// -// pub additional_data: Vec<u8>, -// } -// -// impl CustomGatewayDetails { -// pub fn new(gateway_id: String, additional_data: Vec<u8>) -> Self { -// Self { -// gateway_id, -// additional_data, -// } -// } -// } -// -// impl GatewayDetails { -// pub fn try_get_configured_endpoint(&self) -> Option<&GatewayEndpointConfig> { -// if let GatewayDetails::Configured(endpoint) = &self { -// Some(endpoint) -// } else { -// None -// } -// } -// -// pub fn is_custom(&self) -> bool { -// matches!(self, GatewayDetails::Custom(_)) -// } -// -// pub fn gateway_id(&self) -> &str { -// match self { -// GatewayDetails::Configured(cfg) => &cfg.gateway_id, -// GatewayDetails::Custom(custom) => &custom.gateway_id, -// } -// } -// } -// -// impl From<GatewayEndpointConfig> for GatewayDetails { -// fn from(value: GatewayEndpointConfig) -> Self { -// GatewayDetails::Configured(value) -// } -// } -// -// impl From<PersistedCustomGatewayDetails> for CustomGatewayDetails { -// fn from(value: PersistedCustomGatewayDetails) -> Self { -// CustomGatewayDetails { -// gateway_id: value.gateway_id, -// additional_data: value.additional_data, -// } -// } -// } -// -// impl From<CustomGatewayDetails> for PersistedCustomGatewayDetails { -// fn from(value: CustomGatewayDetails) -> Self { -// PersistedCustomGatewayDetails { -// gateway_id: value.gateway_id, -// additional_data: value.additional_data, -// } -// } -// } -// -// impl From<PersistedGatewayDetails> for GatewayDetails { -// fn from(value: PersistedGatewayDetails) -> Self { -// match value { -// PersistedGatewayDetails::Default(default) => { -// GatewayDetails::Configured(default.details) -// } -// PersistedGatewayDetails::Custom(custom) => GatewayDetails::Custom(custom.into()), -// } -// } -// } #[derive(Clone, Debug)] pub enum GatewaySelectionSpecification { @@ -301,24 +216,23 @@ pub enum GatewaySetup { authenticated_ephemeral_client: InitGatewayClient, // Details of this pre-initialised client (i.e. gateway and keys) - gateway_details: GatewayRegistration, + gateway_details: Box<GatewayRegistration>, - managed_keys: KeyManager, + client_keys: ClientKeys, }, } impl GatewaySetup { pub fn try_reuse_connection(init_res: InitialisationResult) -> Result<Self, ClientCoreError> { - todo!() - // if let Some(authenticated_ephemeral_client) = init_res.authenticated_ephemeral_client { - // Ok(GatewaySetup::ReuseConnection { - // authenticated_ephemeral_client, - // gateway_details: init_res.gateway_details, - // managed_keys: init_res.managed_keys, - // }) - // } else { - // Err(ClientCoreError::NoInitClientPresent) - // } + if let Some(authenticated_ephemeral_client) = init_res.authenticated_ephemeral_client { + Ok(GatewaySetup::ReuseConnection { + authenticated_ephemeral_client, + gateway_details: Box::new(init_res.gateway_registration), + client_keys: init_res.client_keys, + }) + } else { + Err(ClientCoreError::NoInitClientPresent) + } } pub async fn try_setup<K, D>( @@ -332,8 +246,7 @@ impl GatewaySetup { K::StorageError: Send + Sync + 'static, D::StorageError: Send + Sync + 'static, { - todo!() - // setup_gateway(self, key_store, details_store).await + setup_gateway(self, key_store, details_store).await } pub fn is_must_load(&self) -> bool { diff --git a/common/wasm/client-core/src/storage/core_client_traits.rs b/common/wasm/client-core/src/storage/core_client_traits.rs index 7e4ae13e03..dde0b89f08 100644 --- a/common/wasm/client-core/src/storage/core_client_traits.rs +++ b/common/wasm/client-core/src/storage/core_client_traits.rs @@ -7,12 +7,9 @@ use crate::helpers::setup_reply_surb_storage_backend; use crate::storage::wasm_client_traits::WasmClientStorage; use crate::storage::ClientStorage; use async_trait::async_trait; -use nym_client_core::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, PersistedGatewayDetails, -}; use nym_client_core::client::base_client::storage::MixnetClientStorage; use nym_client_core::client::key_manager::persistence::KeyStore; -use nym_client_core::client::key_manager::KeyManager; +use nym_client_core::client::key_manager::ClientKeys; use nym_client_core::client::replies::reply_storage::browser_backend; use nym_credential_storage::ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage; use wasm_utils::console_log; @@ -68,7 +65,7 @@ impl MixnetClientStorage for FullWasmClientStorage { impl KeyStore for ClientStorage { type StorageError = WasmCoreError; - async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> { + async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> { console_log!("attempting to load cryptographic keys..."); // all keys implement `ZeroizeOnDrop`, so if we return an Error, whatever was already loaded will be cleared @@ -77,7 +74,7 @@ impl KeyStore for ClientStorage { let ack_keypair = self.must_read_ack_key().await?; let gateway_shared_key = self.must_read_gateway_shared_key().await?; - Ok(KeyManager::from_keys( + Ok(ClientKeys::from_keys( identity_keypair, encryption_keypair, Some(gateway_shared_key), @@ -85,7 +82,7 @@ impl KeyStore for ClientStorage { )) } - async fn store_keys(&self, keys: &KeyManager) -> Result<(), Self::StorageError> { + async fn store_keys(&self, keys: &ClientKeys) -> Result<(), Self::StorageError> { console_log!("attempting to store cryptographic keys..."); self.store_identity_keypair(&keys.identity_keypair()) diff --git a/nym-connect/desktop/src-tauri/src/operations/export.rs b/nym-connect/desktop/src-tauri/src/operations/export.rs index 3b11891e9c..a8c53e9d37 100644 --- a/nym-connect/desktop/src-tauri/src/operations/export.rs +++ b/nym-connect/desktop/src-tauri/src/operations/export.rs @@ -7,7 +7,7 @@ use crate::{ state::State, }; use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::client::key_manager::KeyManager; +use nym_client_core::client::key_manager::ClientKeys; use nym_crypto::asymmetric::identity; pub async fn get_identity_key( @@ -23,7 +23,7 @@ pub async fn get_identity_key( // wtf, why are we loading EVERYTHING to just get identity key?? let key_store = OnDiskKeys::from(paths); let key_manager = - KeyManager::load_keys(&key_store) + ClientKeys::load_keys(&key_store) .await .map_err(|err| BackendError::UnableToLoadKeys { source: Box::new(err), diff --git a/sdk/rust/nym-sdk/examples/change_gateway.rs b/sdk/rust/nym-sdk/examples/change_gateway.rs new file mode 100644 index 0000000000..7a6771a7b9 --- /dev/null +++ b/sdk/rust/nym-sdk/examples/change_gateway.rs @@ -0,0 +1,9 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +#[tokio::main] +async fn main() { + nym_bin_common::logging::setup_logging(); + + todo!() +} diff --git a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs index b4844005bf..8b1cce1fc1 100644 --- a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs +++ b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs @@ -1,8 +1,5 @@ -use nym_client_core::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, PersistedGatewayDetails, -}; use nym_sdk::mixnet::{ - self, EmptyReplyStorage, EphemeralCredentialStorage, KeyManager, KeyStore, MixnetClientStorage, + self, ClientKeys, EmptyReplyStorage, EphemeralCredentialStorage, KeyStore, MixnetClientStorage, MixnetMessageSender, }; use nym_topology::provider_trait::async_trait; @@ -93,13 +90,13 @@ struct MockKeyStore; impl KeyStore for MockKeyStore { type StorageError = MyError; - async fn load_keys(&self) -> Result<KeyManager, Self::StorageError> { + async fn load_keys(&self) -> Result<ClientKeys, Self::StorageError> { println!("loading stored keys"); Err(MyError) } - async fn store_keys(&self, _keys: &KeyManager) -> Result<(), Self::StorageError> { + async fn store_keys(&self, _keys: &ClientKeys) -> Result<(), Self::StorageError> { println!("storing keys"); Ok(()) diff --git a/sdk/rust/nym-sdk/examples/simple.rs b/sdk/rust/nym-sdk/examples/simple.rs index 14720ba24c..72b6568b6d 100644 --- a/sdk/rust/nym-sdk/examples/simple.rs +++ b/sdk/rust/nym-sdk/examples/simple.rs @@ -12,7 +12,7 @@ async fn main() { let our_address = client.nym_address(); println!("Our client nym address is: {our_address}"); - // Send a message throught the mixnet to ourselves + // Send a message through the mixnet to ourselves client .send_plain_message(*our_address, "hello there") .await diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index b54ef462ee..41fb99998d 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -48,7 +48,7 @@ pub use nym_client_core::{ inbound_messages::InputMessage, key_manager::{ persistence::{InMemEphemeralKeys, KeyStore, OnDiskKeys}, - KeyManager, + ClientKeys, }, replies::reply_storage::{ fs_backend::Backend as ReplyStorage, CombinedReplyStorage, Empty as EmptyReplyStorage, diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index bba70e96a1..56666b1c0d 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -11,9 +11,6 @@ use crate::{Error, Result}; use futures::channel::mpsc; use futures::StreamExt; use log::warn; -use nym_client_core::client::base_client::storage::gateway_details::{ - GatewayDetailsStore, PersistedGatewayDetails, -}; use nym_client_core::client::base_client::storage::{ Ephemeral, GatewaysDetailsStore, MixnetClientStorage, OnDiskPersistent, }; diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index 44b6901438..c2ef5b800e 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -2,9 +2,6 @@ use clap::{CommandFactory, Parser, Subcommand}; use log::{error, trace}; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; -use nym_client_core::client::base_client::storage::gateway_details::{ - OnDiskGatewayDetails, PersistedGatewayDetails, -}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index fb0b8699f3..73710781a1 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -14,9 +14,6 @@ use log::{error, info, trace}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; -use nym_client_core::client::base_client::storage::gateway_details::{ - OnDiskGatewayDetails, PersistedGatewayDetails, -}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; From c7f7e7709928343818a70106ac133ba2415a9525 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 15:14:51 +0000 Subject: [PATCH 296/394] updated config templates --- clients/native/src/client/config/template.rs | 10 +++------- clients/socks5/src/config/template.rs | 12 ++++------- common/client-core/src/lib.rs | 5 ----- .../src/config/old_config_v1_1_33.rs | 2 +- common/socks5-client-core/src/socks/server.rs | 6 +++--- .../desktop/src-tauri/src/config/mod.rs | 2 +- .../desktop/src-tauri/src/config/template.rs | 2 +- .../socks5-listener/src/config/template.rs | 20 ++++--------------- .../ip-packet-router/src/config/template.rs | 12 ++++------- .../network-requester/src/config/template.rs | 12 ++++------- 10 files changed, 25 insertions(+), 58 deletions(-) diff --git a/clients/native/src/client/config/template.rs b/clients/native/src/client/config/template.rs index 413b61790d..965fc07991 100644 --- a/clients/native/src/client/config/template.rs +++ b/clients/native/src/client/config/template.rs @@ -50,10 +50,6 @@ keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key # Path to file containing public encryption key. keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}' -# A gateway specific, optional, base58 stringified shared key used for -# communication with particular gateway. -keys.gateway_shared_key_file = '{{ storage_paths.keys.gateway_shared_key_file }}' - # Path to file containing key used for encrypting and decrypting the content of an # acknowledgement so that nobody besides the client knows which packet it refers to. keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' @@ -64,9 +60,9 @@ credentials_database = '{{ storage_paths.credentials_database }}' # Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. reply_surb_database = '{{ storage_paths.reply_surb_database }}' -# Path to the file containing information about gateway used by this client, -# i.e. details such as its public key, owner address or the network information. -gateway_details = '{{ storage_paths.gateway_details }}' +# Path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +gateway_registrations = '{{ storage_paths.gateway_registrations }}' ##### socket config options ##### diff --git a/clients/socks5/src/config/template.rs b/clients/socks5/src/config/template.rs index 764a7c6884..07556a5401 100644 --- a/clients/socks5/src/config/template.rs +++ b/clients/socks5/src/config/template.rs @@ -50,10 +50,6 @@ keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key # Path to file containing public encryption key. keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}' -# A gateway specific, optional, base58 stringified shared key used for -# communication with particular gateway. -keys.gateway_shared_key_file = '{{ storage_paths.keys.gateway_shared_key_file }}' - # Path to file containing key used for encrypting and decrypting the content of an # acknowledgement so that nobody besides the client knows which packet it refers to. keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' @@ -64,9 +60,9 @@ credentials_database = '{{ storage_paths.credentials_database }}' # Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. reply_surb_database = '{{ storage_paths.reply_surb_database }}' -# Path to the file containing information about gateway used by this client, -# i.e. details such as its public key, owner address or the network information. -gateway_details = '{{ storage_paths.gateway_details }}' +# Path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +gateway_registrations = '{{ storage_paths.gateway_registrations }}' ##### socket config options ##### @@ -77,7 +73,7 @@ provider_mix_address = '{{ core.socks5.provider_mix_address }}' # The address on which the client will be listening for incoming requests # (default: 127.0.0.1:1080) -bind_adddress = '{{ core.socks5.bind_adddress }}' +bind_address = '{{ core.socks5.bind_address }}' # Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. # While this is going to hide its actual address information, it will make the actual communication diff --git a/common/client-core/src/lib.rs b/common/client-core/src/lib.rs index 8c84737049..1eb90ddcf7 100644 --- a/common/client-core/src/lib.rs +++ b/common/client-core/src/lib.rs @@ -32,8 +32,3 @@ where { tokio::spawn(future); } - -fn unused_function() { - let with_unused_variable = 42; - todo!("update all client config templates after changes stabilise") -} diff --git a/common/socks5-client-core/src/config/old_config_v1_1_33.rs b/common/socks5-client-core/src/config/old_config_v1_1_33.rs index c306d42888..715b9d108a 100644 --- a/common/socks5-client-core/src/config/old_config_v1_1_33.rs +++ b/common/socks5-client-core/src/config/old_config_v1_1_33.rs @@ -38,7 +38,7 @@ pub struct Socks5V1_1_33 { /// The address on which the client will be listening for incoming requests /// (default: 127.0.0.1:1080) // there was a typo in here, so accept the wrong name for the purposes of backwards compatibility - #[serde(alias = "bind_adddress")] + #[serde(alias = "bind_address")] pub bind_address: SocketAddr, /// The mix address of the provider to which all requests are going to be sent. diff --git a/common/socks5-client-core/src/socks/server.rs b/common/socks5-client-core/src/socks/server.rs index a67ed64e19..1a3fc22f3f 100644 --- a/common/socks5-client-core/src/socks/server.rs +++ b/common/socks5-client-core/src/socks/server.rs @@ -33,7 +33,7 @@ impl NymSocksServer { /// Create a new SphinxSocks instance #[allow(clippy::too_many_arguments)] pub(crate) fn new( - bind_adddress: SocketAddr, + bind_address: SocketAddr, authenticator: Authenticator, service_provider: Recipient, self_address: Recipient, @@ -42,10 +42,10 @@ impl NymSocksServer { shutdown: TaskClient, packet_type: PacketType, ) -> Self { - info!("Listening on {bind_adddress}"); + info!("Listening on {bind_address}"); NymSocksServer { authenticator, - listening_address: bind_adddress, + listening_address: bind_address, service_provider, self_address, client_config, diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 3426cf36b2..34176af06a 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -255,7 +255,7 @@ fn print_saved_config(config: &Config, gateway_details: &GatewayEndpointConfig) ); log::info!( "Service provider port: {}", - config.core.socks5.bind_adddress.port() + config.core.socks5.bind_address.port() ); log::info!("Client configuration completed."); } diff --git a/nym-connect/desktop/src-tauri/src/config/template.rs b/nym-connect/desktop/src-tauri/src/config/template.rs index 27e2ed435a..3de6a1be5e 100644 --- a/nym-connect/desktop/src-tauri/src/config/template.rs +++ b/nym-connect/desktop/src-tauri/src/config/template.rs @@ -78,7 +78,7 @@ provider_mix_address = '{{ core.socks5.provider_mix_address }}' # The address on which the client will be listening for incoming requests # (default: 127.0.0.1:1080) -bind_adddress = '{{ core.socks5.bind_adddress }}' +bind_address = '{{ core.socks5.bind_address }}' # Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. # While this is going to hide its actual address information, it will make the actual communication diff --git a/sdk/lib/socks5-listener/src/config/template.rs b/sdk/lib/socks5-listener/src/config/template.rs index e310ef2e32..e2ad4c414d 100644 --- a/sdk/lib/socks5-listener/src/config/template.rs +++ b/sdk/lib/socks5-listener/src/config/template.rs @@ -50,10 +50,6 @@ keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key # Path to file containing public encryption key. keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}' -# A gateway specific, optional, base58 stringified shared key used for -# communication with particular gateway. -keys.gateway_shared_key_file = '{{ storage_paths.keys.gateway_shared_key_file }}' - # Path to file containing key used for encrypting and decrypting the content of an # acknowledgement so that nobody besides the client knows which packet it refers to. keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' @@ -64,17 +60,9 @@ credentials_database = '{{ storage_paths.credentials_database }}' # Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. reply_surb_database = '{{ storage_paths.reply_surb_database }}' -# DEPRECATED -[core.client.gateway_endpoint] -# ID of the gateway from which the client should be fetching messages. -gateway_id = '{{ core.client.gateway_endpoint.gateway_id }}' - -# Address of the gateway owner to which the client should send messages. -gateway_owner = '{{ core.client.gateway_endpoint.gateway_owner }}' - -# Address of the gateway listener to which all client requests should be sent. -gateway_listener = '{{ core.client.gateway_endpoint.gateway_listener }}' - +# Path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +gateway_registrations = '{{ storage_paths.gateway_registrations }}' ##### socket config options ##### @@ -85,7 +73,7 @@ provider_mix_address = '{{ core.socks5.provider_mix_address }}' # The address on which the client will be listening for incoming requests # (default: 127.0.0.1:1080) -bind_adddress = '{{ core.socks5.bind_adddress }}' +bind_address = '{{ core.socks5.bind_address }}' # Specifies whether this client is going to use an anonymous sender tag for communication with the service provider. # While this is going to hide its actual address information, it will make the actual communication diff --git a/service-providers/ip-packet-router/src/config/template.rs b/service-providers/ip-packet-router/src/config/template.rs index bbd9e18d5d..ab5db7bbe8 100644 --- a/service-providers/ip-packet-router/src/config/template.rs +++ b/service-providers/ip-packet-router/src/config/template.rs @@ -51,10 +51,6 @@ keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key # Path to file containing public encryption key. keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}' -# A gateway specific, optional, base58 stringified shared key used for -# communication with particular gateway. -keys.gateway_shared_key_file = '{{ storage_paths.keys.gateway_shared_key_file }}' - # Path to file containing key used for encrypting and decrypting the content of an # acknowledgement so that nobody besides the client knows which packet it refers to. keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' @@ -62,13 +58,13 @@ keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' # Path to the database containing bandwidth credentials credentials_database = '{{ storage_paths.credentials_database }}' -# Path to the file containing information about gateway used by this client, -# i.e. details such as its public key, owner address or the network information. -gateway_details = '{{ storage_paths.gateway_details }}' - # Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. reply_surb_database = '{{ storage_paths.reply_surb_database }}' +# Path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +gateway_registrations = '{{ storage_paths.gateway_registrations }}' + # Location of the file containing our allow.list allowed_list_location = '{{ storage_paths.allowed_list_location }}' diff --git a/service-providers/network-requester/src/config/template.rs b/service-providers/network-requester/src/config/template.rs index ee6e3ffc51..84cb00e80c 100644 --- a/service-providers/network-requester/src/config/template.rs +++ b/service-providers/network-requester/src/config/template.rs @@ -51,10 +51,6 @@ keys.private_encryption_key_file = '{{ storage_paths.keys.private_encryption_key # Path to file containing public encryption key. keys.public_encryption_key_file = '{{ storage_paths.keys.public_encryption_key_file }}' -# A gateway specific, optional, base58 stringified shared key used for -# communication with particular gateway. -keys.gateway_shared_key_file = '{{ storage_paths.keys.gateway_shared_key_file }}' - # Path to file containing key used for encrypting and decrypting the content of an # acknowledgement so that nobody besides the client knows which packet it refers to. keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' @@ -62,13 +58,13 @@ keys.ack_key_file = '{{ storage_paths.keys.ack_key_file }}' # Path to the database containing bandwidth credentials credentials_database = '{{ storage_paths.credentials_database }}' -# Path to the file containing information about gateway used by this client, -# i.e. details such as its public key, owner address or the network information. -gateway_details = '{{ storage_paths.gateway_details }}' - # Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. reply_surb_database = '{{ storage_paths.reply_surb_database }}' +# Path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +gateway_registrations = '{{ storage_paths.gateway_registrations }}' + # Location of the file containing our allow.list allowed_list_location = '{{ storage_paths.allowed_list_location }}' From a3b1a7337dbd73c483dfe1125d5b7bf043641a30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 16:00:31 +0000 Subject: [PATCH 297/394] checking for already registered gateways --- .../client-core/gateways-storage/src/lib.rs | 20 ++++++++++++ .../src/cli_helpers/client_init.rs | 32 ++++++++++++++++--- .../src/client/base_client/storage/helpers.rs | 20 +++++++++++- .../src/client/base_client/storage/mod.rs | 6 ++-- .../src/client/key_manager/persistence.rs | 2 -- common/client-core/src/error.rs | 3 ++ common/client-core/src/init/helpers.rs | 12 +++---- 7 files changed, 79 insertions(+), 16 deletions(-) diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 7416abfc90..3f87cdf526 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -21,6 +21,7 @@ pub use error::BadGateway; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use backend::fs_backend::{error::StorageError, OnDiskGatewaysDetails}; +use nym_crypto::asymmetric::identity; #[cfg_attr(target_arch = "wasm32", async_trait(?Send))] #[cfg_attr(not(target_arch = "wasm32"), async_trait)] @@ -54,3 +55,22 @@ pub trait GatewaysDetailsStore { /// Remove given gateway details from the underlying store. async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError>; } + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +pub trait GatewaysDetailsStoreExt: GatewaysDetailsStore { + async fn all_gateways_identities( + &self, + ) -> Result<Vec<identity::PublicKey>, Self::StorageError> { + Ok(self + .all_gateways() + .await? + .into_iter() + .map(|gateway| gateway.details.gateway_id()) + .collect()) + } +} + +#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] +#[cfg_attr(not(target_arch = "wasm32"), async_trait)] +impl<T> GatewaysDetailsStoreExt for T where T: GatewaysDetailsStore {} diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index a75573b3eb..3fd821a9f4 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -6,7 +6,8 @@ use crate::error::ClientCoreError; use crate::{ client::{ base_client::{ - non_wasm_helpers::setup_fs_gateways_storage, storage::helpers::set_active_gateway, + non_wasm_helpers::setup_fs_gateways_storage, + storage::helpers::{get_all_registered_identities, set_active_gateway}, }, key_manager::persistence::OnDiskKeys, }, @@ -181,6 +182,7 @@ where ); let key_store = OnDiskKeys::new(paths.keys.clone()); + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; // if this is a first time client with this particular id is initialised, generated long-term keys if !already_init { @@ -188,10 +190,21 @@ where crate::init::generate_new_client_keys(&mut rng, &key_store).await?; } + let registered_gateways = get_all_registered_identities(&details_store).await?; + + // if user provided gateway id (and we can't overwrite data), make sure we're not trying to register + // with a known gateway + if let Some(user_chosen) = user_chosen_gateway_id { + if !common_args.force_register_gateway && registered_gateways.contains(&user_chosen) { + return Err(ClientCoreError::AlreadyRegistered { + gateway_id: user_chosen.to_base58_string(), + } + .into()); + } + } + // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. - let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; - let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { ClientCoreError::CustomTopologyLoadFailure { @@ -205,8 +218,17 @@ where crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? }; - let unused_variable = 42; - // todo!("remove registered gateways from the list"); + // since we're registering with a brand new gateway, + // make sure the list of available gateways doesn't overlap the list of known gateways + let available_gateways = if common_args.force_register_gateway { + // if we're force registering, all bets are off + available_gateways + } else { + available_gateways + .into_iter() + .filter(|g| !registered_gateways.contains(g.identity())) + .collect() + }; let gateway_setup = GatewaySetup::New { specification: selection_spec, diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index 628942902c..8c58605bda 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -4,7 +4,10 @@ use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::ClientKeys; use crate::error::ClientCoreError; -use nym_client_core_gateways_storage::{GatewayRegistration, GatewaysDetailsStore}; +use nym_client_core_gateways_storage::{ + GatewayRegistration, GatewaysDetailsStore, GatewaysDetailsStoreExt, +}; +use nym_crypto::asymmetric::identity; // helpers for error wrapping pub async fn set_active_gateway<D>( @@ -23,6 +26,21 @@ where }) } +pub async fn get_all_registered_identities<D>( + details_store: &D, +) -> Result<Vec<identity::PublicKey>, ClientCoreError> +where + D: GatewaysDetailsStore + Sync, + D::StorageError: Send + Sync + 'static, +{ + details_store + .all_gateways_identities() + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) +} + pub async fn store_gateway_details<D>( details_store: &D, details: &GatewayRegistration, diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 8a674e80aa..70266be27d 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -26,7 +26,9 @@ use crate::{ #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; -pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; +pub use nym_client_core_gateways_storage::{ + GatewaysDetailsStore, GatewaysDetailsStoreExt, InMemGatewaysDetails, +}; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; @@ -34,7 +36,7 @@ pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; pub mod helpers; // TODO: ideally this should be changed into -// `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewayDetailsStore` +// `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewaysDetailsStore` pub trait MixnetClientStorage { type KeyStore: KeyStore; type ReplyStore: ReplyStorageBackend; diff --git a/common/client-core/src/client/key_manager/persistence.rs b/common/client-core/src/client/key_manager/persistence.rs index e2312194b0..a4711e3d39 100644 --- a/common/client-core/src/client/key_manager/persistence.rs +++ b/common/client-core/src/client/key_manager/persistence.rs @@ -11,8 +11,6 @@ use crate::config::disk_persistence::keys_paths::ClientKeysPaths; #[cfg(not(target_arch = "wasm32"))] use nym_crypto::asymmetric::{encryption, identity}; #[cfg(not(target_arch = "wasm32"))] -use nym_gateway_requests::registration::handshake::SharedKeys; -#[cfg(not(target_arch = "wasm32"))] use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; #[cfg(not(target_arch = "wasm32"))] use nym_pemstore::KeyPairPath; diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 9fa43c8ef2..cca66e6b7f 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -195,6 +195,9 @@ pub enum ClientCoreError { #[source] source: url::ParseError, }, + + #[error("this client has already registered with gateway {gateway_id}")] + AlreadyRegistered { gateway_id: String }, } /// Set of messages that the client can send to listeners via the task manager diff --git a/common/client-core/src/init/helpers.rs b/common/client-core/src/init/helpers.rs index a5cd4a4a43..4d15327634 100644 --- a/common/client-core/src/init/helpers.rs +++ b/common/client-core/src/init/helpers.rs @@ -8,6 +8,7 @@ use log::{debug, info, trace, warn}; use nym_crypto::asymmetric::identity; use nym_gateway_client::GatewayClient; use nym_topology::{filter::VersionFilterable, gateway, mix}; +use nym_validator_client::client::IdentityKeyRef; use rand::{seq::SliceRandom, Rng}; use std::{sync::Arc, time::Duration}; use tungstenite::Message; @@ -16,17 +17,13 @@ use url::Url; #[cfg(not(target_arch = "wasm32"))] use tokio::net::TcpStream; #[cfg(not(target_arch = "wasm32"))] +use tokio::time::sleep; +#[cfg(not(target_arch = "wasm32"))] use tokio::time::Instant; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::connect_async; #[cfg(not(target_arch = "wasm32"))] use tokio_tungstenite::{MaybeTlsStream, WebSocketStream}; -#[cfg(not(target_arch = "wasm32"))] -type WsConn = WebSocketStream<MaybeTlsStream<TcpStream>>; -use nym_validator_client::client::IdentityKeyRef; -use nym_validator_client::nyxd::AccountId; -#[cfg(not(target_arch = "wasm32"))] -use tokio::time::sleep; #[cfg(target_arch = "wasm32")] use wasm_utils::websocket::JSWebsocket; @@ -35,6 +32,9 @@ use wasmtimer::std::Instant; #[cfg(target_arch = "wasm32")] use wasmtimer::tokio::sleep; +#[cfg(not(target_arch = "wasm32"))] +type WsConn = WebSocketStream<MaybeTlsStream<TcpStream>>; + #[cfg(target_arch = "wasm32")] type WsConn = JSWebsocket; From 14ee279ec89e33dd3770595eea25a758e557a956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 16:13:44 +0000 Subject: [PATCH 298/394] dead code --- common/client-core/gateways-storage/src/backend/mem_backend.rs | 2 +- common/client-core/src/error.rs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index 01385342bb..b06e4eb5e9 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::{GatewayDetails, GatewayRegistration}; +use crate::types::GatewayRegistration; use crate::{BadGateway, GatewaysDetailsStore}; use async_trait::async_trait; use std::collections::HashMap; diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index cca66e6b7f..ef2349356b 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -4,7 +4,6 @@ use crate::client::mix_traffic::transceiver::ErasedGatewayError; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_gateway_client::error::GatewayClientError; -use nym_gateway_requests::registration::handshake::shared_key::SharedKeyConversionError; use nym_topology::gateway::GatewayConversionError; use nym_topology::NymTopologyError; use nym_validator_client::ValidatorClientError; From d31fddf940530c32c73ea80dc5f3ecf9ff7b2d53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 7 Mar 2024 17:52:40 +0000 Subject: [PATCH 299/394] gateway info migration + impl for native client other clients are broken --- clients/native/src/client/config/mod.rs | 2 +- .../src/client/config/old_config_v1_1_20_2.rs | 4 +- .../native/src/commands/import_credential.rs | 2 +- clients/native/src/commands/init.rs | 4 +- clients/native/src/commands/mod.rs | 95 ++++---- clients/native/src/commands/run.rs | 2 +- .../src/cli_helpers/client_init.rs | 8 +- .../src/client/base_client/storage/helpers.rs | 2 +- .../base_client/storage/migration_helpers.rs | 211 ++++++++++++++++++ .../src/client/base_client/storage/mod.rs | 10 +- common/client-core/src/config/mod.rs | 81 +------ .../src/config/old_config_v1_1_20_2.rs | 6 +- .../src/config/old_config_v1_1_33.rs | 13 ++ common/client-core/src/error.rs | 3 + 14 files changed, 293 insertions(+), 150 deletions(-) create mode 100644 common/client-core/src/client/base_client/storage/migration_helpers.rs diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index 5c0d156bd5..264c3fec5b 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -19,7 +19,7 @@ use std::path::{Path, PathBuf}; use std::str::FromStr; pub use nym_client_core::config::Config as BaseClientConfig; -pub use nym_client_core::config::{DebugConfig, GatewayEndpointConfig}; +pub use nym_client_core::config::DebugConfig; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; diff --git a/clients/native/src/client/config/old_config_v1_1_20_2.rs b/clients/native/src/client/config/old_config_v1_1_20_2.rs index b6d9703a92..90e161827a 100644 --- a/clients/native/src/client/config/old_config_v1_1_20_2.rs +++ b/clients/native/src/client/config/old_config_v1_1_20_2.rs @@ -9,7 +9,7 @@ use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseConfigV1_1_20_2; use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseConfigV1_1_30; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use nym_network_defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use serde::{Deserialize, Serialize}; @@ -46,7 +46,7 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(ConfigV1_1_33, GatewayEndpointConfig), ClientError> { + pub fn upgrade(self) -> Result<(ConfigV1_1_33, OldGatewayEndpointConfigV1_1_33), ClientError> { let gateway_details = self.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_33 { base: BaseConfigV1_1_30::from(self.base).into(), diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 8554f74ee7..7fa7fa3b52 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -34,7 +34,7 @@ pub(crate) struct Args { } pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; let credentials_store = nym_credential_storage::initialise_persistent_storage( &config.storage_paths.common_paths.credentials_database, diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index def0072d26..dfc7b95cd9 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -29,8 +29,8 @@ impl InitialisableClient for NativeClientInit { type InitArgs = Init; type Config = Config; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id) + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 2c9dfde3cc..d3947b876e 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -12,10 +12,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_client_core::client::base_client::storage::OnDiskGatewaysDetails; -use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; -use nym_client_core::error::ClientCoreError; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::error::Error; use std::net::IpAddr; @@ -121,41 +118,7 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { ) } -fn persist_gateway_details( - config: &Config, - details: GatewayEndpointConfig, -) -> Result<(), ClientError> { - todo!() - // let details_store = - // OnDiskGatewaysDetails::new(&config.storage_paths.common_paths.gateway_details); - // let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - // ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - // source: Box::new(source), - // }) - // })?; - // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - // details_store - // .store_to_disk(&persisted_details) - // .map_err(|source| { - // ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - // source: Box::new(source), - // }) - // }) -} - -fn migrate_gateway_details( - config: &Config, - old_details: Option<GatewayEndpointConfig>, -) -> Result<(), ClientError> { - todo!() -} - -fn extract_gateway_details(config: &ConfigV1_1_33) -> Result<(), ClientError> { - todo!() -} - -fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> { +async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) @@ -170,15 +133,21 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, ClientError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let old_paths = updated_step3.storage_paths.clone(); let updated = updated_step3.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> { +async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) @@ -192,15 +161,20 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, ClientError> { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let old_paths = updated_step2.storage_paths.clone(); let updated = updated_step2.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; - + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> { +async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> { // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -211,15 +185,20 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, ClientError> { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); let updated = updated_step1.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; - + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> { +async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> { // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -229,32 +208,38 @@ fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, ClientError> { info!("It seems the client is using <= v1.1.33 config template."); info!("It is going to get updated to the current specification."); + let old_paths = old_config.storage_paths.clone(); let updated = old_config.try_upgrade()?; - migrate_gateway_details(&updated, None)?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_config(id: &str) -> Result<(), ClientError> { - if try_upgrade_v1_1_13_config(id)? { +async fn try_upgrade_config(id: &str) -> Result<(), ClientError> { + if try_upgrade_v1_1_13_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(id)? { + if try_upgrade_v1_1_20_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(id)? { + if try_upgrade_v1_1_20_2_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_33_config(id)? { + if try_upgrade_v1_1_33_config(id).await? { return Ok(()); } Ok(()) } -fn try_load_current_config(id: &str) -> Result<Config, ClientError> { +async fn try_load_current_config(id: &str) -> Result<Config, ClientError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { return if !cfg.validate() { @@ -265,7 +250,7 @@ fn try_load_current_config(id: &str) -> Result<Config, ClientError> { } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id)?; + try_upgrade_config(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/clients/native/src/commands/run.rs b/clients/native/src/commands/run.rs index b836fe6d20..2ab3fc8489 100644 --- a/clients/native/src/commands/run.rs +++ b/clients/native/src/commands/run.rs @@ -69,7 +69,7 @@ fn version_check(cfg: &Config) -> bool { pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn Error + Send + Sync>> { eprintln!("Starting client {}...", args.common_args.id); - let mut config = try_load_current_config(&args.common_args.id)?; + let mut config = try_load_current_config(&args.common_args.id).await?; config = override_config(config, OverrideConfig::from(args.clone())); if !version_check(&config) { diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 3fd821a9f4..93ad844b08 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -20,13 +20,15 @@ use nym_topology::NymTopology; use rand::rngs::OsRng; use std::path::{Path, PathBuf}; +// we can suppress this warning (as suggested by linter itself) since we're only using it in our own code +#[allow(async_fn_in_trait)] pub trait InitialisableClient { const NAME: &'static str; type Error: From<ClientCoreError>; type InitArgs: AsRef<CommonClientInitArgs>; type Config: ClientConfig; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; fn initialise_storage_paths(id: &str) -> Result<(), Self::Error>; @@ -134,7 +136,7 @@ where let already_init = if C::default_config_path(id).exists() { // in case we're using old config, try to upgrade it // (if we're using the current version, it's a no-op) - C::try_upgrade_outdated_config(id)?; + C::try_upgrade_outdated_config(id).await?; eprintln!("{} client \"{id}\" was already initialised before", C::NAME); true } else { @@ -273,7 +275,7 @@ where ); if init_args.as_ref().set_active { - set_active_gateway(&init_results.gateway_id, &details_store).await?; + set_active_gateway(&details_store, &init_results.gateway_id).await?; } else { info!("registered with new gateway {} (under address {address}), but this will not be our default address", init_results.gateway_id); } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index 8c58605bda..c6f2cf65c2 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -11,8 +11,8 @@ use nym_crypto::asymmetric::identity; // helpers for error wrapping pub async fn set_active_gateway<D>( - gateway_id: &str, details_store: &D, + gateway_id: &str, ) -> Result<(), ClientCoreError> where D: GatewaysDetailsStore, diff --git a/common/client-core/src/client/base_client/storage/migration_helpers.rs b/common/client-core/src/client/base_client/storage/migration_helpers.rs new file mode 100644 index 0000000000..c81011a37f --- /dev/null +++ b/common/client-core/src/client/base_client/storage/migration_helpers.rs @@ -0,0 +1,211 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1_1_33 { + use crate::client::base_client::{ + non_wasm_helpers::setup_fs_gateways_storage, + storage::helpers::{set_active_gateway, store_gateway_details}, + }; + use crate::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; + use crate::config::disk_persistence::CommonClientPaths; + use crate::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; + use crate::error::ClientCoreError; + use nym_client_core_gateways_storage::{ + CustomGatewayDetails, GatewayDetails, GatewayRegistration, RemoteGatewayDetails, + }; + use nym_gateway_requests::registration::handshake::SharedKeys; + use serde::{Deserialize, Serialize}; + use sha2::{digest::Digest, Sha256}; + use std::ops::Deref; + use std::path::Path; + use std::sync::Arc; + use zeroize::Zeroizing; + + mod base64 { + use base64::{engine::general_purpose::STANDARD, Engine as _}; + use serde::{Deserialize, Deserializer, Serializer}; + + pub fn serialize<S: Serializer>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error> { + serializer.serialize_str(&STANDARD.encode(bytes)) + } + + pub fn deserialize<'de, D: Deserializer<'de>>( + deserializer: D, + ) -> Result<Vec<u8>, D::Error> { + let s = <String>::deserialize(deserializer)?; + STANDARD.decode(s).map_err(serde::de::Error::custom) + } + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + #[serde(untagged)] + enum PersistedGatewayDetails { + /// Standard details of a remote gateway + Default(PersistedGatewayConfig), + + /// Custom gateway setup, such as for a client embedded inside gateway itself + Custom(PersistedCustomGatewayDetails), + } + + #[derive(Debug, Clone, Serialize, Deserialize, PartialEq)] + struct PersistedGatewayConfig { + /// The hash of the shared keys to ensure the correct ones are used with those gateway details. + #[serde(with = "base64")] + key_hash: Vec<u8>, + + /// Actual gateway details being persisted. + details: OldGatewayEndpointConfigV1_1_33, + } + + impl PersistedGatewayConfig { + fn verify(&self, shared_key: &SharedKeys) -> bool { + let key_bytes = Zeroizing::new(shared_key.to_bytes()); + + let mut key_hasher = Sha256::new(); + key_hasher.update(&key_bytes); + let key_hash = key_hasher.finalize(); + + self.key_hash == key_hash.deref() + } + } + + #[derive(Debug, Clone, Serialize, Deserialize)] + struct PersistedCustomGatewayDetails { + gateway_id: String, + } + + fn load_shared_key<P: AsRef<Path>>(path: P) -> Result<SharedKeys, ClientCoreError> { + // the shared key was a simple pem file + Ok(nym_pemstore::load_key(path)?) + } + + fn gateway_details_from_raw( + gateway_id: String, + gateway_owner: String, + gateway_listener: String, + gateway_shared_key: SharedKeys, + ) -> Result<GatewayDetails, ClientCoreError> { + Ok(GatewayDetails::Remote(RemoteGatewayDetails { + gateway_id: gateway_id + .parse() + .map_err(|err| ClientCoreError::UpgradeFailure { + message: format!("the stored gateway id was malformed: {err}"), + })?, + derived_aes128_ctr_blake3_hmac_keys: Arc::new(gateway_shared_key), + gateway_owner_address: gateway_owner.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway owner address was malformed: {err}"), + } + })?, + gateway_listener: gateway_listener.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway listener address was malformed: {err}"), + } + })?, + })) + } + + // helper to extract shared key and gateway details into the new GatewayRegistration + fn extract_gateway_registration( + storage_paths: &CommonClientPathsV1_1_33, + ) -> Result<GatewayRegistration, ClientCoreError> { + let details_file = std::fs::File::open(&storage_paths.gateway_details).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!( + "failed to open gateway details file at {}: {err}", + storage_paths.gateway_details.display() + ), + } + })?; + + // in v1.1.33 of the clients, the gateway details struct was saved as json + let details: PersistedGatewayDetails = + serde_json::from_reader(details_file).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!( + "failed to deserialize gateway details from {}: {err}", + storage_paths.gateway_details.display() + ), + } + })?; + + let details = match details { + PersistedGatewayDetails::Default(config) => { + let gateway_shared_key = + load_shared_key(&storage_paths.keys.gateway_shared_key_file)?; + if !config.verify(&gateway_shared_key) { + return Err(ClientCoreError::UpgradeFailure { + message: "failed to verify consistency of the existing gateway details" + .to_string(), + }); + } + gateway_details_from_raw( + config.details.gateway_id, + config.details.gateway_owner, + config.details.gateway_listener, + gateway_shared_key, + )? + } + PersistedGatewayDetails::Custom(custom) => { + GatewayDetails::Custom(CustomGatewayDetails { + gateway_id: custom.gateway_id.parse().map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("the stored gateway id was malformed: {err}"), + } + })?, + data: None, + }) + } + }; + + Ok(details.into()) + } + + // it's responsibility of the caller to ensure this is called **after** new registration has already been saved + fn remove_old_gateway_details(storage_paths: &CommonClientPathsV1_1_33) -> std::io::Result<()> { + std::fs::remove_file(&storage_paths.gateway_details)?; + + if storage_paths.keys.gateway_shared_key_file.exists() { + std::fs::remove_file(&storage_paths.keys.gateway_shared_key_file)?; + } + Ok(()) + } + + pub async fn migrate_gateway_details( + old_storage_paths: &CommonClientPathsV1_1_33, + new_storage_paths: &CommonClientPaths, + preloaded_config: Option<OldGatewayEndpointConfigV1_1_33>, + ) -> Result<(), ClientCoreError> { + let gateway_registration = match preloaded_config { + Some(config) => { + let gateway_shared_key = + load_shared_key(&old_storage_paths.keys.gateway_shared_key_file)?; + gateway_details_from_raw( + config.gateway_id, + config.gateway_owner, + config.gateway_listener, + gateway_shared_key, + )? + .into() + } + None => extract_gateway_registration(old_storage_paths)?, + }; + + // since we're migrating to a brand new store, the store should be empty + // and thus set the 'new' gateway as the active one + let details_store = + setup_fs_gateways_storage(&new_storage_paths.gateway_registrations).await?; + store_gateway_details(&details_store, &gateway_registration).await?; + set_active_gateway( + &details_store, + &gateway_registration.details.gateway_id().to_base58_string(), + ) + .await?; + + remove_old_gateway_details(&old_storage_paths).map_err(|err| { + ClientCoreError::UpgradeFailure { + message: format!("failed to remove old data: {err}"), + } + }) + } +} diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 70266be27d..2158788cd3 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -27,7 +27,8 @@ use crate::{ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; pub use nym_client_core_gateways_storage::{ - GatewaysDetailsStore, GatewaysDetailsStoreExt, InMemGatewaysDetails, + CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, GatewaysDetailsStore, + GatewaysDetailsStoreExt, InMemGatewaysDetails, RegisteredGateway, RemoteGatewayDetails, }; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] @@ -35,6 +36,13 @@ pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; pub mod helpers; +#[cfg(all( + not(target_arch = "wasm32"), + feature = "fs-surb-storage", + feature = "fs-gateways-storage" +))] +pub mod migration_helpers; + // TODO: ideally this should be changed into // `MixnetClientStorage: KeyStore + ReplyStorageBackend + CredentialStorage + GatewaysDetailsStore` pub trait MixnetClientStorage { diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 1fd2cf26f3..2333c58df4 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -1,10 +1,8 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::{client::topology_control::geo_aware_provider::CountryGroup, error::ClientCoreError}; +use crate::client::topology_control::geo_aware_provider::CountryGroup; use nym_config::defaults::NymNetworkDetails; -use nym_crypto::asymmetric::identity; -use nym_gateway_client::client::GatewayConfig; use nym_sphinx::{ addressing::clients::Recipient, params::{PacketSize, PacketType}, @@ -13,9 +11,6 @@ use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; -#[cfg(target_arch = "wasm32")] -use wasm_bindgen::prelude::*; - pub mod disk_persistence; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; @@ -232,80 +227,6 @@ impl Config { } } -#[deprecated] -#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen(getter_with_clone))] -pub struct GatewayEndpointConfig { - /// gateway_id specifies ID of the gateway to which the client should send messages. - /// If initially omitted, a random gateway will be chosen from the available topology. - pub gateway_id: String, - - /// Address of the gateway owner to which the client should send messages. - pub gateway_owner: String, - - /// Address of the gateway listener to which all client requests should be sent. - pub gateway_listener: String, -} - -impl TryFrom<GatewayEndpointConfig> for GatewayConfig { - type Error = ClientCoreError; - - fn try_from(value: GatewayEndpointConfig) -> Result<Self, Self::Error> { - Ok(GatewayConfig { - gateway_identity: identity::PublicKey::from_base58_string(value.gateway_id) - .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId)?, - gateway_owner: Some(value.gateway_owner), - gateway_listener: value.gateway_listener, - }) - } -} - -#[deprecated] -#[cfg_attr(target_arch = "wasm32", wasm_bindgen)] -impl GatewayEndpointConfig { - #[cfg_attr(target_arch = "wasm32", wasm_bindgen(constructor))] - pub fn new( - gateway_id: String, - gateway_owner: String, - gateway_listener: String, - ) -> GatewayEndpointConfig { - GatewayEndpointConfig { - gateway_id, - gateway_owner, - gateway_listener, - } - } -} - -// separate block so it wouldn't be exported via wasm bindgen -#[deprecated] -impl GatewayEndpointConfig { - pub fn try_get_gateway_identity_key(&self) -> Result<identity::PublicKey, ClientCoreError> { - identity::PublicKey::from_base58_string(&self.gateway_id) - .map_err(ClientCoreError::UnableToCreatePublicKeyFromGatewayId) - } - - pub fn from_node( - node: nym_topology::gateway::Node, - must_use_tls: bool, - ) -> Result<Self, ClientCoreError> { - let gateway_listener = if must_use_tls { - node.clients_address_tls() - .ok_or(ClientCoreError::UnsupportedWssProtocol { - gateway: node.identity_key.to_base58_string(), - })? - } else { - node.clients_address() - }; - - Ok(GatewayEndpointConfig { - gateway_id: node.identity_key.to_base58_string(), - gateway_listener, - gateway_owner: node.owner, - }) - } -} - #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] // note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 #[serde(deny_unknown_fields)] diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/src/config/old_config_v1_1_20_2.rs index a7abd41ddc..5fe039fc82 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/src/config/old_config_v1_1_20_2.rs @@ -5,7 +5,7 @@ use crate::config::old_config_v1_1_30::{ AcknowledgementsV1_1_30, ClientV1_1_30, ConfigV1_1_30, CoverTrafficV1_1_30, DebugConfigV1_1_30, GatewayConnectionV1_1_30, ReplySurbsV1_1_30, TopologyV1_1_30, TrafficV1_1_30, }; -use crate::config::GatewayEndpointConfig; +use crate::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_sphinx::params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; @@ -81,9 +81,9 @@ pub struct GatewayEndpointConfigV1_1_20_2 { pub gateway_listener: String, } -impl From<GatewayEndpointConfigV1_1_20_2> for GatewayEndpointConfig { +impl From<GatewayEndpointConfigV1_1_20_2> for OldGatewayEndpointConfigV1_1_33 { fn from(value: GatewayEndpointConfigV1_1_20_2) -> Self { - GatewayEndpointConfig { + OldGatewayEndpointConfigV1_1_33 { gateway_id: value.gateway_id, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, diff --git a/common/client-core/src/config/old_config_v1_1_33.rs b/common/client-core/src/config/old_config_v1_1_33.rs index 0d47b95361..028b35fb52 100644 --- a/common/client-core/src/config/old_config_v1_1_33.rs +++ b/common/client-core/src/config/old_config_v1_1_33.rs @@ -55,6 +55,19 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6 // 24 hours const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +#[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] +pub struct OldGatewayEndpointConfigV1_1_33 { + /// gateway_id specifies ID of the gateway to which the client should send messages. + /// If initially omitted, a random gateway will be chosen from the available topology. + pub gateway_id: String, + + /// Address of the gateway owner to which the client should send messages. + pub gateway_owner: String, + + /// Address of the gateway listener to which all client requests should be sent. + pub gateway_listener: String, +} + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct ConfigV1_1_33 { diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index ef2349356b..d2d391f102 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -127,6 +127,9 @@ pub enum ClientCoreError { #[error("unable to upgrade config file to `{new_version}`")] UnableToUpgradeConfigFile { new_version: String }, + #[error("failed to upgrade config file: {message}")] + UpgradeFailure { message: String }, + #[error("the provided gateway details don't much the stored data")] MismatchedStoredGatewayDetails, From 35d84b6e420ab72dec257e8885a82528731837fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 09:47:24 +0000 Subject: [PATCH 300/394] ibid for socks5 --- .../socks5/src/commands/import_credential.rs | 3 +- clients/socks5/src/commands/init.rs | 4 +- clients/socks5/src/commands/mod.rs | 108 +++++++++--------- clients/socks5/src/commands/run.rs | 2 +- .../socks5/src/config/old_config_v1_1_20_2.rs | 13 +-- .../socks5/src/config/old_config_v1_1_30.rs | 2 +- 6 files changed, 68 insertions(+), 64 deletions(-) diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index 8a13e799d3..a3bfd7dd45 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -4,7 +4,6 @@ use crate::commands::try_load_current_config; use crate::error::Socks5ClientError; use clap::ArgGroup; - use nym_id::import_credential; use std::fs; use std::path::PathBuf; @@ -34,7 +33,7 @@ pub(crate) struct Args { } pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; let credentials_store = nym_credential_storage::initialise_persistent_storage( &config.storage_paths.common_paths.credentials_database, diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 3bc5cd098a..548059d701 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -29,8 +29,8 @@ impl InitialisableClient for Socks5ClientInit { type InitArgs = Init; type Config = Config; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id) + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 47de0929ef..d367a061cd 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -6,17 +6,16 @@ use crate::config::old_config_v1_1_20::ConfigV1_1_20; use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; use crate::config::old_config_v1_1_30::ConfigV1_1_30; use crate::config::old_config_v1_1_33::ConfigV1_1_33; -use crate::config::{BaseClientConfig, Config, SocksClientPaths}; +use crate::config::{BaseClientConfig, Config}; use crate::error::Socks5ClientError; use clap::CommandFactory; use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_client_core::client::key_manager::persistence::OnDiskKeys; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; -use nym_client_core::config::{GatewayEndpointConfig, GroupBy, TopologyStructure}; -use nym_client_core::error::ClientCoreError; +use nym_client_core::config::{GroupBy, TopologyStructure}; use nym_config::OptionalSet; use nym_sphinx::params::{PacketSize, PacketType}; use std::error::Error; @@ -166,36 +165,7 @@ pub(crate) fn override_config(config: Config, args: OverrideConfig) -> Config { ) } -fn persist_gateway_details( - storage_paths: &SocksClientPaths, - details: GatewayEndpointConfig, -) -> Result<(), Socks5ClientError> { - todo!() - // let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); - // let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); - // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - // Socks5ClientError::ClientCoreError(ClientCoreError::KeyStoreError { - // source: Box::new(source), - // }) - // })?; - // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - // details_store - // .store_to_disk(&persisted_details) - // .map_err(|source| { - // Socks5ClientError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - // source: Box::new(source), - // }) - // }) -} - -fn migrate_gateway_details( - config: &Config, - old_details: Option<GatewayEndpointConfig>, -) -> Result<(), Socks5ClientError> { - todo!() -} - -fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> { +async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) @@ -210,16 +180,23 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, Socks5ClientError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let old_paths = updated_step3.storage_paths.clone(); + let updated_step4: ConfigV1_1_33 = updated_step3.into(); let updated = updated_step4.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> { +async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) @@ -233,16 +210,23 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, Socks5ClientError> { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let old_paths = updated_step2.storage_paths.clone(); + let updated_step3: ConfigV1_1_33 = updated_step2.into(); let updated = updated_step3.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> { +async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> { // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -253,16 +237,23 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, Socks5ClientError> { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); + let updated_step2: ConfigV1_1_33 = updated_step1.into(); let updated = updated_step2.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool, Socks5ClientError> { +async fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool, Socks5ClientError> { // explicitly load it as v1.1.30 (which is incompatible with the current one, i.e. +1.1.31) let Ok(old_config) = ConfigV1_1_30::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -272,15 +263,23 @@ fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool, Socks5ClientError> { info!("It seems the client is using <= v1.1.30 config template."); info!("It is going to get updated to the current specification."); + let old_paths = old_config.storage_paths.clone(); + let updated_step1: ConfigV1_1_33 = old_config.into(); let updated = updated_step1.try_upgrade()?; - migrate_gateway_details(&updated, None)?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, Socks5ClientError> { +async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, Socks5ClientError> { // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -290,35 +289,42 @@ fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, Socks5ClientError> { info!("It seems the client is using <= v1.1.33 config template."); info!("It is going to get updated to the current specification."); + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; - migrate_gateway_details(&updated, None)?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> { - if try_upgrade_v1_1_13_config(id)? { +async fn try_upgrade_config(id: &str) -> Result<(), Socks5ClientError> { + if try_upgrade_v1_1_13_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(id)? { + if try_upgrade_v1_1_20_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(id)? { + if try_upgrade_v1_1_20_2_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_30_config(id)? { + if try_upgrade_v1_1_30_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_33_config(id)? { + if try_upgrade_v1_1_33_config(id).await? { return Ok(()); } Ok(()) } -fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> { +async fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { return if !cfg.validate() { @@ -329,7 +335,7 @@ fn try_load_current_config(id: &str) -> Result<Config, Socks5ClientError> { } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id)?; + try_upgrade_config(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/clients/socks5/src/commands/run.rs b/clients/socks5/src/commands/run.rs index 5638c80d9b..87234d676c 100644 --- a/clients/socks5/src/commands/run.rs +++ b/clients/socks5/src/commands/run.rs @@ -105,7 +105,7 @@ fn version_check(cfg: &Config) -> bool { pub(crate) async fn execute(args: Run) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { eprintln!("Starting client {}...", args.common_args.id); - let mut config = try_load_current_config(&args.common_args.id)?; + let mut config = try_load_current_config(&args.common_args.id).await?; config = override_config(config, OverrideConfig::from(args.clone())); if !version_check(&config) { diff --git a/clients/socks5/src/config/old_config_v1_1_20_2.rs b/clients/socks5/src/config/old_config_v1_1_20_2.rs index d396082e68..6b1e5f0219 100644 --- a/clients/socks5/src/config/old_config_v1_1_20_2.rs +++ b/clients/socks5/src/config/old_config_v1_1_20_2.rs @@ -2,19 +2,16 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::old_config_v1_1_30::ConfigV1_1_30; -use crate::{ - config::{default_config_filepath, persistence::SocksClientPaths}, - error::Socks5ClientError, -}; +use crate::config::old_config_v1_1_33::SocksClientPathsV1_1_33; +use crate::{config::default_config_filepath, error::Socks5ClientError}; use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use serde::{Deserialize, Serialize}; use std::io; use std::path::Path; -use crate::config::old_config_v1_1_33::SocksClientPathsV1_1_33; pub use nym_socks5_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as CoreConfigV1_1_20_2; #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] @@ -44,7 +41,9 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(ConfigV1_1_30, GatewayEndpointConfig), Socks5ClientError> { + pub fn upgrade( + self, + ) -> Result<(ConfigV1_1_30, OldGatewayEndpointConfigV1_1_33), Socks5ClientError> { let gateway_details = self.core.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_30 { core: self.core.into(), diff --git a/clients/socks5/src/config/old_config_v1_1_30.rs b/clients/socks5/src/config/old_config_v1_1_30.rs index 7395891dc3..e6f3a12bc0 100644 --- a/clients/socks5/src/config/old_config_v1_1_30.rs +++ b/clients/socks5/src/config/old_config_v1_1_30.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::config::default_config_filepath; use crate::config::old_config_v1_1_33::{ConfigV1_1_33, SocksClientPathsV1_1_33}; -use crate::config::{default_config_filepath, Config}; use nym_bin_common::logging::LoggingSettings; use nym_config::read_config_from_toml_file; use nym_socks5_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as CoreConfigV1_1_30; From 6e1b869c99901030201a291f841ea1478c9e24dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 09:52:46 +0000 Subject: [PATCH 301/394] ibid for network requester --- .../src/cli/import_credential.rs | 3 +- .../network-requester/src/cli/init.rs | 4 +- .../network-requester/src/cli/mod.rs | 92 ++++++++----------- .../network-requester/src/cli/run.rs | 2 +- .../network-requester/src/cli/sign.rs | 2 +- .../src/config/old_config_v1_1_20.rs | 1 - .../src/config/old_config_v1_1_20_2.rs | 6 +- 7 files changed, 49 insertions(+), 61 deletions(-) diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index d46b0442bf..31a11c92a0 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -4,7 +4,6 @@ use crate::cli::try_load_current_config; use crate::error::NetworkRequesterError; use clap::ArgGroup; - use nym_id::import_credential; use std::fs; use std::path::PathBuf; @@ -34,7 +33,7 @@ pub(crate) struct Args { } pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; let credentials_store = nym_credential_storage::initialise_persistent_storage( &config.storage_paths.common_paths.credentials_database, diff --git a/service-providers/network-requester/src/cli/init.rs b/service-providers/network-requester/src/cli/init.rs index 630c4546f4..b8771961eb 100644 --- a/service-providers/network-requester/src/cli/init.rs +++ b/service-providers/network-requester/src/cli/init.rs @@ -26,8 +26,8 @@ impl InitialisableClient for NetworkRequesterInit { type InitArgs = Init; type Config = Config; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id) + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 73710781a1..6aedc24cf0 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -14,9 +14,7 @@ use log::{error, info, trace}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; -use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; -use nym_client_core::error::ClientCoreError; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::sync::OnceLock; @@ -164,41 +162,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Ok(()) } -fn persist_gateway_details( - config: &Config, - details: GatewayEndpointConfig, -) -> Result<(), NetworkRequesterError> { - todo!() - // let details_store = - // OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); - // let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - // let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - // NetworkRequesterError::ClientCoreError(ClientCoreError::KeyStoreError { - // source: Box::new(source), - // }) - // })?; - // let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - // details_store - // .store_to_disk(&persisted_details) - // .map_err(|source| { - // NetworkRequesterError::ClientCoreError(ClientCoreError::GatewayDetailsStoreError { - // source: Box::new(source), - // }) - // }) -} - -fn migrate_gateway_details( - config: &Config, - old_details: Option<GatewayEndpointConfig>, -) -> Result<(), NetworkRequesterError> { - todo!() -} - -fn extract_gateway_details(config: &ConfigV1_1_33) -> Result<(), NetworkRequesterError> { - todo!() -} - -fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { +async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.13 config"); use nym_config::legacy_helpers::nym_config::MigrationNymConfig; @@ -214,15 +178,21 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let old_paths = updated_step3.storage_paths.clone(); let updated = updated_step3.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> { +async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.20 config"); use nym_config::legacy_helpers::nym_config::MigrationNymConfig; @@ -238,15 +208,21 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let old_paths = updated_step2.storage_paths.clone(); let updated = updated_step2.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError> { +async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.20_2 config"); // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) @@ -259,15 +235,21 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError> info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); let updated = updated_step1.try_upgrade()?; - migrate_gateway_details(&updated, Some(gateway_config))?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, NetworkRequesterError> { +async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, NetworkRequesterError> { // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -277,33 +259,39 @@ fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, NetworkRequesterError> { info!("It seems the client is using <= v1.1.33 config template."); info!("It is going to get updated to the current specification."); + let old_paths = old_config.storage_paths.clone(); let updated = old_config.try_upgrade()?; - migrate_gateway_details(&updated, None)?; + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_config(id: &str) -> Result<(), NetworkRequesterError> { +async fn try_upgrade_config(id: &str) -> Result<(), NetworkRequesterError> { trace!("Attempting to upgrade config"); - if try_upgrade_v1_1_13_config(id)? { + if try_upgrade_v1_1_13_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(id)? { + if try_upgrade_v1_1_20_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(id)? { + if try_upgrade_v1_1_20_2_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_33_config(id)? { + if try_upgrade_v1_1_33_config(id).await? { return Ok(()); } Ok(()) } -fn try_load_current_config(id: &str) -> Result<Config, NetworkRequesterError> { +async fn try_load_current_config(id: &str) -> Result<Config, NetworkRequesterError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { return if !cfg.validate() { @@ -314,7 +302,7 @@ fn try_load_current_config(id: &str) -> Result<Config, NetworkRequesterError> { } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id)?; + try_upgrade_config(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/service-providers/network-requester/src/cli/run.rs b/service-providers/network-requester/src/cli/run.rs index 1295734bda..cd3a5ad653 100644 --- a/service-providers/network-requester/src/cli/run.rs +++ b/service-providers/network-requester/src/cli/run.rs @@ -66,7 +66,7 @@ impl From<Run> for OverrideConfig { } pub(crate) async fn execute(args: &Run) -> Result<(), NetworkRequesterError> { - let mut config = try_load_current_config(&args.common_args.id)?; + let mut config = try_load_current_config(&args.common_args.id).await?; config = override_config(config, OverrideConfig::from(args.clone())); log::debug!("Using config: {:#?}", config); diff --git a/service-providers/network-requester/src/cli/sign.rs b/service-providers/network-requester/src/cli/sign.rs index 7a0dc29d7b..9e43de6009 100644 --- a/service-providers/network-requester/src/cli/sign.rs +++ b/service-providers/network-requester/src/cli/sign.rs @@ -55,7 +55,7 @@ fn print_signed_contract_msg( } pub(crate) async fn execute(args: &Sign) -> Result<(), NetworkRequesterError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; if !version_check(&config) { log::error!("Failed the local version check"); diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20.rs b/service-providers/network-requester/src/config/old_config_v1_1_20.rs index 42d82646fa..603b0f6d92 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20.rs @@ -4,7 +4,6 @@ use crate::config::old_config_v1_1_20_2::{ ConfigV1_1_20_2, DebugV1_1_20_2, NetworkRequesterPathsV1_1_20_2, }; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs index 6c9d3e0255..642270911b 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs @@ -10,7 +10,7 @@ use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseClientConfigV1_1_20_2; use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseConfigV1_1_30; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use serde::{Deserialize, Serialize}; use std::io; @@ -61,7 +61,9 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(ConfigV1_1_33, GatewayEndpointConfig), NetworkRequesterError> { + pub fn upgrade( + self, + ) -> Result<(ConfigV1_1_33, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> { trace!("Upgrading from v1.1.20_2"); let gateway_details = self.base.client.gateway_endpoint.clone().into(); let nr_description = self From fc43cb590bbed8f28dc3a4df6e6426d6a0763ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 14:54:16 +0000 Subject: [PATCH 302/394] further adjusting storage and setup to allow for wg use --- .../20240304120000_create_initial_tables.sql | 3 +- .../src/backend/fs_backend/mod.rs | 7 +- .../src/backend/mem_backend.rs | 10 +- .../client-core/gateways-storage/src/lib.rs | 6 +- .../client-core/gateways-storage/src/types.rs | 24 ++ .../src/cli_helpers/client_init.rs | 1 + .../client-core/src/client/base_client/mod.rs | 65 +++-- .../src/client/base_client/storage/helpers.rs | 14 +- .../base_client/storage/migration_helpers.rs | 1 + common/client-core/src/init/mod.rs | 31 ++- common/client-core/src/init/types.rs | 53 ++++ common/network-defaults/src/lib.rs | 2 + gateway/src/commands/helpers.rs | 25 +- sdk/rust/nym-sdk/src/mixnet.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 226 ++++++++++-------- 15 files changed, 291 insertions(+), 179 deletions(-) diff --git a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql index bb4d59f7a1..77c32b4fa9 100644 --- a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql +++ b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql @@ -24,7 +24,8 @@ CREATE TABLE remote_gateway_details gateway_id_bs58 TEXT NOT NULL UNIQUE PRIMARY KEY REFERENCES registered_gateway (gateway_id_bs58), derived_aes128_ctr_blake3_hmac_keys_bs58 TEXT NOT NULL, gateway_owner_address TEXT NOT NULL, - gateway_listener TEXT NOT NULL + gateway_listener TEXT NOT NULL, + wg_tun_address TEXT ); CREATE TABLE custom_gateway_details diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 4b759c0e5f..5061fe60fc 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::types::GatewayRegistration; -use crate::{GatewaysDetailsStore, StorageError}; +use crate::{ActiveGateway, GatewaysDetailsStore, StorageError}; use async_trait::async_trait; use manager::StorageManager; use std::path::Path; @@ -26,11 +26,12 @@ impl OnDiskGatewaysDetails { #[async_trait] impl GatewaysDetailsStore for OnDiskGatewaysDetails { type StorageError = error::StorageError; - + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { todo!() } - async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { + + async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError> { todo!() } diff --git a/common/client-core/gateways-storage/src/backend/mem_backend.rs b/common/client-core/gateways-storage/src/backend/mem_backend.rs index b06e4eb5e9..451f6b2187 100644 --- a/common/client-core/gateways-storage/src/backend/mem_backend.rs +++ b/common/client-core/gateways-storage/src/backend/mem_backend.rs @@ -1,7 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::GatewayRegistration; +use crate::types::{ActiveGateway, GatewayRegistration}; use crate::{BadGateway, GatewaysDetailsStore}; use async_trait::async_trait; use std::collections::HashMap; @@ -38,14 +38,16 @@ impl GatewaysDetailsStore for InMemGatewaysDetails { Ok(self.inner.read().await.gateways.contains_key(gateway_id)) } - async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError> { + async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError> { let guard = self.inner.read().await; - Ok(guard.active_gateway.as_ref().map(|id| { + let registration = guard.active_gateway.as_ref().map(|id| { // SAFETY: if particular gateway is set as active, its details MUST exist #[allow(clippy::unwrap_used)] guard.gateways.get(id).unwrap().clone() - })) + }); + + Ok(ActiveGateway { registration }) } async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 3f87cdf526..26deeec049 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -13,8 +13,8 @@ pub mod types; // todo: export port types pub use crate::types::{ - CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, RegisteredGateway, - RemoteGatewayDetails, + ActiveGateway, CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, + RegisteredGateway, RemoteGatewayDetails, }; pub use backend::mem_backend::{InMemGatewaysDetails, InMemStorageError}; pub use error::BadGateway; @@ -29,7 +29,7 @@ pub trait GatewaysDetailsStore { type StorageError: Error + From<error::BadGateway>; /// Returns details of the currently active gateway, if available. - async fn active_gateway(&self) -> Result<Option<GatewayRegistration>, Self::StorageError>; + async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError>; /// Set the provided gateway as the currently active gateway. async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError>; diff --git a/common/client-core/gateways-storage/src/types.rs b/common/client-core/gateways-storage/src/types.rs index c165147bba..a63cd4f5d8 100644 --- a/common/client-core/gateways-storage/src/types.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -16,6 +16,11 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub const REMOTE_GATEWAY_TYPE: &str = "remote"; pub const CUSTOM_GATEWAY_TYPE: &str = "custom"; +#[derive(Debug, Clone, Default)] +pub struct ActiveGateway { + pub registration: Option<GatewayRegistration>, +} + #[derive(Debug, Clone)] pub struct GatewayRegistration { pub details: GatewayDetails, @@ -46,12 +51,14 @@ impl GatewayDetails { derived_aes128_ctr_blake3_hmac_keys: Arc<SharedKeys>, gateway_owner_address: AccountId, gateway_listener: Url, + wg_tun_address: Option<Url>, ) -> Self { GatewayDetails::Remote(RemoteGatewayDetails { gateway_id, derived_aes128_ctr_blake3_hmac_keys, gateway_owner_address, gateway_listener, + wg_tun_address, }) } @@ -136,6 +143,7 @@ pub struct RawRemoteGatewayDetails { pub derived_aes128_ctr_blake3_hmac_keys_bs58: String, pub gateway_owner_address: String, pub gateway_listener: String, + pub wg_tun_address: Option<String>, } impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { @@ -175,11 +183,24 @@ impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { } })?; + let wg_tun_address = value + .wg_tun_address + .as_ref() + .map(|addr| { + Url::parse(addr).map_err(|source| BadGateway::MalformedListener { + gateway_id: value.gateway_id_bs58.clone(), + raw_listener: addr.clone(), + source, + }) + }) + .transpose()?; + Ok(RemoteGatewayDetails { gateway_id, derived_aes128_ctr_blake3_hmac_keys, gateway_owner_address, gateway_listener, + wg_tun_address, }) } } @@ -193,6 +214,7 @@ impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { .to_base58_string(), gateway_owner_address: value.gateway_owner_address.to_string(), gateway_listener: value.gateway_listener.to_string(), + wg_tun_address: value.wg_tun_address.map(|addr| addr.to_string()), } } } @@ -208,6 +230,8 @@ pub struct RemoteGatewayDetails { pub gateway_owner_address: AccountId, pub gateway_listener: Url, + + pub wg_tun_address: Option<Url>, } #[derive(Debug, Clone, Serialize, Deserialize)] diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 93ad844b08..e878a12028 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -236,6 +236,7 @@ where specification: selection_spec, available_gateways, overwrite_data: common_args.force_register_gateway, + wg_tun_address: None, }; let init_details = diff --git a/common/client-core/src/client/base_client/mod.rs b/common/client-core/src/client/base_client/mod.rs index 7870c5cc39..42adcf2da4 100644 --- a/common/client-core/src/client/base_client/mod.rs +++ b/common/client-core/src/client/base_client/mod.rs @@ -35,7 +35,7 @@ use crate::init::{ }; use crate::{config, spawn_future}; use futures::channel::mpsc; -use log::{debug, error, info}; +use log::{debug, error, info, warn}; use nym_bandwidth_controller::BandwidthController; use nym_client_core_gateways_storage::{GatewayDetails, GatewaysDetailsStore}; use nym_credential_storage::storage::Storage as CredentialStorage; @@ -43,6 +43,7 @@ use nym_crypto::asymmetric::encryption; use nym_gateway_client::{ AcknowledgementReceiver, GatewayClient, GatewayConfig, MixnetMessageReceiver, PacketRouter, }; +use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, WG_TUN_DEVICE_ADDRESS}; use nym_sphinx::acknowledgements::AckKey; use nym_sphinx::addressing::clients::Recipient; use nym_sphinx::addressing::nodes::NodeIdentity; @@ -179,6 +180,7 @@ pub struct BaseClientBuilder<'a, C, S: MixnetClientStorage> { dkg_query_client: Option<C>, wait_for_gateway: bool, + wireguard_connection: bool, custom_topology_provider: Option<Box<dyn TopologyProvider + Send + Sync>>, custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send>>, shutdown: Option<TaskClient>, @@ -201,6 +203,7 @@ where client_store, dkg_query_client, wait_for_gateway: false, + wireguard_connection: false, custom_topology_provider: None, custom_gateway_transceiver: None, shutdown: None, @@ -220,6 +223,12 @@ where self } + #[must_use] + pub fn with_wireguard_connection(mut self, wireguard_connection: bool) -> Self { + self.wireguard_connection = wireguard_connection; + self + } + #[must_use] pub fn with_topology_provider( mut self, @@ -343,6 +352,7 @@ where async fn start_gateway_client( config: &Config, + wireguard_connection: bool, initialisation_result: InitialisationResult, bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>, packet_router: PacketRouter, @@ -358,27 +368,41 @@ where return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails); }; - let mut gateway_client = - if let Some(existing_client) = initialisation_result.authenticated_ephemeral_client { - existing_client.upgrade(packet_router, bandwidth_controller, shutdown) + let mut gateway_client = if let Some(existing_client) = + initialisation_result.authenticated_ephemeral_client + { + existing_client.upgrade(packet_router, bandwidth_controller, shutdown) + } else { + let gateway_listener = if wireguard_connection { + if let Some(tun_address) = details.wg_tun_address { + tun_address.to_string() + } else { + let default = + format!("ws://{WG_TUN_DEVICE_ADDRESS}:{DEFAULT_CLIENT_LISTENING_PORT}"); + warn!("gateway {} does not have tun device address set. defaulting to '{default}'", details.gateway_id); + default + } } else { - let cfg = GatewayConfig::new( - details.gateway_id, - Some(details.gateway_owner_address.to_string()), - details.gateway_listener.to_string(), - ); - GatewayClient::new( - cfg, - managed_keys.identity_keypair(), - Some(details.derived_aes128_ctr_blake3_hmac_keys), - packet_router, - bandwidth_controller, - shutdown, - ) - .with_disabled_credentials_mode(config.client.disabled_credentials_mode) - .with_response_timeout(config.debug.gateway_connection.gateway_response_timeout) + details.gateway_listener.to_string() }; + let cfg = GatewayConfig::new( + details.gateway_id, + Some(details.gateway_owner_address.to_string()), + gateway_listener, + ); + GatewayClient::new( + cfg, + managed_keys.identity_keypair(), + Some(details.derived_aes128_ctr_blake3_hmac_keys), + packet_router, + bandwidth_controller, + shutdown, + ) + .with_disabled_credentials_mode(config.client.disabled_credentials_mode) + .with_response_timeout(config.debug.gateway_connection.gateway_response_timeout) + }; + gateway_client .authenticate_and_start() .await @@ -396,6 +420,7 @@ where async fn setup_gateway_transceiver( custom_gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send>>, config: &Config, + wireguard_connection: bool, initialisation_result: InitialisationResult, bandwidth_controller: Option<BandwidthController<C, S::CredentialStore>>, packet_router: PacketRouter, @@ -424,6 +449,7 @@ where // otherwise, setup normal gateway client, etc let gateway_client = Self::start_gateway_client( config, + wireguard_connection, initialisation_result, bandwidth_controller, packet_router, @@ -680,6 +706,7 @@ where let gateway_transceiver = Self::setup_gateway_transceiver( self.custom_gateway_transceiver, self.config, + self.wireguard_connection, init_res, bandwidth_controller, gateway_packet_router, diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index c6f2cf65c2..d760499c31 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -5,7 +5,7 @@ use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::ClientKeys; use crate::error::ClientCoreError; use nym_client_core_gateways_storage::{ - GatewayRegistration, GatewaysDetailsStore, GatewaysDetailsStoreExt, + ActiveGateway, GatewayRegistration, GatewaysDetailsStore, GatewaysDetailsStoreExt, }; use nym_crypto::asymmetric::identity; @@ -59,18 +59,16 @@ where pub async fn load_active_gateway_details<D>( details_store: &D, -) -> Result<GatewayRegistration, ClientCoreError> +) -> Result<ActiveGateway, ClientCoreError> where D: GatewaysDetailsStore, D::StorageError: Send + Sync + 'static, { - details_store - .active_gateway() - .await - .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + details_store.active_gateway().await.map_err(|source| { + ClientCoreError::GatewaysDetailsStoreError { source: Box::new(source), - })? - .ok_or(ClientCoreError::NoActiveGatewaySet) + } + }) } pub async fn load_gateway_details<D>( diff --git a/common/client-core/src/client/base_client/storage/migration_helpers.rs b/common/client-core/src/client/base_client/storage/migration_helpers.rs index c81011a37f..83869b5796 100644 --- a/common/client-core/src/client/base_client/storage/migration_helpers.rs +++ b/common/client-core/src/client/base_client/storage/migration_helpers.rs @@ -102,6 +102,7 @@ pub mod v1_1_33 { message: format!("the stored gateway listener address was malformed: {err}"), } })?, + wg_tun_address: None, })) } diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index d82faaba69..6bc0fa8e91 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -23,6 +23,7 @@ use nym_topology::gateway; use rand::rngs::OsRng; use rand::{CryptoRng, RngCore}; use serde::Serialize; +use std::net::IpAddr; pub mod helpers; pub mod types; @@ -46,19 +47,13 @@ where }) } -// fn ensure_valid_details( -// details: &PersistedGatewayDetails, -// loaded_keys: &ManagedKeys, -// ) -> Result<(), ClientCoreError> { -// details.validate(loaded_keys.gateway_shared_key().as_deref()) -// } - async fn setup_new_gateway<K, D>( key_store: &K, details_store: &D, overwrite_data: bool, selection_specification: GatewaySelectionSpecification, available_gateways: Vec<gateway::Node>, + wg_tun_ip_address: Option<IpAddr>, ) -> Result<InitialisationResult, ClientCoreError> where K: KeyStore, @@ -76,19 +71,19 @@ where let selected_gateway = match selection_specification { GatewaySelectionSpecification::UniformRemote { must_use_tls } => { let gateway = uniformly_random_gateway(&mut rng, &available_gateways, must_use_tls)?; - SelectedGateway::from_topology_node(gateway, must_use_tls)? + SelectedGateway::from_topology_node(gateway, wg_tun_ip_address, must_use_tls)? } GatewaySelectionSpecification::RemoteByLatency { must_use_tls } => { let gateway = choose_gateway_by_latency(&mut rng, &available_gateways, must_use_tls).await?; - SelectedGateway::from_topology_node(gateway, must_use_tls)? + SelectedGateway::from_topology_node(gateway, wg_tun_ip_address, must_use_tls)? } GatewaySelectionSpecification::Specified { must_use_tls, identity, } => { let gateway = get_specified_gateway(&identity, &available_gateways, must_use_tls)?; - SelectedGateway::from_topology_node(gateway, must_use_tls)? + SelectedGateway::from_topology_node(gateway, wg_tun_ip_address, must_use_tls)? } GatewaySelectionSpecification::Custom { gateway_identity, @@ -110,18 +105,23 @@ where gateway_id, gateway_owner_address, gateway_listener, + wg_tun_address, } => { // if we're using a 'normal' gateway setup, do register let our_identity = client_keys.identity_keypair(); + + // if wg address is set, use that one + let url = wg_tun_address.clone().unwrap_or(gateway_listener.clone()); + let registration = - helpers::register_with_gateway(gateway_id, gateway_listener.clone(), our_identity) - .await?; + helpers::register_with_gateway(gateway_id, url, our_identity).await?; ( GatewayDetails::new_remote( gateway_id, registration.shared_keys, gateway_owner_address, gateway_listener, + wg_tun_address, ), Some(registration.authenticated_ephemeral_client), ) @@ -161,7 +161,10 @@ where let loaded_details = if let Some(gateway_id) = gateway_id { load_gateway_details(details_store, &gateway_id).await? } else { - load_active_gateway_details(details_store).await? + load_active_gateway_details(details_store) + .await? + .registration + .ok_or(ClientCoreError::NoActiveGatewaySet)? }; let loaded_keys = load_client_keys(key_store).await?; @@ -205,6 +208,7 @@ where specification, available_gateways, overwrite_data, + wg_tun_address, } => { setup_new_gateway( key_store, @@ -212,6 +216,7 @@ where overwrite_data, specification, available_gateways, + wg_tun_address, ) .await } diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 7c0f1ae71b..cfbac41121 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -6,6 +6,7 @@ use crate::client::key_manager::ClientKeys; use crate::config::Config; use crate::error::ClientCoreError; use crate::init::{setup_gateway, use_loaded_gateway_details}; +use log::info; use nym_client_core_gateways_storage::{ GatewayRegistration, GatewaysDetailsStore, RemoteGatewayDetails, }; @@ -18,6 +19,7 @@ use nym_validator_client::client::IdentityKey; use nym_validator_client::nyxd::AccountId; use serde::Serialize; use std::fmt::Display; +use std::net::IpAddr; use std::str::FromStr; use std::sync::Arc; use time::OffsetDateTime; @@ -30,6 +32,8 @@ pub enum SelectedGateway { gateway_owner_address: AccountId, gateway_listener: Url, + + wg_tun_address: Option<Url>, }, Custom { gateway_id: identity::PublicKey, @@ -37,9 +41,36 @@ pub enum SelectedGateway { }, } +fn wg_tun_address( + tun_ip: Option<IpAddr>, + gateway: &gateway::Node, +) -> Result<Option<Url>, ClientCoreError> { + let Some(tun_ip) = tun_ip else { + return Ok(None); + }; + + // log this so we'd remember about it if we ever decided to actually use that port + if gateway.clients_wss_port.is_some() { + info!( + "gateway {} exposes wss but for wireguard we're going to use ws", + gateway.identity_key + ); + } + + let raw_url = format!("ws://{tun_ip}:{}", gateway.clients_ws_port); + Ok(Some(raw_url.as_str().parse().map_err(|source| { + ClientCoreError::MalformedListener { + gateway_id: gateway.identity_key.to_base58_string(), + raw_listener: raw_url, + source, + } + })?)) +} + impl SelectedGateway { pub fn from_topology_node( node: gateway::Node, + wg_tun_ip_address: Option<IpAddr>, must_use_tls: bool, ) -> Result<Self, ClientCoreError> { let gateway_listener = if must_use_tls { @@ -51,6 +82,8 @@ impl SelectedGateway { node.clients_address() }; + let wg_tun_address = wg_tun_address(wg_tun_ip_address, &node)?; + let gateway_owner_address = AccountId::from_str(&node.owner).map_err(|source| { ClientCoreError::MalformedGatewayOwnerAccountAddress { gateway_id: node.identity_key.to_base58_string(), @@ -70,6 +103,7 @@ impl SelectedGateway { gateway_id: node.identity_key, gateway_owner_address, gateway_listener, + wg_tun_address, }) } @@ -209,6 +243,12 @@ pub enum GatewaySetup { /// Specifies whether old data should be overwritten whilst setting up new gateway client. overwrite_data: bool, + + /// Implicitly specify whether the chosen gateway must use wireguard mode by setting the tun address. + /// + /// Currently this is imperfect solution as I'd imagine this address could vary from gateway to gateway + /// so perhaps it should be part of gateway::Node struct + wg_tun_address: Option<IpAddr>, }, ReuseConnection { @@ -235,6 +275,19 @@ impl GatewaySetup { } } + /// new gateway setup performed by each client that's inbuilt in a gateway (like NR or IPR) + pub fn new_inbuilt(identity: identity::PublicKey) -> Self { + GatewaySetup::New { + specification: GatewaySelectionSpecification::Custom { + gateway_identity: identity.to_base58_string(), + additional_data: None, + }, + available_gateways: vec![], + overwrite_data: false, + wg_tun_address: None, + } + } + pub async fn try_setup<K, D>( self, key_store: &K, diff --git a/common/network-defaults/src/lib.rs b/common/network-defaults/src/lib.rs index 17968821bb..55037c50ee 100644 --- a/common/network-defaults/src/lib.rs +++ b/common/network-defaults/src/lib.rs @@ -4,6 +4,7 @@ use crate::var_names::{DEPRECATED_API_VALIDATOR, DEPRECATED_NYMD_VALIDATOR, NYM_API, NYXD}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; +use std::net::{IpAddr, Ipv4Addr}; use std::path::Path; use std::{ env::{var, VarError}, @@ -521,4 +522,5 @@ pub const WG_PORT: u16 = 51822; // The interface used to route traffic pub const WG_TUN_BASE_NAME: &str = "nymwg"; pub const WG_TUN_DEVICE_ADDRESS: &str = "10.1.0.1"; +pub const WG_TUN_DEVICE_IP_ADDRESS: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 1, 0, 1)); pub const WG_TUN_DEVICE_NETMASK: &str = "255.255.255.0"; diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 8ea29169f2..e12cc337f1 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -16,10 +16,7 @@ use nym_network_defaults::mainnet; use nym_network_defaults::var_names::NYXD; use nym_network_defaults::var_names::{BECH32_PREFIX, NYM_API, STATISTICS_SERVICE_DOMAIN_ADDRESS}; use nym_network_requester::config::BaseClientConfig; -use nym_network_requester::{ - setup_fs_gateways_storage, setup_gateway, GatewaySelectionSpecification, GatewaySetup, - OnDiskKeys, -}; +use nym_network_requester::{setup_fs_gateways_storage, setup_gateway, GatewaySetup, OnDiskKeys}; use nym_types::gateway::{GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails}; use nym_validator_client::nyxd::AccountId; use std::net::IpAddr; @@ -251,7 +248,7 @@ pub(crate) fn override_ip_packet_router_config( // disable poisson rate in the BASE client if the IPR option is enabled if cfg.ip_packet_router.disable_poisson_rate { - log::info!("Disabling poisson rate for ip packet router"); + info!("Disabling poisson rate for ip packet router"); cfg.set_no_poisson_process(); } @@ -280,14 +277,7 @@ pub(crate) async fn initialise_local_network_requester( // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( - GatewaySetup::New { - specification: GatewaySelectionSpecification::Custom { - gateway_identity: identity.to_base58_string(), - additional_data: Default::default(), - }, - available_gateways: vec![], - overwrite_data: false, - }, + GatewaySetup::new_inbuilt(identity), &key_store, &details_store, ) @@ -353,14 +343,7 @@ pub(crate) async fn initialise_local_ip_packet_router( // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( - GatewaySetup::New { - specification: GatewaySelectionSpecification::Custom { - gateway_identity: identity.to_base58_string(), - additional_data: Default::default(), - }, - available_gateways: vec![], - overwrite_data: false, - }, + GatewaySetup::new_inbuilt(identity), &key_store, &details_store, ) diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index 41fb99998d..23c951119b 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -56,7 +56,7 @@ pub use nym_client_core::{ }, topology_control::geo_aware_provider::{CountryGroup, GeoAwareTopologyProvider}, }, - config::{GatewayEndpointConfig, GroupBy}, + config::GroupBy, }; pub use nym_credential_storage::{ ephemeral_storage::EphemeralStorage as EphemeralCredentialStorage, diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index 56666b1c0d..de0299b314 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -11,25 +11,27 @@ use crate::{Error, Result}; use futures::channel::mpsc; use futures::StreamExt; use log::warn; +use nym_client_core::client::base_client::storage::helpers::get_all_registered_identities; use nym_client_core::client::base_client::storage::{ Ephemeral, GatewaysDetailsStore, MixnetClientStorage, OnDiskPersistent, }; use nym_client_core::client::base_client::BaseClient; use nym_client_core::client::key_manager::persistence::KeyStore; +use nym_client_core::client::{ + base_client::BaseClientBuilder, replies::reply_storage::ReplyStorageBackend, +}; use nym_client_core::config::DebugConfig; +use nym_client_core::error::ClientCoreError; use nym_client_core::init::helpers::current_gateways; use nym_client_core::init::types::{GatewaySelectionSpecification, GatewaySetup}; -use nym_client_core::{ - client::{base_client::BaseClientBuilder, replies::reply_storage::ReplyStorageBackend}, - config::GatewayEndpointConfig, -}; -use nym_network_defaults::{DEFAULT_CLIENT_LISTENING_PORT, WG_TUN_DEVICE_ADDRESS}; +use nym_network_defaults::WG_TUN_DEVICE_IP_ADDRESS; use nym_socks5_client_core::config::Socks5; use nym_task::manager::TaskStatus; use nym_task::{TaskClient, TaskHandle}; use nym_topology::provider_trait::TopologyProvider; use nym_validator_client::{nyxd, QueryHttpRpcNyxdClient}; use rand::rngs::OsRng; +use std::net::IpAddr; use std::path::Path; use std::path::PathBuf; use url::Url; @@ -41,7 +43,6 @@ const DEFAULT_NUMBER_OF_SURBS: u32 = 10; pub struct MixnetClientBuilder<S: MixnetClientStorage = Ephemeral> { config: Config, storage_paths: Option<StoragePaths>, - gateway_config: Option<GatewayEndpointConfig>, socks5_config: Option<Socks5>, wireguard_mode: bool, @@ -78,7 +79,6 @@ impl MixnetClientBuilder<OnDiskPersistent> { Ok(MixnetClientBuilder { config: Default::default(), storage_paths: None, - gateway_config: None, socks5_config: None, wireguard_mode: false, wait_for_gateway: false, @@ -98,6 +98,7 @@ impl<S> MixnetClientBuilder<S> where S: MixnetClientStorage + 'static, S::ReplyStore: Send + Sync, + S::GatewaysDetailsStore: Sync, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, @@ -109,7 +110,6 @@ where MixnetClientBuilder { config: Default::default(), storage_paths: None, - gateway_config: None, socks5_config: None, wireguard_mode: false, wait_for_gateway: false, @@ -128,7 +128,6 @@ where MixnetClientBuilder { config: self.config, storage_paths: self.storage_paths, - gateway_config: self.gateway_config, socks5_config: self.socks5_config, wireguard_mode: self.wireguard_mode, wait_for_gateway: self.wait_for_gateway, @@ -303,6 +302,7 @@ impl<S> DisconnectedMixnetClient<S> where S: MixnetClientStorage + 'static, S::ReplyStore: Send + Sync, + S::GatewaysDetailsStore: Sync, <S::ReplyStore as ReplyStorageBackend>::StorageError: Sync + Send, <S::CredentialStore as CredentialStorage>::StorageError: Send + Sync, <S::KeyStore as KeyStore>::StorageError: Send + Sync, @@ -410,40 +410,58 @@ where .collect() } - /// Client keys are generated at client creation if none were found. The gateway shared - /// key, however, is created during the gateway registration handshake, so it might not - /// necessarily be available. - /// Furthermore, it has to be coupled with particular gateway's config. - async fn has_valid_gateway_info(&self) -> bool { - let keys = match self.storage.key_store().load_keys().await { - Ok(keys) => keys, + fn wireguard_tun_address(&self) -> Option<IpAddr> { + // currently use a hardcoded value here, but perhaps we should change that later + if self.wireguard_mode { + Some(WG_TUN_DEVICE_IP_ADDRESS) + } else { + None + } + } + + async fn new_gateway_setup(&self) -> Result<GatewaySetup, ClientCoreError> { + let nym_api_endpoints = self.get_api_endpoints(); + + let selection_spec = GatewaySelectionSpecification::new( + self.config.user_chosen_gateway.clone(), + None, + self.force_tls, + ); + + let mut rng = OsRng; + let available_gateways = current_gateways(&mut rng, &nym_api_endpoints).await?; + + Ok(GatewaySetup::New { + specification: selection_spec, + available_gateways, + overwrite_data: !self.config.key_mode.is_keep(), + wg_tun_address: self.wireguard_tun_address(), + }) + } + + /// Check if the client already has an active gateway enabled. + async fn has_active_gateway(&self) -> bool { + let storage = self.storage.gateway_details_store(); + + if storage.active_gateway().await.is_ok() { + return true; + } + + match get_all_registered_identities(storage).await { Err(err) => { - warn!("failed to load stored keys: {err}"); - return false; + warn!("failed to query for all registered gateways: {err}") } - }; + Ok(all_ids) => { + if !all_ids.is_empty() { + warn!("this client doesn't have an active gateway set, however, it's already registered with the following gateways (consider making one of them active):"); + for id in all_ids { + warn!("{id}") + } + } + } + } - todo!() - - // let gateway_details = match self - // .storage - // .gateway_details_store() - // .load_gateway_details() - // .await - // { - // Ok(details) => details, - // Err(err) => { - // warn!("failed to load stored gateway details: {err}"); - // return false; - // } - // }; - // - // if let Err(err) = gateway_details.validate(keys.gateway_shared_key().as_deref()) { - // warn!("stored key verification failure: {err}"); - // return false; - // } - // - // true + false } /// Register with a gateway. If a gateway is provided in the config then that will try to be @@ -460,24 +478,10 @@ where log::debug!("Registering with gateway"); - let api_endpoints = self.get_api_endpoints(); - - let gateway_setup = if self.has_valid_gateway_info().await { + let gateway_setup = if self.has_active_gateway().await { GatewaySetup::MustLoad { gateway_id: None } } else { - let selection_spec = GatewaySelectionSpecification::new( - self.config.user_chosen_gateway.clone(), - None, - self.force_tls, - ); - - let mut rng = OsRng; - - GatewaySetup::New { - specification: selection_spec, - available_gateways: current_gateways(&mut rng, &api_endpoints).await?, - overwrite_data: !self.config.key_mode.is_keep(), - } + self.new_gateway_setup().await? }; // this will perform necessary key and details load and optional store @@ -525,60 +529,70 @@ where .config .as_base_client_config(nyxd_endpoints, nym_api_endpoints.clone()); - let known_gateway = self.has_valid_gateway_info().await; + let known_gateway = self.has_active_gateway().await; - let mut base_builder: BaseClientBuilder<_, _> = if !known_gateway { - let selection_spec = GatewaySelectionSpecification::new( - self.config.user_chosen_gateway, - None, - self.force_tls, - ); - - let mut rng = OsRng; - let mut available_gateways = current_gateways(&mut rng, &nym_api_endpoints).await?; - if self.wireguard_mode { - available_gateways - .iter_mut() - .for_each(|node| node.host = WG_TUN_DEVICE_ADDRESS.parse().unwrap()); - } - let setup = GatewaySetup::New { - specification: selection_spec, - available_gateways, - overwrite_data: !self.config.key_mode.is_keep(), - }; - - BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) - .with_wait_for_gateway(self.wait_for_gateway) - .with_gateway_setup(setup) - } else if self.wireguard_mode { - todo!() - // if let Ok(PersistedGatewayDetails::Default(mut config)) = self - // .storage - // .gateway_details_store() - // .load_gateway_details() - // .await - // { - // config.details.gateway_listener = format!( - // "ws://{}:{}", - // WG_TUN_DEVICE_ADDRESS, DEFAULT_CLIENT_LISTENING_PORT - // ); - // if let Err(e) = self - // .storage - // .gateway_details_store() - // .store_gateway_details(&PersistedGatewayDetails::Default(config)) - // .await - // { - // warn!("Could not switch to using wireguard mode - {:?}", e); - // } - // } else { - // warn!("Storage type not supported with wireguard mode"); - // } - // BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) - // .with_wait_for_gateway(self.wait_for_gateway) + // if we have a known gateway, don't bother doing all of those queries + let gateway_setup = if known_gateway { + None } else { + Some(self.new_gateway_setup().await?) + }; + + let mut base_builder: BaseClientBuilder<_, _> = BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) .with_wait_for_gateway(self.wait_for_gateway) - }; + .with_wireguard_connection(self.wireguard_mode); + + if !known_gateway { + // safety: `gateway_setup` is always set whenever `known_gateway` is false + base_builder = base_builder.with_gateway_setup(gateway_setup.unwrap()); + } + + // let mut base_builder: BaseClientBuilder<_, _> = if !known_gateway { + // // we need to setup a new gateway + // let setup = self.new_gateway_setup().await; + // + // BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + // .with_wait_for_gateway(self.wait_for_gateway) + // .with_gateway_setup(setup) + // // } else if self.wireguard_mode { + // // // load current active gateway in wireguard mode + // // details_store.set_wireguard_mode(true).await?; + // // + // // if let Ok(PersistedGatewayDetails::Default(mut config)) = self + // // .storage + // // .gateway_details_store() + // // .load_gateway_details() + // // .await + // // { + // // config.details.gateway_listener = format!( + // // "ws://{}:{}", + // // WG_TUN_DEVICE_ADDRESS, DEFAULT_CLIENT_LISTENING_PORT + // // ); + // // if let Err(e) = self + // // .storage + // // .gateway_details_store() + // // .store_gateway_details(&PersistedGatewayDetails::Default(config)) + // // .await + // // { + // // warn!("Could not switch to using wireguard mode - {:?}", e); + // // } + // // } else { + // // warn!("Storage type not supported with wireguard mode"); + // // } + // // BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + // // .with_wait_for_gateway(self.wait_for_gateway) + // } else { + // // load current active gateway in non-wireguard mode + // + // // make sure our current storage mode matches the desired wg mode + // details_store + // .set_wireguard_mode(self.wireguard_mode) + // .await?; + // + // BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) + // .with_wait_for_gateway(self.wait_for_gateway) + // }; if let Some(topology_provider) = self.custom_topology_provider { base_builder = base_builder.with_topology_provider(topology_provider); From b4e45ef3ef76236c573f805d18a011f7c32ee1c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 15:08:26 +0000 Subject: [PATCH 303/394] fixed active gateway detection in rust sdk --- sdk/rust/nym-sdk/src/mixnet/client.rs | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index de0299b314..b59b7d20bb 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -443,8 +443,16 @@ where async fn has_active_gateway(&self) -> bool { let storage = self.storage.gateway_details_store(); - if storage.active_gateway().await.is_ok() { - return true; + match storage.active_gateway().await { + Err(err) => { + warn!("failed to query for the current active gateway: {err}"); + return false; + } + Ok(active) => { + if active.registration.is_some() { + return true; + } + } } match get_all_registered_identities(storage).await { From 40f08dcbb20026798a50cb63bad722b322b0a8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 16:02:06 +0000 Subject: [PATCH 304/394] impl GatewaysDetailsStore for OnDiskGatewaysDetails without the underlying sql --- .../20240304120000_create_initial_tables.sql | 3 + .../src/backend/fs_backend/manager.rs | 92 ++++++++++++++- .../src/backend/fs_backend/mod.rs | 105 ++++++++++++++++-- .../client-core/gateways-storage/src/lib.rs | 31 ++---- .../client-core/gateways-storage/src/types.rs | 36 +++++- .../src/client/base_client/storage/helpers.rs | 4 +- .../src/client/base_client/storage/mod.rs | 2 +- 7 files changed, 234 insertions(+), 39 deletions(-) diff --git a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql index 77c32b4fa9..0382f37313 100644 --- a/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql +++ b/common/client-core/gateways-storage/fs_gateways_migrations/20240304120000_create_initial_tables.sql @@ -34,3 +34,6 @@ CREATE TABLE custom_gateway_details data BLOB ); + +INSERT INTO active_gateway(id, active_gateway_id_bs58) +values (0, NULL); \ No newline at end of file diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 5447c6c9ab..72d886bce6 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -1,7 +1,12 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::backend::fs_backend::error::StorageError; +use crate::{ + backend::fs_backend::error::StorageError, + types::{ + RawActiveGateway, RawCustomGatewayDetails, RawRegisteredGateway, RawRemoteGatewayDetails, + }, +}; use log::{error, info}; use sqlx::ConnectOptions; use std::path::Path; @@ -47,4 +52,89 @@ impl StorageManager { info!("Database migration finished!"); Ok(StorageManager { connection_pool }) } + + pub(crate) async fn get_active_gateway(&self) -> Result<RawActiveGateway, sqlx::Error> { + todo!() + } + + pub(crate) async fn set_active_gateway( + &self, + gateway_id: Option<&str>, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn maybe_get_registered_gateway( + &self, + gateway_id: &str, + ) -> Result<Option<RawRegisteredGateway>, sqlx::Error> { + todo!() + } + + pub(crate) async fn must_get_registered_gateway( + &self, + gateway_id: &str, + ) -> Result<RawRegisteredGateway, sqlx::Error> { + todo!() + } + + pub(crate) async fn set_registered_gateway( + &self, + registered_gateway: &RawRegisteredGateway, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn remove_registered_gateway( + &self, + gateway_id: &str, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn get_remote_gateway_details( + &self, + gateway_id: &str, + ) -> Result<RawRemoteGatewayDetails, sqlx::Error> { + todo!() + } + + pub(crate) async fn set_remote_gateway_details( + &self, + remote: &RawRemoteGatewayDetails, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn remove_remote_gateway_details( + &self, + gateway_id: &str, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn get_custom_gateway_details( + &self, + gateway_id: &str, + ) -> Result<RawCustomGatewayDetails, sqlx::Error> { + todo!() + } + + pub(crate) async fn set_custom_gateway_details( + &self, + custom: &RawCustomGatewayDetails, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn remove_custom_gateway_details( + &self, + gateway_id: &str, + ) -> Result<(), sqlx::Error> { + todo!() + } + + pub(crate) async fn registered_gateways(&self) -> Result<Vec<String>, sqlx::Error> { + todo!() + } } diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 5061fe60fc..7e0fbcdebc 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -1,10 +1,13 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::types::GatewayRegistration; -use crate::{ActiveGateway, GatewaysDetailsStore, StorageError}; +use crate::{ + ActiveGateway, BadGateway, GatewayDetails, GatewayRegistration, GatewayType, + GatewaysDetailsStore, StorageError, +}; use async_trait::async_trait; use manager::StorageManager; +use nym_crypto::asymmetric::identity::PublicKey; use std::path::Path; pub mod error; @@ -28,36 +31,120 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { type StorageError = error::StorageError; async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { - todo!() + Ok(self + .manager + .maybe_get_registered_gateway(gateway_id) + .await? + .is_some()) } async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError> { - todo!() + let raw_active = self.manager.get_active_gateway().await?; + let registration = match raw_active.active_gateway_id_bs58 { + None => None, + Some(gateway_id) => Some(self.load_gateway_details(&gateway_id).await?), + }; + + Ok(ActiveGateway { registration }) } async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { - todo!() + Ok(self.manager.set_active_gateway(Some(gateway_id)).await?) } async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { - todo!() + let identities = self.manager.registered_gateways().await?; + let mut registered = Vec::with_capacity(identities.len()); + for gateway_id in identities { + registered.push(self.load_gateway_details(&gateway_id).await?) + } + + Ok(registered) + } + + async fn all_gateways_identities(&self) -> Result<Vec<PublicKey>, Self::StorageError> { + Ok(self + .manager + .registered_gateways() + .await? + .into_iter() + .map(|gateway_id| { + gateway_id + .as_str() + .parse() + .map_err(|source| BadGateway::MalformedGatewayIdentity { gateway_id, source }) + }) + .collect::<Result<_, _>>()?) } async fn load_gateway_details( &self, gateway_id: &str, ) -> Result<GatewayRegistration, Self::StorageError> { - todo!() + let raw_registration = self.manager.must_get_registered_gateway(gateway_id).await?; + let typ: GatewayType = raw_registration.gateway_type.parse()?; + + let details = match typ { + GatewayType::Remote => { + let raw_details = self.manager.get_remote_gateway_details(gateway_id).await?; + GatewayDetails::Remote(raw_details.try_into()?) + } + GatewayType::Custom => { + let raw_details = self.manager.get_custom_gateway_details(gateway_id).await?; + GatewayDetails::Custom(raw_details.try_into()?) + } + }; + + Ok(GatewayRegistration { + details, + registration_timestamp: raw_registration.registration_timestamp, + }) } async fn store_gateway_details( &self, details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { - todo!() + let raw_registration = details.into(); + self.manager + .set_registered_gateway(&raw_registration) + .await?; + + match &details.details { + GatewayDetails::Remote(remote_details) => { + let raw_details = remote_details.into(); + self.manager + .set_remote_gateway_details(&raw_details) + .await?; + } + GatewayDetails::Custom(custom_details) => { + let raw_details = custom_details.into(); + self.manager + .set_custom_gateway_details(&raw_details) + .await?; + } + } + Ok(()) } + // ideally all of those should be run under a storage tx to ensure storage consistency, + // but at that point it's fine async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError> { - todo!() + let active = self.manager.get_active_gateway().await?; + if let Some(currently_active) = &active.active_gateway_id_bs58 { + if currently_active == gateway_id { + self.manager.set_active_gateway(None).await?; + } + } + + // just try remove it from all tables even if it doesn't actually exist + self.manager.remove_registered_gateway(gateway_id).await?; + self.manager + .remove_remote_gateway_details(gateway_id) + .await?; + self.manager + .remove_custom_gateway_details(gateway_id) + .await?; + Ok(()) } } diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 26deeec049..42c10b9df9 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -37,6 +37,18 @@ pub trait GatewaysDetailsStore { /// Returns details of all registered gateways. async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError>; + /// Return identity keys of all registered gateways. + async fn all_gateways_identities( + &self, + ) -> Result<Vec<identity::PublicKey>, Self::StorageError> { + Ok(self + .all_gateways() + .await? + .into_iter() + .map(|gateway| gateway.details.gateway_id()) + .collect()) + } + /// Check if the gateway with the provided id already exists in the store. async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError>; @@ -55,22 +67,3 @@ pub trait GatewaysDetailsStore { /// Remove given gateway details from the underlying store. async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError>; } - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -pub trait GatewaysDetailsStoreExt: GatewaysDetailsStore { - async fn all_gateways_identities( - &self, - ) -> Result<Vec<identity::PublicKey>, Self::StorageError> { - Ok(self - .all_gateways() - .await? - .into_iter() - .map(|gateway| gateway.details.gateway_id()) - .collect()) - } -} - -#[cfg_attr(target_arch = "wasm32", async_trait(?Send))] -#[cfg_attr(not(target_arch = "wasm32"), async_trait)] -impl<T> GatewaysDetailsStoreExt for T where T: GatewaysDetailsStore {} diff --git a/common/client-core/gateways-storage/src/types.rs b/common/client-core/gateways-storage/src/types.rs index a63cd4f5d8..3755cb6127 100644 --- a/common/client-core/gateways-storage/src/types.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -27,6 +27,16 @@ pub struct GatewayRegistration { pub registration_timestamp: OffsetDateTime, } +impl<'a> From<&'a GatewayRegistration> for RawRegisteredGateway { + fn from(value: &'a GatewayRegistration) -> Self { + RawRegisteredGateway { + gateway_id_bs58: value.details.gateway_id().to_base58_string(), + registration_timestamp: value.registration_timestamp, + gateway_type: value.details.typ().to_string(), + } + } +} + #[derive(Debug, Clone)] pub enum GatewayDetails { /// Standard details of a remote gateway @@ -83,6 +93,13 @@ impl GatewayDetails { pub fn is_custom(&self) -> bool { matches!(self, GatewayDetails::Custom(..)) } + + pub fn typ(&self) -> GatewayType { + match self { + GatewayDetails::Remote(_) => GatewayType::Remote, + GatewayDetails::Custom(_) => GatewayType::Custom, + } + } } #[derive(Debug, Copy, Clone, Default)] @@ -116,6 +133,12 @@ impl Display for GatewayType { } } +#[derive(Debug, Clone, Serialize, Deserialize)] +#[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] +pub struct RawActiveGateway { + pub active_gateway_id_bs58: Option<String>, +} + #[derive(Debug, Clone, Serialize, Deserialize)] #[cfg_attr(feature = "sqlx", derive(sqlx::FromRow))] pub struct RawRegisteredGateway { @@ -205,8 +228,8 @@ impl TryFrom<RawRemoteGatewayDetails> for RemoteGatewayDetails { } } -impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { - fn from(value: RemoteGatewayDetails) -> Self { +impl<'a> From<&'a RemoteGatewayDetails> for RawRemoteGatewayDetails { + fn from(value: &'a RemoteGatewayDetails) -> Self { RawRemoteGatewayDetails { gateway_id_bs58: value.gateway_id.to_base58_string(), derived_aes128_ctr_blake3_hmac_keys_bs58: value @@ -214,7 +237,7 @@ impl From<RemoteGatewayDetails> for RawRemoteGatewayDetails { .to_base58_string(), gateway_owner_address: value.gateway_owner_address.to_string(), gateway_listener: value.gateway_listener.to_string(), - wg_tun_address: value.wg_tun_address.map(|addr| addr.to_string()), + wg_tun_address: value.wg_tun_address.as_ref().map(|addr| addr.to_string()), } } } @@ -260,11 +283,12 @@ impl TryFrom<RawCustomGatewayDetails> for CustomGatewayDetails { } } -impl From<CustomGatewayDetails> for RawCustomGatewayDetails { - fn from(value: CustomGatewayDetails) -> Self { +impl<'a> From<&'a CustomGatewayDetails> for RawCustomGatewayDetails { + fn from(value: &'a CustomGatewayDetails) -> Self { RawCustomGatewayDetails { gateway_id_bs58: value.gateway_id.to_base58_string(), - data: value.data, + // I don't know what to feel about that clone here given it might contain possibly sensitive data + data: value.data.clone(), } } } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index d760499c31..3ed3379b10 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -4,9 +4,7 @@ use crate::client::key_manager::persistence::KeyStore; use crate::client::key_manager::ClientKeys; use crate::error::ClientCoreError; -use nym_client_core_gateways_storage::{ - ActiveGateway, GatewayRegistration, GatewaysDetailsStore, GatewaysDetailsStoreExt, -}; +use nym_client_core_gateways_storage::{ActiveGateway, GatewayRegistration, GatewaysDetailsStore}; use nym_crypto::asymmetric::identity; // helpers for error wrapping diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 2158788cd3..583625cddf 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -28,7 +28,7 @@ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentC pub use nym_client_core_gateways_storage::{ CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, GatewaysDetailsStore, - GatewaysDetailsStoreExt, InMemGatewaysDetails, RegisteredGateway, RemoteGatewayDetails, + InMemGatewaysDetails, RegisteredGateway, RemoteGatewayDetails, }; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] From c4bc156cacd984c654cb1699f324bb034753cffa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 16:39:38 +0000 Subject: [PATCH 305/394] actual sql --- .../client-core/gateways-storage/Cargo.toml | 2 +- .../src/backend/fs_backend/manager.rs | 110 +++++++++++++++--- .../base_client/storage/migration_helpers.rs | 2 +- nym-connect/desktop/Cargo.lock | 1 + 4 files changed, 100 insertions(+), 15 deletions(-) diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml index 3968df079e..567744d1b6 100644 --- a/common/client-core/gateways-storage/Cargo.toml +++ b/common/client-core/gateways-storage/Cargo.toml @@ -21,7 +21,7 @@ nym-gateway-requests = { path = "../../../gateway/gateway-requests" } [target."cfg(not(target_arch = \"wasm32\"))".dependencies.sqlx] workspace = true -features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] +features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate", "time"] optional = true [build-dependencies] diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 72d886bce6..965ace23f6 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -54,87 +54,171 @@ impl StorageManager { } pub(crate) async fn get_active_gateway(&self) -> Result<RawActiveGateway, sqlx::Error> { - todo!() + sqlx::query_as!( + RawActiveGateway, + "SELECT active_gateway_id_bs58 FROM active_gateway" + ) + .fetch_one(&self.connection_pool) + .await } pub(crate) async fn set_active_gateway( &self, gateway_id: Option<&str>, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + "UPDATE active_gateway SET active_gateway_id_bs58 = ?", + gateway_id + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn maybe_get_registered_gateway( &self, gateway_id: &str, ) -> Result<Option<RawRegisteredGateway>, sqlx::Error> { - todo!() + sqlx::query_as("SELECT * FROM registered_gateway WHERE gateway_id_bs58 = ?") + .bind(gateway_id) + .fetch_optional(&self.connection_pool) + .await } pub(crate) async fn must_get_registered_gateway( &self, gateway_id: &str, ) -> Result<RawRegisteredGateway, sqlx::Error> { - todo!() + sqlx::query_as("SELECT * FROM registered_gateway WHERE gateway_id_bs58 = ?") + .bind(gateway_id) + .fetch_one(&self.connection_pool) + .await } pub(crate) async fn set_registered_gateway( &self, registered_gateway: &RawRegisteredGateway, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO registered_gateway(gateway_id_bs58, registration_timestamp, gateway_type) + VALUES (?, ?, ?) + "#, + registered_gateway.gateway_id_bs58, + registered_gateway.registration_timestamp, + registered_gateway.gateway_type, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn remove_registered_gateway( &self, gateway_id: &str, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + "DELETE FROM registered_gateway WHERE gateway_id_bs58 = ?", + gateway_id + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn get_remote_gateway_details( &self, gateway_id: &str, ) -> Result<RawRemoteGatewayDetails, sqlx::Error> { - todo!() + sqlx::query_as!( + RawRemoteGatewayDetails, + "SELECT * FROM remote_gateway_details WHERE gateway_id_bs58 = ?", + gateway_id + ) + .fetch_one(&self.connection_pool) + .await } pub(crate) async fn set_remote_gateway_details( &self, remote: &RawRemoteGatewayDetails, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO remote_gateway_details(gateway_id_bs58, derived_aes128_ctr_blake3_hmac_keys_bs58, gateway_owner_address, gateway_listener, wg_tun_address) + VALUES (?, ?, ?, ?, ?) + "#, + remote.gateway_id_bs58, + remote.derived_aes128_ctr_blake3_hmac_keys_bs58, + remote.gateway_owner_address, + remote.gateway_listener, + remote.wg_tun_address, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn remove_remote_gateway_details( &self, gateway_id: &str, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + "DELETE FROM remote_gateway_details WHERE gateway_id_bs58 = ?", + gateway_id + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn get_custom_gateway_details( &self, gateway_id: &str, ) -> Result<RawCustomGatewayDetails, sqlx::Error> { - todo!() + sqlx::query_as!( + RawCustomGatewayDetails, + "SELECT * FROM custom_gateway_details WHERE gateway_id_bs58 = ?", + gateway_id + ) + .fetch_one(&self.connection_pool) + .await } pub(crate) async fn set_custom_gateway_details( &self, custom: &RawCustomGatewayDetails, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + r#" + INSERT INTO custom_gateway_details(gateway_id_bs58, data) + VALUES (?, ?) + "#, + custom.gateway_id_bs58, + custom.data, + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn remove_custom_gateway_details( &self, gateway_id: &str, ) -> Result<(), sqlx::Error> { - todo!() + sqlx::query!( + "DELETE FROM custom_gateway_details WHERE gateway_id_bs58 = ?", + gateway_id + ) + .execute(&self.connection_pool) + .await?; + Ok(()) } pub(crate) async fn registered_gateways(&self) -> Result<Vec<String>, sqlx::Error> { - todo!() + sqlx::query!("SELECT gateway_id_bs58 FROM registered_gateway") + .fetch_all(&self.connection_pool) + .await + .map(|records| records.into_iter().map(|r| r.gateway_id_bs58).collect()) } } diff --git a/common/client-core/src/client/base_client/storage/migration_helpers.rs b/common/client-core/src/client/base_client/storage/migration_helpers.rs index 83869b5796..87738faef4 100644 --- a/common/client-core/src/client/base_client/storage/migration_helpers.rs +++ b/common/client-core/src/client/base_client/storage/migration_helpers.rs @@ -203,7 +203,7 @@ pub mod v1_1_33 { ) .await?; - remove_old_gateway_details(&old_storage_paths).map_err(|err| { + remove_old_gateway_details(old_storage_paths).map_err(|err| { ClientCoreError::UpgradeFailure { message: format!("failed to remove old data: {err}"), } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 86afcd16e4..afbc2f403f 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -6618,6 +6618,7 @@ dependencies = [ "sqlx-rt", "stringprep", "thiserror", + "time", "tokio-stream", "url", "webpki-roots", From 765ac715c103b440fa56b0d13be429ae3a50d9ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 8 Mar 2024 17:25:36 +0000 Subject: [PATCH 306/394] fixing builds of x86-based binaries --- .../src/client/base_client/storage/mod.rs | 5 +- common/client-core/src/init/types.rs | 5 +- common/wasm/client-core/src/lib.rs | 2 +- .../desktop/src-tauri/src/config/mod.rs | 72 +++++----- .../src/config/old_config_v1_1_20.rs | 4 +- .../src/config/old_config_v1_1_20_2.rs | 8 +- .../src/config/old_config_v1_1_30.rs | 13 +- .../src/config/old_config_v1_1_33.rs | 47 ++++++ .../desktop/src-tauri/src/config/upgrade.rs | 135 +++++++++++------- .../src-tauri/src/operations/export.rs | 4 - nym-connect/desktop/src-tauri/src/state.rs | 8 +- nym-connect/desktop/src-tauri/src/tasks.rs | 14 +- sdk/lib/socks5-listener/src/lib.rs | 1 + .../examples/manually_handle_storage.rs | 50 ++++++- 14 files changed, 245 insertions(+), 123 deletions(-) create mode 100644 nym-connect/desktop/src-tauri/src/config/old_config_v1_1_33.rs diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 583625cddf..e1b02fc347 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -27,8 +27,9 @@ use crate::{ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; pub use nym_client_core_gateways_storage::{ - CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, GatewaysDetailsStore, - InMemGatewaysDetails, RegisteredGateway, RemoteGatewayDetails, + ActiveGateway, BadGateway, CustomGatewayDetails, GatewayDetails, GatewayRegistration, + GatewayType, GatewaysDetailsStore, InMemGatewaysDetails, RegisteredGateway, + RemoteGatewayDetails, }; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index cfbac41121..019b5218e3 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -320,6 +320,7 @@ pub struct InitResults { pub encryption_key: String, pub gateway_id: String, pub gateway_listener: String, + pub gateway_registration: OffsetDateTime, pub address: Recipient, } @@ -337,6 +338,7 @@ impl InitResults { encryption_key: address.encryption_key().to_base58_string(), gateway_id: gateway.gateway_id.to_base58_string(), gateway_listener: gateway.gateway_listener.to_string(), + gateway_registration: registration, address, } } @@ -349,6 +351,7 @@ impl Display for InitResults { writeln!(f, "Identity key: {}", self.identity_key)?; writeln!(f, "Encryption: {}", self.encryption_key)?; writeln!(f, "Gateway ID: {}", self.gateway_id)?; - write!(f, "Gateway: {}", self.gateway_listener) + writeln!(f, "Gateway: {}", self.gateway_listener)?; + write!(f, "Registered at: {}", self.gateway_registration) } } diff --git a/common/wasm/client-core/src/lib.rs b/common/wasm/client-core/src/lib.rs index 568b2b459e..5204b75925 100644 --- a/common/wasm/client-core/src/lib.rs +++ b/common/wasm/client-core/src/lib.rs @@ -16,7 +16,7 @@ pub mod topology; pub use nym_bandwidth_controller::BandwidthController; pub use nym_client_core::*; pub use nym_client_core::{ - client::key_manager::ManagedKeys, error::ClientCoreError, init::types::InitialisationResult, + client::key_manager::ClientKeys, error::ClientCoreError, init::types::InitialisationResult, }; pub use nym_gateway_client::{error::GatewayClientError, GatewayClient, GatewayConfig}; pub use nym_sphinx::{ diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 34176af06a..2a855b82ba 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -5,10 +5,11 @@ use crate::config::persistence::NymConnectPaths; use crate::config::template::CONFIG_TEMPLATE; use crate::config::upgrade::try_upgrade_config; use crate::error::{BackendError, Result}; -use nym_client_core::client::base_client::storage::gateway_details::OnDiskGatewayDetails; +use nym_client_core::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use nym_client_core::client::base_client::storage::{GatewayDetails, RemoteGatewayDetails}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; use nym_client_core::error::ClientCoreError; +use nym_client_core::init::generate_new_client_keys; use nym_client_core::init::helpers::current_gateways; use nym_client_core::init::types::{GatewaySelectionSpecification, GatewaySetup}; use nym_config::{ @@ -17,6 +18,7 @@ use nym_config::{ }; use nym_crypto::asymmetric::identity; use nym_socks5_client_core::config::Config as Socks5CoreConfig; +use rand_07::rngs::OsRng; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; use std::{fs, io}; @@ -26,6 +28,7 @@ mod old_config_v1_1_13; mod old_config_v1_1_20; mod old_config_v1_1_20_2; mod old_config_v1_1_30; +mod old_config_v1_1_33; mod persistence; mod template; mod upgrade; @@ -163,24 +166,21 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str let already_init = if config_path.exists() { // in case we're using old config, try to upgrade it // (if we're using the current version, it's a no-op) - if let Err(err) = try_upgrade_config(&id) { + if let Err(err) = try_upgrade_config(&id).await { log::error!( - "Failed to upgrade config file {}: {:?}", + "Failed to upgrade config file {}: {err}", config_path.display(), - err ); - if let Some(failed_at_version) = try_extract_version_for_upgrade_failure(err) { - return Err( + return if let Some(failed_at_version) = try_extract_version_for_upgrade_failure(err) { + Err( BackendError::CouldNotUpgradeExistingConfigurationFileAtVersion { file: config_path, failed_at_version, }, - ); + ) } else { - return Err(BackendError::CouldNotUpgradeExistingConfigurationFile { - file: config_path, - }); - } + Err(BackendError::CouldNotUpgradeExistingConfigurationFile { file: config_path }) + }; }; eprintln!("SOCKS5 client \"{id}\" was already initialised before"); true @@ -189,13 +189,8 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str false }; - // Future proofing. This flag exists for the other clients - let user_wants_force_register = false; - - // If the client was already initialized, don't generate new keys and don't re-register with - // the gateway (because this would create a new shared key). - // Unless the user really wants to. - let register_gateway = !already_init || user_wants_force_register; + // // Future proofing. This flag exists for the other clients + // let user_wants_force_register = false; log::trace!("Creating config for id: {id}"); let mut config = Config::new(&id, &provider_address); @@ -204,7 +199,17 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str config.core.base.client.nym_api_urls = nym_config::parse_urls(&raw_validators); } - let gateway_setup = if register_gateway { + let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); + let details_store = + setup_fs_gateways_storage(&config.storage_paths.common_paths.gateway_registrations).await?; + + // if this is a first time client with this particular id is initialised, generated long-term keys + if !already_init { + let mut rng = OsRng; + generate_new_client_keys(&mut rng, &key_store).await?; + } + + let gateway_setup = if !already_init { let selection_spec = GatewaySelectionSpecification::new(Some(chosen_gateway_id), None, false); let mut rng = rand_07::thread_rng(); @@ -213,41 +218,40 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: register_gateway, + overwrite_data: true, + wg_tun_address: None, } } else { - GatewaySetup::MustLoad + GatewaySetup::MustLoad { + gateway_id: Some(chosen_gateway_id), + } }; - // Setup gateway by either registering a new one, or reusing exiting keys - let key_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - let details_store = - OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); let init_details = nym_client_core::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; - let gateway_endpoint = init_details - .gateway_details - .try_get_configured_endpoint() - .unwrap(); + + let GatewayDetails::Remote(gateway_details) = &init_details.gateway_registration.details else { + return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; + }; config.save_to_default_location().tap_err(|_| { log::error!("Failed to save the config file"); })?; - print_saved_config(&config, gateway_endpoint); + print_saved_config(&config, gateway_details); - let address = init_details.client_address()?; + let address = init_details.client_address(); log::info!("The address of this client is: {address}"); Ok(()) } -fn print_saved_config(config: &Config, gateway_details: &GatewayEndpointConfig) { +fn print_saved_config(config: &Config, gateway_details: &RemoteGatewayDetails) { log::info!( "Saved configuration file to {}", config.default_location().display() ); log::info!("Gateway id: {}", gateway_details.gateway_id); - log::info!("Gateway owner: {}", gateway_details.gateway_owner); + log::info!("Gateway owner: {}", gateway_details.gateway_owner_address); log::info!("Gateway listener: {}", gateway_details.gateway_listener); log::info!( "Service provider address: {}", diff --git a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20.rs b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20.rs index 4acc4fccbd..fbad434c68 100644 --- a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20.rs +++ b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20.rs @@ -5,8 +5,8 @@ use crate::config::old_config_v1_1_20_2::{ ConfigV1_1_20_2, CoreConfigV1_1_20_2, SocksClientPathsV1_1_20_2, }; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; use nym_client_core::config::old_config_v1_1_20_2::ClientV1_1_20_2; use nym_config::legacy_helpers::nym_config::MigrationNymConfig; @@ -50,7 +50,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { }, storage_paths: SocksClientPathsV1_1_20_2 { common_paths: CommonClientPathsV1_1_20_2 { - keys: ClientKeysPaths { + keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, public_identity_key_file: value.base.client.public_identity_key_file, private_encryption_key_file: value.base.client.private_encryption_key_file, diff --git a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20_2.rs b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20_2.rs index d87f41ae0f..6af24d249a 100644 --- a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20_2.rs +++ b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_20_2.rs @@ -3,11 +3,11 @@ use crate::config::default_config_filepath; use crate::config::old_config_v1_1_30::ConfigV1_1_30; -use crate::config::persistence::NymConnectPaths; +use crate::config::old_config_v1_1_33::NymConnectPathsV1_1_33; use crate::error::Result; use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use serde::{Deserialize, Serialize}; use std::io; @@ -42,11 +42,11 @@ impl ConfigV1_1_20_2 { // in this upgrade, gateway endpoint configuration was moved out of the config file, // so its returned to be stored elsewhere. - pub fn upgrade(self) -> Result<(ConfigV1_1_30, GatewayEndpointConfig)> { + pub fn upgrade(self) -> Result<(ConfigV1_1_30, OldGatewayEndpointConfigV1_1_33)> { let gateway_details = self.core.base.client.gateway_endpoint.clone().into(); let config = ConfigV1_1_30 { core: self.core.into(), - storage_paths: NymConnectPaths { + storage_paths: NymConnectPathsV1_1_33 { common_paths: self.storage_paths.common_paths.upgrade_default()?, }, // logging: self.logging, diff --git a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_30.rs b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_30.rs index a18ae5831c..3d64011c8c 100644 --- a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_30.rs +++ b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_30.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::persistence::NymConnectPaths; -use crate::config::{default_config_filepath, Config}; +use crate::config::default_config_filepath; +use crate::config::old_config_v1_1_33::{ConfigV1_1_33, NymConnectPathsV1_1_33}; use nym_config::read_config_from_toml_file; use nym_socks5_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as CoreConfigV1_1_30; use serde::{Deserialize, Serialize}; @@ -14,15 +14,12 @@ use std::path::Path; pub struct ConfigV1_1_30 { pub core: CoreConfigV1_1_30, - // I'm leaving a landmine here for when the paths actually do change the next time, - // but propagating the change right now (in ALL clients) would be such a hassle..., - // so sorry for the next person looking at it : ) - pub storage_paths: NymConnectPaths, + pub storage_paths: NymConnectPathsV1_1_33, } -impl From<ConfigV1_1_30> for Config { +impl From<ConfigV1_1_30> for ConfigV1_1_33 { fn from(value: ConfigV1_1_30) -> Self { - Config { + ConfigV1_1_33 { core: value.core.into(), storage_paths: value.storage_paths, } diff --git a/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_33.rs b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_33.rs new file mode 100644 index 0000000000..15de9d1750 --- /dev/null +++ b/nym-connect/desktop/src-tauri/src/config/old_config_v1_1_33.rs @@ -0,0 +1,47 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::persistence::NymConnectPaths; +use crate::config::{default_config_filepath, Config}; +use crate::error::BackendError; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_socks5_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as CoreConfigV1_1_33; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::Path; + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +pub struct NymConnectPathsV1_1_33 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, +} + +#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1_1_33 { + pub core: CoreConfigV1_1_33, + + // \/ CHANGED + pub storage_paths: NymConnectPathsV1_1_33, + // /\ CHANGED +} + +impl ConfigV1_1_33 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result<Config, BackendError> { + Ok(Config { + core: self.core.into(), + storage_paths: NymConnectPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + }, + }) + } +} diff --git a/nym-connect/desktop/src-tauri/src/config/upgrade.rs b/nym-connect/desktop/src-tauri/src/config/upgrade.rs index 2c7118196e..8df77ab7b6 100644 --- a/nym-connect/desktop/src-tauri/src/config/upgrade.rs +++ b/nym-connect/desktop/src-tauri/src/config/upgrade.rs @@ -2,47 +2,18 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::old_config_v1_1_30::ConfigV1_1_30; -use crate::config::persistence::NymConnectPaths; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; use crate::{ config::{ old_config_v1_1_13::OldConfigV1_1_13, old_config_v1_1_20::ConfigV1_1_20, - old_config_v1_1_20_2::ConfigV1_1_20_2, Config, + old_config_v1_1_20_2::ConfigV1_1_20_2, }, - error::{BackendError, Result}, + error::Result, }; use log::{debug, info}; -use nym_client_core::{ - client::{ - base_client::storage::gateway_details::{OnDiskGatewayDetails, PersistedGatewayDetails}, - key_manager::persistence::OnDiskKeys, - }, - config::GatewayEndpointConfig, - error::ClientCoreError, -}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; -fn persist_gateway_details( - storage_paths: &NymConnectPaths, - details: GatewayEndpointConfig, -) -> Result<()> { - let details_store = OnDiskGatewayDetails::new(&storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - BackendError::ClientCoreError { - source: ClientCoreError::KeyStoreError { - source: Box::new(source), - }, - } - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| BackendError::ClientCoreError { - source: ClientCoreError::GatewaysDetailsStoreError { - source: Box::new(source), - }, - }) -} -fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool> { +async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) @@ -57,14 +28,23 @@ fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool> { let updated_step1: ConfigV1_1_20 = old_config.into(); let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; - persist_gateway_details(&updated_step3.storage_paths, gateway_config)?; + let old_paths = updated_step3.storage_paths.clone(); + + let updated_step4: ConfigV1_1_33 = updated_step3.into(); + let updated = updated_step4.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; - let updated: Config = updated_step3.into(); updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool> { +async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) @@ -78,14 +58,23 @@ fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool> { let updated_step1: ConfigV1_1_20_2 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; - persist_gateway_details(&updated_step2.storage_paths, gateway_config)?; + let old_paths = updated_step2.storage_paths.clone(); + + let updated_step3: ConfigV1_1_33 = updated_step2.into(); + let updated = updated_step3.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; - let updated: Config = updated_step2.into(); updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool> { +async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool> { // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -96,14 +85,23 @@ fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool> { info!("It is going to get updated to the current specification."); let (updated_step1, gateway_config) = old_config.upgrade()?; - persist_gateway_details(&updated_step1.storage_paths, gateway_config)?; + let old_paths = updated_step1.storage_paths.clone(); + + let updated_step2: ConfigV1_1_33 = updated_step1.into(); + let updated = updated_step2.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; - let updated: Config = updated_step1.into(); updated.save_to_default_location()?; Ok(true) } -fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool> { +async fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool> { // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) let Ok(old_config) = ConfigV1_1_30::read_from_default_path(id) else { // if we failed to load it, there might have been nothing to upgrade @@ -113,23 +111,62 @@ fn try_upgrade_v1_1_30_config(id: &str) -> Result<bool> { info!("It seems the client is using <= v1.1.30 config template."); info!("It is going to get updated to the current specification."); - let updated: Config = old_config.into(); + let old_paths = old_config.storage_paths.clone(); + + let updated_step1: ConfigV1_1_33 = old_config.into(); + let updated = updated_step1.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + updated.save_to_default_location()?; Ok(true) } -pub fn try_upgrade_config(id: &str) -> Result<()> { +async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool> { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +pub async fn try_upgrade_config(id: &str) -> Result<()> { debug!("Attempting to upgrade config file for \"{id}\""); - if try_upgrade_v1_1_13_config(id)? { + if try_upgrade_v1_1_13_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(id)? { + if try_upgrade_v1_1_20_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(id)? { + if try_upgrade_v1_1_20_2_config(id).await? { return Ok(()); } - if try_upgrade_v1_1_30_config(id)? { + if try_upgrade_v1_1_30_config(id).await? { + return Ok(()); + } + if try_upgrade_v1_1_33_config(id).await? { return Ok(()); } diff --git a/nym-connect/desktop/src-tauri/src/operations/export.rs b/nym-connect/desktop/src-tauri/src/operations/export.rs index a8c53e9d37..bf047ee84e 100644 --- a/nym-connect/desktop/src-tauri/src/operations/export.rs +++ b/nym-connect/desktop/src-tauri/src/operations/export.rs @@ -54,7 +54,6 @@ pub async fn export_keys(state: tauri::State<'_, Arc<RwLock<State>>>) -> Result< // Get key paths let ack_key_file = key_paths.ack_key(); - let gateway_shared_key_file = key_paths.gateway_shared_key(); let pub_id_key_file = key_paths.public_identity_key(); let priv_id_key_file = key_paths.private_identity_key(); @@ -64,7 +63,6 @@ pub async fn export_keys(state: tauri::State<'_, Arc<RwLock<State>>>) -> Result< // Read file contents let ack_key = fs::read_to_string(ack_key_file)?; - let gateway_shared_key = fs::read_to_string(gateway_shared_key_file)?; let pub_id_key = fs::read_to_string(pub_id_key_file)?; let priv_id_key = fs::read_to_string(priv_id_key_file)?; @@ -73,7 +71,6 @@ pub async fn export_keys(state: tauri::State<'_, Arc<RwLock<State>>>) -> Result< let priv_enc_key = fs::read_to_string(priv_enc_key_file)?; let ack_key_file = key_filename(&key_paths.ack_key_file)?; - let gateway_shared_key_file = key_filename(&key_paths.gateway_shared_key_file)?; let pub_id_key_file = key_filename(&key_paths.public_identity_key_file)?; let priv_id_key_file = key_filename(&key_paths.private_identity_key_file)?; let pub_enc_key_file = key_filename(&key_paths.public_encryption_key_file)?; @@ -82,7 +79,6 @@ pub async fn export_keys(state: tauri::State<'_, Arc<RwLock<State>>>) -> Result< // Format and return as json let json = serde_json::json!({ ack_key_file: ack_key, - gateway_shared_key_file: gateway_shared_key, pub_id_key_file: pub_id_key, priv_id_key_file: priv_id_key, pub_enc_key_file: pub_enc_key, diff --git a/nym-connect/desktop/src-tauri/src/state.rs b/nym-connect/desktop/src-tauri/src/state.rs index 20471e6171..83350b98fe 100644 --- a/nym-connect/desktop/src-tauri/src/state.rs +++ b/nym-connect/desktop/src-tauri/src/state.rs @@ -257,13 +257,7 @@ impl State { let (control_tx, msg_rx, exit_status_rx, used_gateway) = tasks::start_nym_socks5_client(&id, &privacy_level).await?; self.socks5_client_sender = Some(control_tx); - self.gateway = Some( - used_gateway - .try_get_configured_endpoint() - .unwrap() - .gateway_id - .clone(), - ); + self.gateway = Some(used_gateway.gateway_id().to_base58_string()); Ok((msg_rx, exit_status_rx)) } diff --git a/nym-connect/desktop/src-tauri/src/tasks.rs b/nym-connect/desktop/src-tauri/src/tasks.rs index d4264f2274..6431979fa2 100644 --- a/nym-connect/desktop/src-tauri/src/tasks.rs +++ b/nym-connect/desktop/src-tauri/src/tasks.rs @@ -1,9 +1,7 @@ use futures::{channel::mpsc, StreamExt}; -use nym_client_core::init::types::GatewayDetails; +use nym_client_core::client::base_client::storage::{GatewayDetails, GatewaysDetailsStore}; use nym_client_core::{ - client::base_client::storage::{ - gateway_details::GatewayDetailsStore, MixnetClientStorage, OnDiskPersistent, - }, + client::base_client::storage::{MixnetClientStorage, OnDiskPersistent}, config::{GroupBy, TopologyStructure}, error::ClientCoreStatusMessage, }; @@ -90,10 +88,12 @@ pub async fn start_nym_socks5_client( let used_gateway = storage .gateway_details_store() - .load_gateway_details() + .active_gateway() .await - .expect("failed to load gateway details") - .into(); + .expect("failed to load active gateway details") + .registration + .expect("no active gateway set") + .details; log::info!("Starting socks5 client"); diff --git a/sdk/lib/socks5-listener/src/lib.rs b/sdk/lib/socks5-listener/src/lib.rs index 0c9e2f7771..a4059a14d8 100644 --- a/sdk/lib/socks5-listener/src/lib.rs +++ b/sdk/lib/socks5-listener/src/lib.rs @@ -277,6 +277,7 @@ where }, available_gateways: current_gateways(&mut rng, &nym_apis).await?, overwrite_data: false, + wg_tun_address: None, }); eprintln!("starting the socks5 client"); diff --git a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs index 8b1cce1fc1..529a69688f 100644 --- a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs +++ b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs @@ -1,3 +1,6 @@ +use nym_client_core::client::base_client::storage::{ + ActiveGateway, BadGateway, GatewayRegistration, GatewaysDetailsStore, +}; use nym_sdk::mixnet::{ self, ClientKeys, EmptyReplyStorage, EphemeralCredentialStorage, KeyStore, MixnetClientStorage, MixnetMessageSender, @@ -106,23 +109,56 @@ impl KeyStore for MockKeyStore { struct MockGatewayDetailsStore; #[async_trait] -impl GatewayDetailsStore for MockGatewayDetailsStore { +impl GatewaysDetailsStore for MockGatewayDetailsStore { type StorageError = MyError; - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> { - println!("loading stored gateway details"); + async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError> { + println!("getting active gateway"); + + Err(MyError) + } + + async fn set_active_gateway(&self, _gateway_id: &str) -> Result<(), Self::StorageError> { + println!("setting active gateway"); + + Ok(()) + } + + async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { + println!("getting all registered gateways"); + + Err(MyError) + } + + async fn has_gateway_details(&self, _gateway_id: &str) -> Result<bool, Self::StorageError> { + println!("checking for gateway details"); + + Err(MyError) + } + + async fn load_gateway_details( + &self, + _gateway_id: &str, + ) -> Result<GatewayRegistration, Self::StorageError> { + println!("loading gateway details"); Err(MyError) } async fn store_gateway_details( &self, - _details: &PersistedGatewayDetails, + _details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { println!("storing gateway details"); Ok(()) } + + async fn remove_gateway_details(&self, _gateway_id: &str) -> Result<(), Self::StorageError> { + println!("removing gateway details"); + + Ok(()) + } } // @@ -178,3 +214,9 @@ impl GatewayDetailsStore for MockGatewayDetailsStore { #[derive(thiserror::Error, Debug)] #[error("foobar")] struct MyError; + +impl From<BadGateway> for MyError { + fn from(_: BadGateway) -> Self { + MyError + } +} From 67c5a3689496d52e362da46632a9c7e120ed932e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 11 Mar 2024 11:12:56 +0000 Subject: [PATCH 307/394] building wasm-client-core --- Cargo.lock | 1 + .../client-core/gateways-storage/src/lib.rs | 5 +- .../src/client/base_client/storage/mod.rs | 7 +- common/wasm/client-core/src/error.rs | 12 +- common/wasm/client-core/src/helpers.rs | 12 +- .../src/storage/core_client_traits.rs | 55 ++++-- common/wasm/client-core/src/storage/mod.rs | 19 +- common/wasm/client-core/src/storage/types.rs | 62 +++++++ .../src/storage/wasm_client_traits.rs | 168 +++++++++++------- common/wasm/client-core/src/topology.rs | 5 - 10 files changed, 250 insertions(+), 96 deletions(-) create mode 100644 common/wasm/client-core/src/storage/types.rs diff --git a/Cargo.lock b/Cargo.lock index d136c0c614..966999d607 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10878,6 +10878,7 @@ dependencies = [ "serde", "serde-wasm-bindgen", "thiserror", + "time", "tsify", "url", "wasm-bindgen", diff --git a/common/client-core/gateways-storage/src/lib.rs b/common/client-core/gateways-storage/src/lib.rs index 42c10b9df9..2d4f18422f 100644 --- a/common/client-core/gateways-storage/src/lib.rs +++ b/common/client-core/gateways-storage/src/lib.rs @@ -12,10 +12,7 @@ pub mod error; pub mod types; // todo: export port types -pub use crate::types::{ - ActiveGateway, CustomGatewayDetails, GatewayDetails, GatewayRegistration, GatewayType, - RegisteredGateway, RemoteGatewayDetails, -}; +pub use crate::types::*; pub use backend::mem_backend::{InMemGatewaysDetails, InMemStorageError}; pub use error::BadGateway; diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index e1b02fc347..2680707e35 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -26,11 +26,8 @@ use crate::{ #[cfg(all(not(target_arch = "wasm32"), feature = "fs-surb-storage"))] use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; -pub use nym_client_core_gateways_storage::{ - ActiveGateway, BadGateway, CustomGatewayDetails, GatewayDetails, GatewayRegistration, - GatewayType, GatewaysDetailsStore, InMemGatewaysDetails, RegisteredGateway, - RemoteGatewayDetails, -}; +pub use nym_client_core_gateways_storage as gateways_storage; +use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; diff --git a/common/wasm/client-core/src/error.rs b/common/wasm/client-core/src/error.rs index 01cbbcd757..f80327265a 100644 --- a/common/wasm/client-core/src/error.rs +++ b/common/wasm/client-core/src/error.rs @@ -4,7 +4,7 @@ use crate::storage::wasm_client_traits::WasmClientStorageError; use crate::topology::WasmTopologyError; use js_sys::Promise; -use nym_client_core::config::GatewayEndpointConfig; +use nym_client_core::client::base_client::storage::gateways_storage::BadGateway; use nym_client_core::error::ClientCoreError; use nym_crypto::asymmetric::identity::Ed25519RecoveryError; use nym_gateway_client::error::GatewayClientError; @@ -89,10 +89,14 @@ pub enum WasmCoreError { source: WasmClientStorageError, }, - #[error("this client has already registered with a gateway: {gateway_config:?}")] - AlreadyRegistered { - gateway_config: GatewayEndpointConfig, + #[error(transparent)] + MalformedGateway { + #[from] + source: BadGateway, }, + + #[error("this client has already registered with a gateway: {gateway_id:?}")] + AlreadyRegistered { gateway_id: String }, } wasm_error!(WasmCoreError); diff --git a/common/wasm/client-core/src/helpers.rs b/common/wasm/client-core/src/helpers.rs index 6b59d30d80..a64341907c 100644 --- a/common/wasm/client-core/src/helpers.rs +++ b/common/wasm/client-core/src/helpers.rs @@ -90,8 +90,15 @@ pub async fn setup_gateway_wasm( chosen_gateway: Option<IdentityKey>, gateways: &[gateway::Node], ) -> Result<InitialisationResult, WasmCoreError> { - let setup = if client_store.has_full_gateway_info().await? { - GatewaySetup::MustLoad + // TODO: so much optimization and extra features could be added here, but that's for the future + + let setup = if client_store + .get_active_gateway_id() + .await? + .active_gateway_id_bs58 + .is_some() + { + GatewaySetup::MustLoad { gateway_id: None } } else { let selection_spec = GatewaySelectionSpecification::new(chosen_gateway.clone(), None, force_tls); @@ -100,6 +107,7 @@ pub async fn setup_gateway_wasm( specification: selection_spec, available_gateways: gateways.to_vec(), overwrite_data: false, + wg_tun_address: None, } }; diff --git a/common/wasm/client-core/src/storage/core_client_traits.rs b/common/wasm/client-core/src/storage/core_client_traits.rs index dde0b89f08..20105ac339 100644 --- a/common/wasm/client-core/src/storage/core_client_traits.rs +++ b/common/wasm/client-core/src/storage/core_client_traits.rs @@ -7,7 +7,10 @@ use crate::helpers::setup_reply_surb_storage_backend; use crate::storage::wasm_client_traits::WasmClientStorage; use crate::storage::ClientStorage; use async_trait::async_trait; -use nym_client_core::client::base_client::storage::MixnetClientStorage; +use nym_client_core::client::base_client::storage::{ + gateways_storage::{ActiveGateway, GatewayRegistration, GatewaysDetailsStore}, + MixnetClientStorage, +}; use nym_client_core::client::key_manager::persistence::KeyStore; use nym_client_core::client::key_manager::ClientKeys; use nym_client_core::client::replies::reply_storage::browser_backend; @@ -72,12 +75,10 @@ impl KeyStore for ClientStorage { let identity_keypair = self.must_read_identity_keypair().await?; let encryption_keypair = self.must_read_encryption_keypair().await?; let ack_keypair = self.must_read_ack_key().await?; - let gateway_shared_key = self.must_read_gateway_shared_key().await?; Ok(ClientKeys::from_keys( identity_keypair, encryption_keypair, - Some(gateway_shared_key), ack_keypair, )) } @@ -91,25 +92,57 @@ impl KeyStore for ClientStorage { .await?; self.store_ack_key(&keys.ack_key()).await?; - if let Some(shared_keys) = keys.gateway_shared_key() { - self.store_gateway_shared_key(&shared_keys).await?; - } Ok(()) } } #[async_trait(?Send)] -impl GatewayDetailsStore for ClientStorage { +impl GatewaysDetailsStore for ClientStorage { type StorageError = WasmCoreError; - async fn load_gateway_details(&self) -> Result<PersistedGatewayDetails, Self::StorageError> { - self.must_read_gateway_details().await + async fn active_gateway(&self) -> Result<ActiveGateway, Self::StorageError> { + let raw_active = self.get_active_gateway_id().await?; + let registration = match raw_active.active_gateway_id_bs58 { + None => None, + Some(gateway_id) => Some(self.load_gateway_details(&gateway_id).await?), + }; + + Ok(ActiveGateway { registration }) + } + + async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + <Self as WasmClientStorage>::set_active_gateway(self, Some(gateway_id)).await?; + Ok(()) + } + + async fn all_gateways(&self) -> Result<Vec<GatewayRegistration>, Self::StorageError> { + todo!() + // let identities = self.all + } + + async fn has_gateway_details(&self, gateway_id: &str) -> Result<bool, Self::StorageError> { + self.has_registered_gateway(gateway_id).await + } + + async fn load_gateway_details( + &self, + gateway_id: &str, + ) -> Result<GatewayRegistration, Self::StorageError> { + Ok(self + .must_get_registered_gateway(gateway_id) + .await? + .try_into()?) } async fn store_gateway_details( &self, - details: &PersistedGatewayDetails, + details: &GatewayRegistration, ) -> Result<(), Self::StorageError> { - <Self as WasmClientStorage>::store_gateway_details(self, details).await + let raw_registration = details.into(); + self.store_registered_gateway(&raw_registration).await + } + + async fn remove_gateway_details(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + self.remove_registered_gateway(gateway_id).await } } diff --git a/common/wasm/client-core/src/storage/mod.rs b/common/wasm/client-core/src/storage/mod.rs index c94e8fc599..c210dc1dcc 100644 --- a/common/wasm/client-core/src/storage/mod.rs +++ b/common/wasm/client-core/src/storage/mod.rs @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use crate::error::WasmCoreError; -use crate::storage::wasm_client_traits::{v1, WasmClientStorage}; +use crate::storage::wasm_client_traits::{v1, v2, WasmClientStorage}; use async_trait::async_trait; use js_sys::{Array, Promise}; use serde::de::DeserializeOwned; @@ -11,14 +11,15 @@ use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; use wasm_storage::traits::BaseWasmStorage; use wasm_storage::{IdbVersionChangeEvent, WasmStorage}; -use wasm_utils::error::PromisableResult; +use wasm_utils::error::{simple_js_error, PromisableResult}; use zeroize::Zeroizing; pub mod core_client_traits; +mod types; pub mod wasm_client_traits; const STORAGE_NAME_PREFIX: &str = "wasm-client-storage"; -const STORAGE_VERSION: u32 = 1; +const STORAGE_VERSION: u32 = 2; #[wasm_bindgen] pub struct ClientStorage { @@ -48,13 +49,21 @@ impl ClientStorage { // works with an unsigned integer. // See <https://github.com/rustwasm/wasm-bindgen/issues/1149> let old_version = evt.old_version() as u32; + let db = evt.db(); if old_version < 1 { - // migrating to version 1 - let db = evt.db(); + // migrating to version 2 db.create_object_store(v1::KEYS_STORE)?; db.create_object_store(v1::CORE_STORE)?; + + db.create_object_store(v2::GATEWAY_REGISTRATIONS_ACTIVE_GATEWAY_STORE)?; + db.create_object_store(v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE)?; + } + + // version 1 -> unimplemented migration + if old_version < 2 { + return Err(simple_js_error("this client is incompatible with existing storage. please initialise it again.")); } Ok(()) diff --git a/common/wasm/client-core/src/storage/types.rs b/common/wasm/client-core/src/storage/types.rs new file mode 100644 index 0000000000..5b40629778 --- /dev/null +++ b/common/wasm/client-core/src/storage/types.rs @@ -0,0 +1,62 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_client_core::client::base_client::storage::gateways_storage::{ + BadGateway, GatewayDetails, GatewayRegistration, RawRemoteGatewayDetails, RemoteGatewayDetails, +}; +use serde::{Deserialize, Serialize}; +use time::OffsetDateTime; + +// a more nested struct since we only have a single gateway type in wasm (no 'custom') +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct WasmRawRegisteredGateway { + pub gateway_id_bs58: String, + + pub registration_timestamp: OffsetDateTime, + + pub derived_aes128_ctr_blake3_hmac_keys_bs58: String, + + pub gateway_owner_address: String, + + pub gateway_listener: String, +} + +impl TryFrom<WasmRawRegisteredGateway> for GatewayRegistration { + type Error = BadGateway; + + fn try_from(value: WasmRawRegisteredGateway) -> Result<Self, Self::Error> { + // offload some parsing to an existing impl + let raw_remote = RawRemoteGatewayDetails { + gateway_id_bs58: value.gateway_id_bs58, + derived_aes128_ctr_blake3_hmac_keys_bs58: value + .derived_aes128_ctr_blake3_hmac_keys_bs58, + gateway_owner_address: value.gateway_owner_address, + gateway_listener: value.gateway_listener, + wg_tun_address: None, + }; + let remote: RemoteGatewayDetails = raw_remote.try_into()?; + + Ok(GatewayRegistration { + details: GatewayDetails::Remote(remote), + registration_timestamp: value.registration_timestamp, + }) + } +} + +impl <'a> From<&'a GatewayRegistration> for WasmRawRegisteredGateway { + fn from(value: &'a GatewayRegistration) -> Self { + let GatewayDetails::Remote(remote_details) = &value.details else { + panic!("somehow obtained custom gateway registration in wasm!") + }; + + WasmRawRegisteredGateway { + gateway_id_bs58: remote_details.gateway_id.to_string(), + registration_timestamp: value.registration_timestamp, + derived_aes128_ctr_blake3_hmac_keys_bs58: remote_details + .derived_aes128_ctr_blake3_hmac_keys + .to_base58_string(), + gateway_owner_address: remote_details.gateway_owner_address.to_string(), + gateway_listener: remote_details.gateway_listener.to_string(), + } + } +} diff --git a/common/wasm/client-core/src/storage/wasm_client_traits.rs b/common/wasm/client-core/src/storage/wasm_client_traits.rs index 83e0ca1340..b8ad2c8065 100644 --- a/common/wasm/client-core/src/storage/wasm_client_traits.rs +++ b/common/wasm/client-core/src/storage/wasm_client_traits.rs @@ -1,10 +1,10 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::storage::types::WasmRawRegisteredGateway; use async_trait::async_trait; -use nym_client_core::client::base_client::storage::gateway_details::PersistedGatewayDetails; +use nym_client_core::client::base_client::storage::gateways_storage::RawActiveGateway; use nym_crypto::asymmetric::{encryption, identity}; -use nym_gateway_client::SharedKeys; use nym_sphinx_acknowledgements::AckKey; use std::error::Error; use thiserror::Error; @@ -19,14 +19,22 @@ pub(crate) mod v1 { // keys // pub const CONFIG: &str = "config"; - pub const GATEWAY_DETAILS: &str = "gateway_details"; + // pub const GATEWAY_DETAILS: &str = "gateway_details"; pub const ED25519_IDENTITY_KEYPAIR: &str = "ed25519_identity_keypair"; pub const X25519_ENCRYPTION_KEYPAIR: &str = "x25519_encryption_keypair"; // TODO: for those we could actually use the subtle crypto storage pub const AES128CTR_ACK_KEY: &str = "aes128ctr_ack_key"; - pub const AES128CTR_BLAKE3_HMAC_GATEWAY_KEYS: &str = "aes128ctr_blake3_hmac_gateway_keys"; + // pub const AES128CTR_BLAKE3_HMAC_GATEWAY_KEYS: &str = "aes128ctr_blake3_hmac_gateway_keys"; +} + +pub(crate) mod v2 { + pub const GATEWAY_REGISTRATIONS_ACTIVE_GATEWAY_STORE: &str = "active_gateway"; + pub const ACTIVE_GATEWAY_KEY: &str = "active_gateway"; + + // there's no concept of 'custom' gateways in wasm so the store is simpler + pub const GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE: &str = "gateway_registrations"; } #[derive(Debug, Error)] @@ -34,32 +42,20 @@ pub enum WasmClientStorageError { #[error("{typ} cryptographic key is not available in storage")] CryptoKeyNotInStorage { typ: String }, - #[error("the prior gateway details are not available in the storage")] - GatewayDetailsNotInStorage, + #[error( + "the prior gateway details for gateway {gateway_id:?} are not available in the storage" + )] + GatewayDetailsNotInStorage { gateway_id: String }, } #[async_trait(?Send)] +#[async_trait] pub trait WasmClientStorage: BaseWasmStorage { type StorageError: Error + From<<Self as BaseWasmStorage>::StorageError> + From<WasmClientStorageError>; - async fn may_read_gateway_details( - &self, - ) -> Result<Option<PersistedGatewayDetails>, <Self as WasmClientStorage>::StorageError> { - self.read_value(v1::CORE_STORE, JsValue::from_str(v1::GATEWAY_DETAILS)) - .await - .map_err(Into::into) - } - - async fn must_read_gateway_details( - &self, - ) -> Result<PersistedGatewayDetails, <Self as WasmClientStorage>::StorageError> { - self.may_read_gateway_details() - .await? - .ok_or(WasmClientStorageError::GatewayDetailsNotInStorage) - .map_err(Into::into) - } + // keys: async fn may_read_identity_keypair( &self, @@ -91,17 +87,6 @@ pub trait WasmClientStorage: BaseWasmStorage { .map_err(Into::into) } - async fn may_read_gateway_shared_key( - &self, - ) -> Result<Option<SharedKeys>, <Self as WasmClientStorage>::StorageError> { - self.read_value( - v1::KEYS_STORE, - JsValue::from_str(v1::AES128CTR_BLAKE3_HMAC_GATEWAY_KEYS), - ) - .await - .map_err(Into::into) - } - async fn must_read_identity_keypair( &self, ) -> Result<identity::KeyPair, <Self as WasmClientStorage>::StorageError> { @@ -133,17 +118,6 @@ pub trait WasmClientStorage: BaseWasmStorage { .map_err(Into::into) } - async fn must_read_gateway_shared_key( - &self, - ) -> Result<SharedKeys, <Self as WasmClientStorage>::StorageError> { - self.may_read_gateway_shared_key() - .await? - .ok_or(WasmClientStorageError::CryptoKeyNotInStorage { - typ: v1::AES128CTR_BLAKE3_HMAC_GATEWAY_KEYS.to_string(), - }) - .map_err(Into::into) - } - async fn store_identity_keypair( &self, keypair: &identity::KeyPair, @@ -183,38 +157,112 @@ pub trait WasmClientStorage: BaseWasmStorage { .map_err(Into::into) } - async fn store_gateway_shared_key( + // gateways: + + async fn get_active_gateway_id( &self, - key: &SharedKeys, + ) -> Result<RawActiveGateway, <Self as WasmClientStorage>::StorageError> { + let maybe_active: Option<RawActiveGateway> = self + .read_value( + v2::GATEWAY_REGISTRATIONS_ACTIVE_GATEWAY_STORE, + JsValue::from_str(v2::ACTIVE_GATEWAY_KEY), + ) + .await?; + + // a 'temporary' hack + // (proper solution: make sure to insert empty value during db creation) + Ok(RawActiveGateway { + active_gateway_id_bs58: maybe_active.map(|a| a.active_gateway_id_bs58).flatten(), + }) + } + + async fn set_active_gateway( + &self, + gateway_id: Option<&str>, ) -> Result<(), <Self as WasmClientStorage>::StorageError> { self.store_value( - v1::KEYS_STORE, - JsValue::from_str(v1::AES128CTR_BLAKE3_HMAC_GATEWAY_KEYS), - key, + v2::GATEWAY_REGISTRATIONS_ACTIVE_GATEWAY_STORE, + JsValue::from_str(v2::ACTIVE_GATEWAY_KEY), + &RawActiveGateway { + active_gateway_id_bs58: gateway_id.map(|id| id.to_string()), + }, ) .await .map_err(Into::into) } - async fn store_gateway_details( + async fn maybe_get_registered_gateway( &self, - gateway_endpoint: &PersistedGatewayDetails, - ) -> Result<(), <Self as WasmClientStorage>::StorageError> { - self.store_value( - v1::CORE_STORE, - JsValue::from_str(v1::GATEWAY_DETAILS), - gateway_endpoint, + gateway_id: &str, + ) -> Result<Option<WasmRawRegisteredGateway>, <Self as WasmClientStorage>::StorageError> { + self.read_value( + v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE, + JsValue::from_str(gateway_id), ) .await .map_err(Into::into) } - async fn has_full_gateway_info( + async fn must_get_registered_gateway( &self, + gateway_id: &str, + ) -> Result<WasmRawRegisteredGateway, <Self as WasmClientStorage>::StorageError> { + self.maybe_get_registered_gateway(gateway_id) + .await? + .ok_or(WasmClientStorageError::GatewayDetailsNotInStorage { + gateway_id: gateway_id.to_string(), + }) + .map_err(Into::into) + } + + async fn store_registered_gateway( + &self, + registered_gateway: &WasmRawRegisteredGateway, + ) -> Result<(), <Self as WasmClientStorage>::StorageError> { + self.store_value( + v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE, + JsValue::from_str(®istered_gateway.gateway_id_bs58), + registered_gateway, + ) + .await + .map_err(Into::into) + } + + async fn remove_registered_gateway( + &self, + gateway_id: &str, + ) -> Result<(), <Self as WasmClientStorage>::StorageError> { + self.remove_value( + v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE, + JsValue::from_str(gateway_id), + ) + .await + .map_err(Into::into) + } + + async fn has_registered_gateway( + &self, + gateway_id: &str, ) -> Result<bool, <Self as WasmClientStorage>::StorageError> { - let has_keys = self.may_read_gateway_shared_key().await?.is_some(); - let has_details = self.may_read_gateway_details().await?.is_some(); + self.has_value( + v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE, + JsValue::from_str(gateway_id), + ) + .await + .map_err(Into::into) + } - Ok(has_keys && has_details) + async fn registered_gateways( + &self, + ) -> Result<Vec<String>, <Self as WasmClientStorage>::StorageError> { + self.get_all_keys(v2::GATEWAY_REGISTRATIONS_REGISTERED_GATEWAYS_STORE) + .await + .map_err(Into::into) + .map(|arr| { + arr.to_vec() + .into_iter() + .filter_map(|key| key.as_string()) + .collect() + }) } } diff --git a/common/wasm/client-core/src/topology.rs b/common/wasm/client-core/src/topology.rs index 8c84dee4a1..25300c41a4 100644 --- a/common/wasm/client-core/src/topology.rs +++ b/common/wasm/client-core/src/topology.rs @@ -1,7 +1,6 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use nym_client_core::config::GatewayEndpointConfig; use nym_topology::SerializableTopologyError; use nym_validator_client::client::IdentityKeyRef; use wasm_utils::console_log; @@ -17,10 +16,6 @@ pub type WasmTopologyError = SerializableTopologyError; pub trait SerializableTopologyExt { fn print(&self); - fn ensure_contains(&self, gateway_config: &GatewayEndpointConfig) -> bool { - self.ensure_contains_gateway_id(&gateway_config.gateway_id) - } - fn ensure_contains_gateway_id(&self, gateway_id: IdentityKeyRef) -> bool; } From a4e5b2af93e0ec4382dae3c10a9dd9ba9b6463c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 11 Mar 2024 11:31:01 +0000 Subject: [PATCH 308/394] further wasm fixes --- Cargo.lock | 8 ++--- .../src/client/base_client/storage/mod.rs | 2 +- common/wasm/client-core/Cargo.toml | 1 + nym-browser-extension/storage/Cargo.toml | 2 +- .../desktop/src-tauri/src/config/mod.rs | 4 ++- nym-connect/desktop/src-tauri/src/tasks.rs | 4 ++- .../examples/manually_handle_storage.rs | 7 ++--- sdk/rust/nym-sdk/src/mixnet.rs | 7 ++++- .../codegen/contract-clients/package.json | 2 +- sdk/typescript/docs/package.json | 2 +- .../packages/mix-fetch-node/package.json | 2 +- .../packages/mix-fetch/package.json | 2 +- .../packages/node-tester/package.json | 2 +- .../packages/nodejs-client/package.json | 2 +- .../packages/sdk-react/package.json | 2 +- sdk/typescript/packages/sdk/package.json | 2 +- wasm/client/Cargo.toml | 2 +- wasm/mix-fetch/Cargo.toml | 2 +- wasm/node-tester/Cargo.toml | 2 +- wasm/node-tester/src/tester.rs | 29 +++++++++++-------- 20 files changed, 49 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 966999d607..23c3ccf211 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2549,7 +2549,7 @@ dependencies = [ [[package]] name = "extension-storage" -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" dependencies = [ "bip39", "console_error_panic_hook", @@ -4557,7 +4557,7 @@ dependencies = [ [[package]] name = "mix-fetch-wasm" -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" dependencies = [ "async-trait", "futures", @@ -5313,7 +5313,7 @@ dependencies = [ [[package]] name = "nym-client-wasm" -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" dependencies = [ "anyhow", "futures", @@ -6117,7 +6117,7 @@ dependencies = [ [[package]] name = "nym-node-tester-wasm" -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" dependencies = [ "futures", "js-sys", diff --git a/common/client-core/src/client/base_client/storage/mod.rs b/common/client-core/src/client/base_client/storage/mod.rs index 2680707e35..e7c15315a6 100644 --- a/common/client-core/src/client/base_client/storage/mod.rs +++ b/common/client-core/src/client/base_client/storage/mod.rs @@ -27,7 +27,7 @@ use crate::{ use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; pub use nym_client_core_gateways_storage as gateways_storage; -use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; +pub use nym_client_core_gateways_storage::{GatewaysDetailsStore, InMemGatewaysDetails}; #[cfg(all(not(target_arch = "wasm32"), feature = "fs-gateways-storage"))] pub use nym_client_core_gateways_storage::{OnDiskGatewaysDetails, StorageError}; diff --git a/common/wasm/client-core/Cargo.toml b/common/wasm/client-core/Cargo.toml index 3e8ec57163..5e6a701883 100644 --- a/common/wasm/client-core/Cargo.toml +++ b/common/wasm/client-core/Cargo.toml @@ -15,6 +15,7 @@ rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { workspace = true, features = ["derive"] } serde-wasm-bindgen = { workspace = true } thiserror = { workspace = true } +time = { workspace = true, features = ["wasm-bindgen"] } tsify = { workspace = true, features = ["js"] } url = { workspace = true } wasm-bindgen = { workspace = true } diff --git a/nym-browser-extension/storage/Cargo.toml b/nym-browser-extension/storage/Cargo.toml index 037386774c..68ed96e26b 100644 --- a/nym-browser-extension/storage/Cargo.toml +++ b/nym-browser-extension/storage/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "extension-storage" -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" edition = "2021" license = "Apache-2.0" repository = "https://github.com/nymtech/nym" diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 2a855b82ba..83c72dde79 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -6,7 +6,9 @@ use crate::config::template::CONFIG_TEMPLATE; use crate::config::upgrade::try_upgrade_config; use crate::error::{BackendError, Result}; use nym_client_core::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; -use nym_client_core::client::base_client::storage::{GatewayDetails, RemoteGatewayDetails}; +use nym_client_core::client::base_client::storage::gateways_storage::{ + GatewayDetails, RemoteGatewayDetails, +}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::error::ClientCoreError; use nym_client_core::init::generate_new_client_keys; diff --git a/nym-connect/desktop/src-tauri/src/tasks.rs b/nym-connect/desktop/src-tauri/src/tasks.rs index 6431979fa2..d2f2e1c3a7 100644 --- a/nym-connect/desktop/src-tauri/src/tasks.rs +++ b/nym-connect/desktop/src-tauri/src/tasks.rs @@ -1,5 +1,7 @@ use futures::{channel::mpsc, StreamExt}; -use nym_client_core::client::base_client::storage::{GatewayDetails, GatewaysDetailsStore}; +use nym_client_core::client::base_client::storage::gateways_storage::{ + GatewayDetails, GatewaysDetailsStore, +}; use nym_client_core::{ client::base_client::storage::{MixnetClientStorage, OnDiskPersistent}, config::{GroupBy, TopologyStructure}, diff --git a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs index 529a69688f..298502458c 100644 --- a/sdk/rust/nym-sdk/examples/manually_handle_storage.rs +++ b/sdk/rust/nym-sdk/examples/manually_handle_storage.rs @@ -1,9 +1,6 @@ -use nym_client_core::client::base_client::storage::{ - ActiveGateway, BadGateway, GatewayRegistration, GatewaysDetailsStore, -}; use nym_sdk::mixnet::{ - self, ClientKeys, EmptyReplyStorage, EphemeralCredentialStorage, KeyStore, MixnetClientStorage, - MixnetMessageSender, + self, ActiveGateway, BadGateway, ClientKeys, EmptyReplyStorage, EphemeralCredentialStorage, + GatewayRegistration, GatewaysDetailsStore, KeyStore, MixnetClientStorage, MixnetMessageSender, }; use nym_topology::provider_trait::async_trait; diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index 23c951119b..c89229fb28 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -44,7 +44,12 @@ pub use native_client::MixnetClient; pub use native_client::MixnetClientSender; pub use nym_client_core::{ client::{ - base_client::storage::{Ephemeral, MixnetClientStorage, OnDiskPersistent}, + base_client::storage::{ + gateways_storage::{ + ActiveGateway, BadGateway, GatewayRegistration, GatewaysDetailsStore, + }, + Ephemeral, MixnetClientStorage, OnDiskPersistent, + }, inbound_messages::InputMessage, key_manager::{ persistence::{InMemEphemeralKeys, KeyStore, OnDiskKeys}, diff --git a/sdk/typescript/codegen/contract-clients/package.json b/sdk/typescript/codegen/contract-clients/package.json index b4f91a948b..f429659cbb 100644 --- a/sdk/typescript/codegen/contract-clients/package.json +++ b/sdk/typescript/codegen/contract-clients/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/contract-clients", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "description": "A client for all Nym smart contracts", "license": "Apache-2.0", "author": "Nym Technologies SA", diff --git a/sdk/typescript/docs/package.json b/sdk/typescript/docs/package.json index 4d0bb71c80..abdf67048a 100644 --- a/sdk/typescript/docs/package.json +++ b/sdk/typescript/docs/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/ts-sdk-docs", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "description": "Nym Typescript SDK Docs", "license": "Apache-2.0", "author": "Nym Technologies SA", diff --git a/sdk/typescript/packages/mix-fetch-node/package.json b/sdk/typescript/packages/mix-fetch-node/package.json index 3367b87244..e1618cb318 100644 --- a/sdk/typescript/packages/mix-fetch-node/package.json +++ b/sdk/typescript/packages/mix-fetch-node/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/mix-fetch-node", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "description": "This package is a drop-in replacement for `fetch` in NodeJS to send HTTP requests over the Nym Mixnet.", "license": "Apache-2.0", "author": "Nym Technologies SA", diff --git a/sdk/typescript/packages/mix-fetch/package.json b/sdk/typescript/packages/mix-fetch/package.json index 381ea96372..9af4e116f2 100644 --- a/sdk/typescript/packages/mix-fetch/package.json +++ b/sdk/typescript/packages/mix-fetch/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/mix-fetch", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "description": "This package is a drop-in replacement for `fetch` to send HTTP requests over the Nym Mixnet.", "license": "Apache-2.0", "author": "Nym Technologies SA", diff --git a/sdk/typescript/packages/node-tester/package.json b/sdk/typescript/packages/node-tester/package.json index eb377423bd..de487b0729 100644 --- a/sdk/typescript/packages/node-tester/package.json +++ b/sdk/typescript/packages/node-tester/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/node-tester", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "description": "This package provides a tester that can send test packets to mixnode that is part of the Nym Mixnet.", "license": "Apache-2.0", "author": "Nym Technologies SA", diff --git a/sdk/typescript/packages/nodejs-client/package.json b/sdk/typescript/packages/nodejs-client/package.json index e8df393fc4..7cd003087c 100644 --- a/sdk/typescript/packages/nodejs-client/package.json +++ b/sdk/typescript/packages/nodejs-client/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/nodejs-client", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "license": "Apache-2.0", "author": "Nym Technologies SA", "files": [ diff --git a/sdk/typescript/packages/sdk-react/package.json b/sdk/typescript/packages/sdk-react/package.json index 6a163d7269..e67263157f 100644 --- a/sdk/typescript/packages/sdk-react/package.json +++ b/sdk/typescript/packages/sdk-react/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/sdk-react", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "license": "Apache-2.0", "author": "Nym Technologies SA", "files": [ diff --git a/sdk/typescript/packages/sdk/package.json b/sdk/typescript/packages/sdk/package.json index fabc99574a..0a416329f4 100644 --- a/sdk/typescript/packages/sdk/package.json +++ b/sdk/typescript/packages/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@nymproject/sdk", - "version": "1.2.4-rc.2", + "version": "1.3.0-rc.0", "license": "Apache-2.0", "author": "Nym Technologies SA", "files": [ diff --git a/wasm/client/Cargo.toml b/wasm/client/Cargo.toml index 6961325d61..2232c88877 100644 --- a/wasm/client/Cargo.toml +++ b/wasm/client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-client-wasm" authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jedrzej Stuczynski <andrew@nymtech.net>"] -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" edition = "2021" keywords = ["nym", "sphinx", "wasm", "webassembly", "privacy", "client"] license = "Apache-2.0" diff --git a/wasm/mix-fetch/Cargo.toml b/wasm/mix-fetch/Cargo.toml index 336cee63e3..373b6d423f 100644 --- a/wasm/mix-fetch/Cargo.toml +++ b/wasm/mix-fetch/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "mix-fetch-wasm" authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"] -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" edition = "2021" keywords = ["nym", "fetch", "wasm", "webassembly", "privacy"] license = "Apache-2.0" diff --git a/wasm/node-tester/Cargo.toml b/wasm/node-tester/Cargo.toml index 6a3d8126e7..fd295cd0e3 100644 --- a/wasm/node-tester/Cargo.toml +++ b/wasm/node-tester/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "nym-node-tester-wasm" authors = ["Jedrzej Stuczynski <andrew@nymtech.net>"] -version = "1.2.4-rc.2" +version = "1.3.0-rc.0" edition = "2021" keywords = ["nym", "sphinx", "webassembly", "privacy", "tester"] license = "Apache-2.0" diff --git a/wasm/node-tester/src/tester.rs b/wasm/node-tester/src/tester.rs index 1da2ee7a4f..790c80257d 100644 --- a/wasm/node-tester/src/tester.rs +++ b/wasm/node-tester/src/tester.rs @@ -20,16 +20,16 @@ use tokio::sync::Mutex as AsyncMutex; use tsify::Tsify; use wasm_bindgen::prelude::*; use wasm_bindgen_futures::future_to_promise; +use wasm_client_core::client::base_client::storage::gateways_storage::GatewayDetails; use wasm_client_core::client::mix_traffic::transceiver::PacketRouter; use wasm_client_core::helpers::{ current_network_topology_async, setup_from_topology, EphemeralCredentialStorage, }; -use wasm_client_core::init::types::GatewayDetails; use wasm_client_core::storage::ClientStorage; use wasm_client_core::topology::SerializableNymTopology; use wasm_client_core::{ - nym_task, BandwidthController, GatewayClient, GatewayConfig, IdentityKey, InitialisationResult, - ManagedKeys, NodeIdentity, NymTopology, QueryReqwestRpcNyxdClient, Recipient, + nym_task, BandwidthController, ClientKeys, GatewayClient, GatewayConfig, IdentityKey, + InitialisationResult, NodeIdentity, NymTopology, QueryReqwestRpcNyxdClient, Recipient, }; use wasm_utils::check_promise_result; use wasm_utils::error::PromisableResult; @@ -77,10 +77,10 @@ pub struct NymNodeTesterBuilder { Option<BandwidthController<QueryReqwestRpcNyxdClient, EphemeralCredentialStorage>>, } -fn address(keys: &ManagedKeys, gateway_identity: NodeIdentity) -> Recipient { +fn address(keys: &ClientKeys, gateway_identity: NodeIdentity) -> Recipient { Recipient::new( - *keys.identity_public_key(), - *keys.encryption_public_key(), + *keys.identity_keypair().public_key(), + *keys.encryption_keypair().public_key(), gateway_identity, ) } @@ -161,13 +161,14 @@ impl NymNodeTesterBuilder { let client_store = ClientStorage::new_async(&storage_id, None).await?; let initialisation_result = self.gateway_info(&client_store).await?; - let GatewayDetails::Configured(gateway_endpoint) = initialisation_result.gateway_details + let GatewayDetails::Remote(gateway_info) = + initialisation_result.gateway_registration.details else { // don't bother supporting it panic!("unsupported custom gateway configuration in wasm node tester") }; - let managed_keys = initialisation_result.managed_keys; + let managed_keys = initialisation_result.client_keys; let (mixnet_message_sender, mixnet_message_receiver) = mpsc::unbounded(); let (ack_sender, ack_receiver) = mpsc::unbounded(); @@ -179,8 +180,7 @@ impl NymNodeTesterBuilder { gateway_task.fork("packet_router"), ); - let gateway_config: GatewayConfig = gateway_endpoint.try_into()?; - let gateway_identity = gateway_config.gateway_identity; + let gateway_identity = gateway_info.gateway_id; let mut gateway_client = if let Some(existing_client) = initialisation_result.authenticated_ephemeral_client { @@ -190,10 +190,15 @@ impl NymNodeTesterBuilder { gateway_task, ) } else { + let cfg = GatewayConfig::new( + gateway_info.gateway_id, + Some(gateway_info.gateway_owner_address.to_string()), + gateway_info.gateway_listener.to_string(), + ); GatewayClient::new( - gateway_config, + cfg, managed_keys.identity_keypair(), - Some(managed_keys.must_get_gateway_shared_key()), + Some(gateway_info.derived_aes128_ctr_blake3_hmac_keys), packet_router, self.bandwidth_controller.take(), gateway_task, From e48af11e8fffe3b71d8f669002051306fa4217e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 11 Mar 2024 11:41:22 +0000 Subject: [PATCH 309/394] clippy et. al --- clients/native/src/client/config/persistence.rs | 2 -- common/wasm/client-core/src/storage/types.rs | 2 +- common/wasm/client-core/src/storage/wasm_client_traits.rs | 2 +- service-providers/network-requester/src/config/mod.rs | 2 +- 4 files changed, 3 insertions(+), 5 deletions(-) diff --git a/clients/native/src/client/config/persistence.rs b/clients/native/src/client/config/persistence.rs index bdd3cd6a65..a61913a2f7 100644 --- a/clients/native/src/client/config/persistence.rs +++ b/clients/native/src/client/config/persistence.rs @@ -5,8 +5,6 @@ use nym_client_core::config::disk_persistence::CommonClientPaths; use serde::{Deserialize, Serialize}; use std::path::Path; - - #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] pub struct ClientPaths { #[serde(flatten)] diff --git a/common/wasm/client-core/src/storage/types.rs b/common/wasm/client-core/src/storage/types.rs index 5b40629778..e0cc790739 100644 --- a/common/wasm/client-core/src/storage/types.rs +++ b/common/wasm/client-core/src/storage/types.rs @@ -43,7 +43,7 @@ impl TryFrom<WasmRawRegisteredGateway> for GatewayRegistration { } } -impl <'a> From<&'a GatewayRegistration> for WasmRawRegisteredGateway { +impl<'a> From<&'a GatewayRegistration> for WasmRawRegisteredGateway { fn from(value: &'a GatewayRegistration) -> Self { let GatewayDetails::Remote(remote_details) = &value.details else { panic!("somehow obtained custom gateway registration in wasm!") diff --git a/common/wasm/client-core/src/storage/wasm_client_traits.rs b/common/wasm/client-core/src/storage/wasm_client_traits.rs index b8ad2c8065..7c1b8e3e02 100644 --- a/common/wasm/client-core/src/storage/wasm_client_traits.rs +++ b/common/wasm/client-core/src/storage/wasm_client_traits.rs @@ -172,7 +172,7 @@ pub trait WasmClientStorage: BaseWasmStorage { // a 'temporary' hack // (proper solution: make sure to insert empty value during db creation) Ok(RawActiveGateway { - active_gateway_id_bs58: maybe_active.map(|a| a.active_gateway_id_bs58).flatten(), + active_gateway_id_bs58: maybe_active.and_then(|a| a.active_gateway_id_bs58), }) } diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index 72a51d6edc..1270d7d980 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -26,9 +26,9 @@ pub use nym_client_core::config::Config as BaseClientConfig; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; +pub mod old_config_v1_1_33; mod persistence; mod template; -pub mod old_config_v1_1_33; const DEFAULT_NETWORK_REQUESTERS_DIR: &str = "network-requester"; From 9b10871efb4877e036b5d7ed33ffdfb52ddb9a22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 11 Mar 2024 12:09:37 +0000 Subject: [PATCH 310/394] ipr config migration --- .../ip-packet-router/src/cli/init.rs | 4 +- .../ip-packet-router/src/cli/mod.rs | 71 +++++++------- .../ip-packet-router/src/cli/run.rs | 2 +- .../ip-packet-router/src/cli/sign.rs | 2 +- .../ip-packet-router/src/config/mod.rs | 1 + .../src/config/old_config_v1.rs | 95 +++++++++++++++++++ 6 files changed, 137 insertions(+), 38 deletions(-) create mode 100644 service-providers/ip-packet-router/src/config/old_config_v1.rs diff --git a/service-providers/ip-packet-router/src/cli/init.rs b/service-providers/ip-packet-router/src/cli/init.rs index 207a6a748c..9a5808b755 100644 --- a/service-providers/ip-packet-router/src/cli/init.rs +++ b/service-providers/ip-packet-router/src/cli/init.rs @@ -21,8 +21,8 @@ impl InitialisableClient for IpPacketRouterInit { type InitArgs = Init; type Config = Config; - fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id) + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index c2ef5b800e..1ed7ca2920 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -1,14 +1,12 @@ -use clap::{CommandFactory, Parser, Subcommand}; -use log::{error, trace}; -use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_bin_common::{bin_info, version_checker}; -use nym_client_core::client::key_manager::persistence::OnDiskKeys; -use nym_client_core::config::GatewayEndpointConfig; -use nym_client_core::error::ClientCoreError; -use std::sync::OnceLock; - use crate::config::{BaseClientConfig, Config}; use crate::error::IpPacketRouterError; +use clap::{CommandFactory, Parser, Subcommand}; +use log::{error, info, trace}; +use nym_bin_common::completions::{fig_generate, ArgShell}; +use nym_bin_common::{bin_info, version_checker}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; +use nym_ip_packet_router::config::old_config_v1::ConfigV1; +use std::sync::OnceLock; mod build_info; mod init; @@ -105,36 +103,41 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Ok(()) } -// Unused until we need to start implementing config upgrades -#[allow(unused)] -fn persist_gateway_details( - config: &Config, - details: GatewayEndpointConfig, -) -> Result<(), IpPacketRouterError> { - let details_store = - OnDiskGatewayDetails::new(&config.storage_paths.common_paths.gateway_details); - let keys_store = OnDiskKeys::new(config.storage_paths.common_paths.keys.clone()); - let shared_keys = keys_store.ephemeral_load_gateway_keys().map_err(|source| { - IpPacketRouterError::ClientCoreError(ClientCoreError::KeyStoreError { - source: Box::new(source), - }) - })?; - let persisted_details = PersistedGatewayDetails::new(details.into(), Some(&shared_keys))?; - details_store - .store_to_disk(&persisted_details) - .map_err(|source| { - IpPacketRouterError::ClientCoreError(ClientCoreError::GatewaysDetailsStoreError { - source: Box::new(source), - }) - }) +async fn try_upgrade_v1_config(id: &str) -> Result<bool, IpPacketRouterError> { + // explicitly load it as v1 (which is incompatible with the current one) + let Ok(old_config) = ConfigV1::read_from_default_path(id) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using v1 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) } -fn try_upgrade_config(_id: &str) -> Result<(), IpPacketRouterError> { +async fn try_upgrade_config(id: &str) -> Result<(), IpPacketRouterError> { trace!("Attempting to upgrade config"); + + if try_upgrade_v1_config(id).await? { + return Ok(()); + } + Ok(()) } -fn try_load_current_config(id: &str) -> Result<Config, IpPacketRouterError> { +async fn try_load_current_config(id: &str) -> Result<Config, IpPacketRouterError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { return if !cfg.validate() { @@ -145,7 +148,7 @@ fn try_load_current_config(id: &str) -> Result<Config, IpPacketRouterError> { } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id)?; + try_upgrade_config(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/service-providers/ip-packet-router/src/cli/run.rs b/service-providers/ip-packet-router/src/cli/run.rs index cbfb3f8453..6167de7666 100644 --- a/service-providers/ip-packet-router/src/cli/run.rs +++ b/service-providers/ip-packet-router/src/cli/run.rs @@ -25,7 +25,7 @@ impl From<Run> for OverrideConfig { } pub(crate) async fn execute(args: &Run) -> Result<(), IpPacketRouterError> { - let mut config = try_load_current_config(&args.common_args.id)?; + let mut config = try_load_current_config(&args.common_args.id).await?; config = override_config(config, OverrideConfig::from(args.clone())); log::debug!("Using config: {:#?}", config); diff --git a/service-providers/ip-packet-router/src/cli/sign.rs b/service-providers/ip-packet-router/src/cli/sign.rs index c282483de3..2b56007b47 100644 --- a/service-providers/ip-packet-router/src/cli/sign.rs +++ b/service-providers/ip-packet-router/src/cli/sign.rs @@ -52,7 +52,7 @@ fn print_signed_contract_msg( } pub(crate) async fn execute(args: &Sign) -> Result<(), IpPacketRouterError> { - let config = try_load_current_config(&args.id)?; + let config = try_load_current_config(&args.id).await?; if !version_check(&config) { log::error!("Failed the local version check"); diff --git a/service-providers/ip-packet-router/src/config/mod.rs b/service-providers/ip-packet-router/src/config/mod.rs index 1ea0ee755b..1d36c97d16 100644 --- a/service-providers/ip-packet-router/src/config/mod.rs +++ b/service-providers/ip-packet-router/src/config/mod.rs @@ -22,6 +22,7 @@ use crate::config::persistence::IpPacketRouterPaths; use self::template::CONFIG_TEMPLATE; +pub mod old_config_v1; mod persistence; mod template; diff --git a/service-providers/ip-packet-router/src/config/old_config_v1.rs b/service-providers/ip-packet-router/src/config/old_config_v1.rs new file mode 100644 index 0000000000..34399af4cf --- /dev/null +++ b/service-providers/ip-packet-router/src/config/old_config_v1.rs @@ -0,0 +1,95 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::persistence::IpPacketRouterPaths; +use crate::config::Config; +use crate::config::{default_config_filepath, IpPacketRouter}; +use crate::error::IpPacketRouterError; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33; +use nym_config::read_config_from_toml_file; +use nym_config::serde_helpers::de_maybe_stringified; +use nym_network_defaults::mainnet; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::{Path, PathBuf}; +use url::Url; + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct IpPacketRouterPathsV1 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, + + /// Location of the file containing our description + pub ip_packet_router_description: PathBuf, +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV1 { + #[serde(flatten)] + pub base: BaseConfigV1_1_33, + + #[serde(default)] + pub ip_packet_router: IpPacketRouterV1, + + pub storage_paths: IpPacketRouterPathsV1, + + pub logging: LoggingSettings, +} + +impl ConfigV1 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } + + pub fn try_upgrade(self) -> Result<Config, IpPacketRouterError> { + Ok(Config { + base: self.base.into(), + ip_packet_router: self.ip_packet_router.into(), + storage_paths: IpPacketRouterPaths { + common_paths: self.storage_paths.common_paths.upgrade_default()?, + ip_packet_router_description: self.storage_paths.ip_packet_router_description, + }, + logging: self.logging, + }) + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct IpPacketRouterV1 { + /// Disable Poisson sending rate. + pub disable_poisson_rate: bool, + + /// Specifies the url for an upstream source of the exit policy used by this node. + #[serde(deserialize_with = "de_maybe_stringified")] + pub upstream_exit_policy_url: Option<Url>, +} + +impl Default for IpPacketRouterV1 { + fn default() -> Self { + IpPacketRouterV1 { + disable_poisson_rate: true, + upstream_exit_policy_url: Some( + mainnet::EXIT_POLICY_URL + .parse() + .expect("invalid default exit policy URL"), + ), + } + } +} + +impl From<IpPacketRouterV1> for IpPacketRouter { + fn from(value: IpPacketRouterV1) -> Self { + IpPacketRouter { + disable_poisson_rate: value.disable_poisson_rate, + upstream_exit_policy_url: value.upstream_exit_policy_url, + } + } +} From 0ac8098dad6d72cc463a793aa98e7395159237ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 11 Mar 2024 17:38:15 +0000 Subject: [PATCH 311/394] ability to reuse free passes from the storage for new gateways --- common/bandwidth-controller/src/lib.rs | 16 ++-- .../client-libs/gateway-client/src/client.rs | 6 +- ...0240311120000_credential_used_gateways.sql | 31 ++++++++ .../migrations/20240311120001_drop_erc20.sql | 7 ++ .../credential-storage/src/backends/memory.rs | 78 +++++++++++++++---- .../credential-storage/src/backends/sqlite.rs | 53 +++++++++++-- .../src/ephemeral_storage.rs | 20 ++++- common/credential-storage/src/models.rs | 7 +- .../src/persistent_storage.rs | 20 ++++- common/credential-storage/src/storage.rs | 8 +- 10 files changed, 206 insertions(+), 40 deletions(-) create mode 100644 common/credential-storage/migrations/20240311120000_credential_used_gateways.sql create mode 100644 common/credential-storage/migrations/20240311120001_drop_erc20.sql diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 31d499dac9..33f9428e44 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -49,6 +49,7 @@ impl<C, St: Storage> BandwidthController<C, St> { /// It marks any retrieved intermediate credentials as expired. pub async fn get_next_usable_credential( &self, + gateway_id: &str, ) -> Result<RetrievedCredential, BandwidthControllerError> where <St as Storage>::StorageError: Send + Sync + 'static, @@ -56,7 +57,7 @@ impl<C, St: Storage> BandwidthController<C, St> { loop { let Some(maybe_next) = self .storage - .get_next_unspent_credential() + .get_next_unspent_credential(gateway_id) .await .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err)))? else { @@ -114,12 +115,13 @@ impl<C, St: Storage> BandwidthController<C, St> { pub async fn prepare_bandwidth_credential( &self, + gateway_id: &str, ) -> Result<PreparedCredential, BandwidthControllerError> where C: DkgQueryClient + Sync + Send, <St as Storage>::StorageError: Send + Sync + 'static, { - let retrieved_credential = self.get_next_usable_credential().await?; + let retrieved_credential = self.get_next_usable_credential(gateway_id).await?; let epoch_id = retrieved_credential.credential.epoch_id(); let credential_id = retrieved_credential.credential_id; @@ -137,14 +139,16 @@ impl<C, St: Storage> BandwidthController<C, St> { }) } - pub async fn consume_credential(&self, id: i64) -> Result<(), BandwidthControllerError> + pub async fn consume_credential( + &self, + id: i64, + gateway_id: &str, + ) -> Result<(), BandwidthControllerError> where <St as Storage>::StorageError: Send + Sync + 'static, { - // JS: shouldn't we send some contract/validator/gateway message here to actually, you know, - // consume it? self.storage - .consume_coconut_credential(id) + .consume_coconut_credential(id, gateway_id) .await .map_err(|err| BandwidthControllerError::CredentialStorageError(Box::new(err))) } diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 2d7d4b9b57..5fb062065f 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -626,11 +626,13 @@ impl<C, St> GatewayClient<C, St> { }); } + let gateway_id = self.gateway_identity().to_base58_string(); + let prepared_credential = self .bandwidth_controller .as_ref() .unwrap() - .prepare_bandwidth_credential() + .prepare_bandwidth_credential(&gateway_id) .await?; self.claim_coconut_bandwidth(prepared_credential.data) @@ -638,7 +640,7 @@ impl<C, St> GatewayClient<C, St> { self.bandwidth_controller .as_ref() .unwrap() - .consume_credential(prepared_credential.credential_id) + .consume_credential(prepared_credential.credential_id, &gateway_id) .await?; Ok(()) diff --git a/common/credential-storage/migrations/20240311120000_credential_used_gateways.sql b/common/credential-storage/migrations/20240311120000_credential_used_gateways.sql new file mode 100644 index 0000000000..96398f6251 --- /dev/null +++ b/common/credential-storage/migrations/20240311120000_credential_used_gateways.sql @@ -0,0 +1,31 @@ +/* + * Copyright 2024 - Nym Technologies SA <contact@nymtech.net> + * SPDX-License-Identifier: Apache-2.0 + */ + +DROP TABLE coconut_credentials; +CREATE TABLE coconut_credentials +( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + +-- introduce a way for us to introduce breaking changes in serialization + serialization_revision INTEGER NOT NULL, + +-- the best we can do without enums + credential_type TEXT CHECK ( credential_type IN ('BandwidthVoucher', 'FreeBandwidthPass') ) NOT NULL, + credential_data BLOB NOT NULL, + epoch_id INTEGER NOT NULL, + +-- this field is only really applicable to free passes + expired BOOLEAN NOT NULL +); + +-- for bandwidth vouchers there's going to be only a single entry; for freepasses there can be as many as there are gateways +CREATE TABLE credential_usage +( + credential_id INTEGER NOT NULL REFERENCES coconut_credentials (id), + gateway_id_bs58 TEXT NOT NULL, + +-- no matter credential type, we can't spend the same credential with the same gateway multiple times + UNIQUE (credential_id, gateway_id_bs58) +) \ No newline at end of file diff --git a/common/credential-storage/migrations/20240311120001_drop_erc20.sql b/common/credential-storage/migrations/20240311120001_drop_erc20.sql new file mode 100644 index 0000000000..f74034ffc6 --- /dev/null +++ b/common/credential-storage/migrations/20240311120001_drop_erc20.sql @@ -0,0 +1,7 @@ +/* + * Copyright 2024 - Nym Technologies SA <contact@nymtech.net> + * SPDX-License-Identifier: Apache-2.0 + */ + +-- we never actually dropped that table... +DROP TABLE erc20_credentials; \ No newline at end of file diff --git a/common/credential-storage/src/backends/memory.rs b/common/credential-storage/src/backends/memory.rs index ddf5b7017e..78d18f3b88 100644 --- a/common/credential-storage/src/backends/memory.rs +++ b/common/credential-storage/src/backends/memory.rs @@ -1,7 +1,7 @@ // Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::models::StoredIssuedCredential; +use crate::models::{CredentialUsage, StoredIssuedCredential}; use std::sync::Arc; use tokio::sync::RwLock; @@ -12,7 +12,8 @@ pub struct CoconutCredentialManager { #[derive(Default)] struct CoconutCredentialManagerInner { - data: Vec<StoredIssuedCredential>, + credentials: Vec<StoredIssuedCredential>, + credential_usage: Vec<CredentialUsage>, _next_id: i64, } @@ -41,25 +42,67 @@ impl CoconutCredentialManager { ) { let mut inner = self.inner.write().await; let id = inner.next_id(); - inner.data.push(StoredIssuedCredential { + inner.credentials.push(StoredIssuedCredential { id, serialization_revision, credential_data: credential_data.to_vec(), credential_type, epoch_id, - consumed: false, expired: false, }) } - /// Tries to retrieve one of the stored, unused credentials. - pub async fn get_next_unspent_credential(&self) -> Option<StoredIssuedCredential> { - let creds = self.inner.read().await; - creds - .data + async fn bandwidth_voucher_spent(&self, id: i64) -> bool { + self.inner + .read() + .await + .credential_usage .iter() - .find(|c| !c.consumed && !c.expired) - .cloned() + .any(|c| c.credential_id == id) + } + + async fn freepass_spent(&self, id: i64, gateway_id: &str) -> bool { + self.inner + .read() + .await + .credential_usage + .iter() + .any(|c| c.credential_id == id && c.gateway_id_bs58 == gateway_id) + } + + /// Tries to retrieve one of the stored, unused credentials. + pub async fn get_next_unspect_bandwidth_voucher(&self) -> Option<StoredIssuedCredential> { + let guard = self.inner.read().await; + for credential in guard + .credentials + .iter() + .filter(|c| c.credential_type == "BandwidthVoucher") + { + if !self.bandwidth_voucher_spent(credential.id).await { + return Some(credential.clone()); + } + } + None + } + + pub async fn get_next_unspect_freepass( + &self, + gateway_id: &str, + ) -> Option<StoredIssuedCredential> { + let guard = self.inner.read().await; + for credential in guard + .credentials + .iter() + .filter(|c| c.credential_type == "FreeBandwidthPass") + { + if credential.expired { + continue; + } + if !self.freepass_spent(credential.id, gateway_id).await { + return Some(credential.clone()); + } + } + None } /// Consumes in the database the specified credential. @@ -67,11 +110,12 @@ impl CoconutCredentialManager { /// # Arguments /// /// * `id`: Database id. - pub async fn consume_coconut_credential(&self, id: i64) { - let mut creds = self.inner.write().await; - if let Some(cred) = creds.data.get_mut(id as usize) { - cred.consumed = true; - } + pub async fn consume_coconut_credential(&self, id: i64, gateway_id: &str) { + let mut guard = self.inner.write().await; + guard.credential_usage.push(CredentialUsage { + credential_id: id, + gateway_id_bs58: gateway_id.to_string(), + }); } /// Marks the specified credential as expired @@ -81,7 +125,7 @@ impl CoconutCredentialManager { /// * `id`: Id of the credential to mark as expired. pub async fn mark_expired(&self, id: i64) { let mut creds = self.inner.write().await; - if let Some(cred) = creds.data.get_mut(id as usize) { + if let Some(cred) = creds.credentials.get_mut(id as usize) { cred.expired = true; } } diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs index 50465f434d..c46c713a5f 100644 --- a/common/credential-storage/src/backends/sqlite.rs +++ b/common/credential-storage/src/backends/sqlite.rs @@ -27,19 +27,52 @@ impl CoconutCredentialManager { ) -> Result<(), sqlx::Error> { sqlx::query!( r#" - INSERT INTO coconut_credentials(serialization_revision, credential_type, credential_data, epoch_id, consumed, expired) - VALUES (?, ?, ?, ?, false, false) + INSERT INTO coconut_credentials(serialization_revision, credential_type, credential_data, epoch_id, expired) + VALUES (?, ?, ?, ?, false) "#, serialization_revision, credential_type, credential_data, epoch_id ).execute(&self.connection_pool).await?; Ok(()) } - pub async fn get_next_unspent_credential( + pub async fn get_next_unspect_freepass( + &self, + gateway_id: &str, + ) -> Result<Option<StoredIssuedCredential>, sqlx::Error> { + // get a credential of freepass type that doesn't appear in `credential_usage` for the provided gateway_id + sqlx::query_as( + r#" + SELECT * + FROM coconut_credentials + WHERE coconut_credentials.credential_type == "FreeBandwidthPass" + AND NOT EXISTS (SELECT 1 + FROM credential_usage + WHERE credential_usage.credential_id = coconut_credential.id + AND credential_usage.gateway_id_bs58 == ?) + ORDER BY coconut_credentials.id + LIMIT 1 + "#, + ) + .bind(gateway_id) + .fetch_optional(&self.connection_pool) + .await + } + + pub async fn get_next_unspect_bandwidth_voucher( &self, ) -> Result<Option<StoredIssuedCredential>, sqlx::Error> { + // get a credential of bandwidth voucher type that doesn't appear in `credential_usage` for any gateway_id sqlx::query_as( - "SELECT * FROM coconut_credentials WHERE NOT consumed AND NOT expired LIMIT 1", + r#" + SELECT * + FROM coconut_credentials + WHERE coconut_credentials.credential_type == "BandwidthVoucher" + AND NOT EXISTS (SELECT 1 + FROM credential_usage + WHERE credential_usage.credential_id = coconut_credential.id) + ORDER BY coconut_credentials.id + LIMIT 1 + "#, ) .fetch_optional(&self.connection_pool) .await @@ -50,10 +83,16 @@ impl CoconutCredentialManager { /// # Arguments /// /// * `id`: Database id. - pub async fn consume_coconut_credential(&self, id: i64) -> Result<(), sqlx::Error> { + /// * `gateway_id`: id of the gateway that received the credential + pub async fn consume_coconut_credential( + &self, + id: i64, + gateway_id: &str, + ) -> Result<(), sqlx::Error> { sqlx::query!( - "UPDATE coconut_credentials SET consumed = TRUE WHERE id = ?", - id + "INSERT INTO credential_usage (credential_id, gateway_id_bs58) VALUES (?, ?)", + id, + gateway_id ) .execute(&self.connection_pool) .await?; diff --git a/common/credential-storage/src/ephemeral_storage.rs b/common/credential-storage/src/ephemeral_storage.rs index 5b1b5b23e9..97d456ea46 100644 --- a/common/credential-storage/src/ephemeral_storage.rs +++ b/common/credential-storage/src/ephemeral_storage.rs @@ -44,16 +44,30 @@ impl Storage for EphemeralStorage { async fn get_next_unspent_credential( &self, + gateway_id: &str, ) -> Result<Option<StoredIssuedCredential>, Self::StorageError> { + // first try to get a free pass if available, otherwise fallback to bandwidth voucher + let maybe_freepass = self + .coconut_credential_manager + .get_next_unspect_freepass(gateway_id) + .await; + if maybe_freepass.is_some() { + return Ok(maybe_freepass); + } + Ok(self .coconut_credential_manager - .get_next_unspent_credential() + .get_next_unspect_bandwidth_voucher() .await) } - async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { + async fn consume_coconut_credential( + &self, + id: i64, + gateway_id: &str, + ) -> Result<(), StorageError> { self.coconut_credential_manager - .consume_coconut_credential(id) + .consume_coconut_credential(id, gateway_id) .await; Ok(()) diff --git a/common/credential-storage/src/models.rs b/common/credential-storage/src/models.rs index 5af5a3c089..49c004ece0 100644 --- a/common/credential-storage/src/models.rs +++ b/common/credential-storage/src/models.rs @@ -26,7 +26,6 @@ pub struct StoredIssuedCredential { pub credential_type: String, pub epoch_id: u32, - pub consumed: bool, pub expired: bool, } @@ -37,3 +36,9 @@ pub struct StorableIssuedCredential<'a> { pub epoch_id: u32, } + +#[cfg_attr(not(target_arch = "wasm32"), derive(sqlx::FromRow))] +pub struct CredentialUsage { + pub credential_id: i64, + pub gateway_id_bs58: String, +} diff --git a/common/credential-storage/src/persistent_storage.rs b/common/credential-storage/src/persistent_storage.rs index 8d0961c38d..f03d1abf68 100644 --- a/common/credential-storage/src/persistent_storage.rs +++ b/common/credential-storage/src/persistent_storage.rs @@ -76,16 +76,30 @@ impl Storage for PersistentStorage { async fn get_next_unspent_credential( &self, + gateway_id: &str, ) -> Result<Option<StoredIssuedCredential>, Self::StorageError> { + // first try to get a free pass if available, otherwise fallback to bandwidth voucher + let maybe_freepass = self + .coconut_credential_manager + .get_next_unspect_freepass(gateway_id) + .await?; + if maybe_freepass.is_some() { + return Ok(maybe_freepass); + } + Ok(self .coconut_credential_manager - .get_next_unspent_credential() + .get_next_unspect_bandwidth_voucher() .await?) } - async fn consume_coconut_credential(&self, id: i64) -> Result<(), StorageError> { + async fn consume_coconut_credential( + &self, + id: i64, + gateway_id: &str, + ) -> Result<(), StorageError> { self.coconut_credential_manager - .consume_coconut_credential(id) + .consume_coconut_credential(id, gateway_id) .await?; Ok(()) diff --git a/common/credential-storage/src/storage.rs b/common/credential-storage/src/storage.rs index 8f8cb7798e..7880a3722e 100644 --- a/common/credential-storage/src/storage.rs +++ b/common/credential-storage/src/storage.rs @@ -18,6 +18,7 @@ pub trait Storage: Send + Sync { /// that is also not marked as expired async fn get_next_unspent_credential( &self, + gateway_id: &str, ) -> Result<Option<StoredIssuedCredential>, Self::StorageError>; /// Marks as consumed in the database the specified credential. @@ -25,7 +26,12 @@ pub trait Storage: Send + Sync { /// # Arguments /// /// * `id`: Id of the credential to be consumed. - async fn consume_coconut_credential(&self, id: i64) -> Result<(), Self::StorageError>; + /// * `gateway_id`: id of the gateway that received the credential. + async fn consume_coconut_credential( + &self, + id: i64, + gateway_id: &str, + ) -> Result<(), Self::StorageError>; /// Marks the specified credential as expired /// From b59487cfb04d2395462bcfbfeec9eea288972f3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 09:59:08 +0000 Subject: [PATCH 312/394] fixed ipr imports --- .../ip-packet-router/src/cli/init.rs | 10 ++++----- .../ip-packet-router/src/cli/mod.rs | 4 ++-- .../ip-packet-router/src/cli/run.rs | 8 +++---- .../ip-packet-router/src/cli/sign.rs | 2 +- .../ip-packet-router/src/main.rs | 22 +------------------ 5 files changed, 11 insertions(+), 35 deletions(-) diff --git a/service-providers/ip-packet-router/src/cli/init.rs b/service-providers/ip-packet-router/src/cli/init.rs index 9a5808b755..c7060410f7 100644 --- a/service-providers/ip-packet-router/src/cli/init.rs +++ b/service-providers/ip-packet-router/src/cli/init.rs @@ -1,17 +1,15 @@ -use std::{fmt::Display, fs, path::PathBuf}; - +use crate::cli::{override_config, try_upgrade_config, OverrideConfig}; use clap::Args; use nym_bin_common::output_format::OutputFormat; use nym_client_core::cli_helpers::client_init::{ initialise_client, CommonClientInitArgs, InitResultsWithConfig, InitialisableClient, }; -use serde::Serialize; - -use crate::{ - cli::{override_config, try_upgrade_config, OverrideConfig}, +use nym_ip_packet_router::{ config::{default_config_directory, default_config_filepath, default_data_directory, Config}, error::IpPacketRouterError, }; +use serde::Serialize; +use std::{fmt::Display, fs, path::PathBuf}; struct IpPacketRouterInit; diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index 1ed7ca2920..d809e0b9e7 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -1,11 +1,11 @@ -use crate::config::{BaseClientConfig, Config}; -use crate::error::IpPacketRouterError; use clap::{CommandFactory, Parser, Subcommand}; use log::{error, info, trace}; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_ip_packet_router::config::old_config_v1::ConfigV1; +use nym_ip_packet_router::config::{BaseClientConfig, Config}; +use nym_ip_packet_router::error::IpPacketRouterError; use std::sync::OnceLock; mod build_info; diff --git a/service-providers/ip-packet-router/src/cli/run.rs b/service-providers/ip-packet-router/src/cli/run.rs index 6167de7666..32d97efddc 100644 --- a/service-providers/ip-packet-router/src/cli/run.rs +++ b/service-providers/ip-packet-router/src/cli/run.rs @@ -1,11 +1,9 @@ +use crate::cli::{override_config, OverrideConfig}; use crate::cli::{try_load_current_config, version_check}; -use crate::{ - cli::{override_config, OverrideConfig}, - error::IpPacketRouterError, -}; use clap::Args; use log::error; use nym_client_core::cli_helpers::client_run::CommonClientRunArgs; +use nym_ip_packet_router::error::IpPacketRouterError; #[allow(clippy::struct_excessive_bools)] #[derive(Args, Clone)] @@ -35,7 +33,7 @@ pub(crate) async fn execute(args: &Run) -> Result<(), IpPacketRouterError> { } log::info!("Starting ip packet router service provider"); - let mut server = crate::ip_packet_router::IpPacketRouter::new(config); + let mut server = nym_ip_packet_router::IpPacketRouter::new(config); if let Some(custom_mixnet) = &args.common_args.custom_mixnet { server = server.with_stored_topology(custom_mixnet)? } diff --git a/service-providers/ip-packet-router/src/cli/sign.rs b/service-providers/ip-packet-router/src/cli/sign.rs index 2b56007b47..968ce83536 100644 --- a/service-providers/ip-packet-router/src/cli/sign.rs +++ b/service-providers/ip-packet-router/src/cli/sign.rs @@ -1,10 +1,10 @@ use crate::cli::{try_load_current_config, version_check}; -use crate::error::IpPacketRouterError; use clap::Args; use nym_bin_common::output_format::OutputFormat; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::error::ClientCoreError; use nym_crypto::asymmetric::identity; +use nym_ip_packet_router::error::IpPacketRouterError; use nym_types::helpers::ConsoleSigningOutput; #[derive(Args, Clone)] diff --git a/service-providers/ip-packet-router/src/main.rs b/service-providers/ip-packet-router/src/main.rs index 143833aecb..0412ea62a9 100644 --- a/service-providers/ip-packet-router/src/main.rs +++ b/service-providers/ip-packet-router/src/main.rs @@ -1,29 +1,9 @@ #[cfg(target_os = "linux")] mod cli; -#[cfg(target_os = "linux")] -mod config; -#[cfg(target_os = "linux")] -mod connected_client_handler; -#[cfg(target_os = "linux")] -mod constants; -#[cfg(target_os = "linux")] -mod error; -#[cfg(target_os = "linux")] -mod ip_packet_router; -#[cfg(target_os = "linux")] -mod mixnet_client; -#[cfg(target_os = "linux")] -mod mixnet_listener; -#[cfg(target_os = "linux")] -mod request_filter; -#[cfg(target_os = "linux")] -mod tun_listener; -#[cfg(target_os = "linux")] -mod util; #[cfg(target_os = "linux")] #[tokio::main] -async fn main() -> Result<(), error::IpPacketRouterError> { +async fn main() -> Result<(), nym_ip_packet_router::error::IpPacketRouterError> { use clap::Parser; let args = cli::Cli::parse(); From 6c0573cb0121ab3798863dcfdd7b5b973faf4af2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 12:06:52 +0000 Subject: [PATCH 313/394] split up InitialisableClient trait --- clients/native/src/client/config/mod.rs | 4 +-- clients/native/src/commands/init.rs | 15 +++-------- clients/native/src/commands/mod.rs | 13 ++++++++++ clients/socks5/src/commands/init.rs | 15 +++-------- clients/socks5/src/commands/mod.rs | 13 ++++++++++ clients/socks5/src/config/mod.rs | 4 +-- .../src/cli_helpers/client_init.rs | 25 ++++-------------- common/client-core/src/cli_helpers/mod.rs | 4 +++ common/client-core/src/cli_helpers/traits.rs | 26 +++++++++++++++++++ .../ip-packet-router/src/cli/init.rs | 13 ++-------- .../ip-packet-router/src/cli/mod.rs | 13 ++++++++++ .../ip-packet-router/src/config/mod.rs | 6 ++--- .../network-requester/src/cli/init.rs | 15 +++-------- .../network-requester/src/cli/mod.rs | 13 ++++++++++ .../network-requester/src/config/mod.rs | 4 +-- 15 files changed, 106 insertions(+), 77 deletions(-) create mode 100644 common/client-core/src/cli_helpers/traits.rs diff --git a/clients/native/src/client/config/mod.rs b/clients/native/src/client/config/mod.rs index 264c3fec5b..f699d1e027 100644 --- a/clients/native/src/client/config/mod.rs +++ b/clients/native/src/client/config/mod.rs @@ -4,7 +4,7 @@ use crate::client::config::persistence::ClientPaths; use crate::client::config::template::CONFIG_TEMPLATE; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::cli_helpers::client_init::ClientConfig; +use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::defaults::DEFAULT_WEBSOCKET_LISTENING_PORT; use nym_config::{ @@ -75,7 +75,7 @@ impl NymConfigTemplate for Config { } } -impl ClientConfig for Config { +impl CliClientConfig for Config { fn common_paths(&self) -> &CommonClientPaths { &self.storage_paths.common_paths } diff --git a/clients/native/src/commands/init.rs b/clients/native/src/commands/init.rs index dfc7b95cd9..b71b168b03 100644 --- a/clients/native/src/commands/init.rs +++ b/clients/native/src/commands/init.rs @@ -4,7 +4,7 @@ use crate::client::config::{ default_config_directory, default_config_filepath, default_data_directory, }; -use crate::commands::try_upgrade_config; +use crate::commands::CliNativeClient; use crate::{ client::config::Config, commands::{override_config, OverrideConfig}, @@ -21,17 +21,8 @@ use std::fs; use std::net::IpAddr; use std::path::PathBuf; -struct NativeClientInit; - -impl InitialisableClient for NativeClientInit { - const NAME: &'static str = "native"; - type Error = ClientError; +impl InitialisableClient for CliNativeClient { type InitArgs = Init; - type Config = Config; - - async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await - } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { fs::create_dir_all(default_data_directory(id))?; @@ -124,7 +115,7 @@ pub(crate) async fn execute(args: Init) -> Result<(), ClientError> { eprintln!("Initialising client..."); let output = args.output; - let res = initialise_client::<NativeClientInit>(args).await?; + let res = initialise_client::<CliNativeClient>(args).await?; let init_results = InitResults::new(res); println!("{}", output.format(&init_results)); diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index d3947b876e..bb26918fa1 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -12,6 +12,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; +use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::error::Error; @@ -23,6 +24,18 @@ pub(crate) mod import_credential; pub(crate) mod init; pub(crate) mod run; +pub(crate) struct CliNativeClient; + +impl CliClient for CliNativeClient { + const NAME: &'static str = "native"; + type Error = ClientError; + type Config = Config; + + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await + } +} + fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) diff --git a/clients/socks5/src/commands/init.rs b/clients/socks5/src/commands/init.rs index 548059d701..83c26e7a3c 100644 --- a/clients/socks5/src/commands/init.rs +++ b/clients/socks5/src/commands/init.rs @@ -1,7 +1,7 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::commands::try_upgrade_config; +use crate::commands::CliSocks5Client; use crate::config::{ default_config_directory, default_config_filepath, default_data_directory, Config, }; @@ -21,17 +21,8 @@ use std::fs; use std::net::{IpAddr, SocketAddr}; use std::path::PathBuf; -struct Socks5ClientInit; - -impl InitialisableClient for Socks5ClientInit { - const NAME: &'static str = "socks5"; - type Error = Socks5ClientError; +impl InitialisableClient for CliSocks5Client { type InitArgs = Init; - type Config = Config; - - async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await - } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { fs::create_dir_all(default_data_directory(id))?; @@ -139,7 +130,7 @@ pub(crate) async fn execute(args: Init) -> Result<(), Socks5ClientError> { eprintln!("Initialising client..."); let output = args.output; - let res = initialise_client::<Socks5ClientInit>(args).await?; + let res = initialise_client::<CliSocks5Client>(args).await?; let init_results = InitResults::new(res); println!("{}", output.format(&init_results)); diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index d367a061cd..ba543a6e5c 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -13,6 +13,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; +use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; use nym_client_core::config::{GroupBy, TopologyStructure}; @@ -27,6 +28,18 @@ mod import_credential; pub mod init; pub(crate) mod run; +pub(crate) struct CliSocks5Client; + +impl CliClient for CliSocks5Client { + const NAME: &'static str = "socks5"; + type Error = Socks5ClientError; + type Config = Config; + + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await + } +} + fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) diff --git a/clients/socks5/src/config/mod.rs b/clients/socks5/src/config/mod.rs index 2a04d6d66d..5f2f07d64d 100644 --- a/clients/socks5/src/config/mod.rs +++ b/clients/socks5/src/config/mod.rs @@ -3,7 +3,7 @@ use crate::config::template::CONFIG_TEMPLATE; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::cli_helpers::client_init::ClientConfig; +use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::{ must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate, @@ -72,7 +72,7 @@ impl NymConfigTemplate for Config { } } -impl ClientConfig for Config { +impl CliClientConfig for Config { fn common_paths(&self) -> &CommonClientPaths { &self.storage_paths.common_paths } diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index e878a12028..1d83302210 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -1,7 +1,7 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::disk_persistence::CommonClientPaths; +use crate::cli_helpers::traits::{CliClient, CliClientConfig}; use crate::error::ClientCoreError; use crate::{ client::{ @@ -18,17 +18,12 @@ use nym_client_core_gateways_storage::GatewayDetails; use nym_crypto::asymmetric::identity; use nym_topology::NymTopology; use rand::rngs::OsRng; -use std::path::{Path, PathBuf}; +use std::path::PathBuf; // we can suppress this warning (as suggested by linter itself) since we're only using it in our own code #[allow(async_fn_in_trait)] -pub trait InitialisableClient { - const NAME: &'static str; - type Error: From<ClientCoreError>; +pub trait InitialisableClient: CliClient { type InitArgs: AsRef<CommonClientInitArgs>; - type Config: ClientConfig; - - async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; fn initialise_storage_paths(id: &str) -> Result<(), Self::Error>; @@ -37,16 +32,6 @@ pub trait InitialisableClient { fn construct_config(init_args: &Self::InitArgs) -> Self::Config; } -pub trait ClientConfig { - fn common_paths(&self) -> &CommonClientPaths; - - fn core_config(&self) -> &crate::config::Config; - - fn default_store_location(&self) -> PathBuf; - - fn save_to<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()>; -} - #[cfg_attr(feature = "cli", derive(clap::Args))] #[derive(Debug, Clone)] pub struct CommonClientInitArgs { @@ -125,7 +110,7 @@ pub async fn initialise_client<C>( ) -> Result<InitResultsWithConfig<C::Config>, C::Error> where C: InitialisableClient, - <C as InitialisableClient>::Config: std::fmt::Debug, + <C as CliClient>::Config: std::fmt::Debug, <C as InitialisableClient>::InitArgs: std::fmt::Debug, { info!("initialising {} client", C::NAME); diff --git a/common/client-core/src/cli_helpers/mod.rs b/common/client-core/src/cli_helpers/mod.rs index 874663b75e..985f0440bf 100644 --- a/common/client-core/src/cli_helpers/mod.rs +++ b/common/client-core/src/cli_helpers/mod.rs @@ -3,3 +3,7 @@ pub mod client_init; pub mod client_run; +pub mod traits; + +pub use client_init::InitialisableClient; +pub use traits::{CliClient, CliClientConfig}; diff --git a/common/client-core/src/cli_helpers/traits.rs b/common/client-core/src/cli_helpers/traits.rs new file mode 100644 index 0000000000..21b234d19b --- /dev/null +++ b/common/client-core/src/cli_helpers/traits.rs @@ -0,0 +1,26 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::disk_persistence::CommonClientPaths; +use crate::error::ClientCoreError; +use std::path::{Path, PathBuf}; + +// we can suppress this warning (as suggested by linter itself) since we're only using it in our own code +#[allow(async_fn_in_trait)] +pub trait CliClient { + const NAME: &'static str; + type Error: From<ClientCoreError>; + type Config: CliClientConfig; + + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; +} + +pub trait CliClientConfig { + fn common_paths(&self) -> &CommonClientPaths; + + fn core_config(&self) -> &crate::config::Config; + + fn default_store_location(&self) -> PathBuf; + + fn save_to<P: AsRef<Path>>(&self, path: P) -> std::io::Result<()>; +} diff --git a/service-providers/ip-packet-router/src/cli/init.rs b/service-providers/ip-packet-router/src/cli/init.rs index c7060410f7..b5f4e0f05c 100644 --- a/service-providers/ip-packet-router/src/cli/init.rs +++ b/service-providers/ip-packet-router/src/cli/init.rs @@ -11,17 +11,8 @@ use nym_ip_packet_router::{ use serde::Serialize; use std::{fmt::Display, fs, path::PathBuf}; -struct IpPacketRouterInit; - -impl InitialisableClient for IpPacketRouterInit { - const NAME: &'static str = "ip packet router"; - type Error = IpPacketRouterError; +impl InitialisableClient for CliIpPacketRouterClient { type InitArgs = Init; - type Config = Config; - - async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await - } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { fs::create_dir_all(default_data_directory(id))?; @@ -97,7 +88,7 @@ pub(crate) async fn execute(args: Init) -> Result<(), IpPacketRouterError> { eprintln!("Initialising client..."); let output = args.output; - let res = initialise_client::<IpPacketRouterInit>(args).await?; + let res = initialise_client::<CliIpPacketRouterClient>(args).await?; let init_results = InitResults::new(res); println!("{}", output.format(&init_results)); diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index d809e0b9e7..e5168d3284 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -2,6 +2,7 @@ use clap::{CommandFactory, Parser, Subcommand}; use log::{error, info, trace}; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; +use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_ip_packet_router::config::old_config_v1::ConfigV1; use nym_ip_packet_router::config::{BaseClientConfig, Config}; @@ -13,6 +14,18 @@ mod init; mod run; mod sign; +pub(crate) struct CliIpPacketRouterClient; + +impl CliClient for CliIpPacketRouterClient { + const NAME: &'static str = "ip packet router"; + type Error = IpPacketRouterError; + type Config = Config; + + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await + } +} + fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) diff --git a/service-providers/ip-packet-router/src/config/mod.rs b/service-providers/ip-packet-router/src/config/mod.rs index 1d36c97d16..88f6b32e68 100644 --- a/service-providers/ip-packet-router/src/config/mod.rs +++ b/service-providers/ip-packet-router/src/config/mod.rs @@ -1,9 +1,7 @@ pub use nym_client_core::config::Config as BaseClientConfig; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::{ - cli_helpers::client_init::ClientConfig, config::disk_persistence::CommonClientPaths, -}; +use nym_client_core::{cli_helpers::CliClientConfig, config::disk_persistence::CommonClientPaths}; use nym_config::{ defaults::mainnet, must_get_home, save_formatted_config_to_file, serde_helpers::de_maybe_stringified, NymConfigTemplate, OptionalSet, DEFAULT_CONFIG_DIR, @@ -76,7 +74,7 @@ impl NymConfigTemplate for Config { } } -impl ClientConfig for Config { +impl CliClientConfig for Config { fn common_paths(&self) -> &CommonClientPaths { &self.storage_paths.common_paths } diff --git a/service-providers/network-requester/src/cli/init.rs b/service-providers/network-requester/src/cli/init.rs index b8771961eb..b9cef1f16a 100644 --- a/service-providers/network-requester/src/cli/init.rs +++ b/service-providers/network-requester/src/cli/init.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::cli::try_upgrade_config; +use crate::cli::CliNetworkRequesterClient; use crate::config::{default_config_directory, default_config_filepath, default_data_directory}; use crate::{ cli::{override_config, OverrideConfig}, @@ -18,17 +18,8 @@ use std::fmt::Display; use std::fs; use std::path::PathBuf; -struct NetworkRequesterInit; - -impl InitialisableClient for NetworkRequesterInit { - const NAME: &'static str = "network requester"; - type Error = NetworkRequesterError; +impl InitialisableClient for CliNetworkRequesterClient { type InitArgs = Init; - type Config = Config; - - async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await - } fn initialise_storage_paths(id: &str) -> Result<(), Self::Error> { fs::create_dir_all(default_data_directory(id))?; @@ -130,7 +121,7 @@ pub(crate) async fn execute(args: Init) -> Result<(), NetworkRequesterError> { eprintln!("Initialising client..."); let output = args.output; - let res = initialise_client::<NetworkRequesterInit>(args).await?; + let res = initialise_client::<CliNetworkRequesterClient>(args).await?; let init_results = InitResults::new(res); println!("{}", output.format(&init_results)); diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 6aedc24cf0..938464c6fc 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -14,6 +14,7 @@ use log::{error, info, trace}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; +use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::sync::OnceLock; @@ -24,6 +25,18 @@ mod init; mod run; mod sign; +pub(crate) struct CliNetworkRequesterClient; + +impl CliClient for CliNetworkRequesterClient { + const NAME: &'static str = "network requester"; + type Error = NetworkRequesterError; + type Config = Config; + + async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { + try_upgrade_config(id).await + } +} + fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index 1270d7d980..a45180b200 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -4,7 +4,7 @@ use crate::config::persistence::NetworkRequesterPaths; use crate::config::template::CONFIG_TEMPLATE; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::cli_helpers::client_init::ClientConfig; +use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_config::{ must_get_home, read_config_from_toml_file, save_formatted_config_to_file, @@ -85,7 +85,7 @@ impl NymConfigTemplate for Config { } } -impl ClientConfig for Config { +impl CliClientConfig for Config { fn common_paths(&self) -> &CommonClientPaths { &self.storage_paths.common_paths } From 1b5a0f8cf29a4e3fad74d9e10aabb663fde93251 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 12:44:41 +0000 Subject: [PATCH 314/394] list gateways cli command --- clients/native/src/commands/list_gateways.rs | 32 ++++++ clients/native/src/commands/mod.rs | 9 ++ clients/socks5/src/commands/list_gateways.rs | 32 ++++++ clients/socks5/src/commands/mod.rs | 9 ++ .../src/cli_helpers/client_list_gateways.rs | 106 ++++++++++++++++++ .../src/cli_helpers/client_switch_gateway.rs | 2 + common/client-core/src/cli_helpers/mod.rs | 4 +- common/client-core/src/cli_helpers/traits.rs | 2 + .../src/client/base_client/storage/helpers.rs | 14 +++ .../ip-packet-router/src/cli/list_gateways.rs | 31 +++++ .../ip-packet-router/src/cli/mod.rs | 9 ++ .../src/cli/list_gateways.rs | 32 ++++++ .../network-requester/src/cli/mod.rs | 9 ++ 13 files changed, 290 insertions(+), 1 deletion(-) create mode 100644 clients/native/src/commands/list_gateways.rs create mode 100644 clients/socks5/src/commands/list_gateways.rs create mode 100644 common/client-core/src/cli_helpers/client_list_gateways.rs create mode 100644 common/client-core/src/cli_helpers/client_switch_gateway.rs create mode 100644 service-providers/ip-packet-router/src/cli/list_gateways.rs create mode 100644 service-providers/network-requester/src/cli/list_gateways.rs diff --git a/clients/native/src/commands/list_gateways.rs b/clients/native/src/commands/list_gateways.rs new file mode 100644 index 0000000000..63f41e7bfb --- /dev/null +++ b/clients/native/src/commands/list_gateways.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliNativeClient; +use crate::error::ClientError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { + let output = args.output; + let res = list_gateways::<CliNativeClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index bb26918fa1..f4a2fb2ec9 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -22,6 +22,7 @@ use std::sync::OnceLock; pub(crate) mod build_info; pub(crate) mod import_credential; pub(crate) mod init; +mod list_gateways; pub(crate) mod run; pub(crate) struct CliNativeClient; @@ -34,6 +35,10 @@ impl CliClient for CliNativeClient { async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { try_upgrade_config(id).await } + + async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error> { + try_load_current_config(id).await + } } fn pretty_build_info_static() -> &'static str { @@ -67,6 +72,9 @@ pub(crate) enum Commands { /// Import a pre-generated credential ImportCredential(import_credential::Args), + /// List all registered with gateways + ListGateways(list_gateways::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -96,6 +104,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, + Commands::ListGateways(args) => list_gateways::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/socks5/src/commands/list_gateways.rs b/clients/socks5/src/commands/list_gateways.rs new file mode 100644 index 0000000000..e33921c05f --- /dev/null +++ b/clients/socks5/src/commands/list_gateways.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliSocks5Client; +use crate::error::Socks5ClientError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { + let output = args.output; + let res = list_gateways::<CliSocks5Client, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index ba543a6e5c..5543fb7e67 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -26,6 +26,7 @@ use std::sync::OnceLock; pub(crate) mod build_info; mod import_credential; pub mod init; +mod list_gateways; pub(crate) mod run; pub(crate) struct CliSocks5Client; @@ -38,6 +39,10 @@ impl CliClient for CliSocks5Client { async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { try_upgrade_config(id).await } + + async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error> { + try_load_current_config(id).await + } } fn pretty_build_info_static() -> &'static str { @@ -71,6 +76,9 @@ pub(crate) enum Commands { /// Import a pre-generated credential ImportCredential(import_credential::Args), + /// List all registered with gateways + ListGateways(list_gateways::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -103,6 +111,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, + Commands::ListGateways(args) => list_gateways::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/common/client-core/src/cli_helpers/client_list_gateways.rs b/common/client-core/src/cli_helpers/client_list_gateways.rs new file mode 100644 index 0000000000..cbb914b22d --- /dev/null +++ b/common/client-core/src/cli_helpers/client_list_gateways.rs @@ -0,0 +1,106 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli_helpers::{CliClient, CliClientConfig}; +use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use crate::client::base_client::storage::helpers::get_gateway_registrations; +use nym_client_core_gateways_storage::{GatewayDetails, GatewayRegistration, GatewayType}; +use nym_crypto::asymmetric::identity; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; +use time::OffsetDateTime; +use url::Url; + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[derive(Debug, Clone)] +pub struct CommonClientListGatewaysArgs { + /// Id of client we want to list gateways for. + #[cfg_attr(feature = "cli", clap(long))] + pub id: String, +} + +#[derive(Serialize, Deserialize)] +#[serde(transparent)] +pub struct RegisteredGateways(Vec<GatewayInfo>); + +impl From<Vec<GatewayRegistration>> for RegisteredGateways { + fn from(value: Vec<GatewayRegistration>) -> Self { + RegisteredGateways(value.into_iter().map(Into::into).collect()) + } +} + +impl Display for RegisteredGateways { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + for (i, gateway) in self.0.iter().enumerate() { + writeln!(f, "[{i}]: {gateway}")?; + } + Ok(()) + } +} + +#[derive(Serialize, Deserialize)] +pub struct GatewayInfo { + pub registration: OffsetDateTime, + pub identity: identity::PublicKey, + + pub typ: String, + pub endpoint: Option<Url>, + pub wg_tun_address: Option<Url>, +} + +impl From<GatewayRegistration> for GatewayInfo { + fn from(value: GatewayRegistration) -> Self { + match value.details { + GatewayDetails::Remote(remote_details) => GatewayInfo { + registration: value.registration_timestamp, + identity: remote_details.gateway_id, + typ: GatewayType::Remote.to_string(), + endpoint: Some(remote_details.gateway_listener), + wg_tun_address: remote_details.wg_tun_address, + }, + GatewayDetails::Custom(_) => GatewayInfo { + registration: value.registration_timestamp, + identity: value.details.gateway_id(), + typ: value.details.typ().to_string(), + endpoint: None, + wg_tun_address: None, + }, + } + } +} + +impl Display for GatewayInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!( + f, + "{} gateway '{}' registered at: {}", + self.typ, self.identity, self.registration + )?; + if let Some(endpoint) = &self.endpoint { + write!(f, " endpoint: {endpoint}")?; + } + + if let Some(wg_tun_address) = &self.wg_tun_address { + write!(f, " wg tun address: {wg_tun_address}")?; + } + Ok(()) + } +} + +pub async fn list_gateways<C, A>(args: A) -> Result<RegisteredGateways, C::Error> +where + A: AsRef<CommonClientListGatewaysArgs>, + C: CliClient, +{ + let common_args = args.as_ref(); + let id = &common_args.id; + + let config = C::try_load_current_config(id).await?; + let paths = config.common_paths(); + + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; + + let gateways = get_gateway_registrations(&details_store).await?; + + Ok(gateways.into()) +} diff --git a/common/client-core/src/cli_helpers/client_switch_gateway.rs b/common/client-core/src/cli_helpers/client_switch_gateway.rs new file mode 100644 index 0000000000..755fb6cc8b --- /dev/null +++ b/common/client-core/src/cli_helpers/client_switch_gateway.rs @@ -0,0 +1,2 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 diff --git a/common/client-core/src/cli_helpers/mod.rs b/common/client-core/src/cli_helpers/mod.rs index 985f0440bf..a513f7065a 100644 --- a/common/client-core/src/cli_helpers/mod.rs +++ b/common/client-core/src/cli_helpers/mod.rs @@ -1,8 +1,10 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 pub mod client_init; +pub mod client_list_gateways; pub mod client_run; +pub mod client_switch_gateway; pub mod traits; pub use client_init::InitialisableClient; diff --git a/common/client-core/src/cli_helpers/traits.rs b/common/client-core/src/cli_helpers/traits.rs index 21b234d19b..ec93cb09dd 100644 --- a/common/client-core/src/cli_helpers/traits.rs +++ b/common/client-core/src/cli_helpers/traits.rs @@ -13,6 +13,8 @@ pub trait CliClient { type Config: CliClientConfig; async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error>; + + async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error>; } pub trait CliClientConfig { diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index 3ed3379b10..f3c96d0cd4 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -39,6 +39,20 @@ where }) } +pub async fn get_gateway_registrations<D>( + details_store: &D, +) -> Result<Vec<GatewayRegistration>, ClientCoreError> +where + D: GatewaysDetailsStore + Sync, + D::StorageError: Send + Sync + 'static, +{ + details_store.all_gateways().await.map_err(|source| { + ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + } + }) +} + pub async fn store_gateway_details<D>( details_store: &D, details: &GatewayRegistration, diff --git a/service-providers/ip-packet-router/src/cli/list_gateways.rs b/service-providers/ip-packet-router/src/cli/list_gateways.rs new file mode 100644 index 0000000000..fc7f94a78f --- /dev/null +++ b/service-providers/ip-packet-router/src/cli/list_gateways.rs @@ -0,0 +1,31 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; +use nym_ip_packet_router::error::IpPacketRouterError; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), IpPacketRouterError> { + let output = args.output; + let res = list_gateways::<CliIpPacketRouterClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index e5168d3284..8234e77444 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -11,6 +11,7 @@ use std::sync::OnceLock; mod build_info; mod init; +mod list_gateways; mod run; mod sign; @@ -24,6 +25,10 @@ impl CliClient for CliIpPacketRouterClient { async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { try_upgrade_config(id).await } + + async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error> { + try_load_current_config(id).await + } } fn pretty_build_info_static() -> &'static str { @@ -56,6 +61,9 @@ pub(crate) enum Commands { /// parameters. Run(run::Run), + /// List all registered with gateways + ListGateways(list_gateways::Args), + /// Sign to prove ownership of this network requester Sign(sign::Sign), @@ -108,6 +116,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { match args.command { Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(&m).await?, + Commands::ListGateways(args) => list_gateways::execute(args).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), diff --git a/service-providers/network-requester/src/cli/list_gateways.rs b/service-providers/network-requester/src/cli/list_gateways.rs new file mode 100644 index 0000000000..ec4703045b --- /dev/null +++ b/service-providers/network-requester/src/cli/list_gateways.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliNetworkRequesterClient; +use crate::error::NetworkRequesterError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { + let output = args.output; + let res = list_gateways::<CliNetworkRequesterClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 938464c6fc..ed5f82f82a 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -22,6 +22,7 @@ use std::sync::OnceLock; mod build_info; mod import_credential; mod init; +mod list_gateways; mod run; mod sign; @@ -35,6 +36,10 @@ impl CliClient for CliNetworkRequesterClient { async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { try_upgrade_config(id).await } + + async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error> { + try_load_current_config(id).await + } } fn pretty_build_info_static() -> &'static str { @@ -73,6 +78,9 @@ pub(crate) enum Commands { /// Import a pre-generated credential ImportCredential(import_credential::Args), + /// List all registered with gateways + ListGateways(list_gateways::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -168,6 +176,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Commands::Run(m) => run::execute(&m).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, + Commands::ListGateways(args) => list_gateways::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), From 28b02c83db0c79c120539f7bf757d58533f18507 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 13:02:17 +0000 Subject: [PATCH 315/394] unified credential import cli + added it for ipr --- Cargo.lock | 220 ++++++------------ .../native/src/commands/import_credential.rs | 54 +---- clients/native/src/commands/mod.rs | 3 +- .../socks5/src/commands/import_credential.rs | 55 +---- clients/socks5/src/commands/mod.rs | 3 +- common/client-core/Cargo.toml | 2 + .../cli_helpers/client_import_credential.rs | 58 +++++ common/client-core/src/cli_helpers/mod.rs | 1 + service-providers/ip-packet-router/Cargo.toml | 1 + .../src/cli/import_credential.rs | 14 ++ .../ip-packet-router/src/cli/init.rs | 2 +- .../ip-packet-router/src/cli/list_gateways.rs | 1 + .../ip-packet-router/src/cli/mod.rs | 6 + .../ip-packet-router/src/error.rs | 4 + .../src/cli/import_credential.rs | 55 +---- .../network-requester/src/cli/mod.rs | 3 +- 16 files changed, 190 insertions(+), 292 deletions(-) create mode 100644 common/client-core/src/cli_helpers/client_import_credential.rs create mode 100644 service-providers/ip-packet-router/src/cli/import_credential.rs diff --git a/Cargo.lock b/Cargo.lock index 23c3ccf211..95910fc24b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,6 +389,16 @@ dependencies = [ "futures-core", ] +[[package]] +name = "async-file-watcher" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "notify", + "tokio", +] + [[package]] name = "async-io" version = "1.13.0" @@ -547,9 +557,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http", + "http-body", + "hyper", "itoa", "matchit", "memchr", @@ -577,8 +587,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http", + "http-body", "mime", "rustversion", "tower-layer", @@ -3001,7 +3011,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http 0.2.9", + "http", "js-sys", "pin-project", "serde", @@ -3070,7 +3080,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http 0.2.9", + "http", "indexmap 1.9.3", "slab", "tokio", @@ -3281,14 +3291,17 @@ dependencies = [ ] [[package]] -name = "http" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +name = "http-api-client" +version = "0.1.0" dependencies = [ - "bytes", - "fnv", - "itoa", + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", ] [[package]] @@ -3298,30 +3311,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http 0.2.9", - "pin-project-lite 0.2.13", -] - -[[package]] -name = "http-body" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" -dependencies = [ - "bytes", - "http 1.1.0", -] - -[[package]] -name = "http-body-util" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" -dependencies = [ - "bytes", - "futures-core", - "http 1.1.0", - "http-body 1.0.0", + "http", "pin-project-lite 0.2.13", ] @@ -3389,8 +3379,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", + "http", + "http-body", "httparse", "httpdate", "itoa", @@ -3402,25 +3392,6 @@ dependencies = [ "want", ] -[[package]] -name = "hyper" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" -dependencies = [ - "bytes", - "futures-channel", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "httparse", - "httpdate", - "itoa", - "pin-project-lite 0.2.13", - "smallvec", - "tokio", -] - [[package]] name = "hyper-rustls" version = "0.24.1" @@ -3428,8 +3399,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http 0.2.9", - "hyper 0.14.27", + "http", + "hyper", "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", @@ -3441,28 +3412,12 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper 0.14.27", + "hyper", "pin-project-lite 0.2.13", "tokio", "tokio-io-timeout", ] -[[package]] -name = "hyper-util" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" -dependencies = [ - "bytes", - "futures-util", - "http 1.1.0", - "http-body 1.0.0", - "hyper 1.2.0", - "pin-project-lite 0.2.13", - "socket2 0.5.4", - "tokio", -] - [[package]] name = "iana-time-zone" version = "0.1.58" @@ -3787,7 +3742,7 @@ dependencies = [ "curl-sys", "event-listener", "futures-lite", - "http 0.2.9", + "http", "log", "once_cell", "polling", @@ -3919,6 +3874,17 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +[[package]] +name = "ledger" +version = "0.1.0" +dependencies = [ + "bip32", + "k256", + "ledger-transport", + "ledger-transport-hid", + "thiserror", +] + [[package]] name = "ledger-apdu" version = "0.10.0" @@ -4561,9 +4527,9 @@ version = "1.3.0-rc.0" dependencies = [ "async-trait", "futures", + "http-api-client", "js-sys", "nym-bin-common", - "nym-http-api-client", "nym-ordered-buffer", "nym-service-providers-common", "nym-socks5-requests", @@ -4589,7 +4555,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http 0.2.9", + "http", "httparse", "log", "memchr", @@ -5038,16 +5004,6 @@ dependencies = [ "ts-rs", ] -[[package]] -name = "nym-async-file-watcher" -version = "0.1.0" -dependencies = [ - "futures", - "log", - "notify", - "tokio", -] - [[package]] name = "nym-bandwidth-controller" version = "0.1.0" @@ -5230,14 +5186,12 @@ version = "1.1.15" dependencies = [ "async-trait", "base64 0.21.4", + "bs58 0.5.0", "cfg-if", "clap 4.4.7", "futures", "gloo-timers", - "http-body-util", "humantime-serde", - "hyper 1.2.0", - "hyper-util", "log", "nym-bandwidth-controller", "nym-client-core-gateways-storage", @@ -5248,7 +5202,7 @@ dependencies = [ "nym-explorer-client", "nym-gateway-client", "nym-gateway-requests", - "nym-metrics", + "nym-id", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", @@ -5594,7 +5548,7 @@ dependencies = [ "dotenvy", "futures", "humantime-serde", - "hyper 0.14.27", + "hyper", "ipnetwork 0.16.0", "log", "nym-api-requests", @@ -5702,20 +5656,6 @@ dependencies = [ "serde", ] -[[package]] -name = "nym-http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "nym-id" version = "0.1.0" @@ -5782,6 +5722,7 @@ dependencies = [ "nym-config", "nym-crypto", "nym-exit-policy", + "nym-id", "nym-ip-packet-requests", "nym-network-defaults", "nym-network-requester", @@ -5805,17 +5746,6 @@ dependencies = [ "url", ] -[[package]] -name = "nym-ledger" -version = "0.1.0" -dependencies = [ - "bip32", - "k256", - "ledger-transport", - "ledger-transport-hid", - "thiserror", -] - [[package]] name = "nym-metrics" version = "0.1.0" @@ -5824,6 +5754,7 @@ dependencies = [ "lazy_static", "log", "prometheus", + "regex", ] [[package]] @@ -5980,6 +5911,7 @@ version = "1.1.33" dependencies = [ "addr", "anyhow", + "async-file-watcher", "async-trait", "bs58 0.5.0", "clap 4.4.7", @@ -5988,7 +5920,6 @@ dependencies = [ "humantime-serde", "ipnetwork 0.20.0", "log", - "nym-async-file-watcher", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", @@ -6054,7 +5985,7 @@ dependencies = [ "dashmap", "fastrand 2.0.1", "hmac 0.12.1", - "hyper 0.14.27", + "hyper", "ipnetwork 0.16.0", "mime", "nym-config", @@ -6083,10 +6014,10 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.4", + "http-api-client", "nym-bin-common", "nym-crypto", "nym-exit-policy", - "nym-http-api-client", "nym-wireguard-types", "schemars", "serde", @@ -6207,7 +6138,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http 0.2.9", + "http", "httpcodec", "libp2p", "log", @@ -6664,6 +6595,7 @@ dependencies = [ "eyre", "flate2", "futures", + "http-api-client", "itertools 0.10.5", "log", "nym-api-requests", @@ -6674,7 +6606,6 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", - "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -6800,6 +6731,7 @@ name = "nymvisor" version = "0.1.0" dependencies = [ "anyhow", + "async-file-watcher", "bytes", "clap 4.4.7", "dotenvy", @@ -6809,7 +6741,6 @@ dependencies = [ "humantime 2.1.0", "humantime-serde", "nix 0.27.1", - "nym-async-file-watcher", "nym-bin-common", "nym-config", "nym-task", @@ -6947,7 +6878,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906" dependencies = [ "async-trait", "bytes", - "http 0.2.9", + "http", "isahc", "opentelemetry_api", ] @@ -6961,7 +6892,7 @@ dependencies = [ "async-trait", "futures", "futures-executor", - "http 0.2.9", + "http", "isahc", "once_cell", "opentelemetry", @@ -8142,9 +8073,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http", + "http-body", + "hyper", "hyper-rustls", "ipnet", "js-sys", @@ -8303,7 +8234,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ - "http 0.2.9", + "http", "log", "regex", "rocket", @@ -8323,8 +8254,8 @@ dependencies = [ "cookie", "either", "futures", - "http 0.2.9", - "hyper 0.14.27", + "http", + "hyper", "indexmap 2.0.2", "log", "memchr", @@ -9128,9 +9059,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.13.1" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" +checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" [[package]] name = "snafu" @@ -9979,10 +9910,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.10", - "rustls-native-certs", "tokio", - "tokio-rustls 0.24.1", "tungstenite", ] @@ -10085,9 +10013,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http 0.2.9", - "http-body 0.4.5", - "hyper 0.14.27", + "http", + "http-body", + "hyper", "hyper-timeout", "percent-encoding", "pin-project", @@ -10130,8 +10058,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http 0.2.9", - "http-body 0.4.5", + "http", + "http-body", "http-range-header", "httpdate", "mime", @@ -10409,7 +10337,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http 0.2.9", + "http", "httparse", "log", "rand 0.8.5", diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index 7fa7fa3b52..c7327797d0 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -1,54 +1,12 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::commands::try_load_current_config; +use crate::commands::CliNativeClient; use crate::error::ClientError; -use clap::ArgGroup; +use nym_client_core::cli_helpers::client_import_credential::{ + import_credential, CommonClientImportCredentialArgs, +}; -use nym_id::import_credential; -use std::fs; -use std::path::PathBuf; - -fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { - bs58::decode(raw).into_vec() -} - -#[derive(clap::Args)] -#[clap(group(ArgGroup::new("cred_data").required(true)))] -pub(crate) struct Args { - /// Id of client that is going to import the credential - #[clap(long)] - pub id: String, - - /// Explicitly provide the encoded credential data (as base58) - #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] - pub(crate) credential_data: Option<Vec<u8>>, - - /// Specifies the path to file containing binary credential data - #[clap(long, group = "cred_data")] - pub(crate) credential_path: Option<PathBuf>, - - // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true)] - pub(crate) version: Option<u8>, -} - -pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { - let config = try_load_current_config(&args.id).await?; - - let credentials_store = nym_credential_storage::initialise_persistent_storage( - &config.storage_paths.common_paths.credentials_database, - ) - .await; - - let raw_credential = match args.credential_data { - Some(data) => data, - None => { - // SAFETY: one of those arguments must have been set - fs::read(args.credential_path.unwrap())? - } - }; - - import_credential(credentials_store, raw_credential, args.version).await?; - Ok(()) +pub(crate) async fn execute(args: CommonClientImportCredentialArgs) -> Result<(), ClientError> { + import_credential::<CliNativeClient, _>(args).await } diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index f4a2fb2ec9..b13a09877d 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -12,6 +12,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; +use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; @@ -70,7 +71,7 @@ pub(crate) enum Commands { Run(run::Run), /// Import a pre-generated credential - ImportCredential(import_credential::Args), + ImportCredential(CommonClientImportCredentialArgs), /// List all registered with gateways ListGateways(list_gateways::Args), diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index a3bfd7dd45..91ea0bf552 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -1,53 +1,14 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::commands::try_load_current_config; +use crate::commands::CliSocks5Client; use crate::error::Socks5ClientError; -use clap::ArgGroup; -use nym_id::import_credential; -use std::fs; -use std::path::PathBuf; +use nym_client_core::cli_helpers::client_import_credential::{ + import_credential, CommonClientImportCredentialArgs, +}; -fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { - bs58::decode(raw).into_vec() -} - -#[derive(clap::Args)] -#[clap(group(ArgGroup::new("cred_data").required(true)))] -pub(crate) struct Args { - /// Id of client that is going to import the credential - #[clap(long)] - pub id: String, - - /// Explicitly provide the encoded credential data (as base58) - #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] - pub(crate) credential_data: Option<Vec<u8>>, - - /// Specifies the path to file containing binary credential data - #[clap(long, group = "cred_data")] - pub(crate) credential_path: Option<PathBuf>, - - // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true)] - pub(crate) version: Option<u8>, -} - -pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { - let config = try_load_current_config(&args.id).await?; - - let credentials_store = nym_credential_storage::initialise_persistent_storage( - &config.storage_paths.common_paths.credentials_database, - ) - .await; - - let raw_credential = match args.credential_data { - Some(data) => data, - None => { - // SAFETY: one of those arguments must have been set - fs::read(args.credential_path.unwrap())? - } - }; - - import_credential(credentials_store, raw_credential, args.version).await?; - Ok(()) +pub(crate) async fn execute( + args: CommonClientImportCredentialArgs, +) -> Result<(), Socks5ClientError> { + import_credential::<CliSocks5Client, _>(args).await } diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index 5543fb7e67..d60b9a8574 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -13,6 +13,7 @@ use clap::{Parser, Subcommand}; use log::{error, info}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; +use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_client_core::client::topology_control::geo_aware_provider::CountryGroup; @@ -74,7 +75,7 @@ pub(crate) enum Commands { Run(run::Run), /// Import a pre-generated credential - ImportCredential(import_credential::Args), + ImportCredential(CommonClientImportCredentialArgs), /// List all registered with gateways ListGateways(list_gateways::Args), diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index f144aa4373..b5c8aa5e2e 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -11,6 +11,7 @@ license.workspace = true [dependencies] async-trait = { workspace = true } base64 = "0.21.2" +bs58 = { workspace = true } cfg-if = "1.0.0" clap = { workspace = true, optional = true } futures = { workspace = true } @@ -30,6 +31,7 @@ time = { workspace = true } zeroize = { workspace = true } # internal +nym-id = { path = "../nym-id" } nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } nym-crypto = { path = "../crypto" } diff --git a/common/client-core/src/cli_helpers/client_import_credential.rs b/common/client-core/src/cli_helpers/client_import_credential.rs new file mode 100644 index 0000000000..55d005975a --- /dev/null +++ b/common/client-core/src/cli_helpers/client_import_credential.rs @@ -0,0 +1,58 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli_helpers::{CliClient, CliClientConfig}; +use std::fs; +use std::path::PathBuf; + +fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { + bs58::decode(raw).into_vec() +} + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[cfg_attr(feature = "cli", clap(group(clap::ArgGroup::new("cred_data").required(true))))] +#[derive(Debug, Clone)] +pub struct CommonClientImportCredentialArgs { + /// Id of client that is going to import the credential + #[cfg_attr(feature = "cli", clap(long))] + pub id: String, + + /// Explicitly provide the encoded credential data (as base58) + #[cfg_attr(feature = "cli", clap(long, group = "cred_data", value_parser = parse_encoded_credential_data))] + pub(crate) credential_data: Option<Vec<u8>>, + + /// Specifies the path to file containing binary credential data + #[cfg_attr(feature = "cli", clap(long, group = "cred_data"))] + pub(crate) credential_path: Option<PathBuf>, + + // currently hidden as there exists only a single serialization standard + #[cfg_attr(feature = "cli", clap(long, hide = true))] + pub(crate) version: Option<u8>, +} + +pub async fn import_credential<C, A>(args: A) -> Result<(), C::Error> +where + A: Into<CommonClientImportCredentialArgs>, + C: CliClient, + C::Error: From<std::io::Error> + From<nym_id::NymIdError>, +{ + let common_args = args.into(); + let id = &common_args.id; + + let config = C::try_load_current_config(id).await?; + let paths = config.common_paths(); + + let credentials_store = + nym_credential_storage::initialise_persistent_storage(&paths.credentials_database).await; + + let raw_credential = match common_args.credential_data { + Some(data) => data, + None => { + // SAFETY: one of those arguments must have been set + fs::read(common_args.credential_path.unwrap())? + } + }; + + nym_id::import_credential(credentials_store, raw_credential, common_args.version).await?; + Ok(()) +} diff --git a/common/client-core/src/cli_helpers/mod.rs b/common/client-core/src/cli_helpers/mod.rs index a513f7065a..e2a018cb18 100644 --- a/common/client-core/src/cli_helpers/mod.rs +++ b/common/client-core/src/cli_helpers/mod.rs @@ -1,6 +1,7 @@ // Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +pub mod client_import_credential; pub mod client_init; pub mod client_list_gateways; pub mod client_run; diff --git a/service-providers/ip-packet-router/Cargo.toml b/service-providers/ip-packet-router/Cargo.toml index e700505a96..3029a66a61 100644 --- a/service-providers/ip-packet-router/Cargo.toml +++ b/service-providers/ip-packet-router/Cargo.toml @@ -32,6 +32,7 @@ nym-tun = { path = "../../common/tun" } nym-types = { path = "../../common/types" } nym-wireguard = { path = "../../common/wireguard" } nym-wireguard-types = { path = "../../common/wireguard-types" } +nym-id = { path = "../../common/nym-id" } rand = "0.8.5" reqwest.workspace = true serde = { workspace = true, features = ["derive"] } diff --git a/service-providers/ip-packet-router/src/cli/import_credential.rs b/service-providers/ip-packet-router/src/cli/import_credential.rs new file mode 100644 index 0000000000..2ef4119803 --- /dev/null +++ b/service-providers/ip-packet-router/src/cli/import_credential.rs @@ -0,0 +1,14 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliIpPacketRouterClient; +use nym_client_core::cli_helpers::client_import_credential::{ + import_credential, CommonClientImportCredentialArgs, +}; +use nym_ip_packet_router::error::IpPacketRouterError; + +pub(crate) async fn execute( + args: CommonClientImportCredentialArgs, +) -> Result<(), IpPacketRouterError> { + import_credential::<CliIpPacketRouterClient, _>(args).await +} diff --git a/service-providers/ip-packet-router/src/cli/init.rs b/service-providers/ip-packet-router/src/cli/init.rs index b5f4e0f05c..6b41b287d8 100644 --- a/service-providers/ip-packet-router/src/cli/init.rs +++ b/service-providers/ip-packet-router/src/cli/init.rs @@ -1,4 +1,4 @@ -use crate::cli::{override_config, try_upgrade_config, OverrideConfig}; +use crate::cli::{override_config, CliIpPacketRouterClient, OverrideConfig}; use clap::Args; use nym_bin_common::output_format::OutputFormat; use nym_client_core::cli_helpers::client_init::{ diff --git a/service-providers/ip-packet-router/src/cli/list_gateways.rs b/service-providers/ip-packet-router/src/cli/list_gateways.rs index fc7f94a78f..3050233c87 100644 --- a/service-providers/ip-packet-router/src/cli/list_gateways.rs +++ b/service-providers/ip-packet-router/src/cli/list_gateways.rs @@ -1,6 +1,7 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::cli::CliIpPacketRouterClient; use nym_bin_common::output_format::OutputFormat; use nym_client_core::cli_helpers::client_list_gateways::{ list_gateways, CommonClientListGatewaysArgs, diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index 8234e77444..da35a12add 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -2,6 +2,7 @@ use clap::{CommandFactory, Parser, Subcommand}; use log::{error, info, trace}; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; +use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_ip_packet_router::config::old_config_v1::ConfigV1; @@ -10,6 +11,7 @@ use nym_ip_packet_router::error::IpPacketRouterError; use std::sync::OnceLock; mod build_info; +mod import_credential; mod init; mod list_gateways; mod run; @@ -61,6 +63,9 @@ pub(crate) enum Commands { /// parameters. Run(run::Run), + /// Import a pre-generated credential + ImportCredential(CommonClientImportCredentialArgs), + /// List all registered with gateways ListGateways(list_gateways::Args), @@ -116,6 +121,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { match args.command { Commands::Init(m) => init::execute(m).await?, Commands::Run(m) => run::execute(&m).await?, + Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::BuildInfo(m) => build_info::execute(m), diff --git a/service-providers/ip-packet-router/src/error.rs b/service-providers/ip-packet-router/src/error.rs index 4732177191..2cff116db4 100644 --- a/service-providers/ip-packet-router/src/error.rs +++ b/service-providers/ip-packet-router/src/error.rs @@ -2,6 +2,7 @@ use std::net::SocketAddr; pub use nym_client_core::error::ClientCoreError; use nym_exit_policy::PolicyError; +use nym_id::NymIdError; #[derive(thiserror::Error, Debug)] pub enum IpPacketRouterError { @@ -81,6 +82,9 @@ pub enum IpPacketRouterError { #[error("failed to update client activity")] FailedToUpdateClientActivity, + + #[error(transparent)] + NymIdError(#[from] NymIdError), } pub type Result<T> = std::result::Result<T, IpPacketRouterError>; diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index 31a11c92a0..aeb42d79b7 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -1,53 +1,14 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::cli::try_load_current_config; +use crate::cli::CliNetworkRequesterClient; use crate::error::NetworkRequesterError; -use clap::ArgGroup; -use nym_id::import_credential; -use std::fs; -use std::path::PathBuf; +use nym_client_core::cli_helpers::client_import_credential::{ + import_credential, CommonClientImportCredentialArgs, +}; -fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { - bs58::decode(raw).into_vec() -} - -#[derive(clap::Args)] -#[clap(group(ArgGroup::new("cred_data").required(true)))] -pub(crate) struct Args { - /// Id of client that is going to import the credential - #[clap(long)] - pub id: String, - - /// Explicitly provide the encoded credential data (as base58) - #[clap(long, group = "cred_data", value_parser = parse_encoded_credential_data)] - pub(crate) credential_data: Option<Vec<u8>>, - - /// Specifies the path to file containing binary credential data - #[clap(long, group = "cred_data")] - pub(crate) credential_path: Option<PathBuf>, - - // currently hidden as there exists only a single serialization standard - #[clap(long, hide = true)] - pub(crate) version: Option<u8>, -} - -pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { - let config = try_load_current_config(&args.id).await?; - - let credentials_store = nym_credential_storage::initialise_persistent_storage( - &config.storage_paths.common_paths.credentials_database, - ) - .await; - - let raw_credential = match args.credential_data { - Some(data) => data, - None => { - // SAFETY: one of those arguments must have been set - fs::read(args.credential_path.unwrap())? - } - }; - - import_credential(credentials_store, raw_credential, args.version).await?; - Ok(()) +pub(crate) async fn execute( + args: CommonClientImportCredentialArgs, +) -> Result<(), NetworkRequesterError> { + import_credential::<CliNetworkRequesterClient, _>(args).await } diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index ed5f82f82a..e721d38614 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -14,6 +14,7 @@ use log::{error, info, trace}; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; +use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; @@ -76,7 +77,7 @@ pub(crate) enum Commands { Sign(sign::Sign), /// Import a pre-generated credential - ImportCredential(import_credential::Args), + ImportCredential(CommonClientImportCredentialArgs), /// List all registered with gateways ListGateways(list_gateways::Args), From 062f4517d6b92ed0ff0b288355866cc8d29f2da5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 13:19:08 +0000 Subject: [PATCH 316/394] added cli command for switching active gateway --- clients/native/src/commands/mod.rs | 5 +++ clients/native/src/commands/switch_gateway.rs | 24 +++++++++++++ clients/socks5/src/commands/mod.rs | 5 +++ clients/socks5/src/commands/switch_gateway.rs | 24 +++++++++++++ .../src/backend/fs_backend/error.rs | 3 ++ .../src/backend/fs_backend/manager.rs | 10 ++++++ .../src/backend/fs_backend/mod.rs | 5 +++ .../src/cli_helpers/client_switch_gateway.rs | 35 +++++++++++++++++++ .../ip-packet-router/src/cli/mod.rs | 5 +++ .../src/cli/switch_gateway.rs | 24 +++++++++++++ .../network-requester/src/cli/mod.rs | 5 +++ .../src/cli/switch_gateway.rs | 24 +++++++++++++ 12 files changed, 169 insertions(+) create mode 100644 clients/native/src/commands/switch_gateway.rs create mode 100644 clients/socks5/src/commands/switch_gateway.rs create mode 100644 service-providers/ip-packet-router/src/cli/switch_gateway.rs create mode 100644 service-providers/network-requester/src/cli/switch_gateway.rs diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index b13a09877d..9c7c016580 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -25,6 +25,7 @@ pub(crate) mod import_credential; pub(crate) mod init; mod list_gateways; pub(crate) mod run; +mod switch_gateway; pub(crate) struct CliNativeClient; @@ -76,6 +77,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -106,6 +110,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/native/src/commands/switch_gateway.rs b/clients/native/src/commands/switch_gateway.rs new file mode 100644 index 0000000000..f7dbcfa65d --- /dev/null +++ b/clients/native/src/commands/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliNativeClient; +use crate::error::ClientError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef<CommonClientSwitchGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { + switch_gateway::<CliNativeClient, _>(args).await +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index d60b9a8574..d982b86a9e 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -29,6 +29,7 @@ mod import_credential; pub mod init; mod list_gateways; pub(crate) mod run; +mod switch_gateway; pub(crate) struct CliSocks5Client; @@ -80,6 +81,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -113,6 +117,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/clients/socks5/src/commands/switch_gateway.rs b/clients/socks5/src/commands/switch_gateway.rs new file mode 100644 index 0000000000..6b24fbb6a3 --- /dev/null +++ b/clients/socks5/src/commands/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliSocks5Client; +use crate::error::Socks5ClientError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef<CommonClientSwitchGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { + switch_gateway::<CliSocks5Client, _>(args).await +} diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs index 44cab38a8c..bdcaa0fdb5 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/error.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/error.rs @@ -39,4 +39,7 @@ pub enum StorageError { #[error(transparent)] MalformedGateway(#[from] BadGateway), + + #[error("gateway {gateway_id} does not exist in the storage")] + GatewayDoesNotExist { gateway_id: String }, } diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 965ace23f6..58cb451d97 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -75,6 +75,16 @@ impl StorageManager { Ok(()) } + pub(crate) async fn has_registered_gateway( + &self, + gateway_id: &str, + ) -> Result<bool, sqlx::Error> { + sqlx::query!("SELECT EXISTS (SELECT 1 FROM registered_gateway WHERE gateway_id_bs58 = ?) AS 'exists'", gateway_id) + .fetch_one(&self.connection_pool) + .await + .map(|result| result.exists == 1) + } + pub(crate) async fn maybe_get_registered_gateway( &self, gateway_id: &str, diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs index 7e0fbcdebc..0b93d284f6 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/mod.rs @@ -49,6 +49,11 @@ impl GatewaysDetailsStore for OnDiskGatewaysDetails { } async fn set_active_gateway(&self, gateway_id: &str) -> Result<(), Self::StorageError> { + if !self.manager.has_registered_gateway(gateway_id).await? { + return Err(StorageError::GatewayDoesNotExist { + gateway_id: gateway_id.to_string(), + }); + } Ok(self.manager.set_active_gateway(Some(gateway_id)).await?) } diff --git a/common/client-core/src/cli_helpers/client_switch_gateway.rs b/common/client-core/src/cli_helpers/client_switch_gateway.rs index 755fb6cc8b..0468575e63 100644 --- a/common/client-core/src/cli_helpers/client_switch_gateway.rs +++ b/common/client-core/src/cli_helpers/client_switch_gateway.rs @@ -1,2 +1,37 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 + +use crate::cli_helpers::{CliClient, CliClientConfig}; +use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use crate::client::base_client::storage::helpers::set_active_gateway; +use nym_crypto::asymmetric::identity; + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[derive(Debug, Clone)] +pub struct CommonClientSwitchGatewaysArgs { + /// Id of client we want to list gateways for. + #[cfg_attr(feature = "cli", clap(long))] + pub id: String, + + /// Id of the gateway we want to switch to. + #[cfg_attr(feature = "cli", clap(long))] + pub gateway_id: identity::PublicKey, +} + +pub async fn switch_gateway<C, A>(args: A) -> Result<(), C::Error> +where + A: AsRef<CommonClientSwitchGatewaysArgs>, + C: CliClient, +{ + let common_args = args.as_ref(); + let id = &common_args.id; + + let config = C::try_load_current_config(id).await?; + let paths = config.common_paths(); + + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; + + set_active_gateway(&details_store, &common_args.gateway_id.to_base58_string()).await?; + + Ok(()) +} diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index da35a12add..dc04d7e3cb 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -16,6 +16,7 @@ mod init; mod list_gateways; mod run; mod sign; +mod switch_gateway; pub(crate) struct CliIpPacketRouterClient; @@ -69,6 +70,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Sign to prove ownership of this network requester Sign(sign::Sign), @@ -123,6 +127,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Commands::Run(m) => run::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), diff --git a/service-providers/ip-packet-router/src/cli/switch_gateway.rs b/service-providers/ip-packet-router/src/cli/switch_gateway.rs new file mode 100644 index 0000000000..4a365a4bdb --- /dev/null +++ b/service-providers/ip-packet-router/src/cli/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliIpPacketRouterClient; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; +use nym_ip_packet_router::error::IpPacketRouterError; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef<CommonClientSwitchGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), IpPacketRouterError> { + switch_gateway::<CliIpPacketRouterClient, _>(args).await +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index e721d38614..29057aa523 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -26,6 +26,7 @@ mod init; mod list_gateways; mod run; mod sign; +mod switch_gateway; pub(crate) struct CliNetworkRequesterClient; @@ -82,6 +83,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! + SwitchGateway(switch_gateway::Args), + /// Show build information of this binary BuildInfo(build_info::BuildInfo), @@ -178,6 +182,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Commands::Sign(m) => sign::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), Commands::GenerateFigSpec => fig_generate(&mut Cli::command(), bin_name), diff --git a/service-providers/network-requester/src/cli/switch_gateway.rs b/service-providers/network-requester/src/cli/switch_gateway.rs new file mode 100644 index 0000000000..7496fc0018 --- /dev/null +++ b/service-providers/network-requester/src/cli/switch_gateway.rs @@ -0,0 +1,24 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliNetworkRequesterClient; +use crate::error::NetworkRequesterError; +use nym_client_core::cli_helpers::client_switch_gateway::{ + switch_gateway, CommonClientSwitchGatewaysArgs, +}; + +#[derive(clap::Args, Clone, Debug)] +pub struct Args { + #[command(flatten)] + common_args: CommonClientSwitchGatewaysArgs, +} + +impl AsRef<CommonClientSwitchGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientSwitchGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { + switch_gateway::<CliNetworkRequesterClient, _>(args).await +} From c07b782afab2274052c3336eda21ececae4e1c82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 13:24:51 +0000 Subject: [PATCH 317/394] added bool to list gateways to indicate currently active gateway --- .../src/cli_helpers/client_list_gateways.rs | 64 ++++++++++--------- .../src/client/base_client/storage/helpers.rs | 16 +++++ 2 files changed, 49 insertions(+), 31 deletions(-) diff --git a/common/client-core/src/cli_helpers/client_list_gateways.rs b/common/client-core/src/cli_helpers/client_list_gateways.rs index cbb914b22d..641b29d16e 100644 --- a/common/client-core/src/cli_helpers/client_list_gateways.rs +++ b/common/client-core/src/cli_helpers/client_list_gateways.rs @@ -3,8 +3,10 @@ use crate::cli_helpers::{CliClient, CliClientConfig}; use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; -use crate::client::base_client::storage::helpers::get_gateway_registrations; -use nym_client_core_gateways_storage::{GatewayDetails, GatewayRegistration, GatewayType}; +use crate::client::base_client::storage::helpers::{ + get_active_gateway_identity, get_gateway_registrations, +}; +use nym_client_core_gateways_storage::{GatewayDetails, GatewayType}; use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; @@ -23,12 +25,6 @@ pub struct CommonClientListGatewaysArgs { #[serde(transparent)] pub struct RegisteredGateways(Vec<GatewayInfo>); -impl From<Vec<GatewayRegistration>> for RegisteredGateways { - fn from(value: Vec<GatewayRegistration>) -> Self { - RegisteredGateways(value.into_iter().map(Into::into).collect()) - } -} - impl Display for RegisteredGateways { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { for (i, gateway) in self.0.iter().enumerate() { @@ -42,35 +38,18 @@ impl Display for RegisteredGateways { pub struct GatewayInfo { pub registration: OffsetDateTime, pub identity: identity::PublicKey, + pub active: bool, pub typ: String, pub endpoint: Option<Url>, pub wg_tun_address: Option<Url>, } -impl From<GatewayRegistration> for GatewayInfo { - fn from(value: GatewayRegistration) -> Self { - match value.details { - GatewayDetails::Remote(remote_details) => GatewayInfo { - registration: value.registration_timestamp, - identity: remote_details.gateway_id, - typ: GatewayType::Remote.to_string(), - endpoint: Some(remote_details.gateway_listener), - wg_tun_address: remote_details.wg_tun_address, - }, - GatewayDetails::Custom(_) => GatewayInfo { - registration: value.registration_timestamp, - identity: value.details.gateway_id(), - typ: value.details.typ().to_string(), - endpoint: None, - wg_tun_address: None, - }, - } - } -} - impl Display for GatewayInfo { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if self.active { + write!(f, "[ACTIVE] ")?; + } write!( f, "{} gateway '{}' registered at: {}", @@ -100,7 +79,30 @@ where let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; - let gateways = get_gateway_registrations(&details_store).await?; + let active_gateway = get_active_gateway_identity(&details_store).await?; - Ok(gateways.into()) + let gateways = get_gateway_registrations(&details_store).await?; + let mut info = Vec::with_capacity(gateways.len()); + for gateway in gateways { + match gateway.details { + GatewayDetails::Remote(remote_details) => info.push(GatewayInfo { + registration: gateway.registration_timestamp, + identity: remote_details.gateway_id, + active: active_gateway == Some(remote_details.gateway_id), + typ: GatewayType::Remote.to_string(), + endpoint: Some(remote_details.gateway_listener), + wg_tun_address: remote_details.wg_tun_address, + }), + GatewayDetails::Custom(_) => info.push(GatewayInfo { + registration: gateway.registration_timestamp, + identity: gateway.details.gateway_id(), + active: active_gateway == Some(gateway.details.gateway_id()), + typ: gateway.details.typ().to_string(), + endpoint: None, + wg_tun_address: None, + }), + }; + } + + Ok(RegisteredGateways(info)) } diff --git a/common/client-core/src/client/base_client/storage/helpers.rs b/common/client-core/src/client/base_client/storage/helpers.rs index f3c96d0cd4..b2a200579d 100644 --- a/common/client-core/src/client/base_client/storage/helpers.rs +++ b/common/client-core/src/client/base_client/storage/helpers.rs @@ -24,6 +24,22 @@ where }) } +pub async fn get_active_gateway_identity<D>( + details_store: &D, +) -> Result<Option<identity::PublicKey>, ClientCoreError> +where + D: GatewaysDetailsStore, + D::StorageError: Send + Sync + 'static, +{ + details_store + .active_gateway() + .await + .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { + source: Box::new(source), + }) + .map(|a| a.registration.map(|r| r.details.gateway_id())) +} + pub async fn get_all_registered_identities<D>( details_store: &D, ) -> Result<Vec<identity::PublicKey>, ClientCoreError> From 7c14a92baa7fe138a98af45eafa80abfc1a29335 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 13:26:44 +0000 Subject: [PATCH 318/394] decreased logging level --- .../gateways-storage/src/backend/fs_backend/manager.rs | 4 ++-- .../client-core/src/client/base_client/non_wasm_helpers.rs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs index 58cb451d97..4c3e3c48b5 100644 --- a/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs +++ b/common/client-core/gateways-storage/src/backend/fs_backend/manager.rs @@ -7,7 +7,7 @@ use crate::{ RawActiveGateway, RawCustomGatewayDetails, RawRegisteredGateway, RawRemoteGatewayDetails, }, }; -use log::{error, info}; +use log::{debug, error}; use sqlx::ConnectOptions; use std::path::Path; @@ -49,7 +49,7 @@ impl StorageManager { error!("Failed to initialize SQLx database: {err}"); })?; - info!("Database migration finished!"); + debug!("Database migration finished!"); Ok(StorageManager { connection_pool }) } diff --git a/common/client-core/src/client/base_client/non_wasm_helpers.rs b/common/client-core/src/client/base_client/non_wasm_helpers.rs index 740e75bb33..ce3f05b0f2 100644 --- a/common/client-core/src/client/base_client/non_wasm_helpers.rs +++ b/common/client-core/src/client/base_client/non_wasm_helpers.rs @@ -1,4 +1,4 @@ -// Copyright 2022-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use crate::client::replies::reply_storage::{ @@ -7,7 +7,7 @@ use crate::client::replies::reply_storage::{ use crate::config; use crate::config::Config; use crate::error::ClientCoreError; -use log::{error, info}; +use log::{error, info, trace}; use nym_bandwidth_controller::BandwidthController; use nym_client_core_gateways_storage::OnDiskGatewaysDetails; use nym_credential_storage::storage::Storage as CredentialStorage; @@ -105,7 +105,7 @@ pub async fn setup_fs_reply_surb_backend<P: AsRef<Path>>( pub async fn setup_fs_gateways_storage<P: AsRef<Path>>( db_path: P, ) -> Result<OnDiskGatewaysDetails, ClientCoreError> { - info!("setting up gateways details storage"); + trace!("setting up gateways details storage"); OnDiskGatewaysDetails::init(db_path) .await .map_err(|source| ClientCoreError::GatewaysDetailsStoreError { From 06abe53399622176ceaf971cc8c3e555f7246d66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 14:30:07 +0000 Subject: [PATCH 319/394] CT-80 From c95e42498149382b319150f5f5b92ac097445e64 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 12 Mar 2024 15:26:59 +0000 Subject: [PATCH 320/394] missing licenses for new crates --- common/client-core/gateways-storage/Cargo.toml | 1 + common/client-core/surb-storage/Cargo.toml | 1 + 2 files changed, 2 insertions(+) diff --git a/common/client-core/gateways-storage/Cargo.toml b/common/client-core/gateways-storage/Cargo.toml index 567744d1b6..4392798c0b 100644 --- a/common/client-core/gateways-storage/Cargo.toml +++ b/common/client-core/gateways-storage/Cargo.toml @@ -2,6 +2,7 @@ name = "nym-client-core-gateways-storage" version = "0.1.0" edition = "2021" +license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/common/client-core/surb-storage/Cargo.toml b/common/client-core/surb-storage/Cargo.toml index 24f466e1e3..7a902bef94 100644 --- a/common/client-core/surb-storage/Cargo.toml +++ b/common/client-core/surb-storage/Cargo.toml @@ -2,6 +2,7 @@ name = "nym-client-core-surb-storage" version = "0.1.0" edition = "2021" +license.workspace = true # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html From 73d6e704c4f0582c00c2371fc1c64cba797d17f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 20 Mar 2024 14:28:14 +0000 Subject: [PATCH 321/394] fixed gateway not generating keys for nr and ipr --- common/client-core/src/init/mod.rs | 15 ++++++++++----- gateway/src/commands/helpers.rs | 17 ++++++++++++++++- service-providers/network-requester/src/lib.rs | 2 +- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 6bc0fa8e91..388902045f 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -202,6 +202,7 @@ where log::debug!("Setting up gateway"); match setup { GatewaySetup::MustLoad { gateway_id } => { + log::trace!("GatewaySetup::MustLoad with id: {gateway_id:?}"); use_loaded_gateway_details(key_store, details_store, gateway_id).await } GatewaySetup::New { @@ -210,6 +211,7 @@ where overwrite_data, wg_tun_address, } => { + log::trace!("GatewaySetup::New with spec: {specification:?}"); setup_new_gateway( key_store, details_store, @@ -224,11 +226,14 @@ where authenticated_ephemeral_client, gateway_details, client_keys: managed_keys, - } => Ok(reuse_gateway_connection( - authenticated_ephemeral_client, - *gateway_details, - managed_keys, - )), + } => { + log::trace!("GatewaySetup::ReuseConnection"); + Ok(reuse_gateway_connection( + authenticated_ephemeral_client, + *gateway_details, + managed_keys, + )) + } } } diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index e12cc337f1..d7cc0c4743 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -16,9 +16,12 @@ use nym_network_defaults::mainnet; use nym_network_defaults::var_names::NYXD; use nym_network_defaults::var_names::{BECH32_PREFIX, NYM_API, STATISTICS_SERVICE_DOMAIN_ADDRESS}; use nym_network_requester::config::BaseClientConfig; -use nym_network_requester::{setup_fs_gateways_storage, setup_gateway, GatewaySetup, OnDiskKeys}; +use nym_network_requester::{ + generate_new_client_keys, setup_fs_gateways_storage, setup_gateway, GatewaySetup, OnDiskKeys, +}; use nym_types::gateway::{GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails}; use nym_validator_client::nyxd::AccountId; +use rand::rngs::OsRng; use std::net::IpAddr; use std::path::PathBuf; @@ -275,6 +278,12 @@ pub(crate) async fn initialise_local_network_requester( let details_store = setup_fs_gateways_storage(&nr_cfg.storage_paths.common_paths.gateway_registrations).await?; + // if this is a first time client with this particular id is initialised, generated long-term keys + if !nr_cfg_path.exists() { + let mut rng = OsRng; + generate_new_client_keys(&mut rng, &key_store).await?; + } + // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( GatewaySetup::new_inbuilt(identity), @@ -341,6 +350,12 @@ pub(crate) async fn initialise_local_ip_packet_router( let details_store = setup_fs_gateways_storage(&ip_cfg.storage_paths.common_paths.gateway_registrations).await?; + // if this is a first time client with this particular id is initialised, generated long-term keys + if !ip_cfg_path.exists() { + let mut rng = OsRng; + generate_new_client_keys(&mut rng, &key_store).await?; + } + // gateway setup here is way simpler as we're 'connecting' to ourselves let init_res = setup_gateway( GatewaySetup::new_inbuilt(identity), diff --git a/service-providers/network-requester/src/lib.rs b/service-providers/network-requester/src/lib.rs index 01bdaf3a42..6145b9681d 100644 --- a/service-providers/network-requester/src/lib.rs +++ b/service-providers/network-requester/src/lib.rs @@ -21,7 +21,7 @@ pub use nym_client_core::{ mix_traffic::transceiver::*, }, init::{ - setup_gateway, + generate_new_client_keys, setup_gateway, types::{GatewaySelectionSpecification, GatewaySetup, InitResults, InitialisationResult}, }, }; From 6259106b6baf5429ef17985a5fe641ed35af87d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 20 Mar 2024 14:34:09 +0000 Subject: [PATCH 322/394] fixed embedded SP not correctly setting active gateway --- common/client-core/src/init/types.rs | 6 +++++- gateway/src/commands/helpers.rs | 5 ++++- service-providers/network-requester/src/lib.rs | 5 ++++- 3 files changed, 13 insertions(+), 3 deletions(-) diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index 019b5218e3..f8f5d93fdb 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -172,9 +172,13 @@ impl InitialisationResult { *self.client_keys.encryption_keypair().public_key(), // TODO: below only works under assumption that gateway address == gateway id // (which currently is true) - self.gateway_registration.details.gateway_id(), + self.gateway_id(), ) } + + pub fn gateway_id(&self) -> identity::PublicKey { + self.gateway_registration.details.gateway_id() + } } #[derive(Clone, Debug)] diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index d7cc0c4743..968b9b14c6 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -17,7 +17,8 @@ use nym_network_defaults::var_names::NYXD; use nym_network_defaults::var_names::{BECH32_PREFIX, NYM_API, STATISTICS_SERVICE_DOMAIN_ADDRESS}; use nym_network_requester::config::BaseClientConfig; use nym_network_requester::{ - generate_new_client_keys, setup_fs_gateways_storage, setup_gateway, GatewaySetup, OnDiskKeys, + generate_new_client_keys, set_active_gateway, setup_fs_gateways_storage, setup_gateway, + GatewaySetup, OnDiskKeys, }; use nym_types::gateway::{GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails}; use nym_validator_client::nyxd::AccountId; @@ -291,6 +292,7 @@ pub(crate) async fn initialise_local_network_requester( &details_store, ) .await?; + set_active_gateway(&details_store, &init_res.gateway_id().to_base58_string()).await?; let address = init_res.client_address(); @@ -363,6 +365,7 @@ pub(crate) async fn initialise_local_ip_packet_router( &details_store, ) .await?; + set_active_gateway(&details_store, &init_res.gateway_id().to_base58_string()).await?; let address = init_res.client_address(); diff --git a/service-providers/network-requester/src/lib.rs b/service-providers/network-requester/src/lib.rs index 6145b9681d..457afc99cd 100644 --- a/service-providers/network-requester/src/lib.rs +++ b/service-providers/network-requester/src/lib.rs @@ -15,7 +15,10 @@ pub use nym_client_core::{ client::{ base_client::{ non_wasm_helpers::{setup_fs_gateways_storage, setup_fs_reply_surb_backend}, - storage::{GatewaysDetailsStore, OnDiskGatewaysDetails, OnDiskPersistent}, + storage::{ + helpers::set_active_gateway, GatewaysDetailsStore, OnDiskGatewaysDetails, + OnDiskPersistent, + }, }, key_manager::persistence::OnDiskKeys, mix_traffic::transceiver::*, From 36f84ca18ff0b46420f2cfb9a37190ca9c52d840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 10:49:25 +0000 Subject: [PATCH 323/394] fixed typo in SQL query --- common/credential-storage/src/backends/sqlite.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs index c46c713a5f..c356e09820 100644 --- a/common/credential-storage/src/backends/sqlite.rs +++ b/common/credential-storage/src/backends/sqlite.rs @@ -47,7 +47,7 @@ impl CoconutCredentialManager { WHERE coconut_credentials.credential_type == "FreeBandwidthPass" AND NOT EXISTS (SELECT 1 FROM credential_usage - WHERE credential_usage.credential_id = coconut_credential.id + WHERE credential_usage.credential_id = coconut_credentials.id AND credential_usage.gateway_id_bs58 == ?) ORDER BY coconut_credentials.id LIMIT 1 @@ -69,7 +69,7 @@ impl CoconutCredentialManager { WHERE coconut_credentials.credential_type == "BandwidthVoucher" AND NOT EXISTS (SELECT 1 FROM credential_usage - WHERE credential_usage.credential_id = coconut_credential.id) + WHERE credential_usage.credential_id = coconut_credentials.id) ORDER BY coconut_credentials.id LIMIT 1 "#, From ebd1eeb38df1fd5e95d4b79e08b6fdc13806a718 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 11:26:49 +0000 Subject: [PATCH 324/394] allow gateways to migrate configs of embedded NR/IPR --- gateway/src/commands/init.rs | 2 +- gateway/src/commands/node_details.rs | 2 +- gateway/src/commands/run.rs | 2 +- gateway/src/node/helpers.rs | 38 ++++- gateway/src/node/mod.rs | 4 +- .../ip-packet-router/src/cli/mod.rs | 39 +---- .../ip-packet-router/src/config/helpers.rs | 48 ++++++ .../ip-packet-router/src/config/mod.rs | 1 + .../network-requester/src/cli/mod.rs | 141 +--------------- .../network-requester/src/config/helpers.rs | 155 ++++++++++++++++++ .../network-requester/src/config/mod.rs | 1 + .../src/config/old_config_v1_1_20_2.rs | 1 + .../src/config/old_config_v1_1_33.rs | 1 + 13 files changed, 251 insertions(+), 184 deletions(-) create mode 100644 service-providers/ip-packet-router/src/config/helpers.rs create mode 100644 service-providers/network-requester/src/config/helpers.rs diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index b65cc062d2..010d270222 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -265,7 +265,7 @@ pub async fn execute(args: Init) -> anyhow::Result<()> { ); eprintln!("Gateway configuration completed.\n\n\n"); - output.to_stdout(&node_details(&config)?); + output.to_stdout(&node_details(&config).await?); Ok(()) } diff --git a/gateway/src/commands/node_details.rs b/gateway/src/commands/node_details.rs index 02c0ca9875..72840a8a7a 100644 --- a/gateway/src/commands/node_details.rs +++ b/gateway/src/commands/node_details.rs @@ -18,7 +18,7 @@ pub struct NodeDetails { pub async fn execute(args: NodeDetails) -> anyhow::Result<()> { let config = try_load_current_config(&args.id)?; - args.output.to_stdout(&node_details(&config)?); + args.output.to_stdout(&node_details(&config).await?); Ok(()) } diff --git a/gateway/src/commands/run.rs b/gateway/src/commands/run.rs index 3418c216ac..34c1b6be8d 100644 --- a/gateway/src/commands/run.rs +++ b/gateway/src/commands/run.rs @@ -248,7 +248,7 @@ pub async fn execute(args: Run) -> anyhow::Result<()> { show_binding_warning(config.gateway.listening_address); } - let node_details = node_details(&config)?; + let node_details = node_details(&config).await?; let gateway = crate::node::create_gateway(config, Some(nr_opts), Some(ip_opts), custom_mixnet).await?; eprintln!( diff --git a/gateway/src/node/helpers.rs b/gateway/src/node/helpers.rs index b6765cc7bb..3e2d54417a 100644 --- a/gateway/src/node/helpers.rs +++ b/gateway/src/node/helpers.rs @@ -23,7 +23,9 @@ fn display_path<P: AsRef<Path>>(path: P) -> String { path.as_ref().display().to_string() } -pub(crate) fn node_details(config: &Config) -> Result<GatewayNodeDetailsResponse, GatewayError> { +pub(crate) async fn node_details( + config: &Config, +) -> Result<GatewayNodeDetailsResponse, GatewayError> { let gateway_identity_public_key: identity::PublicKey = load_public_key( &config.storage_paths.keys.public_identity_key_file, "gateway identity", @@ -36,7 +38,7 @@ pub(crate) fn node_details(config: &Config) -> Result<GatewayNodeDetailsResponse let network_requester = if let Some(nr_cfg_path) = &config.storage_paths.network_requester_config { - let cfg = load_network_requester_config(&config.gateway.id, nr_cfg_path)?; + let cfg = load_network_requester_config(&config.gateway.id, nr_cfg_path).await?; let nr_identity_public_key: identity::PublicKey = load_public_key( &cfg.storage_paths.common_paths.keys.public_identity_key_file, @@ -75,7 +77,7 @@ pub(crate) fn node_details(config: &Config) -> Result<GatewayNodeDetailsResponse let ip_packet_router = if let Some(nr_cfg_path) = &config.storage_paths.ip_packet_router_config { - let cfg = load_ip_packet_router_config(&config.gateway.id, nr_cfg_path)?; + let cfg = load_ip_packet_router_config(&config.gateway.id, nr_cfg_path).await?; let nr_identity_public_key: identity::PublicKey = load_public_key( &cfg.storage_paths.common_paths.keys.public_identity_key_file, @@ -120,7 +122,33 @@ pub(crate) fn node_details(config: &Config) -> Result<GatewayNodeDetailsResponse }) } -pub(crate) fn load_network_requester_config<P: AsRef<Path>>( +pub(crate) async fn load_network_requester_config<P: AsRef<Path>>( + id: &str, + path: P, +) -> Result<nym_network_requester::Config, GatewayError> { + let path = path.as_ref(); + if let Ok(cfg) = read_network_requester_config(id, path) { + return Ok(cfg); + } + + nym_network_requester::config::helpers::try_upgrade_config(path).await?; + read_network_requester_config(id, path) +} + +pub(crate) async fn load_ip_packet_router_config<P: AsRef<Path>>( + id: &str, + path: P, +) -> Result<nym_ip_packet_router::Config, GatewayError> { + let path = path.as_ref(); + if let Ok(cfg) = read_ip_packet_router_config(id, path) { + return Ok(cfg); + } + + nym_ip_packet_router::config::helpers::try_upgrade_config(path).await?; + read_ip_packet_router_config(id, path) +} + +fn read_network_requester_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_network_requester::Config, GatewayError> { @@ -134,7 +162,7 @@ pub(crate) fn load_network_requester_config<P: AsRef<Path>>( }) } -pub(crate) fn load_ip_packet_router_config<P: AsRef<Path>>( +fn read_ip_packet_router_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_ip_packet_router::Config, GatewayError> { diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 30e1302d1a..26ad47b689 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -62,7 +62,7 @@ pub(crate) async fn create_gateway( // don't attempt to read config if NR is disabled let network_requester_config = if config.network_requester.enabled { if let Some(path) = &config.storage_paths.network_requester_config { - let cfg = load_network_requester_config(&config.gateway.id, path)?; + let cfg = load_network_requester_config(&config.gateway.id, path).await?; Some(override_network_requester_config(cfg, nr_config_override)) } else { // if NR is enabled, the config path must be specified @@ -75,7 +75,7 @@ pub(crate) async fn create_gateway( // don't attempt to read config if NR is disabled let ip_packet_router_config = if config.ip_packet_router.enabled { if let Some(path) = &config.storage_paths.ip_packet_router_config { - let cfg = load_ip_packet_router_config(&config.gateway.id, path)?; + let cfg = load_ip_packet_router_config(&config.gateway.id, path).await?; Some(override_ip_packet_router_config(cfg, ip_config_override)) } else { // if IPR is enabled, the config path must be specified diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index dc04d7e3cb..912c13cc7a 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -1,11 +1,10 @@ use clap::{CommandFactory, Parser, Subcommand}; -use log::{error, info, trace}; +use log::error; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::{bin_info, version_checker}; use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; -use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; -use nym_ip_packet_router::config::old_config_v1::ConfigV1; +use nym_ip_packet_router::config::helpers::try_upgrade_config; use nym_ip_packet_router::config::{BaseClientConfig, Config}; use nym_ip_packet_router::error::IpPacketRouterError; use std::sync::OnceLock; @@ -136,40 +135,6 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Ok(()) } -async fn try_upgrade_v1_config(id: &str) -> Result<bool, IpPacketRouterError> { - // explicitly load it as v1 (which is incompatible with the current one) - let Ok(old_config) = ConfigV1::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using v1 config template."); - info!("It is going to get updated to the current specification."); - - let old_paths = old_config.storage_paths.clone(); - let updated = old_config.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - None, - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_config(id: &str) -> Result<(), IpPacketRouterError> { - trace!("Attempting to upgrade config"); - - if try_upgrade_v1_config(id).await? { - return Ok(()); - } - - Ok(()) -} - async fn try_load_current_config(id: &str) -> Result<Config, IpPacketRouterError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { diff --git a/service-providers/ip-packet-router/src/config/helpers.rs b/service-providers/ip-packet-router/src/config/helpers.rs new file mode 100644 index 0000000000..5c965e8951 --- /dev/null +++ b/service-providers/ip-packet-router/src/config/helpers.rs @@ -0,0 +1,48 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::default_config_filepath; +use crate::config::old_config_v1::ConfigV1; +use crate::error::IpPacketRouterError; +use log::{info, trace}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; +use std::path::Path; + +async fn try_upgrade_v1_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, IpPacketRouterError> { + // explicitly load it as v1 (which is incompatible with the current one) + let Ok(old_config) = ConfigV1::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using v1 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +pub async fn try_upgrade_config<P: AsRef<Path>>(config_path: P) -> Result<(), IpPacketRouterError> { + trace!("Attempting to upgrade config"); + if try_upgrade_v1_config(config_path).await? { + return Ok(()); + } + + Ok(()) +} + +pub async fn try_upgrade_config_by_id(id: &str) -> Result<(), IpPacketRouterError> { + try_upgrade_config(default_config_filepath(id)).await +} diff --git a/service-providers/ip-packet-router/src/config/mod.rs b/service-providers/ip-packet-router/src/config/mod.rs index 88f6b32e68..048fcd67f8 100644 --- a/service-providers/ip-packet-router/src/config/mod.rs +++ b/service-providers/ip-packet-router/src/config/mod.rs @@ -20,6 +20,7 @@ use crate::config::persistence::IpPacketRouterPaths; use self::template::CONFIG_TEMPLATE; +pub mod helpers; pub mod old_config_v1; mod persistence; mod template; diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 29057aa523..7ba2462c61 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -1,22 +1,18 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::old_config_v1_1_13::OldConfigV1_1_13; -use crate::config::old_config_v1_1_20::ConfigV1_1_20; -use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; -use crate::config::old_config_v1_1_33::ConfigV1_1_33; +use crate::config::helpers::try_upgrade_config_by_id; use crate::{ config::{BaseClientConfig, Config}, error::NetworkRequesterError, }; use clap::{CommandFactory, Parser, Subcommand}; -use log::{error, info, trace}; +use log::error; use nym_bin_common::bin_info; use nym_bin_common::completions::{fig_generate, ArgShell}; use nym_bin_common::version_checker; use nym_client_core::cli_helpers::client_import_credential::CommonClientImportCredentialArgs; use nym_client_core::cli_helpers::CliClient; -use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use nym_config::OptionalSet; use std::sync::OnceLock; @@ -36,7 +32,7 @@ impl CliClient for CliNetworkRequesterClient { type Config = Config; async fn try_upgrade_outdated_config(id: &str) -> Result<(), Self::Error> { - try_upgrade_config(id).await + try_upgrade_config_by_id(id).await } async fn try_load_current_config(id: &str) -> Result<Self::Config, Self::Error> { @@ -190,135 +186,6 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Ok(()) } -async fn try_upgrade_v1_1_13_config(id: &str) -> Result<bool, NetworkRequesterError> { - trace!("Trying to load as v1.1.13 config"); - use nym_config::legacy_helpers::nym_config::MigrationNymConfig; - - // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) - let Ok(old_config) = OldConfigV1_1_13::load_from_file(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.13 config template."); - info!("It is going to get updated to the current specification."); - - let updated_step1: ConfigV1_1_20 = old_config.into(); - let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); - let (updated_step3, gateway_config) = updated_step2.upgrade()?; - let old_paths = updated_step3.storage_paths.clone(); - let updated = updated_step3.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, NetworkRequesterError> { - trace!("Trying to load as v1.1.20 config"); - use nym_config::legacy_helpers::nym_config::MigrationNymConfig; - - // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20::load_from_file(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - - info!("It seems the client is using <= v1.1.20 config template."); - info!("It is going to get updated to the current specification."); - - let updated_step1: ConfigV1_1_20_2 = old_config.into(); - let (updated_step2, gateway_config) = updated_step1.upgrade()?; - let old_paths = updated_step2.storage_paths.clone(); - let updated = updated_step2.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_20_2_config(id: &str) -> Result<bool, NetworkRequesterError> { - trace!("Trying to load as v1.1.20_2 config"); - - // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20_2::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.20_2 config template."); - info!("It is going to get updated to the current specification."); - - let (updated_step1, gateway_config) = old_config.upgrade()?; - let old_paths = updated_step1.storage_paths.clone(); - let updated = updated_step1.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - Some(gateway_config), - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_v1_1_33_config(id: &str) -> Result<bool, NetworkRequesterError> { - // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) - let Ok(old_config) = ConfigV1_1_33::read_from_default_path(id) else { - // if we failed to load it, there might have been nothing to upgrade - // or maybe it was an even older file. in either way. just ignore it and carry on with our day - return Ok(false); - }; - info!("It seems the client is using <= v1.1.33 config template."); - info!("It is going to get updated to the current specification."); - - let old_paths = old_config.storage_paths.clone(); - let updated = old_config.try_upgrade()?; - - v1_1_33::migrate_gateway_details( - &old_paths.common_paths, - &updated.storage_paths.common_paths, - None, - ) - .await?; - - updated.save_to_default_location()?; - Ok(true) -} - -async fn try_upgrade_config(id: &str) -> Result<(), NetworkRequesterError> { - trace!("Attempting to upgrade config"); - if try_upgrade_v1_1_13_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_20_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_20_2_config(id).await? { - return Ok(()); - } - if try_upgrade_v1_1_33_config(id).await? { - return Ok(()); - } - - Ok(()) -} - async fn try_load_current_config(id: &str) -> Result<Config, NetworkRequesterError> { // try to load the config as is if let Ok(cfg) = Config::read_from_default_path(id) { @@ -330,7 +197,7 @@ async fn try_load_current_config(id: &str) -> Result<Config, NetworkRequesterErr } // we couldn't load it - try upgrading it from older revisions - try_upgrade_config(id).await?; + try_upgrade_config_by_id(id).await?; let config = match Config::read_from_default_path(id) { Ok(cfg) => cfg, diff --git a/service-providers/network-requester/src/config/helpers.rs b/service-providers/network-requester/src/config/helpers.rs new file mode 100644 index 0000000000..5ef027d078 --- /dev/null +++ b/service-providers/network-requester/src/config/helpers.rs @@ -0,0 +1,155 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::default_config_filepath; +use crate::config::old_config_v1_1_13::OldConfigV1_1_13; +use crate::config::old_config_v1_1_20::ConfigV1_1_20; +use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; +use crate::config::old_config_v1_1_33::ConfigV1_1_33; +use crate::error::NetworkRequesterError; +use log::{info, trace}; +use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; +use std::path::Path; + +async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, NetworkRequesterError> { + trace!("Trying to load as v1.1.13 config"); + use nym_config::legacy_helpers::nym_config::MigrationNymConfig; + + // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) + let Ok(old_config) = OldConfigV1_1_13::load_from_filepath(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.13 config template."); + info!("It is going to get updated to the current specification."); + + let updated_step1: ConfigV1_1_20 = old_config.into(); + let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); + let (updated_step3, gateway_config) = updated_step2.upgrade()?; + let old_paths = updated_step3.storage_paths.clone(); + let updated = updated_step3.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, NetworkRequesterError> { + trace!("Trying to load as v1.1.20 config"); + use nym_config::legacy_helpers::nym_config::MigrationNymConfig; + + // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) + let Ok(old_config) = ConfigV1_1_20::load_from_filepath(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + + info!("It seems the client is using <= v1.1.20 config template."); + info!("It is going to get updated to the current specification."); + + let updated_step1: ConfigV1_1_20_2 = old_config.into(); + let (updated_step2, gateway_config) = updated_step1.upgrade()?; + let old_paths = updated_step2.storage_paths.clone(); + let updated = updated_step2.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, NetworkRequesterError> { + trace!("Trying to load as v1.1.20_2 config"); + + // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) + let Ok(old_config) = ConfigV1_1_20_2::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.20_2 config template."); + info!("It is going to get updated to the current specification."); + + let (updated_step1, gateway_config) = old_config.upgrade()?; + let old_paths = updated_step1.storage_paths.clone(); + let updated = updated_step1.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + Some(gateway_config), + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, NetworkRequesterError> { + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) + let Ok(old_config) = ConfigV1_1_33::read_from_toml_file(config_path) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v1.1.33 config template."); + info!("It is going to get updated to the current specification."); + + let old_paths = old_config.storage_paths.clone(); + let updated = old_config.try_upgrade()?; + + v1_1_33::migrate_gateway_details( + &old_paths.common_paths, + &updated.storage_paths.common_paths, + None, + ) + .await?; + + updated.save_to_default_location()?; + Ok(true) +} + +pub async fn try_upgrade_config<P: AsRef<Path>>( + config_path: P, +) -> Result<(), NetworkRequesterError> { + trace!("Attempting to upgrade config"); + if try_upgrade_v1_1_13_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_20_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_20_2_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v1_1_33_config(config_path).await? { + return Ok(()); + } + + Ok(()) +} + +pub async fn try_upgrade_config_by_id(id: &str) -> Result<(), NetworkRequesterError> { + try_upgrade_config(default_config_filepath(id)).await +} diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index a45180b200..cba8253039 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -23,6 +23,7 @@ use url::Url; pub use nym_client_core::config::Config as BaseClientConfig; +pub mod helpers; pub mod old_config_v1_1_13; pub mod old_config_v1_1_20; pub mod old_config_v1_1_20_2; diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs index 642270911b..8fe4c90232 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs @@ -55,6 +55,7 @@ impl ConfigV1_1_20_2 { read_config_from_toml_file(path) } + #[allow(dead_code)] pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { Self::read_from_toml_file(default_config_filepath(id)) } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_33.rs b/service-providers/network-requester/src/config/old_config_v1_1_33.rs index b49bb514d1..e211256643 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_33.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_33.rs @@ -54,6 +54,7 @@ impl ConfigV1_1_33 { read_config_from_toml_file(path) } + #[allow(dead_code)] pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { Self::read_from_toml_file(default_config_filepath(id)) } From dcd3d80b246d2cd4ffd867af8abecd7fb2b838be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 11:55:28 +0000 Subject: [PATCH 325/394] fixed post-rebasing clippy issues --- Cargo.lock | 145 +++++++++++++----- .../cli_helpers/client_import_credential.rs | 1 + nym-connect/desktop/Cargo.lock | 30 +++- 3 files changed, 133 insertions(+), 43 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 95910fc24b..c809facc92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -557,9 +557,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "itoa", "matchit", "memchr", @@ -587,8 +587,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "mime", "rustversion", "tower-layer", @@ -3011,7 +3011,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 0.2.9", "js-sys", "pin-project", "serde", @@ -3080,7 +3080,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.9", "indexmap 1.9.3", "slab", "tokio", @@ -3290,6 +3290,17 @@ 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-api-client" version = "0.1.0" @@ -3311,7 +3322,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.9", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite 0.2.13", ] @@ -3379,8 +3413,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -3392,6 +3426,25 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite 0.2.13", + "smallvec", + "tokio", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -3399,8 +3452,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", @@ -3412,12 +3465,28 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.27", "pin-project-lite 0.2.13", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite 0.2.13", + "socket2 0.5.4", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -3742,7 +3811,7 @@ dependencies = [ "curl-sys", "event-listener", "futures-lite", - "http", + "http 0.2.9", "log", "once_cell", "polling", @@ -4555,7 +4624,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.9", "httparse", "log", "memchr", @@ -5191,7 +5260,10 @@ dependencies = [ "clap 4.4.7", "futures", "gloo-timers", + "http-body-util", "humantime-serde", + "hyper 1.2.0", + "hyper-util", "log", "nym-bandwidth-controller", "nym-client-core-gateways-storage", @@ -5203,6 +5275,7 @@ dependencies = [ "nym-gateway-client", "nym-gateway-requests", "nym-id", + "nym-metrics", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", @@ -5548,7 +5621,7 @@ dependencies = [ "dotenvy", "futures", "humantime-serde", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "log", "nym-api-requests", @@ -5754,7 +5827,6 @@ dependencies = [ "lazy_static", "log", "prometheus", - "regex", ] [[package]] @@ -5985,7 +6057,7 @@ dependencies = [ "dashmap", "fastrand 2.0.1", "hmac 0.12.1", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "mime", "nym-config", @@ -6138,7 +6210,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http", + "http 0.2.9", "httpcodec", "libp2p", "log", @@ -6878,7 +6950,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906" dependencies = [ "async-trait", "bytes", - "http", + "http 0.2.9", "isahc", "opentelemetry_api", ] @@ -6892,7 +6964,7 @@ dependencies = [ "async-trait", "futures", "futures-executor", - "http", + "http 0.2.9", "isahc", "once_cell", "opentelemetry", @@ -8073,9 +8145,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "ipnet", "js-sys", @@ -8234,7 +8306,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ - "http", + "http 0.2.9", "log", "regex", "rocket", @@ -8254,8 +8326,8 @@ dependencies = [ "cookie", "either", "futures", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "indexmap 2.0.2", "log", "memchr", @@ -9059,9 +9131,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "snafu" @@ -9910,7 +9982,10 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", + "rustls 0.21.10", + "rustls-native-certs", "tokio", + "tokio-rustls 0.24.1", "tungstenite", ] @@ -10013,9 +10088,9 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-timeout", "percent-encoding", "pin-project", @@ -10058,8 +10133,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "http-range-header", "httpdate", "mime", @@ -10337,7 +10412,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.9", "httparse", "log", "rand 0.8.5", diff --git a/common/client-core/src/cli_helpers/client_import_credential.rs b/common/client-core/src/cli_helpers/client_import_credential.rs index 55d005975a..48468771da 100644 --- a/common/client-core/src/cli_helpers/client_import_credential.rs +++ b/common/client-core/src/cli_helpers/client_import_credential.rs @@ -5,6 +5,7 @@ use crate::cli_helpers::{CliClient, CliClientConfig}; use std::fs; use std::path::PathBuf; +#[cfg(feature = "cli")] fn parse_encoded_credential_data(raw: &str) -> bs58::decode::Result<Vec<u8>> { bs58::decode(raw).into_vec() } diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index afbc2f403f..3f3c7fd428 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2844,6 +2844,20 @@ dependencies = [ "itoa 1.0.9", ] +[[package]] +name = "http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "http-body" version = "0.4.5" @@ -3804,6 +3818,7 @@ version = "1.1.15" dependencies = [ "async-trait", "base64 0.21.4", + "bs58 0.5.0", "cfg-if", "futures", "gloo-timers", @@ -3821,6 +3836,7 @@ dependencies = [ "nym-explorer-client", "nym-gateway-client", "nym-gateway-requests", + "nym-id", "nym-metrics", "nym-network-defaults", "nym-nonexhaustive-delayqueue", @@ -4196,17 +4212,15 @@ dependencies = [ ] [[package]] -name = "nym-http-api-client" +name = "nym-id" version = "0.1.0" dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", + "nym-credential-storage", + "nym-credentials", "thiserror", + "time", "tracing", - "url", - "wasmtimer", + "zeroize", ] [[package]] @@ -4622,6 +4636,7 @@ dependencies = [ "eyre", "flate2", "futures", + "http-api-client", "itertools", "log", "nym-api-requests", @@ -4632,7 +4647,6 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", - "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", From b8ab07020c4495bb098a925ac09f5277031a150f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 14:26:45 +0000 Subject: [PATCH 326/394] fixed eda61b57dc8d349a9b0af70cbd02743eba1e10bf --- .../ip-packet-router/src/config/helpers.rs | 5 +++-- .../network-requester/src/config/helpers.rs | 19 +++++++++++-------- .../src/config/old_config_v1_1_33.rs | 1 + 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/service-providers/ip-packet-router/src/config/helpers.rs b/service-providers/ip-packet-router/src/config/helpers.rs index 5c965e8951..e6abda1d98 100644 --- a/service-providers/ip-packet-router/src/config/helpers.rs +++ b/service-providers/ip-packet-router/src/config/helpers.rs @@ -5,6 +5,7 @@ use crate::config::default_config_filepath; use crate::config::old_config_v1::ConfigV1; use crate::error::IpPacketRouterError; use log::{info, trace}; +use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use std::path::Path; @@ -12,7 +13,7 @@ async fn try_upgrade_v1_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, IpPacketRouterError> { // explicitly load it as v1 (which is incompatible with the current one) - let Ok(old_config) = ConfigV1::read_from_toml_file(config_path) else { + let Ok(old_config) = ConfigV1::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -30,7 +31,7 @@ async fn try_upgrade_v1_config<P: AsRef<Path>>( ) .await?; - updated.save_to_default_location()?; + updated.save_to(config_path)?; Ok(true) } diff --git a/service-providers/network-requester/src/config/helpers.rs b/service-providers/network-requester/src/config/helpers.rs index 5ef027d078..e03281fa01 100644 --- a/service-providers/network-requester/src/config/helpers.rs +++ b/service-providers/network-requester/src/config/helpers.rs @@ -8,6 +8,7 @@ use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; use crate::config::old_config_v1_1_33::ConfigV1_1_33; use crate::error::NetworkRequesterError; use log::{info, trace}; +use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use std::path::Path; @@ -18,7 +19,7 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) - let Ok(old_config) = OldConfigV1_1_13::load_from_filepath(config_path) else { + let Ok(old_config) = OldConfigV1_1_13::load_from_filepath(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -39,7 +40,7 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( ) .await?; - updated.save_to_default_location()?; + updated.save_to(config_path)?; Ok(true) } @@ -50,7 +51,7 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20::load_from_filepath(config_path) else { + let Ok(old_config) = ConfigV1_1_20::load_from_filepath(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -71,7 +72,7 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( ) .await?; - updated.save_to_default_location()?; + updated.save_to(config_path)?; Ok(true) } @@ -81,7 +82,7 @@ async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( trace!("Trying to load as v1.1.20_2 config"); // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20_2::read_from_toml_file(config_path) else { + let Ok(old_config) = ConfigV1_1_20_2::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -100,15 +101,17 @@ async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( ) .await?; - updated.save_to_default_location()?; + updated.save_to(config_path)?; Ok(true) } async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, NetworkRequesterError> { + trace!("Trying to load as v1.1.33 config"); + // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) - let Ok(old_config) = ConfigV1_1_33::read_from_toml_file(config_path) else { + let Ok(old_config) = ConfigV1_1_33::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -126,7 +129,7 @@ async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( ) .await?; - updated.save_to_default_location()?; + updated.save_to(config_path)?; Ok(true) } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_33.rs b/service-providers/network-requester/src/config/old_config_v1_1_33.rs index e211256643..b3089b036f 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_33.rs +++ b/service-providers/network-requester/src/config/old_config_v1_1_33.rs @@ -36,6 +36,7 @@ pub struct NetworkRequesterPathsV1_1_33 { #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct ConfigV1_1_33 { + #[serde(flatten)] pub base: BaseConfigV1_1_33, #[serde(default)] From ff499869d33b6f297860f76f5ae2d2ce3ced1809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 14:39:53 +0000 Subject: [PATCH 327/394] clippy --- service-providers/network-requester/src/config/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index cba8253039..53cdc143f4 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -135,6 +135,7 @@ impl Config { default_config_filepath(&self.base.client.id) } + #[allow(dead_code)] pub fn save_to_default_location(&self) -> io::Result<()> { let config_save_location: PathBuf = self.default_location(); save_formatted_config_to_file(self, config_save_location) From 74d03bfb3b9608ea83cd6dcd75758e004e3458cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 27 Mar 2024 14:01:48 +0000 Subject: [PATCH 328/394] moved for adding new gateways to separate command and made client init only first time setup related --- clients/native/src/commands/add_gateway.rs | 30 +++ clients/native/src/commands/mod.rs | 5 + clients/socks5/src/commands/add_gateway.rs | 30 +++ clients/socks5/src/commands/mod.rs | 5 + .../src/cli_helpers/client_add_gateway.rs | 174 ++++++++++++++++++ .../src/cli_helpers/client_init.rs | 108 +++-------- .../src/cli_helpers/client_list_gateways.rs | 36 +--- common/client-core/src/cli_helpers/mod.rs | 2 + common/client-core/src/cli_helpers/types.rs | 40 ++++ common/client-core/src/error.rs | 3 + .../mixnet-contract/src/nym_node.rs | 13 ++ .../ip-packet-router/src/cli/add_gateway.rs | 32 ++++ .../ip-packet-router/src/cli/mod.rs | 5 + .../network-requester/src/cli/add_gateway.rs | 32 ++++ .../network-requester/src/cli/mod.rs | 5 + 15 files changed, 402 insertions(+), 118 deletions(-) create mode 100644 clients/native/src/commands/add_gateway.rs create mode 100644 clients/socks5/src/commands/add_gateway.rs create mode 100644 common/client-core/src/cli_helpers/client_add_gateway.rs create mode 100644 common/client-core/src/cli_helpers/types.rs create mode 100644 common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs create mode 100644 service-providers/ip-packet-router/src/cli/add_gateway.rs create mode 100644 service-providers/network-requester/src/cli/add_gateway.rs diff --git a/clients/native/src/commands/add_gateway.rs b/clients/native/src/commands/add_gateway.rs new file mode 100644 index 0000000000..254839af04 --- /dev/null +++ b/clients/native/src/commands/add_gateway.rs @@ -0,0 +1,30 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliNativeClient; +use crate::error::ClientError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_add_gateway::{add_gateway, CommonClientAddGatewayArgs}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientAddGatewayArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientAddGatewayArgs> for Args { + fn as_ref(&self) -> &CommonClientAddGatewayArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), ClientError> { + let output = args.output; + let res = add_gateway::<CliNativeClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/clients/native/src/commands/mod.rs b/clients/native/src/commands/mod.rs index 9c7c016580..3f8e86e94f 100644 --- a/clients/native/src/commands/mod.rs +++ b/clients/native/src/commands/mod.rs @@ -20,6 +20,7 @@ use std::error::Error; use std::net::IpAddr; use std::sync::OnceLock; +mod add_gateway; pub(crate) mod build_info; pub(crate) mod import_credential; pub(crate) mod init; @@ -77,6 +78,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Add new gateway to this client + AddGateway(add_gateway::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! SwitchGateway(switch_gateway::Args), @@ -110,6 +114,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::AddGateway(args) => add_gateway::execute(args).await?, Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), diff --git a/clients/socks5/src/commands/add_gateway.rs b/clients/socks5/src/commands/add_gateway.rs new file mode 100644 index 0000000000..fb7b645619 --- /dev/null +++ b/clients/socks5/src/commands/add_gateway.rs @@ -0,0 +1,30 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::commands::CliSocks5Client; +use crate::error::Socks5ClientError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_add_gateway::{add_gateway, CommonClientAddGatewayArgs}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientAddGatewayArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientAddGatewayArgs> for Args { + fn as_ref(&self) -> &CommonClientAddGatewayArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), Socks5ClientError> { + let output = args.output; + let res = add_gateway::<CliSocks5Client, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/clients/socks5/src/commands/mod.rs b/clients/socks5/src/commands/mod.rs index d982b86a9e..961c6551e5 100644 --- a/clients/socks5/src/commands/mod.rs +++ b/clients/socks5/src/commands/mod.rs @@ -24,6 +24,7 @@ use std::error::Error; use std::net::IpAddr; use std::sync::OnceLock; +mod add_gateway; pub(crate) mod build_info; mod import_credential; pub mod init; @@ -81,6 +82,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Add new gateway to this client + AddGateway(add_gateway::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! SwitchGateway(switch_gateway::Args), @@ -117,6 +121,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), Box<dyn Error + Send + Sync Commands::Run(m) => run::execute(m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::AddGateway(args) => add_gateway::execute(args).await?, Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), diff --git a/common/client-core/src/cli_helpers/client_add_gateway.rs b/common/client-core/src/cli_helpers/client_add_gateway.rs new file mode 100644 index 0000000000..afcb236ec7 --- /dev/null +++ b/common/client-core/src/cli_helpers/client_add_gateway.rs @@ -0,0 +1,174 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli_helpers::types::GatewayInfo; +use crate::cli_helpers::{CliClient, CliClientConfig}; +use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; +use crate::{ + client::{ + base_client::storage::helpers::{get_all_registered_identities, set_active_gateway}, + key_manager::persistence::OnDiskKeys, + }, + error::ClientCoreError, + init::types::{GatewaySelectionSpecification, GatewaySetup}, +}; +use log::info; +use nym_client_core_gateways_storage::GatewayDetails; +use nym_crypto::asymmetric::identity; +use nym_topology::NymTopology; +use std::path::PathBuf; + +#[cfg_attr(feature = "cli", derive(clap::Args))] +#[derive(Debug, Clone)] +pub struct CommonClientAddGatewayArgs { + /// Id of client we want to add gateway for. + #[cfg_attr(feature = "cli", clap(long))] + pub id: String, + + /// Explicitly specify id of the gateway to register with. + /// If unspecified, a random gateway will be chosen instead. + #[cfg_attr(feature = "cli", clap(long))] + pub gateway: Option<identity::PublicKey>, + + /// Specifies whether the client will attempt to enforce tls connection to the desired gateway. + #[cfg_attr(feature = "cli", clap(long))] + pub force_tls_gateway: bool, + + /// Specifies whether the new gateway should be determined based by latency as opposed to being chosen + /// uniformly. + #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))] + pub latency_based_selection: bool, + + /// Force register gateway. WARNING: this will overwrite any existing keys for the given id, + /// potentially causing loss of access. + #[cfg_attr(feature = "cli", clap(long))] + pub force_register_gateway: bool, + + /// Specify whether this new gateway should be set as the active one + #[cfg_attr(feature = "cli", clap(long, default_value_t = true))] + pub set_active: bool, + + /// Comma separated list of rest endpoints of the API validators + #[cfg_attr( + feature = "cli", + clap( + long, + alias = "api_validators", + value_delimiter = ',', + group = "network" + ) + )] + pub nym_apis: Option<Vec<url::Url>>, + + /// Path to .json file containing custom network specification. + #[cfg_attr(feature = "cli", clap(long, group = "network", hide = true))] + pub custom_mixnet: Option<PathBuf>, +} + +pub async fn add_gateway<C, A>(args: A) -> Result<GatewayInfo, C::Error> +where + A: AsRef<CommonClientAddGatewayArgs>, + C: CliClient, +{ + let common_args = args.as_ref(); + let id = &common_args.id; + + let config = C::try_load_current_config(id).await?; + let core = config.core_config(); + let paths = config.common_paths(); + + let key_store = OnDiskKeys::new(paths.keys.clone()); + let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; + + let user_wants_force_register = common_args.force_register_gateway; + if user_wants_force_register { + eprintln!("Instructed to force registering gateway. This might overwrite keys!"); + } + + // Attempt to use a user-provided gateway, if possible + let user_chosen_gateway_id = common_args.gateway; + log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); + + let selection_spec = GatewaySelectionSpecification::new( + user_chosen_gateway_id.map(|id| id.to_base58_string()), + Some(common_args.latency_based_selection), + common_args.force_tls_gateway, + ); + log::debug!("Gateway selection specification: {selection_spec:?}"); + + let registered_gateways = get_all_registered_identities(&details_store).await?; + + // if user provided gateway id (and we can't overwrite data), make sure we're not trying to register + // with a known gateway + if let Some(user_chosen) = user_chosen_gateway_id { + if !common_args.force_register_gateway && registered_gateways.contains(&user_chosen) { + return Err(ClientCoreError::AlreadyRegistered { + gateway_id: user_chosen.to_base58_string(), + } + .into()); + } + } + + // Setup gateway by either registering a new one, or creating a new config from the selected + // one but with keys kept, or reusing the gateway configuration. + let available_gateways = if let Some(custom_mixnet) = common_args.custom_mixnet.as_ref() { + let hardcoded_topology = NymTopology::new_from_file(custom_mixnet).map_err(|source| { + ClientCoreError::CustomTopologyLoadFailure { + file_path: custom_mixnet.clone(), + source, + } + })?; + hardcoded_topology.get_gateways() + } else { + let mut rng = rand::thread_rng(); + crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? + }; + + // since we're registering with a brand new gateway, + // make sure the list of available gateways doesn't overlap the list of known gateways + let available_gateways = if common_args.force_register_gateway { + // if we're force registering, all bets are off + available_gateways + } else { + available_gateways + .into_iter() + .filter(|g| !registered_gateways.contains(g.identity())) + .collect() + }; + + let gateway_setup = GatewaySetup::New { + specification: selection_spec, + available_gateways, + overwrite_data: common_args.force_register_gateway, + wg_tun_address: None, + }; + + let init_details = + crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; + + let address = init_details.client_address(); + + let gateway_registration = init_details.gateway_registration; + let GatewayDetails::Remote(ref gateway_details) = gateway_registration.details else { + return Err(ClientCoreError::UnexpectedPersistedCustomGatewayDetails)?; + }; + + if common_args.set_active { + set_active_gateway( + &details_store, + &gateway_details.gateway_id.to_base58_string(), + ) + .await?; + } else { + info!("registered with new gateway {} (under address {address}), but this will not be our default address", gateway_details.gateway_id); + } + + Ok(GatewayInfo { + registration: gateway_registration.registration_timestamp, + identity: gateway_details.gateway_id, + active: common_args.set_active, + typ: gateway_registration.details.typ().to_string(), + endpoint: Some(gateway_details.gateway_listener.clone()), + wg_tun_address: gateway_details.wg_tun_address.clone(), + }) +} diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index 1d83302210..f765117d35 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -6,8 +6,7 @@ use crate::error::ClientCoreError; use crate::{ client::{ base_client::{ - non_wasm_helpers::setup_fs_gateways_storage, - storage::helpers::{get_all_registered_identities, set_active_gateway}, + non_wasm_helpers::setup_fs_gateways_storage, storage::helpers::set_active_gateway, }, key_manager::persistence::OnDiskKeys, }, @@ -52,16 +51,6 @@ pub struct CommonClientInitArgs { #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))] pub latency_based_selection: bool, - /// Force register gateway. WARNING: this will overwrite any existing keys for the given id, - /// potentially causing loss of access. - #[cfg_attr(feature = "cli", clap(long))] - pub force_register_gateway: bool, - - /// If the registration is happening against new gateway, - /// specify whether it should be set as the currently active gateway - #[cfg_attr(feature = "cli", clap(long, default_value_t = true))] - pub set_active: bool, - /// Comma separated list of rest endpoints of the nyxd validators #[cfg_attr( feature = "cli", @@ -118,28 +107,16 @@ where let common_args = init_args.as_ref(); let id = &common_args.id; - let already_init = if C::default_config_path(id).exists() { - // in case we're using old config, try to upgrade it - // (if we're using the current version, it's a no-op) - C::try_upgrade_outdated_config(id).await?; + if C::default_config_path(id).exists() { eprintln!("{} client \"{id}\" was already initialised before", C::NAME); - true - } else { - info!( - "{} client {id:?} hasn't been initialised before - new keys are going to be generated", - C::NAME - ); - C::initialise_storage_paths(id)?; - false - }; - - // Usually you only register with the gateway on the first init, however you can force - // re-registering if wanted. - let user_wants_force_register = common_args.force_register_gateway; - if user_wants_force_register { - eprintln!("Instructed to force registering gateway. This might overwrite keys!"); + return Err(ClientCoreError::AlreadyInitialised { + client_id: id.to_string(), + } + .into()); } + C::initialise_storage_paths(id)?; + // Attempt to use a user-provided gateway, if possible let user_chosen_gateway_id = common_args.gateway; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); @@ -171,24 +148,8 @@ where let key_store = OnDiskKeys::new(paths.keys.clone()); let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; - // if this is a first time client with this particular id is initialised, generated long-term keys - if !already_init { - let mut rng = OsRng; - crate::init::generate_new_client_keys(&mut rng, &key_store).await?; - } - - let registered_gateways = get_all_registered_identities(&details_store).await?; - - // if user provided gateway id (and we can't overwrite data), make sure we're not trying to register - // with a known gateway - if let Some(user_chosen) = user_chosen_gateway_id { - if !common_args.force_register_gateway && registered_gateways.contains(&user_chosen) { - return Err(ClientCoreError::AlreadyRegistered { - gateway_id: user_chosen.to_base58_string(), - } - .into()); - } - } + let mut rng = OsRng; + crate::init::generate_new_client_keys(&mut rng, &key_store).await?; // Setup gateway by either registering a new one, or creating a new config from the selected // one but with keys kept, or reusing the gateway configuration. @@ -205,22 +166,10 @@ where crate::init::helpers::current_gateways(&mut rng, &core.client.nym_api_urls).await? }; - // since we're registering with a brand new gateway, - // make sure the list of available gateways doesn't overlap the list of known gateways - let available_gateways = if common_args.force_register_gateway { - // if we're force registering, all bets are off - available_gateways - } else { - available_gateways - .into_iter() - .filter(|g| !registered_gateways.contains(g.identity())) - .collect() - }; - let gateway_setup = GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: common_args.force_register_gateway, + overwrite_data: false, wg_tun_address: None, }; @@ -228,25 +177,22 @@ where crate::init::setup_gateway(gateway_setup, &key_store, &details_store).await?; // TODO: ask the service provider we specified for its interface version and set it in the config - - if !already_init { - let config_save_location = config.default_store_location(); - if let Err(err) = config.save_to(&config_save_location) { - return Err(ClientCoreError::ConfigSaveFailure { - typ: C::NAME.to_string(), - id: id.to_string(), - path: config_save_location, - source: err, - } - .into()); + let config_save_location = config.default_store_location(); + if let Err(err) = config.save_to(&config_save_location) { + return Err(ClientCoreError::ConfigSaveFailure { + typ: C::NAME.to_string(), + id: id.to_string(), + path: config_save_location, + source: err, } - - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); + .into()); } + eprintln!( + "Saved configuration file to {}", + config_save_location.display() + ); + let address = init_details.client_address(); let GatewayDetails::Remote(gateway_details) = init_details.gateway_registration.details else { @@ -260,11 +206,7 @@ where init_details.gateway_registration.registration_timestamp, ); - if init_args.as_ref().set_active { - set_active_gateway(&details_store, &init_results.gateway_id).await?; - } else { - info!("registered with new gateway {} (under address {address}), but this will not be our default address", init_results.gateway_id); - } + set_active_gateway(&details_store, &init_results.gateway_id).await?; Ok(InitResultsWithConfig { config, diff --git a/common/client-core/src/cli_helpers/client_list_gateways.rs b/common/client-core/src/cli_helpers/client_list_gateways.rs index 641b29d16e..1bfcafb027 100644 --- a/common/client-core/src/cli_helpers/client_list_gateways.rs +++ b/common/client-core/src/cli_helpers/client_list_gateways.rs @@ -1,17 +1,15 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use super::types::GatewayInfo; use crate::cli_helpers::{CliClient, CliClientConfig}; use crate::client::base_client::non_wasm_helpers::setup_fs_gateways_storage; use crate::client::base_client::storage::helpers::{ get_active_gateway_identity, get_gateway_registrations, }; use nym_client_core_gateways_storage::{GatewayDetails, GatewayType}; -use nym_crypto::asymmetric::identity; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; -use time::OffsetDateTime; -use url::Url; #[cfg_attr(feature = "cli", derive(clap::Args))] #[derive(Debug, Clone)] @@ -34,38 +32,6 @@ impl Display for RegisteredGateways { } } -#[derive(Serialize, Deserialize)] -pub struct GatewayInfo { - pub registration: OffsetDateTime, - pub identity: identity::PublicKey, - pub active: bool, - - pub typ: String, - pub endpoint: Option<Url>, - pub wg_tun_address: Option<Url>, -} - -impl Display for GatewayInfo { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - if self.active { - write!(f, "[ACTIVE] ")?; - } - write!( - f, - "{} gateway '{}' registered at: {}", - self.typ, self.identity, self.registration - )?; - if let Some(endpoint) = &self.endpoint { - write!(f, " endpoint: {endpoint}")?; - } - - if let Some(wg_tun_address) = &self.wg_tun_address { - write!(f, " wg tun address: {wg_tun_address}")?; - } - Ok(()) - } -} - pub async fn list_gateways<C, A>(args: A) -> Result<RegisteredGateways, C::Error> where A: AsRef<CommonClientListGatewaysArgs>, diff --git a/common/client-core/src/cli_helpers/mod.rs b/common/client-core/src/cli_helpers/mod.rs index e2a018cb18..5ab51b8b4c 100644 --- a/common/client-core/src/cli_helpers/mod.rs +++ b/common/client-core/src/cli_helpers/mod.rs @@ -1,12 +1,14 @@ // Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +pub mod client_add_gateway; pub mod client_import_credential; pub mod client_init; pub mod client_list_gateways; pub mod client_run; pub mod client_switch_gateway; pub mod traits; +mod types; pub use client_init::InitialisableClient; pub use traits::{CliClient, CliClientConfig}; diff --git a/common/client-core/src/cli_helpers/types.rs b/common/client-core/src/cli_helpers/types.rs new file mode 100644 index 0000000000..4a351f38ef --- /dev/null +++ b/common/client-core/src/cli_helpers/types.rs @@ -0,0 +1,40 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_crypto::asymmetric::identity; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; +use time::OffsetDateTime; +use url::Url; + +#[derive(Serialize, Deserialize)] +pub struct GatewayInfo { + pub registration: OffsetDateTime, + pub identity: identity::PublicKey, + pub active: bool, + + pub typ: String, + pub endpoint: Option<Url>, + pub wg_tun_address: Option<Url>, +} + +impl Display for GatewayInfo { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + if self.active { + write!(f, "[ACTIVE] ")?; + } + write!( + f, + "{} gateway '{}' registered at: {}", + self.typ, self.identity, self.registration + )?; + if let Some(endpoint) = &self.endpoint { + write!(f, " endpoint: {endpoint}")?; + } + + if let Some(wg_tun_address) = &self.wg_tun_address { + write!(f, " wg tun address: {wg_tun_address}")?; + } + Ok(()) + } +} diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index d2d391f102..67382c468e 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -198,6 +198,9 @@ pub enum ClientCoreError { source: url::ParseError, }, + #[error("this client (id: '{client_id}') has already been initialised before. If you want to add additional gateway, use `add-gateway` command")] + AlreadyInitialised { client_id: String }, + #[error("this client has already registered with gateway {gateway_id}")] AlreadyRegistered { gateway_id: String }, } diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs new file mode 100644 index 0000000000..fcef40052d --- /dev/null +++ b/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs @@ -0,0 +1,13 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::IdentityKey; + +pub struct NymNode { + /// Network address of this mixnode, for example 1.1.1.1 or foo.nymnode.com + /// that will used for discovering other capabilities of this node. + pub host: String, + + /// Base58-encoded ed25519 EdDSA public key. + pub identity_key: IdentityKey, +} diff --git a/service-providers/ip-packet-router/src/cli/add_gateway.rs b/service-providers/ip-packet-router/src/cli/add_gateway.rs new file mode 100644 index 0000000000..3050233c87 --- /dev/null +++ b/service-providers/ip-packet-router/src/cli/add_gateway.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliIpPacketRouterClient; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; +use nym_ip_packet_router::error::IpPacketRouterError; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), IpPacketRouterError> { + let output = args.output; + let res = list_gateways::<CliIpPacketRouterClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/service-providers/ip-packet-router/src/cli/mod.rs b/service-providers/ip-packet-router/src/cli/mod.rs index 912c13cc7a..3de91de6be 100644 --- a/service-providers/ip-packet-router/src/cli/mod.rs +++ b/service-providers/ip-packet-router/src/cli/mod.rs @@ -9,6 +9,7 @@ use nym_ip_packet_router::config::{BaseClientConfig, Config}; use nym_ip_packet_router::error::IpPacketRouterError; use std::sync::OnceLock; +mod add_gateway; mod build_info; mod import_credential; mod init; @@ -69,6 +70,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Add new gateway to this client + AddGateway(add_gateway::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! SwitchGateway(switch_gateway::Args), @@ -126,6 +130,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), IpPacketRouterError> { Commands::Run(m) => run::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::AddGateway(args) => add_gateway::execute(args).await?, Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::Sign(m) => sign::execute(&m).await?, Commands::BuildInfo(m) => build_info::execute(m), diff --git a/service-providers/network-requester/src/cli/add_gateway.rs b/service-providers/network-requester/src/cli/add_gateway.rs new file mode 100644 index 0000000000..ec4703045b --- /dev/null +++ b/service-providers/network-requester/src/cli/add_gateway.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::cli::CliNetworkRequesterClient; +use crate::error::NetworkRequesterError; +use nym_bin_common::output_format::OutputFormat; +use nym_client_core::cli_helpers::client_list_gateways::{ + list_gateways, CommonClientListGatewaysArgs, +}; + +#[derive(clap::Args)] +pub(crate) struct Args { + #[command(flatten)] + common_args: CommonClientListGatewaysArgs, + + #[arg(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +impl AsRef<CommonClientListGatewaysArgs> for Args { + fn as_ref(&self) -> &CommonClientListGatewaysArgs { + &self.common_args + } +} + +pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { + let output = args.output; + let res = list_gateways::<CliNetworkRequesterClient, _>(args).await?; + + println!("{}", output.format(&res)); + Ok(()) +} diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 7ba2462c61..290c4b8980 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -16,6 +16,7 @@ use nym_client_core::cli_helpers::CliClient; use nym_config::OptionalSet; use std::sync::OnceLock; +mod add_gateway; mod build_info; mod import_credential; mod init; @@ -79,6 +80,9 @@ pub(crate) enum Commands { /// List all registered with gateways ListGateways(list_gateways::Args), + /// Add new gateway to this client + AddGateway(add_gateway::Args), + /// Change the currently active gateway. Note that you must have already registered with the new gateway! SwitchGateway(switch_gateway::Args), @@ -178,6 +182,7 @@ pub(crate) async fn execute(args: Cli) -> Result<(), NetworkRequesterError> { Commands::Sign(m) => sign::execute(&m).await?, Commands::ImportCredential(m) => import_credential::execute(m).await?, Commands::ListGateways(args) => list_gateways::execute(args).await?, + Commands::AddGateway(args) => add_gateway::execute(args).await?, Commands::SwitchGateway(args) => switch_gateway::execute(args).await?, Commands::BuildInfo(m) => build_info::execute(m), Commands::Completions(s) => s.generate(&mut Cli::command(), bin_name), From f012a1a069462e387b6f9109b7f6bead39f92f19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 27 Mar 2024 16:07:07 +0000 Subject: [PATCH 329/394] fixed add gateway commands for nr and ipr --- .../ip-packet-router/src/cli/add_gateway.rs | 12 +++++------- .../network-requester/src/cli/add_gateway.rs | 13 ++++++------- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/service-providers/ip-packet-router/src/cli/add_gateway.rs b/service-providers/ip-packet-router/src/cli/add_gateway.rs index 3050233c87..ebfffcf149 100644 --- a/service-providers/ip-packet-router/src/cli/add_gateway.rs +++ b/service-providers/ip-packet-router/src/cli/add_gateway.rs @@ -3,29 +3,27 @@ use crate::cli::CliIpPacketRouterClient; use nym_bin_common::output_format::OutputFormat; -use nym_client_core::cli_helpers::client_list_gateways::{ - list_gateways, CommonClientListGatewaysArgs, -}; +use nym_client_core::cli_helpers::client_add_gateway::{add_gateway, CommonClientAddGatewayArgs}; use nym_ip_packet_router::error::IpPacketRouterError; #[derive(clap::Args)] pub(crate) struct Args { #[command(flatten)] - common_args: CommonClientListGatewaysArgs, + common_args: CommonClientAddGatewayArgs, #[arg(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } -impl AsRef<CommonClientListGatewaysArgs> for Args { - fn as_ref(&self) -> &CommonClientListGatewaysArgs { +impl AsRef<CommonClientAddGatewayArgs> for Args { + fn as_ref(&self) -> &CommonClientAddGatewayArgs { &self.common_args } } pub(crate) async fn execute(args: Args) -> Result<(), IpPacketRouterError> { let output = args.output; - let res = list_gateways::<CliIpPacketRouterClient, _>(args).await?; + let res = add_gateway::<CliIpPacketRouterClient, _>(args).await?; println!("{}", output.format(&res)); Ok(()) diff --git a/service-providers/network-requester/src/cli/add_gateway.rs b/service-providers/network-requester/src/cli/add_gateway.rs index ec4703045b..8b4b102b34 100644 --- a/service-providers/network-requester/src/cli/add_gateway.rs +++ b/service-providers/network-requester/src/cli/add_gateway.rs @@ -4,28 +4,27 @@ use crate::cli::CliNetworkRequesterClient; use crate::error::NetworkRequesterError; use nym_bin_common::output_format::OutputFormat; -use nym_client_core::cli_helpers::client_list_gateways::{ - list_gateways, CommonClientListGatewaysArgs, -}; +use nym_client_core::cli_helpers::client_add_gateway::{add_gateway, CommonClientAddGatewayArgs}; + #[derive(clap::Args)] pub(crate) struct Args { #[command(flatten)] - common_args: CommonClientListGatewaysArgs, + common_args: CommonClientAddGatewayArgs, #[arg(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } -impl AsRef<CommonClientListGatewaysArgs> for Args { - fn as_ref(&self) -> &CommonClientListGatewaysArgs { +impl AsRef<CommonClientAddGatewayArgs> for Args { + fn as_ref(&self) -> &CommonClientAddGatewayArgs { &self.common_args } } pub(crate) async fn execute(args: Args) -> Result<(), NetworkRequesterError> { let output = args.output; - let res = list_gateways::<CliNetworkRequesterClient, _>(args).await?; + let res = add_gateway::<CliNetworkRequesterClient, _>(args).await?; println!("{}", output.format(&res)); Ok(()) From b869c309092922453fe5b1d195de222f8481e18b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 27 Mar 2024 16:07:43 +0000 Subject: [PATCH 330/394] added extra alias --- common/client-core/src/cli_helpers/client_add_gateway.rs | 6 +++--- service-providers/network-requester/src/cli/add_gateway.rs | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/common/client-core/src/cli_helpers/client_add_gateway.rs b/common/client-core/src/cli_helpers/client_add_gateway.rs index afcb236ec7..ba37d20523 100644 --- a/common/client-core/src/cli_helpers/client_add_gateway.rs +++ b/common/client-core/src/cli_helpers/client_add_gateway.rs @@ -27,8 +27,8 @@ pub struct CommonClientAddGatewayArgs { /// Explicitly specify id of the gateway to register with. /// If unspecified, a random gateway will be chosen instead. - #[cfg_attr(feature = "cli", clap(long))] - pub gateway: Option<identity::PublicKey>, + #[cfg_attr(feature = "cli", clap(long, alias = "gateway"))] + pub gateway_id: Option<identity::PublicKey>, /// Specifies whether the client will attempt to enforce tls connection to the desired gateway. #[cfg_attr(feature = "cli", clap(long))] @@ -86,7 +86,7 @@ where } // Attempt to use a user-provided gateway, if possible - let user_chosen_gateway_id = common_args.gateway; + let user_chosen_gateway_id = common_args.gateway_id; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); let selection_spec = GatewaySelectionSpecification::new( diff --git a/service-providers/network-requester/src/cli/add_gateway.rs b/service-providers/network-requester/src/cli/add_gateway.rs index 8b4b102b34..e07f16f46d 100644 --- a/service-providers/network-requester/src/cli/add_gateway.rs +++ b/service-providers/network-requester/src/cli/add_gateway.rs @@ -6,7 +6,6 @@ use crate::error::NetworkRequesterError; use nym_bin_common::output_format::OutputFormat; use nym_client_core::cli_helpers::client_add_gateway::{add_gateway, CommonClientAddGatewayArgs}; - #[derive(clap::Args)] pub(crate) struct Args { #[command(flatten)] From 8fa213502da054a7edc451ad2d0e4a017ae8be0e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 08:11:57 +0000 Subject: [PATCH 331/394] removed force register flag + improved error message on no gateways available --- Cargo.lock | 80 +++++++++---------- .../src/cli_helpers/client_add_gateway.rs | 30 +++---- .../src/cli_helpers/client_init.rs | 1 - common/client-core/src/error.rs | 3 + common/client-core/src/init/mod.rs | 7 +- common/client-core/src/init/types.rs | 6 +- common/wasm/client-core/src/helpers.rs | 1 - nym-connect/desktop/Cargo.lock | 30 +++---- .../desktop/src-tauri/src/config/mod.rs | 1 - sdk/lib/socks5-listener/src/lib.rs | 1 - sdk/rust/nym-sdk/src/mixnet/client.rs | 1 - 11 files changed, 70 insertions(+), 91 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c809facc92..ea89e7ec2a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -389,16 +389,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "async-file-watcher" -version = "0.1.0" -dependencies = [ - "futures", - "log", - "notify", - "tokio", -] - [[package]] name = "async-io" version = "1.13.0" @@ -3301,20 +3291,6 @@ dependencies = [ "itoa", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -3943,17 +3919,6 @@ version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" -[[package]] -name = "ledger" -version = "0.1.0" -dependencies = [ - "bip32", - "k256", - "ledger-transport", - "ledger-transport-hid", - "thiserror", -] - [[package]] name = "ledger-apdu" version = "0.10.0" @@ -4596,9 +4561,9 @@ version = "1.3.0-rc.0" dependencies = [ "async-trait", "futures", - "http-api-client", "js-sys", "nym-bin-common", + "nym-http-api-client", "nym-ordered-buffer", "nym-service-providers-common", "nym-socks5-requests", @@ -5073,6 +5038,16 @@ dependencies = [ "ts-rs", ] +[[package]] +name = "nym-async-file-watcher" +version = "0.1.0" +dependencies = [ + "futures", + "log", + "notify", + "tokio", +] + [[package]] name = "nym-bandwidth-controller" version = "0.1.0" @@ -5729,6 +5704,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-id" version = "0.1.0" @@ -5819,6 +5808,17 @@ dependencies = [ "url", ] +[[package]] +name = "nym-ledger" +version = "0.1.0" +dependencies = [ + "bip32", + "k256", + "ledger-transport", + "ledger-transport-hid", + "thiserror", +] + [[package]] name = "nym-metrics" version = "0.1.0" @@ -5983,7 +5983,6 @@ version = "1.1.33" dependencies = [ "addr", "anyhow", - "async-file-watcher", "async-trait", "bs58 0.5.0", "clap 4.4.7", @@ -5992,6 +5991,7 @@ dependencies = [ "humantime-serde", "ipnetwork 0.20.0", "log", + "nym-async-file-watcher", "nym-bin-common", "nym-client-core", "nym-client-websocket-requests", @@ -6086,10 +6086,10 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.4", - "http-api-client", "nym-bin-common", "nym-crypto", "nym-exit-policy", + "nym-http-api-client", "nym-wireguard-types", "schemars", "serde", @@ -6667,7 +6667,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools 0.10.5", "log", "nym-api-requests", @@ -6678,6 +6677,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -6803,7 +6803,6 @@ name = "nymvisor" version = "0.1.0" dependencies = [ "anyhow", - "async-file-watcher", "bytes", "clap 4.4.7", "dotenvy", @@ -6813,6 +6812,7 @@ dependencies = [ "humantime 2.1.0", "humantime-serde", "nix 0.27.1", + "nym-async-file-watcher", "nym-bin-common", "nym-config", "nym-task", diff --git a/common/client-core/src/cli_helpers/client_add_gateway.rs b/common/client-core/src/cli_helpers/client_add_gateway.rs index ba37d20523..f28cbabd59 100644 --- a/common/client-core/src/cli_helpers/client_add_gateway.rs +++ b/common/client-core/src/cli_helpers/client_add_gateway.rs @@ -39,11 +39,6 @@ pub struct CommonClientAddGatewayArgs { #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))] pub latency_based_selection: bool, - /// Force register gateway. WARNING: this will overwrite any existing keys for the given id, - /// potentially causing loss of access. - #[cfg_attr(feature = "cli", clap(long))] - pub force_register_gateway: bool, - /// Specify whether this new gateway should be set as the active one #[cfg_attr(feature = "cli", clap(long, default_value_t = true))] pub set_active: bool, @@ -80,11 +75,6 @@ where let key_store = OnDiskKeys::new(paths.keys.clone()); let details_store = setup_fs_gateways_storage(&paths.gateway_registrations).await?; - let user_wants_force_register = common_args.force_register_gateway; - if user_wants_force_register { - eprintln!("Instructed to force registering gateway. This might overwrite keys!"); - } - // Attempt to use a user-provided gateway, if possible let user_chosen_gateway_id = common_args.gateway_id; log::debug!("User chosen gateway id: {user_chosen_gateway_id:?}"); @@ -101,7 +91,7 @@ where // if user provided gateway id (and we can't overwrite data), make sure we're not trying to register // with a known gateway if let Some(user_chosen) = user_chosen_gateway_id { - if !common_args.force_register_gateway && registered_gateways.contains(&user_chosen) { + if registered_gateways.contains(&user_chosen) { return Err(ClientCoreError::AlreadyRegistered { gateway_id: user_chosen.to_base58_string(), } @@ -126,20 +116,18 @@ where // since we're registering with a brand new gateway, // make sure the list of available gateways doesn't overlap the list of known gateways - let available_gateways = if common_args.force_register_gateway { - // if we're force registering, all bets are off - available_gateways - } else { - available_gateways - .into_iter() - .filter(|g| !registered_gateways.contains(g.identity())) - .collect() - }; + let available_gateways = available_gateways + .into_iter() + .filter(|g| !registered_gateways.contains(g.identity())) + .collect::<Vec<_>>(); + + if available_gateways.is_empty() { + return Err(ClientCoreError::NoNewGatewaysAvailable.into()) + } let gateway_setup = GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: common_args.force_register_gateway, wg_tun_address: None, }; diff --git a/common/client-core/src/cli_helpers/client_init.rs b/common/client-core/src/cli_helpers/client_init.rs index f765117d35..019416fb2d 100644 --- a/common/client-core/src/cli_helpers/client_init.rs +++ b/common/client-core/src/cli_helpers/client_init.rs @@ -169,7 +169,6 @@ where let gateway_setup = GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: false, wg_tun_address: None, }; diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 67382c468e..56b95c2a43 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -38,6 +38,9 @@ pub enum ClientCoreError { #[error("no gateways on network")] NoGatewaysOnNetwork, + + #[error("there are no more new gateways on the network - it seems this client has already registered with all nodes it could have")] + NoNewGatewaysAvailable, #[error("list of nym apis is empty")] ListOfNymApisIsEmpty, diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index 388902045f..a45c87da6a 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -50,7 +50,6 @@ where async fn setup_new_gateway<K, D>( key_store: &K, details_store: &D, - overwrite_data: bool, selection_specification: GatewaySelectionSpecification, available_gateways: Vec<gateway::Node>, wg_tun_ip_address: Option<IpAddr>, @@ -94,8 +93,8 @@ where // check if we already have details associated with this particular gateway // and if so, see if we can overwrite it let selected_id = selected_gateway.gateway_id().to_base58_string(); - if has_gateway_details(details_store, &selected_id).await? && !overwrite_data { - return Err(ClientCoreError::ForbiddenGatewayKeyOverwrite { + if has_gateway_details(details_store, &selected_id).await? { + return Err(ClientCoreError::AlreadyRegistered { gateway_id: selected_id, }); } @@ -208,14 +207,12 @@ where GatewaySetup::New { specification, available_gateways, - overwrite_data, wg_tun_address, } => { log::trace!("GatewaySetup::New with spec: {specification:?}"); setup_new_gateway( key_store, details_store, - overwrite_data, specification, available_gateways, wg_tun_address, diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index f8f5d93fdb..b9c21b128a 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -244,10 +244,7 @@ pub enum GatewaySetup { // TODO: seems to be a bit inefficient to pass them by value available_gateways: Vec<gateway::Node>, - - /// Specifies whether old data should be overwritten whilst setting up new gateway client. - overwrite_data: bool, - + /// Implicitly specify whether the chosen gateway must use wireguard mode by setting the tun address. /// /// Currently this is imperfect solution as I'd imagine this address could vary from gateway to gateway @@ -287,7 +284,6 @@ impl GatewaySetup { additional_data: None, }, available_gateways: vec![], - overwrite_data: false, wg_tun_address: None, } } diff --git a/common/wasm/client-core/src/helpers.rs b/common/wasm/client-core/src/helpers.rs index a64341907c..80c9e90135 100644 --- a/common/wasm/client-core/src/helpers.rs +++ b/common/wasm/client-core/src/helpers.rs @@ -106,7 +106,6 @@ pub async fn setup_gateway_wasm( GatewaySetup::New { specification: selection_spec, available_gateways: gateways.to_vec(), - overwrite_data: false, wg_tun_address: None, } }; diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 3f3c7fd428..11e7b040c7 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -2844,20 +2844,6 @@ dependencies = [ "itoa 1.0.9", ] -[[package]] -name = "http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "http-body" version = "0.4.5" @@ -4211,6 +4197,20 @@ dependencies = [ "serde", ] +[[package]] +name = "nym-http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "nym-id" version = "0.1.0" @@ -4636,7 +4636,6 @@ dependencies = [ "eyre", "flate2", "futures", - "http-api-client", "itertools", "log", "nym-api-requests", @@ -4647,6 +4646,7 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", + "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", diff --git a/nym-connect/desktop/src-tauri/src/config/mod.rs b/nym-connect/desktop/src-tauri/src/config/mod.rs index 83c72dde79..79b70f814b 100644 --- a/nym-connect/desktop/src-tauri/src/config/mod.rs +++ b/nym-connect/desktop/src-tauri/src/config/mod.rs @@ -220,7 +220,6 @@ pub async fn init_socks5_config(provider_address: String, chosen_gateway_id: Str GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: true, wg_tun_address: None, } } else { diff --git a/sdk/lib/socks5-listener/src/lib.rs b/sdk/lib/socks5-listener/src/lib.rs index a4059a14d8..a0127d713c 100644 --- a/sdk/lib/socks5-listener/src/lib.rs +++ b/sdk/lib/socks5-listener/src/lib.rs @@ -276,7 +276,6 @@ where must_use_tls: false, }, available_gateways: current_gateways(&mut rng, &nym_apis).await?, - overwrite_data: false, wg_tun_address: None, }); diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index b59b7d20bb..ec438e40ef 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -434,7 +434,6 @@ where Ok(GatewaySetup::New { specification: selection_spec, available_gateways, - overwrite_data: !self.config.key_mode.is_keep(), wg_tun_address: self.wireguard_tun_address(), }) } From 1804c66a964d154eea7ed63db45f9458c556f682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 08:12:41 +0000 Subject: [PATCH 332/394] CI: remove ephemera contract upload --- .github/workflows/ci-contracts-upload-binaries.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/ci-contracts-upload-binaries.yml b/.github/workflows/ci-contracts-upload-binaries.yml index 620012763e..25e9f6cc4e 100644 --- a/.github/workflows/ci-contracts-upload-binaries.yml +++ b/.github/workflows/ci-contracts-upload-binaries.yml @@ -60,7 +60,6 @@ jobs: cp contracts/target/wasm32-unknown-unknown/release/cw4_group.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/nym_service_provider_directory.wasm $OUTPUT_DIR cp contracts/target/wasm32-unknown-unknown/release/nym_name_service.wasm $OUTPUT_DIR - cp contracts/target/wasm32-unknown-unknown/release/nym_ephemera.wasm $OUTPUT_DIR - name: Deploy branch to CI www continue-on-error: true From 4c43935862804fc52b264a27ae2856dbbaf7d41d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 08:49:30 +0000 Subject: [PATCH 333/394] change NR+IPR return types --- Cargo.lock | 1 + service-providers/ip-packet-router/Cargo.toml | 1 + service-providers/ip-packet-router/src/main.rs | 5 +++-- service-providers/network-requester/Cargo.toml | 2 +- service-providers/network-requester/src/main.rs | 6 ++++-- 5 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ea89e7ec2a..61a6d6120e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5772,6 +5772,7 @@ dependencies = [ name = "nym-ip-packet-router" version = "0.1.0" dependencies = [ + "anyhow", "bincode", "bs58 0.5.0", "bytes", diff --git a/service-providers/ip-packet-router/Cargo.toml b/service-providers/ip-packet-router/Cargo.toml index 3029a66a61..f36c7b7ed9 100644 --- a/service-providers/ip-packet-router/Cargo.toml +++ b/service-providers/ip-packet-router/Cargo.toml @@ -9,6 +9,7 @@ edition.workspace = true license.workspace = true [dependencies] +anyhow.workspace = true bincode = "1.3.3" bs58 = { workspace = true } bytes = "1.5.0" diff --git a/service-providers/ip-packet-router/src/main.rs b/service-providers/ip-packet-router/src/main.rs index 0412ea62a9..c8f9fd0e1b 100644 --- a/service-providers/ip-packet-router/src/main.rs +++ b/service-providers/ip-packet-router/src/main.rs @@ -3,7 +3,7 @@ mod cli; #[cfg(target_os = "linux")] #[tokio::main] -async fn main() -> Result<(), nym_ip_packet_router::error::IpPacketRouterError> { +async fn main() -> anyhow::Result<()> { use clap::Parser; let args = cli::Cli::parse(); @@ -14,7 +14,8 @@ async fn main() -> Result<(), nym_ip_packet_router::error::IpPacketRouterError> nym_bin_common::logging::maybe_print_banner(clap::crate_name!(), clap::crate_version!()); } - cli::execute(args).await + cli::execute(args).await?; + Ok(()) } #[cfg(not(target_os = "linux"))] diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index e0aa58d955..63e82dbe58 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -16,6 +16,7 @@ name = "nym_network_requester" path = "src/lib.rs" [dependencies] +anyhow = { workspace = true } addr = "0.15.6" async-trait = { workspace = true } bs58 = { workspace = true } @@ -65,4 +66,3 @@ nym-id = { path = "../../common/nym-id" } [dev-dependencies] tempfile = "3.5.0" -anyhow = { workspace = true } diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 391fe38242..00d62f083b 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -16,7 +16,7 @@ mod socks5; mod statistics; #[tokio::main] -async fn main() -> Result<(), NetworkRequesterError> { +async fn main() -> anyhow::Result<()> { let args = cli::Cli::parse(); setup_env(args.config_env_file.as_ref()); @@ -25,5 +25,7 @@ async fn main() -> Result<(), NetworkRequesterError> { } setup_logging(); - cli::execute(args).await + cli::execute(args).await?; + + Ok(()) } From 0b46d6486967394369ccba066ed2213f44586090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 08:57:17 +0000 Subject: [PATCH 334/394] cargo fmt --- common/client-core/src/cli_helpers/client_add_gateway.rs | 2 +- common/client-core/src/error.rs | 2 +- common/client-core/src/init/types.rs | 2 +- service-providers/network-requester/src/main.rs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/common/client-core/src/cli_helpers/client_add_gateway.rs b/common/client-core/src/cli_helpers/client_add_gateway.rs index f28cbabd59..148c947d8a 100644 --- a/common/client-core/src/cli_helpers/client_add_gateway.rs +++ b/common/client-core/src/cli_helpers/client_add_gateway.rs @@ -122,7 +122,7 @@ where .collect::<Vec<_>>(); if available_gateways.is_empty() { - return Err(ClientCoreError::NoNewGatewaysAvailable.into()) + return Err(ClientCoreError::NoNewGatewaysAvailable.into()); } let gateway_setup = GatewaySetup::New { diff --git a/common/client-core/src/error.rs b/common/client-core/src/error.rs index 56b95c2a43..bdfecfda5e 100644 --- a/common/client-core/src/error.rs +++ b/common/client-core/src/error.rs @@ -38,7 +38,7 @@ pub enum ClientCoreError { #[error("no gateways on network")] NoGatewaysOnNetwork, - + #[error("there are no more new gateways on the network - it seems this client has already registered with all nodes it could have")] NoNewGatewaysAvailable, diff --git a/common/client-core/src/init/types.rs b/common/client-core/src/init/types.rs index b9c21b128a..74a6a72ab8 100644 --- a/common/client-core/src/init/types.rs +++ b/common/client-core/src/init/types.rs @@ -244,7 +244,7 @@ pub enum GatewaySetup { // TODO: seems to be a bit inefficient to pass them by value available_gateways: Vec<gateway::Node>, - + /// Implicitly specify whether the chosen gateway must use wireguard mode by setting the tun address. /// /// Currently this is imperfect solution as I'd imagine this address could vary from gateway to gateway diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 00d62f083b..1ab71f0ddc 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -26,6 +26,6 @@ async fn main() -> anyhow::Result<()> { setup_logging(); cli::execute(args).await?; - + Ok(()) } From c585753d026dc9abefa11635a40815ee132bf3bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 09:10:57 +0000 Subject: [PATCH 335/394] removing unused code --- .../mixnet-contract/src/nym_node.rs | 13 ------------- service-providers/network-requester/src/main.rs | 1 - 2 files changed, 14 deletions(-) delete mode 100644 common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs diff --git a/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs b/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs deleted file mode 100644 index fcef40052d..0000000000 --- a/common/cosmwasm-smart-contracts/mixnet-contract/src/nym_node.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: Apache-2.0 - -use crate::IdentityKey; - -pub struct NymNode { - /// Network address of this mixnode, for example 1.1.1.1 or foo.nymnode.com - /// that will used for discovering other capabilities of this node. - pub host: String, - - /// Base58-encoded ed25519 EdDSA public key. - pub identity_key: IdentityKey, -} diff --git a/service-providers/network-requester/src/main.rs b/service-providers/network-requester/src/main.rs index 1ab71f0ddc..edf687e167 100644 --- a/service-providers/network-requester/src/main.rs +++ b/service-providers/network-requester/src/main.rs @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-3.0-only use clap::{crate_name, crate_version, Parser}; -use error::NetworkRequesterError; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; use nym_network_defaults::setup_env; From 91b790accc583c2254ed3863ef000561b7683388 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 09:30:27 +0000 Subject: [PATCH 336/394] fixed incorrect ArgGroup naming --- common/client-core/src/cli_helpers/client_add_gateway.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/src/cli_helpers/client_add_gateway.rs b/common/client-core/src/cli_helpers/client_add_gateway.rs index 148c947d8a..05c367f49a 100644 --- a/common/client-core/src/cli_helpers/client_add_gateway.rs +++ b/common/client-core/src/cli_helpers/client_add_gateway.rs @@ -36,7 +36,7 @@ pub struct CommonClientAddGatewayArgs { /// Specifies whether the new gateway should be determined based by latency as opposed to being chosen /// uniformly. - #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway"))] + #[cfg_attr(feature = "cli", clap(long, conflicts_with = "gateway_id"))] pub latency_based_selection: bool, /// Specify whether this new gateway should be set as the active one From 6fc4a06b3bf1ee956e490ed07c5b0e832d3de0e8 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Thu, 28 Mar 2024 09:33:06 +0000 Subject: [PATCH 337/394] [DOC]: Serinko/operators/fast-and-furious (#4466) * initialise performance testing pages * draft perfomance testing flow * initialise metric template page * add guides TOC * spell check * edit metrics monitoring page * syntax edit * draft initial prometheus setup flow * add prometheus config * setup prometheus systemd service * add self-hosted-monitor scripts * steps to run explorenym self-hosted monitor * add screenshots and explain steps * changed test page url and syntax edit * add grafana info * finalise explorenym scripts page and initialise docker page * initialise node setup page * clarify remaining todos and sort summary * add initial node setup steps * update node-setup * update docker setup layout * syntax edit * simplify node-setup and add troubleshooting * fix typo * implement feedback * new release version * remove sandbox from nymvpn gui guides * cleaning after FF testing * add blacklist troubleshooting * added run command * address review comments --- .../dev-portal/src/nymvpn/cli-linux.md | 2 +- .../dev-portal/src/nymvpn/cli-mac.md | 2 +- documentation/dev-portal/src/nymvpn/cli.md | 3 +- .../dev-portal/src/nymvpn/gui-linux.md | 6 +- .../dev-portal/src/nymvpn/gui-mac.md | 31 +-- documentation/dev-portal/src/nymvpn/gui.md | 18 +- documentation/operators/book.toml | 8 +- documentation/operators/src/SUMMARY.md | 6 + .../grafana/add-data-source-prometheus.png | Bin 0 -> 22776 bytes .../grafana/add-data-sources-button.png | Bin 0 -> 14954 bytes .../src/images/grafana/add-data-sources.png | Bin 0 -> 54971 bytes .../src/images/grafana/add-prometheus.png | Bin 0 -> 5785 bytes .../operators/src/images/grafana/id-1860.png | Bin 0 -> 8454 bytes .../src/images/grafana/import-dashboard.png | Bin 0 -> 75407 bytes .../src/images/grafana/menu-data-sources.png | Bin 0 -> 24824 bytes .../operators/src/legal/landing-pages.md | 4 +- .../operators/src/nodes/troubleshooting.md | 86 ++++-- .../operators/src/testing/docker-monitor.md | 246 ++++++++++++++++++ .../src/testing/explorenym-scripts.md | 131 ++++++++++ .../operators/src/testing/node-setup.md | 79 ++++++ .../operators/src/testing/performance.md | 32 +++ .../src/testing/prometheus-grafana.md | 36 +++ .../operators/src/testing/templates.md | 17 ++ 23 files changed, 652 insertions(+), 55 deletions(-) create mode 100644 documentation/operators/src/images/grafana/add-data-source-prometheus.png create mode 100644 documentation/operators/src/images/grafana/add-data-sources-button.png create mode 100644 documentation/operators/src/images/grafana/add-data-sources.png create mode 100644 documentation/operators/src/images/grafana/add-prometheus.png create mode 100644 documentation/operators/src/images/grafana/id-1860.png create mode 100644 documentation/operators/src/images/grafana/import-dashboard.png create mode 100644 documentation/operators/src/images/grafana/menu-data-sources.png create mode 100644 documentation/operators/src/testing/docker-monitor.md create mode 100644 documentation/operators/src/testing/explorenym-scripts.md create mode 100644 documentation/operators/src/testing/node-setup.md create mode 100644 documentation/operators/src/testing/performance.md create mode 100644 documentation/operators/src/testing/prometheus-grafana.md create mode 100644 documentation/operators/src/testing/templates.md diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index 2c8f932e0a..2d4db55778 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -1,7 +1,7 @@ # NymVPN alpha CLI: Guide for GNU/Linux ```admonish info -NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. +NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. ``` ## Installation diff --git a/documentation/dev-portal/src/nymvpn/cli-mac.md b/documentation/dev-portal/src/nymvpn/cli-mac.md index fa75a90659..9ae4039cdc 100644 --- a/documentation/dev-portal/src/nymvpn/cli-mac.md +++ b/documentation/dev-portal/src/nymvpn/cli-mac.md @@ -1,7 +1,7 @@ # NymVPN alpha CLI: Guide for MacOS ```admonish info -NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. +NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. ``` ## Preparation diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index 7151082e2a..f040b9cff2 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -5,6 +5,7 @@ Our alpha testing round is done with participants at live workshop events. This **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` + Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. @@ -15,7 +16,7 @@ We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8 1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/serinko/d65450653d6bbafacbcee71c9cb8fb31/raw/4b70371fb000fd08910c0f778e78566d002e1319/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/d39f98dbb36ccff761a7e940073388a6fe7b73fe/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh ``` 2. Follow the prompts in the program diff --git a/documentation/dev-portal/src/nymvpn/gui-linux.md b/documentation/dev-portal/src/nymvpn/gui-linux.md index 2f66420bf1..e77945d9eb 100644 --- a/documentation/dev-portal/src/nymvpn/gui-linux.md +++ b/documentation/dev-portal/src/nymvpn/gui-linux.md @@ -3,7 +3,7 @@ <div style="padding:56.25% 0 0 0;position:relative;"><iframe src="https://player.vimeo.com/video/908221306?h=404b2bbdc8" style="position:absolute;top:0;left:0;width:100%;height:100%;" frameborder="0" allow="autoplay; fullscreen; picture-in-picture" allowfullscreen></iframe></div><script src="https://player.vimeo.com/api/player.js"></script> ```admonish info -NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. +NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. ``` ## Preparation @@ -14,7 +14,7 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes 1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux -2. Required (if you don't want to check shasum, skip this point): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: +2. (Optional: if you don't want to check shasum, skip this point) Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh echo "<SHA_STRING>" | shasum -a 256 -c @@ -43,6 +43,7 @@ sudo dpkg -i ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64. sudo apt-get install -f ./nym-vpn_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_amd64.deb ``` +<!-- NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. ### Configuration @@ -63,6 +64,7 @@ curl -o $HOME/.config/nym-vpn/sandbox.env -L https://raw.githubusercontent.com/n # change <USER> to your username env_config_file = "/home/<USER>/.config/nym-vpn/sandbox.env" ``` +--> ## Run NymVPN diff --git a/documentation/dev-portal/src/nymvpn/gui-mac.md b/documentation/dev-portal/src/nymvpn/gui-mac.md index 9602f608cf..f3f3ccb89b 100644 --- a/documentation/dev-portal/src/nymvpn/gui-mac.md +++ b/documentation/dev-portal/src/nymvpn/gui-mac.md @@ -1,7 +1,7 @@ # NymVPN alpha - Desktop: Guide for Mac OS ```admonish info -NymVPN is an experimental software and it's for [testing](./testing.md) purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. +NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. ``` ## Preparation @@ -10,13 +10,6 @@ NymVPN is an experimental software and it's for [testing](./testing.md) purposes ### Installation -<!-- Seems redundant -1. Create a directory `~/nym-vpn-latest` -```sh -mkdir -p "$HOME/nym-vpn-latest" -``` ---> - 1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for your version of MacOS 2. Recommended (skip this point if you don't want to verify): Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: @@ -33,27 +26,9 @@ tar -xvf <BINARY>.tar.gz # for example # tar -xvf nym-vpn-desktop_<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->_macos_aarch64.tar.gz ``` -<!-- seems redundant -5. Move to the application content directory: -```sh -cd "macos/nym-vpn.app/Contents/MacOS" - -# if it didn't work, try -cd "/Applications/nym-vpn.app/Contents/MacOS/" -``` -6. Make executable -```sh -chmod u+x nym-vpn -``` - -7. Move `nym-vpn` to your `~/nym-vpn-latest` directory -```sh -mv nym-vpn "$HOME/nym-vpn-latest" -``` ---> 4. Mount the `.dmg` image you extracted by double clicking on it and move it (drag it) to your `/Application` folder - +<!-- NymVPN alpha version runs over Nym testnet (called sandbox), a little extra configuration is needed for the application to work. ### Configuration @@ -73,6 +48,8 @@ Alternatively do it by using this command: ```sh echo "env_config_file = sandbox.env" > /Applications/nym-vpn.app/Contents/MacOS/config.toml ``` +--> + ## Run NymVPN **For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index ca75730cc4..e410573a93 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -6,19 +6,31 @@ Our alpha testing round is done with participants at live workshop events. This **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` -This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. For qualitative testing the [CLI](cli.md) is a necessity but to run the GUI holds the same importance as it provides the user with an experience of the actual app and the developers with a valuable feedback from the users. +This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for your distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. -## Automated Script for GUI Installation +## Linux AppImage Automated Installation Method + +The latest releases contain `appimage.sh` script. This method makes the installation simple for Linux users who want to run NymVPN from AppImmage. Executing the command below will download the binary to `~/.local/bin` and verify the checksum. +```sh +curl -fsSL https://github.com/nymtech/nym-vpn-client/releases/download/nym-vpn-desktop-v<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->/appimage.sh | bash +``` + +Run with the command +```sh +sudo -E ~/.local/bin/nym-vpn.appimage +``` + +## Automated Script for GUI Installation (Linux and Mac) We wrote a [script](https://gist.github.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19) which does download of dependencies and the application, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically. Turn off all VPNs and follow the steps below. 1. Open a terminal window in a directory where you want the script to be downloaded and run ```sh -curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/6c81619ec26b092dfa174bce79335f4163c657ff/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh +curl -o nym-vpn-desktop-install-run.sh -L https://gist.githubusercontent.com/tommyv1987/7d210d4daa8f7abc61f9a696d0321f19/raw/939ac8d0afed69f43739b9cf2e5728454ea2c437/nym-vpn-client-install-run.sh && chmod u+x nym-vpn-desktop-install-run.sh && sudo -E ./nym-vpn-desktop-install-run.sh ``` 2. Follow the prompts in the program diff --git a/documentation/operators/book.toml b/documentation/operators/book.toml index ba325763ad..d987773f01 100644 --- a/documentation/operators/book.toml +++ b/documentation/operators/book.toml @@ -30,9 +30,11 @@ assets_version = "3.0.0" # do not edit: managed by `mdbook-admonish install` [preprocessor.variables.variables] minimum_rust_version = "1.66" wallet_release_version = "1.2.8" -# nym-vpn related variables -nym_vpn_latest_binary_url = "https://github.com/nymtech/nym/releases/tag/nym-vpn-alpha-0.0.4" -nym_vpn_form_url = "https://opnform.com/forms/nymvpn-user-research-at-37c3-yccqko-2" +performance_testing_webpage = "https://nymtech.net/events/fast-and-furious" +performance_validator = "http://validator.performance.nymte.ch/" +performance_testing_release = "v2024.2-fast-and-furious-v2" +# dependencies +prometheus_latest_version = "v2.50.1" [preprocessor.last-changed] command = "mdbook-last-changed" diff --git a/documentation/operators/src/SUMMARY.md b/documentation/operators/src/SUMMARY.md index 6afd7c893c..669fd2a42d 100644 --- a/documentation/operators/src/SUMMARY.md +++ b/documentation/operators/src/SUMMARY.md @@ -21,6 +21,12 @@ - [Maintenance](nodes/maintenance.md) - [Manual Node Upgrade](nodes/manual-upgrade.md) - [Automatic Node Upgrade: Nymvisor Setup and Usage](nodes/nymvisor-upgrade.md) +- [Performance Testing](testing/performance.md) + - [Node Setup](testing/node-setup.md) +- [Metrics Monitoring](testing/templates.md) + - [Prometheus & Grafana](testing/prometheus-grafana.md) + - [ExploreNYM scripts](testing/explorenym-scripts.md) +<!-- - [Run in a Docker](testing/docker-monitor.md) --> - [Troubleshooting](nodes/troubleshooting.md) # Token Economics diff --git a/documentation/operators/src/images/grafana/add-data-source-prometheus.png b/documentation/operators/src/images/grafana/add-data-source-prometheus.png new file mode 100644 index 0000000000000000000000000000000000000000..c9bae39f390ae0e6b78c3976fc4db9a1855b51ad GIT binary patch literal 22776 zcmeFZXH-*N+coN~w-o^a0i|jXP<ro0B?wZb_uiz2-ixR}=pxdabg7ZvK|w%B=uNtm z0HK5udI@KV&wJkQ#~J6xJI;^q8{=eTDB0QUy;r%eHLp46BJ`D#4B;)RTbC|fB77+e zRlRiS-+)V({t>-#85}{@*53gCU2%E-QvJq_8<TU&zb{>SaOoxVnYw4{`m~k4+A`hs ztpHNe)>}TTJ}}3(cCS>N#>7SJifG-Zdnc{+CMW$i9AF_;6ZOm-j;vCzpilQ_eBP5k z@9=Z7OAdZmd8g{kPqJAy9ak*2D;<!roVxs#t=Rr1xF>jZBnBrX9c`pvx%l*LHsghq z)Y*T3q(5<2zWC<SZ~A{Q1Q$O(rTx(S_t^0Nf9QYO6T_dHclQX1Hlm|NT}80{m{2mN zbBupHn<0tE%I@5in`RT{T-W#0;i9hIM}s2)O{^C^eweSKc6{q5(XyiuYI*DH>%H6F z*S#@8V+%xS_?35kumkAd5t;^<Z<Wf1KjxGSf#)eDbu8mXcsVY<`$qem7K5BZwf6M9 zgZuwFj?`vb!X2sQE2y>A{vA~hBDWmG*RQe=8+-e%o~D>2w@5goHNVJ2|Kj^Mq9MUl z9XAL<A7u@*K5?!)-9hJslI0y9UAwnJU0GE_I0}`K@#tOm8hYEx#$LSmh?A3bI>6DR z8~x+qiz70{YYS+!XaE)>bKOcxDtmvw`V%r#)c>p?TS`dV?~30$9c~w9rBoh=RKjSa zt+hP|JA0I}P<(QH))yD!&6^wvNMCn1C(vuja1oLBteTwaSeyCxT`DoW1_o1+5fMJ# z-c(eprFr?Z66G*>)hcZ8N5N3G*_6KczsJW-O-*QYu2mmXDqNB!0ePY&AXt$o=n;c} zy$Pxd(q=0yLMSRUIzsTTwY2i(dJrvBBE8<H7~bs+J1=GQ$ETmqk$oqjD;0f`B1w)B zPi_;2dg8~m;4A4CWfT<gtnnq=ySv=|f`{`(=X8=z(1FqE9v6r8=gcycYHAfThAP%N zT}K2~N@*ewW8{weG^M1>I(EnBGF7VG_mjnXmg4h@iz67Eu7}Bo1-D3C^ma{qVm_y+ z=yg3kA4t8ga15LypGorgry30r^P@-evQvTor2P8ztLdmCKp{eroRN;s5WHv4wnmJz zPeYlmn3id;VU1dh@ubqBp`q66saMIE6#Vy(BCiM}37PCv^quNyX(_9iI#`-GSaQ2{ zSCTO=NSyD)nh^CYY^R@$Ap_Okku!Q<yrQCdc`Z@?8+(*;axhvhA(~!Z<)(WSR0WR* z`bW1M4|c#Cm$Ef;9oA*egFXf$A|Qe1B<$@uzkTS-9{6;&ecXPoH5Uf+XXKRhNQ|XV zZfIC$<!mYdFV$Yl3PG_(r~P8DFj9_$wGA|QQ;YiG^-_#VU|-Zq5eV4UaZ!pv>hxX4 zB}<AW6>f0-fa$u8gtW;Q7S$JhWoC{VqI8)FmK~0D5>JEc>Zag!T&AYQ7+SNhD;Rlu zzx9~K%NotTfvc*Ls;QC%weCAD*e#)w1J0X>^Nr-G<Cxy*RJ-z%HBC(DE=19>v2vof zJ!6@#1_!;6I9tTA3CQO*H#IG^7)||H*nXti1?B|?V@*r@+{FcXgrk@opXfwI^mO$| zxCjKo(|x_g!+ZR<0%cCmm_EhD`EG5CLLbG+ksFBDZ3{DbYiMZvpcPd&Fz8yaKK4B6 zN#dP-I{Q0l*~o9P>_nq{=n~GTJS@~ON$0+k4Dsm5$SU<c6g-`rltzO6u`5QL)dM?I z`h|vq>S#BX^Nxy@mCRI`6eFXw7+oK7h*?CW16(YvM$-RyTn34h4{7m!H-5On>*qJ` zcikPmH2ol}eu66RbbwH~0~NuTwVGVG&>1~EI<m61cKvFwLMm5#Z|~fO;Oy+-uy@Rt zkOCCidDicQftp$rBKPuT<0n_c$9JPD=;%eQ0^{QLy2%gR-QDS;CeO#LF4hRH7aanA zW!lC4A8tV86y-_6+ZE>8<(I)&fB|G<FR`^P(ny}F*?-0)<A+BxGb?p)2NhU9=~VvF z)Nqvjk}Q9p9<9uG|3gp^x}32H{-v>Tw>>~|dSLwfC!<<VfepECmvisBfY>iT?<?$j zpG78=TIJ2M^>hmb%%LbV@O^`W-kK<VCO-}Jcrq0a4@#1~Fdq%o$by3VII2okEj7WG z6I~-CdNqGx{(`J5yM=}G@@lH(wS@roh1Gt^z;T&wRJSL(YWc3p#zYk>M5S+cMJMwi zNyGlSF;?>Kja@KRW8kZ6Yw14Qq4DvSc{_Eu{JvC0PuroB<m6;!dtYqQG9C4ne>=&X zwT;9XLdJH@<`aQm<5}WLTyp$QZv%oA%NwCAL?>$XJvc;AS67!)_baq4yUMkTg~{9R z_$XxiW@l3CuC4WUepJgrFEfZe+c7c6{nLVn4tK8pneDYr9s9$C9v;fPye^P>M@(_n z)_ksu0vG&-mftpIbbePO;kvWUM~Do!w|D*d3Fi7)$RS9+WcMY~kmzpoPIOIUKHM+@ zN7?%*Uw?IWv0<}C_h73~5r#iGSdoT8O`SGDs)GL<`0gbnB`6?JtlQu@q{kUhjuw~R zHBFVE?z4*#7MaOnrBfdI_U!|_yqrhfy{q|rJ4J>*;P*h}+FcbE9^d-(^fz#c@tt&t zH@CBMMZnP>GsM~5-Ob~GruQ_Y+GSZF4%`g4%+8e6+Zz=v;V*+GLDXhnA1cjx#ANUo z@z_jGh(>9B{Rry1WcL<a1e%qOXg>P{KlCm6c_Ve{4}iMlQCg;Ggt8Bro}Si1<gwh+ z)6?Ur;DJAeu*u~%XTUDuT>A&iLQW1eH8oXVB_52W+_vmqd;sa@{K?M2u^zBzemd}v z-pJS(VJ+jx(2x{Vj1HE_DHtpJ$XZKv;v}u~VFJ>}$0t<wbH1c2v8fYh1&-HVH!-R@ zYA3h1m&g*Q`0(-L_i#D+@Cumu{^shhPzD9aEuvf0y^A67Nqz>o@B7AXZDl~AR=rHF zZXSEEa!g6WtRGCxbnxm@Q9?dvEIBdl_*jdxp&=1&&DZZT{@CuHKke%Hd2hz+=bYo) z{2&sQZnQkhiSTl7#y*blYh@)^1N%4+&t6|=Wwl+BQgYaT<F~ZD%tBwkwVZrA7{elX z&|!Rbds<&vt8cXTd+XF7YS`}7bMi^-l_X~(EAw#FoMSOtNoQmQw_pVqui(M<{@Ca! z6NE5Q@4#jEa1Jf61=3jnZm$}*tZam={g~oo_RZ7G)=UPfBdG2|lAWL5@a4<5o)I%} zQ4&S}r%jL;xzOBPa+k~Ink~ix5A^gzAs^*({Y<xOodnKUhetIhBWkLu=?=7(|G?l& zT$UYNepe5bNpI|iekm#n_c~rXPzfL)oikDC#vuE@!QoIy%zW`x@)CP?7RG?At~Z`y zitOwg4_7^0-DPt~BmGsnhllN!B7{jy29}m6y3q`N`eE&+SCt5(qQbThQa%f%7!Ht! z=X(F{eB(b|r}&vUk(_tz>8vrnu^r5}cqF==F(`qwk6w}_UkI9xM6a%_kgB-23>h16 zC)_5Ce6h<K9C}nlC>|&|EXW6e5QX5-%aXTM6qPZHFaNaQjcCukJkBLXB$Q9keQxSk z(3R1fH$xAxA&9#&=iH$|J#@SNvI6pZgBh=R;3+27@KWs@sz5NjhJHti5=P<hN2)Ka zt(~N#{1g>6OjH7s3Xa~b(cPcv|1sxi=x;r=_)@S2sjHg|(l<5L8WM@*so)i8+Al3D z>vBAfk;^smZ$kgtZi^w|1q;ltapAApYyf94%OqUIVaIp(kwHO6&|RN+YO#kr1fs<# zL1(!IV%BUTT=dU{0y-PwKTU94zE`xHTTmeEwo|F6$=ffub&%qSuE}o&3t%X`a{;ru z>W1H*A_$I&DU<60?RZe8JvBXDQc@!R2dZ5m3dz=QwXDeSTD>Y^R8um+Qqmur4R zallgAn=0WWw7_GjkkJE0<Sd3y`s14m>zxnnPgq$w&rH??p*h(l3m6P71r<33m9??) z;b{dztlB9}n~fs8-M}DCM5JEoy~q;Un!TiLLfD)bW~=mUprowqCfN;`MoSXh+sB8J zllFVzMGBZw>0t3wOyh|Zwx1sv%b?$Sb&F0JmymI=eWW{QG7z?_VW8ITyS20P^5x6* z+3vP!`P@aYz$myW=2pZO)#Pu!(V9NlGqbhr%SoWG_IJUaTE`WM)YrGsB*2*tl_6Qj z!Sx3cp7KYG#)1ul1NXlSl(@Nh<mTn(<mIZXe=5;Ady^X!7as28zV8NMK|IC*EVR3O z|LemH1bT7(IW$hr%568a9cupi^{<xZxh+WPb9;M5ummL__jYIw5qX)J4`WXK@0eOx zTqUu#vC-Ah85{o6ocm{#F8wa$(zK!jD1<~sM&`Opqe%cr&gfxt)oyF3t2mCzrP*kG z{pwjtZC(B3xbT;|_)w;IFBKJ;AU-~w|6G|YPSlPgZC>iJ9vd0iM@aq{H98Ne<va3) z*x1>v&^Lh@nJ7vP>v}r-03vogcb$GM0GBiGN|-&Hz91)8FAI$#Qc9<rIcrE3x8=aS zpUlm{g|$}i3qZ;%Tvh_`ojIXu!Msve0ZQ;9a997K5VvsuKCF3rCLzPG<@KEElC9+^ z|59d^4(~G2FB9`0u2xoKCK9yQ|1``|FXH9#;Lr%cjYL`KlLXGaXtG<BWPKzg8GRWd zXv<e5;XZw-k<1Xu*-J})uWr@Xdn=3K?ar0((Ae*(!YSVxNskMd(*^qlUp3$5<&779 zXrSZgM~egLSRFkm9-iRidHc>>qS;Dhq=LHh<=EL&8Us`h-qAG##Lz;txH#&_$LHj1 z4U@3cW56f+f<H?kI?O~uT~mXLzBg6gI4VEjxQkNVq1x30r(bt!2w`DEX-WLU^QWka zxE)EJ37=b8@$JhZZ%fT-&1^e?%PK2x8uc~iILE&PNLymYUqHY;%$GGrHi}kK;m;~( zNi?WVK}EWaQseaBnM<%8E2hTq{ppEI!@=3CT(xc`Bw=BR-~TPls5yV7Cc5Hhy0_<s zGo^H@(^pi)1CWu}I@L%$pu&6PTXOTCSbhB|KCk4wJj=kqhsu)MjRi^LNfkGVh?GE8 zHfA8ndi<x{8Xg&W!d!<?ev_X5K!oK*Y#-%~-87msEjB%uzAW^UC!yZnmnAYXlH$HM zG8D-SFRZSbSXgh&uUlFzf17iRh)`&3@}sYX`Jqt1x(jdl1xk=?OxIK(lu@@$%+1BD z=hf})?ZMIT_VOARV}}j0Ta#A3i6xntB&0N@-_fhD*Fb&pLK@{czilN<qhyo;Ra4__ zd2nFkJ#hzzC@8o^91hTJ3YSTFZV+Qi54Ql%{{Fs?=X5rxJVI9h`Z^)TTCyDM?+Xa> zU%eW%vbx%nC?T&WFQcsddvTG9y5TpNvJ2aure%jcHAa?nMP_`%V?F8o(QR{w$Ny^U zMK3#fEp&|k`0+!c9v}K6C)~YypN)c*pTDklacOeU&VD2RY7ptb9K#8DCp#WL2K&M* zAmHTeT2@U*PfGe7?Mz4*(J1COTI_FZxc(ecSXyvwjywrFA$D=Dc$asL`rf^3$^<UX z&U4#*k+&nKro<9Bbm~mUsVKrnMrZcBn9oV}3ez3_rrQu>9qs5=f;9Eh<uqk*(fWE3 ztr8tnW2FaIpV*!$2#x}E@69v$Nq?V#twSdPSksY&%j&ywMDvmQ;8@M}c0iYTxfek` ztI;tS*dL~4*p>s6xF%XiVPT;sHi%i`d{@-WEOtZGf2z($RL#N8ZU^6>r{0^)oK?yC zB=jX^y7#;nM7P?x8RD~bbgC?Qq`4i%Q>Wi-y7zqP>xW!<%~FGsdbgp;$&;l?gc$zU zP&|cZNc8&oegkK4dP`bbTMF#7^QYsR{I5GZ&NH5Cvn<zR6{6Gkeq}4~Nxm?8Y!_gQ zE2{G<L`Z~3g?Y_y2NX<=Yik-F?-cdn8{LRgdhqMGXeA~Zvu-IVNP56NIYjrMzYyeB zyxP2@5H+2D);W8cLI$kqEKH8o&+lD=(FEUbzs$%;LYRYpZe?ZdIpd#Tc_aE`Wz#R| zUW&x-?`$@THP!jLAB*8qTJf@v0DiC&XecOnxjoOB`Bi*wI5a)o!N4GpB4c)JEWzl* z33^Pg*GOn%aYf9+`PF%3vE+a`*BDQ!rKQEn%E}J^kr*8!H}_~aDVE-U$H7W#x%EiC zvZ{*Q#|Sz+G?eDJ`d*!deC1|kWhEo&OC7H+thgw^ytdTT4WGZ=IbN7afI{j#F~w1( z=`k@R(fLo-?-<rOCkgj&zEINKk5r(wH!v^|C*-IpY1(tP*$JU<QPWNogkd4#22FZc zKN1x^JzL+_?U@-vc6N4Jds@@7i3z=ma!~13Z3N5)6!<=3$j-@GISs0SI<q&&gV0x2 zR+g65nHqR^KE2aCFBB^|%*ozen+^(Q1SgkqnRb;Mf2VSX-|_hMv@}}Qcm(ah3?)ey zdIwAhP+KM^`_e^sjxC0JOJ6;z^V!EAqqWXAR_+!KZ*GvM38%c$)Xd7wZ6E0WZM)+G z6=!Uh4q4bgKNvblNu~-hq`4T3Nn3^e|IlDh+qKiY{;-+g)%|}EODI%-`CZvcLg&!! zn^B3vE=sRu-!~NHr!Ma8RiSb(orm&Tp?Yi6B`6l6sz8w3zjselGkz8udeP2r29}`x zwffj@v~6md{zo;AjoB7fPDy468;cm54O>V36>;2fcy;xDjSofkZx~MM;@7bMQke}{ z{~k70Y#vpfY$gl!24!wmadqiZx-^ovf(IbKPSd}1-W$=W#2ijy;!R{iY~o7$V^-EW z$8EL*q{b&ey8U}K*ik4ob!wg0ifqwYn8ez44Jy-HS>y4c+dL@9%c?JpG`ziK4?`}* zsQno+J2>dOJy`egBP4I?#}7Uc=e*pws@fXC1#fRqjpR*r4~js<CQzs>0OoAGb&snm z@i<pkN1|J|1-Q94u-N8!Cq{nu+yGjR1nT?TZ6oal90`m}1~m0`>FG1UAsG*{au15_ ztnKmm5QGlf=#QIfr@mKQ_jYxYQ#hE?wNUyxuZ-b{XvqwO#_TJ~49DVvf*ANOJNK<h zE>2~7I^~M``kmczPo{?C#Kf6^&9)4Gyb25fhp%tYF83Ln&MMC`XLZv1FbShSMkgSi z8h=Gs5UY=F4Cdkhns3v|z)PAByv=QzpULhd;wE3W+o0ss#gB~XRl2!?TsddtVIQ7E zQp9`*EQ(BzXka!DG<c(nTI)Bx>2Ai!;OHPxI)(e(;5Zh`f!+bMNNK4Oq`a~c)U0c< zyJ-^CMp{Oq?2jvp8j6~mqk1e6+SM<VTu;sQO`fIaht$Nz+A1kgkkkn^^d$2isLmhd z<b?bA`Em0uscXg&1U-l7R?Ro(Ep@cX>?g#N%LFUKU@%(;he65}gszv-ek5whY5_!6 zTU&MxkF~vh)s8O;g-YNwNOL+{1#HtEq1%88H-H58_9ZNmR)8!U)m(_m5c-&whS@;d zTAS$TX{qVxNEqXSgO4NDF#q6V=cDKvKY2cbU{daIJ>lY7M2)}ykwd^nAu8f**|Fyu z3e6IGAJU+;Rrxi$lbD&wfJ=ZUUC2r9MTZ6iAd$KCb*c<UwzCOxGPQ~izqg9l*GNO5 zdU~C+uvP#-3)G)OgM(i<l+ry(AParHv-s3S4d+6sl&`OJH`E(n>o9+x*D@hK&eh$0 z%GvMu_*mT^uE3Nc_GHV(yHJ6NA?sVg_cVhvkcUv_3W`1R3(<^>MtnRxw+KUP(~};? z$%WvwE`sH7`QBL*r=mm#s0s%@R4p<uM9bw49v_Q{>V-IsF7Waq#>a*4-A`IS^(Lsu zby@j|-y;@xaBxsDG7_|q>mMm90QZ0n{~9(nH5KtPHP+BzB*9>A%E{fDoSdAPoNPXt zr38gN$<c{28^;p`r8+2-oxP{NzP`EnpFfmB-{;Isd=X5-;<AaYt-PN>NnEa*wRM>@ ztv$QFpjPy>kGncxng(LBuhUO&{pjyWB2__r$<I%L10EWUUgiPhR@czm=ZcCw>O>oN zZtRMRh;$?6(auK&L(JoL0s!&v`1xJgr~jp)tN9$-sZ8VbdOF+CP(rIzpU(RXkRf*| zXQzIv>eP%@k7BXCbH&m699l;YrQ5GM*G&z47jAiw&^9L|+K?V0nfE0l)wv+AIvK8% z5$fUO?&9Xw*WG=u_dnA-!)$j*3n2@I>iU*M5zQI9y?>sm&SD|q;qIQCoJbl|mn7{X zPe#@RmwjxvxxUWDTk!>f;N|64mcyTwwt#>D%iIzUJ)ARMvFzi03~C=V<suITi9)qb zcu$c<OCpC&D#qCaiq84?`1zZ}{7?!#gpm>8-=e}Ib(VYgsVlUL>+4hU`NP_qA|oT) zVEz?kQrQ5^MnozC3R{OQJ~((ad3n+D=;)eQC3fKBVAkN^$B%;$2oFEEMaB3Czu?Iy zB$~f!1kk|m*bAOpS>?}Hbk~!UlTWeH&m2FFmCHT4TIb+E2mU46SAwdm>wm7*)ziyP zw30Ft$6Y@o%f6UXr;(BV$E#Qjc4hsZ<V;>>nPHvpPR_TTus`z(0{KWhrHv19rjW-3 zjK-BdKIil`9Smwbr2(>qk5B&Z-&<F%yC=jYkg8~o?p0PU2I|h5TiLcaejl8gS|2Q* zFTxar2?<`xwSFu?RB=@Kx&O_Zm-p{$xwuqNQ&EqW8jiI@y?T5K$O4-6G=M=(Eqkr) z?0z*JBs^mt3UHS)qBGBh)k&O9|LoFr?z=^ou)MSslaNvLvk&@1Gfaa<U>Ol{QTT3o z@G~*@E-#uZCg1&%o16RC>8r;rg2?r?HR>!4DXFHivVy!kCY;8DI{@AY@C}oxn3*-j z#Z_hHfhjB{MN8r&lnNp!B_&05=%dHxxQeRkA_gM`1&|A{DjTitOY~q_T(mB{y}Y!l zqG{+1v=NY}k|%5eoBhw9@Cyne(a!DtzRmFk1>@`~$T-ztkWN&0+QSoi!OY(egLW@R zJ-+epWpVLm&rA$k3&;S8`n9S`kdMpG#^F<!xn{gzh-H~J0GcR-C3baqV8DdqJ{1*V zbq>qg5_ZWN)EKBem7|AHbq$SykrDLD;=1vsD+9CI(cqy|HR?JcAtA2|!P4*tlc>KP zLd?ws(<?0~*>}Y49Hcymd+Fxp+SKIBz+jb=Z`9S(!vv9+XLWHQXrGL?x8HE9baTcz zRMyng)z^+sidI)w-@A7Yl_-&)TgAxF9}4n~iuP-Dpav;0fto&@&&kHO)hY99THo?) z!_qU3gvs%76KfON-;!lHIbRCv%S%f5g&wOvxZ~>XmXws#*{kzy!AT<>!^6Yl<m7Ju z`peL7XHaiM(OaqMY3UiN6za=BFuZ(xI|pg~gM-B-CA8$i?+{%8ycHF*(Pz~mYFcC; zk=~m0@sTFlk78oVQ;a0MEdESgJ>u!-j1&(kv|V(8+FPl&ZPY1Lp8AGQzd^5DX#;Ev z(0ycNte$^c938c!i>9QaaWFOY=9x=`LI4+U2#^d#d=Gn%rsgOav%(Ut>TbTnT}n!p zs68#6nw2j}!gYcoqN2eS5-gJMpA3wS?&H!P#K`uhNuKG2MzzfTD|IEi6w7e|0SuJ2 zIOm3)3e-hVDi>jef7tQJ50ojOP6hS4zr;T?hRwPY6HlHbBo0x&-r8kMKoSt(?Csaz z<p<T*d4pm*RmkgoT~kS2-5&`MWb4J3ftSUbVsCbW6d5WDi2<_2;gRBvTer(9Dq3P< z(^8#PI1<94Svxzb#2$!m1w$Z&c5p6zMnVkd3-*x!@Lmplz{b}--BVFmuL{^CC?sxI z8fsy|_~J#!v%pNOLplKbHamQx4I-?p$dK1F0}pSfiu8<iN^Z!>>39`XWFsqobLml^ z0KB!nPJ4?0r!lDI=9U{1Gf?^M0|;bLUaxGoZEV;>)in(Zv$J{G9}o9=JV$7|3Sr;O ztJJS1+js~@cg0@0>iw1#Q=k;ZaV3uv?KU(t5~(btsiW}>+NMJvN8kDhEQ|^Sx0;gE zJ9ed7auEzpCk&80<zyj^sY#zl*f-OD&)ELU3-DD+==8sOSes(By2gjdag2+P%hz!_ z`}_nO4j7p{C>m{cF$i3V++LGBr|de~+KNdupaRQ+8~**m*UWkK+UeOn>Xc&rGR@D- zaAhI?hUJUManx!}3%NM!((0Qg&c8poJw3ko^3tp8IsaQ7>c6)~=jQ4fNf@b<J@fa; zzD?Wh4keUjI(g}Y)*@iTKG!bVQ0o(kPYYp#K>zdn<eu37p^?F4clLmv2GmTHlv*yl z@-8mnJ7MKv7w<_PvcDa+_j~2m?H4sNR|228$m8yi+u5yS8xEc+6T=GBTTNr?>ZD&8 ze~pYZc=jw^o#p;?*WcfodN|y4U}0uf<2~Ycbk)nr={kt`uvW|fcahd?jo*o;v`K(` zLTPz<xh99O+bY!EeQByLyuLwHIU@>)GddMZfr#dbK~T7l<=2~>b-Y(&4httZ_x=l? zF4-s=B`2TyP;mBf{+z6V<vV*xOONl<>d^<R7xaJF0%r%WJY0S;S`|?gh5&*lgoTq6 zLtn$Bm}~>vto1pF8c4y<QjA_O_fH9jlbiJorVoAn^{2k$6TE$-Z{{og=+)tJ{j;0` z(&5z;fLibM==_~H5&u->ak}t^gMRvsWk>b(g{MgYUW`FJkiot8ZB%a*P#9R{@?<(a zy^rn;s40sFoF2xUp6b)ur@`SEa3<+Xqh}`ms)JX{v{6$9p7T(BSw~OcQUQ#cx;OAH z5KwZ^3OY1?Z4&3kJXZlkdeTvM+=0XNaZ7czW?pZ3Zqe%M+9w&Syy2M{V1zKxpOVf> zU;HF5EIbYc9LnX(OkO@G7|d#QB_A`R5eqxJ=IOr@8Jp{i6H|kCDLwi-JNqV)3EIU) zT53ass)-Kl>?O~oAPPOG1`$z&g?`VgiEHZpqoYK`(bW}hAG&g+rLR(Qq?3oYLo2~Z zAPc%cX>>UdpJ0Ud_*ykMFtB%!ad>uM#I5BeHgg<8FX?_N>*O>Syhq)aCb@vd*jrdk z<0s$V4luo#8t0BS;!ZPDQ>O4DDY0#S)n(39!0nb66`jr27~Q2LFCSkIB1rhTST61p zAnd*V0m!kaq_VJXI=UH|d7@Mave}l5&!55KGM^?I(A(3*ZME-9K!5}VLj01Y7Nua` z+ounJo&>%bXekNF_t0<~87-O3Gio5Er8P4)mW2Wc9Lubzs33NZ+oul?BUnZy^)2I) zjyX6S>goiWPw+*+!;vem<@76+zQ*5YXK~=$H)8?<c?ghpC^__XH8ppTQ5hVJ=@}x7 zKW787x<A_q_{_a!^i{;;uQY)A1mMKzw2G%rBYm6?o?zxVTTc0Y=%Sa=E2}HII+13j zKnU2~+lz~f<1zvZ9Z>ebJ=a*ZIQ!E1VTWXYjZ0Nnzc{T=4YjpI?r~j~&rK%ph%2ND zS<L@<g0fOk?i-u+6)@%p;>Fk)b8J_AeFOaG%uGz*n27%=T%UtE>+sMF#2F&Hq)lDI z1FMdF5W+`6NzOGX1Yi(FyrzFMnbL4Okj))kaJ8w)3Q!IXET|6%3Ej>nM~BtXOO|8< zRkm8Er<Z}YJvpJv%Tr20vB+If?~L9VE*Mf!Kou6Uz-67*{WUFv!^8EQ<xGt-Y5|>9 zRn-n^?b6cGv9XrQ9Qgg3+$tRznX%5!O+b8hznhqtpr*RNc{WRldgmw;P3!wRkkHa{ ziI8v)`pKWaBq!(fO4UbKc@`EVh(}wSLio>~k*3cNlv(0<;s|cxZr$2}uXIGR0sDyM zvtVBCi}~~lcFe*_c$0{FedakmtfhJ%K%UIOgq;Fvo+P`(h2*4U>$MfJ^0}Mn=i-5% z5r}9wU@5QLYOAT09O~=o_1Jl#(bG3>-QpGyuy$~8c5&<L>Y@8u^6Ig=FBXGQS$Dcm zb^qu{nTv;qn_Ix7Oq+^|CQtuSecc{&To?QcLfIEr1nr)4g#SbhPjz=656GmOck9>* zq_nS|%j@YTlUseb5!71RtHe8$f+=#@GAd*fJb3Z?^<te%{-H14lX`M-I^k}@>Z%QS z#@gE2l>T&x@P8U+du&?mk*6Gu2`FzY3ZKk*six8Ud>!^pO)xmSpg;v(84Zg0C5LaB zkArSVX8}0;rL@o$$f!spw*YsKXwGrvuRD24X-k`e4|#bRBqf>4%ADG}tJ+}lP(cTC zgSzBG^#}ByKgx~&eD_L4#YBA(1?(fY2?;?7`H74&eD9<L)U-6;e_V7keth_Nijrhw zydidR7to_1#n{;Fg#MhGf{3tKZqK8kIY*P%28=qV%zwVNv*F|8TU{d~2-<jV;$xJd zZ8U2vq-Qlcx^OoGWSf-al*B#|Ycy%8v}viVtgL^)nIx-+VBaU?OTg-aafUWQO0Rhw z+5;HagF+=`Jh)r!Qm0R+td^@JW%e$ntSoP-$5~uFFe*x^tz@TgN0%f9I;f?t4k+~b zm6hTh*~wa`1@ep%f4vWL3b!v>Fnm^xo-rH%tAvzP>v9K&`rYcPnvKaCwb(wZDEPfN zvc-mm2H;^+P*4yRc@NMPz(X!(luV39pJX3BdzLw&t2^mo*JQyAm@hn@3`77eO{(3- zIyvkI3tM+IJQX{K1!f4bES;+ADj^Xe4K0mw;dM}6Ci&J1Dw7WEtzm$IqN2hJoCQ@? zRS*WNPj@NPP8M{+frZPyguTM5M_#E8h^5cpwz0ByU-xBGOxn@q_F!LHnogvn&CbpB zJKlYXPTqGX0=F+JWT64Kx7$d(dcXJY5Ivp7g!}tcX@QyqtTNC?cky#Nh=E(iSFd{Y zDwP7N6tHYl;3-ZHHi-zrQ$;;U!nNZx(AO8D3G-vaDf_&<j^F<qQbRBqO)Cl_qwQ08 z`~3X;^Xop$?J;X@cj*Iww@4TnUqb5cs$cKgi$eJx+Jm{Wk3HdkB;<?v7&kBBWN4^l zI`0)H0%GqxP<(DqC7gmIw#(vT2}!N9=wq>!hQ`IA*#sI&n>CLx{1BkXt<29;kkaHe zK4?q2cQI0b?3^++GLuf#SA&iM>g%GT>8A-fUqyw6#v%VuB{SI2h?^AQd*7~5tA6AJ zC8g?J2kjPaz>Uw(w@wOOgwLCXG5cR9R1;|#4ZFMl0$#bdx76nV@7=J>!xRw_k(R1o ztMBm4WM(7%0y}-1?W9d;#`=E$ZUXujh)7}7B<GeCoVrZ0T}r7!t*JkWFCHy>KB@tC z=i<lTu$R-!y?@j7DeptS3)=0{mn(ym7hk^-dGKF{+E(&8g-N23w0jPJPr}+{2h97r z*jALJU9lZLx$wVSs!jP*zpt*YuddSk_lf^wZ1=ybmGzm~u+Q$+miPHI`xQeGU-R>t zSwA4HHE)*%G*unN0Y)xc;&?^(yni7u@H=&e=a=jXvxwlsV`K^Nrp@{vw7+%(77}1I zJ^w4cP?t#jB|H(-XS*6YI@?$ukX?YJ2)G(NunD2YKy42J{c2<5u#Ump-^-LS0HTDN zS~irWX__n(Ff{^A_zXAVl0w**hH00Ji@lNjLo3OIaB*WU<Hm>DCVNJtw&P;_**69{ zhhF$im3_7Ci!$(WpTg=~4EDF#?<@HTy&W7OaJ~`KO?(B5Q1a2~AhNGm*DE8u!uF;0 z_H}xP>T)`d*@=*j=!$~E(!-rKb}ujCu<Ejk<<1TcK7Q_^(gHF6)1TY1PFILbY;3Br zctQ~A<7}G#&t?Q?{XwDiU4I^TWUGZBNT=vnwk1!vi#^=SU!Qe&<9jZt$HLMLkbtQr zs;f2~4|)Med=EsNmzs##%viK_wWkAS+du*$4SmFVavUw`H`)Ix07;?&LY`BveqzE# zAMmrLTCcck;*gt!w{Hsw@L0btmUMz(`(yk-fmkM!o=#3C51l=S$;gB_wyy?3%^e(^ zKy$>z8{OR8!sWx<H)fpBs}|B)Yyv(Tt8OlqeGFN<wpz_+*znO&ilxCjga9EXYY@K= zdI82`WLVvP5-(+=yTd+a57)ft$Isse$nQlMY?57Onw%6~pKOt@>u+u4;W6!qsl5X9 z9+VY;dQB((;{H4i^Y5QL{5}WljQHBU$pz*pPjAn@NCQt$X8vJfHCQ(rU>j05Z*~&X zk8?5~f!prxx-O%azufLNEtBv)cL563X7l;#)X`9LGu~yHP0W4%D_{=Gv|;w%lHUU6 z5e@zl9{AnE?dl@U8J~@bk)<UjNHU!`5;-ITiNV*q=uN~S0cvWNzyn(DI`IZ01aKAS z{-^xW$jN=&!Tlr*ph&HHBE;Q}&5bfV;UpSM0_=}>+n0?R(!K1*(rF_V2@hruzLrKg z=y+j9cKIO32jQ@Pl?g;W9XDfY&w%~wpj2n9|CN@iuD*)SX#Xq8hsJ|T9!Alk-d_N) z($hO>p%1Y54BJBXW+<ga)l^pM)|qa!hc5#oF~Fql<@}oQqX2UOhN?CumYj})oQ}#1 zkR}RD)L9Qn#LMxa@U0d5$pE;h_fsvc&E_g%10_WpTU%Q1>1($9n&%o9u`re9&^DtL zaGeNS=gc1m_n$i6Xh@Ot-+Wgyh{z=wAeQvUb;%fsh=?qs(JPpn@lzG^V`-EA<8_g6 zRSst7U#aBC(I2$pk7Hy%`2c2!O0pMB$r(AhW?3lEI7&IN&ULA9CgoeZ`#XLZv{m92 z$&Vj7{g1l@!HVU#(36l@-AXhEY_ph*WME8gN1}PgkqGh5#V`~q0@i|mV!4#+cj7_F zofXDkgl$Pq-~TR?l7tu;(LkJ@D7KHh3)#m`*YGk6UXa&b-k!>7VjIJlSfDy+XplqI zRaJk89Wchoww%wcHJ+w+bX<ef$2(aZAY_;n67>z#a#uF06ghb$A2AD_;MmW@Z$tz8 zwuGw`J?xx-vJVi{a!{S|u_1(k$<9dsnt=9SWBV(2nH)snti#~i>MA6wqa&pTcQa@M znp2W11qDG!MH9KeydXqF<igL5X$4-ZefOv!>7(wZs_JS$4;AY=aV8*pYSU)`hgM6{ zI~!msZQ%t>ahqw6j2f*5oTVqTvfloaO-XX~P!X{E!vhb^C#tKf7MEtWfZS9QFm{K5 zg_nzqMzHtA(X(=7!Ao)R=`h3}&A{CJwV1<{CkP|JlEw{v;wh^=06t4L3gqD6ME78K z?`R;fj;*e+u;|x%YHmvb&PrY`ys7DQo-B%Znu}Rbl#Q(rh<e>|NR5%Wu<QH5hBe=H z|0d0HQHWpHwFxFw<1#oLASw9Da*2<6>8*b+$C1|Q<AG>iYEXfV*;9UPZJm&ifSqbO z1Gk3eaQ4^Shxxn?Xp|$Pi)N+>PpW>WDD@e}<ulqiUa|Cqa*1-0NPM2&yPxb%%={5+ zo{64M%DgR*czni+E53fUac}^#);bnzN?6ZS9LI`{Olx{7uUAx-*<4wiQ={eTk_%UV z@h}TehvMSj*{S{adg80AM}e(O$KyOWesqb9dEOm618~YkTL`N^UgV;41rO*k717f7 zoPd@c&baJV+iMfFHm|>&Z)JP@va8O1hiknm4>bR{!qsk2jYbifC@NOXcSr^`H#g5I zJmAGm1ilM^2LQ8eKLd*vh5L=rpFe+UtF)Sy-6o7k?2C^d<rF(u-6oUqpTXb5d6!XU z1oS)&_?^F#m2Dc&X>f*FrcY~eOzw<=>>8H8!`)Ivx4-GpD$5H=YpKH)|YDW=HMM zD=NPNdR)J1rx`F0z-s@u2~FvLo4~g|DIPcn%)cMxaxE<>z!XEZ(5XZ>HwS*v%26Gf zLYelgUI*I01&@x23LeO|W@Xv{|3E*bJGG;x8XFqq2X1EcS(Rx^*?B$DZ*XrP7^rK^ zQXd$dntDFPOy>=?0LmQ*Bj8d9`}o`1#8)EY$j;KH*R%{cgiugU;Cx?SEd0`CM_m3( zP_O{i!w#T6nG&rP>9Ek+_T|9l9c^Gkrb<m2n3$Ov=<R*TDr&Y84E(CwSr)(|3{}_D zs&F~j2SIt=r!(`vmx=Y#@e>;uY_iI#Gn+d7Yjt@qvX7sSPq*4!Lr-sQWLG^d8OW5l zWe#8~l_d3e3N|L-r`jPgaIc(Iu)QNSb=_kI|9UpipsI==*umrzio-;`zkcT0j3@h} zS@eH^dk6;j?*5u9E$sz-G#HVYiBlUtzv(*+g@<09(VR_N$GE=ckBP3|2M2B3QH^;^ zFP2nazRZ*zt}r<x0~QmoqXn#g%R9AU!TkIh&UL=vB%oko#s(c0&Do9Wy%)^-^pz9= zkDerI^=y+~?KKRs(xbT9&P+2jIA~bys^R8_9(T!yzlH~!mI?6*K`brTIa}~RPawH_ z&(zW~-5tFH@(uL=&Nrz-eZEW(umuHdI9VWz;^!A6i7Ac3o_d7?9tL!a)So;B_6Yoh z-{<Bv1Di|KhCWJ;??_aHWEaZ}$0nuCZ3=R`_nra`)6K1l-fzc2!;R5pPj%ia@TnxY z`R>X+US8b0>j$Uxw$v`x-n+%6r5sCB&x3bDagdnD+(&OKV%Ji2aDYofKRO5C28E%L zivChuUfx((&*Q243w7T`K~X{SaD^7s=^Y)xMHp+)GG;+Qv3vt@E-YFHm~-_(=7Es` zakr&MBmh*nySeoyiA##uya2la$jL42H|%5PhVo@P6Yr(?pG;E%L0C>MyrLYz%iJ4q z-Zn;BV2%#+IXh)Cw=x2sdw}f{3d9axZK*%D{pzZ+6kZ>H^B<td?e&oKb$haX`oCh2 z@~_oR(=Hd0bLsG;!8ZNmFXLBR^#6wL{~rMV{|AR&NBBom>2oA>nwGt2vbuOCP|^UG z&_nNwWP52>@EAid@R#`gEGc&Iw}|*mBy04y0jqCz|BpHJ*{Ol~Qj5>ZcbPnycCL(E zRcm>97uD|ErW1Eyo|~Boed4ng2?SUH-~IN^8Xw3-3q6ur?2iZ0AKoz`WkT#rpDpRf zcaI!Pcs0G}X)tGO+EK#TC;k2g@(sYB@{oCFFL(F-3NzCUyLG|y<;Y2)+#Z<UD>b#f zb}c=Jg$w7;CHytK0|xmPnGE~6KVTxf6XK+ndou(cCS8u=ILg%2G05;mEqkznS&Mci z#T|jg3q%TWiO-MGj?%`g_3GZg!+|esQ9ceEwc_M6C1!O!i($yv_?aKnk!l*V{xp1D zy}^zx?_hcAXBPx0cSV442j+C;G}6k=Z>0b#ZFx3cA44!g0K+^|gx%ZO1@d#9m$0b+ zQ9*g(TkDfi>hprqg2Ixb$TV?fDXE3unSRXk(Iq-=Mz4&y!h4z>=hmw?BxQ321@R!= zY9boJ{uw<;%;KUYY<64COzmA@;9QN7JtM@5IpJ&nPhbxAnO{`N^H*PtkS0g~93@aW zeGl5k08<zy+?UGjGm6p%9=wVA<oE9vZssfVppglsM8x4!TfeS^CF`}E?}1HQU=t2m zOlT-3S>xd3_z)=K0G`nMA6M7c+eBzx)Wc6p@I)9^-HfJ*PxjxNq_H9+9Fe2Tw^hE! z^!bm5HBG2jH*G6*83WlA`iIu`1=&1R61I(PY5_DhSxj^D_eogu7>C_#{f18{l!w)_ z7koZ%ZOH)4vBfI5sfULL%>MvvAn7|9l@M}jU2J?ir3h<TU0gZ+eTABeYAu>h^i)rB zlK{9Q&bO%rQYswr;wgp!%XO6L>nnGfPbYA|uh&>m;IxT10F0zUO(};15ZGEyk1L)& z(Dv>N%g^w|qqQ<(k!Wb;ZhBleCA+w<dB8K1=8%Rl;B+5Y#DPs#RL553+QkV*zEY4l z-@TrENX!cGKN)&i50NQL4vsO?rMO*$Wi25VyNmwPr3>rb9;n;%9~0dB2qsxSCfww^ zg`{nJdM4*do}unk5!QzUcnG4ZiAby+>wwquVEV+^-ayg+8J$a9-xzRL)=;N7IPkG2 z)+DygHEu7ph>D7aKIUgf#}Z2#Rhy&Z`y@<RZiv30tUiAVwLs^pF<oC>qh3EmGyf4q z()gUhz>bpGW(t%ZTSC{&)F~Ai&SC23)K1qJsG-3=4kPVEPSVi#t^2L5zU_~Msi-zj zt;onCf%%2be@lgdVF8pypp*(Cz>YV-mec*f%{RI&1VWlT2g=EqqvalbeCS^l7?@eL zSF2p@>nO~h1eZg~0b?25;XLy5MI>jha3~oOMEs&gh47!FIK~4hlA^0u$El^Z2229x zzTxW)oxe(#q!<Hhj->y2_`I#t%K<ARU$)rkR4D)jA>Jf0i0JdUq5_3oNLI6ilj%-7 z5PidL@$<LLHUg9Q2s2jAcVp#_u8uBmhM(`L>X0f(3jlrd%K1Ml1)KIV8BVUJnyaWZ zn`#wSRwlwDA{CNTQpCiYfWfyF6RRKz{p2ic4FW-rx?%of)<b_cz#srLFv!RXSR~E; zz0uKlu$oDgUT9|Drk6_<jOuB0VI4^hj%$%@FP=9<z^RTMbW}#Jxe&@IVgw0QtJ1=M z4Lm$OY}o|NC5yeawWfc17<{o@68bFgY5&ATmVT?<(=xD^RpM!q-OmjMinSX5T`PqQ zezRjXba;^T)pu27thqu<UEBgGJ-bp+RJLh1AiAU!-^p?$v>fdhf$9msTW>(Oc6aYI zop><k>r>T}|LN~<(`c+bcs}pG7iQ3W+eaSV@GqsxhMe&!xEEiqynqf73K98^5|ESb z{reSQS!&_&wqmxsw+L@Xe3Fm29SP=F;tIcS8ZGVkcoNvl$3hwAEzPj{9&BF~fxjM_ zM8LhhKOw;eF}N&KEce66@1|w7Q?utdTRWS>U0gJP&P{1jz)r3#zHO&y@8;!&kzKx+ z29BLn+cyJi#xmfB2CAz6=D#Z`Bv~~^mPo}hWSpf(24fvPCWe`LS<U8ubO8+orNxmT zXs`Qo4;2x!?;?&%e%E9sZ6WRSk_6X>LNy{bm#!t~bC{I{lk311&0prK@~ZJlOG08~ zAM{(zP)rX_6eD29uRVD=M1<=c>%^8SfZ<~&x2USJ(ws*J%rH*T8qoh>#AEOmgx?#{ z@#)F~e$>hcBO`5Yjyl`%nM2be(UCW9mNU&Jfg(J(O7X|PTvZ!y2!{fteDW0u{1!%P zqG`mzCP_0(6vYZ=a|VYj(c9l-e!LhtCeX=D1B%0BJ|{U(?co!82TLMh;Fs9m+DaBO zakkKq{)0BpZUk)rzc?7kYXk&EAOZoyAWaYt>>U>R%FJ17V~CfJ{Q4wMoTmn)K=;Rx z3<b5i=Vj&~V7=>gy-FOwDeELe1%T+r203^B#syh<YComuW3<*I)Hc2+(hnJ*5!$-x z<L0+xKDT*f?URj46`dNOJzC$h^ccl!`S?t-A|!xG(C6HbSp4)i!?gG`q7i@DC1qCj z#OtVP8MymKOLYzwJFLLoD=z@K!dy7rH;!^MGv_eO8R1c>PRP>z^|QTv`&q?Qt|M?v zuiVq?xQg|S?##POm+mG0`MUtH7MzF+v$>gCTL}Gm2ofz(Z(^qYV;9gfg<4a{N*jAy zKU>_I9g!6P&0_mMW5Kp(1nk%YY;KYbxNzrwON+2Du@|iux3OJ|atMhCda=IOCNZ~l zbgSz`fC}|;x9d43Z*`VT>odp6-Zm9fo$aHf=EQP#kN2$mubUAoDc)WG?4`f`>+}sE z_UN2R$Y!!l90-TYd82nHg+rh@JH4fgN;(Oj;4A74>MCA`qbasRHc{(SL>F`SQoY{b zm^Y4OYDa7KpmTR*bESDv=?RI2dspZeHMut5-L*c&zv}%PC(0ZI=GbnDuGPfUl>E;r zD>VyCaokSwWy}JpX2fwvD_`^1X0NXOJ>TO~!vpDJ9@_7Z*4mw=i)}uf&P5Ogna1dQ zwXkLyXmZkx?~lRr{=ImLryl;t$)$bOzoQP@yCX!(PM@xQV>Wkvd48v+S}@Y?1o<|6 z<F9GpUXrNzb2cuj@!P~Kw6clg?0xHW#%in;dg<e5A?oq{9MqU0BZjoUeEezK^Z-e# zN-TdWrSFrw;frp5Eg@h2$sRL)alD(rkP+ENd;v*~53wt|{L{wfLuN!V^ihFC&uO;x z8efQrUp(6(b3-=nUCsVafrPvHv@@!j(Ke&2pJv1uoDTn&Q(T4;I6_{yPMRdB@3nVJ zt<b!VRY043)pK5~aNAz}&$FkC3i^53M%p>FXOYZ`9F9f0eymxXU$1v=pXj9XTAis{ zyL`$V<*@8Q6mT92_M$?~Kf}Ia@p}`x6E(I>*+Tyid-MrcED^eo0L`we%L2Xx>Q|r% zpREnuyPeV#l_b0zvq!DPVPtD#DuB{tNRHcqxw^R-IroK0^8WFxylFvzM-bi_5ub-E zVT>cNkEW-^THCTp4HZwkI*Gxi#_gTmB#OHt$ycVhFP}1P9qB@c2gYL(eamEqT^cO2 zs&6JHCkYcLHFqRe#D>RYZi8yXkAaz$jn9-V_!T}9uvcKOW{2tBKR0Vg=-5dA_W6Z( z*5_{4#^JWNf;Q3qU^BAyvrJ~PC_to;#=Lqg_G_Zta^&p(7y{HxC5B!`mhQnVoBslb z=3x29ie;sjk4PcTuCD16ceAof)Kql*_ooW5*gx7ofJ=#~9|2-AuhaLR8>|CaCNA)D zzLJZ}UVnc-AP(aaU1Q*$Vun!9%6IQ#wWt1Yp@7zfKNe#vY-nKRXAgpdrSg1sChfYk z*OJ$zfSDTNm4<)nNYwAXBH^>yg8zHx)4fP4GUkwRp_d(9N|yQV?y9^%0^_YJD4FPS zC~x46RcKsLlI7{@{W9SBFLVpqDD+8<gXBXnc4;-d=EQIIY(cSp;#zWtwb6H9Ni_Y| zj#%GG<Fvg-z}it$pD2U>QW=?yWuKCqyrPwkfP}={0X@FPs&kEejD@B2RyNvvxhFO0 zb<H?OoKZ3C%U<fY>V%pi^;OD%t?sy@1cy=e<&s`tQPX&QSJHP+2AzN$9HJQC*e9Fy zO-rj1@zsSY!}<VGb1(S*o~d{UArVn;S8sS^sF}|GX%KH@4b_c@nVBX<E~D?2!?}_o zbFIP%gB|9e<Z)vZ?E21&E6-xbA1fFScf9{#J=E$_?kx5E`Sp-%;Yw+IR6gR$h3b!S zJ39-e`6)e1OYwTG&yw>JIQ4`DEt(aW8b*da>vLZBrY^2CYpLDcixmvm4@qmG9)GhS z^j!AUtF4NZnin$d_q^)~!j*0l5#4#7m6fGc;>#l@X8MyyUDdfT8%Ol;k+qWZi;i2l z&)p6jmb+TbTGw!ggBBR;@W)|=1x-5cm`1KVYNS(?Nyrdp@g@vN_WqYUljA0TZi`Fa z4$4>ZHZ)ULch$A=2HeW}_)FYUuZIu~uhk<Woog*m#2k3;-+VYXM^YzjyXWm^Ya1T! zmZZ=T)@|#5D)T2VB(^ebP9(_jlo|65>@zT4Q}%p+!}{Bxmi8~cu&nnhjQ410YA2`p z#W|iGx;gALO8OmPfRBQo%D!U(dGk-ldKHbOvv5pR!1CKobz*CjUO$QJeni?eb0!+D zOu4jF93zXZ6J>WAT~FdABajf?Y6+O4q@%k}N-B4wtE)S<%lu@2^A!1=lagIGHTBcH zSs^!fS)9h0<mpO{A?*-FPM>VzOK@f{!~6B=g8?v;c(g2}fqloF^Kkdgh|SSyxN@mJ z`+*oooE*C*5<DBMrbfI49rST<9^k4Su?!K(p3e4qcBJ-qE);mGXkWj_{QPNIk3*s5 zPHh!64*csAxMvpVsz|WKyvzLk9nd}H>!srKH(tKr(p)&@Uvn6p`c<{uwz?Wt_XO9Z zRPVh<6>Q?Zc_y`uX}wy2Y5iVXd-&z&N*{i=6Wnpt^%(qh20p&wxYQ>OHqCo~CPY<W zKQPq{BNLGBSo}Bh)gGghN=Gg;%+ADda<uyy{`82q^;z!oq=c07y)p#2w4>u|$Bqb{ z_aBCjtY5x-k`bWtYHK_&G4WS>H2Yq%jl6s;6yn9hYo%m5i210-Fgsdi$#~D!_aNl^ z8r9}~VRvu)jUEFZiCVt~eq1Qq+{nz<ZeDOl{j`syP1E$pR6dVI-#=-ePCQo7Pf`8- zDT4N)>OR*2m-@e~b_|-2>;#G&1MWV|DK9kj{59uX*Uf2^%FCQ|=VR(8)!A2*BO`Op z!kqDG;o)g?kBA}fU)|NvFnD&ux?#Gzy!b`-9!;#p`0vlZKYZvnu{_+;3c#-M%I6M_ zyL{|TWjDE(*V3}tJ+kwOgu5*^v(vGmDRMyw5tVU{iLIV2Q7v$FpHJnrQWj0?ota5b z;TN=IKGt!Pxrub8rQMK<&&1;;q85Nh#8spzI()B@qe?e>;B{oj%)5~0MK1{^rcsPJ zOHpYB+ho7??5tH(csTR>EwMWHvs=iSioI^_NS%1Xn>WFx#nOT%FRX8Y6=jlw0E5YB z9WGZXzaoF^71)nNY6NhV5s@FpQAk}buFYX=O{%ffrTAJ8dyR<5=GWr2^*UY>l9*QN zgOP!EfXI9M_AS_#BA5FSiKgjOxl2wV5SfP=<ZX|P+<X54Oc@S?dgHR&<95|MNDBrd zmy#Dn>W@`FF3;5J@QbbYV|Ib5K11hb2i5GE$<}srvcijpE5M->92|5LA<*eG##&ll zT$Gtvnm_hCTNDi1HwLpEO}av++BD-&5lXkSPG|QWb54Fe^UsRi{f_<08pncoCzspp zC;zcs<k2aYkkA*^!W$25;zXW2VPy15cT8RO3VP0sx{VX#9A+eat{uOpdjc?A!I#Er z0hocKqoaXePf+;s-CK-vUH$!^`#-m|7?td#hcfRsd~XuDwFkQu^f8YS(Y#ad_#q3E zm-iyT@SpVMX`^|s17a~{l~2*(ZXTR1`qj?uh4f<Qq;0p2n%wL1_VaXeM?>B>*Dd5f zzmgpPnEX~ILTi__gT89Jt95}@%N)NoLJvaEWw~!^1MBQ@lSp$*3|6N7-Y6van$+&Y z_jgJ(8$^5}4e5D=gn&Ibm`%!XnW`x8B+gtXVZ>C0B~D7}9k4SfDeL_Zx*t36xRHt| zWZ~B~gM7UCB6_K2)`3-A&#p>W!^X|f!5_O?_5RNPRmzpeL%nu!y)L1;xVe-y31!Ka zC2Lnm$eN`QBik^VaU(<-bSKI(LX34L>rBZ~jAbk%lFLNbtr<(!82dhB8-w?ksrz~V zd_SN2|M~sSvz+Ig^E~H!zVQWSBb_yf-ICJ2a>mBS?ZLWsZ!H>dFC$Jqo2G4HHe4ne zjE)-W<n=6<C#0JfwU!Q#j!wf>byQWCPJKH*$<duT%{*DZ3lEB$k@{%Moam;ab1!&d zzwhToE2Fcl%rMi(ze0xKfyYsPguxknW*}ek5z<^W6X0<$Ha9oNQ=qa)7Z|nc<$P<B zD}0HdE>-S)v&sFABaUKFHGU(l^YgvZ7+aG<Di64BUAIZKd8a{L+61v|oYn%b1-d{K z(nA}D;k8vt4a*a5OUpxt)aKeFJWrGqRo4|&>uAZr=_Nq5aml5OIwIL7vcH)Hse0{> zwG%sT%w&E5OX*pCVze?kFkN8MehYjPEB>>dsU4K?-t**Xq#t3lT+LU>4X&Q^bL2Y2 z_|L9iv)pI<u5gw)$+J$STR1`q-B5~OH5pyT@_LI%Xg{6am6}E>`zrtj&?p7)rXHqE zPL|zFx#4oR6-vl>CVbziJi=bVQJVR5keH+Y5vvC#0`51czHxKpe*XiTFPmG(eZu+; z(B2f$V;Ll1b;ou*06S-nn6|a9#dW{xqo)Liq~dqVB!{%RcNBvN>3X+)l?`!%EoFxH zFeCsxGpISAnr2@Of*G?C0cQ>r@hd?jH_(l`6}3F;3fr?zN>K%?P6pCN`T20b8)s&^ z066lfy@$#<wanmxYOYx^YG7)ocVgPOPR4`|nmq9Nb7sAQt6bV_2(#EyeNGh0EA3n5 z-?MP0%n8>QSCkkEK{<C!WAEQFYqbKzhl1uiKP)_dek#eV!G})0p>e!PSKV6f%$a8; z@++%io1WM%@IDaQg-q3sw%rl$py#<sSQIOSAhNG3B*n*%Y^;S6KnB#ULah>iCSg&p zq@$g#|55cQc{pt`&l=+DYB}{%Da%S&P;fS!o(d3Fn4b|GPg&BN$vq1Az~Od;jF^D2 zZ;w@CLJklNHJp9Kjt(1_(0EfiCx2Uep4fr56Ou++<p}T1DOUJj0Ev)^H_xNIc%|3Z z31khYnQG$m=g${j4gE^SuH?RKyHz^?qfZt8eF3(lVd<luHZU0!-Z5bZkzFy^!}rZx zhCt$s^Ie{11FEJ!SjVH{C2POEueQi|s8>X87i8GRb>FN_lOH|rYUj@fbyD5s?@a~Q zB!l^AKK0qw4!sno^1=6-dgjS#A_^x8y+4=Ou1ex>I)mHZlmm;+VA_^a>>~^9`|sP@ zIs|*QF|Uax)x3D|nzbft{J8VBu3H2&q(`*O45B4w*(0<QmND4hKO5M%A=jpQt-BU^ z%Go|hL0*12sc)a!sS4zJ081B-^!hQv>MHLS_Xq-zPrj&EJFOoy>9>Sx#l!);AFXeJ z$@kSPdt5AUZZ3hnd)P@SrG=N$=jQ@gqt6};B`B+?klmVmJHK`)3zG+ei;aIB1zNCz z-_S81KD-`yg|2u8JO#d{HoIg<3}gxfO)bpkF5E1(fN7ls(!YD_3Wjc(Xf$aesn*KZ z%ZIW)gFj(xeq;NQX83$4Yo<){a#*ls+Fx%LLjypA1rmWQ@6nD1GuS1b`tT}f=hwu{ znSP9WoA#p)9%;bSiKt-ihtla6Owr);$NA)d00^`-i_|n*^)iMV^4f6;Jkr{5Cm<CA z%oFHe7@hS4T=LXK8`J~}5vil6sI900@$;K$eWc-kL|EA>>eZV$Vneq})h}C;QInde zz4M5U*}IYkp*r$<%Yad5WK5Mzxi)|K_C%pCipTdOTTuAxsQN}#Y0{H)r9P&GA&$F0 zB_tL&B1jiG7sLtKLgcAw+Tw|;<vo4kUEBjvvyC4?9lQe@e{Xy$HU%m_r*n^7@}6JQ zzI(UEc@!VffBaiEdaqJ0kTzbo14#ry{BFsMH}OapnpK=VNz;oEG?L@xkg*e5Z>6Fk zJyu2jx(e#LhKBhK4Li4NzCp#uVsaYO<GN9+UxvVW`Pfhsl+?A|tTP<<#>1OgK?7as zSvE$5w@?D$D})>1-%NG$?PQsLVyfL?U-Elc4S7u0dt?1o{!SXMFiKDZabb95Qaogs z4Nq(#1ELF|Yuvsp5Bh|;zo%_9HZ}Kz$*xWit6S^n(c~F+IR}vqi~;#n{mAskj6as; z%=tIDg0=%3c*-&ou`^vtG2q~XSDxrAlp<@e=`NyJg@6>@u0Ag)v@XL2q(zf}C6Jab z3h%G@+7{Q^veLi8MzpcCU-UKeNOPG{vBN5B^O+nN#^lZIIv8J~r~VYXv>|yiEn+c2 z!2UwZwN{!6XPd~e=L_tQ<viZtRE+-|Z@yaFg?z-msb}Il-NVg!E_zP|g*@>5J-RlX z6xfYA{AT6XSJ?7I^L#(G5kXAwK*XHHZkUM<8#l*Oa*25wxu9ORC-b&14gKlaSD&i= zxgdkbx6%dA{T!^=!M(;^^ZKt}>eWwku?ZY6Svkl=I)2%D=-yYeq6V4Q%i*&9tz!NV zEX2Im{!W32G}7zj9pM3BKY$&9bv@uxQ4R99IDd`SmjtCypEz<ejc&&X=D^qjyP4{< z2?A@@xcT9GSw`B?i|Uno6}Gb6c2Yf}Mv<C&TVc9V=H1c<!VjdZVhs3)m6Wy}8>$A> z5U;W|Q<QaC{zD66QIw@>58UMgu{yBBxky10rwa!DpFT~v*Z0Pat@&%kU6*47S`ZS7 z>vyW0vg1d@Eu_?wqmrppwu773z!ayYJnO!;c=vO&iW)&RNRxM<!`+T(J{7d29INR5 z2AgSP>v92gj#IC|N{)XaT1HL(oah+Oc;rtwS!lLx(cqL~>Fp!vM&WVAC}9S1ghW;^ zn3SMZU$hRWm`>RSN~hY*h`mYNv^4@+_o-0{l3-C57)TU+`l*v580zJ4DVALVjk4-w z$l_~ODOzwRRS5-&-S=e|Wb;aKN=p7GUvpk5NA0cO?c_`He)Tp-f<+1=#&f@O^;@$5 z3z@>gcd^M)dq&*^=h#K6p_ennb$3nE2v1}j`$)f)@=3diSvu6MXD?hfrya7HL*$kI zGP+j=5+m*vW66_m!$8ofBH!C1d&#Akh>HsFjl2v|`H2;M2{z0!`p*(~T0Racw(nFL z9DKG3mVI3llp3Gf8`$wzV8>9^;ihH#%ZiqKiRYtU3QOVr?N)_MhnpQ24LxUW4{R>E zA_bn9Fc;?cue&*I(aJ|Zn7dc61|q`8cCq}K$B<7~@W{yh?Xbi)Vd0AgQS&zZk*vU2 z)RdzQ>CMt3>~8o+J^n?{gFW`>S|qByyzC3Nl%XTgWYy3lkL>u+eX-J{nDNo&Aeg_m zWCY_h^6Yg`sgK8JqxPQcD>}`Mlc&hU?0|}Ds`D9Kg}~n3-PYH)8q%k?>yKdZO^A|0 z0(Dm0Fs#ud!V_v+Y5#7PeY9&|G;Ppc_(dy<j{WinzWWyAKU@;$Hp4!JbGD6E2FF?D z?kDpcj~Uj*|DEVA^s+aWuQ>Lhp%)q?rodVVy7)-yGqLj7BbyJdxw5P-dZTffSZKfG zSmHPD$kBqkA|J_{9k;znbTRHfdy;VJs%e+Gr$BM4?PSBl%lSX`cCB@{HNL$H@85z? zpW$<Zo3%+`rXgokZU^9nP$uttK%_+xDbl6}*%o_V>F;5CBV{74u)VY)q;i?L?FC7W zIz94_D&@%f5WQ`<;N}M&9n3_J<o@KW$bR!yX=GTScC6`pA0s-*i(-oM(E~yKpWOAQ zmIO?rdNR`t6=|<i&XtybU7%`@`j<CAXZ$cbE>n%BS>OfcvCz^3E}najB?lPmJotK0 zt8P{z<>RB+4wqQwOEMqXl3&o+1x+7oj&iG_b*Be_#Z|>nh_#XE&M``#U!4O3ofm-J zd7^cp_46=dZbg!PT%+TFj-P8h3y&>|bt^d$HppUqAI;B?Lv<Y|A2{st_F5lk<wyoX z{eeMnq)Gii0-yN79Puuip?PB^HzDKC_KPCQDfC>+-0yf(j{B0<!Znx(9}_;)gjLi^ zE}80}()yi{;n-}zo8K9ucNnAL{Z$7)k3P(m{#}jdkA^mZe^3YitB)NtPH`8pJu-*d z4^;Bwe*nTqe?SKQzhA|+;8ZZvoQ84-BWbxVvc;g?Rp;?w&)U7{kW?=%h<LLnnx7pq zREx)(|E+R?t?5XB<73Q2*3|Bh)X4)?9&>!GL6HJ>)Mzn}u>pVY3FMIZ_X=0`HRQ%B Tzi@pz&~??++N9jr<Kce+_wlu4 literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/add-data-sources-button.png b/documentation/operators/src/images/grafana/add-data-sources-button.png new file mode 100644 index 0000000000000000000000000000000000000000..9f90c5643a24ad2c491941d46f62375111173369 GIT binary patch literal 14954 zcmeI3hf`DC*Y8mt8;FR~5s;3AqSCuc0O`^@2uPP8HMD?=G-(gLgY+JxLuk@FNJ;1* zCG_5V?)JU+{sDLHJ9FnZb2FI)PUh@$&faUUz1I4EcF;RzSt0^z0z5oCBDuFvH9WkV z-|+Bm!0z4zN8%PzO~4nv(;GRByLazS&8z&u!+VM+2Ys#Kmb^7%X`rr6e`nX{(VNfT z#Lag?zk2d$ywj@;)3ckwpk!zCiZPnSReJi`GnqDM)Jf_eqr2=+J;R?r66iiyunFPJ zN3U32AtW2$!nVavrkzywdxcMKyOV3V{sXSLxvQ%UzW$g6Jim>H_x`@geLTEhlr5Ba zc%NT<djWniyK4qMJ05m`&k%-?8+dq>Qk3|3c+dU+{|Wz(duinNP{dCp7>i%BL`?r_ zqonxW>SG7$0Ul0rd71q7`R%ha_jSUpk6XR+3g9(Yq=*nlFiDvuaN_JVb|qT|FpXJR zHAO{5%jiTt*s=9HI1|(2s->#k)M;FF?9xh;pG6zh7vcvp9lH(*f|f&N*-g}xlm)Sr zG*q~X57|L$Nj{LRG59ab8BcV*^2#rjbse3?J#Gn3gDCkn6o1LF?#Zn0?fbp`{XwCj zrBzjD%Ns*lu>$tlH!Fpi@OH?)z3_s9Q>dw_u`4T;)@bF*-@S!M#aMcJ`iqWs4-XH? z2ZY5Yx1^*poAH~p*h%f{gNcLVv}Zy>4nz75sWC&pf3MC~u1p>^ZB3RhT7Q6=nznpy zM!;qsxI@U?wy18n%~}0K;{C#f=jOuY<@bF9P9`h2KCO1mO~2t$+1U;3l+TXzT%X^b zK)HD0BYZ6fGak^3>lhel)IPz-Z~dkG+ST>=*|ToTfmA-h^1FnDER1yFEBYngBdq;L zhlgq6!6J^E?^RV*4=lK@rr>Jqq-iJH@V)(7*>E~58=EQ^dZ2eiUtRs+I7Od=JGHp1 zDwJBldbTM0Z5A0hoyX>>3DRGTuEac8;OL5)z^_FVZVa137B~6(@AgeZO^>MfqAV@U zZwDBlhlZ#`+}h?d?})hE=j4IRRhTyv{6j<(>Upx0-1JGNQr5l%RjgMP@s^o{WWG~{ z?imkHNjhtc?NpJqLd08Va3vm<v`&-o8myN@lhTH3<Iy@K###Kdr(d4|I$Eb~EPIE| z&Ti{?OJs6lf?mS$m8K7}1vI|?TjEzwkI1?1(ih(g4gS)KiuF}`D-%^VVV1Q&&4@D| z){H_?COmqAkdS$%1?<{mva7?6{`U$B5V)WUEd89lz&@>{BQzm8F>!x)=<31s4W=e4 z{o043`WNO3TGTW&a}A!oJv|=#Sya>P{|>JBh?-1(zLr{8Fx#1HqM>{^TG&YeWsd50 zc5Wk4X<<zL#=^$7wn4*bSf3%cXc7K~zN4c(j8dXwu=+K&;Xb{<`hgLG-cQ2obk%!K z;wnkdRt}n&m^jxTPeJ*Rlx|OmfdO{<Q<YZqAIFV5t^~us-OgrE8@Xu?_zuMIk{qQ( zVmcvCSq{YRZmP$<prActV%mvj$<I?uz25k;VU$Vn(Uc@4*SaT0zIVJ0rIa|vT;Jo; zU%VJnVM+_3;%}}_r60=z*DJT|x1XyrTV0gZ)uoDJRkp`eu#jZu=HBybsW~10-ASA# zfoMS+vy(cK!A5^}|GJjS7M|$t4r=f`wwpqUSI2dPCUVDDXJu6^&0dL0%pNTxnrfDL z)uv!KcIkd~QA#kT(ivUgW*>tm;u5bkoO%E{CnPkazn`;a$!e(HrLKxLXCOX4iiw3W zK~cb_O^7Z$SK=Y*-GAnklU+AY=kWuMNrwCsR;pl=E?ehhj0<~i+9ie_pw~=H7)WaC zJioV_GJ=1ve>2P_OE`U{Y5(3HY3NxsS3}iDHa;ZzSzjq7KS=iu?(@AU889Ryss;v% zrfQ5NMAXki0+;(z20}@JbtVeH20~f4wrE>1*FAPHbMxZdTzYakd8kpU#M+v*BzKCj zh6WVc8W5_+!@wpe%hAu8vD~jGU^nd5QPl13UJGqoIS_Teo0rbIK3TO_vNQIn=kVUN zox_{-j+KUU2mFyQR{=fPGGi@ntgEG+-G=@kkI>S3cJInm70hRG*#*Wvi1s-`X&U%} z4u)uREpixCBh!$nbR-FhiJ^4DCe0bb5vnRds}tpU(uA>8G)YTKZ~x1n9|GUR`PVm5 zQAs`^*5rr*^Y^Mqzl3Y*`d!oe=|ao2%uZqlIYlVA%b1dV0qbc+#vyT!%jYK*z@OIC z#P{xl*YDo}sdTeiS{N5jP8va*GWU(!j4%243d~HprI|>&v1P#H==0f|o0zPv{;_)h zp7M&bpv9=C2TX~c#xsvTZ12jBWDN}+Nk`1$T;oXJgt~@PmAkup4yy%pX?~j}s(0b> zLJbylCoon6J`Z<~G+}roVO0-HvIrvC^LL%)Tvk?_7T4q_6<XSq8l{3Fxmz=+V<Fdt z!1dcMwTc5oibO>Bf$I`+U)On``*fQHc)`(8QpVxmzdt!RT-f5cVYLBuaR%Ir17G8E zPZG)pA$@j{(a})ojKmg0j71%)2D~3fq=GIbqo6>4lEIUB8lU4I?gu=sa#%FYykWhw z5&P)J$*kId019~X_;g=O&#)c>id|ng=43^+9I4KE9PLck>gwsWi1Q0p|NGXtR`q=~ zQd}EXRqE^WxiQt-)b#7Sylz9mqy58yo&m6wu`s5;b6Pmf4<_ff9sg1KnWt-DAXdIy zT`dx#p~=yI4I3EE%KElF<5_%dXZEU-dm1^yJDicpq*+*7QzI=ciG9E&c8N8&R|#Kv zyfYnmu(v2%(4)=%#mvG27%5kOgr1(R1MY+4M0b>IVPTMn`eR;*!p6V<+7_@33~*0> zxj4rR#$gHh{R&JoQ>Fc<>y@G014uDCX=!n+z~27h{J>4^dD(R0TI}>gNioLg!1W7$ zMFka2GL|8<xYyEWMb^Uk5InC}&tHO$ipveR`4yd#a`b1ufi*NKDKRlc)F(0U{(YjL zyq`Zm>%Ue|C`4Q+dtOiKrax4FTt0qEi5~eeU|6gABc<HhTqT`oHn<ub?R+uCdE+ zYokFoshUgO!6~~|9h-F!t!xt}33-3FX)97@9`+!A+~D16!$>XZ>KMh^ubd(bv$E<^ z`t0;%lXk{nW(>C{N+K*Q5+LDC_g+Lq#JiD5tK=$1gK2<*X_<f}J~8oGPj7iyIq)?> zR;?ZU(}4+{i+gTjFs&awiFw-Sw$bRorCVhyDoTpL+^bAR^cY{hd?_a<cW%~7z0E>I zM1&p;6BkFM%1CHl{haC@xfqTiJY0X6V2e6E)k#p4fy&5q*kY~<daO0A(J2u<#RR(& zt-#@t1BYkA1KVTCa9UCE^h8&dRV+Ue;pfk;udny@!3*!?efcs~!o}6gYZJ_V2x(+$ z#OzORGZ5~izvInQ7<07~{gnC2k}YmwfiYi09!j(>xPEXJSAbVlSs5o^e(UB95@FF= z3v=_>m>3%?E9Z*}*%4MQj_~>96a(NS&FxoSK`|HsBsWYD_RnKgHMNY;%HpJ?JD{^_ z71IPP2WKVK)uMvl>MKmO&M0VW4^B>6^yLNV>FE^^cB~72Z&Lf3d62xbEC`zp5q0%@ zGnDP5{pHnDas?T0URTUvE&nLg&_d=mNu~W*gudnFcsFB2plIIG60;?nHZd^|Bk&l) zKC_XjX@~(kEOxC}gkmsY$3#<OTw!Y#6&<~#Oe-1;)w}uS>GP*n{q{60kK~9f|M}DU zHR6RADJSRpCyEeFh3)AEO&y&d>FLd(t&UDkRd#cS=s4fT)62sB{jw2DmF?N`@_l=^ zYl+ji>aois+v?b8QhK2Z9&x5nh2RU~?c>cM%T|<~bh~tOvvzrTxrT`ou6f2t{QUHE zG)cg0A*PUmO)0t2d@)VBy<Ik(R*fSj91<F0wrENxfol4&$0IE*O(1>NEOnuhCjJ^) z4V$Z>^D@7lrU#+v!NI}tWu^L2VOFawaR{Y^>*D#=Jc$W0{fwX>?+Wq{hy{%s9bapf zdE9%cd!5?g<H+*XDNDcF{<3W6m$&gDTLz7wuXd51mXy+{`G*{Op_*!3oNv>n=yM4M z?xhYFCMhP^dymECquWO`11SwZfsd}JIBd($yhFUh#t7_Eo8km<aq@}9t;Um#w5zuK zU3v@Mwvo?AgI;l?CWoVM4(e5Qv&HY&Q`@0D24ZnEFSOyn)p3f+Qt)70@Z5~8tgS&@ z^1;%w5cyh*_2J!+P^Gf+a*oSl*)Ol&+t{$i$U|^^y3CKBk;)?#Bi{D@`t_8TSIUJ# zGv@yN`_hc6SoGoHVJ()dk$v~fOG!xyjZoqLJu*UJ{rzP*N9@x_LHCJ59UZgC2=bAv z>&`5wn_wz6*pnFz50O}!TQ(l6m^H?}diwl@02e!F-tL&<|6auYCYv=D{|WggbrA&b zT|}6YCnEfYmy$S!?8Z|@wdf_Rzdhuw&>)I&*VsSeMLqoAwq2un+x0ci`|k}2Ps61s zTRrc{-QS@(lye*V@6M;MCCyF)PlY#xbiX@So<XCH^8)2LQ1pgfC{Sv+Yj!Gh|H1R^ znaOt<h7KHWwerS2bx~&;<WYJz@IF24*qy7k3N%-+@9x%j*M4IjA=jQikq!M|!t7l7 zsB%9Roa$Od+CQ0mY2jCmgy=r+iVPG;>6>&sKT4M<4tIa|_)1t`om---#L-Wg=&<o( zc;Od1+4x$yMCq0y5#RBkLx>y~RSjQNESYNolZdCFBtvGFzy|&=+>I8>>x&v@qY8*7 z!o<ea+QxM)M)oBm!N<d8oQqfPZ4ao1M#f#MJnf|C7Rb=>EHnHDwtLcd%|4&pX`z%L z_!4>;4b`UW&WJP)3rXRUF7{%^u?DeBURuyCtS&8_9!9!0qKuC9!p(wbjf!vlG5hk| zKm3h`V`*Bs>xz7B5(ihPJU4i>2Hn!F^)&*1H-`EBZy|qA`a*OB`Sv1QHm&-_CPr~? z`dxgqCd$iL5Bnz3{rer4m##%jJv^Lq4g&gGd3o-+uFHu`5-*NihFLSp;RkTzF67Uz z<=IxRWSQXlTug?cqnpF()d#M|(Xp}5j@rL69i-H_ct5d_hAwKe%?5Kk&A>=RrWW6S z!U<($;1S7o!^I>!ofM=>voWfO7B}DMFmj!wzG-A?(LJj${J45wqh$YVG&j^_rQ_Ts z<Xc(GzP<{9KuXU-BOb{R#nydUgbivQx?IIOSZHUPQ)`Ao=okzI#_Sc4d5g!J6qJyR zLV1+*1f1QUkgNsY^2HC)_fWXc{MFfdZNl@cj{7ZPuyK{<lm`kiNhyLE;#6m+mw-$< za%{*kHc~d<!8f^2?*|G0kfdT>s}q#WB~32#hEcws8+2uuBF8e4s!6wW`iaY@crk`d zXnK}wW27;0R$MGZ6B2^!E0R_4jeLns>AHz1eLwMOqbp1MQHG)TOfCNUuG=Ad&d&-( z;eGXy&QkuFKX&Gv2D}4W8U5iZJaPjZcIw)uW*i#E&8=FtXiA#&&v3S~KLaB-B`s4* z>f*-}Y`Mo1^b88bKJn+KCxwOPTYx*@uj6B?4hi(AdP#{(&{Yk3DWs^Smh*9q>#Wg- zmP_fnl%_TY^2e0r+@*pjO?Hf~H@mECIW>|B!3BMD-Mk?TZCe~_Y1ZPZZ&TAf3%%=3 z%VhGNslg(3A)<+u`8rB>Z@d4f|2`j`7(}s~n}rcP(-m||M5d*tA~NulQJZGyhjIsz zp-TrYwX4##=~xCBNq1D-oR`|uNBfB$t9(bl6DqjZU>{y@!3lmn1SU-$?631^s87k> zEmO;U*`L~lw(?*Jo9^I8a7)}nOJ`87E+Ou8Uy7>ws~PQ(CD;8W>F@ShZJoJs4^_b| zv_|x4vh1GmH3mEjmzCUnE9@zl76?YDDZDb@BzMlslyPX8{=tA@Bac!(v!Pvc&k$xE zqC-hQ-$_o_5CLCSrXvZeJoU5?cHSMiF!w>#zuoJdTPts>`1t}Y<}AMA5uZE-Rgv8l zLR#%1HIR|B$CHJf6VCSO#^#i8n;*IP&H8XYr<JphjFZgWi4$XQ6x!4qCR-Gqq!@@T zSO4Q4@ip-F9ZKQ{&r`=+KMteXCaa56!`}ZI7DBsuw6U=QTb7k_^qEY`(TMc_d@}N> z@HV#y7lN5$dqtm`Fu+A1OofN4l7m6TNEzCwJPDDR{A*FMf|WO(2S}dZp!bWNjckZ> z0!FTCQtKD-GrM}Jzi0EEad>AYB>kn|*TB^lUoS=it6fLd`t0iX&dfzYr`ms+GRy=W z&D6eYLfodTY1V9@tYl6gSyJt8XG7<BL4H5nP4tu_CD8NXRL^H-1hZbd|HP47tc$)$ zBtpRy<fH6OZ<|-5g1jr|>IKt!sB2#uX?A}#y+x8hb+^z!S1ao&qx~H_{GiW)jvuh< zxVMvt*F6pEJGlx_8WoGbY1!1khn1dQnwoV=`G3%wKgxLF2O4sHE9#=ghJIf$bO`TJ zb8L^FsJf)_L#KIf36jd<+(L#wDUDINObhyy_qam7<qwy2Eiv99R3dCG2*3FU;rln1 zGAM#VWOZd($+T;}^tP`PvE>EjsUr*-MSO7XVMcEMN+RoY)m2JUb$*2ou2bF%TD3MU zJ=copZhzpCx-+_PMo^+?AgSbGj&Siu-Bcnna@4XmdVSV=6JkhpR5rGMf_5n*)lITW zT(#YGgF?ONN>HY^yo?C#9h_8xeEo7_g5IgfzJh+W(USbc)j6k9?H70Y#~^n#dg0C> z!Qf1<y5Y0x7ii{;z|%NQ4sCX(sP8nWb)5t&dGpGv$B^3nxI0!wh3QNSY!=aZ^ez@g z3G1bmLH`E&y9iKWCbHfLcbtFKu(sy<U-O3Gf?EMJp?~)FGP#oL{!w6^3nbrd&OARj zCQsY8)kp6~a7<wDD0Z&?r9vNDYE#Mf7hB;17P2==SI^?Y>$T0w&VPF~+O?AzAtrM} z=T~7l?b$t3D%b$2zov0fDY#!TQc$Hx*H5pJn_Ug%fHaYCOZrIStWEcNR59q{G&UZ3 zlo&FmIx8q(ywj*q8{%tJe7`DnVAAbn;rC1g1awgkwb2R*$yO~pf>Qm(=3`zE9+<qM zY?WnbddC1!ORkB5n@1J3D3Hr^*uQ(<dF}xvjZ%A3a_nILlzh}__<>bkr{4?sK}2CF zrhAIVGBu^xXxUU=>lsO{ZqrMV5|f{)DaJ+y1$=^}>%q4QN;3=5kk_K@ziKKBChS%3 z!=1=U5LkPS)-OW(-}O8c7^A++76q=r{D+6VlrmytAcJ#*D>?tvZ&ql9mafeWxviXS zW;`-Cl?jR|{oOAEIoLaJCEs-)h-J)<j4YE6%&URQK~W++xkXBaX_7wPqwZM0b^?f* zlA+ye@A-pF0p8!gDF`#vzmpNj_i(agM80G>DRg*{Ci|WG=953-zP25^s=v|8qWa$p z>TUI^hv&MyxFo_aH#Qy(?O&~xS2Gu0D^2~YVNh^bF|uG`TOt+-i5bl<O)XAftu}f0 z7y*o3QyBQgi8FKM*o-h9B%i46_nS0Y7j-LTj^>}@Lk2VFU$gRX@KFBVizy=8b;n}m z(JWJ_2a`yFk}Ma8{K!D(id6c_SHGAtT1@@cS$B<!Z4%i|tKuetqz8<S2YVH}IJqEf z9xoat;lPXfy9!`P#CdRq4`gmXY6k0<wYM+{i$&~1)g;s-@zT$M&^NPj{NCD6GaUW) zTkxsURG1|B=WjRPl(2WSKM0N5tf`yek%)dqI+~gNrQz(Ls`B|Gy5yC^kxvi_iTOYH zUm{*yo){9v9NE~pEojYxD2R~B#82{ks5Zig=tNPodr-Gi!<dOFcXO!lAmdj1_rmm- zK9Vz^{XJ-uKXhb~)7Qry=qmVv3&AA0o<Af^=9I2ZCFOG*na60eTVcP1)Lw0PjSVi0 z<eX=l%hTW4(pOn3_9|$|{Ww$FCj(nhNm}=uvSqW3aT~Xh4C8WEyNGnyGx2^e)c~5@ zhLTeT-Xbz^Q7e-#Ry3OJJQPB%M&+Dm)+JUQM{Ekk(I)65M{DYhsa~9v3Jg7KKVD{h zEdJ%Zq@1IMLUX)0p_zxNs3f2}SRp2K#<_yeJpj4lD0wFC!dB9d22&^AOXH<|V@3cx z84{CG|8<{?=elBLrVA{ik3^mN4SBaRBfoF;@zYCqUimG#$nsLxta=S=%yqsN6)0}& z*8_p77o~caxsRz#cSlr$G5p2E^X_f1s;UNML?r1HwKvh|{&4HJuevcyaZ}2S_iq;D zmuj0<t^f4o1cKtj>`cEcf!j)LcM3G<)0|(d=}{BHQ+tgx*SI$li8eoMnzD#cM|vK} zwWpPm$8m@X{N@!L9fz|71j3+Q!SbX6If+Ptj0`pG^wu*Ek(>6OTZF_PO08L-q)B>@ z5;Q*8Wvtm`W@om~xiM}SX}k_N_aNDm2BBt8-2l%!10POaK~fPki7w?m9<eTC7xqkJ z&&(&fXU(?4Q0I*x1O2ES8!q5}xSy$WPefUm6<C`UxbN!0!itguGopek`OXHk7%d^i zxk2qJkAjhsvHFw*;#(CU9KJ`DeNdI_YL7HV{*W}DW-1OV{6x#7M1RMQ0-~B&@v&2Q zZCQPA$B8xL;KaN=TV9k`352UeH-H)T&qXB0pLxAB&d=H~DHD--<0O@y4qa?POrXqk zjVpNjy0}C=nBoHKX)9=IgLY)d#NH9EWjw-8)VWVGHmcJ`l*h0){kYt*74ALBj*Awb z+i11)1BS7D`wh4R<Z=J_XyhER`ICG33%R=XoVc~rY8~oVxBhpI>W60YY08YeN_GL! z%QS9=8KMDYp>Xo?A^1}n8Fu{M@YX3$D<8iXbX%J2DdNT-@o!T!AbtFARVM4<q%7`5 zg?PIJ|1)3Po$V%?^B<IO^I@0YcWkXLMc%sX+<RhJuQLWj(Lb3W<@=k#{zu5ABkv8r z2+psq^)oSMg#4AL_&O@VL!81TvYwL%x8q+B+l~Ir*WuLSx~#VsJaX~!TJKLi!#}CX z%3|i`ULKs8q6_fDI8vZc9yDY2CH0rX*n_4L-7~p&)vk7zY$`M*8XP!ltbXN3UYoYl zZuL$U7PbQNFgoGp?jiS{!#yk(i>r90brb*V<&;bEOGL{QSJjGT+6Ac2T(lM?YTFLg zYc}!Re#;zL`dFp{hCU8ek?pq_JZD&tJDo+;&B99Qk)b}DI(6IC`qfg`X`%>O@#5P+ zpPHk%nyTK3PK*?@9T<HUWwE>@j~oBFjMKWo=n*U$^Ol*(KfHKj(R00TFU1F@8S~N1 ztlDd>#5dqLilPg5Wh7+mbsZC~(x6+OTVH%r@(sNrrRccmz!~iI>n~n&b9MGJsEE`E zR`Os$`_qw;5z!(wjB?VMovv;|SeWugtes_lyrB7{+tJ;kF9zI6=L`LkX6Gky+$l|T zUVece9H~geJ;{qRxxCB6uOZqzF6-mwuW$^(abh^+pVdF3D9tHp$$^W{k?~v+Z*32| z?#YIcAJKW?;Zc+SWdZ1F+%IH|jJBJEX>qdyb{F24*4LS`#POR~h8wfRmiSFF<txgT zh7mXj{f-Byof};DMz&?SF`{sPV9is(h3hpnHC&e_)^jBupVIK{9dgrdyTBctjp{!b z>3K{}aZ%0sorr|cZqm9qJA?6cl=He62<4g*=)w+OM6JIz4+^@Moy`J0T#~D)OOl<c zx)#Mv>m`YEkbWPpq1<-R)wQnTQ#gtaY-y2dZLt;YLVoPUNRo5uXq6!6fSws>_2;t* zd}n5vPRj0Wn<)@o4k!k5va^SqBxv!-RzXS1+;XPIJ;l>wd9xemLp!^md~`(gw=t%c zS&!~r?)oMZF{@ucxl<&ubiLU9-QC}FV@1pv`B4@gZf@aJxXP3id=hhu52FUk242Yt z`BWqhQM`rTxU)iU-@nDMGiy-CJgtW}0UNEXtYl(r5wyQx5*E()&lp|l7q~7p>%|al zO}Tz@I(Vy~GSgt$8Jg4#WqxGcpHjZNk0oSNrY-*IepsHT5I0D?D*2(OVlR}2-^In@ z!nKET8)!>$K;sb-5n5Ts0!`zxYsh!{v;A<JwXUwNewE!HEqx(e?!Po+;ZMZhrGG$( zUorRwTwn@~wT!$sw7M``G=zkNL0uh_RmO8SKtT`GA4ByS^s8X(+}sNsO=c_0nBvJg zp*q%F=HiRRlhxHO0`q;hdX=vz_#yFg0Rd%2`RRkPfw~izwoYe92dwMIJdzuE>(;H@ z!Bma@4K273nHTkFgF+nA1BC(-+CWc_8W+Xge~b^$3hXwH-=tf(wJq9B31(-phEq!9 zAnL-P6*ldt&CMc`%m57`S~P7$aPZXU5`Up_QTgnNPL(IZ?&mt#o<L~EYy2h{Cd==Q zY9o9Ob`(cFYCl>iOK)pCRew3Ho*NEC+F#>cZv8t+fmX+T^pR0ftcui{NmW3~6ZiC* z9g=*<8QazdEt#ufWnc&s9p?}=@vDUbtp(I*F+T6;x8LKgFG^guMB)?UiJt7=BB`{Q zsOq$A=vVBIjEn-s*n@!?eSUh+MH!`w<28F2EFvP}dS%<rU`$h$|H!!RL9s#Q=Hw9s z`oYRd$P+^hL(+9Wlk@qgLrVp$6*wV1K3lRqKCvHWaSa!6dSQ=O4UpM-s(QOlRwM-T zJ4#7WF@Tr`JHH*1lyq>BNH&twcWr(42A!Q9Mtjrq<noP_)M8Jif_}A~20JMkwHErb zp5CNN>Nop|sxL{m3y~(ZB6sF$j&-YzZhraGgH`~>@Qx#<P^*Ynu=-EfIXD80RJUQ^ zP5LL`4Y>3x7_#?E8tUpBHh^TjIa6JDoSWaHJX~NtRhr56Xb4H`1EjP4a3b4LxSo_5 zm_c&PkwA;={&41beC@ur?|vkp>Y|FYFVe?N)e>5AB;Smwvb&Vr!1Q)?3B7pXJ(fxf zs?{awb&X%vMNF`8a?PV>hBIdcKjVN;9dEFd1&)mNNiuAvvDAFZ-$Y906jPX%lvHjq zG6`zyj)j^hLmFq|n&##8>N{&Qqp7L0h9W-aBm3<m7K+imSgM4zrV_*M2GYkDoMK`c z+;N`nZWN@X^~blld3no|lb@hRs*11TuIk-@ECc2HiTh37uUD*FZ8I=UC0r|fu*@0x zmbtQIN&D({sxaJfDLy?Q{7L+C*!SRa2+7`=7e2leZDrx)`t@|fOxt(`Km-sMhmsEa zR`T*Mfmj-kz|DNk%j*Iz{Nr3{?FL(#%MPaS82#|>KfIQGWWg+i<cOxtmG&wiIm!Ac zK;NV<!^^$dIXDt|;pYq42jVjg9!IAJm74G3U_M(j!mx!vpwQWOs$lor$i5TZzq>xv zFoqPLVpE~@Ine5=ew?ETOMW&t(AC!$FXY}g2#IxmaMuP?A-zSM>+ADtrQrgo6<2k_ zBm4V~_#!S^4SZI=o=eW%mMk$izar)(Bp_HG&}DyQZ8y_sJsA=N<y)-lR<~3vGI$>& z`@zQMcqYXCWM?h`s1^f;`kqJU847=LW2$Lic!lKFje)Ci8i_O+iA&z`l!etcq_jrM z@!HQ4B#0ndFm^N-hoE#);$6k(dD`_lJ3G6n$e>4Q36lf(3oF{u?5Xw2rZAlA2QSm< zZw^tlSbNMpe0*Qmtyu}gay4``%i(~eRhC}d;}ej$wUGwNd=99nC<UTUn5pUc);H_i z!DLEN@6&lEpKyB7iLNf4hTY;R!7IdjdkyEM-3VXUEUKC7GE1QvEKB_fqJ|v(sY2cy zX}HVG)}bLeSy@X=ay|u5s^-r3UZ3ls*#VQ`wlPI#TPv%+M2Wc0#r`BoTOf?%H&Qb` z3eqS6utHreipNOA=Kw=QI|;WLtCGS#8m0c^p^S7M*t}(MkDsrovNAM3e`1vCvGygZ z2*3t*Qx$9(3BVGj>$xGKwxAbi1WSs4#-;l<?G=u_$CmVx^CawS=+B|sw<=fiTC5Ao zqP|Vn3>a2Zzwqb^ODXA_MNh|XO`ZqHiqQ!=w3RLf$lj+{?`%;+=p%!T8eD~ehz}kW zX;7zONR%XCE%E8s?-`%1WQmQb4Tdob#iYfhRYf#>%%=dQtb-L*sEj$!<<oR(<glG7 zm`OY;WL2WIwcq(^)vPk+TjIrQ^BYK0o#83Wqy%d&^h)b&g(wU6+}V)`hn-XeeSqIA ziuR?)k{exk^~W<)bk^bQRb9|qPICC#^wId96hCQ3b~ZXk)04uo8jM6fIc)Y=*3|SS zNsvn$07<TEoFxQR>pix5jJ1pGraEw|rHMTnaPg(}qd$dE=lKO)V3uEQyat#7Sc+uA z=+tIdg@uO!f$@NP*F{%%t+6RB{MSu<6f<+1-Bf8%AYfml8H>T9_e5eJ&Q-!PR=8nl zZhh6?^?Dk9V64UYcahB)9*zV7;9sT65gA}`^yx&y&gHs=3U+PNnWjH>Sv531&dhrd zBkUiQ8+I$eptn2X(NKEph2#!;Yye|)r3HWx%a0!&PiD6c4=ccXXwjd7oP6~96L8#N zPsE+q_HQwM4?--juQzj1Yy^s)-tiJOzki}+el!_lt8I_m8GA0YWMgE+O#-4$M`Dh= z{lJ@|F11c4m}`6=5>++FjP!KX+y^P)DMCe!>8YvS2NuQNIzksfX@^!gqW4`21)X@> zJK95@h(i;ZSTdqVmjHLh%?&%DpT;Iiv&I1+44qRP*wxm?DGE7IUB&l%Q)+$S@#WPk zT*hNMagVqBms_*NE2WFF1BOCU(7k&O`PR>BYlWd2Go>^%R0nSL8w}b`PEO!gC-Eg} z_<{xjA>sG$guT5zHB1Z1;yxTgOVlKG)AifcF&j!seZ#}*L2tR^?8j?jX^cisZ1ZNx ze2hvDPc(gmgoN7LpxW@KN9*T+8tG5u&HnM@b0EMFR=fm_j|w8AZO3q0T3Y0f9~+K! zj<wDlOrMRcCuv*#;@{A!w3<!qTtrX*B*=EW2<s>Cd&ANH;6d&B_Oi?TLha>c{nxKI z{W1)$^3rysIju)f4Fwf3g|Wp~2&aCwynX8eWYnjV%%$aJ4L4s6H)Cz9zCbpUY0s7M zpw=&6UL%pPXZhVcQ%d=L-4Q^nCH&`WPe3M8e=Jqh6?X4ItvpmtE(nI)-kNj`^d{Fd zha>ROE-mY`y3<+(D%Q#|D~0=w1I9wFO5Xq6F)lQ2Vi+?FPZOIgm!;?BJpkNDqGaNz zik3_NzD4Leg&i|WPY(}IcaL1lETsg#Ox4yLNiJgplT!$JaBWg;Selrc`Ms&?O$J7Z zG@iKL>+u@am-|8MEY_|9C%-y6l%GBn3k~^`$`RAk)s<VoplSz|7S|LH^Cm}^xff1; zbOBTn%+Qlg+&li_kb%+Dvy)AQNdqE=pk|0zO^lCs)Rr;sZJvGc?AdD<vkx*B9x@iF zbu{4BL_}+KbaX^SgxU+0_{{6$X9s(GnHYm~)EGiy<g?9b3kSZW>F7_4PmTjlA^lx> z3jvUP=|w$Erv$d7r08$Yxm_n1CAH4)xoO2>REKzIo-fG7Cl!h|2=N3{aB4SXWoMgP zSX@uK0u$fdqMex$tNQ3A;lurKS5r!a459!5XjLMHo0Bt8B~Y`Wpg40RN6AxE|4y$+ z?D26J2w1ddk8G#D2O<p`#`C5A^cZ8Nn|w~Led|uP=hA(K?v-Z`*1ZVtEU$JNuf}0V z&x@x9JIm0to*K>{Ru=;xu{iIO*%W|`y@CCs&Xtvu^NBc1?HLIOPAZ%kGp47Xpp#9o zNcI>DkWpbCb^u;cPVQd8$(y#Q=SNgv^$aO1d%5kPtXvfuYUtMw;rsC>y~go~5inlv znBPAqbQ22Jw(IK+6cjcR!)GQZWxy~Y_FkyHd-srnUjKk~5PrD8r@AE)gi560mD<`j zFfvMo7U?IQYy5Ia1wQH+=lHxD%1$crz!Qpg9us`mO7qhn9=oodsNQ?P64hOE2a7eA zmiC)A+g@f!_y5-jL^<>SE6OpW4Dj>2uJ9^tNI`(Gpw!_7nfJS9meSgU_WHB(g1P|P z4tNwGq2%SimzTZNv|k=u*juHaN$6c^x~$4eSDlLG<l^Gu=7{XxM^kXf*>#e!g`jP9 zj%+nClK>3u^y^)Gya3`Yhof_IKqDRn{TN%HDYTFKrJ|fB>~J)RJv|+#r{F579{}0! zS1F{xuI<u>J}y|onET9{0d9^ZdJs@@tdp-XkStzXQK3-@<&Hx)E|VoUxy9B!Im$R( z=V&dttU-qFjCPkJjq02M4Y9};ez-oA+hb=tqLq+9wb(?vwlej*vu-=kzN4eFom=M; zp^45zJ=TJ++iGD;<Kp6YbPgK=>a-g?ywh$YFu5mjycSB47$I-Qf-U{b1wFKezKalG zHlbTk?RxUlV^|C>cL(O;C1ISe5gXG`l$(*LTS%>}ZYLsltMX%?k9BKK<vdBariy~R zd|u-AxkZyfUfE;Je##LBy`LFWU>yrz7jLle+Hk!qNNYIX@y`)+SP(*MW*Ow6_wG4Z zTj%pLJG?RV0$5w{!GW!$7~SARH@|>D4(bSUaCoRC?&{<ct`b;sRkd!qXlh_Mt*K&Y zIKAXZC8!+JjlF%_f7<cOt6wugTJBD^5E@!q+U@-OeBC6>mb+MLwYH&>Qa?z>MG?zw zAjdvDI>f0K>s5cOv&W?xdb<7-U=Y)7o|u?H0I{;Ns;P5lWo3OLvVU^v=d?XrH<ROX zkw`2nov*>l+EIsUH0U2$bT?yVZHJH&@Twn#gg9@f6^9zSySGod+B}nx7#NzB(*)XZ zRaKR%pUb1DM`Q$k>l{CzjHQSdH*IH&upoQJAaPru$`TQw(x-^Nv&u7vF0q3!zI^e5 zU*Kh}!@;?~lC6)<^Qq3<)Y@8UqLhCxuG2*>$jMy_#9n2qQBlwrdfzLTKETArYVkj* z(~;eLze7n*hq666em2s1aCUj_O#~s+M<i*LywT<Zjq*JY2}Q`DPnNQ>p!zhTc3Ue+ zLZY>onI*Jj)Bt|H<GjvDu5f)-r%x+*mcNc<jEF5x5kIMk%?+|yWky%H5QUyqvB&hB zeiNdxrO{-2!OOoWgVb~#6C9UzN%`3U$JD7Mg|ilv>dxk$@P!BifD0gC1-T%XP$0*d z!YtA=Gu5RYjYS%8i+XO4j!DU4Kx|>Z^4#=Phl{H?IIf_ER5j(ik?5-kyt3SB6<w~< zfbz~&re|XWm6N>|Yzn?aK0+8As4lO>70f-=r>O&^syEvH_mEjYO)p?$P5uJTGX*KW z4U4-bnFW^?9$->LM`ztz%mGgd;2LF0!EA@j9Qo{*EG!^eoknSj0=^C4OVxQZoG5um zd9~Ktp`coll48&ima22ct!2lxwPP``F|`7LDA<Bn3M86Aa`*V@!%&ZN!w|#Swg7eo z^xB0F|M*gSZn+|>sLx)XU~4Cz-SG4P#{19b^v9hlWZF(r)3zyMh&~MFdc%Z?mNwaI z1Dz&;6~!H=a1=$QrNOt(&5>+1sG4vZUO5*ceioLAiSG8^-cCSrt^R8dcpeRX?9#GZ zjl09a%3muX*d*mMn|#8fVozf`_3JaYW33`b4CeQ}?BUId!_hDJ{$NewhmBSsG*7r4 z9?;Ixk7n!FRb2}RxV|<-g;Bo<>#bT3n?a)y*Y))JRaSP^*4VkmsMJ&m_`)c5c{x5o zAFNsVEk6V}oZEvIbHoS`yCHQQx=JdIPA9R7v63d!9{{w3l4vwW2%pjuHF5C&iKm<K zjEjl6x`0=srl*rZSwzN5yrbF(u}umwPF|Qy%UKtZQ-(btK_BgDvWVpRcX$Oqpg*fq zSV4k&nw*%tsNN8AIycx3HjJ5x2?T5!Y&u>}lbq#I(B{??4O~rYKJqbUcfbQ~b2bD; z3-*d0Nhqrq78zY^<dG}}t~%&gfpP&g|HpG7PUo{hNp9Usg&3cW#k9#XJE^o;V^FI! z($^OS^~Mv)zCIt9;~I-P+~iP^buZ5ak)n#qg*jGj`=(|;TwVK_xcFAUtvRAiNxtV# z*?D+QR!gM<j4$2R_G1W-j~{?t1zg(f51vfhnwsjl9{|+$R`ALLs>7pAUCHQ}n3;OA zGM5V(#_!+53{E<CuFfC)eiXDl)8u)&+U!q6J=UmII9Bw8*Jj}>ee4Gdi|tdVLSJ8X zKeB!EGlf{L(}JB}paRs3E$h|hrUOxUe?aE;r5~>;tpmU<nI8ebZy-&`9m*fv2trZ- zScBX%2r9_UZ85*FQx2%FxOX(bksd4$uH&$O+~;_>IXFOqus>j^dAZ<q<&XBg?Je$b zso|I5HMYG~K->dRVk#;cl@z|hnwr(k+7V*9Sxvh#yNevK?O}VI;XTN({#x8*`H6}h z?Up^8;>hr@Hy}AzJKd)T`wBL`$!9yZm-PA*)A0MuhO4SZ{0(tlcqztoQa*81VjtZc zYN*c7w>DK<C`+So8fz*PJqB$5=5%GTecCl3E&+>eiz!xX`nRK&&MO;$^}!U}Q&ncX zCtT$Mqjje4?thDBQ&sj$Mg>T=xaerkONZ?-DH(4`&qfUn!*XwQpS5P+?AWXSs?h)x zeVOYNx$KYN1%a`^hu^zFi@EHi-vM41XcS^=>yucp!AwQ9cIUx1t)%PUJsIA*wHlS) zz`2nd)_F@m{kx~b5)`UGSeSpDEK9ve(RZ2AR8dh;FJD)fsS<Ei@G(gDK*4d_4HvGO zWA|*`EE_~CFRe1xldvfZ!YH?f4a6l4*uvuEZUDlV#}^-GFLi+nbh6}07WKh25ik1q zcGKVe=X3{bA9-h}{3xgbpnc+In5=4ve=g%{bmh_26#xdmb;nrTar5bje6vrFr}#_O zjNrI|85AvJTra3jWhf;bg9ZV!*XVpEHpP7VbM+hM;dA$i0);qkgIZVBtY_=9#oDf} zT9--Jh#<Hnpq0hw?B}j$Sh87^s0HCa;RfX}vW>ruU(j_NE({uhvedBvKMy<mdkI$1 zTsAO;YBc2hXbrc<HWMvR5bjq0e(0nUcdHH8A8SW*`<VXxYV#IYEx)y$noII{FE+hB znmZUnPF~yj6YKfmqF0MO=W_GW4KW*SKttI{B7XLFquF)T>_(aZ_`~b|e>X1of3?Al z`qr(NKtlw2NuJ4v{{&v~KSGoG|GNtRPxoGK`pD8WHqB!>m4Pkd$w@0ik#F9A{U0@S B;(Gu9 literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/add-data-sources.png b/documentation/operators/src/images/grafana/add-data-sources.png new file mode 100644 index 0000000000000000000000000000000000000000..6ec2b2fb7b222d4f20e49344c8d24ebb9b1bcecf GIT binary patch literal 54971 zcmc$`1yoht-!6)Y3Zk@<N_TgvY`WaQrbBYmNH?e`9WUJ=-5@QkbR*r}v1!;eXX2~h z|2sF%xMz$z?p=eSZ1#$|)||h3p69px-pYwTenjvH1qJ1?qy$6(1?4^y3d(Jr2e-jr z;2~9(;J-VzZzPo-Ja{lUFF%KZ@&ZK?@><C$VQU($i8Fe2e|MJ2FuLMU%SHU38OW<w zZ<Wl8kywf{ii#Z56x`h0%PT8X+?UCESV0uWGp`^J9GttMGyD=hTB`5x$1WS5X<=ew z;=WDZX~Qpt_jX?x{b*d|g{z8XM%@Kh{=Mza6^mE@{ea@6NfTms3w+#F9sKocXml7J zWcM5eB?Oljs&AX7I>j~c1?9)$11JvIC6K~h>#}4(&qQTZ0{=G3?lUM1T3lB08s{Dg z`EBe&u*W-!V&8v6ZlR#Fo2cM>r``S`ar5P$t!e2a1e(m7TW^+i_M#X4@1LI(oi`{C z@jK8R+?9e*Y$#mS=bzUnlm7jhL;>ln6p=%)DLH7iHxj-=r+Z&2)0BbCX2{@t;~m?J zKl}aAM<j`fn$VWEnwI#|WXbj_rX1nX9Rx;LZoyJ_5@CMXxr&yZhM4^u^kM0E<8`?I zxqe=XI5e*(VzwLxbu&l2WX!m7W#d)adHi<-PUw#X{THT*1ZZut@01H>5xCk+8o-Ec zjK+op$d^0rO9@c!4=eM%9khKi45s<VqHoiD@bkqNbA)Jj#SE7-mVf_{Yu!9T6!ex~ zX*B(eu?oSe^+M7L!!K3J${f1F)t4k06&MXi;261J%r?!Pp2~WRwqXBf3}|S1U(lj# zsx+xQY@RJXBf?QoR<3rOmGeutozoW-sGXh`EO(yJE9T*+W~Zes&RYF>RWydyXXPt| ztEQy%eztFGnX|X0g^_IGNi2F7F*xTB5%V>ul8k;|%`rDd(MI~PN!W;`b3>v=&GKd` zMRE{q`dxwB*UVLi>6;O|lz#iBUZp3i?XlgThKl<${L7c&h;O@*^rH}nIq{32{o`Ze zolVcHi}C6+bwRDmhaa(rhdK51QoZwz&+`ilGr#@ApTIlh{Wu<jc*5tFF^ZS2t}a-{ zDLsSFzlOXW3QJ1jYM)iaz|a>Zn;*^_uH06yanM@wBgc(guH-)s1|t?5`88{*GW=3_ z>{ru5d#ujRili&5jK1^M(Q#*YQE{!AiZiu%9DQUDcT?WYGMww>A=+-dCw;JQi<}lf z$*ryBSSTvso8bHT`sE#>?S%!8J-x=r!!DH~Ww;?6BA)#8K_H1!{}UNQL(w;HE+kZL zp<Mpz?^mnR3;JNytk;jyaMvv@l73`u4IM{?mWL;hlZ(yySL7X(KwnoEFKzk`RU)!f zB1|pw>OD`pWLMfg_J-m&r(JSV_=Mw|Ovk>}OFIS*my?Pn8tZkMcwm4eXc!p5noP*G zey_^yFbTdidC}fDUhXrcB?Lxvmw_fHXG>dHSZY`pS&KL|b+q;3ML9<~0U=>8b%J3l z?Kf2h<|6CDLK5}3I9b`ChkmOuA_7x&tvrDRg@tyG2i5QQ+@z$!s;gZjBw`{nf@DS% zm6V=39+xT68TRI<q*T4T!qUecTv^GCiOG(O%c~rrdiqQr9b*|SkZ)pgurNI{oq`p? zEYL8or;u7&N*|JSxfr5@6l!jo?g9%5JW9I*j#q}1%SVJ<+hcoh3yUD1n&?H<)lZ*l z!BDHKt5ehDvvYFp-MwpKY>bDyA}%iOfV5-xN%rGMENq$T>Cxdl>Z49zWa!>;XOxvK zfG4|$`mXfpOifLdSxn-Q+1S~U>}>We?#0E$V__}03d?+GBMQk9fizrR4HCQ7pZEF* zB*{rjOYewb_^?|{bh91@W92L@w0uraZ(g4-O=zv=;p3YOv7RcY*F#L$pPurPY|rH6 zbnLD69`a^IMh1mc?##IJTh&d)um&qOW?F@uXi;EcTppvKY*)Jar@96CDj7n`8urC7 z%E!F~`;?QEm}hn9$W!;cx15zZW@0LQzNsXJ!u*%Xo*S(K_xU67;fWY9^vd{8(b3WT zW>jjbs?(Mg(o#|b5wwHl<@Po<C3JM1)iqZ6$|hDjEY=H4;Mse7yO^0xR@vfhPY^>j zG#0nFm-%~llw_3L-4nf<#$wr5&Byok;c#lqhbNy}Th9_}Dgs*cxZ(w^wo`+HgD+7X zXlZFt?|u0!A8&us?y<6@t-aWr91<Xmk3UDsW80cAdwrtD)UZw}EI?v4|0&~ntVx!B zn!WuI)fYLa9z7)`HJdB&APWm}+?<>kh?Mp9jjrW=;j5GJ@o`4CiEeN2v+0`amG?Xc zD@^;lhxK;rWP^+}@Aam}2ixR{iYqE&Sug#jU9UEXWBpnz8m{)62K#ECK6frFDM|3% zLbS>}jK_0bQIhR}NlR~zm#!ct8%lF?ZHz^43*>THxM?tDHC)Y{bq_K(CkK$He*NKh zGryg<W=l3_8=lwO$n0H{QY9s&`pa!;S=k=S02MASt^{9!+|*okHE5E{Db`@yueZAg z%(IddVH!{1rQ@BQbd?qH@oF;hT(+yhi1rkecV*9Aa5$Ai67G&-Wo!1Ad%lY`86dzv z&3SYhU_GjS9DPi|+23%fCU<*6Ab3XVtA(hO9|^F~sqr5N>)YRroRuBCvtdgJPRrwb zXF);1ShaOOzrF4;O48)Ly*>E;fvq1{>HW=PL*wHG6%|yBj2SP4Ri>DzQl+Dr&Q4`n zSmxN(0wH9)?tF0%Bl8O^?2itSS7&z)^yl{$ebCWQ{5OpZ(s6N?Frnt=hl=vTeTyb& zU$}!lymv&Jn&%6<az*(P5NyDdls<V;Ye`kL=iiBp3)9rp<oVoYk0_R)1gjcice<bP z_3J-fCbW9i@v2kGnhMRUXgJgRXg0BveVv`(N=o+LBZKpKbI0hTyJCG_gi7%7@%gsH z6LdC~Bf7ioGL78b?^x~Z`KF?ry=!HxC@X_pl*1@YU#6CnV67}7FrdoH)<l~Zp4Z4A zB{~z+u#2lU`O6jAXeKQKy}j3LEK8_zF-~(ow$Hq)YidwYKA>9pLWe%FmN^R)D-}KQ z*3*d(<{tT=N;FQLlRuM)#0{mDKQ6&%d?uZ&si&1+=i>rQXs#Hltj%Q<*n~J{dyRY0 zG=or5ihzO8pPM@|$$N5+O0Y(_HQ5m0i~jfo+l!huDo#N`xiJ5GMSW3WQj$+rWm3|| zkM*|#T0nf%o0yzz@&767CgP!}n6}U+8Y)47<%ffhtDWpZju+tP+qL}2iX`+0H;$4{ zfr1-|QVTX!>gobi#irPmk581gUk!}^G;d$F2~$*2!9OU@s?m^KZxz093Hg{?P+)EM zjDOeU@#7PGW~#%&aVxhUbwdw#vrSD*po)uF9nJz4WMpA^Io2BL>Xwy|i0W#-j%ELk z(w8f5Awz@HeH!geP4KEJ=Mq&0u7IPJ_#N#2>no(QN_2$p8<9re>;gp6mB1|&r&r!s zqCuQr`<g60T)U2F{Kp_f&W7}PeJ}fQ^P?{fAsjP-xLN|A&2DlI{jB_a3Yzx|h|IaF zDwnbc8fOeu1I#%}agm8o4V6-xWyOgJzBjsP#cOt39W!1oG3%}#9@qkcwS$9$`}-w* zqod3k^=B2-b(b!8_HP{@Ir0PyBT3~P;S%Dds@&S-Y3b=4F(NMV?6qxSw@6_0D*1jV zW}7jr`d+uG=?E74T9#K=^EHcCx{A(XzmE3z%Q4`EWc8#&2?*lqymmf{ijf2b3YhBa zuk!bLt`;Kd9Etfo+S}U=W~M|vEw2l*P)ik1-q}6x?An@n5?QQdb++8x5GAwBfh7&& zike0KldHTjhz-p0-MfFYDaFjswmefpHAJmE!Gx>$w&$E(!$U({`Lo8BmN~{y7>qJ? zyO4>@)I581l>4dQ=Wb>a`S=d6Rz5zR?=kO%=FL4kEVI%TGa8mve6tJd<>Ymeo90<a z!PJ3p`*T(WIN;*FAbkDj&toO{_%$>{?+^`$XF*a^Qhu6muB~BQy}HNFZrf7fS8O7p zFCv`ia>+9F>#dcZdG3j^xq*UCh?+2pyZh;IgPEDx!lJ(L<(5cG(aFi!#6+BjEe+Ym z#ztpX4+dI%W^Qh7US6fkFndMCF@z#g>gezgH5O+!SBoJyBm@z9^x0eP`Pn53ioi3G z=eXs<(HG{HQV~f6%-4%-@xF9l4wcc*17fF1+i0|C;Jgo)#>*MV2&`!JtqmYc27%X* zJ18h0eomA+t^%(*Qg>*2n1g+K>Wn3s_3GWy#=`vOrZ|Mia@JQWB`pn1v6IV5elyx? zTzvfDA^OE76%H<*rUoh<rOC$7bA+C?vuJE+sI~E01U7Xr4&DlPCCB*07!0QTEpqJE z)oV8A>+3Jd%E|)+Qyltd*narEAUNH-_r<?uVQZ`V^~_KteGbT3UVnVaTcyS~QT_V$ zOW?b@-$1>Tw6xY21?#J-s<N^s+uE%DxkKYpT2Zohc$kyVP+44D`mJoD?z~9jysWY^ zJ}%~=M%))N-Te%-!OR|W6O+Q6I#Uzf<+ZhL8G9utRPFnFH90wDb@fM>vWaY3l9KC? zB`BGVy}hID(O8YuDuRmWmH=B!Y-69m!5etnt1e#a;qODUWeeD$;#u;^NBiERvD|B{ zR%Nwrrvsl(r5P9tc24x_7Zw^l@MFR|416#Ut}E;Kot;uK_qIT4>X!n6y0VWoGA%#J zbco;3Jm(I7o~#|)enur1JFYP<g(l#N=QL1HZ*DYn@}`euq21TmKhInWgPzZkCaw4; zS+yn)wG+E2=j5R=05QhD6;HRT-kqOUb2~rQ){jO|uwYg{O^)Q?=<)8}^P-%b;hCAF z@c76Wr{M9(=;$V+(zeqR*#`+@bXYB|NqQc~{LcF)WhU&=3~Db;Ed(96Wp?cAUBST5 zpKLvR7%Sj86GoyY57qUU8Xx;P8}XK6s?rnwewV`WNm20e@z9V#O90~j`cxG=NQ;E` znlCCUDh64hBg$Nk_B@!B6wM*e7oXwqKxwc@ggs6+hBq|Mn-c|zv9MM)R`$A>XYp~C zXzA(C&(03YoO*g>#e+$*b8}yi;RR%*6sA0Tk(rrUnD2&2j?T>`vVYt&!+r~RlkUbP zOG^^IiA&}OE!hPHe!;=D_Ugru0q5Ph84dpH6VF+e$%d;lksU2}p&6<E*EHr;(`M)3 z*+1=SAKLG&vux^6J^tBUxHmGoLefwyZ*OHPJU;TKXqy>N0+$q-ky~3|bUnWfp7rkc zVvf>o(kahT4OLalPzgJIcN%W)5H<Ey5<!Pu2a}<+=BB1ell-n({)*}I9Bn5Lk;9z! z)YMO|!nh~`wXI|P5wNHrJ6x1q9)bnJ!)N0v<3&3vf>-LOA@tO#*G%Cu_K4H72q}l* z^6RUGoc=t;>LiTnD3MDKIm((iceaBhrW<G=BufLI*^>y1#+yrivbD9aD#Iil?WPF- zu7Zqv1mh~M4~Aa7yDFzd$#jv<a*-A#&flV=B-<~o+3W4ElguS0R;X+1x;fzRI3^v6 zeVf{bcWP{GEtKh|%AeDo_PHgs@`=Pq(&nB8#_8tNVe79tzuY46_uH51U<Z_tl*P6u zvu&l9hX;<xJ@cDCIW7x9pkxpGk7%TZey-#k9b83wZr3BwZUBql+Z?O4PAZME8Mk3H zErPde9J_7aq&<<b#&50s9<hghjqlo<VE^ny`yGG`{JVYdnQ-?__2B<`iD(XbEl<Wu z&#Ljox1=*7IdNRb-fdKvd}!yA?$6FByWd<tFqdNcsp%j_PE3(rHGfZoA|NwHuJv~} z6al8EqBjY*L>P8XZgwD;3zQIi7%uLq#3=Z!0F~$U6R_`GFhM*aV}bdu2R6!wc?xP% zb4#LiI+QuqFElq3AQq-NMTJ*+Gm~Irkzx6L(9Q2C-Val0e*Xggc}CUgR{t*D?C<9f zZJ%tkv=BE}`m=@HllcXF?C<S^?x)`;|NY^AJ`G5${%r4JUikmLv;Qv+NEIk+s=qwL zCp4RUNu;W&d9rWT_XLr8eTw8BACJ|zzJT?U%@JN6Z|ZDndsO7-8yK$=8D&x#(W?k7 zuWbCBe~*TCa5ZxZcM+SAz#ontRE@5jy_lOu>J;TOkgltr>6MPhYrFc4Z?CVLU~<9X za4JgbPJ@zA#=rQ=eSMG${wh{&a&Lh)4Gf$e$X}}{DeW%G&)PXS+`W6(^P(R=+3h$a zK=L8E7J>WWd;{8}gG%uWIf%V|`9r@wM#dg;ts#p<f4}_PLL~(Syxn^q9v@d$qFj-P zf4Y|M5S1AJEQy=Q1En3hO3<ID{43<87?io;Z0fRL(fZqbMv&V0b5hT<Ti9{w=~Mxq z8JX*Lr4(!yez113m>K6^uSf5QRr`MgY177rso&bhaPC4_BRt8azokV`|1gO8&kTPM z@^)7m@-nd6`F6Y>y|uLk61-qy;j-&FOR9x&OzXKm-&qln#w~LMv!=|6Vb>FI8UM;? zD{1M25MlSku()ob?KPI;*esp0@?tY{Qvo-F>wbOIotUT2uBS#u8PXJqj`=-fV?+J@ z>lu&x4uw`zn$D}MYdASMG$z&kXgDa$J5q7o>Y;|P(_>%ZFlMb6WT3Djt)Je%^05-U z-r~D+#{*1M<*a)@nfc39$C)#6Sp<wxR{Q;136O|1&w4f|2=VUL(a_QsXx3Ai+kB6U zQ+JSCVb<`-&u6$kT1B*qQE4YFMlq-toA!{A$e;UIRWhgvi8EN%Xu-M_FA*Wh)beo~ zEUm>QxeGO<^>j4t<YbTSgYc6)$45t#Me`$u(sw*gO6uw^Jp@}d{2-};fgEsZ6)JzW zU)<;z7@X|o|8yCi-gC~<mv^wYFK}O>Bqr9PrzdRK!}hpXCoKM6Fl*`FYyR%tGcJ?3 zV!s?EGRc}S7omBEK}!PzHd+dq7c7=m_&Rbm5fN^PkNG;4taKZyuXRZ<LC|S9?$nqh z_bAG#+gM&-TwBwG!RFWJ-GyEXoetcyw-5RzISA@67lV?<Pql;a)C>h$OaM=K%O)8a znoJK5M@A=Odosz<MLxy!X?hq>WND_~rw5gkv|j4am*M|+Vf_$U?N_Tv=)-qA-itoH z$4fY?dOb-h+>>1C)Zb|6Ul;x+%k6yHbJW6Vq;=vrkJ*EVkhI37Cv}Xy-^zR<KQ;9Y z<aT|3!_{eWL_~VDj;rowg-$fH)@Ae7sblTh=MP^qq?K)WrudI<7KoV{BQrB%dW_8c z)U}O^$|vsW(^}o>%sZ$^bGOS3c5Bx7*~_fb@VwO3z}@ldv!%<Rq6Sd+C3$SL>S-ua z`M`}birjUNem1%4XkS<R`K|vzmK?`MfAXSoKbXe1s=qX~wLQopy^e00H+Ru@2MY%* zH{}AgA-ML;4_HrPDa%5U@JRi)>eSQ=1h??JVpYiD;UKeWj0Pyk&A_d<fs1J#ZMnMz zUgj3&uyL?ZkQo{-w**8vO4c}RUD(cEX{{LHU3t8Q;Orqs_Weu1>Ht=lS*PVzW9i-< zUn(&~cXk<){DgRX70eim5d-F)(}XmB(RX!4;yolOd_m8x?esh-`F-1?d$-9ke6Yc3 zy7TGHxm^1{We_nrB4>zEpCC9{miiJ{eSBjas$}Z*SC5;-k@0bHeF=MaZJpYiS=`;d z0B&M+z4?SB1fK|puMG7MBF(Zul4;oGXAFQ5G<*hx<7obKTj?&Tii<03%*ZG_+o~ye zvWE${2~hS!?AXpAhOm2>Ey*E-tL#@(r#xhQZihbxDDwjEwgRM*9o}6PlknZv@h&Dz zIcjtBxlFRq`LB8RJENtxj?Dut^wCUeRkkY4KfGKxILjv{Chpgli-;eKijq>N4wPV_ z+2-9lh&C{Uv$$RZZws@h#6$>xGixc~^iL}(WtVSDqDU3-LG~o^_Vxd)s;=H}K!RH2 zIf>9_nrB_K3vaA%{pogq-_LMWh6)Lat?liN2s<ur?r9i|IxU2K($oChaMOzaF*^F@ z=H`j_r`n4IfGv_uTwHB-J0+hVJv*nw3y6J|S5tEyV$mQ)k=RYQQsq2uWP}F+&WLFf z07Dykt<KYh8l>v#057_o@=cV+{Pc8`H0Gm(c9PK1<D+7@93~W$P5%B;#u8)1qq5O< z4r0mv2KO_^$HvyzpKk&4UXgo3I&Nj$PE7_(zA)}ARKJ0BS`I>@R_apV?VYJQ)w*b+ zQ>PA7(UFGK9A6AiPrFx!Jowl2-bFaIM==WHVmqI--)a#T6uf*Qd=fEUQC{5D)1$D} z+0ipFFt9-QsBlCH8)_EsYqGPxy}h;et|B%9A}Sim>$asDt;LVQUK24UWqzFK6F59P zOs5xN;c5B&D_lb(FDhyTaSTdw0LT&ZS0W2N#|L0_%+2NxzA(ns^)@wQk2?6N$4F0Y zYlDg)A~M3ZP?$1SrWHabQnYb4EK2qg)5K(dV{;ROc;<Y2l5}D`s45}KX1>wcsBz-Q z{p)Av896EA<McmlY>!yj*!qWu*|DAtkB&}nXY)JM#6+;@w-UkOmHYbxwHHKG{tE{| zxq0-s?zy@2Rhpb6@~(5RnHxyMFZOmlRA14H%o-aMwS(BZK^#MzT=|nj=dVcQH5e?V zC98N={l47(XsxCu`TDiCEMk~n=%#Q6+lT)3ml_qd85tSh)8FoeK3_`x<!VTcH*LRy z>%P%^b*IKEA?SWh#L2re+-MwAV`Fu-@rWoqdII}0d!z0c+okra3Nvn-MVWlpt}Smj z=F6&@T&4^P!8(T)r&$z7?!G?Za~I@HgX8vuM_Zcl`;cNCDymGGsPvqia?=*Y$3aK; z?wx|t&nR;RR1=lQqz07-58<{4B^DN21qF!PcSJCV#<bLx-*9`zKkm1XgU-HnT>CXM z!`RI&W-Zyz+~8ql#@#wFWjbCmjL(!HU;BPLDd68bLwR;9q*oo<LMa*?EaxABfgxvM zQE&&{e?2Wde{5u=zM|0kv<0T9sG``g2n88k$3i4o==;?|-;b`!Dk{q>M#5Dau`?#U zwN(LGva$VCmf>B?85u3X7`^^l!5I1h0Ri{bE?(?p)Yj(LWKH(#G7JXw81==miYqDx zScV6o7tqnu$0sEvWrw$29n6M!&Ym3{nv`y<?#_`e7TDR@X=w=nBlc}?Y*bJaHSC)q zHc?Rk1?14MmD@d6AL~1Iif<JZ*w{I(%*`dF<fiIYixw8%z~S6v02|=sWQEzWvvMIK z?AV&(C=wG12nb|q3JYftj|%hhhDW)V-t%;eTO?HkloDcs1qDo1x~BRwS;||A2nTzU z%{8`zEA+>wY*h?`m;0gms0#~vfGgNOroAa2z!r!VB8Ovtc=FneK0a$i0B&f4*ug(J zj9bMZnV6hrAA{Kk6Z0Eb7}jjJjBc5?Ik^U%&((!w$t7C1rA28!d3(RKu^%byvCJ{D z9PW9^O~YdF=GAU|Q3JQ<%tErqX>e?Hx#Mgvz_>rlVpNuuC7m}n{`1c_09`*WIe9%J zt)XFNFjO3^?Ka$Hn-Ek!-L<KsQ)?{h=!lP5UdAyw9?Z&Ky2j3E{Qy>1a&;6`RBxzn zvC3j({{Ee@v*<W6T76!d1OzZUZuLI^20LjswV#pK)hW%!R`e8VtB5Tgxwx>EnU%FO zzl~UPB8Qma2Y^T-DCmwC!1;>%9t<`tiWZG}&wFiseNuHYHZF#fi|c9sa+$QZ_XY5# z0OLD8#(0TMty66m`Y@0#j}8PR4RzJnxVU?=52~g&@uj5#;^GP6eQ|Je13e=nA=eQB zS65UrIwo42NAasYYQ~mEy5{D5t}9cLFLk>m8?$;7Ft6?=GqZ4U+1tH0H8y|Nt@x)N zc=m;)#IOtXt%k<Iwri2_d3OMyaB&}fLB&9<3yL6ufoE$dbzU5l7rZ`&>p0q#CG!%N z+D{fa3T(K&aWhgrdvPaXpd?Jz%2Ks_AtzefNfZ{T_%;SPgKDKMDQ|e3#7~-)n_KPF z|ENCYYi{mBxcqf!Y^2c18LBgLgXL+8ev4vJ-F_xW36&jIYIZC(wzeoz1<xI7kIr0Y zJr6eX2zAyHzoMt)dV22lOEcG=C3|`@hIcS$X`O)t8mx9LK{2vN@kDZv>1i#Hwnr;4 zX-i2eOgSkX?#+FDi;Ek%5SF^Mgyv9j++Bz!`B1()u5zWLe6sRd=oR;u-+YFnJbDsG zZ(C7mDLFkqJ1uXh@8`xSt(xmcj}sS`*9T|%liUCWAqTOB%lpX3^IB~$R8)+F_qSP? zZ=Eq}Q-veOYxMWiO#<*4ch=WwX}SY~1Y62>W)6_)zj6SFp;xR5_*iNTB3%q#5WE44 zxh$;$7>|L0FvYC2`=?)jTLdT%38O-DmY-q}y5PVRI21Nz{@4o2k9GpR{}9^mD@hW| z|5MpTi2UcPrn|ox^WWz~$A&=voEVgvzpK~ZAAhj?ha68s3K#y>0-*fw9{j&JAmY^R z=l@i$E>~AigcjbKD{fsy+ns#+@3=^?W4@yP9pe9sSO34h*Z;+E|F;i_5U>8gzxe(; zQ*R+8A~y16s9mrf@83INfusTA{@~tV6a3)uJ;)N^eaZGEZVGt(dm)@E_{in1q+0#T z21oO*_F6Xdqd&(9K*Wyj3JU3bGuV@|NII@SXjE9truGbKmpD--Ge29eo-3|!8xQB= za_FuI3QE+g;U*-k`PmHnb9hL6KR;b(%Qz#4oxcQyQsC!_Dt<kelPy4BwYG|Zq<l6y zk3r|yz|gQ|{AAD{4_w05Z1lPq5e?|JbDM`whdB87^`*|_nC{0NDv)M#WNX=<0`wJW znw?TaK<VV+?)dKj_Mj!O7EEYj4H<-N9{iE1*OFZ0<=^|CD(HVEIzGuO^CUSj*4_}r zJE6@8P-OBuiW(Sc#gYh3&h+Z0)BRP3e0cdR2>Y<Mu5EaDG|5+BVn^FA{Q$BA6`F0I zbk%&VJLARF3Ltw0iI`XKre>Jx69D^odV8?mW4hILwU>vt>d}eVmoKNFwDbP*1$a{c z{I12cgFG`c9>C<r63>#YhDJu>!r~HKcu!yB{{;wGOoLjXP{<IRW#}p26uv;xG02vI zuM@wxY>WN=Y}We9W09KXn2*0oOpN$af07vl@MZrj8{1OPi}m=egl>S|(b3XkhH}Zf z_BSqrBw(__ikFa-@afYf1cD#k@Gm|SD3@lfq+|sScR4YyPx;`xv0;WQ9WyJw=ziID zeuk{+>Ke?dPZ2uqrX|ZQDpG_(A3lC4EhQJxVE~Cp3LP05l7N7uxPr^U`IHwD5f-<# zgP)z2HaRvnx4y2Zr1_82JP{@*C#R{YX?2ZjMmojx?Ac$(L4pUCVjMsGWptCQL?AVp zRgpDVl~(7rU6*wbqm{@A?SmB#&N94ioksJ6Q!!AD`fI_4BQ*;NLb9d@24o<KiKAjh z9R_SbS5rDYI4uk5&ZYqqGc>fdd{o3<GiJ^e&{N&e^7mfB8g|9W=oyrh2oz3!A9ea{ zj?`|J`K6`Rj^Kb)V~xp1vZjYTbzl4Uu!IDsMRTMb+n+`A!DrGqBvnjVORFHqFJ~bQ z%pBlJ05`tBdv?Z$jjcF;banr}H$!9gUzE(rEoi{7OWd!^BpT!yfSDsC*hL_S-%!cj z@WrKXhh98cCEU-Fi)DKHOhaR`H@UL8r)Tja-ha)1T+jd%Dv-qG(^NNYw$DSv6q4mW zJIdS;`F5<t45^cnqF5{7KEXc`&a5S~!8y4dtgasCxb6QSmdE*Y0H%<`!B4$uezA_K z!iY`?V6Hx)Q~&W7WJWdeJ|Ny;X8*a)J3Ia7vFgEgkKKVqbSIYX22X<wN8@b_H!%Fe zm5qgZVAGCU$H-ud=dmjHZQls#u%K7{fhT_$vk;`wkO5zE?0|8{j)tbYNq%S7_|;#B z9})uPdtFpmh$o!zUo)Wh&HTSS(f^YWfYM|T!K8tKf}D;UHp6F9oyaP#si`T4DQQC; zco75ZgZ;8SLF5XA|4x(uRRo7KAGy|@ANsN)B8m)nPny1fye=_8^Ngcp+#D=J@{h$n zHOTJgwh<ALrM7I#Hm8ExX5!5svy$B8V3FYtlt(1;e=6Y+tU&+UPFokVeX}>UUqxJ8 zby8tcKtN5JS9osj21uz8<_O_Sq|fy9G`R-FpAm!sZ!O@^+uY*YV&P5zvUoth8Nm5l z9TTog<r_{0nP-C}EdJeh*SM)<8RZp3NlEkMxP}nua(s<f0(rs1B-g_HbGlC~bdOL9 z*SEG#_C1p?Po{S|J39|n8Lut^Jdf7r77_f;0~|iA`hXzg=i>u7oq|F*s3u3r%ys#A z_yR9?JnK~sb-ur&Eq!}-`nfdO{YqZ6Cb*&(cts(h#hz{kC74ot9HF$7znmDUyi`5Q ziK(*yg4(E$RJd2?1&cBaW?^pH-Yzj&V+A*awG<?dn;(DvFqflf6cewu>r~s?>fM<7 zDXk5|$Pj+Go&!ib_e~PAv$M(T1b@GcQb&;W@>^Yc`2xV?Y-5-%b1#duGA=fbl;`^@ zD5(WlU9TcK=BcQR^sFa4sqyJBlvGrbx$KSJzVi+Jp(-m|mr{Jy89CG>ejKe5apdX< z%2C^7)wz|GoFe#(P$?<tfW^K<-skRb=pv^U)Bb&A&(r{}Jm<Z!k^8y%1Y}qMMB^a} zhS)HkyoJHs^#_eS8(xXZGydK*G|qDr;cmMjmHyI?P@Nx=TFs7f*XQNrWEf-a2HkZd z2M3d-1$$gCUf;LH0wm}YF3%|>MR=3fZIRjYxuAq8K-_}|hMc)<H`xlJoD2$*1wY_h zIkDuEz3ckz?J8k3{kroJA3!WyT2z*oU$>nnudQ#)()?&|9&0z)h<FYh^LVAFO7fLr zmW&Q^!Awd@s$1O9&=4SmaOzPt_LYmxaAaOCy{lt=p7_76lVt&{vLCWQ`1Ba#5ey2o zwtHV4<`HY+X4ph1g8@@h^Ef<7$<2KPg9XRuwROkZ+LhVQxEx&Kj|x(Tclb;DkJeo< zU|z147IAWL$crWO*cp&w(ne*LR8+Vl5uSj41<Ith1R;>oPfgHaJqTPCDE`qoz~?rR z4?@deasM5a?39#_&&&t}0u^JsKFqo*FRu&4&GoQIm+CXpT4V=%AET9(6`YTrp5F6p zFIqWj1Y*a_xIA_GJu1qGoP2S8&?q)mO$LyWFxXLpj=RfFpT(P3EXmB@6QZ!Nv4@AI zvQtwV%LobMJ+9VAHJK{2vQ~%IvjK9NqhxAm$Zpn31d!Mq>SQx3D`8A$h;`Dhf4)VJ zHpoGMLud;o2DOF)3`V@l?g3I?0NGq$v^D5VAL?mnY(6FV*TR1oe*n~krGjcqpLtAN z96K~3<>hSKWVA0R;NADfQMI(RWPAVu56E@G5i2%MR$Iq|+Jq>wNGVXJ`btoR1Fnq1 zK!{Ezi6gQj<!W!9Uu8hCsN5*MB~kFQsj`89FkbFSvU?j19S=>!^Sg(8Svy(qbk?AI z_ng<)qZ=;I;P&?RAd&+_FXp%<K$(Sis6x1MYrIm#I*eTWN$pYVIri;OB2;ohgq~-G zEBB8B`tXSa%HUl)!bc{ahL==K(e#m0!WV1AqBopCTL|eHGV7Y1z0_%=V|AgomE|KQ z5UEX-Zu(|tf8V|Itfj?z7<;vf-K#Ap?F<Y7%mRSd%t5&QZ%@Rq>((3<c!b^F!NE+W zP#v90y`xW_S7ry-^{1MlBCL9P^2djVPeTg|F5k)3FIQf>u2kV(U#v|N^5S4(N@j$8 zFU|66A6e;LWyN}i4V9Od7h8#(K}5oE<7cM6*|lhjo}>cVgzJhXnN**|W}*mYs0`Kl zEO#>67e)vN{P@#P9N}-7nXLtr6^AAO@U^wJrcM=fy;g>Z1_BQF`tm}{#AI&|+lQBk zX^@B3z&{GF2rLa@oeOC&x`o~(xw-@y$Y53vC~IUE=ScrdHO<GHsU8>}ZV5C|fI(p# z4vvnXetl6}FHrSKlL<Z&zF=bVWdEYPoHKe*!O~)9ZS4ga3<hJ0=HGozK(Og2At`AB zR+76zWCV`A-Be5n2#$prE##>HSe<oA>h0}aQw)VHZEXCstHB3=PGuo4?$f6-5Syxt zwPLSI5*tcE`%8MW%Bxc|Tie0%tE<;H$<h$~HBD>B8a4#rK^YIW?qC1OAH@88^gofX z8@wW0Ct81lLINN!BCdE@$Yp)LtfXWIDC)br-~8ZSK)Y*Mm;`hako0`FQO_7-6H_(y z@n;VMPrco2ZM*jBuSS`zeH0UeLbU1+B^enDRCGMZ?G~0kqpbog04Rw%miL7O85#0p zg1Wm8J>(;kLMz_?RN#uYFf#QBp?7n1I6gp)$f&}_jEsyd)7F_bc^4I>3{g^a9q#U4 z7^(B8tdx=Mc@(g}Zu!@yX!hPiprERZ=rS4I_66MQTz^)PBSO^5KZOs{tXF(-dAo_q z$JND&9&gDAXo*_fihr_jEXl|7vD@i^9C~O~z)QgE?b!aj_)hKR3aYoao1-H$_#rd3 zu#l}vz<F-ZP&%r_sih@I7A8e$Q7QQ;1}f^GgiH)BWWwa+;6l$V_4oJp_NKxVWHr0O zE?s%@OL6n;eE+{c+ZX<9K&Qc7YQP2Lhho)4AH;7YkKJOTuzRH`>FH&siJoV{HC(1S zIXT7o`RRrAfCJ<ZWJe^Ex@8twv9yQR)Hv5QoRTxC1o>9GR)g>fLT_FkJs{~$y+6T| zovr^_?da-rzRKVP;#!Y-?1aSWvftaAPt-nl<%5On7bbTa3_da975f^04ct7duaO$O zzjJ1S8d*}T>Xpb^&^b?2fqMF%<?zBEFdY;)<xim>Jbx9UJ{5I#4n8<M92ptG3}{gU z`aAqy)-IMOrNECU!C(pUJp32Y_tzL{SU&rvD@b~HU<|U^ccN4INJ#`<+n!rRj*{or zv>26g*Pr1<=Yg}Ffy{)GB56|)_5DP|b4Pow93>k%stqL>oPd^+Z{PO!51sW!+(bmK zBEGFxIrBoPL;8;>$9Rc?0Yt6mpkZ}(-@98(QE~Bw)qJ79xuq!?nS0%9QG10P$Q0Aa z+tCyKP3CiqErJW!{e%Cysh3O|LaToFx*=hxLC>)w|9P7H&r>U1OA|{=XU{(2-Ztj< zjm<+tOMs}Lrbw`NJW$HN;-BGucUnTdv$KpM#tZPp&748r9HmYU7uR6&)QRf2zJ`<0 z0^SI3@75RcmL?`Wfyrm?n|;8;p5=>Xr0_NiD=gVKtEqK-^m5hqII6<aMZ^3elhD0I z$INWVrI|2&COFd5lIUx|7ONNgzC~+u<B;8O$8vQq5*C3K3M8^CN3{0tG_$oVc<j4_ z6RpREg{dq*{$?JO-p@oCb&i+dq@JfQ252yR%q%T2=SXn~*bD)<3Q8MEio|<gPJvqT z4YccUS4|qP2>o#^)*PvUrDclKowI+cYMiOGeH#*@6tuJ=L!BwvHey0U_uQ*6KllVk zWsYnT&Kj1E+f>yevxzXGr6EU0_LUgVfVNrBX!6L~!egqZbmsf0XVb`#X5G<K;n{~? z`GY{V0V+pa?EARtlj>bk0XZt~B0`-r%3%<QeD^kdof3FB!%lRv&UOg^p3CUF*2GAr zZ6Sy)1q~8HW?uvtP*5aL0;LM4*~*j#vYMv`adAH9y5nY`r`K6VL6t;K2Cl=$S6z9` z&0YH75qkf~2(%3S>JPRPh$WKn71_HIl<dAgeDhd(UE|LZkJ${49rQDO`l!hK(o2DL zrKaY8`}V=vamKGb4S*Ivl~>4QDf7UdkBg6zb6uN>I=o|OXb6`yz#q-uAI+D>Z9_&y z<q4UK{@@CE8^+R#5#bu)eN>;gSoQYhk_$j&7E{+$SNj@YRtEvQsH*yY;KVoUhWrwp z6_S=_3xj>h@<E<{K3S5+=iuOIqLMEyDcimgpY{0(<F}#TheDyTIDEsp-KtfZ4ni-l zw6|~1&G7P8<$Ic>eX06QLe-?FOB4r41_SW-!HHP8J*U3|pwx~wwKtLG#EHZLNfq@! zWw8fM&5DRY$(;ZSW!F)ly$6-ZeYFkmqxkL~2Ebx~3dFTY+|tr$er^sj+J=V-;$>g| zqE8f~+Vb{F72xmz(n!NsI=(fk?JO;>;p2-zJf3A7-L-sruL{5#R~{eb<d}eD!Cz}I zv-j{llE5G|Fm<7^JKqi;UfF^c4L8hyAF7LMYG}YOrHibqObabZ00=3gFSFGFFkTZ= z(>mZ|Z)nmP&uY_bv)bbg4gD?R42AVv&VU##FVElY87L@epTnr+SAnRge`+eih1a<^ z;fqK8E$Y<ZnYK>=RWC0GOqCIk(E%YfkVfE|efNblHa1>>aTKeXTdlr@syT28Rb*wI zYcq{bPZP6Qmwc?(b#!zz%L8c?D`FXU8Dc|exQxJT7#$rg8Q&VtO9EaXIFK(cI(cys zkyls<WUy}__4QY`MSjMXvf?u(?QCrUxY*jk!OYY&&|gR!274La5yh-E+&_c)+`jA^ z&+K$h*T4WBH+Q_Rk&I{KQ1cdKDHP~>Rq!44$rtlDhfk{ZSkqHdXz>Dk=HCD*yv)=f zP%E0~8tUuA_4Ri)Hb^*h7viW#nY6!udTwdUC3Jl4ag~Ww9|b7W#L#n4i2>POCmkKZ z1_2&kRJcf1eeIP!C1plop(Tb-cyw}jSX@4jL4I0k#+OLH;#de>|IpCDAa{0N9%60l z{rmT9tX#zUJI02FKxCMn1)tm4xB?7AQ&vxIHpA$O33fja<JVND-<gtdR2c<qQWBn3 z<L7sj6=8AJ)sc}$OTTh9wOwREmdX_EiCk0x-auwGAwdSzH$Xn{#E}^k5W#e9zy8@- zM4Wd50iT*H@PjVmN{}JYit_SBOpD&Vd)@$-$;mSto8)ECs5YIy$mq`^v#>z;t+n^x z@n3_FbXN%^IY>(Oe+gK%D&XR$wv`&Q1C%oX7S$XYupJ;k2MTNpw`E2V5h2XW{mmyJ z^^sWx*-+++7#N6<&Ql;+@UHf*uJ(?N6@B&U7g+lYjQPICqe%@4MZz03E`L|p&pJj8 zrs%;-4@3lH;D!`V{{<KgB_m~*WDKy>f%k+PY4Kt@lahT4?52Mc`aYrW1Q004hjt*T zPUQDgri+xwz{*jg3-7>5!@3$f&Vvke7{LA|Z2iM2bgJKi#-BwzK7P<w!Y14S5Gw28 zp%9|;pi?KZ{dNE^fLdsoEjG<-a9hwbQY8Yj9}q)2F7wN-4a6UQI_;faHH`D|^8?+_ zDu^CuwYH4R!mB{sqFm%ACNF>80qdigpv3ABCvB+om^M>acgKG-QHR_CNmy=f0wB#p zeL<0_<8kCnc6NMzeYIL@b@z4}%Jo;2>ldQez!iaN&i!ba8&%O$>CoDYum)6q&j@1= zo!66;=q~rNtX!TLZftLRATLK}XD^t=QK>;vgpBv$1R|ibE1#mX1mW#1lP8Wvw7P>; zn%fu70j`y83BhrEhG*~mm9h&9UEl|;p0(FNNVpARxMHIv5mR_a#bp)c{tCynojFH9 z%fvU!aKNDf`u;2d0cd)Dhb!K)za=LDI;($4aq;=qBD2}1>Fjvz-W47Mf+b0f%`W>S znK4x2(W3*LniIF5?%gTR{?#Lcq}7Kt7@JClgJllz4Jr+S)0%>TfiiaXM}c?6>QD*F z%BML*i|e%VPb9T}a1Xp49s6dfxPt+_XBbv|iyp0Vcc>KQ(a{ldGZ^K*JYA$eq;a5R zA!2BW9WGaX9Je$)38rclFqN!k^=WD0nNd*^6f*MilU4jcqhC9FMM)`YReRalxonn@ zpjk!46rGltpFRbU!m+V$SCQoaNWs`e<6vV8?OKk6EoaGzl7tAbu{sURbzQBmT47@^ z0%IiLA5jw*SD_0X86C~kuD1iEU<=2qdnw<R5sunu2`tu9s^4Q{zko8NI431Ld+x-q z$$jM^o!h~*Cp+6<mQP<vMM-3rVPqsOw7(5VRtfn>oOea(aBx=YzHR52D8ldFmjOdi zR#dby&X%tUvpHG2)zY|8*8<A#P-nxHL*AsM88?wzDzXJR#jN!Fi(`Hw-7%dng>NK# zfWO9UV`C%k<X?9{@BlY|0AelDF(rGZyN5BFNxRC{5wgQ;cF8p(4!AqcywR(($q*0# z7TxcdTOh7yii3QC@Itx3DL19K{_Bf|s*H~Ap{a>Zs)d~bNEyJev$OU6YrDG!+j@re zH<LADLO{p?<R8%cBHSantmBJ|J4z_?8cw$x{G)w=d@3`&?8L2c9MxKfC2sHZ({Eno z50m$f2Yv6ci|5YR@hc$q){BzI^HcY2ZyE0y?}+q`Nge~4GXVNIIgduQ-MbnarTSBI zbEP2NE=v&Z6&lbvM3<MnHC{uGkdjhU^8@VzkL7@{BB`*xEKiyS>yhXi6P4(S;6fQH zGjsEZu4VsGBM|Pob6NjIg@6k3+e^7${B};WiTu-qBq8Dufu!Ck-hh}blg7_;V`GYM zpaDQ_?p_5E7k9O`o(HlQV2~E3rbDCL=m}3X-^R2-%t1{luF>}E1G6bE7dNN15-)H} z!zy_U-33I%iSb3unL^(d!rr8ObDl}~0;G3#$ius`F~IcdkNOyii4njzDmG<`C-c1w zmAZZ5MS<1fUPb$7d>^1@zE-~o?+eY;PY4i$=)Ik^4aBRBji8W|2F{$xXL4}RebZ(| zL{U?-ef~XwH3bCSfCm8>RLmf>dtwO`?U|V?KYym^6@UNAQdC~R$-~k-*rY)f4jO6J z*Vozex=+r|@Nsczv=89s=44NwWoStn3Uw~;fBGb#h;8e6{R$sGnz_=dPmLj&p+H8* z$T%`M_+<A9$>y3HFXNZAP800P`Nu9HDY~v+H{C#B`{7Htpbl-CTRw{CqfC7GaIa30 z8jStJhZjsf=Ln=u@H-0>B<9E;ap#A&wzZ(tvhwmTZ|0}BZ#%91Regdlo<=j0-oNu% z7IY{5*+|6Fxc{RH6-WQ?3e^Aqq@(`_HR}iQ<k^!CtD}WGgT_Wid##y0AbHKqG-4LI zE=fwd@*NssW>-Am=CUAJr+fGP@&4xa4*qw$j$GYr)cYbZ(W9#JO^_3cRsZH3os7W) zaXMUHGCFXY0HVV>!nQH~p&=yzjgW<Y`}(4&PD?;x`Da>N^VngKZ2b5Z<~hAl|0hF` zhLGDIiO)FAegNd1K}Ah<&7(&)goFfQ6~AF=C*PZPW_N2IO~A0!X;6gqMhqE{?H}(i zzvroQ%t)sK^jDKQ=?@VJ8go$cI=p}8TAr!iZ)~;t4`?UDEU&0Y;v?p?8NT&HM20E4 zEs2+N;5V=Lqsd@M6be=>XmoHV*xcCkHC9-Q5JE8EZ2}*ln~OfD8x<doSf970V)8yU zreImwE4x9t+kgDn1<2j`@i}wsyHVf)tS;^XZ~`!WC$?~@E-BwN@L0mbut3x0)BfhU z4seB8_v?%@=}u6v=1)Ge-&eKNmfPui{(qbGTU)dC$`!V@W&)!CrRu1rd>c?XihQC5 zlC9ApZCP2_4J6ZwK=IddSo3l&Z=kigu{n>OQ;|<iWqdq!01fSFV@vwo%=m&J_Ya<5 zKYrA8bv+0A2gwe6oXRTrY;Z@4VtJX<GHymFv@NFioo1o>+c}6UKPrZgqMDlZhMkhF zEw(M4{1Z|g9Z%3%n2?a4nR%a(@Enw~*qHG>7?04ctsN8<6bkbhLW1}+cs{>;`m8|v zv^#3n!`#xuNL`u1b>CF>Xno9>E1sA~H#ML%K9>&Y6v(KK4M34ypz{DIvUp4J-7XQH zF{@Ed^9k_*{2^HfJ&rnu&J1E=RN-$L@7`WKcGz1ki%4IBWP&V_+<bt;%q*THHvj7j zZb0XOvRR-tDhiL23A85Vq?I0AoPO`lKm17AkAigF90tqMNG@3f0))(~QZ5?+q^dlx zCs-Oy^ld#2L>`kAWoAZ&hYwHC5uET_AlRAL*VceG>Le)nM#T)sk4q2fL*4&bvYLC+ zwY)-DYrS=5Pneb(jEl2^8Cp`ZZ&p-WF1UaMa%CWz3l8pu!ElpEW>&Em0Jrsh8ec+0 zgx!2!@aPIOUjO@E01kTT&BDS$pw~OGwN}Vk8fgUK{h|$ZzpOkyj-W3wfS!)&d%57% zR4iyv`PkrFd0zeGtz^*-Y#2n86<5yxQ~8MWz_}w(IC(h(yq%5X!II6e>82@QL_kDt zn6CVdxeE~dOD#3YGITTc^e{G@?1uw_0sQ!P+Tg>vSCYFxFyMC-2d$WmTL7!kgsN#n zp<Dx$cc!o(Kb9>%`6wT3W`TQ8E(QqB$EYmH$w0fZl)1xxMgSzeu<%Bd%L*FRvnF-B z$7prui{Yu*%n3W|p&+@^QcxJ8vII?OiwE~WJ`3SsbqdS%mjW`jl_(>9eQZbWqVRrd z7nf?>QPAe6UAGatva-^iody_LU^*Kc1cu9$kfqH{E8}-gE9Nq9^lCp?EiJMO9oev9 z0vlq|D4`=ikTN$f`>sXA@$z%iJQYPNvI-5Pn1DGv@Y@5z63}6UdV<Qy#Yw_fTU1eD z1b7Re1p|UIKpd|xL;~rSo?LQ%K^~9@Yino>4h(cpfi5mngQ5PwZVpG4C!jnyXgUDB zJC7fqhC;;^6~e(YOia`qWFPQt@93a3-!J?AJq8WG7xa<2e0R0Cb71i#l1<_m?i@IC zTI#1)QMf183efPP^sG(;Hqji=(wXLkeWNPH1|T;v0hR+Dl@x<zJP{x01e!NE+#BkO zMn^vdo)Petp#9R-^QEtZiVDz)t~a(EblYM-d(@i{R0Vp%;c)RCc;li;k@}vJF7#*4 zAe56+#mnoBA)E8jFdbKXop}cxZ@*u5+P%{%;8PqNFviE9ck7o`653K;?gI-oiRLgL zD4VL?>g^4_MbeMhuAI#S4fKG@;tjGtZAfllq+{AzU$2@*4!>yF-nLBo`8r&$528~W z^R=L0aejLo2zX*6J!*E!5~di)$-^5{FT8w?D=Gu5kc|DSbo5aLCdT=~ZU&x`CjIIE z(7w@?*4G!=A<Qo*c!=@Hurw0ruVR>`pwL^`<bdP!Z1{0_*k!T61=a<SP68x7du<U| z6j%k7=eHSks&muo$k{fGb*<}b;-fP%V3w8+$+@71M-E7H0Xy^g^GPAo`cMwLlvKdv zgu0dG&ZA_$($o?e3arPwqP5eb?jNLZX7gyH!yi9Jze6n}Qxm2R<cSn23d%Did#>*8 z1u|5M0{$OKRT>(QiLKRlK@aR!^E?nW9vvOJyR~LzWK5mPbKJyur<kB>D748O;CZsL z-M$h`(SRSr!^NkdNWu=7^nRZ!L{8wM?`@M198~`VceVq-U(@BQ%oKLJ*IUz$nu@De zsJm7YFLWvM(I1HXBM9-HQ}%Y<fr{4^I81HNU|6|2w(T5`OpeTKn?}2uO_QlofBO33 zg=^7g+4~PaFCp8CLrY9CKW?mEZjg4^CLJW~JU2bv7nmLNdjs-#2ITQ^UK9*7G&)OO z{p_f4nvAS9fuFQb#u~^EBc&3(K7GnFgnjvPuhgj5uvk@-sjqiLh*5C3#ZXlj`Y}Gw z)zHv63$C3t2xR3d>IL4CJqD`=y!<r;m6@|L^vulUsmZ-<!d3HXW@ekfTIc5e>FnG` z!|%fktrY{cb!#BWEW!^b8VAq~nEgRzIHaTvUD17&73Fw1E5qDFel5X331L&URm#l8 z?&(iRuwgh1lM5b5O}%Y|?22Y)8FUT{!)^;oZ07(?T;Sas#vBA>QnIo)a-Dz{wrA+` zx}mhRlH9=jB&doUY{J+st2DKDeSa0qdi+GUUswu}7u=hA|D;b&v5BqJ^6VT{Te4OH z;!%GE8c^8OaHG4x%NhjVzjuUMzbxH3YfHjFC$dIN4A1Pm+b?ehuRJJ3q`aKxEa&Wg zloLl#rI2B4HHzK;O_v1NPmR#EZxz3fr@(IW8N6A~Pexf5vW#mOtH$j|LrF=?U=R_W zHpJ7Fvq`zJ>{cUKEtjRgZ)jTX?|k3IrEq({-pBhhwT`sG?Wm5t3<Y>*T^4mghG+p` z8_mr0NxWuAACjAydFbkDD=O-PSc$LW-YA2%VfP7i*+Ikg!^4W~WcVF2hK+lh6FHut zLvWt6R%8)2vsa$%jp1cZ`h^P%RU6d-!^radKt|qn^VWx|{y24K5q&T9f~|?|xfg*C zNSiJ?Hjb&-s_S+HMN<dYJ@)dG_%>GYe~>Ag<yDlI!-_^7FDpxsUBifEcOjjxZ)v2Y z{L$}=OpPmgsp|aJUfh=<RlMOz^gQZj8~V}x0|Uz<Hai%i{DOW^2{70kk#Bm8UG;cb zo1zdK!r@=O1oL^moSB*V+1o2bU3qYUMuzpUr9WJsT0T&>-i9Y(phOQO?DR&qJXn6% zvvE3VFsP;ihsP8JnT@S2Gfnr-@q6-5Vp0@x6%`Ix#p#)1mgZKLmU=>EW!ZkdZS3H8 zhi~`}`T8v~X=_o|a!(JMEX*|M56ZQ&^litw;Y`tl&sg42;7m@8`+Z*6_qSQxmK7$| znoeEW>yGWa@Ab21czS%irMFj`Aq>2TgDbvZaQ!nzYOwT&t}f{e1$;6rz6Y{0GRngH zsEbtW?Cc-E9-t5AYdptpm3Mgm6wnVRr}qtvG6<0c*$mty)g`%a7{U(i>cylCk)E`E zkg(29eri=UwV!TJ11Ri|%3B$9ZEeF9a-RBGW~Bx?e)JtO#qFD_jg}tjIz6^K?0tQ_ zt2w>wURi3Joh!%UQIJhzYh%OZfmoN^%#IdsTr(Y52CtF0cQ=rRk+HX<t|dK{FY%qI zA#Vu0cNMK#E_XwsK$+Dfv5?%Z_H`6qRNvL!axnk?=_k4CGvCh(!Gq1<4F@$AMcE8H z-z(}SR});mgLTlz#kzi&Z)9kAXfvWEUop76aop!IQV>t>B{C{}Y^MwLfI@Y3p-9i< z8|U}KD?KD98@xWH6(T!*veJd5HC$Y<amDx|L9;Q&gyrvxe(A~(sm>VP1q?K=let~% zsJ*%)To1HXO*M$$dS=I4RhgQW$;0!YPQaaxz6<w}Xyr6m(gq_Dtag0FnC0c=k<pO= zuirnt04)If`wFP8sAy=?)Z!*n<Kc;7;PnUEm+jSnGO4Yd(io5JRlrB;k~9#I1hi}% zA6RjA{}0~YIx5Skc^Ae`L_j1Y6s5Zx47y9YySvk-QMv>K>Fy3`X^DsK?(X~s<Ndwg zS?Bz5{yFz@Ed`(Fj(zVvd*+&Ju4#9zIY}%w(|v$}3FTq7nOyydKt2jeN-75WZkWx; z*Xsb!_R}m_UZdn(VMNs%_BUrYL)b*zOO<2{3kf?qI?!Kaz{TZ_P%L-v@ftZLqTSgE zo1$SEX?>j-(^=f~{am`Z6JvDO^?WvIICgzYsJvBRs(W^OkWI0Ut72r7tLbyB%f<wL z(l>-^j0TMpPF#|l+rdVaKUIs_xzOq+;BXES#YG;1?3LEr)Te!|h>?+#-M&uF5w6jZ zPhzpm=}G)m;Hq=uVqT25o4`@H_s~J3$a>Z3xc&H0@A@FAo?jcVcsQ7G+;a)=m<o;O z-FnBy+-6%EfIJsHh1;`e!-c^xXH}X@*W=;rkgEWy8xC7LblRDUslAR{^;q2Ml5%oZ z@SEud&0K{pDVcWy9}EhImRY33nK*WQ;&ZA=HAE{z)wu0WHWIwLz@Y%((8R<fxv}Gm zu&ONi>}HSvd(1tfnwJ9PA$b`UHYFa(9v=GrfsDRGN~M*RUleO!@lsQpHQFkF<U2IW zTI+K;OO<JYIvLpWp{DM&(d+*C76igi+vr03XfC}ttTVe&PKLtXs)C`jA+hdV)p$#P zQ*}wg#>}F2n|#&t$LpF&ckAE;4GpVMsir60UB&IzC<f56bgED8k0MKAaZ}YywQS6r zCcZuupHTJz1XyEtkn3yT*!T%W&)wZxiPA54A>ZLtIo2%Ia<^407nev}l*?g`h7qJ^ z=FB;jmCMW7)Ipf()N%GPD(rZX;o(p*(K?&g6);_*k|mc;M93X$ZfMx>b=n;9d%cP; zdd9@0mshOY+A>L#=uaQ<Vq*61?b$8u3NhIH>=|i)TBDbbM<foL1nfRS&GK{Yst@kd z#+M|d^xR@+6J}CEW+)d(?@~}wqF=2X$%vtr67%Dv*D^6ye#F4{b7bTt=>sPFl%E|b zsR3+kLVk%Yr!H4?ww8{L%EVX2{iRDQ%9631`emM}#v%f0G>h{X7;(fT7IW38<s}YW zxTD&e+gm%@TdUlj>W&T}7cmzhSBkS=P}<&%mvcYVC8cZ|hl!=-HC=9Qx-|X<I9PV8 zgMFJka{|1jDtn_S>h?py-P_BdM;U2l@9HK8h6Yf(pcLZk*RP*(xi(IVGRy2n0dI=n z4kBq78s=CTI;}$)uAbaJL?_|Jwnstn;l#6_`Vq%vXSWACnBOXtdP22VQ`Y)4y7=eY zpM9~IA`L&sa5nTeozJ9x=dgFpmQI(WRBoqCy6;tgXO0F^(T97-*}#>;W-$vaKem`Q zczfw7q>|i;*RFchDV8}TW~mli_wVa>#C+u>>tnV5F-}9vNjX)Y`d!`pG^0q48;BWh z)p8r<LD508%a0zTa?r1LEH4>tg>2+_ZsZ8YNiq@|%z%CPifewZp(q(nV{4aNkQ3aT z?v;{|V4-7SplP4JjkB~|syFiE4Jtgy)Aw~Qu2<Zcatd~q(Y&T-gmMYv9O^yq6PN={ zCy@kdr_gf0r~5=zR=zT6v#DaL-aj)cR7ywCb~%-x5b&7gS;{Q!8h@`9xN*(zfzPw) zCNVUhdeL(J9xI0F#)8y*mx|L5FQsgHgG=)<A!C~Letu>w4|U-BbzfRNO?bUZPD{Z9 z*lTs1yo8%OsrhYfZQ;@j!in*zsdVf{-U=%Vv$N<Auv}Q?olhH?;PDK#e1E-|nVn@Y z?|2y}$;->va19yR)>@CoBA68>d0RwfPC|hKae7%49mnFVi!*zfQsT3CO*4ETO!RJB z+lK9P%^nrz<amDjp^+;{?<k$|hDKw^*|EEqJVb#qH$PuLSHXT;FgzlHO0mMK_MjQY z2!Aa`nq(d@)GQKKN9ndgWBG_fOIQS`-y2Ix?*$1*llVrNENHSzN`$54kXEOrYSvUV zK>pO<znd+8PC&wcmHj6ofdX8;7jJ9s-K*Wm`H9^#A0A;@UUYnX!}eI|M|qdbv*=ia zVZMNXzi!|g@{ksOji)yEElWq##EYh9mxO-)l=8u(wzssj&cXcj>4R}W<XZBli-7pY zm6@@Y&_{P|%qh5?u#Z@Z_8-lu>Z#y=cB0m6o4=EmMn1ztPdHR*U!GMLAF_>!7LF-P zqE^|PtB|3T$c}Cw=&6%uL}Bdapr9jdrA2ei*Eu`inR$|NTRX5gEIToA7V32yWZMkQ z&DD!$P?J!=NXnO%4(4|Cz^TKr*;T<S$`u<3K-DG@_cSsy^Y-Bhi3)2sF)}eRkV@Ch zGnz}Djh~9YHT}JeYDN0Bs^e1IrWbm=sF>ItpWA^!=v*GoyZ8z~dw=`BoJ7L=7BX^n zMh0t?g%jXut{hFqWb&DrnV4<rLqN_Bb&Ec%L-_3N?NuJzb%b-1u(HZhr&l>Fj(i=w z6CuXZEnT9rc94tiI5)>OsF>QHU0QZen;BSOOlse~{3C0pBU+7hocGrk_5#6%&dtx? zBUm%6@a26FYoT{iB1fDI`OzZleH1FH;yW66Y)%&p3=oq^%}Ns$E#q`uT2bd3hd^%B zxk!LdOp`d3h)7*XNQjWIQmq=Qh{6{PMZz+Amv@1daclnQZ0<u$M{)9Z7A6)VwMs_k zz7r_he#(Qtuvl8wdhE76hm0S_0gfSlCnp017ZFp0Q2YK?0uixl42N^gci`M_)b*7+ zK2uUsx`#W&V5qf|veAVjCZZ?DFTE8aPLg6KMWSBbQh?qiF+ZIw5ml&hCY>m4dDLc! zg3>we^nPz;6cvxjw&sM0@?kn81L|uC%GY9ooPFvheet>cJ262`5io?XLy{zI=U1+y zP>9Qs<$faO<dsmDZzQKCRph+BS5(AI*wWFwwYR5QXf#@Ct)D$!(zn`dSEj;MYI8_J z-ERT_yPlp(M1~PmqP9J`*x)BFH3kZf9_2)Nc+7(x4s6zaH13e<j=AvhBR{Wz*kbPi z7-ICUA;f2Uqt6no)}PV8%VjAjtEt(Yy{yP>7>Ycf`J@ktjMkwc9OkH1wvl0lwt<n6 zsrR4Hz?tP7@#u^yFG-S9la>w!fsu+pUq$x)O_Hea-jMR+4M*#Tt|f<Dgpn-v0bqib zb}Z-ai;H&)$Z?h(x<`GuSBufw@3OP$uB2=prWV6xTvel?LH-&9#he|Fu$EUq9w4Ur z{`ex7t2Y1V{hggN&0#q`d*-Oq?mOA*L;0B*86P_5vsJ3(vilzy*X-?xIAf_029%h$ zCTSq$44UZS+(Z?N#4<Hsx0slS8E34`h}gb+y>1g-z^#(vVr)R%@Z0D7_%YYxYI;T6 z>iIZN&!%bAt}L$M@NB|3Rxo&$vm!3F*m~4xr~naoFOF0vh)YLj`8keCNHqAuim5tT za<Aj6998+0sgO%dw;7nbC(}6?!_m_us!+}SVsTA`W?yy(vryyGnv}uMlnK-)o41ky zj3Yv8f`3EMesW~SGrfIC7+2pkY~CM3u%`ay_njeC)3}QAtqvTjLU6Rdxa-I(3u-y0 z<rVyWJxOjLwb1Ar^Cjpao^T@5qkP~UEX?P01a#+R2rpsr`=zGDu!^Yq#zuclxSjYi z9kC<*<A7R(roXSxCPQ>2cY(&J=JLq*ov8jpmouP!Q&Cc4c+aH^g_$QLj-9T-2J2kn ztX5@Jm6tblcJ0>hTiQ78Zj$Yte0qG$;{QU&Q1c0zmzV-E1WuEa0ZDp#Jf}9H><<{K z;zSBj2W%+yV1ZH=D!EQ}voS|aFHfs0%O9r;&@nJXvFqw7Ie{|PXn5B&dbV2py=%VH z9Wk=0uQi{1_r2!3{Aj6e#G|~dB(*o~OTZ*oh#ECzi#$1o^*m*T#U{xe>+M`^5}Z5r zpL}s=S7)uac5)vU;=lkOJx}h5K3-fYjqTVo-3RXVt~uwQp+tG(Ord=C{N~-e_wL^9 zTi(5$82|0@zVH-Lp%P!^Lk4cEor&OqMT)R&I;^`54SbfH$!@!(*b$4k_w=Er8o<1M z>A)=F(X5#vnM>2<l$9f6V^#L&9jUnt;7w%8lKV%qR@iK==FO&DyYuIYNUy{QT0_Tq zrW?gqlrX)>@CscP)5KT9vQ<iK4o{Hyu3NZ&`$zca<oq;}kz!01J?@#@We|QOxp_;U z9YMA}1j?#^j!zj+SSW5!XuencOCQ?Upv7MK_rFLJnr~(QvIRgg^nSws6q&twjPaMW z4??n6Q~woVAYnZgypTotef&Ur0aW_G$Mu`ie=h+-C(pn9Pnzk{yZ`G;e66_$0*M^= znt-C@+n|MP_xR66Hgf7RNZ;Hb*pmG7GcE7kT}3GXiW(YTKYM@<I1lJTr6G*2bCA9n z$DWD%^C=Batg=*6>M%?^j7M1aM^d?-GEi|pxp(V7dBXANCz0N0UiFZ?ez;)@z9x{7 z>uUK?rG$m^e0+=*3_key41;FDjMboq$DaueXRf{^LTLMF1&e*!%F(!=vvGRs9{!lT zoZL%Z!hmqk@R1<+(mO{VCZ%@!ar4ssQYqMfLfF~tO}u#QiHV3(QC@LvH-(8uvxkPo zT7Q00Q^)@dZG62V4P;MU@&3xvPEaE^C`xrn<zB98zc4MF4^F>+&|2aL?kGNIg*lX^ z!2gkm<5%w2>FOjTsz@-qy(WLK&rSU2$&rw3m}aD5fM{qRvl1~ihkFnbzI}cl2MraA z^<C2}9a$PECFK0_bR)w_lupm>yHK>bI5d#%mdXaF`#icJsp2R@Q2gN||NQ{D^e!VN z(V-MzZc;MVA{th?sXTqWVwR>>_D+kaAbc4c(_D>g+Fu=i4H|c#9r@|gb^OndCI}J` zM%m+nrGXB)%WG&}GCMO0xdT#}a;nvqR8V_q7z-v|IyDD%;NGLTT-T;zL|z(rwBMgL zDJm<2)ln&N$SO%#aQh0A;`i}GQiFcrl1*dq$J@ww4KDX@Ue%041<lFwJrj5ru=<oT zVJtm9`P17~5p<{vPFR&{#(noRSPG7ah+q*B@re)v1mQI~LSC7h!)iz4=g%BZsqY-C zt@C$6X<QT1%B&#r?l`q!*6Iz12+LRb{pI&}e71h?WMw$uPA{a8VbVk&yAAiPd{y>& zNFC;hx88&OZ&}<egEi+}qcwU)Yu9!aXn+;iSoe8($x?-)*+<HMdeVWB^;PFNx5|GR zXJBm1VLNwF!FFeO$Ogh7p#Ia@85o&W*c@`Al7)Cvc!dFChC{+d_wrS(v5_%aM*}KE zVk5o1j7C-_(pwmnY7)F3`L6YwC(v>|{f(!_MqB$p$(d22^!&GP6Gn=!tE2zc@*w?? zq=)Iyb_A*>I;AR&vs;{8u8d0U5V3ob5-~xZ(rYm&FmPpRrH_UwhCPHzK2^5O0}?(J zCnIFJJs_XapL@aJ{<vvfn9(xS64^RyyYd)K2(S`AbqexUM^0;Q^<M)6&v}Jsqw^ME z8+5W-nen1)lZPaplAO!B{=X7HT1MnjSy@BHTd1WaC3Ca$4vtRSC7hXZK>-nVhb`BL zQ5q~PEt%}91S*56K$s1&IMgQE&dwZ}vzB3`lV7erX+S%&+SOSfO-WNNgC&yOGrAh{ zcXA+Av%I3lXm}P=`||15mNg_t7iT^@9+pO{1<g-QH9q)Kw%<R$OGs%G9FmBLdwL8d z)#@tJ3DRT{cKZ7A+61XV`7cu!9(+=v4q_MbQ;)_?#K}x5E%ho($qX4DzQd4jMz5}_ zG6Gte$LFH|uKDTH6ZxXAo>S;kk&%z)JC!NXy!>oi{4iSJlXIQQBfTS7vG@CFJn{>2 zG#d5K@(T(G2`{PBYP$3ee(2%jyVk(>5!i-|d-GPM@Hd(do~!FA#1G|TnwA99M}EdI zQM&7~;@<ykZPnjO2siG}qW>7rUK;5_#7RlWNhwYG!0#qbsZQ5zz@qy9Bc+A%>0%;! z7AUoY@q*i^fStscObAj}lbWc&l@A1IAsqaNUA-d?3ma8uk!ToLSh!eNCMQmZEgwa~ zI)Oo+o>KDd+vCrkQ=QR{Cnyrv4{p%)gymW1?Kqu!>!w3CBRlb#s#saK;gA1#(@@MP zUz`$@ttuwGHsTQw9o@jJDZuX=&H5y*w3LkcOx8@zuKMf0UFXOBdhju?b9`E}EUj2b z8Tj#LLVOk0^5!keeOp5{8o(tIBpI7XzG4S|ue&1j3~gWJ(wUk9sNVK({#|fu-I8B1 z8h#lufg$vh@U*tI)RvoXp3Q?A^%~)q|5oJ>E*#heKFOs+=nj9dSDycSc@t{LyRyBK z)(1b&YVQ5}_{6>uY1RLzb>R#CKiKyEH<y^uBzY*3Al?y;GpgdDsHCvxD0)eKg4D9C zxCEckEUT`qz1_V~S*JdngoTp<*yx0joMes7LPInHO?a2yJh}X5<9_2Y%5!$qalCF? zl$*;`G%!4PK0i*tc9YK)-+I=Y3Gj@y%1+<Ke1e#no7O^^l$p-!MH**;0{xt0y}giI zompAgsz2fpj#fD$dQ)Ed6kGzNe`k*TUf<l;Cmv@I!}z3S0P8;O%T!qar}iBc+|Pfs zW%#PGgBWF|a=BV||Ni0qYMM)zo*Eg=Fcog89a*q`J+#JjJ)1qZTN?vfgQ}WZk=|(D zjIq}#+K=opRHQd=YyLSa8nlPUH=uYfDN+4%B(C#8(-l$eH|`UeE28gfez@#z@5Zvy z4e@KpD1^JuEIi4S>#@as^k{fd1_V%%)6>#8(e0%v1ECiBK5+YSuyNVhttew@0A@Ph z9C+f#&tTVf5WbM=ROtrgR`VUPm5vPUZEYq~A5xIcpF{bNF<JAi`KdBLJ6VUB0lI0( z>-1&%YBznRMa@&l*qkQ*_~`>k0VO4j4YC+n-SyCRB3^s8ZQGG?SZG@)k4B@UpukzQ z)(jO$;?eY#s{K{F!!&+R;qd|2oI>xw`izA|t5tg-1m4TwV6lJfNp59jWtd<YKZo9q z19h15%0U3I8rw3WM9aOrniIUFVEaP8Ugk3UQre0T70`{^I@c0VdbR0&z*4L!;Kpg- z8+*%P{VW<{`vmFvceNFe{=|N2X%#5$6+s=qDkt|Em%TtDPIkvl06GWsuWRGVjU)bX z0px-OpFQ-de~<Uu0sL`=^al@V_2Ye`ZVVEV)a=hZJp-24+hO&`IM2;OP2f%xi<Wj0 z*KU2j>J3Y4yuGt(p1k5>2{Exy;pp?7Eq=Z0U*M)e$Dv4XmjF_r<|Bg9+@^g~A6vZy zQ)OXj^yYPR=XGAo$=$rlyk2>%39~s0d$ED2LBh;|SVu>p|GSC9$zr09{79RiM75)K zLmooA32K|+y|A#HX&)6R0=(GTBFxNrwgb+%=sCP~OICZgV{ZG7%X(;`vF1M(e&#Os zagPoB`V#6^Ieinjl*<Ip<ji_F`K?bW`nh*!@_{c6Ll1S)6=thPYJ`h8ka_!zfq^kI zH_N%ba|Z@IT*OFEZ!e7H41>#2n18OltSmB2-Nm(SVUzb+SSz3)AkhKzL~Cp7@B?7O zM7$CBD3GOks_;tNRaf^AfIMOeUp;>`I-?!s^8<Th<>lQ+WB?+a9}JgQjt7*xQi97H zHQtnw0^S90f$@G(&As2-<;08Wb<CXeA8U|Opm((Gof%m9O6knuoGVy6Bi85_jm5;a zhw!5T$?E&yMY$X`&nr;MH3>a8VLnd8ROhfe`B_tU>`6MAoIh?l>bSUdjSx6@m^7!s zZrl7KB6m;^kB&fJ4o&K){n6*sNv|G#aax9O&>pf|JDY@euJ?nCt|#0K?-m{}fc9z* zhl?#Ow+W#To;;hBBpytJIIsKZ@p2pG6M(6^P_-i>c<Vkn>bO=#462gb&TU^)ET;E_ zDFnIb({bnXZUaW%g2~Nf4*y>Ry#v1_C3xXo65z4fO+Ru6%!!Z?9X)7Zz_60HyK6>> z4kFU*inDhwyF_`DlD@(epbrY{%W@M<ly=+ba&DXa8m%gD-9tsF;-Kg7pc(ypHnFN+ zk|o`y`%y!a=ns$rB5*z7M&Iy6ebVQ`je6^2JP-G7t@8Q_6Ae$8=j}V&<BrR&&dwfC za~rdE6Y0mdM@y-s0fM*>*+Eyq4><0zAf`td)(Y{&#b)v5#s@HVkS^So`&6SL$ckC4 zF*apheV(QrmjY^JcwBDb&96|UtgU7Gm&C!z%gD(1jL%c+f>^Xs$_#DRDJ(A5*GV`& zz9yX5;g6Q=DHQ+}6ildtLqlxBU&HI~qXK`Zw)UN+Hi_Ufar`xWX67QOZHe}eH|}4w zDI@9Qu|9J-@hj+69#m{&rR$P8KM9lfO-F!??#FwCgj?Ill4-$-x<sPRZ`>sv9m#^Q zZf~G)TJJpz>RV*5P3>ulKoNPEnUX>pOKXO<ji}RR%@-*Su%S0!tJNlP)43<WOP=T* z5v*gZ{Ro|FcP3T4C%Hq5dGMwQq~|>$-|gUdxH4EBWVjC(N)2vPy$NSWx98B%3-k8A z4LFUy=BrngfHW3|(V%V~x)637F;$L$5r4swfVtr4c$A@fTH@oQ%&(`!uNN7X+?kh{ z4h8o|r_WugCPKo-74jT(oA__sn53You9@9B;>?Ih9sIQ035wif)^C1q*83l;-8Hne zuP~I)k4S6+ClF$Uqr+>oALHu@y?UEVr%iCoX=0&#THH2(|GEbxnjvRLuil{L6%xY4 zaK!*rpkvR>MNHZlFR4qasp%ORHTH_YAZ4Uy2Q{a8U8o#1%&WW3ukP2?5e^Wq93342 zgDx$tMLdp~vA6oLU!H=z1^Ne^ES?vMM$rec6+px(`9*(aZgw_E{Y&dt*y!wAR1c3w z)vSKDF}Ji;7~ZYwxp_B0kTQgwg^`(6D6!35IAm+4`8yY1cfhX~&up#4MJsenK!R9H z+-2sc<VR^uBRwNr=4x6Rx<z_aM@Of8h2YrO))gpesvo&VJOP$bl!KviS<db{D(pI~ zGl<5xjEv0BCk~RSvU^q+=3JFPpRYZtoOEr4EJS#)y33}1b}LCDmMS}7b*R#h%m=H} zPr1qjv9p*jQcb>CB&ij9cyxg1Yq{_+!j)5$d-v&Ob?OHu>ncH9&);*%#?;Yq(6+Gf z^uh12@;T3)4HSCu(A4Z~5s_+qY&tp82hn~!V!X^nMZCRR+viWV9V!+UQp@*E))_s2 zy^vK=(m7!_Zd8GdAZj^BS46I=Z1dyR7Cj*l>G@x2UkTENS3s}F54%WN={+cZMQ%Hv zsXjQNXdINr1FsO?Cr$NPuxE_>o<u-^ws<s~nXz#z<*9ZF%J#<Q-sx7lgr`A?hd%$@ z>W<&Xk9-i$N$`w|HV*RhbcQZ5zLO;FE-vmz^bZaXqIdNxb8G8~<SI};^l50jxy&5s zAIE<4BX5HA_?cyM%?m6#qqcr!9uh(h4v(}n@9e5G-@*Dx3rPQN503MYvd|QRgxI_? z`a#dft4Fgtq;uV%;0Gncgn9Y-=PN$#jg%pl1u<)a{pq)nXg7{nDU4>l3)ia(o4dQy z+`ljWL^Sv{%|^2xey3Z8pqN^{>c{k!it5PGz5+M*8APsre#n3jow8CgG%FHkuQk#A z_D7Ebs@0$Ob!OW>jnCgqzH)_MF#2o6iL9;dYiDO?n9UD;0J=XvN_QutqB>i2aY=qL z!?d;W>*ghO4I?9FC^JiG&TYH<xN}lXDKjZ9?yYC-O93k7BTu^1nI(2;)DhFJhaNC* zv0hfD1PEo_BuFM&*vyn<ZQFBtIJ*|x&eO8k6I$8XZSHNAI_=&@1-1Ng*7Bo+1JtgK zNww_iz5Y>Wd)e3WXaQ`UBb_Wih9aSqXbbu+Y&md(ZS<$Panf)TKgQj4TOAcuJKVZ| zc^7mHq3{keIY5e8d6az)?hboeW@=n4#TYwBIp_IGY>5iBwKQ=2W9lkTPcD1@l$zSf zc0ajLWNcHrboRE<+0uDQPLAc$4Vx5F_1CZ2!21OztzJGL=(~gGMZj&?y;u&P-f?&Q zcb2+fvpsCRXM}Vv#4(!u)$Hs%ZB#hQ>C4AC0iJjgUrz!$F%OOo#sx)Ii<C8fctZFO ztT2$sq*mdSSCQuBg`AJAF$*q-n?rZKK}3a8ru4OIe$V3N)!e3=v~T3+=f@mQizJKV zwYGLbAhf@W{Ij`~iQOv0%S#Ac#)A(GZ9F6<%p68r58SJfu5=}e%tLA&f)xn2_WN)B z=Jnf%5L)Wo=EGJ7BuZJS7x$h=#QUD!-h)#VWqGcx1&G#%hHaCl#n*-^D|?nW3E3?S zBs6|hSDl=c_sOloW)Ep1VtK2lRJNcMs_wp7$)8?oHLC^Gemca(Z#QdoU%aTvHg(yo zZLp@PJ~%2?wlgRg0@(A>-A`@Q`SGA;&}}|;uwPC96sO9n(_fRPaJl<ZTZQQWLmu>x zpJ!)gip3d>Rq8umK-^*A*m9Rn4pOO~Sx|6LoX#QV3bx6bZSA9Qx<9F5wQ52Q7H(Lp z<OoN_!Fg15tO-6>UzSQ$q-Pef>fy%pzOz@t_eiC~npe*9Jb7yY7{;KEiI%NalwYV# zOa##-?n9ij{ptz;tRc-V{*~Qn;intnlm+XUTGjF1x*q=qY)I*^+f)}G<bbaSppHJb zd+BTsW{mUfvANyi?h#m!;_*`s2IaJ5j>|~24|1M$b9c~gZEU#gub#K0fhW7^b>`<q zXSPzGt4(~O-!mLNr0#g=*D6oFqn$)duhsT5U{c-XaFdp0AF6>}_8RnvOB)j+n9t3F z<kB}c_oA3>=N1{70H6V`1Z2;Ks-}mH6ft^|6A~6`6Jvv0^fHT>=(T*KqK@Gy3zhuD zlb6H2aahcx_4J&it>WKT)<JbqXJc$tL;ydO+ILvl;@Qou2xZDKKm_15u*t7PE-i(E z5+LYO?X#(@Fw%6(7k0#rAJdx-m*0xHx>n}yNy?ir508z-RaJGAjI<3<Kkx<xzcRT2 zK);+S-(rK*AP8iFFcOxrhka{fV`%HF-71K4h3|<Q(xaoJ1BFPta9wTV@NyP*aZ%Rx zO%-au-m-FY<9Z%nY*vLKOi^`o0OAxh*Vg7ig(<Lcu0U2tgGRPE#gC}lZ*}w{VtZk4 zZvKk_%d=rAS+EQM7bo>55<-B?-kqpiu&E49O?Nl<L@HxOQYCon!>#A1^R3NLr9cHp zb_w^v0~M-tt)dt)R#kcX^2f5q#_4L=>vl<4`D&dSw4@>4fVOo=hecr<a^llG)~G*w zU+&{`$7^9B_tgcp?vz9E!b^BFF8saAfU#QICLW@w;qfeRyBM-PmW9(1b_W@n!r}W_ z!v*(HnOInChqL;Z*NIUOtv8i2i-r%Jy%U~(l<sOxQY$(m1|5#k(5s7!{s4@ZaVN!d za&nHl8V89|4+Amb^wIsNv>NpTbm*Q2husL(Vt+h_IB3tJ@P0#W;HF8vR?~0Zp;|T# zWy}8V?mEEB|0}m_T22pbC0m+2(yv-uDjfltP+kyx*3i<bt;qWTn2o6za@rqzaKUU! z1!j}|_*u57T;--;*qTh-MU=3G6JZ%)-=8TZC38fCF*`ji!3$s{OA*k;z+!!j-(DvL z`Vu7#4U^kywqX`!=q=R3;&E(0M~Z(UY(L&7!-?@Ys(m<|m$+vkiPbvWJj=!#eTR^K zX3Ho*a)jo_*6wC`NOXk5F4}fTgBF!~(NI&<`A}gxUOD&-tE(Ryi^WSyN|+dX_i1(Z z>Gl)isyZ}iFE*&+=E%s%+aC$1qjdkFD)`SJGlj>USM5H%z?+V^dj0B+>sR-?C&xZ( zX=_uU2?4x`fEoJ8+S>fkPKZxctcu?HNTpEewY1U<sin7Hgxk(Q9Pom(w9{nCAHDVa z^`bY!V5#J&l7zev%2J(&dKDoB!$?I1enNRwz(2TgqQ=5pw{<-VB%>oci=V`Uhkf(o z)Q1lYybmy#5|jAtE}|lcJ}UOVgYgG1JnvrXnkOj(1;m>7-~LF_*0!^IIQ#(*o6Zg( z0qAE{av(E07w1XJLDD)rY>!B@o$rXQbekR;{b0GZ(>1VQXsu84>(O1XmbA0sdxsZm z_4o0KK9qNfd4O&Q@M#*z3bxLo0;)b(s6YIEALr&nA3om3X32DX#jv2DkdszJ#SJ8M zuloJt)S{f6vh3*#eheHViBH%mS|FZs-9(V6#f<R=hs6%lEN^{^gyK!WBfx4c*sz<^ zsOJh=ZS{85-20cK`F4&B=@OJHz~$VTA<HtW6J<*(EZh<aqk+;nWIIV(3tEc5pT)-q zFzPP-zl6}lq$VKle=ZNxvF<Ofbn%P-Ckdhd4Kj9d?f-MmsTOb}=)fa#`3k>hgFlP; z7%3$=1TF9JP%plBaqNuV7vob@QmQ-{N&hbJx%|}i5GO>~5r8EQJ2#dT%YRS%d>pw! zHaIa6(U)C>?z1~Nx1aS)O*%CgA3tV$j#8=A#ZQp*%wpU5J>KKr=e;=fwP9~_h5<U8 zy&(#BR39S9nv)SRm1bs!T(nq%yk%ZNUL>2VxTfU`M@K~-{EpgMt@gC03p}MTogkL= zNz1o>%m;J3(+8*Tni$Tf^4A}D&jAcy<A3caA~7*UII%3-gO-V@{J*CJ3xzOcsINcn zG29_Uwh<43JP^{_hlRO(@q`4woV~olj%F>O8Ql1~%g^ae;8TJ4+Uz{$#sEQ#jZLuG z>7I`p_PH9RVu4m~N*8#(oT!F{kreXOfaamt{m!`2vQnzVUvo1SZ9906cM}OUpsKKR zv2TAV@8ANfaC85pLQYOf8}6BP^3@O)>t3yOHd=siBIwV%OaA)#?Z*V*H4JMjscwp? z#V(5=X1hGEHt<c7+>?}wi-}~vkLP^P9Xt(S1B@LXoHl6Cx>W9N*ZBYTimoGXNzx{S zhi}65A-nj7`=C8F#nBoQDkSx$qi7iNL%~9;JM4wz-%19(u5p@6ULUjwwbVlACnpc# zMjk%I`0B?~c$S;YM<_If5CP~#-Sp7rR9m8T7QtcX>Q2)HxCofiz1897nK-QeY;~xn z$_6iV8v&^MDM1W~^Z*rx6PSl@Upe2seg$=P#Ll9XMZKO^0`@ejY|`U{pmT@>?{_u! zpUF|B=M_y!e5F;4lQbFLYzGO(Hc3c$1E$5Sqf;W6Uh1%zOi*P0Ivv4Vua_^M>B7jY zR|Xg!c!?106jW5~l<J=`UO>9+AnNG6UTu5!vbMwY2G7y>ahpxfI1YwSgHn|Z!gtXc zaE7frTik~$b<oStxzy%j9@75!;_)u-dgn8w9lvJt(I*fLMyTwqDM!I5asA%P&~p`_ z3T0RR`2}MgT15qU%29(Jw*IsP80ho5_VtEFQRPw>WYmivLH7>EdUQJXz~$}xO4_H( zddYjBtqWaPE)<*G_A|vw9gEeRW+SM^U8*c<x<P~ztNcQ)et6HkkEb*#BV%V*{=7vi zH+&D^B!J2Kc}nMg1-N!{ZIh6YkfG)duDGAAo<mx}*xhaNeC#;6T73dA!;T&G^MM}V z6u1M`L(TQ{<EKxb?8ls9TW8%WcY8*ii|6Nbv)ydqg{o)pue_2CBIfUmEk1bPzHaJZ zWGW=IY3%N_jZXu;9e*Fs2~Or@gM|}EU=J5%UK%ZCZl1~WGq0!@)mp-Yaga4aRIvGY z8raMzgeYCi6>aS#ARX-@LM5P@4t!GL_>z1Q_-8o6#TDfI`FLCI$;7iqa9O*7bTkBx zG}P3Px;yDJuU4QnCyQ#=D~jQ^=44pb16mZzxGUL1Aza)KqRw)1{4TYNfGvOyTYv9Q zSJ%s)q>MVjOtJ9f=72it=#8FeY&!$I0pJiADKV%d3F_po2o01~2tMy>IzOBnrctCs zFI37jH0)ZmK}OyMZq+_kh~TrV%uFE>5%}rwq_v%<;$){%h2`(lzo}Xj$s{Fyw7WKZ zP85IE{)+A%!C0|XgOc8*31#zhB4)j#JDnFzjxf-fUMI@A7S5tC(K>n`{$ddh3G~d! zJOnAHQ9G=)$%yD^!xJY8j-H_*rDqT1F9N>`{>B1m8;crHh*6!yKb9Nq37Igsi-<TA z(-kPB9<g)@kZhaFVKeE-jQt$nzl`3|u#0a;5HHM%$zpvpLc?=>req{-WYk?4oS<IG z`uCQRPP0Diw!S8xwWcvy7?<?5TRBprv{N}h=;38F?})FRx*Q^0dbXMT+6W=9?oJr= z8a+UPGA>p`cvlf%I8#+I$>$bQQZJhJK$>GzP(-(H0sF4~kYasVSRDqapKiND@wD`~ z<oxVxk4K!Fu`CnQ7P3Sp9tJ)(C*e$~zB(B-^-1fv8j}s~KQ_d~*>U@wo$HM^2u_bP z?a$Ms)A>K+7h4_TXywBEa9jI`+!!xQCnd8uUn=FQM~j7q)<LOK(mQk{UReojL4p2^ zexpKOSq0e%s2&@cnV!y;B@a)PsD3SF87I5c9d8)WoUXgI^ia%)cPgc4QCLL8W|du? zfCt1)y_#1dwqdb*{d_)}?0s}UM3U6X!s3D!k{s*4)2M#NNY5%uXt`AP+Yi1N!4V$_ zesPe%^mBi6uP)t;1(R3MvwR3fV7^^7*kPBR;nkAb%2>Ip?7_l$)p_&VE9J{e#=zwT zB;4ts=@gK1UZ~HH!|u_~cD8x-vKCuFV37cS)M8<STeUn3<%Y13P+I8gN;vhn`S?)Z zP?-~g;HpcFH4S&1EV+0L``(TWjmzHQ96+q#odDmlsUemyzOnJTSG{F;l(U$hN}?RL z$I>g=eEoI;4yTj3b0`oui{!Gdl1?=+NLl{xXNimQCXBDI7XcHM?Y^@3?ac&Uc{L4X z8>SBtU02UsyP_av-^FVgLy7A$P#Zp|g=S=7RH{Vx2SC5crEs=qn#7-0SvPNqr}{9t ziNM(i5;TC+-#}T1vKxu<dkMz<m4NX<9-*oF<S>>pR0w!cC_GM|6$$qd{jmj{d20X< zLg3KZ)^e~NMPm#FK<w_5BM=6hAD<;FS0A1%Y;y1=9o<Ll;f*VWE1S8jn$OKW1Z5fb z<0k&O-xbLhujPstQ9v28-Q8-f*)68+IcS8K!&vl8t@5Ns0J>3HEh4>t`3w!{-RkT1 zD3p{LYs&}lC0e9}e3ZL(H<6-W<EpX_JVE-g-uWd4qhTO-`M8b;f5U<R{{a?dcED(x zVEMkS<HdC@4%!X38>ys(;IV*xTgw$>`}1pvYO<ajUFZ7ulf%aUk?>RfS?Le6$0GKF zgVJ65DW#~W`vLKMvFdT9Qora2UR(m|>Yac2z}_;$JrUv|r3ia9@;H;Ob*}M^_SCW$ zUf@{boBZ|TIDN+s-}f9mPY-Ht$D|K-#28vSVkQh6h;R}rMZcWcCzii&GgY-IraOK; zmbG>%Qy|*YV7a->T;kkGc)3t_N-^MFwVS*xwOE&_N2=xt3qb&G#lS($rNhyyj|(PO z&eH{?Y?p`jz1Qg{CjCcBWcd`umPdD>UnKXdKZK<T&H9<Ru|dVr+}yIN%(AN0S}`J2 zF@lEm?FpH>1KtEfgv6csaWQhEUt+iOBGDQ<$$Bn^$D;blA6C@Hmq>1J^T%ZtG7;*I z`f|a^==LwaAS!3#GTOu%4-_BD8i~wiN<GcI@@bRahv^iP2?^<>>ObFY$?pB+5ZSp9 zXq#qc(3;)r#BO=aY$BUeNahjZAo5zS2ZyQK$*JU<47qnhd}5HvydSEksTjr55c6t~ zEuM~V_3U?<RW968@6bI{%iWfTuIo2!(WAK7lv%Ax*iai1$?b@G?UyDN>s1*VI{HKO z_1jak%sFf`9s5f^F-O19Xg=FiuZ!S5-!B1B^}OK337{C_>xxv78q?I1R$_|RUJspO z;&iI5yPZBpJuKgZ_km);FrTA1TbSwWZp0ceVlrZ+^|F<Cu*35{>re!_@=%a<ud)P! zZjpyj319bk2Y0fc#HgCbn!`jsV6dp)LpQ`A<|L(eKyy0|C+-acMIepwFRr5051v;; zS8RJ$nr<i!D&)>0n_Bi`aG>KT71(DXW;B*{gG{(^+ijd)ImOKl%h<Bb3f{T=<MF>& z_{4THX)8*`R!ur98C_mWUziuMYkC+mRB@Y1h9b?pjy`=mODDC(NNM-FH;!T9;kSy+ zQH_<2lgnMTo6MQ)uY_ZiG@9Mq-&?CS&}==Gs_AoApZ=-U)gB+p96g!JR@*i;rnW>< z$a1>ECQkvSQI5vCs>2DWa?~$-{P9jy90_=)wOaHNXHsRX5Km$rF6*<Gc(soWsb!in zz-+`?)1D+`EDuaf%Q8<l>_+X1zs1~1bKg)2Sw1f~lf4cme|4taOhg23`A{zt5)GOC zHi4?Bf(@Ar;#;rZZt+mb%UUKTHk;A_PX$UR=V%+1H@ffhPK}CMx;ku*NYAj`Ta%f? zLe4{X-)uMC=4Jj`P#c;CiwI32uiB*x(bZAF+ZU;twrMxX&5qz68J;?nXo*O#q#s&q z9=z9{wwHj*)E~?=)Tvbv+t8{mn=qHUe)bIs>Ga;eb==S4Zb2B&W4@~GxRq63^c59< z4!-6a_^>j@>|xPW6cz$>4M%R(W}6L*8EP#3@7)Wr2RQ|@W5T@ogx9jE&>soV(#6eV z-d3bMnlDN#k-diM$ZpBw*q0dgo||sCre$R2XGoIRvCj1?ic$GIN8hcR?x897v`vM6 zmyha9U_=if>eShPw3hqi1ZA)FHO}dc8#C^Xyi<gX94@7sR-xX5AI)nzD7z}k^CNH3 zTZA7bcb2vhkSs7`FfsX>H)^_C7T7tvaG{zOrX6qJzV*44-V6^D$|zD@=iGJ4{bD>} zQmeDHpEZ1p5344vJ~nPG*2s3uu4fHff&uckOA<hjI?I>WqrLCZe$;v0Fg&c`;Boqg zN4H6wdz$nI!djGL&q^{B5#qd0J)+zXf?K!m@Y*Z3;2}+LFP@Ca{Whx(g1#sPL(Wx} z+i{WNt7sfOn{VY@A2BcocWQNgyqgHjt>7<7kK+wB?fa1YQ3`Z&7aXL~gQlLuYs*J@ zrxi5bduujl*Y_1BbdU#O{E6^t^F5zY_Q@PY?JF5OPDfh`nKjRO6ATPlvTU@UC6K{V z{tEd=R3E<Eeq;3?aIbQmnVrD`k#LnYx+|TDKo9uYSTNin3=e;KwB0mgfVVfr#C<p2 zTlE%lTVMEnW5OY;Jpblbm@e-?i{g(i0BYC1{!*0es^-|kBDs~A%L_}QM)`Cox>_&6 zy6rk0oh+>8_Z2=G8&j*?$&82LA&kT|Y1hmbPi9oM5PN2q1W&zmT~#fyQB{jLcl8XC z+}E$`{b7)DCR8Mhe2%f}NdIL=uDnLHI^E4l7>Q#f#=FU4rXPUT{h+fQ({HbMMmaB{ zlnq`9Z?JOKYKgpBV&CZI-V35)juWkBHM0hqBYPd=cIN3E^5vmO#H#)E6=_s54J;bH zgk1}gto-*8@88sEp`u3QC~zUSGHd$XDZpJepQWY?Vh`V<8sM#8i#x6n@uPdvH+`8B z<<!;TMF?|d&g{yrp7uvd%s6aR-LSD+sjB8b(|>((Ru;r-!wIg;<XTA)vYo%Wn#uN1 zC1@+M&tG44ID^5>&W@HSzDb{zle;dihjs6=o$ae(Rs07?-^TxA{D<tTo@Bq|c=D6H zzDGr?l_W{S@uS`N;dQV8o4mv0?BBwITXlk&xi)=vEs5*Bu?<}}q`&7T$_OV<%M)|d zAL$0B%m;U^x^mbb%=UwYJZF_iF=bF`eT^q%LY~&0<y*9EKfTLJ>~pr8G7VPdy6!PT zIql$)_lVW1fCR^WZ?z)gY#=G{)?2v%x6l`L4n8CUlrb9Hql;x!B+F%N!)`T%g!DUk z(R{oG$11O!q~>Mi9U=Bcq7DB`>U9t#Q`!;sJL9$5{+QV!9`(#_&lSr;m^9WCCT${K zARcq*%EaVcPwk;7xi?wq>S`^A<7!7Fhs0uZhU9D2N2rIa=URGlH0Xs(7^_3f?+5y1 zHJX__9&Lr55w`CvFdi4#)wS4rhX>B^7LYe)g`scSOu_PKN&m%ts7WSs`K$gO#o;s6 z@+W7X-bLJdIMH}~fE|XASt)MnH&#NPWy+LxmLb4YGo4#qZe!L2tAl(!Eyb9K&@}z6 zX9m?8Wgq%ph1JHMB1>_x!LGD3gRyl{{Oq2hj|uB#5xW;5a@on=L(GIm2yE(+3TtaI zg@kn?*K0_$k0t+rV-rtwP0gkj>sR;09Q)>~4@s_}KWzA*gx-~Ox>fC>Y<RL>m`zb& zdflA`KVKXii;$Y<3{MZT2pRO66ay~Xdqr4&^$iSl`e;^yZr{?0k@ShfGTCFh9Cw3R zwR}=IwEF|!BR#egTu$fqV0E3y0pg53yZ5=WJvZ&G&BN4Z(%{U5c@v}D#>`QCyi`h+ zn+@(hBs<IkD~S#9=<5#G@0N4vDVj!QMK8>ks_M&N@a_!Ub-uH<x+&i<1e>hPRxh%* z9U*zPDN(%8(~N^q6T+#;Jp4r_8GhbXr&li{yX!y1L{9$@eWMkXb5_7xF{{fmhx}>2 zJH&~L3fG)L)a7_cctsTDRQtf4Sx{_4<}uP;^0q&0ZwD;ZHc9Fj182h0!&<S#`i=ta z%#>R%<QVujol_r-W!{Zb}@C#C$b6+_b~^Gxd#J#oF066^UgdLbWT=v5dFrf>1! zR^D)-N}(T-a|t>Nn*di!)4Rp&{vLrF#%EPSo9!WiY~Qb$vcLLL?r7z2^iuM3NN+W( z97ju&RfoZg3EJ(JGC3akZP-R8@uW@WyD@s|4wcpHM4DxW74qsTsM3~(67Jcj+3SZI z=zV^8Vwq*3^#xIszw0<V<Xu(-dt5B%vb1C(9`PLe#$aQCtbG5r@|<7p;e^n9t0K8+ z)RWq#clwR&E~Tk_=_K(oWbIu~`o5o1+Mf(^eNW-j(qCF_GnFfLcX-~h5);`kO=t{` z+3Lx5&dKe}r~%5#js81=urm?2wQB7dyntuO%|J9oP~<X*(HLpctHaz?7Vpc7UEJ7h zHA{6g5=(ar{+vkE`HV>-v;TZ)011?z{y>XJoV`HNktIjCa(zfm9n7`|jO<OE-+E<+ z`wdQK)fc=BPp`tThlv)bvb4L6G9DA5n`*zzh+YvZj?FwTX^q--Dz;0j3=4K<%q1fe z7&QzkYNsXgr74<SDgPzNE1&;5Qm)eHSKIK%bVG)dQxEd0YaABgjxQtg6#9gD8xWa} z7&!Vj7|bzau663PdX+67E)7V!*`*S1%CVeJCrB>S=#w`TCDq}T!Uphxv7yPsSdM>~ ziF_DE)#zFL3~oqigjX>`|9E@FYyE?Lvk15ppMl+iw9NOsXwTc^g`5oN5@h`{Ev;1j zbHT>c`f1OKlFrQLV#G)CB8%KlB)Qx(zNt!ZxVh1&35fpix6^yEHV2Mi#*5-rlRB1U zv+7}g&na`#LeuLk0TJ00pX-u*uv^?s)2Xv7D}B2(zO^a}3vkHfW~OFhkW7Bs^3k?! z{cd6$X(N!$j4Ji5{E(EOwb#W~$>Tvt65@W?kVyv<_S(<gU@MHJy(?ijEUQ7qOJ)R2 zl{tyugei*Xc5P>c@Y=l7m3i1ywzai-%*!$>WoFjan!1oCp49x|x7J*AF;qAg1)K;( zD4iDflEcm_pfD>hFHn3HvRY8ibdh-6XJ{P1XwjD<+X76iyLOLXg$X_jZPnf1z5no` zs|z**coui@x(9Ep_51{{Ge%s6!Wx}Wx@cjWqOgCPV?Ge6?6sxMq=p9+DDWtJ69AE# zX?bM|duu#BO|v+&n(FfX`ev!4pDh9`t{Yiu*(C9xZ{b(89c6O?cxx<_#ANfYL5;)p zySMvLQ4bFe^mUS0n3)}%kMG%0qC`G2OdT9l{7VhIxRqPs7<`xC`thzffWQSb$AW@c zex)?aAV0s=-T`bVfd=^3ZA-AJa%9v)A_mLU*jSw^9aJ-x>}CK^gf3W-+YX>XN`=#& zD8i$wlf(d8mYKi=L536%usoV8Z6~KBGBbxFdgd)ylc3G>V?q@BPC#>3IdaldQr>tz zq){0I0yFWNPVy_DO@V+zgO)&{lI<zKFwo<ZMr&*7nVllb%LU5SV#C6sEvU1A6BPCZ z==83xSFEhe{QPl^wX_0lDV}mq`qpSXz9698nkKn%-B%-@4d9PkJPnZBVi4HeN5MsB zi=nyS+uyHRaUk<TGp5>oA_IHdb72;fB`Gl(fIclC7~STxcBzfv=Dmh=-Z|#l#AI9P zj^ti@`#$rt$Ij+2K9vMaKDR_v$}6WMhSCZ%hcuO`RF5)Mhsp#-zpqhIU*(h1S?8*| zD>Tr&{@GZ@jWU(~D$jbD`!kmLnC%g3i7j%8PPX6G_ekG7YBEUkimmU<-t_i90Ob+T z=ECjBSG9fc;6ajjjH0}{J+Qjd`)LmE;x%%5hj{MTl%kV}iir!cZ}hLFEc}ccJEMYb ze}hC69M;DjnJ5IK1Z;%R70knPW@aWyG?F?*5Cw0{9Xg7EgwBtyX-`rns=?m2uZ9h6 zZO{#<rMKRf3_8gL21bsgSRo^~1ML#%6!@$q90zku*;S`pTu04I`V<rdTy6_Hi_@H0 zX9t!+$|zo*AXdr9#I(OQ?zlISI@XcZAx_<9$um9~`cN*pGv*>&U@Nu@6~q99g6@5z z+l=Rr4G+y5_g4J<{BU^O0zo`XOY6idNB~d)0-o^-+wYnMG!HR;``nOyc_zpg5S{r- z7^tzjdb&_TG%(0c+eAf`!G;U{;oRpjXP`CVNEJFIM*{*u#lmvjF&g#p<XuV%30<xf z)$5q(APn?JL}<4NxSS-Vp3tu7^729(;1=>U{mxkO8B860ebow^zM+=TIw=tm30;a@ zN6ssR^bCa#Co`x)-t>%&TFuQ&qtv6L?Lq4GC{>Proiw7N-aLo<T^TE)Np5&}l??h4 zkSBmHoH5+a-6L%;)yKbueDM?{54k>GLHs~2K|i5^q#pZG#C_DL%$237v;7EkP$Y(X z^a<-|X>L|jR6>`kcDn*MxWTw|t2%}DWbzcw>D^FUR#parT!d&od`wIT<nOMzDSt=h z8;Rp6=7OQ2(c<!cne{#~s?f8*-U1zG=O)jlN#2C?ba`17SsCTJ;I`)G!05!}*7nxU zkji$m4XLM>YpOpBWBBlaE-!CFC&NUF)tGWwnx+uE@`{SDBNe#T4BNL~l!k_0bVTLi zIwm8_Z5O4=qh~NOHh%QFV;XyAPOo(g6nSWAb{wxm-z3Dj$wTV<!FN7laK^lN@xo2y z32H#j%g3kln)#4|k(UqiEOAl+acH*uhb`h#($d|%y@Z7L^5<#`c!QfWGxeeDle+Q0 zlR~iR#mv}B@C^>Kp>-vA_2>#HP==P3IYCLqcG=|SCz7HqDdi2H+Y+(dV;i25&z{9Y z<9T%L{JgxpuOllUH~j8|Q~N2p40`^D`Vzh6LlXO)uPADdYd_t?9Z^-6CviSrN8eO3 zsw7&)`8U06II@o~b2)Q(lpKU}9Tzd2@2!nXy;g0QNrqKe#_nXo97SfRWkSy3qb_SO z(5kRkG$~+OGmp7su-w<%7ka0q_1Y{`VPT}w5SrHqPwAdOWMn^RaMIl)<3-B#w7s`C zL!Rb)FYzNjRFF1#8vt#p2YvkjrEHIwE-O<}oB>h?uD_C|W{vypKq*<3X90pBHySPp zXLVA+M<<U}*BJO_d&8Lo1dEN>xDftQe-oL{S$36@<3Task@J1B1OX<-W`w(o8!V)+ zmC;X86O)MGbwJG_BQ0$~K@JY10cp^?C-Fa%KO^6Dx-cNqOXVdc%|&5G-+K#YpnE7w zqXaV@^D3g%z+~boPpoF!6f1XiPEt|hSjT3ptZZ6-kO<^96&)3OobY)Zf6i`wayqu& zb%17O(@o+a7|$CV8Y2x=Vs>qhD(~Kf0ciA(2oH!*ll-!OSry<~Y>ZQ#8PDe&$~UOP z=I1$FM#8;Jis(^C-S00gc4Zgmr^n#;_k15ud6O$FYy$KB1Fw#m9@#KbOxOSKiD`c2 zgN1|^rgG!-bh%v&Nu?mr9TFCX$6;wupCiSP)Q)<aqC=gN%XW)0Nz~G^t64_C<<k+U zo56flL8+o&^fNRymnRIs<+A(LX<z>cJt;>a!?$h6C%L1A8(vFMQQjmb2AY(bS{5kg z87VQy#CxVxRIL2$s&;YpfTjlC_3<|*<38haX)N*BoqVYt{|T*rgr5c0Cw!QQl0P?| z|EW^$=4kOcBzE0GS2yIPTTL$djgPgr38AfkjHKkkxce6n0vEFE8c+T_J3o&mRr-x{ z#qDSKk6Vk_sh}=l;(%Di`p@JPpuF-lKg<8pL}BCfqW#WGzSpk{=P@swL;0w#@Sskb ztG`OEI>c6%?jwCWcFe?F_)nT!|K<PGa<bq0pIXjeLVv@)h3n6l-eujpG;v-Ne)SFJ z`#)8k&sik#i&5MU>(XCIKPCM<+>ek#dS0CH3-RZ~KeoN{%{=qXY-}$IerWFG$N#lQ zNZ*3~3viD9uL{$JXIw7XDU0`7V(-a<4A}U`emse^^(BjmUFfW;Dlb0_SNL<-<l=Kv zEcIN%Rn>LGD;jBv@m9sVQ_&Y3JfMpA*E~G$U!Kg5w+Wt2kR~KFWlm4m{`bHRqq`fj z4}{9u|J@MMfq;YrpAaqfKf1)k>#jN(De1q#4SdW&cL%=m@IPZ#!S3Wle*4bOzcZ*| zb8%vPyyo=p=WKuc81LH4|1kD9@&cbF_%z@C6?#Sbksj}n9G?(4|KPysv=~&pcwsR^ zz6YQ00|Ad?LPkab!@Iwf4<v_nxU{VD!-Z?(6>gi|ifn9bAdU~4@;l~}lD!@j5#@G% zF)W_uy3BR`Wgf#~)_;$wcEw5+@A-|OytC8(%WuC?ay_MDq9S6X)H#)3CjWo|S(o+t z`~UecCYOs`uQlcZleE0N{nSj?erVQ#_OUs1`2taMpr!3C4Xg9<F>!O-^^fsvZ&_i| zD9z1teD(ClXRn+MBY3qoN=L^W&8D68zA}hc+MS2f1e(wy5U>4=pmfL8x`qQE+8RIP z^70+nn>P;$(IV{b{iRZ(Aw?j+Uv_kK1LfsD-T?Gk65>slb5T)Isn8$4H@D-betzHX zd~DD<SyZ%*+4X#zrrI<HGOk8SE%rPn1`4kn90tZtIU;aCO9aTDtJAB=DJc&y3G&U) zLC|tUj_}{(Ef{dQ$;rNVHx2sw^;<%M&bM(Na37sI`})q@m8;HmMq46>B6ZiZ9>-T6 z+edTSQnC>lb_E`y)UH#Ile?C!K^;+AXTLkz&S}5@o_G+6xT(@A$W{3HiB=sLtqw`Z zFE4KDb%ej--P+nR?$4OF=w)`<Zb)h$kBm~xQ0hwJbLSpA<1xE8lxuBVhvPPat7Bwz zHr5>?8gXbnZnZp}>)5)l?oud6`7rz3<!Myri1cr**^B8E{mrA(+vzRILP$s$Dyo2( zpJ&lY9w=5oK^$6FV(UD&>Tw9zAKk=~w6eUaEb*f9Lk|KfOdmdw`sTHvS%DX#-D6bh zG?Fk=4-KCPkBsW{A)5=`b*A)m3{E-%4+(QUJ(<sUPR*-LigR*c8X9u_96c`5*Vji4 zD38*w0}5u(K2Yv?>!oJzZWEMR?dDZfs1P2x4u_gnuiM#g-$gDTHu<j`Zc2_n+s0N> z8sdHS;C95es#7@#@!;&y=g}7H<SJ}!-9{5)D18KOU!NQ^bovA5FG3Mp?9SI}3q6Fl z1VjO`+^%S6w3MKy;Rynv)>e7plxV1%KDR*>34V@^@+PMu(^O;3e5)=i$O|3MVANmy zf9-u`Sd?$uCngpmpdcV1prWLb(jpB40#Z`a($WnUQUZd~F?4t5prmwzLrQmd46`T3 z|9SS^clXQget3`Lox?Bc)P2u&U1$A*l)X_}R#9<!ZBy0zFZwHn0QOFg+b~ceVHTa9 zo__Jdx-xy=fJ~pUq0yPqGQw-u04UF|fi~=32dUvvvmtQ!#5-C&0(imF(v5?XG7g6A z-NyLD=F#oVRZCmTJtLQn#wvfrLx=a_(@n~)G85W`uPVYwbQ==83K1^Ks;YF{)lXK8 z?&1GA310j4P3(9(9uaJk$US=&&SPQp1MLKx3jBnn{n}Jr_tsia^0*YdPvx{Rs>bg& z{qsNj1O|3-jJi5Z&DW)*h)LnJ>Kn7Ou!Z#WYgSq4H8b%qV~pEhVFHc~BlS&mLD#$K zOK10lk+ETNax#9v(_7lp@Vix1@c1_y7Y&H8y(+DU9dV^6q~oTMrwUjt*>`rO+-UEq z%|L2&{fAX%)O?Z`2ZzCm<)VXw!>Lm>58g}!1t~y6Bq;Ru!W%LAb>exqt%2L*GH&}l zDtS<%H{0)@O}e8mTz6PeaRdC(cCL&jOrAEN2@yEu0rV+$Q@yn~y{WhBHKLdA($ZeO zasMGVjgM!vkO=Ho=N#v)P91E>^bOi0DXx))g$F+tT3gHY8FB1)@-zpW#MkeSQVaIz z4Ap8f&gkiZeA?)h3+^0d8ZHK%d7vEw?*TY;+#OtHq_%~PjY59F-_zInqyrmHW|m*< zDVG=7lumC)%<uI|UEJNf1Rg&meDq)Y4MGcpq@Gz%W>;ad)t*WV;d|Y>Gd%}^)%;1Q z?u!@p^P6iY(AaPeJfTW$Z*9&kwhCp_F;h`d*{wOaeY=h&sr~%*2W3#a3fPCn#&-Jt zO!p=6_V(L+wZg5perbi0kC=GQ%><JP2{~;L-#OfcrA21brWSb5hWZ8*^aRKdaZxq3 zJW-NY0!GgG&u@Y?%cB#o9`2pl^YU5)dt_=4e=e8l)A{RJS~%zf9B*HrBddm$CpZBC z{=Gdtpj5<4`{Lu<ibHc%H%Mho?gjcG@g4~=EL~|IOYstlyKMSgRyI{|;SbpJC3Wzd z02QT%jyGL2*PAuCHSR4`i(%DjYvngM@SuTr1kYDc$o#kG(|7z0Kd+^`AQUnz=KS4L zSn4qlyTrPZuxE}>*G()C8E$dgU)?)=?AnlZbQb>2{sAxVHTPe-6CK?a4<j9{Miv)P zh?=qQm!+c~Ahp6qD%JT_53X&LB_-XVre699YQ4FgrY4Wo)pceN2NC2|HV5_Qs>L7A z-&o=9!PNMVn$Lw*WnO2tpDp(p#jM6pah9U;-bscyztA(R-2c3@u&{tJc2~dsLN}&r zWwjUK+=1+scGNLi8Od6xdfxAt3+u5Zl21uWYN-;J&<S_VVQjFoti8|W8sduG;%@AA zX3@bwDf(*>zblU0^}aA)+YT|~Gd^_y)$>D)dLC8`*&y5s9D4`y*1MLti)^1`3HA8- zrlqDbXlzDHuJDCqYwRxk)KF=KvnT?IarhR&B0O&E6w?8vtkaII`VMM-JMBtL!|Yh< z-Cwu%b#!a>(E5f9hi6^f1P!i-$0*Yz5wJpsxi52ZaW$|vvbt2*>Zz+oLEPDSfv_<~ zs-f2oa0nh{LPkr0-bh{vmqC`;EYw$aaKj;c-s>(Ko3MiWhPIbKx1G7~bw0=CNOyrz z-sUgB9CpB6I|dDv%aW%V=c1b6w!MPt8?X--Pfsyfachid9{9N()bz{B2B>#AibmXb z4fIeQZSQmI>V0FK230!ffema{t>jrTd(DdLzAr%svN7c5<__-m?y%^~=(=JL<aXx1 zA;_T5e1|;9i^+*`F+TgcXyIQM+fY3O{()?F*uxtId7Z7@+L2^bo%vNsx=i6sZEc|H zLK*k|{X>xarl7!7U0ybo^no48OYQ3bNuR3Rb9yI9p<Ij3Tnp2v7ri~vm4j8NRgg1N zo$PJ^EYPwlo<9Y1b}U2B!y9MLxRY{ZgG7I~<mlzsB2XUzqhW==q@kkHaY=5bp~KG? z(wVw?;fA_~BBxfY4%>gN)ch92LEo&bP8e9y++}3kFV0l;oQ+p7Cc6<CQi&-F3p;~% zZEY{JACwBdO{{x*ssyh$n@7Omg$NH`AI2p;&OxNZ=D2$xPrA*=XSRb}DlO&AeAfG_ zuA^-U8?>CpW>{L<+G1nwV^#xB?NGeOha$h?Xv4SI99y%(IjeK-UTPzpa-rM?WApx_ zJM)91ef4Hj^Lj0!ii+$2Ife3!k?4y$(sFFEv?{ET?_a4>(vSLVw{zugD~qM_zD9lj zo?5N0=0HvZ{9^n7uiQCM?IBx?x)r#8Fs9|Sy$p5=+Hd(+`^{D;UD^AJK=cZZEe4P% zk&U7!G=B2){n!yT_$uaG<@w)0(~Ymyi0DBkM%bnaR6#mIpKP`ATdJLXT~n;g?60b4 zJ11CsdRIOSF)}g+lZAwYAoxs+{EHEBadK+TEl6}Zh%)?58(sJ2`~w5W>m-TT%g7ki z1AKjlhfo(8S{NY21L4MLu4ymnTMlY*Z)1eK!~7Ful#9D#A1EA3cA|JJ!gF&|W8x0i zgDyf9)YaQLyg$fDwQsTnnr5678IHvaE_K?uccdb@hWK9}cWNZ}tY-Q$GA>PPN07bu zRg~Sbu+c0WpWxg`en8~3J}Ij?s-?y|QsLh1_44}*gqQh~F$)LiL5TVtZQZ4+*fNG+ z!mYl5bASJ=v+EeJY(it{s2AqrJ*3U|rW!su*?EeA_i4V3CJMy`QO{&_&FPq&edgn( z8>}zHoVAC(kHz~(J#>am_d#&&+q(`IY}*Hdxj_LL$qnk8edU+8rKhI!s!Y*y6TJv@ zj$yos?9!^%3HduxN>87b5Lg<oAfxcT5@Z{ixSp!0+@_>7gZ<NT^?NW^uovg1>vz%# zn&#%_(NZU4_;<O~%@D*<M?c4lto^oO)vCjyQmq#7@B<;F8$2)XiYJQtlL4Pgyj=|V z!A}Rx<@4X^!bL;6e=|-HTUw*i)$qVC6Nl6^k>%or3(!J4d-*!mRmB^ewyS+hq&Npc z>_TC=YYm7h4P4~FEaCUvOIvO_hq`2B!;6b8f})psd>y-*Ub&oLz^P6er8inuDoZ@* zO$mw`#J$01`PC`M-`!mSqNvmMlD+ZRIA7K>TspU{sS`f&x2wi;$*FU8X(+Q3_9u>O zmj>FbV6ntoL2}|afpQR6I+i%Oxctf4wmqZ-D6&;RN@`cwy~=d3+8J63Bt%3E_+F7W zBI~r*tcn?C*6hLdHLv)eyqgZMHDY5r=7eC;(OUD&LjRYb5SP6@4mb`>aV@u79F(#( zpXV*MLNm=J$GOnAkO8l;vC+`bFrEEJYg+6(kDY}%OAp6`wovw&@kA>Jhf<;1-U*kr zxet?*2{wq#5w{mRB@fJ>T<0%c(gLxLZ1w!;8ri|sRw79Inc3Lf%;zMiAO+mF9##S& z6+|}X*6cwx*;3RUnMhi0x>uXK@eN1MA(N4o?rYlN*Ulx8$;G`+{LrF$Qc!f;ZMX9P zx4K5rb=9J~O{LOON*2$p&Z8N!_TiL(H>dV-jSh}eb6~=K1YD`x{$9gLfxYi|@wybP zh=X8N3jbE9a>mmOwR7#!Go&b!DL4{bD)i6bW$ta(`1fVJe6E$R1Y}V@^^K{|H2!=V z`Qw!0*hYV`0NH|0G&0eATrW(zf9>FxD+PPWD{qmQf!<ySWPzOEx|R#!5qnIF!e#v% zOgWOJ!cYypl?es9P)0%99W%JjoBuwO!G+EKliknRwJP(2J#>&Hb3O~7@)4!gVcl7+ zM~{AjSP8#Md7$UM1CCn7%Q<M-W~=OsMR9W|W$xBCH6;ZZ_jgZZ9sZo4Q({8y9L2$p zg~W__fMXsG-DtU6f1`XupnM=9Lm1}fA)nPNAn5mJX&yPFX%Z7}(~V%nq?b_$C14&x zR9)c1%ucr&<9Lk!t<u&aZ@XT&aAAQ@rCmE0dFVLYHtg0CRr#q^znO2!atr*a-yt!M zJ0oN@ha$WCmyDkazPo&wkWsO@(awIKt)MHnzW$CH<4Qamo$LOds3t;-PY~_-a>*dw zZuuy_B*7kT1jJ_Jo~DS4BNkR$Kh`(=1x8(lll{vxeTS`9Wa9^W7H^&}ck@@tEw`Vm zKIMk43X90JOUm|lgX44knoqmt!+iVBJdLv-aN6}g%npAVjMcIuVhD4inN*a-+g{;# zH8RA3OMzbaY(ux=?w+x?Yegq%Y~)aKqy)QBze*)9pX5kF{^Cyhy%kEND&|nHS9B#T zLe)8c%)=?xZp6XvD5{)e)Xh97E{=+KB{_Ah)hJaJOXCqP;@XzFHmZUBIRpi(vXXS2 zH~r70q->O6)P%+R?Ta{zwsw3C#RmrUbv~cEeGB<dCY&R=1Rh>M9sfwqwtVQ`o%t*- zBZJ4<6X9DpJc2IQ#kN}+jE(}N!3~8rIO|4TF>Lul%R8p3u1AIu?N2dQGpgzNu})fc zEAAt=<9<f;5AEBZ{&?w$gmgy6RVJ0PoJ4t$>XM1#V|QB~1RdK38NLV?g8P=%ii-8f zQ{|p_sac|06{9%}#=`Px21`6Z(kdb#c8yzdnq`CeZ$0}AES|<ho9ndk<l8HA;2ieL z%Qri%si(Mn<6(*2LN+(Jjd*(>jUFCzG(A4Je+df0@0??yff<XIzR}35Q}%>DiRtM? zYr9%nS_06R?V9qTrK>ZoihLdL#-Ke4X~P}r+0`X)YDyM50T+57695ZWXWhEWd@yfm zXBg}Y;1@je){+YUTvHg4FRPRA32G63?{oYX^LO#Uxd!CyKVD~_KdfWHk?HB^xbg7C zcO_DOA1^PeIEE^d{fV977STCkL&;!9dIq}NanSMrFB($Pa+(0VC&lN4tGzD>sP21v zZf@G&t`nB+48Zr&?O*1fnwpxseRizWDp^k+apxn#`luSU@J-1JSWnbdH?u1$K6*Yc zvsEWkC-kvlS~LR+_}0(#o$AM-q%`s>_p;KmGP2WkvOF!8>Zdw#u22n>9{6h(A2#+* zfCmWyZ~~yoLCR8CJKUN-_H^j5d#4JW2eUX3KTb@%XklXkLR|}dnhb<KUMb)awINd# z>_U5cu87|)Gd&$*wZ+_U!?%&OeP22p8S|bupqQc8@yMLer`NGTBB2YI2a>k}ySf59 za>}=DrN41xD?K|0PPjsHqpN9%!fIL4`6ZfkQz(<o4ovM9I8x?JjSN5CKj?tYFWdfG z)_o0*`Ig=H%G2dmN8@3yUq1rr3b<`<2U0*$q{~cA4Gsx0cjUzJrQn$Rs_FE&W*J{r zTDmAIvogCq2fWhsJr*v$G`v!@*{a<Zh?Zapuhf(pEW>jS3fm<lAsJs@ZoJfgF{Di@ z{Go3{cY9-_8T!vQ(#RnA$<`00RD+c}{89fUvGR!fm9@34r8VOuQHDlgQnmqxg8d9z z_&)H?Lm66_)VKysa1M5EP*OqDFF>rsWu`A7;WSD#@%HVOi@@7-aM-I&u%8AnfRu#9 z7by=zpUFuf)B=3XZ>Ky8rZP5&+CIW{47szkjE+E;+$`+Vbtbw`q1VA~CM&r?&sNBh z@uF38WF$SRCI>?4VccU>vMaJCGt=bKrAsh2V<x4~9mC}3$lkniC4fXUQ<fI$S!m>t zT)SWY<9jWP0l`;}mX?in73Nec4C-SnJxpBthO=k`V&5XQ%ixW`%qlItSA1%MKpW1_ zIm7{ef!60mYKY9_GMG|y$Ko|Oe+C9Q7g2jAQ!y}8GU4+77!V6eJ%J3f=^0lI^b?!; zz+sw<tEauCr#dGjwzO35@nf~_B*dVSkoC-RD_+gXqC@kA&op>4RMaqU5Mp|8PErDa zqXW!%GkuH0+A5z5H57ai4Lx0jG|9Jw8+f4EV-6LAaD&i?VcbOa@9ph68ef8g@dKdl z7NEqFb#MqXDSXx)3j)~MT4pE-+NPEk9vT|SZFNr>Pt%g^v=mQGC8dT6Mmo9&4;~m> zJH}rI*&Ms&ky}(w+zpCcMF}NhMIACX?{cuRnxO|^zyXy30cMXFt_pbmnTYj_ST{3* zLeo#IJ&p$Jr1Vb+&z&~9u~k&teU8O`y4As|E#piJp0IFT=#RTbS|!NWipbZQ&iT4k zT_4#;m||C<k_L@&1%;p%WBu+&!e@jXM`YyVSDxh$pIklZX#cC3AJgFJ>wBan|EV<0 z0m3aD629b=?US)EhSPMd%u0*`3DtcqFfxK;+`=MYQ3f@moqIGW?=>}f6m>5qrlSut z0QC3FtTg-!bR^_o*oSuWr;<Ba)kSvN=UO}Z`u1!ml0f5W)njL6q}<ee=Etk^Eml%t zJUZ52L*bAc!6}Uj3p-lkhzJknghcb@4|UvPq|1JZ41#^3oPwR1JFVjD)OR*}h9HT4 z*KIA(%Utvn+Z@NVZ`HRNx3IHfdPd~#TS{q`Z!T|idMqq|7;?lXwixR|H4-GVIhm>M z!_R;@YPxOa!sEnUPVYKX+46A{M?jO6NMz$(PNM2)nSOR966spQq51F!cWGIfFOIX$ zz!w$czD!zEo8?P|dvAt)B@3?<En33N+lXXnw%!S=aC8C>vrt@43HuEMij;QDBLfNb z>5D8Q2AIW240Q~U31sC(b#)EjNBVkto?fiks*6@cE#5Sl;7A`XTub(PK1=wTsH0}* z7b<F2yqe;}gNth<rVWGlaf5=R2fF3}LZPBUeCEtv=45PM9t$)sOfwKmd)3;x8JQ+v zO7xs|^h<nv{$gQNri;F!{$RW5@o2EGUSqqjuU`5VKC{)A_f!GF!R%IQ8XD0kx5~LW z@HT^drUm>yIeG^D>$Ew!OYh#h=d!UBqLiia(c8PHr{hpY)&X~$({=oNEHyTqX<+bo z`?hWTNl16LZT;Xo!SMaiabgCx#pSJSW3;7if}EkPZBph^RoxA;Xd8W7=_DblF^er| z@=POAy;NLWCR)=5@3OGebPY);2Ib{Jg&`5ojN(M$dkGaC_yhfSjz8ZVYKI$pn`>~k zSK1ti$jP1bAADumSLN2tSDfuBCgY!;9&d;FRtfjirEn}Cx<Xr9IM0dSKiQVD-GS*N zo6{S)R90%1%CSD-cV`_*Nk|GUmu@KdxtHphsBJ>BsN}Ye1mSmRQhzp5UG5HMBk^{0 zR5N8*+T46*<Zx?dQWvb2Qd4-i>js*p`EL)C*u+Fe4nbbbd804{W6M!Xe-MbH#IAab zZEzT_9~8>G6iB#V7Sv|K1Ru;oS5x~#h+WKHjhw|e6*abhQmTOUoGM!1=1b8bt8Du5 zcDw(Ja#uzSDLsq46-rf9bY|u4QF1%WQw0Un+qk_V&~hEvYBsMbt?jLA9cs~Di`#)T z!hFO?|6*Wp$<Erj8*FVYE!yh|hFOeez#6_u#jeWvaw18Vx}l&l8VJ3iVd3r3oTELp zE$QYM6w3^P+btZ0yv4^?lx@Hdc^u(%FtkjIQ7Y%*09;?U<Woit3^dh42z@t|Ub(*= zB9Z9ezzOc5@Z1j{M5sUblk^mAy<>)2Kbl+vUJXrnIJ!GG8}(?LXc1Xx%lZP8$cK8^ zSc@iPAo%yZD)IxP1|Prv=0iwo;RT@6-f=*~L3#Cp`B24vTbv$rC|Oz95F9(L*H+wW z4Yf#jXUeRnDpFJT2F)2jxqg0P{-|+Y28|YBrInYZJXdNLL43Z5eY-g%GjJ&iIG@I* zdJ~g9U?Mx&>b^2NKi}9!OUGoDW2LQl`FN$=eIfKS+@Igh(i#TOIM+F!-@*?L4lZIo z2k8PBrOvdvbaz!ZrJK7|P1`Q&NAg)wz1p<bq;Ml3$cH)Eh<Zh2<6?pJ5@Z{iZhK2V z1xDaL9Jx}1<!%^hKj<Y9%Zz^QseKZB!O%xU(4ua=7gD9vmJtz#kCUQ!V~@4!u$%b{ z3Ulq|h7Gne&R`7Zr9NL)W4EaO0+@^AW%Nu#gV2^=cWtnFzod+%Sb4vl0kRLsJD|qI z3xNJ$o-<)QEGkiGSKQz=Qu{e;p`SE;gskaz&5IT{X6IJ(dfCVgMnkH-CJG?s0JxBC z|I*0dvs!ec8GhaMh&x85kcVUao<CZ%92ZZ+b<JLP@30S~n^z&D(K_1k9HvLx<uMqj zkQ<ILrm>n|qg}X@q{0fV8xLq{X+cyG=1WE6nCuAS;jwt^vzrt=#?uwh`^A{<MWaHK zwrFPA(sOctrsE*mA~y7)_x>j4aA>dFpp93x-SR*>r?j;0u++Ry@>cQ@Us7^|siPw( zRep%sx;RsXMwMmH&(D*;_gEUP`s@iM*wK%pL1;Avp%xotsM;bA2D@w0mt@gMo8~+_ zC6nFxa=@OQ!rlQ1I5yg+lo`9r4LJD*Eu;hw1#aPwAgwl9P@gk3r3E?OW?Mev>`rQV zCNE!QGgDtDX`r`&ZMSqJfA?w|6t>~vjv^uh^)XD~p)yGBAPDCwL^m^tpPH_C03~qX znB3O%*k)(gp79%<X?Jp}JD?E1wdHYnB_#2DoBG4d`1FI$G#eOGLY?U4OhU=62NLKP zrz?4#e|#5~oaTqc2Lf{MXwzuv_;;0|`NGC96=7bL0Z#S7*g$hb&&^N}Rc<Z!Yq~~6 zMs7kD<U_<@yiFol^Z4qupgYo`)l-(xJaZemQM>5W+f~T#x;~pNc%c6zB0fG|RarS_ z%U_ekET*P}$T1nw|2oE(f0;WcqA|BfxF%K^><(d!I(ih<BFf-92}i2$XqKDPSRfPM zL0Lh8^#Y<Q16>kk<CFQxCMGXW!uj!H2q~XwrH*C`9JuNa-8#K@lpt9K>RS#bth;A> zu&3+h*v3T}w96uThwr2F{w~ZuLxRi`Sq5dlS8~H#j-Xx&THa=|58V2r`B(VQB?fz> z1MN0YZbMZqEIiZ&vm}#O+#r1eJXoGezRL+RS8OnxkRd1>V!&d0t@onGK7<=<_6bk4 ztJauRbTK;cnF6MUpyUKrjOr@!e7kOZt+oYNMTBT(TUlFcU{Lj2n%Pc!&w84F{O-M* z7WiMoI#hzFl;>VxQnZd7_UO-0?OpD6)4<Q?lMIeO)UWZ6jkRl!#*|CGJNeoS>o=&N z3=vVB<-vc6z)J|4W)xgK=4b;_GO{T1VPt2a!(FVGMDS+Q6mF$9bi2~urHb&Kz!C!H zI5-qryWYxcN21`d2~NXcu!XKTdraO#PlRNFc0$>S-zo@Yx2GRC%n{GYm+XTbZ1arZ ziAPSUSy}sAI|zO02vCr;PyI4Jt^*@q;X#BW%5Zye@PT<-gr;+mfVfvwP}JVUbPQm7 zH2V}_T0Y!MY5gIUrQXiwTnB^AyEBgLeYR?h{+_#s)d`dDvo2%DMEwE^R3zA<D2@RM zF;*32`EdZ7^GZoe<GT6cBeQClXIff%psUmiKj^aBSvbS9u(HqoQoW8Lbr6=9<%vE5 z+m0Yq6AV_Hesz1UbXIVhOGR)E!sIWlY#toR$$0-!$-o*2sR;j|2os{vq@-yOyjKwl zkf8=^aVms}Py^33FCmyR!I&1eT9ESw8`xsMfByqEyse?EprF-W9<J}lC)zsk&+l!I zH5IC$!cGcA+|dP@z{<Vpz$V%U2+dt)J&ovqfHfeo%6A9S(a~{dU9;D^;YX5>5^a!u zW^y!^cYF!(h+4cBbuF<)(e>)uPm$GL(r-$7*rZ6ZhcCpq*$vERz;*nkzEM_M9BtOs zV#z4b*aV_?ov<*Iihff9@!lB+NW%|hGIusezzN=JwL{~$vIg_h+HpTA+uxsng~ijK z9_mfY#MIu@mQz%uhcEN1<T3TS%e6muJWrXN?BQmiizh4g$;-F;=;ts$KMt~Em|M(o z>hr)Lhnlm}IV?m;R`$38_A~p39$b2~ak3I5L0z`$iXoGN5OpOWF>xydfqgF*b^g4? z68<OXe!$(evDwttjt1c9{@&%CS345Y(pSzk0cH~HJfKT0CB*<BE?nH~u0VK<hnUF9 z%NwT@Yp!M*Lu_d2;o+K2U8H7UShCQ$<9D5JAkhx-w%XZ%rXR|MH!(xQt=*&M@4*SQ zmLsXG++p2k_e14JIEm(YYh`5oAswd=5c7PA>I#CM80-P)K_HPeL0^6VKy+@@JO&_i z0Bz}hpK%Ef=f-_q7y(eebAgdOs3}8Zb<iAX{Nlw+6BDkNF?KM1fkO%GGVapRMe!Jx zrKYN=Ie(01<hc2wWmPM_Vt*TCgc@6(0F3zr^~uWp%N<Yqud{ZPClrKw1~aOxL2n(2 z^z(#Lv%%LvC)DjV^k@KBAZ=DeAJ`<3i)ddRs}TWw-_@&=fKX#X6?YIS$NU*-X5*G( z9IFc#LM~po_?F!yub`l)py2XAj+b(VasQxc7mj~&`=Wf?6E7Ird--`)fW1ha<V>6n zRaB%S!STQr97LY#({0%AGmXYoM!k!9{PbC^jJP;6JNwkDXx?oN0RgS~$uOHO8weKV zj_APl4lQ~@N!#G8tY{%xGz?>LsmV|Kk<2VEI<BrFp`%Yi99B}kWjf#u&wxz?u$1;_ z?%qLEFRC$7_Jk<5fedc8Pe}XHkHW%~lvj(P9G<gZzwyHU^rs>}M4I}TxJTuGZXPv| zR;#p?J^u7BVTEjk@afzZ>z**Vd3_}4ISaLs){Y>|QQSt0ZgX<xYSEF9gabOKskt49 z%sZ{B{cxLSN6kMi%EQN%@0gj6?tuY!XGtyrsRq-Z4e+)3p#9<|<n!S+bnn;!l#=7+ zdEvsvz6{lS_~*HA7D;OxEPM)#6a%+0Vt^{x7G1{kukrfcRUKY42BzVaNktz#=NA^B z#e17Oy{v41tmZ&ybGGvog*nF4^WtMI_ovDMfq^e$M$--HTAuTyKBK*=So;grDkLn* zP9GB+s{*6OfPgze64~li^fWZ0LI4O7cX2T_HLW2>k~=4s?4q{i;M-@zc<PQ8AYw^K zBk*ORRF#tQ6{0e9)C}cRYe{>=SM^j@wzJ>h$Gg?1NgtAB1E7)-vR>Hst@9a?S5hK6 zcbW-R`FGbdGvz6Lp(hm<T8j3drKg9<S2)KEgZ|(;q<DE`O<<oIRv8zn-~`D47*R5z zB7>8Hk*-Yo@~^-$FFe@9eC2yW9N?F|y?sE8AG&k8Y&^MX^Qi7wP!Pv!^zQBLZKnIq zVJfCf`9cC8v<UiodrhC+WM@qCPd|Wt13ND=7&4aNA-R^vW0-|kAtNrZ^a~4ZE^XpO zAKc<2Z@;;NxCZb@FzCq0h=aSNs3;+n=W$9=(c4Q*Mdi$IekNScOHrm0(^9cpYDeGV zwsG78zC?a1<(=?7|2fRG8Gu-KsPxrG;2>*J1z+QgMVJU&u5h-pwe=HXH5|7_;X%_f zD+}y&zg3voA5KLWyFa@5BiA@R(Y-J%%mETVzN*#PwRf3_xTGXLgTA+M+OBeP+OV^8 z1H9Zzr>sc#X(*4U{Kt<DltvxR>^-`CsgJFp=bs8)wOnEU{3g)L%ZudU3s2Yv&HO^` zBW;w7e0LUI&us+PX@i$sLtEP#tQle9!z1)rkpBS1dMf4z>@JN(&y!<gDVefAg<eI3 zUc~_L=FA46p|N2|aF9f5T~9!2YS`Pj@!ScI(BdL?TO2-<qm1h6lhlILDAgJb5rtlb zyv9HF5Lj4b^9oM@NNZygR9FZNvaQusZ$DQO=M7rCy}iqJmX;2ivu_FuO>Jy?n~UQT z6I&;UPmfk8KC2BOd-CKXAV-~dR{>_0_f+{<8V>sQsc9*fZp^ltr1S_3?Qa$q=9XJe zIVUPFE>Ei{sNaSOycj+H+yd$B>@2fCy-7+z!u!lxTU*P<*5(In4~mQJXwfqcZ>a*r zB;|e58wj2qR<VL60WKhnaJIJneSN#S`nHMZF{@+f%ax43?=2Qq80PSFr8LNuy6(=N z03eXSsmi^>lQOtW<T8kcZipP?8yC;wY{Iyg$9eNn`4ca|6+`&N!L6?q*<rp9!@IQX zY<}DED?Z8qcU{{db)eprfUI4z=!f?wr($O2?s}L@+O<W%^mC2C1C+zO?k;}gW%C<2 zbTEf;7im;r2*PP^{tT3kR{9M0A3VUp#r^DZ6>%j(^Am^D_DNBX5geI&OiW;<z(h?w zfyyV`-Sa!=X3x*MXx5;9jQc!(JQDm3O^tPca3KW664Dt(%dQ&6xx0}a@g)e=vX*t} zatwME&f=;QZVS&8dbtW*f4}rKyQ47Ctn548ZaBT|K{9q`%yB7?^{-n67T0Kcgm<90 zgtVB1^z8gURwY06D!rkX{`)<!9{Iojmk)_G{$FJ)$gKYNK-7Q9PCcUeH>;Ch@K|2N zGukD9(f)pT0!Y@L4Ak{*lK#mAvQN5aUB<%VQd3tqg+EH7f4<1;zfLT$Z&dz3YvDa! zOaGfq%Kzop^Lng=-Ldt<WC{Q;KL)r`Qc}KLCE~TePDn)5?Y>5@TDHDEwISYkUj6!C ze9t4%*|VuBkhQ3nyQ<v6w-uU#Rt`&Yd(h{Qi|0#WVFRFF1p8z6)BXy~PYqGlKk*l9 zm1_ZB7sfKZci^YIF_-4|T?A*AUs+t-5Qfljh62hvnChy6J?@&XuTNIWl>#TLKQ|03 zo8>n=YmAeM+{2%OzqG3V>!6)^UteE=`Bc1!uhZ&J4O{8pMKJ*ZWU5yww1tl|hD%Pw zzNFk1p>B`N4V0)L;OTiYsFvmB$t}*XIPd1j0*V&OzsFi<HUc1yLcoJzElPRt!s#i! zDLtVC7`2z_3ahBhO^SB|q#n|BAjO<Gq4NQkbgH+ws;Ed>U%yO<iV}>(PXMC^GNUD@ z#MP$pS3N>hvj6;q9mHh<v}pweLczXe_IqmFeHm$ST=pFugLd!g#@z@`K-Y+C`rc;` z0Jlc6S-D!bbi-f;*a0B%x)rz&AUUe_b&{{W6C)KaXy7!sM88Qks5+)$=o&2CcUFG1 z+L|7#MY**VD0@PuyG!mpRcsn<L#98rs+Y^uK;7={buS@i*ss8131LJ?ihbPJT$NLp z($!7ElatM+_`9-yZgt`i&hk<R;rsL=74m|Djw^?>#FJ)b(O^XaBd22@L1nlLy}jtp zc<h#BnRqJDFZG;-3BM0fWpY*)<CSw26=#PkT&Vdd{XD&Wd_I2s2tcM*rtdn^rN;rf z#M7Y?C~WidwEB0RIX}+G%{4sG_^Y+_H9d(mAr6wpckCv#cj=Y$&GZiX)YKJ(g`mUK zQuK7&_Oi~&(HDG<hm&Jlq)PTYr{M6IYUb0u3>25#$s;L`^QWg;e3~R4;N7E3KX>{h zxzcF6L8yN*|3<*uw~zG|%NDQ3u3}8>rn<`g-@J(}D)M`SJb}>sfmHfud8W<5@{I9~ z0K_NMkf`OsU>~}=Yt<JB2)ZA;p1?~?OkPG6M|qwU^-a&r)N2wF7XIMj(Ig#E6g!aK z&j_NrO(PJ%*%;#g(;z6Re(BF@{z{h(*Ls<Jz-eiJ%Fo`J9IvikWNV2V0zWLyJm?UW zg@XfMW_kloshtN@d5;AJ<JaBv`RC>=R5l}p-wF%6mz51c?mnIA<)vb1DBi6NSlbKU z-VJ^f+9Lx4KMDtL|2@en(k9EeUe9p5ObcOyWaC{pW^ELD7sD>@mpCeisyf=+w}!IQ z&~Ve;X7lnqCSOdfi(H~e%pPs7t~MGc?N(FUFVGl6uRetsBIEB0_DN7Y-21G5eVf_n zdB)$E)!Es(G%>GbzS2V(^80>XeNdc)g+)jwE+p^_v`1;@&gRE)Ju@|30v8nsK+8}! z(0a&IUV;1$W-6fjcI-RmxcmJCBK8Q*l4E-rU!PK!8Igr+^$iV8&5cl?&GObN-Mm|6 zJ7K9U=iIFgJ}rQvTO}U{YF}u0Fg`iCzNua}rP8@S_j$GH1@ZMT8=Fg5*=*!8RXI5^ z>G6O5YxdIci+`Z?SeuvrPiOa^m;6I*fWQC0Jb(W)_Qe0skC^ObEhyvqki}|MU-3FX z2Yw53D6ss~%gf3{6hStDiZV`55)co;U%p(edQ>PPQlD?oCL<-8m62hx@(B}xtCZE+ z)OPh;lj=Pk6W#T;xSeJ9k-37D7|P3{Qn&DJesMRB?^%>UZ2BpC<iFy?Q?#tC47mu; zi(F-(KJoF@d<jwj;MPW<4V<{*;^(z3+8dcR|JLCnS-%|(;GN2H&2k=@Pk(d(#J0sl zBeG{zC3$%%p6xS4^)$6-u{CXS>>%B&(v1RSaKD*aR$7`-$hp58!106GeLADovLFFc z4s6pO1=HOMWE>pcvfr6Lef|t7KNDkCFqyU8hBdTmk3mwZfNN9ZUG|a}^%T?480j}C ziGTO`%iUX(0Oxannf>?5K}W|S$THD~3rX|yX>fhudzE^ZZg7xWQBlGD{gAhxL(?-o z9UTtc9DnFJ$5b3{NByi#*cDm3OP79$n5U<Hz^_#wu=48V7NrFR?>(QV%1cT*0mDc{ z<PJ3ds}l*6?NpSN_v{Z0!JM9GQdo%RWo6xKyf>9jJCt#~>3vbWZnS)SiZUS!OH0Nk zy0k$O_@D6shLD<>>9Tk9=RkWMok`l_4eVKse6vKPKz0mH1XmdYv<j$<4ywz>j!r;# z#-JVJGCrvVzSNKnw-N&AI4~#*c3q!`|FZuLyp+sLK_TFf0Sn7<{g(ED-zYR}{fJov zq@*f4y-rY{0y<iIBzNh`*Q~Prvahle&$H$K(<(UKkjJrX$crH9PVz0XU1K`{Qa?4v z^r==@Y&`#g{siOn(PC3^Y3XNApN4{MpQ+RmjB2DKd9<}nxMDD$*tf4AuPAs_w3U6! zNHIu|Gh$5d^0T(KuJqW2u1JAJwgpUxX=p+SlKm0@)ZSUT;l|`(;E;bCdZ_?4@tlRI zMQ-MT<3t=39GsGF2*j-S@0A0TH(BS!ogb?~p%_ol9)(dA5O||9ON58Vr?>uu(C2oL zglZa03jUWewwIM$NvU{fXc6*!d|Aq>NAiMJk1*dd3zUI&Bri`LAf}t&WxF!0p{`!H zxI&J&Vr*hE5KR6jg?inu#vyjBCkhMl*;C~l{oy9Rlqy6&77$^*JnOW9+N@b&o#jgd z9W#KGO#vIy9H<C;ht>L$?9Q*Fl<DOZWhsxr8$d2|zetpvbjLtHiRKo&MwF<KTxt)@ zy?^`=5*1ZK7<|>vg<0~#{QUDYSnSy;C7#Ew6VlR(`D?Rtme8WnGtVczYMfXnqUN~s z;QoEcN*{D^yqv54yMIXL|EH)ZKq~w|rsK0jBD6L0<PL|{^Ga3dgKyyV_G2QFwDivx z1_)8X^fu<W@^e?vY(IL3jWcZbLMh%jlG*SBtp@=aSy(^-V~_+5@<AcaSZ=t>aJ{yv zAyn!v(1QnBKte)o$?kRFSpv*p=IlRJBhI!rm;FoghN;+D1kEhS@fCgn&HXe;WxkIv zmowwZ8j9yWqh(`e)gOV`1vm~D6*nI@YtBM-Q@nC|1tNEyHgI7%=wq_7%(S&_mk&n) z9v3K&f9)Cq!9h<uzA!(Vi)xR?df8Q7#_1{>tHq>)QdP-SRQ=MV5f&bP?=CGlx9hC< zWIRw}6cl>dHJE=dNvw)#$nfSj!wAUGKP&pCrl%l>cEnwqu-M||sc<B|&fFlZEejmv z?|5$r2^E3BcuLgYz}CWunp$uIvSF@=59elQ%QkK06{fBd5wX$VB=mtFJ2FZQmNy_O z&f=~+m_?-;Ho{a1a#WmOFpIM|Bm;{=ng4-u320KDV&MR>gv8Xk-U+Cay8`ix@FVW^ zHT2eujHE6p;r#i^+4*Llyyq=}A`y}uY4_??IHwM|l0VTkvU>-!T|riyoGKIb6%QQN zKV~ep93EB_DM2g3`M`Gd(>LVBX@>R9)iUcn=(^d~oCL}cWF5>L`H>tunZQ;U#VOqz z;({SHl!>)eeIE_24$&eb=a6!mnxh5Ezd4gY$kA`t_&NL2nRmCzO7)|RCuE5cyiRZ8 z1y^8AH!Cqg4G_g*{Km`6(B58oFq`Dh*VZujQx=ly*s26deF*0@7I^&F1i+!{Bv-9j zj;9D(0{@<Qe=C~G&I18w5IP398tf+E^lUkt4Ph+aI`OLoe*DJSa7;Sho1Z6f<*Siu zZMk;ss*m>tXo`r7OU=*6#6$pd{`cqGy8sKZqwa4V_PQUth~aPc_+L3C_<KReiOqUh zavadoW_W9}$M68m2GM5Ceqa4smm8Z+QwFpX%DMhh9$(KK*K-j6ASV9?C;hrj6&bL$ zU_ohge31Gs^7k0Aw!5HC_H`o@41Qk1Yy&5v&$&zjibu<ZQ`naP;w7)Bc<*jYmF3oB zSv<tCroe|w+ZMK#0U=7?+uAN6Z8DDo<<KzC(o&SAWgbBL-Vc=%9NllJuQ&Vtf`Wm; zRKQ_xiTj(E_?quLSb0a2qhYX`o|+zVm1y{UX;64LeL5{AWtLmj8%s+|U<SaPP$E(8 z7+$-%L8fJ}a5G5a@$#_YJxe;th&QLsF3ed#?;6@I6z@GAG=O0QAUI+42(!#a@$*0^ z0@#<~l)WTTvwptE9=5W|K#nq0ua1C04-Yq@a$LUs=cNB?EU6(S2uxCYKR}>C**4K2 zv%JE#IzDB!r0TFT;&S?=02tgXo{MPR-kc@cV+AcoPOgWz<gA+j;iKF!gHy@TaT_4# zps#V@d!Hk}<kg&-uI_sX=<s7uBSge*1!`1Yii%W&fhLn?B_uV8F!M34KkUf)1Z4?` z0=|Cz0H)JVTt(|^Dpy{g5QIbl3X6!kK+<WBb#YxGfb?W*e1K*j0D#?n4D$0?pbqvD zs)j}x6$!6VB!D1ciW(n}*tWG@((9mO;^&~Fi`OcIi4l-h5JG%qt`iahT1WRWuiw5s zgz_5L_{81QVqO3N2noHuGW%n2Xowlm2Z<AzYK!+VSd1Y%J986&Jvct&Y)av1gB+v1 zQupQi8d(^~{j-)H8O%b}5FH@lRX0D$&c@0L%t~hFt^~O`=;BXJPI`K_D%#puj26z| z>RWcecMPe>A8P92Ixaxd($lgu%4?r!c6IgvG5GxXT&mnz!=BH(?;q-qJQeh(s-7Si z4@GIfd<q+9bK273iH7)ZNrfN@_iAr=nhy2nlvy!_YYG6-0-$wMOViD`{27d^-P(Fm z01+V}kg^Pt2H;l(SpdkM3=Qvr@B<f@qernRO!}yfk;ay#JXA(=_H;z)v9VzxA@bju zZpKkJ9Dzj=HI)sU@65kKND+jPrmilomo-UmtKYJLV~=Hbu7#|N+VH6B#xStx3krHb zfq`m#-U2Rsy5;#@x}=1Jgw#C~%P?hn?e(X}y6zDHVaQiw<2^l-EiIexYo|lf=3Xw? zm+U~Fxx0HRPnrIVy8(x=GUX?Q+kn%wvGEcURSK!o2BP=_aHB}ub9T+|%|n?O&=8R; zX{w5PH1xK&HQu3ei59RB$NOv!cCayOH+QSHm!~+I7B2l<ee@0|>pBfPQs+aiZ}zP- z7inI5$(p@C`37IuFqMiOja!ypmQ}WpCYP8bF?cu8=yMwFwe#*GZvrnCFk77Oc}VzU z8vi5Hb!x`?%M*+u;tbgI=JwR{Go2>WEgXopa`apTXFN+r`+XCqgIuyfO>hx|urjy2 zJYVH(xJ`Y$!K}JZeTsA4|BO&a4q@UcFsrVIvOTr6_R`XAJ-~1s5~6zWfG-+kj@8Sz z)B9azgR;aEgUwxC7k>WyN-;X{xpL8$w+gwjH>2rlyy)Y}qHyQ4!$u~rBpq${+<Y*b zF-L)!GupR5NvacsKTAs!<KrvyHzvRS{JN~<dOzJo#^KRoR=YQYOro9Z%v4+3XWmMK z0e_4Yx{L<1gCcS;E_2Ep)%lUnYv8&!-=1!4Bp=jlw>03gIg3p}=HkZw`x^RAy?Q$m zJ&M`pvq=%6>Kt`TO-s}N_V$csR!=|MNQHyW=D<tn0^j-ULqx;B#OJcQa)4Q#UIEqy zH7-9hE6<lk-SrI$@=Eq_7lwPZZMw{wl@4ah)#Kw`0Omwbe0QpHK=(RqOe-k$J}FPi z)td64Amdy=itSd9DsHGxTAs{;HU{WwH#gJenG-RpeL>$IX5F&!t#mQiq4;69-s9EI zsQzSn#-JbjEF-LY$VT-?r)f5n*m>D&_Ak`{Bi7&!3yrk%VZVzTpY!gp!l+U7)OYxK zzD90gC8Sg>qPx*f8PmIKZZ0}UhbzcK2|+=5g|hv*<Y?7m+nNB}%Lc~H^9l@1mAjQq zO+A6tanrrV^=AIy`0HY_*ayvt=+T10tfJVIlwEkuAabd0XviI|Qh2XxWo2NvqXWu@ z-5>Gk8|z3;9v;@E@PGh1w%)?qb%}b3Q>sOaCB|Lh^L?2SQOPo<j@yHCQwmd4*9ME0 zOI!{Z-RiCNCM68TQF%?zw8jDr5U5DC$d;^~&1hm`Vppxfw!E(OL`gc$A4OJm-etsn z2G?yjk}_4<%|W~yI!!6r#y3dF!~eP5$QV0KsV7gYT?SO1%k@<lN$E_)UnF;&trWzT zLC<_%OeSKAX1aU#rTUJpl~pr@Ii%gTpPvR4&aiff7@lv|PAr5g6}KSxF-vGCj}K?z zJOp73=#e&5`5RR6S#CAe?$!<zl1AG*yJ!iF#n!Aua}M&Fo~m@=rAsqb<uG}|AW6Z! zJ+^MGU}x9gn@-(r1{MGt>+5-<16$kC40rFURb^$yBIhRjwud5z7C5qGxCK_^Fb0jf zmO6thI9pOgjL{VEASGSk?q}iTL=6uIJr5q~7*JFie05Y^dJ21_^mD0I_7?GnCGLJz z^~yLK7ghO*rf=WgRFOG5X=^*PQ?vLIY{Ks!$~_&Vn1Ed7{TivLrpA2#)!xF$al>24 z9?SLDRQ4+d``&Rj@%pCRug<?f!mmv0t=KQohSLGR^dHVq{c6i!5&DIYyy<!M_$?k? t`R^CPZNU2PoAci*=QzdwufIDmXC_U0QZqJkV~*FgxUjTP*5em%{|Ap`|6>3E literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/add-prometheus.png b/documentation/operators/src/images/grafana/add-prometheus.png new file mode 100644 index 0000000000000000000000000000000000000000..c25dae3b6902b1cb0ce46e33f4d7ce2626a5e9ae GIT binary patch literal 5785 zcmbtY2T&91zF!p-jevmkb_h+n5;_Eq5SoC9lmMZqG^I*!22{F$$e~Fv^dcffN+<y$ zAWeF&0TGZ6(g_53d+wdN@6Ee!-n^NY`6ip$-RxKP`~O<hgZrA)*VwKB06?v+g?I=6 z7tO%mFR3nq-_=rUGvMKpr>eFQ6&2Ogoc<30U^37~+%@w1ut9XNFhb5;`F)<(ef_qV zt^J>OAKXwkxXS=(rI&u=66+LaXHzGXpXxk3tT$zw;9TB@kn&k?Gv$?$Vltw73%&hE zL&~dHsgIA9Buegbao#Yv+;WOm@prF1{NUM_%1rWiRg4)Q%K-bA>(0+n1dshq@4^7! zt9OSg0Q^v}<pF@_oaHwFpoYeb3IHr3L@5BEM2!g?`52KO;;%IG3f(?&?&G3T<3VcY z+DzY=<dH>I%U3YVDJam#cc5N8nstx*R&Ch_{+na$lm8s1swlbfteHSKMk1{VW66!g z5>5|q&kUGTV@`-6KAjQ(G7XB#%PK47L=<5wKWp_+qtwgXn+wZ(<IC<&LDPHW3W+VE zHv)R_n8m(#oia^!eX{EGYg#Em<fa0{fK5*O>0V2lzbEs?WYCXjeZv0QuX9qt?D~Yi zUn`z_+fNBvXXZ4&$+>-E{o>4+D^75S>3oaej;IVG;-bD7PE^n?b2qy7j2`t6l<v3) z;Fo&etgpzpjkhvUU0?PGrz6oPj*to%9v>+h-I{S<PKYDy?Ck}7C2#`(d7n6Ssv4`I zhQRswAo!TH_b#8VxrrAhBlXgyT#hTvX3u}`?<Bb$EYt1n{53YQGc%LD`sq8;I=HE| zbuovwalGc)h6=KtYt-%Qa=cB{(}(M`0<C8oX>Kakq%+jqT!=&8i}LbMKZ%TP^aF!q z)^a{%s;Q25ni1zGMZug3J8R7(ecz2$hc8b&IhmsQb*#;B4qFEf)}{}vtz})Eol!x2 z0I)o~$pe8;!wc@Grl(|}kOhB0i%lwgh^rr_ow4_2!Kt-q9$42rm*It>Purx`A`s<< zYQ-j=N7a|q)hUB>1(+Ebb1ey&cz3w0tfuHTPxe4g`-V!{lE+SKO!uB8{-;g0W}0rk zxjHr7$Z*HRG=KJy3;Q5!P{xfk@#wbKA#IuImoV3~9(yFSEcX84$`ZG8>}>xiH&`JG zV))UU=Cx$&bqzDK6~T;#K369xwu*^v*T4Y3q(r8QDgIXV>n%0-T84P5QU_m5k9|&O zhijUy276n0WW7>DzHX}WW3nx@yrRPM`SVIYpS*jmxXhuo^^Fabb^ONf>RGfrda|3O zubh;SaN44O-qTStgW<UZ0KS#NkYI~lwE5)7Wj!@BGi{qQY5o-C37J$`5a))hn6NNJ zd5+mTIW8=TlY@>r&H`86JsI}{;2C`m)nTfS=g)>5?sF*yeQRmi&11F>^zUSs5GA!Y zq|<=Ysy4CY6_b$Y>Ff~~6T`8DBD~hWxy^HD$Sn-a@iYWTd^q1DK?ovA`@Sv*N1Zt~ z?J>01mzyq+Oiw@}welX)4}5(U@&RkPS@<L<s3at0zFr=35*~hvKIXvLKFtW4!mY<r zad$6m>j@-i4E1BS!2&I)bhPqA5;kY&7x*l8emY%LR$2K;GA<&x=oMQZY<PIki=*vQ z!DsESA$>RB3TA)$^!-xA0sOFAXLEBiDoW7Y`i_K(uM;_3C?SJI{)sO6AokJ~#0`VV z{USx*R>JWPN;S(fUliQo%E5okQvxr0L!0UjK=g1wy3GDB;3&yE3ESj>eZaT=wz$N? zjw<p7q2TLxQHQLCeoe_e%f>)`k;BX2sbf(G9`;b`kyJ*c%*T5PdY6ln@E{sIl4dIJ zhudCe50#Hdc^@0Fc6b%M86#?&<yp-F{Zv!l<UH)VGCHOA=t;+p2-rP<eHkXYP<#1C z{3of@$Z3jvay`2O+&%&Xw`XR41+USLi4B?^?^y4G<G`}dNc<<F@jxyBFW0!b6&MjW z=XoLzZfa5Bn(l*zY{+^~x@~9#gQ)#=7Yi<JCS2*IXw36DF<PHpx@qUtM_~%1Q+Jw2 zk}aNPcNpXkqZ15MEDG@F3>N^PGUB8`qi$TkM!37^4pr3h+6RTarr{%pvUk<O-A>7I zhMr=49Pq#lG&u4a?!%<8=+jXB6QViVDu1{u@i-tv$e_f4P4|k(aBM{K<+@&1Wg76Q z3J<0#Za0UGNl``JD#=X8(g~P6qhG|($7ZbzATL?+TKKsra{|Dhiq8U>N~nC?jvbzO zt7ThwnwRioBWeZmOaeb<&*6l-LWq+u6pH*eCsG3Ts8*M)Kw8?byaTaOqM&a&M-Bh> zstS*!A*TjQCS@UPoC8u5BVSPX+~InS!+tr{;!`edJWh_KwvxC2{P>8o&l=l^Pkvay zn|-X3fr&5NLnNAdpFkLWO~55yHg$PXpxTT_=bg~UZudUX<G$rm0;Pi=uIm)g>+ex- zEX~gsJ-F4Iu875o@n&B*Z3zk77Z(y*<z@=vS#kE*QIFT6XMhi)_*@?p8J6bq30gZl z&rOqHJUm$-in7a=(=+JDuu13RgEP&G72J28T3LysKI>;RhFqcbW>P>RkyyBIUFIJW ze0+P`?KV-%iz%};0n+<N+c}7Z1-=(gCUv9Y-1K6}N87XCzu!wM>h&pin=R`>jaJw} zd2N*74F?-jdI)$R1uZ+*;;+^Gk41`sGVz=@0l;+PN0VAMRMUB)uCcy8CK3VN{uX7J zH#n@5B3?#0DJOB=cYYSvKGCac*sSPt`Knlfn~`nIo}=UR<VZ?Ff<R1$D3i|kDb$TF zqi+_6HZ-3!W@b)V(eD-(ks#t+hE`yLSJahuI(}ruitW){)zgxze>SABC7wM|k>1^{ zYt3*-*o&#$j?*u%s^ZVi%(S|5C#Nq%r9wI=L{!9PHE{(RFQ+KtIV*vWyd}OF0du%d z<gh$?v@$ZxsfhcO_<j7UAxrqPk^qQGd_{$h^ZLy~DQ{w*3csMB9*c_hEiczBC2$`z z6iOLqeZ(p{WNGm+MSb&J66J$w=M~0Ma(&e+4`Ez=80(%NH;;|5C&_gt9_RZ~vpx}( zfp&d=*C{#dXbhq%yS&+@W6iRYD)WsfhN~kZ#%y|O=Vx;xBS{7N8J|CW>i+&+Y4@b? zcVtuSA*m!!8${Y`>czUr1O5H)l9CEX91RT<NEcrf6|vJ%v+XUX!U}B5uh-Tq$djJ9 zZpQZa-wqkb9B_=(DmGd1l2xI4zVGO0Vq&kZKGB(QwO1Vcl=K+8%{jO;DZsAtCfMCd z+8-;?MxGyGADRW162t&tS_R}m|E>TTnx$T|j}L}jXUeUL8oZfHW5=`%9jjsuTSDws zY3-_*qT#{Cm`JFF-<KKLgopW+^%sriy|tji5)zP=ku;)7k+J=5Pf}<DKJwnZX!hu& z#G4R`iw+LVVcE%%Qkb+H$<!Ey(;g!jOAO*$F9h%B-;RiT^OmiNtGud0L|C+JoK=0J zXYQksFqEE(;#w=*h#;T6GuYfrrrgc=-qR%{+R^vD*E#Dp_*O)~!S+~cA*v~Ps^lR$ z-qo8l;<P?#8Ro{p?ZtPKE3kS)NFj`g^P9)6Jr5?9%e$v5-z*B*SFrqDBJS=6^E4q% zkG^Eqt~}dpQ0TIi+?c?(j8zvAg8xK(<5i1LZ*6xoDoi{abpQarKP%09CcTTqxEyVm zK)hiq2vEL=w^1{%^YlTfN1xz*Hj?AxeJbuoxfy$pVC{rOMEK}4+EiMfa2IPBT3e5O zH$)<h0|El_3JOmBH3%3sc{=G{#VHfZoDn&>nd98I__Qndrlnm=OJek!YhdfkI7e?A z_FbW%u)+(t*tuN*zB*1~!aVc}+s2RH%s~b}{c3FFoNGog{%Uniag6B^L(%oapa1xJ z7ZfV5Ucpbv_^t6Ti@lP_lH9#D**}Cm5CIyPw4y+x;mE{99f5>J(lS<D(3(Th=e2pB z@U3p<XntPJxAHIif_-qh#U>2#1na{$Z#<IBy-P=QbaXg4I6x?ngbm?+_8Fr1ladw@ z3%uJ{Id@0Z=J=gA<*r0BCkMyk$Vl<JFbE5VQ)7ikS|&p*9t?=LzRG6b>33byOrDig zc`o%*T!}!ax7}L389{SuZf@@3z^aaYa+vNiFpzUhOXUV)+(U88#t*~CG!FLpQ{&^; zxuk6UY<1C=#Lk5F@f42L)tf2eRxBz(4}*ecn$%7<tLjt@0@ugmv(%s`hqNi3l7oY} zGc!;qxL-)8&OgiM3{(Xj)UnXH@wt3iMG&y(nj+DsZc~g>^Rm!7++zwl$}5yz<rwtx zJkHHCI3efh@l)Nh{<D!k$J$iJZVtCHn%1C_pYN@25~t|ja@M-@7R84A%~`aERY5#y zF0t<8L!HWv3!~C)rrX8Uq8JEhAzsq>5}ZhFjJGNh!}DI1(7)P1#OEL$1(sRpA-+J{ zsgTNaNsckxosMP65&)o7$@R7FAj(58+kye)-)(v=Kb%MiG3pjbS7oX_;xoe@`*&<2 zW`jYg4NR_Iu;q!?`*vl74eV#+Q5N*SIhI~kCXAj2wEW9FLwqVrdP75%;@@&YohcnV zAml;Xgk$;W_QRGOrDe{Dfw!3m#?+uf5Hjs(K5j;UqGam~lE|MT3>gwBo)rT76Den` zt0Cfa43h-*ScQL6`5d5!`~Q&rC^BA@4_?Op6}A;mAO9~+v*!CxnbQr4>c}lZE^tV) zd*hUtQH@SRVLpEoIBVA~xIn<>*HGI3(O&&ijQk(mSVdXTV?*%^^YzV4Q#+Q$L+ooX zM@Hkpn!4#(Q7*=7Sh$iB%ahO3A|kK^Gw~EqVsaAcfR}IGQ$*LN?`k1%FOa2Wtvz;G z5fKsh@?_HVOg58}?!?4KL|g%lpWK@Gn3kgNjdF7qUNzkUT2-iInjSW269V*Koc=fI z^uLbQH)X50vgs}3g^AY5;1Uu4A7bamN5?*CGW%N~hbskISq1f;g%Gszf=xHpyJjq! zDwfcDo!5%6bij|&lHG2I{<)yvfL!0(O-f3yt?ikexWI@|tD4_|&D*>s;;wF@XhE>P zH4h;GfZ6}C6vlD5_mi1T3PY<*E~wAPL>{aY&kj%`OTAXlw+H=;O{NAKK-CYKl!fS{ zS?kZ9dS`~pR>nOr$u&Fk?A&{LD5Pc?^>oOcbYLirkP41ze|;z2jcio!oZm6jdLJ|N zdked0=K-HmUC$}0(5#Dwuj_o;XJ_~nmp3entLOb9@KJ;ioZ0f%76eK7sfmbg^A~4Z zB8{WW6hdk(+ebdU+=SO1`%KmNi?N3yY;UvRTxM@F$~S}9k)1u=-tODBSKIJfjU~Jm zdTP_sCg&Z3iA-*&RV^KJu+43~|6cWag5UACUQ1MuJ&djvU)z^<64#jZSR?0dfVB4- zF4o)o+TR{1?d;q7TuU}5#p}<`W@KC}Wf+N5(h+z`sPiFcDEPl$vr9c5I+6@_n>n{y z74WG(d9Gu&8XL|m=zDc%vBJ*TC6(W>j$B6ANhr2EgU+P%9ZgP1BBbW%QtV*rtYMfw zT+(9lGh}bVx6rHXsC0#C>1y4>72M8G;Zvug=*Z>jF7MJ}aY+_M0jj8uS%M;6UY?~( z9qdG7w2yt%$S4s)L9^Ako0Wo0*=HYfj+(szI^XQDJ}D;1_2s!)_;cbhcd3PTs@&u6 zyde=_c{Q9)b<IF%R;$oUzledpp$996lOkQ?JLjfH&cnaoTL%*x>^Fqd;aga{t=bx| zGupySpaKWy8ZcM4I<|Way2}3JwoA=aw#05#fTw$&xPmUrpx!&<&-_sK@WxprNfU>O z)V1H$grK3XIT9p|^p$_5T4j=Kol-k>1r3vk4gR}ayIP6D6UhmZ!{<a)ldE-dVbsT5 z^FCLvn}UKobVA1WqBW&4;fKn8sDhy{40x-i1`v?llpG~fgUBn237v@;488L62U=Pg zxzS6PY1yE3C*-BHzK5l`Hw+Bi@Ah#u9UL5}3eNq0JWym3oZz*sM3-ktI5@3#3RhMj zSBI*NvIqiyE)8y)-9oZWP#4eS!roT~!04oxyAif-zE0T8H4^o@M!>7^$cudSBJ$LY zRtN2IBWc|Tghm3%Bl$Q=%a=WT98O}aJJ=*QJS<E^@OjaXj*Xd#KDx~UjZpVp`z5i% zbcJHCf7O+E_w(mZw^MZywo<H&-q*4c-bIqhb!k1noPzI5!C*sR17EDl%g67RGSG`8 z2kXbQ6XWAvD^SP2rVD_VIc--3Oh)E<d}`#n3oBF-RoDG&wah7_I4L7T6M+sm6cfYm z-_w53XEk8JOUprSeI)hb=xk}<+gqEtkH5fzP3{jU^k+OONi6m)k0gpL7Ri%c<E^r= zxG1&xP#VS!y3S;{=$6rS8XsHPV@ib^2Ck|1b6||fHQv`8tl^Ozqv5PK7v5WDqu(>! zk=@cTaGzVy9-1ajPrz|F9L%Ac^X9geo{Qeot)O1jC5c9|-&P|Q)a0S6OL&?0*6$o_ zY=#Q-tq=N?8&1y9$Ii+b)~1R2h;%M1_0}-3Ei&2#1rhfztDR6&1DOngroY1az6C^0 zZ?J|lz1{DY7~}66MpTmCznIV+P^|dI3^R^LhrwSQiO43(jH%icKYq$x@R#H1z=A@T zp-_=2L-i`wPDJHwxodYRcx<JTZZ3qMes)9!T`=@)B0|T;rT~P;(D3m672?=aN!;}0 z;zDkD`HH?+z-9^>@62KkihbjeB+#BaRZZ?{I|%Ay+Qx6ItA~NBd%VwHw$osD&#u8( z<0{Z!s3dB3)OxVv`zsP(GpX&#);Mn9DwP_w{OGUOk@j(3-0=R|8uRnHUxS87%xUoH zSfH>KDeVviLm)la*sMFt8mH^oxnI=3m>gzp3D?;1t0$A|OB>Jj-t5sr>yiaxXB(gW z3>CU#z$+nWt>iDvqYz-!RlMR=r%yO~H1k2d!oC}p8iULY2CM!n*Bcc6o&gHx_>DzS z@Uek=6Bvn^m>TtOwp;?1V_3eF216o3>^WSvxVpLLzxdUUb;y>-aQg1UoZ3yJPfkzk z#yoBE7e&2#B|6srHnCnY5sN`!c=@O1-G5}2-sIEf*sD8W1K9(NCYXPPfg!@br<|MO zW>1HOKM%#x3^%j%*xJAEJ@2Co|8fUK<^Tnq?DV4ipzyN~$nhtrpaM&lzK_O6+VdDi z;gqg_kSs=|U;cfkXv(~S74V}3|H2oHHNfbJ%nX2pZyx?%veW-Fx&Je2{r}!xcYcZL XO?zUMz=K^-asb-u_Yozkk6!-=QJxTX literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/id-1860.png b/documentation/operators/src/images/grafana/id-1860.png new file mode 100644 index 0000000000000000000000000000000000000000..3c277642b5b5577d53f48e9695973c3d93118bf3 GIT binary patch literal 8454 zcmd6NWk6JI6y`+~krXNEQjk`<8v$X+p;J;?7(!Y>#Gykv2Bf=(29?gCYbYg#aOln* zzuh0Z`)hyhpP74Zp7*`yJkRr<bD^5*N`!dScmMzpswgXH1HipB%(fx!J<Kmj6lpr< z4;vz<0>;I~MgG=U0RTooML`z)Ap^Z=XQHD|1MH(%W#pbP{^eFR`G~Lhcn4@`d?@mM z;t!w*-mdV|R?>2$D>sfHeL(V<i)R7%1s>klA>i%v*vzxeZe_ztJ+cX@I~c>C{w9<J zYU4)&WS5XBQjHs6`utdKAaZ;hixIQ233)4~gv<2#8+`!;V=8a`znhoYN3n@;9)2S+ zyw6gG{Dlxf!TQo<*U4L9>;3n^jHjWrR00;8N<vS(Ud<P`Kx(^c-4;&``TZS}Q&Q6y zu5L6`@k?#(J6<_)pXNa)o)Ww!^%V1{>hQh5$*j0N7{=kkHEMn5lPM>Uor}3`N^1Qj z+oxM;1_o=S5c+KI=0@(_=Qh(`UJ_`HxcmNO?9Wati`#{diufT?TeI^MTRUnN<Fl`_ zl9Hx}XR}xPKvsH^d)w7;Dx{Ow<up%5q@O2VW)Dt-SJvr4)aX;O)tR<pbE!V*H;C_7 zcHJ|$1@O6|b&b29pE~dDsm;a;zLlTeOjH@BC%;Ssw=3j6B;NBoU=H;kV(0iaxUMxu zQaNrO2yK_rebn%bL+pD|<7UL^_wMPeH9<iRj_)NU+Yw&J=%-@VpJg=Z>bMwpoL{T< z9)kSNH>DEa+~mnSXcSiRe^OcP`QX;{+|Y3ND0n<YY&trNMEnYmLv(n2B{{obL~rIL z7pm1^OQxNy0G?`->=u6K&PVzy#B{EQ&V-H5+94foVX=7>5a*EvgQeeIx=ItXNc7-_ z{wgbr{P;ljK9+-nK;iBPRjMm|Z`PoXosm=Rsk91fGM#u}V_?XAS+$d_^<AOZoDu)y z^V<qZ<b&Yt+ue|!m~=848bPl}eH$CazIGUlRSM^$I$g{8?Mh{CE)6B6X$L!q5X7so zmwr&q#k#ZqGogcic6EJ=`w3LY)mYrA@9UoL$shu;Sa(v`+G>J%ot+OgZl64nczbP4 zNI1Ns^}B=N2E>{`a{tws<M!y!&MlA2n}=to46~i9x~JX@Yoc!l64;0z5<P8p7#`<N z_qz9kL22ar63MII$;<Amud91<^RolteIufn(brcRe%Ri&*w)%gcudI8XTEn~qjcKR z0Ici^y}xc$x%9=U9M=x<cHv=X#{oDJo1eW8ji_}**FFS@yy#}i7P9m67d<ivPZgt& z&!H?<uQfzIe7G||5T+&=hkF_?GhB0Vm*I;(xC&a#%s5m#n2ZZ4Bp@Kbvas84-{Nn3 z)7X8|QZb=A6s6q#JBdOMg5q*=wi^6RMlTt7ZuSdp6zVLZ7}~2r+XNA&2kuea*D40% zgp4)m%xtFgiF>c25T<##xsZdyri8*<MiwZvZE0d%JRl$hyCby9pbVO|^aT3MdU@oE zcvoo5DP*GNbT+^iQC|&TcaI2?_TArYGqyG#do@E#ms!T;93KzcU1%%+{=K#1DqF>D z;#Z|9z4*M&GYZTLe<s9J;-w>L+ODIc!(#j%J%{ugP{R%gIi9iiJKGx=87YyTsu!p~ z-4)GCQ72|#jU`P%psEe1A%XjQzt@-_<1#Z>W=KKQc#?&Ml5h%jNcs2se(F$Dr+va2 z%<yY;S-N~H33^Nx_DR*bS%X41v0&l6X=ne0Qdk6&Yn>F!>Meea<vV|kdu_?u0@g;Q zM{9OO$aQ;KzU?a|CpWn7Zwfi^%jOUrwq&`lqUyxMxLP8em+k1~2UF71Gu}^EHrI>} zxfJQnxcw^8PVl-Z9XQ$z<Kg1<e*l~~PG6u$b1GrwM*?`d+^CCsHhq27?qK3jjymst zeb|@E#PHI7M)NMTJz4_P$E$KaQHk-)DVHe!g56sK5r=yLWV=q~zSxoKTL-cor{~-z zZ9$Uh3zILJ)ZUyHRJ@(_nRUpWURHVjeKMVC>roK!F-@!mSp>RFlFYOGUAvRM^nB)e za#jT7_O!}?gW{PPGW*4(5PavAP)g7EpbGSZzfC@v3jijFLd1v&EZ?PmYxO(aACK{O z5dt>Tytf2Ch$3eznkDYsX7SW*<!+7^eEQr6D@gOcm#n2&bhE$m-mmh;&#pcWuVq-g zgM2dRyV{pSNTgpKHa9lQX~}IIiWmChj6?u=Lq;p}O^_I~gN8p8+*!TWH3gtdLg4f? zv;8d9TlDYs{0XP8$Vr~&_UrZ8dcWnRU8J{@Nu708V&bp@uWQYM%(AAUuIEqY<+|f! zEc_7QW4|>wzR}UC^G3`dc1cOe-`nM$%Fs~VmG}!xS_zjSvu?$PU2|f<9GQGuor$%9 z0aulm_FGBLJ74@FS%p=V2pITXBK7-jGdcBntE;O|U<}IB0(=4#s$HK{H#!0n;FeQQ z09@P*V{v<|ALrGiSEpXfaI4k!o0cy`RO%ECjyr0wUC7p9ljxD%w{K(*xiDnP!m^4% zH%gwYo431l0|Vi**kN&rE#46IH@?lbXg+w7kk6?yHV(m~rTXXA%Lo>wNN45|oGa!z zq^C)f?N&(G88yKZAnER0=XH<cvd_e-Yd7erbkk|$z2uRO<o8#%AuSVjzHX|j)Z&Wu zep=r~w~jrfow+$VP3x?0htFqiWE~@;K#t@i5fKqYMl}QTC4z<>s&>5)%8@d|7N?bu zISH)l#w~#tKRd73e0@22ggwv;&V$qSg$Ua8qYzlV?#_b<e+J2R=^&RM%U2~xryKiX zna5qn_EK|mhL9WE*Ji}#Pa1=}#~ESNd>_u^q=~pp)*Njeq-MOa42ud2D=Y0*8205q zC>Z<*&X01AY=GMzt&UH*xs6364ONyE8PvM7gvu35Pep`_Mu7@LZ&jVjj4Msro>||G zxLLJIe2H>!;=&wYwY69ozmPCn{}jT+<QG(7I@f%qP)ih2dB?Zk<7!n-D@nf2;Xsh8 z;Nd2(q&^)W??_2^#G}O|{|hcw?ZH*n;?o}B#V*m<pvK%>RUtp0DKAjqLZc76%E6+X zMkcrVjr(kJ)Q|*lqRQBEl7+lDlw0O}`rZKV$~MA2(6*H|M@B43GfOm5Mio1w;QOwj z;wGu{wx&xAin{sw`eY`HyV|kz%dTFVt5u0_jWcC<8n(>%VT9#=@#1K(uICJUSWVVv zvsnvRI<<|h@aHm%EfF)YDLs6OePbq$ZsA(+*cte-Bq_tS66);P9AH@hI_tk5iU-`6 zefy5ubn$l@S$+9cQ8^j8pd!9-5RA4xH~C9@lxfEUAlu$zM<Q?r^IS?{FD{?t^UO1n z;A}u9Eb!J)17U9B3VYf#Hg}YKiJF_XX^wMV?pwtEeo9oo2|n7MNNHBL@>-DEg7`pY zN@`42;WrL2o&vbN<#{uzx}`73QuaaW;NYS8zAA(!qe$7%KhC4wcl~vD{m~_&T^ZEm zx2HFa9GY!>cQ|0eJ0s<~loysIeX{|&%wf6OVL0482%)NFE6DH2d#u3T&^0uf!Ik_b zzfhfF7=dW>UvG_uS0quiKng3=Sa*_RSB8d!do}2PyQ`)V2{IqPVJcjiMyGpFOa3u3 zFf-fj>^+N$QX?ZD$r4XYPQF^(>O42DZZo+8KDHo#IL7Hed9vH;pLp3@9l|rx)@Qye zm$R}TXO7`n{QJQ*huXjk?sdHT!SjnJ?q~=%-`}5|e(Z>Z5mOOWilij>Ld0=+cyzXA zQFpgu!JZOZ@?gEd9CO^eBTOo&GXw;k##bsSJu8%mh;GumYTnr5?=^4tCkf)@x%Dz3 zbrYJV1Zc&5o=M*5Dk}Pf$i^R38BlY86Z!38DvfIEP8;8-Hp%5^K6^r*OxAB*)1$71 zHY4lx+FdIuFRx{LCc??NIyATXNfkxuhUZ9`MJRc3>RgbH1Zn~uwvQ-zwc~ZN);HFl zu}X~$4??4xaDdledaOgwk#3?*doBx&6%`|2!=Wqh@mz1oOUujUbH~!&!EfuzB=^Zn zDZ>6D+2fQk?2p03FF0S;bc8J{J3ho6@~~YwZL*{2D>yhftZ$^F>9}}!@FcxUioQ-v ztheBx%sSd{_-mIk2qjY!6RRNzc>PZDpmoiqjwx$`ph%_xR}{Uv<eiAu=6dPm=g;DC zGnE)Uw9sWhouLjI`Z2CuVZwtt;NbL0tmicLpgxgs(a`m2|ET|sx});c-q&YGKNU>i z?(=iUSeV!kS~9pveff){;)~0ouz*~k3b@b0#q3F@4Pyz9-Ih`O`g(?dy6run71UZ} zKU)Az!%H&lk%&Q>>LziP@N{@jON;s{W&Y~g_beBSVkUitrQmg_3#?c#lye|f6RrDg z;=h+&ab>2R1^*|nTQDTL^^D|je3w2>MPW|mZN877KCzDL7m4=P48|7@9)xb54@3ou z74j-<x<>ifIY0Ou^>wA?OUSmKJ60<61*LzGWhH-A=MY$$w<tQq8^BifhgHc{*n1!N zs7I${&1SxCy^yG)!2U{na&k_rfDUVAx|)hAW~8XZQKkEyn5ubbPZ=a@m`=j13te2% zN4Xzv-X6rg#>XzJSx0~*A=^&iEUitb5D>Y^o^CcttSEL}r=|ZpZve_8YwxqY!eAf* z#wL8~<moxQZXKswR8oQmIB|QK1rF256BTOmB+rO;O?EkbT7IIcy0g&gz3p-0AS-Cd z^BA0vs3=DQ6qOX!%+0TpuU~UW0e$O-V#Wn0&~8g0w%>*?HPYz~M(~o!X~|Zz_5UWD zpNC@urgV~ubv{j^_hsMJ)?>*qKAwzeCF1_~MEZ-y?3XZqnZgN-KwMksOzdP|(Ld-P zh6V>;FLwNWD%=ApIV+2doVf}@9v!aZ11m=tf>xAxeYHy3k#&sHh@N?PwaD`)Za3}9 zQ&Ur*`;P#mR~bxn@$AQKu8B)OCetdEgqsCtEM}PFioAFkICi#m!QYOSP?5*S`X~61 zBX<wa<Gx-?Xo^2$a(|vSJJ4s%2V}PfO)Yg4xC60M;MjYBtmgmB2<KntD!H#CODVvp zwN`8ZFMs1tgQYJSIeAG@QB?{T#yOwxR%7tc+uC{>Db;3QA0I(GC<1kGA@R<?WTr5; zT>i0wnOU?YSDRmppiojz0cr71s@bQWAQm$fThQ!+lVXzzPlAf08Fc~NuputpuvzcA zhL%IOyqUQ}odry8L>U8%L>`xyydXOahn}Gl77lQLVz5GfiJ;ce-huTL?emHXbA$e2 zZ7r*!alt;ubv`Kb${F#Rj3)50XHqxUQIEn705bD?c>@YJL(TP$-cZ4BD<-mSz`DLR zDy*_vOv}$(zar5uU-sREMLc<H<8XaD)Eji~qY0~S7fT{;F^9mRo30N?M`G7lOtnM3 z&b=uTF<jtCeNQGmtJW#A5UO~67@UmR%UI+&!k<}OimOeMQ`G!-#D4iSU_&%&(JYq! zZf!da$5l^r?Xc#WaxLk#7Dfm<C`0|@rhMMM4Sc=fc(~j<$;-(p`05o40}T~5>3yxj z;InV3iLH2hTdVi(q1xX#ZYMR@)M#^qxLFe(U|8;jp3_|l)NL5eR8X+7W&|7L)*?$w zN$X!f9IqLVaVjq>o9tS<sqPWnn_gVR!N{ZIgOjWs;T>Oa<9GM#a*<^p{(|A-wWOqT zg!y%xTUttrAc>t-z|Arv79-0MX!J0Yl$9u^i9|GL>3dHN*veE`uj#XK*~RU1Y@mgR zNPs$u3tYAZQd3iH?2fA6Ke#olEg#}8P*1IYJF#sjm2ie$*1ck1HJXs;qB!~>0gR50 zPFmOlK&ad+A)((%?lewG7?){BEMCsf!dY<ttQLwj`RZM-q@<-xHPM<Wkxpz`*@gyJ zg%4VE5F3~NhE)>XP=Lwu!ycYB`^=VZqC+mphv+0Q*{^uLaMn|qyCfkprr>?oVC(rj ztk_CcN-y8BsOZ%;S&au*-k<IHnHU-?3-m7^*!cZc=7Nzhjfj_?4yV=4Q47ZsUNiNk zE)6k=Cx?zgcU^Kz38kf-a1Xx^uln51zsx_J?wzc#e<ME=u2vWPhG-|C4x=%)Q}8)N z3E<FxyC1Xiq~GPfNHn)*d~EI@$CCNMsdt?JjsiHG_+uGF<7bmzYr={asrntG<-tIz zwsCj|(T+VlXO;2}ymD!c@^nNTBp_$u>4Fmtx75juxSpP0a&oF`YfB+9Ss;PL^S_T^ z2;-H8#(GftmQH|xV7(N-5HEt=i;i~TlJM{PJn9sk4m>9H3+S^T#*h<w9uAY5LYe(? zURw5M!TM-o@3}P&l9xYnWobK_!7Rv4GyFWaXFVtT4g_<tHMMjF1q2+dkS=Tc)z&$t z55xG`c*VTX>N>go)_k(7r2_G&^L_?WyO4mXF^gCMYIN7wkyY;p2L}h0d~K+L98WOK z@vA~*rdJ1U_UtpROUxMj9Lw!-oqt@Go2x`|i6E}4t2?EYo*VxqCItUPLnA#U?Ucj_ z{E%6$N^A<n#CSby3)$P2><Eh{%50M;Tu^P~j(Y>ha3qWzm|7s4(PdQaPTc4g?^PNn zK_Q;``2pMOStzCugjtT8G=F$5z&Aycp`O?}fLTVX!^B!lk*6b)CJ%`Ziy$^_@Pa}e ztJ+`$%KM#bWu>cT%VEp6ucvJ&zFAg`n!S=bqTY#<)6Fd^vQM9F*cPeziFZF#PB*{Q zk-FY3bI~HSz;V9i;XA52td9*E2;|9;T@?ttm8NbL1c%@k>CF1{l{6rDICpIvga7;z z1;}h9HMOkj&?l0Lio@S0UclcPD+-pRiRp&g?yme4+LcLa{P4wNlOL9?*)5l)#%kZp zYmC}b%hVGni0=IHe6C*~U=(K`TKFlyT=Foq!~sRmNC9?-^j)c~a|jf0n08jcq$iEn zfFCVurCvAJR7O1>Nr6bS<%CeDTrYXb9?YotpvoK+FT7Z`zb=X2hg@_FQO-Htf!Wy+ zfs$3dkYC^4cD|+;b<c*d^@@=PN?#(shf43_EhVR2USk3VLr+$qgNs(e^qHX((<-;l z=*<*ImHxZ6kd%7Uh}PyGu8-2o0}iy`S%XD@&!$a3tZOz9#tMaFyV8vfdoznCF&sQR z&D3slXMWPo&S+_Q4fX+f1Z;Y244>e<x~gjBPyXnGzz8hH%h%Q|US2!XPU}fYUA?{0 zROm+l!u(lSmU!D}5PL-a0SC7ys-hg!>+}4YnF^IZh)Vlf`?G!f-Am;h&GVyO?uo)n zwN!!JY)03e(-Z4x`_bME<_Di-sxAw&n;;aotpU7+MemQ`^%oaSK=unRjt!^9_FEQj z-!#3J${1H6aq*qaYWZ5bVJ6%^$8)OzSB;!m;a^+%7OXrR(}fW6S-a9zVO(pvdIjzN zw-ehSOXvsGZuuIDY}@aK)p-!^sncc$IzChn%7nXg;x(Bpt$-^fGjA_B^~QdUEFw29 zd1k9zT4Y{Gc>h*IBQz(+jy)Wl^fJUCLw3`&Eb^<m(g6m)^D#nbl8@>yB{zwFe%E!G z)pS#!H~Xufl09hJ`fGM!VbL>1Y*)UTgkQ&8&BXYv&sWIpB*d)7d_1h;gbflHUu>Mx zuV);)tIww^6>d@EU~ib@YwAL>%vGC62ml5=-AQ+t66@<S$FiGwf-+O>Rma`MxbO!J z8biB64yE#U-J-nAwF$ra4j-bh>6BdDX{%qcJ^%h<CvbQxYH=#y81B`E0_&4KdtFw^ zF_{0#gL-FuI3!^iBsye~zLsa=N7C>R7{E7|6k(VRn56Iot;T0`8TZ-^tk;y(w5}DQ z1MISxaknEH7x|z?fjXGV%FBAt!wV(V&#iWGH1(3xSTcq`2g|xtF@7`QzHvKURZ32p z5`B|c!A=3bE>|$EJ#E`nRv~#^K*3GdDI9)nk+|1NB`P|1*CBMdC+fZr-n^KYVZQS! z)e1V3{VyPdDynmD32}q3UnCcNa_%s+<8iIHx;3UMcBF0!3cB5n4!S^Fc)8&BbFSAP zs6t%n57v@5>Xem>n*2#iA)jMwUSeu7n*xVp`8H3qbd6``p6_MVc_<9$Hh*6+hYezV zy!JOzRr=J9tA@hO(TKg{7-<A`FyUK03ddtRTFO-&WOeFu*vi(_xizt$8)wR{#1cl5 z$l)^OpMe(Uq94oQ<{-xW)6w^H7QI?um$nPQLACWzOx0eR{RSb+O&1(*pXE_e@YZ&% zCb-9CWKUZGQ_3Gza)|a&e{9WD$)mphjIPvQ|Ex3^bJLs{YiYEtYFPHSG^R|)20D$6 zL*d^LsSZI*-5)og#8w$aU4D5FVB2~MY^FEZO*}if+Z4n2GFex5Eby;6@xx0FJcx6I zAd@1f=xbeKHWii^W7`X0Ih&mm=tnlBe($+U6aIGrZoWAlwHL8dvB%O71DFN(9z+zg z`#AA8YUIDcg>BJdnh@H)DgUQ=m*qiE=UJF9FM}C{QBMb3CJV;3JH!8V+L`WzXvj~K z4i{sONjhFkdFr!z;nl^1ENMy-FHzg>a8D;V{CiDS*6lnDZqnwy`Zx8Z>t5>p117Nk zjFb`)EF8Ck>Toc}%URrim<iMSxb)(Jz4LI^+2I{?k1hOtAvkc{W@*lwNkdJ&M<`mB zQ*3CEQu*RIondx(%zkj%lT+_LHTBbS!!{_FzLwTvs}EbKoFQCdzahl0H!|y`o8_?h zKbga+U)Dn5GZpmnthg8<?7CE3T6#A1`qRHT4rw<Nb6u{G|5Mu=L3wp>;a~Ha@x{$0 zp@_$ayUwsj{p<*@-FXMs<+0IGTwq}V=Oxup{f^!<Hnyckx0}(N8_cPUF=+z!^X3QD zIXQ)99qPyyS36nRrA@8Xj`<h=!o^kd$bb2wSGh3=wP7y2O*XLZ9;d7zMS=GKU`*%- zesnkKFAP70=56eCe^D|aifJSO$nf$ZcD*MwdK^YyV`9*YNc8CM8}qlg|GGlmRrE%r zSN1epMH`7<V-%CSB#NI6auZDXOCHmfO|svQiya`A((j|}13t?AIF@Z@F`3<V=(<4K za8qANADrl+?tRKuhnnz2K%p6%>*cw*gBCCCM)pDer+GzRv4L_ULo!NA?tOFj1G%*= zon%&xG<7ranTZK~9i73!L0y6P^khd%%gg`fZxbmzslwkkvA-_<Gl~B}>VscXI+0f% z)>uHu>qn`sE=A?k{?SK+&!ct3d*UB`Sz{ty^e7;nY`cqR@Q=2#QrodXIE<0_*Hku$ zxsJL%JabuYM`2>5$;3=so3^TGgJ!~zD++416vH5G0C&>j#8(aKkRc~e%<Ux_+u8<x ztm<+YtsHUm%VC1@>)N8Zu%L0(7Wk7IksDM(6}z7O#`E^gAKgbbQsT9t%!ce5cmQ4b zl&RQc9{N?qUzA}mw;kS^`&S<$H`^xi#1ggT{pt8E6GcVO!KBRAfr00$*K3RnqLwE6 z(QS~8k)om($pd+z4;~=luHOc2c+K0gwTqXphNQi&Up6rzEbZSnJ-24zA|(7&wcE^q zN%|lP(<sZ5LSL2wZPtfC?7&*gcxlh+c)?@Fgb)K}hDp<jo)p`H!s+P@Rx%7O$>wg> z>Q+dW#SUTt)_fn5v=*n5#=ftf3vgdF9nnkr8W|c@8qs|_|Jz?{r!nJd!2SgKg^&&l zScs4R_RS8nbSb;o*5!!kw&Y92RCAs{8&7wep-@BFK(j#tOouU+kMT$hc<NAkUEO7w zlAvb>JwFDy948FSPkl8ibqnV!AHp&c%H)4aPz)|<Tn6zZM<~d7;*bLI@mce8qL249 z%0uJ}2L|w@V7!TMV3L0G4X#0oECIePl0Jv~I}c+p7>IoKxZhp1D;iF~7pBRsAZ*;T zBax#<gt56<J;y#}ELSFXu^k9dfe&Ljaw2tD-Rf*Kml(#!j8c;}Mr+d1#PkaZmzR|$ z)wh50HH#JgY)Dn<az>ORr?G!@tLB6eWf`=7P*ga#;p9wbXg?EoJM?ZcAp$U!DkR*~ z+qP$?5E}E4klNPCve_4;i64EB>9Z!jcFq&}5u@<C_I}a=TYUAd_aPF5$v#w)AG-H! z5H+uI%B9kXfegM!fST8Yit@U*W9R!i-Q?-N_c}w7HtqDjgKSii>ZR^`-*e<{stWY+ zxKl?kc|h@C<S13r`{vRaj3<bxe~rdqQBhT5Wfy&|wJz?6L9`C1d+X`x(MtO6BSv-B zv{Y0ygq?5gFFj!P6aF<dd`Y~<UBAiTEB_Fpo-vK1`uJvX3wVEOYwrMOybcrv)czKt zmlRnV6k2x`Zinp>f&CZd4z31c*20-N>P83siOGA3e#b>VobSb=RrOh3pIVF8+nA}m zKx}-y^ca5^M{>jeIj*?dPUx-pZ!sW`7L5-$J0bJ(J1(!QZa-}niDTn5!<A<+h?0hl z1)NUYI&8g^QoV#>8|Rr{<5B$Yjpro{?60beW1#G=EJ)+O-t=wl%m0|*4e`W39?3iY zzsxkz%)xbcLEWhhXVQPoZII&^=|c`KKY1(UyOb7idy76R7^5Ybac!<xsWHd7xw$3F z^X1P?LWx6+OLj2CmpCVE??e+4t;4yz$myGGbbP_hj3J1<cx;(VScs7r!Se}%baZ~D zT&NAzwlCWG3wq|I_r*2NKQ=p7N&C%d0LXwkhx%+DL^<DFfc`nrD0T-1C$U}~8OMcl z4Dd6rX)`4j<jc+c&#P{d-C(eHTaUk~9hLn@f|J4f5EN#9V#hm;X<C&rp9a+Y`xe0C np9Wx;#Hfe=4*maZw%uXX&BJlM{-Vh--UBL%>IxNd7Qz1mzreuJ literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/import-dashboard.png b/documentation/operators/src/images/grafana/import-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..2a17aed7a54fb300ce10be47085646b478014156 GIT binary patch literal 75407 zcmc$`bySpX+dhh-QVIwXk|GV#B_JS!bhosCbV)a(Qc8DscXtZX-QC?ocl<7V9`}B~ z^}TDa{m)+eUaWDDnYr)#it{|q<2cUwDI+EP3>gm@4i4^_sK^I7IJhTFaBvTi5g&s8 z*)_V92LHfYLqru25fP^sr5E7fUcrfe;8$>n+nKdje<6&IuwT8rQBPV=Ex9Rz<1Ems ziD|;x7BZoeC#x&T8WV*p$=WvIY(X{g{4u{%@Lc+t+e|(5jp?3es*nA{Mp!%F=~_ik zf%VLuHA_DuYuPa(9AZRFjFYOEPm#$3aBgtCVwKQV{^u!pbRuX;`}@oL0rb%O>-=-@ z3rO7G#h>HRGbZZ4&(T@`KY4>c`3^EV<VRVV-*}a19r>!B9*4OGiHC!KEEyf$@2fHY zSmmzn?nkP8f3IUhA@PGmm&r~`^soU3jf8{`rN<lfqO^l4^}Wd>%E$6x*#9}sae046 zz0mU;M>kH^(#oCXJ{w-$<|sf8L`;vcnBT{O^!|NilKe@FiyYtX#mVWj`DqRp3r%N- zCD@TTHZ(OWYou6XbMxg)!{W4|4T;{3y&AS_@$qltDJ70Vo}KY=F~;`4LwEiqQHGD2 z|L~w5dNjsH5t^MmXmVZEiEw&TY}`Baz1c;39Od6rCJCQ==*Zbf6AQrW&K(Lda0|-H zJ`XRX;a!}~9e2ArBaGp&AM8i4v%mcIe_doYduv)<n`8{9>*=LrE+*zO5{Z{r8*K!1 z`|7+23=>y6#wymT2l^a=oDB)d=S3Xx^9Xxv_E^`&rRY)G@f$lssH9|hp5M-TVz0fO zRcJ^^fFJVJQQ<rb^Dq+0klc`O<8=)bYVbt+(PM;byNz`pA7o>+HGS9hUX8Sj93rCU zR{Lj(C@3gf_Pwus8$NRBR2c{gUc@_dFsQ%lUA00YdHwozVs9L`O^1l6Xm-}deq#WU zSieYW#RhDFRd>o%L*r&?DTUkKLcQAV8+uBn!IzDNV%IDC-oz_C7sw16H~Z<(fO^g6 z^y+9qZSBQdt<!<^=1+_n(l@3f9mUMd%m+x8-l%sWAt58xk$*>W;dePT#p?1l&*%Lg zv)pc)jYe!FpU(mkORY;>UFx}WF*wXMlT$Rx4t=b0R<^^n#Kc998U)w5VIPW%2X%Co zV(M8#<wF`Y8-z48bo-_G!optkN8hyOgl{WBYyHrfp|?63g!Q)gN@HVV1=sq!as7>N zuh;pFj}De8ZY<Ano<9%P6IY^-YIK<IugyB-ClW|(bSSaA;fSd(i=b0cQIi*Fjl!n? zxbz8jylvqOh7Zi)RO$9FW%2d!h;TeST#Koqn~`Yf>E3*Hrpf;9mVYPpPyVKFBXeG; zFRQK3BCfCBF)<bIPP>UoieH%Dh;edOKR&`?!F_5>82G@w-C1(3)ZSTDwX2Le(X~>4 zIAj%t>&EKeJrC!S1Xc~$Kw}o_<<9H3V1y_<KCgc+oUh8MtJ@(Rm;8e4i;PIZ%v|CT zRL=){fr-gLOH1xCQ{(E|j>g9nErIHt3g-Tbo{O6L8+wW5QA|t>p3@O#W<YCeD+YvK zo$G3{r}|wj-Su)up+}I1$6GzU@B_`zLiO5LbaX6MD^bK17RYY+B8Z&(+tR{;ad^z1 zTTbvJF+-Qu`x2$n%e#7degr}dbabTJ({8ygosCtINm^PbHDqOtCOJ@Yb7+uAOxc~+ zPhCg2jE%P(9jlX*n+Q<XJG2l4Kkz0ONB`X(Wfg62Hi}-5qz%K%X)aUHfsi1(I8NJ0 z=0Wgo-yroc6?!+QqWi>Xq|P~AFWm#3KGMWY&qRApT1~utU?8gLQ_;sfaBuh=3>F_N zM<=TKr-PD|3$K@!bT@lTOPI4go10x|iUfZK1SCc3>ZB@!DW<3E9UmX7yw2N*63L0{ zUTv%MWoF)ytPcwb!DDu)`t~h2BBLTX+44m{(ILu~e9`vSR%Qmd`~zx;h=R={HnJe} z!}Fj08^O!BTrP)_U*3QD@+&s!YhRtj-&=}LBfK#LbJw6*yrHY`9WTDpZJA~(JvsTH z`LXy0iL>zCtvk_VC74zrfeS9r=xjk-TU#Y13iqaS?d?EhWFKDMGXaQuwR+!KtexC; z9TIX><Ch3sC=RW7EV2Ea)xqK95ss9s#UM#?8=lw5b4ZkgzO}Fc`jf~nNF?lIcCj4h z(8FU{nJ>S3)s!=&V`pb5B-)_Px{OiB6ZJDQae`XCmPPhuC1n>*7nPlzKVvKN%qpDz zUOnUx$$!_FURFUz=eoUvL=Y1bGnV&+r7=?4#5hMWO!4ZZ{L-m4awN}X&m4Yp^!Vi2 z(a}*I@yvnS7X!cbbLvq20jBJ=k5MOjjJOIS9X&0t8Tcye>fW%id1|z?voSg2V|+l= zX2f;9jGC*r4@F<vW2ZXbjdgDvM{AK+9v6|4GOd|j32Vs?H4qUOmEWAZQvEn&k)4zC z)5qts-ev9Va1w+rG{Sco$;r{-;Ro8vi2q)CQm8A0iJD(dMuw4<5&QY`!I2R>7@G=2 z4$N00B1tQ`;OeTLfVW?jbEA-e#&W63(S~G$N<~Ii)&9sP^n;)vLe;YrIqq@^F)^o2 zW!gQ*`LUsq1oo3s-^hM+NLQB_%z0kraMb6wFe)|{RscRXzZ@h)3^y@2THk`Bvn0`0 zRyKLvkU<ekv7z=EGI9q)hgRk3Rj5HgcXwxh98+dNL4cEq-?{@1Wu<%Low~Z*JN@JH zl9Hk3=4-S@^}pjEpX=S020{oY2*-AW+<bg6+h5(jIQ=iMaGpbqO-wi}F3ejwOoRh) zLxXVbFMIgrU2CJKKKIWNN4(KI7*5c7ORzT`#36ipnLnC(e(vP^^XF~Vc4SUY*ER=( zR<+YN8a}5TnbkZ;+C~*xYHBP(!eaB^T|+|{kPfiF!31+y%xEeq+TJx0a@9JLmY0{$ zgEMZ1g!Aoj1!)D{9etbSuGmeV<FY>W2unM@gjI-$iM3MJO_!LtDk_e8YtjFECtv$o z2L^^P?Fc)1HcJiqqK31A#25ti6xVG}XBrLq6JN;m!ttWAv7MBKjnz*58~ALL6F=}} z<5w22(@+;uWm<_4-dqI=iT1`8JpDUB8r_tG(#T1f{CxjnoQ=h(=7PU}g*$%xL-cPH z{hCBV@%ZmwzI#Qz`1>3YPX|D~e~wp%|3AOsedNl{&eqP34@OwhBXTN!Br%!q7-23u zA%Pyr$?23|f5X8s{28Vf+T#!5YS<|$$3cYi(D;)|H@qHM=K{R+75&xUTje1TpTI)@ z9?i05Xk;wk4Hi99v21?=pML42N06SlvZM3-Pv1Z@7_XVx4&9YX;#)@v2?f)=89|2Y z1h5Nitm^-cUyW}9Zs=<d4{z@}B-BrgxLsm2@Cc~kK|yuSF#XJ(>Ie;d9GuX^$nj<_ zd5T_##Q2lz)=(+V*Z+>}`^aGdT{*1qa1j1If@Wq2=p(t?tm^^`?Ik5oykXJZtGsSY zM~heBbcQc|$-DH&k!!K<-#hROX-%mV>;s3@6@8Xy2^E#e>+3rmxu;Kl&-D#Xbtwrc zRlMSZRnHH%v^Y?NR<Gn@Nhk6kqoE}$S=-|qel~PjT49<aJVb@Fv9zl!DGLq?>gjX5 zTUeZ}tDEseiJ+pQ+S<nF;;gx~Tp2$+ESam9oSA(>Lq!$w0*BA}_FO~V@0Bz$99#_* zg7@w1ZHFc5{Z++FGgij*1iF5ePOPhYNRpP45?47e);8DKc`|v_PI=37Nl!m!vO|W1 zB#P<{!ls_SF@K@HzVY*ySaUN8y}g%H(<hDVu2&NWza1Spb=xIgdBpKLzh<K&r+T{( zNZP2R5Z2w<>F6K-0t3V4cp~}h`#UDxw(gD&w=(O;a9{UQGirn;6z{L(>z*jM6rTD- zkh2cq&iF+;k;22n>sA5$U@9I26Ydf8^*vNM@<C3Hv5^tAtn4C-K~Hc*2z?<HY*bua zN{W|;tE4&}oGmgUA|s8=vRa*3%Yq_Q6frw5Z((F~bZktHJ2E_2ml3zPSQemD?L`vs z!ST!<=wMLllNR1<EB{#|HIz*=#-{^OVY<-uTU03z^e67YAu%qn+ue+9Dr%a^NiHhd z+$^eGX56RPzJiFIJzZ2ZG^|WaC~jA6JtOZp$%B#U4zREY&CT>`zchukq@AawwSdQr z?a%f75~7j`d{9dr9T#I`s~zsAGw}EKet-9cU}<DIo>i%v3knMA=?M;FscSr$nBwyA zcqAw+yt1;^b8GtGMoGcOBm3vYbkHk#%%h0m=*X}z0&cg7fnOh`rJ*Z`{U8;B$j+|n z{d-Zp#zhGLieJAvn&vutN0(PNm+4xn|2ZAF<8MSU(mpZv419cn7Vmw~b<D@k((jJe z84_Argp`#PL1r4V5ES$@F*e43c?xnvIz}{yu#}XPlG2`rdXGTj6%Kv;;4q7ff()6* z7o<o{VRdzgq$DXF&!2@OMFdi%kXKv0O$1o_@uH%lD7Ak|xdEPkw}GnS$B&;(M}##b zQzO0BHU>2bP`%x9v#O|AXn*VeT9~kBGG(vzjGy?(Es^k6Ls(c^P-S$its$o-C$G*A zT~1cBpr9Z*Ev@GhV;O5X2*qal`rud7$$lX*F)ol{QWJ^b;A~u#l*XD1{!~Ra(%-8` zKS=mA)}C2dZf)uJ#VvDA(UOs6UEUo92n%_F#33x?RbGb)V1c|`XkD9B+|9*9MXd5} z<-YN;F${?2<GQfmh-hwuWS<ga9l7gLgTUF@C%v(y9diYDuCVEs(VN5vEpTv2wN$jf z-&@>|^f?uXWS#dZ<Ck{L%Wk)^J}Gl3(T&Cg*0%yNNl6|$a>0r6f2RaJhA3va?l&13 zSy))u757_jug560e-jU!29}Q8uCB2Tui-$E$9dH+jzUijoPXc>wE$W749)`%JS_aC zrlJC~^`Aipld}&j>>4r_7VH09;;-*x>i{{{ix-IhF*WiZgrxZ4ydS`64h=Drx3)GH zJchF|ySQ-tAEWp;O~Jwamr{HqWMpK-Q{zvP+DP~(l*7TjkNo`k^P3%-`)huGMi!+e z`KN}jNjrnh|L5Akyf5>=(o<7Y^Z#dH_<zi2?<3Rl(@FpLXOj_XX#AI3PEXH3{*PP! zdqy5o$^SQJq<Br5`D%v?@ms$C?~TFbC(j5#JR+qgi4KnLTeW)pMI8%kG+itIDKcta zt}e>Lm;KI=hzM$GdTcv7xFi!6Mn)PMnit?XIFj%&dh+$9cPLjs!B*C`o)Zu_+%{)N zG9;>~Og(-14l)sL+?j*5eSG}%Pi8zXGc+{(&&evKY)i{~V|J~@1I5P(i;jLy^xSFw zD!@yKL0cK@wj@^!jHN#lvC#+C6x!|Oxc@d9@109S(e`WB<#y=?yV0wD(mP{gW3bZ9 zT0b#1s?}bsJxe66xB)TEr|W$?;+j$@`Bz;R<F^C>X=yKRm`RxENtgmuPw_aiv$90w zAk8BqbtO4n{V<~spK(b%nm$cTbE>LMc6D@NudMT&IRm;#8nL*%n1ikShaa-N{R#SW zZE~_Up5tm|4Gl@e=QudTT%Xf|wJn~wlaZ6pLBC{XWW;d!L`0nadLXc}vNAj*x5rl{ zuc;{%9vgdRYiAQ08p%M_0li%k)zPWT%iCEJ)WU>hNF}JqMBSYokb0ow7}(Q_<0Bz; z?!=v;5zX~>cVo?z!^3@*7Lt;xD9Rmprt<M4DiQ0*P?wURilBr<T~-z&C;4WpFJ(i+ z92*;3a{-|Z@o*-z;nS@Sq{9;>Gw{asT$i}7r)O!Q5c(X_+&ovHS(--|i&*9Lu*iAb z&DmKP(&6Qw3lFbVUZj8a_N>-EL8kvMLH9}dLBH~_WSg@jJ4@*+kDgnXrW@x<>mw^( z{ct|PrKKe;x?8W#&s`n3(uubhw>Pz(8l=22x9yWt6VC{_LeQ6XcGy4t`lO|0L81f; z&3Rhp`^lWmS%)th?0$l)T0eZ2!Hyyh-_f@;<AsHKs!m&jjcAQXPCPnQnJFn4BrX3v zj~lxJG%o<3%3>fL$7QXqq+|~8dyY#|y9_9oK@k?ubrcvEHv>}eG0Dy@0rB}vt<y~k zNXkjy1hSiX>m`Mso;`Ir+B)8Zrlh>4aF84v8>6PBy#hrysQEZ7G<cl%$Vggd@(SxU z?wsc;0}1)!A|qMsdOQMM@6(UdLu%1%N&Lz?tA+h4%h2PKrywx2wzPnt0is^MYW3d4 zAPY8jgg^U*<2($F_?*XO!N6pDzc`n&L-zrk%;DitmS<O27hq8qm4v9k;`R0Q&04)K z7{*FUD*7rF88^S5cwWqQ#zP*~^&V#k^GeiH*aJKA1@{DZz*&sCayu#tn&aY`-(E{t zLNNAAEGa}JWaOe!%YmJAkdx3~5a43sOWGPDBOcq^zD&x=iHL}RAU@YFuB(SBC@7&r zh<NKbEcRXtK5lJJfpBtO<mLIr&6t9vB5p9Ta~BeGkG5{EBp@AtJ}aPy&w>aGM<ykG zE!szih?r{z`1lw@o!4_WakAZ&6qOZ~z$b!rE-o%EFBej!UJzKw5ju&P>H|h9-nSKF zwpiDq(QRx*9MwBCF;Q7jF*_rJo}Qi`adTAMdb}WUJWmrFhnRLG<{=znUp)6XIXU^s z$<w`=df7ozT{(4ngBveJOiGE~&Q4zY+q9zGVI@&fByKxXJ4?d-)7{vhpjQe{c=dRg zC<GBjB_*XKC9yFvIW~2-wziT}QtS?fUT)=wgxu*10K^j+lm|mgPs{pju$`2bmy(j# z^@(u<RjIXAPyqmlkjTVt{qdZvEG%rSCy(nvfKbt>R~8eKQ&-=)+IiztDJb}O1ft^j za&}%!Qt>AJ&e|#7ug3<*;4FhJ&<C}$qC}(Wlc<iIi=3Q}4o1jNIJjdO3JQI|j5QYs zaxfW>;L^NmUHsA)&*yk?cu`U!2SE(&w6Q+<SoP(nmsdtu+DM6BZiC7}dJ!!O+^bh$ zDdNz_ftc&@hJ?f%)({UqrIrWG41l%ZX}xp~^MD-y1UrNErpCrOzeyp5>O6&+xrIqd z6U{MT+S&pWn^&z;Q%MWdYh~2b#2Z^bU)w*6mY_&YUY665Yt|BmqM@M41}Voe=~k46 z;@7JRjJHxabiM4&larIP+BsjOly-gjw5{WL0;nSlF9;q0U;zGtVTV-{xcFOG9_23K zo!wH4EX^xH#KkXfK{2Cwv};8p;9c#grJ>=ft%w1Z!23@ie@-r6ii(Pf(cM~Igy-VO z$%kfRFflPf5G|szsjW*J7;X{~9zRBhq@|}huA>A+DhGvz0x(13k(GOfq3yG>x{3}_ zP#gut{_o~FFVFh&@?!fP*wWpWAc}WKZ|~U1NJ?qG$>~s6r=v8Twc~e1D=Vwluk-9J znP5vgb6$^nW99i2ie_;DimIvF*r3u@PQDr#8%oF4taF$;p556wi=<Cv8{l~D0jg$< z1doz1;<IZAo#|}N9Bh@PMqR7_*RXY6d3k<~69YwPaA+(h@!j5By_&^*!{RJoJoIw4 zdtI%f0H4?8`1~N$*7kUNYeI9`yYk>8E4Hug;<Y3vrz51}Os(PQY~A|m;ASm;Zx0@c z1f<D(#(2}}<;zLg)Hc*F#97J7)FdRqp`nDBn6@`<t5sEPq}XawIIcG_m1Sj5Nj@Kj z4YszP@C;;QQZq2%^J#l{daeQnnuUo82M0&1+(}g8>0O(I*2{Tew9}o*vFVA=TV*P) zbZ-DgIy^ekL^x06xw5dH6jfKB0bGTyu`xX@t+Kj$SP(93d;4bPCz|)~WF;^GRW=9g z?oA6;)$$nu$?|RJkd~H~0xjqF8mFTs5uTp)tFuSdrQ?bU3P>dQ9QjCy`|Hj&F==Tl zS+dJsPl*b$v*}*H2Gp{{$yRH-w2SIQnt!hs`!Cmlg{I#U5<TE*j7=tAzBIbMWhhXu zf8U=n99B?p+w-zCKhJd9ik!Ny&s?6OpOu*z@T>az?;Mw`w@**jo>&_h8$0{Q8k(79 zCJ*}lUaW&AV&R@|jpdv4>UAi|$Q%>wt`5wLN-JwYAg}rO80hFuI_0&96R*Htsxzrb z#{z_vWZc{QM)%Mfr^1++t&XgH`OJVuXPn{Y$@08aYnYkoVLNd<5(#*Ne5U^@p%uS2 zbM$)uY?9T8`CJ{i`Njw|0}I$&mkBECqXscCn$b~3PR_~2#pLk<t*#D{<=TdyKPS^f zhkGS@!^0IpT-QXXyFQ!O_4Is9N071`JCN8E71gn-#gKx$Nw9x~wo`2ni-?W&jvW6i z08eUZ`Ln0zSU8Yav)<{Og_13xs-Kg-^G3r@&(EiQ-JHUQD&Xb!@oe_YBPf=m@cQ)X zHlh&CNZQ@V<E(#q4L083)VhABb9I^+N1%a3vfdZ}?zTTMt(DK-?Be*K-mB~<W~OWT zxk<zN+~RN=tE9``%0`Xrl{B4&?RiI2t}?@ZL|Hn2#U;-ur0u2x3bUzN<oCX>cG_Fh zXlQ9MFqhl?P7j?g@{(R@si=(h+P+tJF-6gu_6TZjeyE$uyJ?gyK{4EG_R5t*05Q8D z`;=hyWCn&5+C;$Y@IlV%Ar=W9=S*oz%2M?_=JV$f**_gMO*Uu1sthDzD*zy7+cl#h zA-USI5#`x$B-*a-@^Tv>n}9(y%_F=#X0N_mkkS+M%=dRyv{h8`WkUc(XAUBthz${H z=It$@$NX<cea3%c3QyPetFWy1CDecAI7$tuC<v(71F0YE*4yo-dY8(3IjASv8qat% zn6q@!^fWZHVYy9;%){X+?hGphIW_fUV<SuX^}sr>hPk$Owb?e2qoZTZ2W4d~Wo793 z{$ONb+}(DefI7XmjTfk|rz>tmGWiX;7A54LLgM0Q*)68{`A$LT!sD<@sh$4CHcxMH ztVKaXQ)9Qg_Kiqj14B;_3m_HnR^4~?c6(Eh$67wVzH{}yASQz1UP-B<KY=G@oPz@< zOx!Wm6~RG~o}Mo7I1K;=h=99VK}Af=<(|fs<JDMnjH>BGQGR3wHmsMd(2fm&#-C<t zXZsnL`o$mo{jYHG&t9^du5>AipZE366c&yK#9yW1Q6!r$iVfA(QP8Q?__&D@>Kq#u zp5QC#>1S}LI?hb|6pt)e;d!j9tD?Ki8%iNLUu)kEhRA=+-o{1+tUVxa*!%>M(Dp?0 z^fVw<*nhgp=-I4Au(EZ2M_ZfQc7%qU+|Y=)rKKgMu(EUQ?KVf=nzM1f@yX2ck}iM< zC&$NvA3msS%)n+FXARN7?JB&_sj8ydmlQv``ROa3r`71$$1aZe91ANvIGBx<_4N37 z3i_%4xAz&I8MAFy4@1Mp=1(JN#WJ$8Cj`5r^G%MEhYT^?VhHR;sP0W48KDQqn~B5Z zPo4;&JoQtLn{Cv%4**!OuERs*T6-AS<d8@iVgw#n_p-8)3gR-|XI{<vrHQ<*tadw( zAV1o_Hc9G&JU3)lag(i=h@I)ZJ&{?s%e%tLEslWq+1Yl-IaA{q8n4GamQ|PVLAN@a zlQf{@XuqWgLxY928Z5iWaD9GFbqS4~X<X$ro&k$ZOk6C1*Ey}AfWJ{uRgM4ydxy;q z!<RfJ2v>N1dbZBhY+@joC9{9cs=BjNls8Z{`iS{dgVnbcWU}zkP=+@hjdsg&PEI#k z>mZ(j5DT~&=Z$>^H-<#8bO1X=MM04eA8&inbrIq00E*@Jxd7V6#i=8a0En)?oH05% z2~*R&TS{kn^Lz|MVL%Eak_0B6uY7K#^hh%pf!YV+a~SQ-c#c@9s){){7~0w@Ch}&C zthnm7`9X1TtYLHcLbao#qhJv%T5&Ql4T6e#XlTfcQ%N2uBiT`5rKPc1S%#@<j|~j$ z!Q4Yc07ayu<Eqm&*GAzC<q~<U142k@3Moxjx4)kgU}c^|D5PWPDQKo5Zc*|vu&~q` zT-bbD#l*z{jKju>%*x9%wWWRhxYc6ZG%q{b?XV@YtSrsm0+Z%0G9_i`(pIfOl{wIU zwKvx8EqCp6$XkNGOZeL4zg~dpN(*KdmKQHx?Cuf*NO^TqdaFGhIG^{iM}Hgx@(^At zIx6ZpB=3%oLeI=hoIy=xGDv>qP7?!yi1h3kU}nq@Bm~cPE(C>Z8&EXG#K5Td)YX0W z6l~-yZFIP~)EkzZnl_DK&=TOmD4i?^ByBnwWoJhhNaATZIY0%e*1ei5jObauh4vwW zQV!N|r6~ttW@2h6D^t*#4|2j=aVDn*OB9n*YT1fYb};zy#f7Ts6cC|3&?P1F6Wy*) zd_7BZa&Da;5^&fp9j=}XCSG6H*~4_ABr>wIJ?rY~qM|0eo=v}1r-!BQ%}%de^>Sy+ zqL7ofK6r2oc&~ca^0@dJ@ZxI6dA)9>-O1AY&hpiHADc2;`@IQaHr<?NFojd9T;P-@ zjk6<G<0K7J4tu-}XW4uB@K2ta<AtXDP7NgDGp%;+o+^*sSijrf2b!dVER!t03Ad!A z8Mbe^@v6NgOeaJ>Wa9*6sq!z2a>msqCCpr0DJ3N-fj^^ja;Cb%=b6saA8!7lperi3 z+~3EIi;q9y`jy!ENmXTXV`Jkvq^IZ2TCbYTN(aA_<P-O5ll6X^_cU}oY~-AxnwoRX z%~orEocGtU{G5C2lf%XNT&9j3KnQOls7^A!3f=UQd9<{)v*V<s+bj%^+Y!6PxBxA< zt>ptdowAI~$iM)g_o`=FJl@vS?LI4kpO;^OZ?K=5+fNeT_{o$#H8r(Xk~drB=y|rf zSxTAZ>Em-KuG}}c>c2Jv^hv(}^XmgpuGF}!x}-J(qPm{%E|P?SntCzP{q7{u&ks2> z<J!anFI$+dbaDp)4aRf65XA~`?|@X|Mf==baI4Pd<|gso)eH!s{fRto_!uKI{rL)& z)GRD0TenxYH`7f`-;Qf_baYDjwBFO*IUi0$v)m0e9`{8tIp5YXAdz6UNgLsX4vmd< zc6QEP->7majBFL3`ve5^bchTO4F!jUR8-oVjwt%LK{B8sAhD{H>cgLWLdUzbYwznF zkxqU3WVqX8DWp(|5!bI+my*}@v}%y50u>z-Q(jhfw)*HQ<3>;QlgV~a6mBDs#JTbo zIHycneab!1K?1;DyV>B*YI66Me~{hW{2k;8a@KcR)U>(R$IFE^HJ3m!?29_M$d(7F zsSsY%?R4_p;T=B}<VSfp9Z6bEjVgeeJ$Z#uQMf!r9!|dK80ZsSS@qfS`mztG*<){( z1NjElb8~YW!K^Eg<7-5NBxYn3oh%@P4yjV_%NZ5lbRNW{yq&5%v&Y0_Ax)jDs6bWN zLQ)06>G9)>`MmQG)x=gEI@KzhW{+&iLb7})bp8AHYjB-|y+fUywnrI+U~IRx@JjXj zZm!Os=csGck2iaYXRXpIGhE-CY10tVP*Y!=9I^>`2YhD4)nd>h#K8D~_9d3b`N7G; z&E-jVd~HJ}eAvyU>hAOzcW5U8>z9pSQUv@PrFnH)RS>jB{Qx7vZmu307WO{8wyMfv zt}OoYQMovN|LpiUm_tD@0c~xXQc?-_=LtW4{D_T3D4(&)3;_bilPa{=9tz6JcSWwG zJa58Ub<Ac<rUwT-TQN?K37{K+@Cwy_em#*|^qCR!4X&lu<JiX6)S;bm-1dV{6X?mx zP)&!J(E^(Q?{nogC)mr_r&Fwyug+mQK?Uj9kX;TS<dzV2X$yEcpBV_sso#q`d`0ck zSEz~wnVDe3Z%N!ik@ADkgs~1}3lJ_@*~-(>^>%hIIq<|bnLaU=FDwtsLB9vMUQX@( zmJTiK=qSo?M*wC8=-n=Exy$O7XOP!k;;wNJ;d#Pk5G=le<J|^^lTCm%AV3RpwfJc7 zE3F^?{&T0lpBTSt1OaPbJGH{%Zu7GI%K7Y;UHke4077=V`577deKXmhhPv9`NFL6- zTO@S)vN@!(MKty6*AJ%^!_QzP*FDHaO%;wG2>kfM$mk^v6SDVj$CazEG-ai>Nls8; zHL;ki32^HJ*=f8`tHJSz=AO)xh<UsFn^p+%;%sGp7g<Es?b?Xjf-e&IW<GrIknLW> zzS%hJ49$>7L4Zz2{yK7py1C8W-Z*EOqX6Fn6RreA#MJa@_?{S`??pwURplX&=9ZQ? z)(_}FlLO+>&{c6+9*lC-m?Arvln1}>3>S8hkwF2Qs!!j%+%;pz!>i9aumri+5lWDs zlXGbV3)r3J=#An`fRP>q@|k6h8<b9Z2VO_S#fj9f)Q8l$@l-`tsx&yQ3TKkwGc|_} zGA{N{6k}$+Om}yO4<z6eu^-6I%bTgSpgfr;VJKv@*${D3o~|%cuh*Y!qzv4hEA_8z zS9kbe=-@y_;?eo}bnj-~kU@1=2|y2RU0rE9*hFzOs>pMQW`oNuth4bVK{a>EYOlJQ zGg+I&1Ks$X2)1^=!%kDe!d5aaEFHjP_r<Yk1OCDJY<Iy-!<7AMDZO;0Bs=@1#@^D7 z)NXZEmEm^9GaCpis<-v^c`%2CCI`<4fW=h!`EPIGowM3R6;A?xH_F@vf{M_~OXxTT zK#ELkz=Mb)q#=?}Q+HmS!OX9obI*X_&VKDk!1xK>qB;z4wd)6#z8aNW*PAA(Qk=c) zs)wV<uC4+Q5p|cHc_?vm_w@9u>1}~O!F&N8)G7b+;G#l8K$6=~(yTv><$$&U#sPqe zEDUV%k*O}b&JZkves#5C9lG%68UDZ!0tUh@d$BEESyJ-mD}$q>r;tTGG;y+Q-L`!I zP2*VRg-@<8_X#r<RZ<dTA`QU+dS#9Enf~z8SR8x|b*{H>2StDIwxkN9P1TA@N!bm{ z5YDCwXD>Da2b8;$RCiC0VN3xpGfkY2d`CB}%ta0`ki;fku75Ex;WkdT(4wW`9L%2{ z&+;b7_0m+}nyOLw%1la1$HJ28iM+l2Qbt#MVrL4UgPy~QgNEicMTGRygdJOKh}X)2 zu`!+vj84qh_^@<6@FJs>`pp}|5$Lz>)kkb$R0k$2Dk{;pxBkO`NOLYtDfy0`l9dH& zX(=ox)_03qrdG(n_ai2-^m*<rb*u(H_US2LLu1(Muz9IHv}mntY|^n`r#7diyvD0{ z-X1GQwTU;ps=i`9<|5d?ll_!n{xd(&3Q#YO`wM%+nSprWN9sOz6v*~ARyT#bk|DiX zwRXjux7<ad-QT}I#7hqYG=sQkKCwnt+DGE`(SZ%UPoF;Ab4HO297MtxF9@PSLT1`X z?W&sgQv^=w>G$4@L7_yOjS(O>(ghyx+~aSqRn}>pr1qe})b{6)oE#ea-Kn7smZ5?t zlbXbb^}}sm2*gtN`m5!RCMB}l6-8Avrwqu$yg35{=pYQ$g7JB4wX!gn>V0`yURG*d zR=I6qI^*5+i7{HDe^8SM{z;)$qmKnu^5Zwy;%aKjpxo2Y5Gaj|C@&|Bca83RVN_;C zNrBnh)#c~+w6v(ml+~qQcR|MZ8%HhY2`MLuhsDrdT-;7ij}3rEva+(0bi3#0_QW46 zQR67)*MEQiei?-~Ybzq%pX7Fv@^G%Mt}MjsYidOVs_pA<4{k@QNK9zeXnOd0v?Id9 zDagrNT0TroOsJ`h@mZ@5!k?*blZ}eY`>Hye(MMP`=l$510rKe@yM=gZXKyzW(zA++ z5<TW<z8f1xGO~@{*m2px=a!bmbYwMMy{jxo8s<{$<-aOnni3M9hgpA{+L<YQemk1| zL0+Dlh6bXp{vG+Z<=eO)KL#?clGmS&jB^-X(z`dwD31?}vnY%YfP-~YSLlwnKbAgz ztPIPDUHzztkr#^J-Q67$f-yZ^p60(Uh3I&@b8x7a3nGT2H>~($3OzkMB8fVEdu6M~ zq(5NRfVyvNw3(G_WN2)}%~>O}S{Df^Rld3KI>eV1KYP70`b|=`&3+H|{kn}<f~yw_ zfe_61%q%XFI5}PJa@jcJKP?38$i{{UfKDI-aC0MYRpS$q8*$chZf;~2!h;G;Ej>HC z+-lW+<PheKnwEK#I1yZy&tEa_?E)(+UTpHl?8&G2V=~c@vo0<AjgXU@i}K7BAMf(? z{D2hb^1r?P6W&_p#KqP5`R$yk*|`;e!X6b&QA9<RN=VQQxQTa!dgG806I;-5u=89c z<mJWX`}5qJ4z5?b4US{Px=tEt)>jXZKB7actgYGD%8^Kp;W!?cEQdk6o{g3=!VHSb z(;x63n<{;?(6p{5c;YTfE=l<;^$7BN&Z>H5V4#wn{S=VK3iO{ZjrMI#n5b)%HQZQO z7}hx+jo=w6mtGvS6Wi@g7#JD?-PqK0Cp*{#%%<VTj@{|;n9~=e@8l&8jXBY*Q5zYt zNyr!)8z>QNOS+!rXO)$Cz;qqm+=#q?14;{2w@XVHHYMz?JnqHI6hKY7hKB|zE6A9> zMZcq`xp?eYFM6dTXZFq>A|j~QDt@=_{seV3-nD<OfzMXXV*W{a`tnm>axT-2A7DR% zQi?^jn`6!jKQ}86)NMejyZ!~{(oFxdV=X5pG`82?bFJ%QE9}Yg@-~pU`4L|-eqzK5 zO+naGR8+hyXTQVR9LOxx;M%qxB)}H88E)HED7repB%XT^UbkIV|KBDM?s|1?EsoQ9 zsc#m)k?>kvKtNtmuvd2>D5JVFR<-8yDqvzaBLPHIfw9QT%crC^8}!DsbAN-iAFX7= zLda=B0^giGo0)l+C2Itz>ot5fL-P<SbAgeRVPbJEoYY>vDc_<kXZ-N67wv6Au`#NK zCfmTGqNJoGr(pyUn8$!Xet$<I0pOCtRf06NIlD>`)XcfnbDI|xQ4+Vxez0&;i_*^S zZjBn#rXUj1C(rQ4##0ijsvePev|^N(+7^}CI-Fh~^u^Cx^PVr}SCd%uc(Ka)Q{b3% ztLq+5q8;NN&f3q*_l5wkfNVl=bV5P`HZjh0WufA*#6De8pqO&r0l#Rinni8jZ2S5x zV7QR_cbwrbY{g9js;XM%5>e&8VHo$r<_$nTi;jzn3X7{UUab+@J}N8L@2l+GwEGk) zMKXo{NpHO5qCjTUtCNE|e)LnqyMqhkgYh@m-K~@HK5w}>Yh`atuCEggq{t`Z0xvhW zTlxj9vFTLBZt}bP`Yun#>m`*9E!=mC3U2G+iBbP}+&2aRUz{ZzJT;}-5FC?|0)Zje zulL-3N7pf($s8pFb*@bCV*nRUcN*<svnzy*Y_69(Qn^mPfa2F`blY58BOxa@Gc&`% zJ@<+E@Du%TfANlo1ZQPEHz(^kkOCAgq@V?3jM^&0dsr@s*dIRNp^3kE>a^1aI3l;H z+EjnFdenU&*uL`k`0-;zWTb5Ww~_ayQBhPm>pwsVUw5r;ES6nK!f$iBw>Ci9t)Ot; zf0B`tGL@C4+w0Y<@9aE(aN0on`t|+gYH861eiO)&{RTgS;OQU#Ww{Nj0ly;N$7(re zERrMcp>4^<GaRjZaGwE*DJen5Le9>j%1pQbq=RySs<6gBP*M65`NDyW+%8#WdpxDs ze^=nha<pyxX|A3<ftws4i>xdee*VF!DJe0zoQ#UG$<A<eIYq^brPffTKsMVgiLHyq zs;Z5`RBtd3gQ9i{7v(8nP;>BTXmTV$S>MqibFs$vB~(gQK^+<%7Itp1DlcOwubLud z$_V%Xi@7>GKqCbQ7nhU(p)e_QxRUEj;MklrvAb4T*``)^-;MhI>e3P~fa4Gm4UO4? zS+&><>({#$LAxg;^V|cyui82P_#X_mU+vJ?U;@sf76|WCim+$fm28y(RZ(xtf323y zA$Z`yK@h8*PMQG}W$RiXrK77_IkuV8LqMRUrZzG$QG<xsonGzl-*ux0hsY)3jpdN^ za{wEitufr=SPgN?(+pBnNn)wbdaJxcp=P;q!y(z8bFLE84T_%@XpNg@>I$Q?IZ4QX z<0r-^pjTgBBfY2hDkgTkUv%7<8CZdZgt*E-fus%_z<0XkokC!bt*NP*nAiXY7zV9| z{U-NXg=F7S=Wey~$2>W~kx@}m)s8nd9zcok2-@1p+1Yt>ugR^{BJofY#Scu))Def* zpU>7tY1CGbk+mGyafcYKQ+nn+G3r1Z`%zc-F5WzE7jPzFH8otuCG6O~db-=6bmbEt z?_3;Fnr+(aS}4!Mo$gMbEHr7%F@9rhr1((D)UZBX_RZEbR4RBlsHmr-3T<AUk0PUY zO=)?w`kB{W-P+1VmrijO+9!T~w^UKMsgzaec_@_bLQrs2VH7{yX3yx5GbQG-(u7^E zn^O8_)&>G6=8O+$$pvSGNB3s9KSmQ9QJtlZrAbb}DkozT5X5b$*VO?X&HEX?AYEog z`oQY3E+q9E<1rckG3G0PX@oR28{orD_de1&6D~-vs#XAWq-!ReP6Zk;<_&E|hYe1K zX&eKH##z4t3igdL3FAInylP5O7Vl=205nr*8;y`TWtVM7Jv#cO0u0TS2j0Z3pVNBH zg$Zz~0s^{os3@?xR+)N@9*N#;1Kl~%nfW?LNkk^Laz+yeQ*&_%8a6gg7M6H)(DuNr z-8>=$10D>#mnY^56Lb1Nr{cBPOPQ@b<z|z}5K1*zc#gH}(TEWfqbiBUWY_bE<`C?2 zz-LHe0dgZsHHu45KlLP9Vr@lqcw5<dOPo$blr7Fm-zk-ynv_)6#ALp}sp0S})ov&= z&}ewS%b}2(aHC=T)H-uO8x=6tsL%M@DxS`e)+v*wTILwlc#|?f@770}vt)HQuMNvY zF*9wuDB@q!?-8<*egnE~QF1C?eQtjKZw{d`1xk)6WrnP`zV7a+(JES8rE+RdX3DpR zg{23RfV&Ii?b?#6Dv#J$;Zz<lm+atvOSFHpZ$bH3k9VuBGh@_B>z{>`9XaQ~&vU<W z_~ZDxcfyDxKYeQGN^a;51n(__kFv6ZH+;l+9Of8=grAB(ct3r4Fx{lv)kWhGl#?Tt zL;T3|cDCy54sF9ZF<y}FDIwSQ7?rpbz_XlA_Y&rQwr)3m2{xSMa(-$m#}^q_WBf!4 z=?;GW2S8i*KnIq9e6`boWkcMjZ6J-d`^SnPE?QM97iuPP{PcO6i4BZ>61aSxL`~~k zTg9K6bl78|W4I5htkT^wE<i|-qn@LF`UF&YlZm}CXMkGagK?8loX+2&M0Te?loo1p z&9daMaL|!ca1m2cX$5=-Iw%d};%^%0*s7h+D8QOnn*o&5@G2lkx5vzkYTTS-{j;+# z0Fl14OW3Gh7H7X_Eh^e+sY@x>eSk#FCHh*gck3AdPRHWFV2Oh5B1kuX)*xVz)aZJJ z7hXLxHny1Csx@o?s?Cet82^!B2Y`+PEnHDt?iy~x%*+TJO7%b(HJvI;t>-}obk4*1 zx{L@8^NF^reZB$R4!@U#1T52S)|oA>t#YYBfSS%y!2>UYK+Yv-$6n0B3Hjr7tL<%V zHB}x0Q8Vjf4#1CNbhWFiSXow}tEJVqacz1t8$Q+sdCmv{$F<t;>^+#QSax#@-KrvM zd<jX(-qLkxL=sh1E_Vd9R8Z$mv3@DkNNfOH){fWR3?RW3lwpE&z#R(crTWdP);^wI zp|xI(&)Rc==yIy6CF|{GbP~jab5BI4E_g=2!3fdc0UPM+L}0IeA336asA0%}>V0%{ zJL_ymj1HugNac?WrlTe4v?$1jpqoNLQPGimgn-wo2p~nbmoHzgEiFkQMswQ-hlkTe zcJo-De)#ZVVwkc4WsO0<_#?2l+$B_<Z-r|K3RV{sG`PF#0(-i-rW8VmC98d&5(m&5 z`Tmtt_&tI)Haape-Nr{pcV{b)#<gx=U}2S)lyF|a(zCMmfyM`RrSb72l9jRiT#|Pz zcEEt*Fqon@!m<m1T88x9J02cIK|x7*dD=HS`DJAi!*1`tA1o~La8!N+M6i#KSR=t( z0!+;4urMlmdUNwRWdVUu)pb}S8iyDGHu?e|U`eP&slg9@WH+}1B@YiBH@CP(J&rB) zLwGe9nP9cmN%MeqDsb|En;a{gW;R)i8yR`w==d1L*G--N3?z=<-hpcxjrF~2-_B+? zhk2Eilz?l9({ky1<K5Bq^}EN91t}?&Ra7`3B6@n{gvnRvfRi&fhlg@IuyS!R^YKZm zsR1YJ4<}mgtDDJE$_+Nq2Xn`D*$xUOL=uotkM?mf@bP<JXvajKre8S{UYluIS~8Ur z5Z}?0ldDKeYiVlUZfIrRTqmrpuF}xv0?h*~Sc*)t%}VRC*<=BPyxVuw^z;R3X)Y`K zd_YeC<bDm8)8(bt<fO{x%gtRv?;#N2F3x8X`JlxC0Ysy}TgTgL{Y!-|FC9QNh5^Zt zh&IyG!zX$!2EsC1B_k{{E-tIkV#4sor|Z7GqCl(C6J1A7&w6WRHEZKXP8YJgJPMF9 z8zcKKK{tqOCaT4dic~x=FK~R>+CBpwDOYExuMe`cv~*~sa#3+Ha9^V!?!)Hit4HH) zoZJsi>iLXUa3LMQVB!%pGO|*2K2c#hF(*CW8>@^%uMRGQeb0I+(HbyBii+WFZ4|(8 zHeR4%Iuc$oEFG$Evdw5~?0T09Qas%}%(O-dtj|Q~jnvfqD^c#oOs@TU`0td!rFnec zj`=l#{>{!V@VHsy>!;}h(|i{V=zy|$p92hd>xuTmJX%zhu$iPb1JI?#U3&|JO{Itv z9#T|-34v#DvWklM+;+`nMv0u<wU%#Zh@qDxjnCwpIYwuSRk5(J_{~J(y9E-RU6g@V zt#LIwu2A$IR9JlljkQ<rFPj#+Mo}7xFFoyVa&mGsYAc6=fg+_RE{+d$o|(G18w5Ag z?j953{!_wOBHlbcu*`k$?I1+&;*do^S*{BuZg5?9N|l^@^mqW?ZV7V^3kT<*0sqCZ z){iY){3m;|6Q-wLC%GFlqJWP#Hz&HeRAGwl0dEWVVR{`mHm5Hyt5WQEq-rb@1}qvt z{L7Sx<^&Y+R&Z5T7QnNkW;;WpB_1v30#E|bPq4P;Iy;Ln#2=lP*Hb?4I!q-$1SZ7o z%9YO+8w?v@XQToOfMg3e+wlUre!M3;_f-8J0F7C13&9Bnl1VeA?_4H|WPuzCJP0l~ zU4`|Ey*(21MV4%ALx6EnjXJ|$;1$uDFRH0=>JQ}GUn9N4U6(pIILVme8+9!5hd)Ck zkxsZAvUWP%)a5c-x=*<(QD-3d%~c;cH^jbkI$r4KgQlY1!%Bng1>p6{%L@T54GX^l zU04q6L181SqEhX4BbFmf<K9$MR7AkkJlxr-sII;=Q!W3%4CTbm$sGv=CD}@Y&CkT# z#O~<S?Gji~&<BDl16ncIn77QdwZV3BTWsD0bpr7fs}bsHfK8$j*ymt+GVW~ftg`Hr z_$$twbLs&?)=0jOvv6=oNJue!&^9o}@$oZ$eoo!pv_N|TjhcYC0PP_z#5{(V@6}{w zZ%;V1`r=Cm20H~sWvfBY0=X*G;ACO39yskgLo<OI37AP7Y%C!`p*Ws13()nI7j4ZY zQ;!`mN<*v#n@nVQ<xw<QE}d}BUa1P!{fy(VP$1s+9&eE{1065{03r&6+-(l}_SS<< zZgc{IDx1mcmn>@&AE$wew7R<5;I<0|PTjgXbthDd<gEPs8$eCho|y+65X`r?NJuLB zH+|AKF!1zvG+*Tyjf!zVLr3>B;Afgw*`s=+cM6M=1KWRyI2sz-*RLVdnxSAJ>viM! z5$&>l-v2^JXGS4U#zcKPly2?jCXN5hJGrcK5~y^2v3$BSRX>4=9B?`q7$JIk>6@F` zw}sc{^9_CW^!Wk64x^;0xp!=o_!9q&<f)L7ej5<ZD$O;Poqqt!OP%A9Q{6ZjAWuPr zLG_M}kH<m>2B6+tn~BH>AYU!`stjki0tlUwlcNb3(6~5<)h$Qp9gY_3(_oXxqM}MI zmxIZcpYm5{_DaeyMR|EbBBD!Jr|!?62fA$%=M#X&>g??WD+AO@B<}<+rVQ`C@c^#I zG2nD-cKQPZ!py+1o_^<xf+JNKB)xtZegwKOLMi(hIZ9>Z<fv)rkI$f%hbv4qEUKBN zL)1e<@{w=iVVq7gzxV~pS<9m(^u@#uL4Pr@V6LyS{Z!2yHMCo2$EA<lzS?N=+f0=2 z4kY3+ysFr}JO*OB>)p*1=r#$&-OJ9+RaWbk5)-SkJURr7Ym9!{*75L8(J6Zes*7~_ znKMESxtEs`r357s+-^!nMnXi$&?RUe?6tPCay@y_7zycT((CFGM2W<JfFja-wt|0R z^uflOo$0)|9`V(3pjLrKBiYWD&4W-%$-BeuRga*1d+l3G1@N-3P5_3sOz?mO{&laX zdeQ#e8*Q4)4-t+_2<RbGQxWLEKS6vT@e@vhqO_WI%N4Jr!+<00?8(;zcwp(jx9;17 ze6J{~sMsFwk3kO!4ZY!7NH5BTALx~gJ&nGnL{=`2+Wj#?Pd)<%E{5j{#n#pz1*iY| zs6P={HxxMCn{Yv^>-)eak02n}Di<DbATMCP{%gU9tHDP=$OM+3k&;PQx=UH|b%r>t zI*H-GUI3la$>w~l_x5ZiYwF_SCLl5Z=?#$tFyK4Yq0I#&lw=Hi(vp(#=*(tYc}?zK z^^Qk1|CHo2b%_ZHyyboA;s&7E*h57e4*khLo%=QT%Ht0J3OWWwn5)IS`MXI1IGc!M z0byg4?EwZfLav~=II5OQ7vt~l@RjCjce7KyASD2b(ckLY`fVIATg9E@M5n<yz5b_* zfDBtatoQcgk)42Y=Bq*(6%|p$&JK}UXV}_oEk|{JpW$OT!q=pvz*m)@pAU@dVp4CR zw+b>c%aizvz<xOL!Pd_11{kK&)6!^Yx~#2A1R&o*1E{2gACBGQ2T4o-3+l}Az>)l_ zbB5brjEmQ}xe1m7g#{cOS0XU7Fu_2x$@@qJd5!<kh4B0(=i>(iYoW~6Z3KdXt6?K# za}Xxk;>RcrIe9sN{|CN!VkQ?G5yPS)<8xWyC(0=*N&@b%39QXQpd^a<_<DklxQ!{` z3HTrV6mD`S#*^g$;9NL@zKp-UqVLbV3D!?QE?K7Jy>Hw2=Xf9ZHEIMJL8r00>q<$_ z8{uT6J!g^Bj*czPO2V|4++V-7WeoWNzVHA96XZi5fOri05<uIV-sg$w)=5c0K|q!) znRUc|{iW;yfbXcIHTG<^^Ka0i1N`;l7V4Uydo;73$kW?fhTH!CZd5~_n3@2r-v=Sj z+FGX{KZ+azX-P;n_tpldCqAgF14P=p9&E3z{Xj7hXs4n`Nb>SWT{$#-jhWAbwMXW_ z&4YH)<U#}Byv4twzr66xWMdokm#PK^7W>L?pr07DrU2T}4F~7wc_9O6^Z_dLrjL)+ zeK#REYDn%UY=;PHWrgf|rK-{Bc(HZjOVdT8`>uW1;$+(-JnF?=e<O5tbv-9LTN;;- zoSyfzrBgRB;hl}`2_qw8%J`0nw&TrOxHs?FTLLKwiLmJG$2Sq6ulcir!|-xWP8J>> zZam;mN1~TYO0148g#-41fxW@;YO8a&ebUynUv}AHOE)?q!RZ+G+v2<CeGtmZ0$sw) z(ef0M>sD2u<-Er63Yg0S);BEu1IQ^U*V*jkL`3!nb-f=xylMA)$v{dv{SpTa4(?G? zSC{JlY)v_!q@i(I-}CqLJ1#2=11|e#&-}2kUSwBdgkk{8F4l_`;HLm->^GFi<>XRN zTbo~9-SqV8O|Pcvv6KrjUq@FL6&)S9#|J^r?X3+_aZyZ&)5#DBErC7(rcUb5vAd_Q zq_kzVfd~mm!Hwm)2J4&V*5S=fBLIwntb~Ub^Yn@P6d4aG9WxCu)4TyR9H@M9zBV)@ zd!&uzbB|kDl@1RN@69&qfhI3iRj;#;CCpY&pOCV%=aiMPzInHDCV&9=O1`eqM{r*Q zfuUUDKkpE?wjBWY=Y&Zh-+~@b8X99yK~Ik$p>Oz>mIn>k5ym-NK4N0v5n%IUwYodc zXqA`1wF64nCX4x~=ordOvWUo|3pC(8$;rw~ia0v7p4?I0s#2#{mL7kvrY0;Zs-hw3 z-t-9=3W_F8AtIuk(BVo&g)nguF$~DaC@U~iM>1&i)>;Ge@tnK<f9>4c5NrM|@IN+Y z)C;H$16c!u(WTQ9U_9{;2mp}=5gGN1rJaR#B2bkwDAp_lzDr2<#CB))eZC&I_V4`6 z9CgBwDG@_LPDl9sc}z%1&#D!rRMgZK^~&1nOqFGHW!lbN>L(CxhgM60;RqD<sHalq z1w@q6#OwIf|27c9ZK#7W15KRY^Gsc>$bq{MP$QrvQ&O3QjY(Qcv<|pGKYaeEujCb1 z=Yn$O=Yu>xGQ!ThLq|g+W*}$bqz=By;Vz*21z_Ak$vQeXSPMY&`-R+d5Brpqd|?c0 zYwNHV;U>l=zT!UM2RvEDdcjG63gZGw2oO_^HnYKg<h4Aca&KZ}W;M6%|2O`?5f^y3 zrGeoD+hY@|lcM9Vl$DcnOt6}spPrhV%3<6RmA3N8ctMl&vFBsFt$G{V<FIf=u=}Yg zX~&!SeSLhHOPSw2c^cq~Bk-)&B&Q~0$~r8vq9ULmV6I~^VZ@Ra(73s|poRh=03Q#x zx*FB=<PrEz2VY+lN(afY!Li*@ag)6D^Coz2t7`Q*+p_=GE?79q0}uC$5|T_ZNOFJS z@7M1;v(N}@$AMrl-=K8deS{;OnV!C1AS3e;9q)F`WCo<1e<G-B!<8fEv8s}iUGsT% zc{y9Mwnb<NrW&vLXNB|q<W!<}b<;D*>Ex{>+D)3ecd#mul7V3!pUo;SJlss`^a{sK zx-B4j;_w^r;I)byAfVyhQ_25!olfNoZIe;7@;RSQ%$fz|`I%Z;4*t_?=yLW14leN( z=<0()`TjHRF@x{i;XP&gsz2F3HQBk_pW1ljIu3e)N)k_ghPFRar$vAFr}a8)Y#biW zFyZG<6;so)f4`b%Ht61#X~;+26dDu+AlV*lfdCKt%}xy%68o=T|DbdivOlz%*n6;y z5uV{ipcCVquay^V|B1X{>|TAwtwnhC2t53=1bEcZ;_X2gOUeaG5{@0#{r@I8gYo@W zOAG<jdQtA5*UpB5(?7qjI5$G(8lepTyQMEJE$z|&YU%suJm3FmhPROhj7BJhlv=&< zO$-~pL0{Z(ZlqFfY@Ygo2CzLn%u>r8%b!lk%w^b7wE<p5c-~mH!c|+)A;F$EPeVdN z5=CQ60;~l1V-{vtmp5134A(kH?oAslTmy-<fyLI}jKsOGabs!?i6_=}cP|+}?vEmj z7i30p>IT$a{R%LfZcYax=vGlODYs_+-uE*M$%J>hBOOf5`Dixu|DqK$Iznyb#ZU@* z`rAo^qo~)fl?ybh91bKL{|{SV0TpG`c8i6mv~)@f(%tBQAT8Y?-QB4&NHZYaA}!tB zEhQiwLw9#`5Bh!oz25cDn#B@<ciuQp?Y*Dps7>Ul*#izjXci+&_Hw#af3I`On*uOC z;A{+8ZJEaC@7=<V&;cve-XUsVJ<V8oDBIj=5>bb{9btAzx@fIPc)AYS#x4&ZCAmza zYScQF0*_o|zHfTo^d&qNJ?3ltbj#C}{#!4u7a;$OMhFFJSA--PF%_=6_Q&!w2Ymcv z48s8JYP(OZITX<JOlsLAUP%>|#=Epc>A_kHXg^WV@OW`$;5@4}|NRXN^Xeo7bk+HQ zPQm{+QZjHTjVqm{+wu@mM}R62R1$BZH0xZxc&SKAx_5<PY;4@>?=~z>@*axJ3(>v! z^!mQyn|DXE?kqENR@3H0d~w~B!;(g;{r!B0JN3@HJN>inG^Glx5pm+qfl1>5gm@M| zLRg5U3Lzg&%-FFh(TA=VxdZ7b$vQd5&rYw;(AL*@2F{aK`FVNyy#ll3Q%%eYtgWn6 zlYGkA`}-rer<~3&A8#CA+<clnI3SdioZR(1rP<lpxw*NgF;seUmIcpIlo-yt|G<Zh z)h-q}Q$63x)H1KIP|K6s*%?O6cjDrHs3fsm{#~+To12J{hlfFsad0GxE~3W@UO+@Z z;2#{!IPH#3b~Mm<1sv7N*CFztZe>y`3JN|(#&9VoOj+5eNbLv-DkL&~l9Z?@LSo|8 zwRZ%#AyH8=UCXS{_j(XJDT|ic-3H(7goK0vgCe2Ey(f@0W1;Kiq)81HmVGPsN_hP~ zDN<@z*BZmR8hd<#CS$Fk9U%9|kIJM}RDLK@*E{C6EI@N`di=T#JXfQ3Q}}KND?TR` zC{C_r7ge1Fs^_;jfv#*>2?<9hyPchNMSA+Y{^6}aUBdeMbJyxeit$t9Ywz}tUv=~t zuynOSm-hCuXB&3F;rZ{uM@HndwQFjg!F+s#-!%6Z{X(jLqobg(y^G7uAt0xq5Ym2o zd3zxnBI<*FaEiw7vNyi#b-D{KH#saR36~gKk`l91Bn=yzt0+@`%m4d+G4w1wo^J%v zhm41IyRY$zgfA?OVm(XfynXo<?qkFYsRuT8c0c=nK0|#%!Shw*dvSu{Sn)J~czC(E zB&qp){oXQ~;aI~9Hn!^gwik9uV`D1&T73isI3|8;Hr5>NxwOc7UCBl%8E$Xqk4JB9 z)ipJRIm11B%9NSo@+_yEZ0qaF)h*366u?lbZL?N`B0IaobAHnLH*h#yLs_||uFk+s zbJ(*_6e~0sNl4(74B`*5ooMikNwID!v8pbtyd2$@$X7OxXXWAPQ?C}-Ti)KKEv%|8 zOK<-vQC#$1SvzpsZl%}x;-ZF-U`G#k|K|wP;lb0)tSm;&v)_5&@<xP%jB73!i&v7! zczHRwvgTmk7ht>#X24Nt%1ue?zLk;^59B3>qojkww9w6dX7MkQAN>g>C(Cb<+B>O? z3|7#QpgRSjC50P}<(npM8ZYbR44h!(;ayXe+fSc9eS?I8hNi_-ZRRxJn^&NfyX%hg z>b5}3x0q#L6&q-C^<-sZ+5^pgPF@dpNH=W-HS&6?sBFNz&UhhfO98_N_~-E38{;YG z_3Z4}x;jf#5x?f<n<2t>_52QcVRH_6^5=57!>Fgepc5y>yJ@0y7Xb3=Gn=`jd<N?` z*84bStFV~znS7S(iZ2iS3|B22o$XUnQgVMV?(Xhtc^<1|6^HXMmkPq-AL9O);w3^v z&<%vxs>P<j*IptZ3{*Vw^=)kZG<bET>EfbjCr?KLQ^_3xSYZduguRk2OJ{wp4gkvJ z;enMamY}mHE|EwKDI>!O8TF)Rnbq8M&*dsd0S-Y_RP@MbETmy&?HCaHmX(#8RXaQ! z!N)xAydQMf;q)9iq0e>RH%46}{^w80wqXTu>*C{+f!vx!T9^`3hxag0K8K#JhMkwL zx3AkdL!OUsw{Kv8iYn8<U@0;tW^_8IV{z}%loQAR#3>i{pU4@A9HqdouETV74Gr7% zSd(Oo-6H+{*S7NNa#b3ECO>m{y_<GDKVKRt_4DT>vgUcJjIsCxLRBecr<2jpP|hTo z)#dhOo4Uz{3t3YkA@9IaNoQFa<@XkxStUQVc4p#%ROnaOo`Cxayg|#gHq%Y5vd$dz zCVluMpM!*g0&lQ%c5M%toSb@f5j9hLiiU<p7xmQrrynGhvW<p^_iJFGj;XbENQks9 z%Y>@El%@ql#_G-6_7KqIQB_^t-cI#nWFxeYK$F=>rEMbaD|(7ZYL%k$?AG=+P){4O zs*RJ<jD9{kSoq@mwtrwitJX=JlAy1zTZJx4ulT%W-2IefZ{;8`kjdGhtX-tj-PJZL zle(irwCHSeV^>$Dd1i)!p8jBGh5-5tIHm@#d+l#yG^XMO1Oz}zGc~Dxbb-ypWTmLM z6|AW&?<P%25Ye3;7sr!E(c<gt3VrY5l3ob&HZ=`bs~vCf^iz{^vfYo$%yesjSsNH2 zkA`94;DCO5r(JDHHMMonYH?y&>*iLAgNqx7Jes3$cT!O?F+YC)*viW{V69$}DK||< z^!X%ezj)|bTQgbAQ0uf~xoeUTiyk)`$d=W}5GBE=)xgZpADPmq?`0)J9ig7fDMG%l z!PLmfN5MqbFf=xnlo%<I`d(D@i*%!N<|XPgzsV_$sVNOGRl-NOW#{+o*LRuwE>}TJ zUgmQ7jC2jG+~cIU33Hp9@Zn)Yf-5k(qus7`-bTmU_0pXpP0z;%Qv4kGS&-_GnV+9u z5s{w$a|71(HYif9KP6^PdU|$N*7HlB=`MAFGN()<$Dw3CANic#u3mh+HKiQIo10Ic z?ln`24b`70L%}(PzGJ7xdK&C&<ekK2xZSh4+>V0sL}!#CCMrrwR@TU9<%i;r^>x~* zu|XFNpf=~K6|;ml1hwnwTrGHLXxJ+{5cxD?At8o4=9-T+y-ra}1|DR5+`n1(1*ZRQ z{ViI6fqLPXMqYMiXNl8oneB7t%LR8gS7{lUSSM8tZEZ74OHf2t+bsu8RlbUG?BNW> zB*2tOt%{7qIX-cEE82c>{>Z`EIet`%ki)z0vnS~IR_a4T2?5QDKl11j;^GE3kE2gn z&x?g~cW;%gQk`yGCJxy?xEV7?KZ%my^SqcUFRzr84Ejwsl00+C$Gd}qa-5*;iHkcn zV%po#)%4}q^*7Y(&wQkDD3G)WUF~g0Mjk=Wmg=TI=d9;!Y}jpi>paK&`uOpsxw$n3 zbjdC*H^^MmLtbI{LH*mjjQvxz^kIDOn<Hn{)fmYbrXp1fXqcN^eMw0P&?43lepcnb zUP)-|OfE7uT2dH}&@8CjFVvBG{TkhO;h?|Pnt_3V40`nH6^(3iv!I!o)!O=YM@fEe zV?<nBt6qs%rzm^;TWFX>M%ztbQFQOoOLhY3R8>5Dd`>)MFg37q@d+4=7e|B}<1*ip zrTXq|draf$45`@Lc23UG3C8&^Uuu1PuE#gQ=*o^vw=G%297TRUKA*Q=qvPe<!nf zLeRf<XUxuC#jbIe-Ue1`2?97pwJ_!4VluCH`cj34C8K!W%Gj6>@{T_FVC6u?&v-vj zQ7Hz%dM}`6yQ6sar5NeWy4l%PV9Hsf#9M0}E?DR8nhBdgU@03FKmEb5y|I{>FH$P# z3b<MG6ROm*GGOK5WZd7by#1V{A~zUCdcAhs)bxTLAw*fhEp2>!gPoiR6%B?J0waUA zw59>m1k$ix);hao^6<5fBYrC@U!HgBw9VV7qAq@C$%_Q-rV*G5RhqkT_^z6oEp5=X z(fp^-FcDViv_aMigTm0#+}!JS+{W!KDY;xFqEOtvKH^J?iO5$`oRrzI2?<FF3D=uC zx4N}cK{8qHt4WP!W$G5(me$r>uvLAE>$Wy-2okJw)p}-dY%0X@0HiGrc6J~%k~@6{ zH(TfY<n$#L?r?6NJS{`ChOX}31D#pPl-s#Wp=BHXtgI{x=qGg0pv7X|(xjT}H`@O@ zPiE5I_<c^~@UViH*FDUD@v*VSZEbsbd4d3up>+p-YcH)C;^DTFF;|7rhB_oNpJtou zixDvK2pFLd9DxMpy{jFxeHY7_YsCh$ts){8F}v9zYs0cazt^KJackQr4WqN#e-@6I zfq6$qZuR>jqj}k!J1IEU_fI_bQ4k+Q&wn?PtIw|R#CrVL@0Chp6P>W_{<3xbReWu& zpXq~)koZQU=J;C+0oB7ttv(F-(z!kGN!ZNBGt2Ei0b4-mIgVV8A`$A?)KtDa?QVJH z$%&)B%IMLChU9}}x?g`rbA9X+&mEa<&~m(V!uDGPN=Cb_wP%2}A|@uBFA}J)cNOx! zR#9aoB7y0Y8$^|}TX2doM(7Q!A*G(5SA#bP1zGqzIXM;!oX%FCek1#i&OW|YHhlUx zsX&f*WKfYs^5JA=2VM$VTHj_}7JPalRIwN8US1k(YAPyX9-2d^4VU_#bl)@cL$7ss zBbv$Q_7@jVX@Z&Ykik$=qKegcnhfT1Zws6R`>d1b{d`*+{Gh&Wc#Ws|Eaw)(r*~~P zP&WNE4;-8w+(Pwy&@I@a&9)Z2k@G~KVDK!v-6&@y*n5#S>gj<>^#qdLn_^uH68T&u z2i{?NVcw)qt@D`;PepS_^jgU*o1R`R$7pj{+1fZbq*dz|D$zxma%J}yoLuEkSw}~4 zhbLWmTn~61&2Av0ATF(L4lM2qtRbULJ@;$HKzf*GA8op<m@{Hf@*LvdY#=QYADP^B z@GBVbD%I5!MZfl<M>F^Kx-jO8)CL|w--F31^Rqs3a>Z$BEwkFSH{(Ge0f$EmZdJoP zM6%uLhQ8=O`)4;67Tj)1Va1geoSnc2T@2hzu%m>m7>(js6i+LAyJAZ`N~m{A_`UJG zbG*RsBym0784()xn)xmu{jwPY>$Pl&AZ536@tmHCVg1<6e5^mRo!9#3WDG7@SrN0f z#RH`uSW+Eh(wJbX(T9vYbV!J_<6|_EMVmS(#ph3-8aN1vw{o;N>26z%47YDg_o??# z8qO+UtXx9Ic}9BsM<p_y1|?Ec=@!4QIG&9<^{LR&>#$A<IT@XLn^(Sf_o~~vic__; zv(s}BIh)KCBEm!t4o14XbZ<~2D4PE!eTTlgP@kVa8c(*rhbJv7i;b;C9o_}Xqj7JE zO6M}Q#NXYK<?Lv+l(8u~P4lfZHMM*XTZN_jj`20@=&9MXei9oWP_wbo(6W?gl;_me z3X@|rULBa@I9Jk4fcb^+o14|9k1up|8bR^|GCKR!e)XsAlj8A}({UwL$^@vXAOj{J z%(m^>5W?N2Cp}CgrDt?^YHqnQdNWCiT!I;FO7H+e>Ty=FE*I>576;<;Otn4?221g) z?cAEC=WO}iyT6$A5-SGedh=aH&AQxfOH0C!EYgl@Y9?D-C^Xa)T3X0|<o2l0Was4U zY;U6?Bctx2fjX$xW<N0_Vd(lwOH)(F>l}o8R_0%0Gc(<b``6b#7M<&>xPU)7>82r# z?a!wO_isEqU>i1&$Z%a1F<&-vI=5B+QFeXYttUR|n&~v^@ky7NhqkZ1JxVkKOaKW+ zdgRdnvr?lW!q63n8Z9{??wN%6;Z%D0Z2Ds$A>Lk$2|aw|dv<YF@3NucygM3O;R|LM zZI_fD6vjm*RjRQ8_p{9(IMI*O7&U6vAn?fCxUaH4hGP^&?dT1zh6kI+7xt?I2QGr3 z;Lf34pHOq%_1;4(#W8RnLLeMnm3uyl29Pa;WN{)?<1}HHAJ|K~F7r#0nHof3u48}; z)mKwsHkUf^^K%}tyVuu=ozWrx_F-hi2oZAqZcr0sXRB_NH~)O#p{fdf|FX*K+RS*h zJ|Mt0KEXGKpGux(hEhZDcC(l{9D{|!`G@t)kG1XXQ4@AlRMb<n)49PsDz>*7L)nUE zI^MGDAq%oX*S`kF;4?GAbP)w>$C?FP(TJdV%GE81Y8WZ?ZOE4eDVCj``8Sm=pOMG{ zM0z>YSa|vQ17(a~Kq=*)M0B&`q!IR69>dj7B4PMBQfA0_WNoYG>QYAAfw7OR#ll9r z4CU*a=awCX@Mvgga3Xx`JL2O&wAsq{t9^U|p^hOqas!FAiwI7TC2vSj4&a|}Zf3*g ze$CAl74)BsJkiw35%hq+Qehk&8$(4s(Wu)oO2;f-KbZAsC@hcE(juPKOit1H_<W+< zLeCM3{^|9c>!Bg5si)_5)~X;dE0MSDFE&Ry#>NIdt=ZgMiGh-Yf}%Ckl>YmB&8N@M zX7lSUC*9wXW4Qmq?~#;L9b{l)sIILpw2CiQwKCGtri%h%r_X&T>4PRO8BYtbNMO$P z_Lanh9UwEc&CGNh>W>%V;YrmP1f^<dNJv3m9+K~UYsQq$Q+$FFX8edG$Jxkorb3Pr z9kEh(EaidS8S`pTlNv7fRaJ=)iWMu@N*$Idouil=8~#kb%%UaK@gU65U3|&T<*cGY zcM{*aPmYOXL|pjSkBIhFHg~|1@PP~A^R8>yCyoWI>O``>KE=og_HNxJ4l3*!G7@C% zQ?4}!O3}atzZoRq4%Xb0!bJKqDsx1%xwWx(vVx66a&(G@jEp?nxXYZfJLOb}P4;_e zvQ4iTwEwowy8sA@gvXARlXKR>+1&JtpP!M@(&Z`X$-x3x*x(;P%Fya0mlFvx5zfq3 z_S`u9>a4677>v}XdAh-q>o`}4U+T$2VF}-brcV^f$<rS{e#`6C)Te0g4d&;58QFIN z3M-r)0h2Q`K2Fu{0VV|VV~`hu0k#LlX-sE(o^i;^dXN&)G&#B`g1&|NiWTCi)3eLR zB@>BSwNHtOi9rfX2BoIyOiD_!w?9;)mywtM5koVkZaOwL13ImOLPPag)w;V)-A}eU z<M%c;cPXhdsA#f^Rky}t&-6QW*slp^Zw^?7r>DabBf(6dP9t}#zA4c(wHy7}No*Fh z+0YmHa!fzmYxuzZ*xV)UT0Q_vg~6L6E(lW0%*B<E(&*E=|MUrJP-wMICn&o>A>_PG zhm3+^Ts(e$&Udma1fh<|C;ncVE5OVQ?Ob$rbXG-roe#`#P_7t6{1-1?^1ZU|iv^V+ zce1v|VMVcO;`lfeU`^(<t1CvpQYuy~H#axcv^i7KI|joYuG#?bnLnNi@T>83$<ZHu zy}^kh<Zs`$53L8Eou%*Xy(E0IU{lr7;!|UoWMdH9bG%|#KVczz7xUP;xWGIBTS53( zPmeqNrd8w6S#@irv}U@uq3-bsDLy`ijI1m<6d+H)=DND@IHy1~s2{yRi7Qq{vrNn} zO)4v0Aw>QHCYe;7wSAaJhnRTiP0zHp4o8^VezxJ;tfMv8(Kg>|3^h8<)~Y?(p0WSf zx8maJ>gOw_p7_0|OMRQQZ&-9$B`3<tYDbDXL4;hR=jT@XXq|Vw`gQx5dK{-lhWx&( zpz5ovkTeq<+-J|w4(iSY1-;yzcAq1o#q~K^r>zvK6>*w1pm2I^^{UqTPM$9whwL_i z{`R9Fc%Z-k_hJ0v;wSz6SaF(xBy|^~LkN8N18LNGwU3(+KRN=P0Zb-CK0j%VCsUD5 zL_h6Kb85ho?ho_fJrQ!9RsYoj^z^ik6-r6@qeH-|>*}%*5jl!J%4_;K*D$;D;|J^3 z{A|@tOgTHE&j;Oa17n>`uh_WQ={4Co<>lQ_671eG#=I5lG_>g6AzfqBa<jIx`z)HV zyo>`C6A20GD3esDw;wh^L9BnxjE98<Xo1$l6I$AOF!p$6c!ozvhz9HFXCFvushy|i z_3r2hSnemMr~Uo?CglYDpTc4^=H6tT9v`bp8o6PGn*{H?8R+U2my%+^Lslu&icd*- zi}b|z{?m3U5b^~DLE5U>;Bil*NGeS&Q72YbN(%g{nx-NwKvYvxGh}n;!z15i`Ur7c zoR#5W&;nCYRV6PeQSf0?Ry^bD`T2QzTjcLDWa=Q#O=ZK=A78M|m-Ro))ciuSkT))N zk*NGGDcd9QPAa-5qqT($&ADcx#@$HeA(??CHoy6s0&SuGi8#HAHbRJrDz``$8!MY# z3kA7`dVFG1BKW}KVbT;lG&Gom<P0QZ5L7;&KSPQsP|=<xCMFKavw_BQB$q1yKdYu7 zl~U-ftgZrS1eJX81p8G-JR2{ylsH(dJx6=r;Q6^vo`q!ByK5AV6>3Y$&_zkfgy!Oo zC@4JN-xpsu#g{S2n&ODUz>qWA+`*rJ0tKcY7)WTZBTc1`ET5&3oJb_=FZ;8r3lzU= z8)l96tI=RKxw0kJQ(s7GSNCi@dP@3O;St)=&^oe3K-0+PPIaw2*3#~ah;9}ZTL3PC z_r04pU@$JCPikZ1SVGTK2^FC0jEqFRjyGa(R0h?xtTJ_Gi}w6k22JGlvA23&MFl2- ziyUGlC;xtN;nro4H8Fv|SmWMdrvKk?VrP==-N*Of%j*}SV(pPC)2f<^gvf}3aFxaq zJx$-HvdM9^RcW=$19c6d!Q@T<Z9OL#0X{w|^3(p_u7Kd+=yz>nk_CFiDmw1lVqo#; zqcL{r<~zl$OaK%nA4qrXtVx8pXmm2<L99~k{dr_Fx|70bb>B$G<12-Dj$&-mBZ$d| z4_=aP$^bDFZq*_b1M@m8&CO@)jlC5Of=xWis?MG|jReE>2sz;D%>)zK=SI#?%-!Rz z$K$k2{)VNk^SGj_o!PCe-k}39mqb}z9nq&hJG+jDo&6&^YyHK{OcKs8)K9G8YA6>a z#BuZ@`+hHoR14gi8qc&rYV;5%h=G7ui;oxtE`(%S8rejQ5ZLH%MWF&@Ah1MhxGkOH zP%@Idxi|G~I{AqU{|#>ASszV`hpw%cGeUA$Z!nQH3H%^9P<KWEW}leCZ~NtPWKAbZ zVqy$#Uz_>!MA2;DHURix(nL?=W3kJpXtY?*0DP`l;5?t~lcII@P-EisgR8wOO=!wZ zqxIEg>rR(0vyR~5M#`*5tHX&{>3G8%ezeUL?b}<y+P#4FEr+`kMVOOgUh54DV}305 z*do<Im*!=qF~E#3L8@eX;DwM(gvLv(9N_B453`g<O6~7=@5>JXb0>G2ySlq+B9aPX zG(Fq+fqejsM*4E&j`)_9dG}7$+k013>>h&4XPHF)e4Rm^>I2^iT_Rn=$f?rLGRDE7 zAx&qrMg40e!2l&8ByMNZ^(5g)8Rn!tULfbZPEe!+4gz>lroyTZw)8dESWn-&E{Akt zy#R+VLIhSAf_e`@cW2n1RIp?E=4zFTMBi!v4V-!VobD}ngO5(;0|?k@2<rSq5x}qq zOcNq$0~CWh7qzssmhHCDy!S3b2-|&xuaU^e!_P`nt`5>*@B|#$54035X?7)*m;tDt z=bK9oF!N77anhHvILyz7o6_Pd5?BH|S?y<NF7nM_xw^V<S8^~7#M28oqobmWPOKBO zY!rMinV}-&A+VsIudH?LBfq{&zsl#kf8}GtO^JmXGfU4|k!D*x%cG`|qZt2=UEQq| zPop2<Zj!-)-7~%Ki)HGTQ}xj`7kuMRfQc%m;$tPB91Le?A^VYCV@hO)H%A(o3{0MR z#LRK3egz;)ixb#7jbD?ZXriUOUDxfoxK1t4`KmROB{J%?FJ3d19+mY1go$-RoIb8W z&1vSOgaF*dhPc_;<h#3g_p*@LJj@Qz@zdvDE^^cuBeECEsCg^eq1oWJ-_w%<if@71 z)2VkvL|8SRQ#+X}7ce2O#;h!Rc!MxeXp9;GVv?)P?I2n69FRJ|Cq|N!%16!yL$_<| z>*@+|JY7!~PaR&>%<w%c-sYJ&ci>&TGA8vr>b_K@<9Nk3Rwbzi`Pp~ym5Iq4r0WBH z-CR~^&w?n?ky4U{G}Ii~Xj!OuXtAe~V-(N{Fty#%)~3%(>B=|SigCLQXrSmp?Se(O zU32em9~;AS@)&_Hn;Kwhiq!x(|8lNQWK;}#KwFxh?1r)f(DpFozU=Gn=PKYPB*BS` z4b!wsTT42f{n}0Geo9oNRrKe!fYSb-+j3ra8ga1q&De0|sn|onZ&WCN26-%<#_x)B z=nyKdK$(<_irR$Byr>{BBYSpe$Uk44K1$qZ)o8>lLoGfwwyL|^)?!&JKv61f2*imZ z7y#d&2Z-F!Z~%YhwL7Ck^#gl#DAHMiQCQ^I6wp7mS+`Yb{v$Js1_N@8QVs~v;HeQh zB{f&j4@RHtWSc=vozBiV67g;+Huj8($&;E0Ula+@mzVvOjUX?YnVx<T?hn7XOewNb zE-htSSf^!@EwDwb3jC2U{v)ONO)A#YWgj%Swz@V1DL*fdi0|Nj^cRT?TCBi9xzuLe zmxWcII)!U#{;Z9=FTDa;mh!aSrm8R?Fy!I|iGzCC3gh9Sy{ZrBt|Q0Tbl^qwG0c|^ zY&QVmjirH@fIv0r%Nt`EX;}hzsH}f*Aqpb+yn(5N)%iEZrQE=OyneCfP!k>f#nabs z!eU@hZhlU;(e^zV#Kg)9(LGg>wwOdVHlVw(G%1nDxv!rlyh{r4ISkB+DsKUpQ*2_q zZYlS;24(;jK1QEj$&3KMs?^C@+t{-YFQZO1M%Ns^NHJ<$m`!#)iI{VD<I~q)Xgu8B zMSJE4ZJGZtAJ$I(Us(h~)8Q76Wkk#9%-wz|<!-iemII6(#ilrLbzPS#erX+29*34V z$ohsEDKRndNsrNp+AGkWJ-T(d?EBcHOPah3=Fe?znui<;<L8m=Y+CGBmDkdrUz`z- zdzV#KN^+B%m|9B7_IQlX;o{)Ty6!S~H@+q%g%eLXOJ;l>VDhS2u?05Bp9e_1{{EAY z(7z{U0RaYio*0@7PAsCw&<I6dJ>&}{Rkv_vhBVe7S=8R%(Xm|{R8SA^zoCv$?a`sb z22@Unbt{B|pMPz|)Bux7)_PGRnTynYeq-b3;yD(!j+Mm^QcPrSZjTwOE`yRIL{BlX zsqzKMN-L$dj<!PAOi+*Rm&f3$q$+~cEl%^t*k(Qdu9$!8JU@^29m@HVozla=q3X!U zR>iq<>G#7Z(bCv_De4S&=694|)%K9c=%O|@B#800UcF+v-f98qoY#)kj(Nuu5Mn-5 zS5;X!{MAJ2+N-CC^{tkrL~<-X|Gt!729k-HKt?Ls8Qr1FcWG+V_4aVUsJrlcna?`S z`!`KC2|(Wq>(3M<`P$o;0u;YN@J21J8n_4Z=*;>w21ZU68qgb&6|uOEjY;&y63~$9 z`P8iB7s&-9AuG|vRGn2lp_aA4T}oSWe0q(H@+79)&^$RjEp4&lv(`3o{>~1GX%0TH zGbFMQ(c#%a^{~d$y6=h^%2aJsJiNS4j?OQjMn=Y%SNG5ONu$)UaTDG-W~lc%sdA?) z(mg#T$*Z>Sndqh!5Rfb!(<g0jr+)O<H*%I<TQPTW5tBnbMBY#^2JANQQEY71%Q{W? zuT>=s|0!~RKd_o9m@f7_{d6rBCDGnjvI#h%4jA~jNxrEQY!Y%z;)kt1<8AY!Afv+! z0P}bmfTs{;to2xKDeL|%hgYq6vYash0#-*S4HyKks5ry#Foy>*F*ICmX}9Nd-U<l_ zi1E+b{jIz^V~;+yY&Mwj`HGkZmI62o3W}D4pM>Vgaw^V`!{71SZXF#Q$lFWm3+oeC z)R+9A*Y6qXCw3<$7JnY`-9E(=+IKKJJp>vP+;nfj?Ej3DP)-ZXqY*$6FnZWpY25Tb z@6=YL!)~Wi2_<O|>U7<n(V+ag*iio%96@jYcRN!*6BAP*K5#1^{mNGYixCiXVL-zW zI}W|0{hdl8X!`v-#K7h+V^rBR3mCHVbIoaizK^E7AMuNZhK3f_9b5yRs<wu=S8&1g z5QyG2Zuh5div`0$wk3NPz!q&hN9UOl5ESTfG}w7-2Ic<T>emU8N}2_yal?gItG72Q z7O$IlE5+w+ssLvWP#C=k#}H=NICWHXGzJ!)-AS4=DTfHaFb#gm{!tQxLnJeTO!>Rs zwj9PCAVE>}euk455h0lmE3l{K>grFHQ$f{6BP|_=hWr?T9}V;Q*Jl;m0Jr9~TQbmt z1d7m|92^MRor%a;-HW*6>x#VuK7DHT_4Rvt;M~?ujfn)^x5a??cN<(E(KN=!CGmJ& zMZ#b@va(q*xG}B!U@sOh><2)52T7#wGQI-P!pEmIl-M0CJt^s#@5AeB4jlj*9Un)6 zbWOyS7@yvNuF{N5i+!6@JYqsEH8n8vOTcTZ9b{U6)C)o07v(-_tzBKrcj|?n0<BAR zb%N*5zaAbsbANp&hMEEfdN?>{JoUZ5l^!cK`sslfn9dLp8@sT!=1<&(h3Y3MF3vRV z{(`CU1tq&?s%mUpIN^Ya2gCue4As?-G#LTci<iLH(m@+r;=&sqKG+%B@DUwUEKatz z_yhz<&w_q2Fg<?cy9IaVW)!qF6@P^ztIuOoJ^L7yXrjW>S;~P3Vq#}^f9eM4EbI&o z4aW*v03lfG$dUQ@`sUQTrljQaOb3u^gc1vkj4M`xZ#x%tZYP8W`uctv45eHj#jvpf zRpFOEIv0mE7q6R8gxeQ!ngloma`ssSJwQ)(4%SvR&$-pk4nQ@4`$#(^0aOzWnEAZ> zia)ZLYHBJ$NI(F1ttxYs59%8@bWzc9aTF=xpw8rwBth8o06t85jpk0z%^yJ|9!f}j zA3?X3c`aDG{wBZj29KCnMb+g!U3lX4ngDB@$JTgGTU+GCg*s<~{n=i?R3%-Z_Vwp( z-R&u75I%tj;6tsLSf|&1yYbWZ&!%81g0>$jF%xYyC-*oEeX>0FSH$8mF!Pw`GLQ>Q z5QUm}V37fM21e>_E0+&uNK=r919{E%uV#Ia<zORyaoU|7&?~0GWJ%erEh}4UJ#Do+ zIX)&OAgChc@exm}uD_gxgGZa{)7iGL4v=o>uX*9l&d#^(?J5Ab^g|<!5znaioXMQ0 zqNcPKAE2YHrjC~K^LtCeZFAJe1#dDExzo7NXjQqO0?HBYZD2lIVg5G8BJne=dDigQ zSZP(23s?=_UWccW06?&H5mD5dNrDM_F|o7jt@gL<+lFg0rVUQZ5D96icxQpyETVg| zS|4<C0`u>55|@yoeZ>@2sGeY=%DlFU`)hI%ihgjsucNNMu<!Bk^BY;&0v{ir;v7^U z3koITQPa_xnwr{PUyq8Z?K_h*FgO~mv*fbE0d0C>A|li@S$$p0<6@7_r(8YYk}-l~ zCgnLf>r8cfL-3muu!|ibUDVJ3*BtPdKs%HC71(gf9pc@H+Ii<dn)HDvx9U!T${DPj zYiW@;Y{CwzXDnk01^asWoUrb6VV~<{A|`0qU$(hXLxqivVwZF+DL#40u0Evpj?I?| zO{fqbTo2aolu?5JSliiojl{#J(9%jSDG>yPG`F>#fssy6T<%8?!G*$Pj5TYn&X<<X z#>cxdBvUTW&+WOB>7wl1+<pSgk!%TYK~9Bn?JHsLDDQu2I$U}7&}V#SJd8a<o($`$ z+hvU_zhK2olmsCra&KQ>ph%kc^(Lt@R}eb~*VQ$tH6RQJdb@z!1O3TEoCwRSGN8{e z5@n1K2WgBeKj~DK?$1f!Qg}m*Fv!y7Y0D=sE#(1kcYIt9=%IWKY~Yfutw|s+$;e!7 ziW)0UDl{1Z;s@Hic^Mf8W4(o2XPTS6@+4z&$eO>Q!Eyasd4O8`7ydS}rJ!H~5}A<B z?f#Q+(KHrmK%6tPkkvTmLdfH+tgW}VF5Fo1Kt9lsS#xs2S?uzoq{PC>2yqI?I`kJY z0Si>hGMFvGs-@`g2-f)+5z(}KG9!bkUb|49){!?!fC>%4Meq(h`_mi=m<nFvJhP`w zhvstjjox9PV0uwjR|c&gS$BB2a82U@az||JRwG-GFIjLJdwBF#)yn5E_k}D-@z`FK zNl{yxR^Q?xCG|JW+bAfUc78K0SI<%WTyIp$V;A>(+yu10X1%8yw-^A_@F(3SK+L7i z7ZetHn|5;u!eO0<YTD{Uo5$pX*J(^IagY%ooT%q353WmXIsQWv&RXfSh0*dRg-1rV z=oZBy<A7Qqnf4CK=#R~ch=|x$U^ZNIP^L*vN;<DWR+3<yctY0p!QIXM(Cg-+uxOi` zp9I#5A3;k(Z<aPF2Uy#qqb2#A-`xSWsqe#*qWnm<6pY$*OM(~gVL&=sM37k2EEZn~ zLVv}YM6ULUA+g}o-zT{}kSrt+vin1k7KXO{S^s`_>woe;`+tsGfI1hIRB&)+h76Cy z%&cHw{Hs0%i!a2~B2Q9E0tF4WvA)i3)frco{~}`S%VX!x)JxJQ4}H4DO+oW6JDsJS znV!hYxkFEf9^QHX*M&O8#5U5>j@H)By1F(Wz27@2&-w<f_I4B+8m&-LWmc4NIyyVQ zqg;s5@#=H>QX$(MSw37G`CHf4-d#+?(=%USACG~F2^JD^a4rarZs4FwNnpqf(q}BD zg42+M_T1rwWd8~CyxQSwgyV}s9g3r7KkEc9v(f9PrAFOAQ6BNPgA3U9xCJ2dfc+hB zssQB}Xe=6@w#YZ9440szv!1O{DmGu$29z@T*Pe7YpXQ#;8ylhjkU=;>S@_7*0U{l< z@;U5aPPs+JZg=++kj4r!+FDpR7#hBPiREH{&fhTb>({q!lj42P@vd6g0Z(p9JpaHz z7Rl%M7z*}T7o+)sv$IwqqKk8Lx_q*P!1OxSRZTy#(u7Odk0*lyYg`C$X@E@=;CuS; z0e>>Al1t|$7CjS_tc(n}RoRL^N3N>@t;7{$?9sD&NuV>(WvJTu68SV2$ftgP8yhyU z>S$7>=j1%EH>F6tGZ6$?)UrR@mJI;yKf_(vnp@{!qc}Y}I@sR_JNHdh?q=4=k4<MZ zG&o7IyX`f}kq^G9&)!+znFa)UqxXxLo>%nz>DOk-y8u^@!v{NL_|?}{@h1;}3|3SW z3e<adx(T4k!op4ArYC|Rg~$fiy1Tfz*@Z-it1Yg*<Mmo_a5_=uO~OD&U)t`A=}ylb zc=`XbE0bhh<bQ8PwxR?yEJX*wcR_FQH4sD4<G8Pe3INQZ(R(hOf<|9|(X#UkJ|;3i z-Lb$kNc{HxrGJoYnX0m-B?FOcVZQ5>D!q(_1w_>Zx}UZZ-LVvT6dUWpImPzsRZQQ! z?i6@%|0@H60ii1&>g!ADHi&p<U`{nK@6vEG36olV@c@C}`pz^ucK!k<MHB3tqjFj~ zAZb!n*RB~G{mg-xzdl(m2?C3=vjtpB(W5&3NFB&=A6&xLP%bt$p8DK)?Gn^$djm>u z>ZwyQx0ky0uhY}h=omQj3Nt%99zI40%FWQG3N;Olrj}-L2QeWI?g%cUM|_M%*w?QG zgY-_0<%J|qo%7e^f!x4Y#@qeFhlY|L!L9q6hYop3pJ@rR*o1^s+$)W48(LdiQYB*; zRr!7bP?ILbD-7fa?Fvj_h&-?`pd>29C#*<Q&yP<|ZlNA0z<FwCSD|hZ0YpiEKChC2 zg~jl0KbN|tweX1XI|h;x6KpCn7O?eucxq&NdTw(O=IO9#Bpz*4{KA`NqFbCiS<w52 z!b15nIe8~6Y%fOVLgwvqUv#u+5Y_H$2b<I?ZuGIWU_d0pkUHltEF6##_?=bhD@=ZS z(CXdAS_A|VoKLS+)v7^SU}bgBr@78%emDdLl#p8wum8Ip@mySFY%C^j0#NV*sqyCe zI;hCrTk0@@-FsXJUjN|@?~cSDu`^?yDsKv~9h=PeSkDd}9i7#u;<<Q%e6<KSc;<ob zgC@}b*_1|sN$gOw{7>oqWb@Ah9srFEOaGujPb}}`YE5jW;<aUen^F)y_L&0g^1~Jh z0wKbG*9AC}{{PuF@a|-aW|KP{Pv23p!a9vvCIBO?NRJs}S{@&Q`rj(!?u<EQRT8iQ zMEZOBV8Q+@Q?ny8+G<Lu3<}_9AHz%8-sUS?I{fMOK+t`Dmw<kLHnJ^F+A2ejb9q** z;E`-CX|AuYPu%WXQpBvIq*NgPN?#unz~OHf_35zrJ$(8;{=W*|wzj2x+rhi~<?h9q z3e<QW>KEeS@0PAFQ6t2c4pY3rNs>cXa97YFm;o*}+1@rLb4?AcVEf^ly{%f<tj5Mt z0GlS0^)N%!h#><*2>eAZ>CN0RAy?pIzY9_pN^sb@542G~|G9<dWo6>a%PYg#Rvn16 zKrBWss?*0ng&Cq%W4C`csNh<CPL=T%=2cZta1vcXy{M4^*<W+LgGDxTN=rTesh<V0 zE#)aOd05FaGs*|YU-+VbA2ivw?FJ=BN529?e#n#kZkVASZIpUQx$EDnyt~qm$ES*A z;()h9A`3U^t)c>T44EK4S^5Z2pP`I;QDTOGYVOcgP}U@G8sw4u)+wc=jk#l+>kb{D zh}67V0Hsz}LyK@}X{iA#EjhnL?nuRqc}{L)shcxu=PM?fl)e+iTqVoXc*2B@;_W-2 zKI$n~d~IRjEwDjmhUCCte;MhCg^dlm2yycrMOg6Dl(zM|GyD7EFW)0121BQcftvBX zhX>}#XVElpM$V3vDYsYpm;uuxGpQqHs`O4C9$#7ZBW!9j14YQeFOWeiu(vjLc8CZG zn*{?y0#tGots5^#N4`ti7C-40&oR1`&na6J(}|5wzB(H|&9zpdqyf8bS+IB!VB@pV z6S>{CdUq`ih0PU#YKyOY#8}9yu(0v;SM!}_>p3q4IJ*QO+Pf6>`+J_8S$8Xj?n3;7 zP1PmS&@d|o1SI+47;;Fd(W9cJ4`GZ{JPcGkeP<`uw`UQMR8=sKNzTa=KI_xd!|Tj- z3V=&1Ddt9I757t4$h#cH-y>t0>FI>EZ$2z6VrH<KDmjA5BXm*R+}ukmOI(~IK<)(n zRrLOsQ{f{?&;_sTSzA)rh)YHp(*qQU06#O`|E<r*1<q~2uc&Ab$aVfP>2vVRKL{VH ztH)DfvIK|#+0LK|M<*;9f>d6{38d2crr<{|vw|=~l9#1C{YrG$Cwc}3E;c6LUU+vd z=i*8m=Y#EknH!REWUFhczP>XUen^jFY-cxp=A>trDCP8B-W0%7NMsoYn>@dP@L5~N zOJ-Dgiy{0S(en`g3w*HtTxNTFd;f*Ovc5~3NwEi_FYKQIF5=CnW&=#M+z|)IN`Rv_ z6QncqlfYxoFeYLbr~CS}vNW6=Y}jY~J3R%u!e1Bh&kgDpovs-!XDlx2$R=kDuW!vf z2bX^)aYw%V`;aEni*T}mu(mn%Q*-J)MK?<ulO_vW0g{2o2?iU3xHF|>WP;tk3wGxl zxPW#c#mD}kC}B}s$pw%7vbmi9p02kg>|L8CQ^9_I42??K2t9ponvwzQlcfHwo%Oa^ zpspw_-6Ng(yDq?2mj-@p`$P&TUGC3S+?A7EzFxiJkcfB?npXEcz_<M1sjDg7sG^G5 zI&~a$-pIXVL?R;qHFmg$oTI`^tY9R+O6w^@DOvLH3hOB_z3$7GFIkxurfm49ex|i! zy#^&Er4_9BdEdT;C2r;S^`VR#$Qu#FZvg1!`E&VLDP;%6t#DzQI{xb1i2rN&7J7HB z45FPM(IKy1@eZD;zSp(U^I#1Sp~egVbv4Lx0rw*1a0Qg_bma#JQ9(HFBmw}L9S2nU zc&y7}BiQgV+{6JsE6iG5R&av~G10T*=W@>lMW6&#D%pI5!gJmvM(<5j(gtgD4SUdz z9?<YLV))_bW`Nl!=i(C+10)7;&_^dLm1Ue9?6d7d&@WIX22)>()^UwEshT3@6m+oF zW@5iCv$>h|@sX3jh4?4qXTA$1%(r-SYzT9%9pFA5lKlmV_weqjozPZbg^R$|zCaKc zd86n$)LBIO|A&wp5wY!wqQbo}Nb!3$r3x~!#|fB0?KmNVU*ZOVxs;ZbF%<29X8F4( zhY9kV!<<;zpYL)<fDl|sISRPK@g{))5q@fdne0&zJrU+|I0OXh|A~Jo1)Q{?JjN&5 zASK#>ue}Dp^)V~v{mbz+u#+cvHLa8Z8cuc$MBL=(%uXN?{qt(F-!WCY>qGqSi(lx! zB0|7q-leB^ukpnHsYgB<W5NdD{~YwM=#@W0L|^}Z{ez)1sL4NJ<FB^pKcA>-{rB(x z^X(|%f6`-0p~jE@#I65^{(#o`e{5LV<gPUm)SLI4fBj>1P)=I#|8sGa;r?8_5C0s$ zi0AH+*%F8TXHgbKxX&><wKxYDRED5FM9^@E=dta98~GJjJG?;nXpHx_lm!Q&y^kV4 z7x$X7w)lBN?H#b0Z28~I2IDF?!Qq>p-vhs*cFz&}qqM~xnL5i!ixbqRSIotGmtxG( zF3-;w|NF>hIdg!g2k*a*(naF<<m8`A>&vnYwZ{ocLQiQsJb8n(JzboYQT`+v=k9uY z0k&ZE52T+}kfQirw<``;XMW$Kre><PX3FQjFaYVWvG5MY(L^$ay!H<Pq2e**K;hGT z)jr@YO&;E8TM>#HTIjXv2MAUe(ThK~>F!HY<}tdZJP4k^H^?$#LD2(5W{dS<B6N4D z2gne>+uQq+>DjYGKBq0$NGI|jh;WMmYXBO2Y@+)dqf|m%M#yym`NU1FlAn8=CZ?N& z=k@;_{G;?H*<`v*GWX$>xBFrMrzFS*3@|~e9<Q9+TwzikU+Zk%Mai17dgubf#>51P z7z-B{Ara99UMUA2veL-1UiXoH@13(%1-;rv|Ew;-HV^s6i{s74>r?pc34Hc!#M-Ms zo;F2<eH`L$R4RsodaO_Sfr;c9L0?Gg2|aDSXvPpYbs*(dm%_ovNQy6M2RkrPM}XcX z5`1iOC?4`kkFhpGgBKOwD_QzD<y=LeF-A(&xw;w~3uHPzKEB#}TnMj{<LCZON*aSl zKrjf0C&YgZ?Ob$ss|5}ifDaJ=*Dsb<u%Lc#@z8(d*KaQ_z6$p@-<|c+qye0a?y$YB zYe`bfpEcQJZw?j@>Gzc1dwahMy{>r^7SHeQQTL-VL2#BhSkGAF6kp&07pAdw1^AZe z7!8}Oii@qz-Q(j^5?+_Y))RIw0(=Zl5J?P|siH=f0kHx|8}I8WQok>Vy{xIj`0NDR zt+3g8Wd~Y1RzTDcOlcQ6`Zek_l`r(@c(~3E48VILE|+8gXVR4U`~T-m1g~n`5g)Y7 zC%>lDS=>L9W%q`@e`gb`Yl1+=PEDYtt`6jF=9cEHk`e!Fihy-u`gTOR`syZK4(#sd zRzIr;XR&yh(yaTQ4%_p(epXZ4ScNZ6D%9WqW?{$}C@zswzc2K_-M2escMQNCvXC$< zH~aT_izGyXder)M8>Lv}Dp#lRh7uA0GCbKH5hP-vi-ir@;bGR*)zz9BK9cL#R_t7y zQ>8019FTW~V}OtZ*||!kcya7jUE)<@UjDcSc{n#U0gKlU#Yqk~xg6Cd#7#2jZ!-?i z4U9Cnj?7O2RGXhH$IQy*bC%@#!PEQCYi{BIn9JRo3u+&}TYj=8tiZbO2PkT)DH&}8 z$>8VCA!@LeL(zF1z!s0sz^Ga<+xI1w5pB;;Nr3$ZTRZa3q>&Qe2@x<reAHRZ9NQ$7 z?EmivfH(p5Gl{r3n)X}9=1P7Km|uSpa!JZ-Bz$@=x^St|*sV^xZ@<EdKtt-q7xgU$ zR6jmII)Ey0Wd(8AfHe*(W9)S5pl9vMp8^=aS8D2^6Y&%H)y=wdZmvM!g#iIdUn%Nm z?kM0B$7#s~b23KiBAEVuJk09PqLkhMJ(|gyL`Y=$$^b!mj{m{2`c1y_;hLDOy}fZU zH!w`rxZhQ_y5G1QloAw$6=n*EeZli`kXq~B{|T>2%RW13(uHsEgGK<tzL0KRhL<bl z>f7-w*}s1PZ9Hf~j!~KYMbCJbhIXFb*@KfECC|TJ&M#&0D&TxC%{g0<3;HYiNQyc_ zOG)Vq`p-UwFp2hZXLEGOvuE}&ugG6v%uy1wtoY%6=o>rhyteeAqV{Yvpyfok>AC#Z z;Zjz6pqlA<Wvyxv20;SG^YF1>GVigSqvPADdL#Fim-T9qDV6m$1NZ8iZ7K^oKCSJA z41nj|beNNqWBbnv1PY`SNA6zX55?mkp#=@5clXEs<`71Oxi9+oI2H`0hlUlq|IWeH z-r3zXbt_848E?BQyRk&g?_7D)=PtHNE?%f{tlz8R7tQ50T4c$d{0hy20)D9b)M6Lm zK^v>(J+gy%K?P`~e_{>W7VQR&AqZ@@Hzzuu@B3gte1sps47+BBGi`R?5TQC(7KmmI z10J+QEpdqOEg|vWs&)Lzt1cw~{bJZ~J)U;^sF}&*N<chF{kq|n@fUsmpk|8$h1WjQ zP0M-)+pTe%db|#a{;o{wb&sFI$o7gkdj9&zOt4n>@0UVZ@H(OMqD#TN_ax_}LW`Bi zKfF&y&-8_kiY=UtS#K5(;+CT>-(D0lxw^S=&!N|-9^!q0feRg;Gqs3-Ac4ZWv!rcS zAs3LGOj&c|g9@l3kK?55&VRlgKF|NV<Xj;4tCu=s6B=orn1|Vs&zFAJw637%@91s( z6j<?yWO&}_5D~iXg67HInIuk;T$s#JA+A-BB#Dy7ev(Tnc>}mYb{C1MbWQ<Zz4@Qz zG<?SVASLQ!0R6&1<Nb#<oVAoqCx;5=#JU>d>bsLWwoawTUyMi-{x&;INAoN&JJB53 zis%8`!%N*|4S(|zaB>Y#h)|b1t2dO9am`mw(g!g=C*mu9x0wGl5$Q1=3ZH2WMzMh) zMOD)EtMujdFPT(aHn0;+&3u3~Ty?zFVC%ja7*4J(F1S6;SQ<(y>@2)?5jwPqzP#jG z+J%Ra4mjT4Xs_^5m6RHuqLndxa^vpli;-5>9z+W@hciSuKgBJE-JHIfF0=WGc1yo; zX4cc-P?<t%<SEZ{cuJ06LG|kA^83sLQa=&9rYD(YI=_3B%G5~YOq|xH8qu_qR!TP} z8a3;M_{o0-In*>!M9QAnP{|C?!%eigbp&ej*p}L=ZZ`2{>H9+9h~&@`ZPFq<OQXo1 zeWFtYrlG*uUtF2j*_vLmMJD{CeYePp^c#(re#I#y2JMe|%%hLWXMR)`h$|7)hhQRt zLLUlW`|~vSq+ip}A~byoLa{Nb!I<*H9Z~nxs(cC)JAYD;`J~FhuhOd*j`=2>X^q!6 zXkw7Dk^3iS&l1gJRiT##CDX*}h$CQ??rI;Oe9+MPSeI^kkF1R2WHW8f_9e~ei0*4H zdX)I7n4OaZTyAX#zrYILNh_r)wDZP>RpK_P3D?hltTQ*;hK0-x3R7VhPFX`R;fq}+ zw;h?(iBjvHZ<9wUv!Eo2VCxyr`rvT@_xd>y>O>sF7*kG<{-kPmOYiCckC2R=OryrZ zSf(^x3`r|Lfy>g9&5^$I8m@ElbUB>w3-05N@+Zyx-e)9CTq~aroGBM>c5^jVj9Zcz zsYqb2q|&Z89(MNI18QsaE|tFc0|5hADh@n+wx-QZ<=EFun2<FX{FKuQKmPa4Iia*` z14A=5nM0+9FZz$2_at35Q{nFftXUhj$_0>dX|6_U&bb%^LEF@Z$k`%VowWVlDJAjv zLgvt#&SmR(ticnqGCtog9DS<4#|z`-*1lgQ##)K2C!&&JZSS^y!<>2)6mhUTvVNK_ zj{&*e-VR8XLxE(c51yM;@b!dnbElTCKFsNd?#T674@m15zrEnSKJKi$)-Y*DIW*r1 zlJ*GY3ExacUz%pkZjg6x{1mXb^Gl#a^>@+x(UOno-^2D(t|ys<LN9c5-XYSIfwfLa z@zZz9|F%bI{rf1SlA5We)w~uTJk`@1N`mAea_E9jqW7)Vt~c+`ADc=9#_?HlNVryg z$qXrPkXTIHU^f$7uYUT<Q2oRmb(e#HJBRc?_pp1O<fBd1<4TV-eq#TsL_8IrdovsF zUqC1QM%V(ey=CR+RJL_Q?lTIsye$;FeHo39j6{~Ms>y<y(`q0hZ^P|SZ%bl+^acr= ztM^$}9w*-VadzI@PpxG7e&6c2RiN*4qT<?>g503*?U35T{e_XrQF6SGcSI~JfA-sZ z+<v)o_a<WN$Q<3kfY5V2=5y{8x#X#@NnlA+Js*Q*9qBMgs*V(#b?bEYG{k#7^Amm= zLIM**j@L>;wA0fJc&I7YdbOuwIKrFVFqQA%NS^+sIySS;<J9Xg&Ov*OrOqGyz(`Q@ z3b?bS*MD}HpNkWr<Xv;X;RWRP$2cK@@y8poLUUwLuPfX^3Zq)87GFq*Gt7k2o);RX z4YMkLg=$b`Df=B&E1VoUt@R{SWIEl$^-aCrw7HF@etbZd-vfw=?$syJ>}K)&l&q0? zM=I%Oop#fe9o1f5<~T61iNS(+D&Y}<9((?JE%HmD*=g(TZz;WpYtK#9ACGXw<7OId z)w^QuRWXD|9@*dug;K=Kzjma40YyR^{<69PIU_aZ2m0IF3l}rxV!aDFD3hysp7}@I z?u7ZSZy3dyZ|Xc5ptH!2q3?IcANWr2Wp?{J%*V0wtRHuk?G<x!lsq_+L_o;11Q|%` zfBM_N9Q?77=16&jk0?GU(?NSw3DPTC=(`uA968#sq7LjsP8>;TMkmVi$-PJ?8wg<s zjXgh69X{#~BQ$~GnVIB+X>`a8MLez--&exTc)TT|^;ImwIR`rUBG<0$=xM=>(o;X- z+fAy0;CC@<%M!wcKMs=hbT!R+S8SzSh%RCjl9B25TN4hVn;%Cn@kMXn_;^Zfm!!JB zb}aYO=FSj^TgBKBu3%fW9<K!1)K&$ky#HG*MwdzcA$`u5H$>h&Nn1n7&Qvh15#Vg< zZUy7lq)gWo`d%uR^&nQ%J_v!ts?6->KkxPYHt}e)1gn=K0kz@TQo$g*!ekkGo1u|t zjc)5Ni3EDI>DJy{WyYDfS_flPKVh+wY40kSs}UiwdBhO?CI+OSU+0uiFCIDR*%7&+ zNDZ=#$(_$$#s+oC)|rj;8z##v8brRzXE^XiTAk~`gTVPEZ={UF(<~?6@{!h?#LkQ! zq}2B$)pf_4sCs1lCHnx1bP)lHpC{LxAW8dZEH7z3d{=tAcrAC-aHHFte))ZS`#2)= zw%~Uk1+;<&xR@GjVJ#RYOt^5zNY}lZ7efY@|JQ;1a1JZpuL1+Q6i4s;`Waewq0kY> zQ|9ITXRq9Z&G4wGBFU46%LT_Db$5OG=)OsFHQ>FtyCL!#2_M-+u?{MQ2$$}P#(>m* zHGRmBO4epa0bDwPGYz^8=s?RSF$Z}aalb=lqyJY(qAc#O)yP-3hiSCeKeRO;@>?0U ze;b;<eK9#e8+-a%a(bxb9@&yq$<?X4W3Ap>>+y&SN454xyv8C`FL93@ogD5xK={b< zf7xwN(DSger>gM{s#j2f%UiZwDdnEA(B@9s4aZntkZQ>-zi7nm`3iaIu3#G8AQN$r z0iw@o*Y|buk1eL#%ahd)@U3=lrn6jMZ;O&WbO{HEhd5dP|Do=!qpEznZei>|KtKVd zbW2DGNJ^`0q(iz95RmRp11SNKZY8C=Q|a#R?v71!7W(|o`#j(Ke&dYu=edW&0h_(= zeaCfQ*IIMUH7BbtPpV4tx-6wT2j^{5Qu!7FN=&xgGED-4ex#w<(M06|^KNRCU{M|e z{-=)l!u8Bs`)32C>qUv{$5<2VpPv5~4!tnw@Yv&G?03Y6+?#9ZquVJ3vJU-yY7XTF z?PI$`gq4_?zJ0H4M!mdpG4EXFf3BD#fAtYqFh1Wpnl`YYdM3$WRu+wQ_8`WwV!WMG zeKNpg?BEL@zP81yLBCstgNN@WoTLRjC{a@w{J%3(lknwJ4em2vI-#vpoU+RmU!DGK zH5IYAEp4M~pto0l<z#?X%D|Eazi6o$om%#cn~XfRyI+YCx!wN+)kZBhq!__}MX{IV z-AL4F;T;)g{)p0m170<&On-fzL7D!9(eSISL)93WV%AEzEu5)>dTko~R~4|mD@Mqr z^2eR;KSHZ|bbb17T`C%JHb}FWvvhD`p3jDb%3fLMiE8w>u}hH}QIkxbQq00Z7<&AC zm2xoZLQStCe|`1Y$K!P8Mx&Eq%-11&r}+ZMqZd47`mk{|wT&9pHl3^%qfn#WoZqOJ z*t9y!Db`LL3il(NaEf!7%)T0lX6^bk6^v&lcedN4>UEUmmT*+Q)YjFS(`-LjbL}yu zR!Nd8Tq#}3EjF)o9x;3En4nZ@XeFlGZZ5S~pkvLdgPhT9_q>_cb%t(P8RU1QAM&oB zUMyIp@6$uaAKddFck>TNPYA|W0*=ka)|TFo5F5_USw=){Idcr|cYZF3)tCKLsr?h5 zz7$z(XtnEUtoRb>jrW>+M~8c!qH$S$dKr@9byFHDOMYxLGzJMcxXftL&o$alG?#9p z*;AYFl_m253Gnx`!f=9f4%LQ&mj}UH_#12!jc+5B#b(YgDv5}>T|X7mp9s$B{LKyL zVGCC<*bs^SMFzRTzF4FlG_00V-oDN?QhxbjY0A>gY=tyA)USdEe?ABQZ3x<ZGM55c z+SI2;kl#4O2~vWVezS)sX*c4|)1ULrl?U~6Cca2zEH$&N5h2WN{=Fz(FkSA38{KPv zzR&fw=$AkAJh~=E`~Z@OxZ1Y1isE8mU!H%m3bz4{%uiTcA9hb0YsAUwU5iLW(&8nM zu>X`xjYDV&gJh`4&7&-KbaZ2tm4=B4NgA5exx~bk)DX}#J=!>S`u%%k>R?`-+vap< zciAq{7cL12`;Q+d-QDdGf6zNL+l%++<+lABgl=5^0BAHE%gzm|A06a$*743H<DYH> zEMDK0Rcaa;aXcO2pPR#5#BXm5j{qm2SAN1dg}J;=bI6#;O195+HP9nzJXrGHgPAxS z8bq%q_w>BD0O#~GJG-;z;hz%<Xgoh5q<B+zb%ckPh*zk)#-*#`kzYlT)cMq$oFE|C z++FRk6c}cA!0yE8NpC%Hovz)yx-OqumJnN3Cb+-1zb%pnrL@*tSNC}=rZN+l-qJ~a zf6l}fc^7Yt!RilgvGJC%Ej=*|V|*<-C^5cef4e?LSG{<or$-P8>I^ZCc}*XhS5t3a zy7UpiW*2q`FAo@3VN7$L<gp_67U53j1kZsngu41!KvEZ+8Qk}j6fZSaHZx7(SFh}? ztP(2Xi;I)v;^Jh-VkH|q8+v=6Xm8~`6~aYa#bjjyT9+JCFJ5JFTDn+RD1-G%sOPU= zKM=3WRmOyo(o#A_B}HymQ88S4`bcD;QUZ>MF~)vQL4lo)=GG^(fLMh4#=!?@18Zv& zM}QdbBLOl|d!43@B3lWpb^F(<%F4s=F3rz1TSf=f(^G^I_v57+r`SSRSXdata*lkw zJf<`S#G{$5W;`wf(p++=lpr<OEOO1Mc4#P(pMuHiPy6d*98CLPa9ef)pUq#Bh8525 zskH<(F|U~n8D9F~jtFlh8hltb##xBAZxdJGh}xqm<t75>rmDwd2tTlAXH}b<+61}H z9~eGIs*DICnwr`gn%h0U5Op;dq|v4u8X2Y<P?rYkzD@K-?jmdE(dXLKB<0mh?V7QY z+9N&g;cyx*m^$Sz{0z0gZ%b1|8S#B&Cb#1N37V$r>Z@|H@)_WsJ)0&nT`!hXX!8KU z8o_N)rxGPsXf>R8a?Pf+)Ir>y!Yw%_l!2A3=*&OvTA|_aPsxV)HZ|b+J8$i5dWW>Z zaB(g@94D{zy|2afT;_zYIyO#I%8x{)^prDMCX&leiJtyXOBD>x=jw~E#f5)-t*kV^ z7Z9wpyBLDVUN{MA4t>b)1oGG~)8+X2F(1ZOxxUF)3VLR5IN<u;?x0^hT6o&bu0>eN z?x2{9uD!dvl+DP@jte1`EMt>$oBf#*A}Er>Nd<w8k2m_vX|Cq$!Vkl}babmHY)K_0 z!gMCw+s#53)ZZ8wGzZG}%gm~`%RUAx!h7lIPmE7SJR9ok{dD!LCOSy6f#s+gWIyxV z)#Yn`K1N8hw}*!)XS9-%H87GBNVsheLvU#|^9xgfteCHq{_^2Ecm-?AI97bm&j&%@ zwEX<peb2ZE*39)*D_HIYFt$}O&!5QWF-&dH&EFrO*(H_AbL8c5$ojChp{ebQH*sT{ zS%vO+M%IN%TuL&K9?Z&mub;ovv&f9l)LFd|rE1UQB#|zK?N8pG1A8yH`{`x>ka|)r z_G{q6`{_2$qlb#!R#q}@Ez~!V#=-W}9qj7TR1ilBCw$P=6GGCxlsBMRCO4sD<Km5> zXV3!q+B30=?nO(~h~oN%*b?VQHj>C0p!;X!rNyVE<>jT#MB`tB$?FlQ2ppEbI6ru_ z!>?w>EbCf67H%&qc2?y{rHJO~kAKf^;|lmaiv8K}P%~Q)sP?`jNph)hqXHV=BBA-m zLomH!`gT&ZWC4}(Y&!5^56NQ)p7LqZP&bDzI&i3(DD7i-%9NRm(^caXzZ`4tUA-V~ zRrxv}4ng%SD#paMu(18pW&jz^rmw0p$#+$V4VioU`y>9=VQd*;Hq8~VKz(_%+wiOW z$U3<<1!mPrvrXFAsc*kABKqcL)wQTUVR$@<O<5YtFmpb!U;FwnJ2*J_5Qlf%_4TIb zeV@-BHJbjV5v8Y8h0bf#`Awz-GVMZSn%5lat$kkgAp-InhFI>uk1Cf-4Pq6{Q+mQw z>F1$9+c)u|6G(d=9>y_t_O3to9V^nGRQ@b_u)6QR%IUJTx0hd->*6X8>zrR=PEJH3 zbZC)yVan#hg1LZwoN<xs7p!=8q|@<VV1@eX+tEYCBoQqPPdS65@MBAOvZYj{9xv}2 zYr_g~aB!72^6X{ZtoK%*9H=BNEc^(`Wei<i1y=yB$C?{I_v4rQEml`nabJ<ERyacU zEzfhl1Z{Fg#qK;RruJyg(au43^Zm!LT#>S6fS?6?e@?w`nC)>5wwo08-Fws1s}UhF ze8`(_zs29ouaFt)1ts_DpCpq!NCCz1%U7<FvRnTYOa4MclrEJz<HS9U^JhFnJ~qe~ z=~*TkE4Qh?%J2hD4qix(LvyVkjtdGvoZo@6<H(v$EtvM{;$!Z5^Iv@b=K0xsP^6)a zg_X}?{L`zr!4jwG4RF`^Q4I}D5#fXqQNpF>EZ%l<6b54z(@7xY{|eJru7HY(UcIS7 z)Ftb4p3<sslroNhUj(Zao_B4^Pg)7+_qJP_NzTKr9;Or*EXd0GnUOqHu}!HHDEDG= z7i!CH=<3g$4r_u^Lw1wkX0@q5tDaR76^b_2_;uHF$@-+sNAFJnL82{2?j9kG`Dcl9 zb@!cJ8cQ`=A^8Ra3c`mXmFSB2qId=vYHD;8S2jFu-&9SZw&z5@ixzE8vKHOTBAfWP z?<e|sU2(7DOr6lvHue2kbGgrw3sbX;PXbuvW#xCAo1j8l6;RXNjLv>uSVXfWI1he2 z=HlUDkpt5~8CeZlU`kaP$;iru|Jy*{#vb}pVYSEn_$O4Ic=)s}ox=Q&?$-H!-WdLg ztImH!bIpGEHz3>E-DUf?W%}>i{m8*W^n4kDO@d+?ta$#uxx_BF=HG*df5mC=e88}U z&6P3$<^cacb<*?S(X{x)|2OaH3BxYkRVn*RK6Z?~mofA%c&-%h5x<+F+ICmpmZ zm|?}dMRk@QqfKm5gfs)94?_qxSIYDG=IQzVC$f7+M*e$PdHyc6s)4Wn-@}>6zC%Ky z@jpbNtgNi(&mnBlqHu$1Djd)#T%Ay8-%<Ao30dy@{QDQjjG0L}R!oe}(&)BEx}fxF zf}JK77e~uSsz<lsMN;v1e&u@7x;})Qo#*i**JPlu+rOW6%vhw1py^K;>b<?K?3_GC zD_TEpm|xcE)Ejli53Q(aN);7lHHN;P9}R31ulIK5;y-*mnx9oSFgCt<Gv-Rz>_1$9 zn@_E1CBjqL2d`Y|7bAwC^3TRq@+=Xviuv+IPWcdLU@k%!^L64>-XdpLVsLQKkB|v? zzS2LwlJew?Z#;(J>eD{b!J!^P8f)u1qjoNGZRkGBCHKR}>8cb<;BYw=RXb&wqcSjv zcq%mQROZBTUreLZCwIOruP`+x>}$(p=sIsvgvYVtB^}Y2Tmw`A%xXwxi$fJf5sRVC zN2=kbR#qaS1k+Pp63H?u#o<BzVQqoRii&<hMC;4T{mH!`Qvs`US$X*h-9vs%U(6f# zBo%D620EUxMmU|k8f%o+<B0P00Kb?9>>CiMhKHG@q|!)4v5)oiG~{(vx+tu4U^~A5 zo}E28Qq06A;(dg|ieNUoiT%W7{v^_1u)a$wDZT|H?bz+8S1-g~L~|wa@*?^c6r~44 z3$}?HkdL$`S)SjPcOnMfGStO(xdYYJ%|nNM_FJHav)6J!97U{LXe7#MMyAn20Fw*X z?92j})6&Yfh}sD7)nTL8m2vEf5+@;H%}OaTZ!KA;(^b9CYy7Re{1SHd;EE#C+)`di z`Y`J%Z_)7Rs6`hO6;eh?ZfbV5I&W%qHBK(IjH^8Ckc1?fO+=(5GO``NC93>;Muqiu zFe#W5kubegu<VgMf#7BgRy)+{FuA35*f+-QwTIZy<reV#!9bSY==+Zj&~EVi>aDj; zu=4J1?~dENK^3e<^sFuw=i-M)MBu)L;{Co^03*HnNZElqtPJ3(1KopiGBO+6Ypcke zQI|7|!xo|Hcciq`pap#cJ>x$|Zdas?spLZIHv|HV6yBMbU}4_WZaQ(il$M^3MKYpH zpF%@ZdeA&5eaMGET<!0Zi{Z9WqQ#z_Q){h^c1Q~NzX+|wpcA(L1I?Wh9RI?Q^`KNm zQSm0A>(=VXTPX)onVaSzsoAX#i;xI9YPx}P8v$7>atr5c*OE@IS%Y7fjI8_`XV!52 zaDQ#>E*)GW@gz=ox5}83+G{yU+v@7k0FNRSwVJAi@*|gwjEp-XNO(*@klv*d4RN1? z8H}H&mDXfEWg_hkx=t^Z1_|2<2)GOPzJjnRwp`VSVD%$EJZ#+lVRlE@rGK8e@;_t9 zY%Myfs;xF*e9$7v6X-R;!9kxs?X*{X6GHm>ig#VrD@}|_R+N@b;B9K`EY7HqJIflH zNTyR#dV3fXBz&d4>zjwlr;I+iK9MmMV}*cr{GQ(49+2FyJ<2O+SXo)2*H!iMCDGUT zwY#^Ko|3juu^lV9provv?xLWqTzx!&urzuXn9@t_bj#c>RdRtEr+1u+4Dqe7fFWSl z0|<B=92_|QxdBWOt!jA_{3j3b@bE6aC&q>_5|-iKkdVMTql<_giu0QfL?-tN&Og;z zuBh{6i22VfgxmRL(PEbzj8^;l3i9)V4hFMEHmXXwdU0`*Z9x$AGr752qz71+b8(k} zin4)z>hRDIa@Pu0LAB^HH-0u_hiLTxL6q&(1q5>*WFb++#E0%F>f6GWNqy__6944u zu9Vf?&ur+)p6$GPaq36d&v3?SsFW&|8j1{(p*FKLoiZ;L6_dcCKY5LlJdhsae)?ll zn){)@2k{E=Fw1>KZ_z%4LI1nU*3gv^>>=DN42d#q&CMd7Kg(iUnwv}2c~M=)-a^>^ z3bf`nN8?0nSXj`!NSZj(*{Mj%9@Ab}P=M{tkGf07H}s%aKOZg=Zb};e+zjp8mqCI^ z<E!cJpKqC(n#Oa^Cm%Av1^ctve&e!Yr{d&v_|dUDlusj-{ON$w-^1I>_|s(+Wo%at zPH`Cvxm`(WYD7%t*~VmCsLCzuS(VbMr6GElSAOI+SH1tZD<Ziosi){E+Q)3vBr1Ug z6pazEw-FO1sBVb}5Ug1Z--Fq_axPxD`s%GfzyP#cN82rCm$Y?tCx7mf=~8NdPGaE9 zVq4ow1T{_NU{B9i$gp_j;RM@f8oMFB=8rA8R)nOMRW=^$-JCveX64{ShbcoWj4P^n z7P~Xy%g(~jACnr`;^J+culfE&P7^r(QV%H+q$a#4`kP;PzQE#JLcnTR^dBo*NwLGj zUq5cTMJnQ}(4X0lm9c-ka*;DE&2GM3x!x!2nMoT0AYRF(ia{oP2CMt`<4aM75(Gha z?%jiI+G46F`(F3lPMK=DT&dQ4a82iQqF7X|W;Qi-vowmRgI8He31@=zvA>t+&y0-V zR-KUGQJt@Mup8gD4%-|v+wTlC{OY`!fOy2jO+)jM{j5z@IRK}=J(@*5wHNO$el$mv zbtS&QI^<uEWKtmZwBr)VM&@nLKQXtX!M=+(I$`>(`ZLD-_7xwDE=U+a)C<Qyjo*5+ z>!2|pF<3rujW=s}Ll&hW1M!qcZS26n<l^G|E_rr#wdZy6$1iROOMbu!{C=7I@uHI_ zc9zO$xlcC^%%N^{vUgS4WdE|m&}{9wtSrvWh5l?+Gyg3_`TK{z5!2tF8Cd^7Wq&{L z-(#BpM?T=2e2L-x!FIHT&GrLClsIKb;TY|cim%S%KfXqA(EU9L;1kw%heCc(Ru-8? z6Gn?SEdB<cn8mX513v4?PW5QF6ra}A@yVq^!_hZ+5B`K}@WE&qiNz6aH!0x4A!AE^ z#}W=(8|q8vlYbFrw37VSj?pB%VSNt-ag(;49gBeIF!Ml*pK);?>vM_NHD%sBX9#Id z&&c3#-g+l3Jq@VN@9JyVou$q4B+v4azE6|{#925Vzr(Vjj}ljwQL)|Xc?xahvn?ug zHlkgZq1_+v+ydH<h_h!bg91TAv;5R^8nlu)@`nI_16-`Iun@O1Fz_5spp-~>>P{bd z=BV-d#oVknJYe)(sHGp(N3Uury=rz#Q7a5wd_rcEjoo@J_x{I-$2LUppOX@uq9Ug3 z<yUpWaIelTw0IDEW16zK*lvZl$YFYJ7ebZ*ip1NUV2ner#-T2+ezdye0y8|A^9|<C z84R&NKyz$|vW6LEK;uzq3@gk)0s=`!!)!)}i`RH!NO{ef{}sEK+m#WQ7OV{yiY%-! zl56Woe7Hr(V7h)9)9ssdKU!nGLRGx&w@|yN#uAw?$@2Vi<$Bc`>?e7+*Fu*bM7}De z$^JR!#1CdtNXREYcocDwU=wrYg;Y;MER1MsYl~#D;PI~2H<5?yWst9Q5-!bar~si6 zWY*Ys@2H_RHkO=~c+@53<sSumc)UAmi-G0L1HhT~U%&K*mt0bNsS!gE@)%^&LLV}u zZ|fv8p3?O&%^+vy@!!~fhTwpc6W!CJd6xgy7nQSVm$2;Du<n;_4oSIGx_<agSm^Vw z#}utf=4$|W+!ho(L<FVycvx~o6^3NGyC;D^u6IXJt!7wQ*eI(f6NBSdn9Iw{Kc;%8 zA`xq94{4UW0t3V7=uW`S%F7#lncoUI^Jh_JTqHy2>-jg%roWslw~#VFNVil#G3Dho zcr*+)hPCR@D{aJ{-Uhp__f>1+{{LL9(3|FPwLoNnm^gfHjsg+Rq7@yKZ>6Rt4hE*; zNfA6o)~G{P)&g(5vIj<Ap+jo)aRbT}wX?gqtd^d)GKVs#*u%QMwYL+-wm#^M-=3t- zC4dA$WjU>Eg+i=l@!8R~H}4?E<iKEj2a+qs|MkTe`vMS{?zo(WZ(*cD@B{u`NlB<* zd=5;E^uZ&vjBIQzgD3PD;LhColx@7&V7WIk&C81sfP~>_@b3KCtCy)-YCh2s&7>=S z%gcidk*zSZumB!AVH}P;<3mHQXz{T9g%dPi8De8cv=-nFjPB*Bwmq0YhxnBYq4!ZH zwfE*_>m0m$+wF~t4J~wKM*lU0wgP<vatd+)1RbC)C@<%;+>x|E_l7UJ?GJ!osx0IP zYO4*fPalHl@4Uz#k^?tZBBMS%NzX~FdzEp8&9JI!sN_DqM9kN(7sPxpMwP=DjK4`G zb2*&mh25hhE2_+UA&k_XWs3;E|BX_D)8!PO$#)Q-6t5<8|DV1d`uZt#K2AE%&rCr8 z)Ydd_4fErVl1QM}3;mFpnN^og9x~s~@Fiti>`8`B*UuYS9v<)g4f>o?JKq@-Li+w^ zb4?B%+%VxKn7@HX!t=O__njp2t*yc*1Kz@>rkv{JBZvmE7cEPgn!Fx%R)5CyvB<J1 z3N+(+_IPJ1VOuG^AUhe9+?jZs^IraVOh;uHR9NRHNWk?NI#nQ>0{t4b=JKJ0A8^Dj zXH@`FTsm|IE!8+Zcb0JLC~<iem4($=PEA`!LDRF8rKU#$SeDk-IQ~fLg1kJU`?!Sn zIl$fBwRxI_jjgv&4statk~>yZkIHj%Ki-gX`8@Hx13slyFU6T3g_My~Yl?hmzHu9} zwfzR?WEt}$!7omuzg+)!`u_KfML*9jtr;y5pha`M{2?OC@Ad}}QZ`&Mjq;^a<7($( zW@7U8yw~?*v7yY-lM1Yxq01+Qwf8*u_sq}Vh0tgwJ-yhjKNRQv^A5=RETp@AJ}irR z#>GiXN@mF*sOYFPg+WE`<oI}bd8w&MBn-#K27<cvC2%lZ5>Bic9<Fa~1<9f`2p_0G zTn$hfsN9g@+>pj0BAS|*P>?h&Pfqrvy2tP!vVDGjR@K1BNLv_E8Mpwd<>8}!eRY9I zevIs_tRhEtzPL^Xaz6LEoWT`ue0qjUUW&ARSsG>_{CMvke%MW@&~$e4_2^q!?`bF2 zbam->eE)URZE7fAS^dG_&{p;D-`b3WPzn<DgaIrl_>PZ{@Ac~o(o-w6x2|7@4l(F^ z78R;=Hs;}}0L}2Apu$5_2?=@#;k>-IhKBAZ*7Wy-AIR=pD~^sP5B8O-S2@|)@8aPx zpK_#dFk8AtMX5SFljMrrz;<&N7#J9snNiWMAbS-1>tmcPmztcMj>A!UrvK+#_nIb6 z=~RVvDdxrxi943))Jm$jW=x;)eZJM3XF#W`%|OmYVzM#uv!I|LRX#Ti%zh&_Haz<J zg296`v8Jt!j@k0Lw6xZXUl@rsjg9OK3?Oy@YYY>4M#hPw(+QZ|H8(eh;$UGxqkd*e zN)vQMCDzo}7pn7us6*G`p|W!F<;#~L`~=;lP?H9a$7EzZV`GzbKF4!&I*DYov?G1N zF%c1Q<IUO~-vvcPnrY;7LdCv%KIWjV8~M$}wEfMwJxqgdTES4x{xDtL8Ojru?+l@z zR%Z@=Lr3@i`SV=0rYT6d@>ou;4;%aAjJch$F{bqIdGxEdt^=S_VfHA7%FNXC7A7Xl zN42$XqMm@st&>WstE<ad2T%d;6t%aPoRN`|QnK5;K0CX*wx+S)ygrXVF*PM6C6zXQ ziSqH|n$FJb?-N&Z*%`5S*GVaEU*Fm?S5{UI{r3LSHAQ7*^>X`!bg{-j<g0V{pym*! zU3K!hnp;dvOv_u%pe0TZw}2WtuRtOKG=+4vwHe6)iT-$%pE{^1GLlBrGd<l%VW0|L zJ3dyfytKEs_weBfAtB*S^xewiwhI?tXl5_WwT>Te_4oD3$OJNxN0X?LL`Me&-G#v; z>Y3>mV^HawkifR9jJkaFGCMmb{@uH*#~gyZ%<+{`<tH!>bJQy%(Xj~MX&E@I4$0~~ zGDO_xdhDg!*xXi;CYKua?O`V$`&{IgFWxPvBIF%T!)MuoXPg^fzen)1c^e1Yc^Ko3 zu2g@FyyJS~0U(Cu_=KDz*V!OR@S}LN^L|0+!i1hqB+qTY0db%I0}Mu+5ByhO$p0bY zwWY1C!~6qRQfPhRxjjmY#?|_z``RCL^6&Ig_ZjdyQM98!ZJmJrNn`%2Y!83_AE3a$ zANmKG#9{q((KYGb-smMX+n-tIu9AN@t}yt;^~RfV?!Uj=HfcouCAz}z1cd*82rG9i zdoolTiU$16vL9W#^g)am9S$PyI^oL;Ro%DF50OizZt)WPt9NnpmoHwxPL^4^flIMn zbY8HMtyRZo1d?-0&E`K5?sIk9PkW=dH&y3a)EcI@s8gu{En+iN5<#{<u@AHRDV18V zK0u4-ElN!BoU{tC%Rk#jAXDz-a2Ur`1mgYktT(6Iw6Oq&Iaizl#=pIlNp<HYiQoME za*ThNv5^t(-Fwmswvc(DguERq-YibtU0aLp&zv7i81m941w5r7Z|9vyuv>Ah2z_~H zqLeV%)L73VH<TRQwqxj@(C8T$IM}9FUCJ#e(EC-y`>(6z#r@I(WviklXI%#%9>l(j z=oqARwZ1FWb1y&eB}io#hWG^~1m%bgQqK2SzJq}2etef&Ul@y)8Z@M@6nCR~4?9Ai z!4mdFneFy#5%093BFSW#k^XyszW@#G%k=9;p~km4;7jQ0`heonc}Wn=AI|HdrC*(c zJ>VJ7OiNj)CQtZ_pn4M!+`DtfoQ1MfqAj_55wNwfBaZU^p&|R@nNIgn7_fh~s*j7E zBjr?7OsB`2^MmqqY%DA|{vc;gNt&KBVUCV&vLkdG%G2m`yz2`SfiW)WX=Ti2I|Dx( zLce|c9gL?4U>%+}0QL`W54e541$qE_`i8JAXnS9LKl*dOMq1a`qFBX*KBny0;4le* z9cc;)QntOY_mdxyQ-@g>un+nzl$GB4e~g0^cGI?Ov0Fy~(>GX<9LkYN5>dpwjGc{* z#d&GS)Lxv<zcpuou#uR)B;59CZdYs$dlaib*A0TnZAb{C*uwJd*FZ~vG}f2Me_|dV z>c6Qn)arJNHW?YlBqVB3y|&0u1wDL|icN6~i|&?t7O+a1+?nBI=a2|xu!Fk!Q@+oG z!<;g5!3Oz5H>N3SZ+XrRZ@Jgkvazz<?u;-g3kZq=X!!*ac1RVF<RcV*`>APG*uB!k z0wq!*<p{>78Y=@&alyBWKi0muEI*_l&;BCh!QWAuTJBJB2s`IMbThmpg?R)mS_htu zLGEOb7Jluokhj!Le{y^gTKD9f4#~3>>Lqpt8Hj##xYf@Z4deyiBfHD`=8c-O_>%ue zh~?*I=Wh|*7DvKZJO69_EacziCQr$p<t609WI9r&xH37ZZDdp(2zIuEO!GFD)`p`6 zPgiUFKfTscpbb8KEFeIcE{-}GGNISi6%7x?!Nbee9<K9==m(M2SC}MS<#*v7@IYyF zmt4Arf`*$<7z6_eFV8x%poZQP2cC3i;?#G+Z{!s+qVQNjQPw{wY7;WAWy*0k41yw? zvv$3DX?CKv6~%3q)o_4>Ps<!ilicN3viy;j|5-05=l`4z*gb%^&^T*6wpG2zL<xKY zOv1xTZsNE&%{J9%xjLiZLD~gy&*x11e+}M=hcI}#-CmxaHfcjKS-&?)9mijg*4|~7 z5nlYN<=_Ewz9zwUuwQG-@;f*<m`c9e3lc?aZDWAf@u^vLxV0E3HW>4^h2=kY2~<k2 za6G`l29YMPFVfZ}4Q^JR-Rg^A^Hxzkv@&rEOHArsoZ0Gw><J*gVmtQFclRA%7#JAv z^M?WI>OA#0qLm`HfHk2YS30hfKy4B?$(MzBMCrqlJBC4z{#_>8)bAT5?(X>5|5VM5 zP-pl$GWbjyk_c=-5dFjn0-#_JIjLlf8F0k4-Q3u(uBvHZFbw8G&CM{czWN&NJa%52 z3jKn8_}nrVSouuiqyyc%@jH4{h^6gMfeN(X9&tWZDo%6Ja7tH3+6}l~*Wsqpc^RXW zj^oW=ZrBFZ&8aRw#TP37V79vEQhyLzs(`PE*zoZ2TQbtg#;Y1|vL1r!>2Y!0U$pwl zAKDq9O9yxa3Ma(HX@%VEH<`io@^G9@7!L{#3Je0lv7iwuo#JCQe8)HY59H<992~C6 z<M%tPjZ@w!={x06^n+X?6>umX^^TDdB=YddmEoa4WX-hVf30g+!%k^t8Ilbl6(>v8 z*JF#~v&_Y6^OBjuSlZgv_uV`~sT}aT+8MDfUHp)eLQ`NgK5{e%Q{Ddn)0UxHNBJRw z8rmI)vazkhkthML5CVIBAb)nv9YRDprHv1HFQimdEaM)G1K84EzaEWo5`OOzRNRu3 zZ1=xcRZVEsV`^Oyf^o)BOp;EieVL1-zq^`~mp8=D_VhRXc;>;}5z9Ek4Jt%ad;9Lr z2Hy3{<t8-$Ck!`pjLilglES`Vbs3ef*2fKdQM`5zM?=Gdxc<Itp?q6gTXUfi>m&KQ z`r^R;2m@-@uYf{cVOl(p!(S#X*|m^QmOY$2=W3bagJ0{ss(ZI@lmw@>^HNV3%4+2^ zsZBgF=h^RV)V?r1l^&OcGgI#Ht<p6g@T^ZH=5%>;mX6^P6&YE%f8;V|>$Es*a&lU5 z_j~5bfb)aZfdj?dxd@Kit^&=Sk91+bF`PF3$(QVIJ>$F)R`|K0VK_}?gfKdKtR?K^ z<kGs@cJ@LO$(Y;4>2u38WV~GJ#fu++2Sle>=4km_A&~)A33Bg{`dVKI^I=q$n*h~J z?XhLK^{ST)wZ<tVX|b_{4}YC_{)E|`&O}TodTnWGZho29asRPSXM+3NjqeYclHlU* zSesk={;j*;WXGnudlMgD{@S(rwM+To_X&&fMzStkA|@ib#*cLSbgP3mLGtm+W$QNa zmrmk7X8(y5oBsY8-yA~E-O~>xjaRn`IgiJJzW2w*xo;g5R^Si@F#pQ?wewB5w=V4} zU<{!gc&=lNe<o@I`pTVGL)qH~eLKGbiCybG%nqvr$SKJK8VgnjXeZEtR3}0fyYQ3X zM+ZL;7regs3nF2ux#IY%fH*=sXUuo)#tlp$+Q{|>eRezO-##oZxpCPV5-3iWu_i=c z8N2s4ocb6pt2B^d2zfGAdw{MBP;erdgo|~jNSpX?RbCSi>OxvRo&MmH-@4siJ~gv2 zGW)gUa0v3;X#rm-aa@6{qou|BFzM#a%zp1BJUYi8F7JvaA2KR#?-BFDj83bv@p5Xx zEG&dRL7fY=p$5TSRR9?b5^U|a@wl%|O&6+3_)a7nXSYJsq6=*so6k<x&%!vMaS_e+ zNKs-*1J|3MkTsng5hhw-xw$ouSKbo1K3M8qKg~E>ZZbQSfR0bEx*(;Xs(Mfx67!Uo zjg9Rd-O^6x*>Tjt!=t9z6`GLU*|Ytn%)=Oon1gW-RA%MDQo$~8;c^_JKoU_)FB!_0 zr8V6H0~^zI`G@X@0|dpz@)j1E_se3p4|7+?a;FOfdSQ70#$QRNz;B|l1egkK12y;_ zKgt4MDq_|T9+*ia3-fbpi<2xmEuTo8kH>n<xSxfI_EECQpi#I(*o;P!B49AiJ>4-* z2AsyncS<@kmA7^q)6Sz_*CR$v<i(KYRq$`LXIVC%;|IVnKHiMiSRrn?z`-LwzcrE_ zU7*&_+S*z#n1z_r+O|7!w~$-+?abG~Tzue&C@U!3xihlw+}h853*0VT=34ANA`mb* zAwfFF_NB3a0=812*6F)?ZDp0XLVdfnEvj-*&aGCnHJsgKYeo-XTMP^gnCFZ~OR|%b zU#n}(Ht|w^5#|UEE&+A)esyKWH_!K5BWg`5x36LYz$p}v2uS4o^s;UpE0jzI<rxc& zM#=oWO7o6td3mH8X4`p=zJ-LK+M<;E&o;)_D^4DQ@c~r*%2DG_zX&|IZ8%&KQ$1;k z74+0@tEVuyf+k29k2bR6&97}B!kJrImKn_eiD}^c_y)4DPY#Ro3k!kf7Rl{kk6K&R z&ks)qPC&WyC>|o5iIP0eWnhFI9r9r)o$m!TFZZRhj#P#MS7@)u43|<|6qo={nWklA zWh0;28J?ZSaB^_0EuURP+i|haohQR0ywB!Trve;-{QTbKzRU{S&9d|-XT`eezEiKR zfYi=kT>x)Fs@nsA)|?%0?*X8*<fqM%fJ^D;gc_|>ce2{d`eCL*mzj|<r=YYH&COYI z481gIPqipSBfo;Rpq7RP*h=tP%+-vQb7BBuYebLg4#sdfSrJM6;8$n@k2x}LCtcoT zq@i+^W=Y7!RvC)b5dZSpnli`GgHg^<fl+t9fqbcasjf*~*}$jQLhW1uIJa-V)%XRn zry=y}LnTH5GWHRQ!vJTgXHBpt)|Z--8;l<Isuo1++S(nI?JZ4ZZCsC%Q&zIKKt->D zoz<cg05(o_JM5jE)gZzT<HgJCruF)u*{;4^h(5}ZUaQ2$|L5s0TeQP!J~_-Sc3jPi zOcXz5Qlix#+kW9vVy7wxuF=%Dm*-4nV6^1N*O(zKPwX>ZKCBG%=P?>G#1C->xNvT6 zmOu{o`epUgX=M`=(zzeG0j9r>=V8p3#xRg;*G;jFcV^<>!+yF?s_uBQy=H{^LZ%_p zMS8k{?Oy#bwyzJ5N1fp@!W=+6SC<JuT^C1F$q@FZ#qx9QF1`nYwY6455Ry+%g=E@- zGjLm0cvRI|vx{RZZI-siFLDGd%kA<fsV-*>h^2)Nu)qPp1h5`pp_$M*E0P_yPC_aG zZXi$T$HA}ALrNNpRx!tMW8xjm_;qzxom!z-_KZjz;Dc-}_jMc~C@Ym%*2e25GPAG% zbTh_kPEQ}>;<)Luw}*+0H<S*Ku(){X17xP|m_Ewcnr0zb8Pj#V+g;w7=d}udA0MOR zhED8DkH&4M?M~)}Fzb(}{dfpj4W9ufIn*X@Bq=Ef|D>jh?yl1r8yJ+1(_o<?nGNR3 zV6kLl7F47S_VXK$;ZfUNTMwagn1?*kM(<-_tIpB>{uA}n3PAJPOA84}8m7(9_6{l` zwy)8|t{)kxuV3$#ANz8TapeRnc=4<R<IK=gFsb{%_UMr7XbTdE@w162K)<SStrusR zS69Wvd;k*RiiXlBWv+yb``q4*g`*`b41i$v`r9k=3JNqx4)^!VQDgN6{m#P)N>~oL zu=-L`N@y)XS)#aTM?@$Ln~-fQ%4Y1g=Mshl0X~~~=WqNlp0MUwAEL0^aKnAZ%OBu* z-%16RlJo9t;o)fA@9IbJ&v|HT+K)G*v)|K~<ggy=OjBFCRYd~|C<6o7+1Za+jg%_Q zx;dQkqboyz0K)5ZY=^9QGxrepEf)P9E;W*%-FO&~Xe3l{M?PK?!0oK{p7(rAIS+29 z4`QEcm1J0+)-9Vr7_?wH#9~kp#_IGtzA=vXXeF-mh88q`>ngN1H_!X@hh!<F#m0VM z!>?r4&^*p<Z*8jh#_lp^VdM9y9iLYHl*hfgv8AlY6w3BY6ckBhtAn{8J#^Y4A>3VG zb05d`(`DDH8*w>ZHldQP6AfeB1IyXiIKD@BO3JqPNK1Oa3oSh}(_wkFpF)hJT(eda z5zf0_e0oydqrVGQT_HjNxJhE9XG6>FfEB~?-A-qp-8?BIG%XR$wReneLCF)4r7^99 z;4s??RZ0gMwP#%Y{XQa2YXr7x(FT<19YY$3iKC$WRep4o0JB|tbinZuZy9+=b1AYy z^WYj>A1f=6TeG)n3d{z<#M6=`363b^=Vu#qJ~*8)t)9UPjZ{ML4?MEQJp~`!ZV6|R zP@jbP@jk1eEzq>_)g8kl87bJw7vucSKxq``&Yi8&@$%8!WehY`pZh^OaP+O<&$$=b zD4(eVr5&feMP5se)mUBK_84BHwX(pnG6N*D%c+GZ2cOCQ#%tux$aXG1UHDU@q5XBa zGl8UTjQe+39QH0cMa{>!Xb)sf!V#Weokg)a9iQK|!+k6ObXr?aKB9Ova$UAPi$v&c zSSTI#B4?bAoGE~TDx8>F+&$q5gLfC+ceZilmzHkymT^#k^i0FteCkVByWvRQS}nf% zx>PP@c^DWP1$-SU(i{D94;LTSCAhs^T{yawleyk%OXk1XbMa3%rcvnltqNJDhXqCv z9v;9bdRk=p1%QN*pmE28pewi(b(LF7v4AeNcw=CBzoCA{!I6GEfeYo!uC8yjB5KhL zPn}Oc=uwIjk;n3Tt9|hy{v}hIiDJ~%{Q)bd`svnWVDfaLC~=Zhvc2<<iOmn^$XJ!u z4Z@e)hBt0#g|<`A(?^oW`eI@PM0)v2ysg`304?*EzX=dS*;>uO)P$@NfXr@P@ibKw zvG;BSVLBibrqAY@SZABC<UzX=Y7%|Dz0QY=0vJABr2<`D2!~U*;#8iq8TuIK2FK>~ z&Ubz3>gnBjinMa?1kc7Q2ckF&iFnE?LC0<|k<0eo`cVEj_G<`4=nP80;si^MuF{!1 zv%Fk&Fp(@4gRsBiWN(?&xoB#C^HEDi1wifszC>iP9UT``l^QFfj|wZ#5)u<r;`pjt zeoH={sXR9Ka)#EUy}cW^Zc)TmyQ9XLwql$QU+}WcGzB%Mo*l)|`B$RGhG}?JvbU=5 z9u~7Ei6`8>qe2P0%%amB&b66OmevEA(9~WMjxu`g6Cyz8u{5KB(;Ufagoo`^IkyY} zpMHKxT-+n>laZy~vxl+qHJb$m#|~F-IbAtg;}$9~9F$a2dWkeIKCZ_w@NDSnI`7M9 z88{C>50XgFZ}fGy3{~HgtyEcfZjhjPW&<)H$NSg_VWH@@FKOBEWgOZR*bq5tE%*6= zigH|Md{T^Z{*o5rCMKrO7a~pDg0*s$_ECA4pZH8<eL%bNINd|>CMCs4r}jR1k|P$; z7sKsPBGMYYqXQ^m3zj?Pn$|0E5Kad9-*p?4iv4z%ll0~rSfpcxR?Dyaf2z^qr7Ks4 zFN*APM@I|yf<fN8yiA~twKbqq&inOueS9!z@o3n!Iiw%5+lBl1q{DkouQlI9H+h$@ z<cU0n`{33{))sL@E4}JG-h6smn^YOeoghOE%u4a3<pZ}56<e08r9exEP9P16HAuV{ z@cV)1e;IplU|?b1^>!x|k6K$=JRa{hyr{1BBjN7RMvW=QWptg-T8rqM9LzQ`(RJ_M zeU0X_`x16vM?(Y19o*I}NQ!xFEv+Nh%#JFk(cdB^VYl}<cwSqR1{Jg(?FlI;G@R~^ z0ROUu&%wbRDt%d5*AZP3nH|kdO$!xw<n@;>Ai&dfXLC<mxX#z<v&Yi10Y;&BaR8{a z-6D-<xA<^Ckm#o}nAp-F2<4IU_KMZ1DGtK{Q^@9^{JeNyBg9Gwic}sRVYPfnY-|u! zmPqZ5=Gu(VE^CYCOz+iiZEXcuZT%htnx(v)v-DZ6Gj~yV_}P=$z7A6w8xtcVBilFp z{B~xWCa<16t+pT{jw&lFTkMN@65@eLG@zyMgoZO9EFYh9g)OF}6lKnBqki&(q+5}N zSrEfUCdqh|aW@S*yl6D+*Fo&&8Ke32?IGX~O-=n?GZ@o8E~o_r^KHlUVidbYm+2(f zHP_Of-8nE|BgDlOLE_UzvP6DJ?_R_t84^MM_;Cp+sfk(h>)OPip6z^u*RhR$#V<s_ zk{js3Xhocc*LNi$Cu2Nt1EWF)DoP*)RHR8ZK<%TBOsvD@>GH&cAQEby&B6n#tE*DU z1E!1@rE^nKazvE#S$Zw$Rp{s+KGcJD8+COTn5CTgsS$|2D6Hjs`AVbOtIBRK$2uNZ zS>pj~;9hX5OrauuV>|tu<04&Pdw`0>rfu+<w|6fKqmH2rJ^)#=vUee^*QyhJb2a4Y zU{!VUwGzs#lBlfo<|GjE?}c5NnX!D~(rL)5sWAh!cX$*I&%mn<x?eCz3k-%l1$pz` z?|uKJlZ#pvDK+9!rNifv8L(LwG9P|&(Rlch<v}j2tgBK#4*N-ZJ3EVGV<Qi8R~I@g z)k{jt%6gzu*<6)6yl2kczkMpX-e36Hi*8nROqu|-(h7R<r$;CKnH5`e-(S3jG7+G4 z05-kVQQ<P*dB7CjayyqRm?T%yKBVyrvgf2rRwfV^JBI!Z-YG6eDb8y<e#H>|+1Z2^ zte3j@iJ5B$4vGTqiOnbul+};#5?nriYbabdL-Vd<bC)h8tQnZr)YNPpT%0pLrHf%M zX&Eh*%~iINE5t%mRZt#2UXB?**x$!~ZD+T**j;b1tPf9a8Z0GrA^jiaEwG?6QLAZn zvR{utbais)yu_uXsNCLLSEMa?`LMmc9he2lY1B40+mRerI_;OBmuUlnKv7YmLgSOA z7atLT%y4pY!ZT~xeyO$P+2|wP;D}CvQ}^*R|1bhzgZ&}5$SccPTfnWnib*uGeH{a? zhgzxiY=K06K>^nQ`-O>LrnhvY#;FgiekD6l<XdqVjbGh<b26D}f}uK2SW;QMlf^b% z?%<&F%KrDlQ(*L8yu=r3)uG!GTB_e0b57O2peBz3LQCbkRq2H4DZ2fETHpEL#sACA zDiIc4DLKr4i0K}{K&^N7eiT{rg#m&cfJ9|`&j>HoPH#f~g5mc~n7p9C5n^#V-Q^q| zX&bl{5E3WL7`fQ4uP*m*@64*2t6{bL{{4GU@m*2pH<%0KKH_4turiMvJcIpZR^)`% zYQ{XXTLGa+mCAbukb1AvxB@I!x&Past?f5pbdY%=EjPRDs@WgdXo9WX)RcY^`-2#I zAS-qVkPr~GIDR@hjL6(uA5TAXt;sX5jF)=)wDg73)`i>&ZnV(g`pjm^#ivwQ2z|pq zpadWg2+VrWCM<8pa}X8FMk1Xi-yiYKiPbcBmx>h6n~1EXvZbbEjO6K^B#JGw6Nv*- z2r)K1Q1q%LQ@_lmM(J}3{YbI%^BO`g7~`DBXSQb?XG#)hF27V})G9)DH(vhIy0-jB zuj2TXps9;a*g$XU8I$#hX|>CAonN3}Eiy2WIXc<#yfC@xD--~nqqkj5(j_gfZ-V`N zh*=}UT&pI`i>K?jq1tp<y!R-!t1IF&+a^?KfZ$qg8&nBdJae^sK(vs?hf4GQyHSQP zEgBknJbv;-_UytJ58#}XW%g<3%%LypdOn73N1gPH=rm*JqXtSb4W2Ouf0TvQBVeuB z>~A=q2t1<;X-@m$T$!QP3Zmw^*$NQt-fA{7ItZYY*hOKj@XTL9BcTQl^w5XZw?u$J zLLU41s-Cv?6`*>y>ewgE09fC970XxW&`xLDt5nM#t4~!|nAg;$p^OEjFqcqCN4svv zi5ANmCUf)n3>I}Gf$HkCxzycjqnx1>v`?Nao`N#}edCEY+IqEy+ezwM^p74zc}z`B zVT_ML|Iv()wCB(74`RZK`kPTXBx;XsS0;Qw$!sF~6UGmc=$d#lpaAJfK<R6iDr&9o zu<zu^9cW|c^|h6rWM)J-kI^2CE4V;UXlVh0<32m4QI!*9w|%EB;QqNj_jsk-1*~X8 z!@`P-i(Pi=+t-Q}3AaZpKqBkAhhQQZ^Z_;n#q6}El6NiUF(tMOiAU?`>FH_fvDkI> zKztnJk(0}WA>eG)-__Mb>&R*LGAAgA1zS-`iE%h%+~ih^@O%J;7?k7#1#7~>LhSL1 zjSuq%sT#Y(8l=A^G2uSh_3!WNy^ZZ%8_r>c7r<a{jdQwLEdj~;I@?Qx6!qPfi6VJ* zJ0^1NtJ??N)z#Z^yw2deXv3?%+s@O1^P5{^ocjR+NT!B^N5IiwC-Mb2U)iLb@a|nc z<Pp}$eIdw@*G3DyJ)oa~$z&|ovBI@^wyxGk<=|J0=g+K-S8{T7+{*r}f*#Ot+B-TL zP(3-qdURZMqVY<HBNx$CN+XBq=UteUHL-n#zG7qO>-gM|{XhhifA)tAM8<5j^fafQ zQM>?o?XXBLACHvO)X>`6^^oG?14@^}k^12fNR(}lPG{*|3JYyI7A>#st?N*)@MbB~ znLwzhvfH2e^5vn$Ga|q)T=q{$tE(S*yld|BDO7v8KGtk+`{O&-y(Fxfkw56&nMUql zi;M@*CX6|qRuq(|neeqlyY_t|`mj3-$4`cNA2ietqh>?KY!4FHLiMj<tzv9o-MVow zemWi$G&}B$T8D@E+U3hm+q)czl7orI>!>r--1=Cth@gNUaWtz@u(wDheZ@X+ahYsV zH!xdZIyQluy`Qji$>7~PK{4(u%SNvR5xE6){@BCJ(?P504LZoJ=31B4U7QwwzV@tk zuP@AN*mu0(PY0^iD+8XWyL@tTiGniih7ZnLEwTFTz*?Tu##lAy?ZG$lW)ng?A)(jy zhsBU+pRa%x?G^EWZm$xP;h4$EUETh*>zuA$In-Tku+UKi2meH|Of;?&$Q4Zf$0yzr zCZ!&nXk1*-CPzz4D|fO>Q~evHvxzyKyLgW`>sf%L4%xe!<77U*x~-VHnzHgqzbq-! zCDrw{sakYEys!G{9!z5mdn^D%p;|G*Vsct_@&gQ7cMm9IG7pmgn3Hf(N}xZRB8@38 z)l4|m0L&q-9+Q%c3}SuzvvR+X^6ltX-EAwnNmBVI+v=!=uJyOwbGzM%ZA!U1xf+ua zyeFX%A=Sqt9S=@+a{YJ?r<0&r`V1Ar^0}AQSScjhS)5ea<j;+s$o^<{-sI&+4x!Um z<SWc<Xwi)gNHVT0RMOVA147X~(QyMk|8mH4fbE%*e(v)MJpFA6UdNMN`B6V^(>Lu7 z>y_u#+o7RYxl{}Dj5LLcqB*srHDD@2()|Ql+5li8@k^4SK1Vz#W71X{1(HdI^6X9k z=1PVDW}(9ax$CgErcySe?f-Kv`Wh58kKi$vlC(YNi#5;A&8evt9E+V?3ySVu%+qyd zZ#*`gY52wS<rvbqB8}-GAO!&v2Iyl`HJu42<wM8cK}&);oY#5h2u9Wp5a}5ebH$TV z)6-!NS|>Cq>(F*Ew;cd##%+J`)RX;b6vUS_0W5%Bg~$g&78Mahn!!MnIMn&$U|(Y0 zX|pz|xR@Q-w?KKf;~%UOTOLz6mI}F>xP~N4aX9;^4Sy9*fYxGkH@d>~J$Q~^{Mv;K zSX@NJ=-pR+=I|}AoXU*D?nUEERt{Ye&`OHpRoEL{I)fY)dZ3=r7Uk!&9AT|E9|ZB+ z3`I^xhlk%ESKNE`YOb~bDxXsR5fR%-5<CN0X6YJHX=z{BoKe4_t7LgeAMju;Ej}2_ zHZGNx0Gl6jl)KO`PeMYY8Oif?cFC9g7upxG$Ck+{3nhLKBv*B>Y|EZ~@$zbH5L7>y z^m34cgk?!tWL!3R=$mvM!9!Lw+nzL)gLw!7Lg-ZYH~iMap;%#S`bUHT4UM9@#mU># z6Oz1_$Wj{<HY+5Io;PF)f1Qv-b!M-{+#<eTKN*VKNv|uRt*sl*fq-`~;Cwl6rL(1l zs)FssECoY)6LkcR=Tf2Z@Xo=!Q$g4RuFZ4SOckHoc{Kr+8ll8)J#|O3u}eg@8xvz6 zuc7wrxX_@Ra|H(U(aNK9IJVr4rR{<!nn5HK7-0j#&c6}k|AXi5Alx4?Wo}nJ{p#u! zHzg${R#rhKI`uNMN8_J1X`L+wJLBBFL~e=^{M`|hEIPSjr{h6z0P5Lxf|O8miQz?o zgUs3XeEZ61VQOs7RM-tF;F6O_S->}AUHW(SPxO)#YOdXZPH(3O#j669*Q4W^?CMtv z3JS+XX6Z`lh*)TEGv_w|fE4Pz5MS=to$ut&*5L+P2W>r1M_%m(wNOdxV0wEV&5r2# zB$k^<@SJNF)VVE%Q#*MI%B;^Wb|V5<fIZ=_%!`8Zz1BAh;1b+^t?Kkd+GsPPd1xrm z^M)4m;t~)MK^sr=Y<i0{0M$_aBE1_!KybUK3t<q<g6kj9eU@u8ZYHMYaH&e-_e~lN z?dR7W)_odCrs|AT-}SCpDVG~%uC6)^504EG?+sZgbLOp;q@&-xteAsR)8KOzwH9<G zTPO9a3&b{K2pmUMleSw#Z%1x!%#g9O&$G|;t2-qnB{`gwi0SCe^|A!L`aDA}B1h|` zv@~D(Tzwq++7+pT5T5|Ty?;OS;)S!uzB?_7Lqi-+<>k4mH(|i0mzS^p0$%aNJ(f#G z514b&Tn`L&hN{?yD0@ere6<l774>lVKxLq(f91;OMBVu7ZXdUvhl$F)R{U%w=<gAq zt{k2DleRR<97<}R-S~y$zqN_uy=-WwcQr(ci&aJiIk^kNQ@)RXcmC0*l~p2q{wG30 zVl8crfr9ZOA!&yC`UC_-9bH{}I~#qH{Y62RxrvEV)Ir96qp%Uj+?H3CU!7h}N=O*( z8v68ILjUwV&v`QXXWJejiYm1U5&djhL>Uo(^}XwD98Y8b|HjUa-n+Lt^KTz~x_q$$ zigcx=@){Z>)_G}Vca~{IMI@YO6WFY*td0&3;j&197qxyW_De?|Kk@Td*EMZ4lSagg zYv;GKRv*=4detHf4Q0fPf|8R5!I=A>?}q0=!*@?eQE|}mbkLdAy?nizTY^<PTkzBE zF0yx;e!k{eHY(YU7}h_F;wP-Pp4@bMl@w92Tc@7={M<2Sd>wyzxs<a&`<<Z2ZNzP6 zIF`q6^^poP3W8+Tg0iyt`RR(zO;uGfB%ZT#OE2QW7M2M+elpXAY`--)$5H-n8#1AB zPEs*v%Lc5a2IKAy(fdqoZhXH_-#cHe{!*>|=u>z&p&tpa$8DtwW}UZhFMCU?se$A3 z6JCB+x3{<fQ((O@TMFtN)6*b>P-i^aIBgNuQnC~-EX`5f^?NCs8lKoUB<R<#w*dQp z6;`sUmC*OBx5E|DsvKFFj3$Uy130V>6}nbGEh<=IJ%j?;+A^V}tm;!{X0r37G9x;= z;s-W6(=z5uAoYiacEHGYXJkZ7cU+po+Oj3$<1^QmWiM!c6KZ3FUMB#HjJ&Kgr^_UB zfq|~USxw46Y=6LwWPY_<U!bs_U8>bv0#zsN`L`bYu|~?)_C*fLN(z9(8#&Vj_m1^- zG$60v4Y?!P5V*iEk}RVoBC?!s5Di}MlF@IBoeTU5WBdwv!$i$2b_cSIb3LCrIp!I^ zf6k{`T|3xXRn<{FI{fRGol**1<2TN(>gyNKwg+$Jz3*tbh&GoSrgv%nT})3N_$ISE z?b&KcpIkh1Gw3ti+1jAWd|Yn3m?lcWcYSxqGKSrutE1{&bK-!uh#X^BezIO+5T$~& zbdc$CNkpo^N}sB8#RZ|p8&)mho1Gk`95^^8pDw%C!wq;7Iy*lvDzXdr*EPv2HMRcQ z5sz9CgMtvz=j1{7IeJ6#&6|dTbk3yc(Zk({5IV(8Npcxq(L~3rb*+o<H!kD4Ou5Mz zuMYWm#|F13So<~B51XLY<aHlBBDaY$Us_tqEZ-~e_8#8nlh~7jH2=uj8dHLrWus-7 zq?D73OTR$mX|lUf%PfTf?j6GU#l-kxQ*(2>)%-%#+8{iI-09jKJv}Og#@*^D=i4L| z*Qv_<T4t<lMN3L*{LVJlQ{}&@*-qvU(xHd4TUf4*S%T4OVSve~cm>O3XIqAEx30t& zth34b%-LZWcj~KWA&!MPDJncR5}=k$UH9U85HvZ4gf!S#m^0NU-Ga-|LgVY(MnqTN z*hx;a+;;12|3K9pPfAs18$4W>^>V+qsH5`Y;?1YsVK+HOE$jF2Pq%A%v-4d^-)rjq zB6#%Z5!7T==<vBcMbaNXc+k*Sce?L6P69G|I(1x?dc8e8@)-&N0THs$v~mYi+(6CQ z8Qn*ZLbv^7th?JM@yzKhhoM5{U|ZW}H5SU++N#A`v8p93$>~q)ekl6&%O4WldPzgt zjNnZj9UkrTVm7|~wO1^7H}#&7g&H%4t?aFS8l<~|_GS<Gdw1^!<>XA=AZ0s#3xv$V z0@lL({5Pc%(?=fB6)zMO&FuIW4e>9xJYM+I7#}U%UiU%L+S*q$yQreVw_1afy=0_O zFo-lKC&$yngO!0{Woe~>e!u&Zjmz2ps_m_#s{GcjVH6caq(nL-q)R|Lbkp74-Q5jJ z2nYyBmvnbYmvnb`cXz!D{GD;mdA?_S?_cj842LlGzW2Igt#w`Vn%A5@_4TjH7|Vg$ z^!4>s8>vVt=Kj>>kp#B~?LAfzr@ey#Ddh)pcko=?y1Dra9l{d0u(uBs3A%CK0vF<+ zBWY7p#@;`)pLq`i<I)1hY{2d&@HREw`SPW?gI_mUQc>||R5-)gRW|@+ODC#NomzQ} zHalZtHd%1`fZK2Puz*5T$MW&ea5!)xv$gZLs4s>gDAPN(ulKy~roES;g2oF$eEHJB z=2%u?+|a^AOtjknbOsa-Sy`*($7N~YVcT*SC@H$a!j_6*kVO?~S<%reqa#d^As#OG z_keh6-qx;F1&XT8t&?Vgj6Xv|L7efO4^LzDFkMd6wHdBUWO{6FYj@R!ln6k^A}T5d zhf8{qXk$dFM1Y<T#;RTH*mFu8PChu;y+M)zE@>9aJ$QI3{h~4@BrT%@0)+MWl$PoO z!h^`P7NzvzZL&o{<8DGU1~)zZcO>Wa-E#)|;hEXG6G7+u*?SA`A8~Q*&7PWSYJ^ek zVj?xOBO{>A7J-Lwv+izcy5a7MD5Rec7Nq7P;2D@G{t8RbtK<m?Jb$?WZ{A#i>+F7i z>j47;Gv{=DyUkpXm76PZD@_S#bLu#CJzZV=6cJ-%^6zKsKXOp1S5URJ%)TNxX{ryQ z)u@t`lk-9v8XTN0ae|rsNw9DXu8y5;nGX5DW=3deV7BbC*WKOCm-sJVRCk=~0rI3! zaEFXs48Gy`=2B+4)IFfF+9hN;p>keAqy_-m;^~+S+r}v2OHown=6ZSzEG!sFNaGWV zA$xVE-IT&SJVdf`vN1hV7v9@TE<6^hsxwc~eSZi#yK>R)&QZGca5Ay5(A{OoF)HbB zDd}7nnLUMk6aJ`P;>hZsHa<CtjE~>GYE@*ZqvI?)qK(zd%fgZs?URwAZz$-UP?zdk z&99=eo&N{>=@Wc{GW*>&uRC{6PG}Lz?d5hvfE02RRsCqt*Kk|Szq`A;zb*1`6=7Kn z#GQ3vCNMN+n_xe5oC)-ZKRr4+JURHx@-sX<CLtj?I<!`)?T(h&T$P%f8tYh{gjs1j z)379v;f|0jkuO<t{;u1_+#GLq_6uzT08AtrZra;DD5<H{%Z=3>6=nJKoO*y{us9xY zQyO`C-)J^%udJwec5<Rx=X^MGDWgl&l`RuhWJ^ed?s41eVLn%@uVr3!?W3TkHj^%G z#LqwFl~n)MpBFYc5Z(O7`JkOoN(2`terj5!;qvU&jv0bqOQA-CQR|T$KmX6Mu{Dr^ zYVXhLOiZ)aA04SwRGe{g&W;z{TAj`8EB;PQyu&WsKLqxXxVXI?g4e52_b>gtVUzE# zH#9i#z{~?N=-ANEO(!?EVzGAbk=_RuoINl|gFayHvK8}z!R%K6f|Nz|G2mk-=jRWP zPqR;_1LccZ4EWNsvx-TY)@8U?flEa-#@jh|{=_f>>&?v^RPm;~zzfs>EKAbTH@__D z7>UC^z0>5BPsE$kS`0Lw7w_om8W<ivJ~=^#^U;HoSw@CHLqmhbTF|#h<GVkvwC>1~ zw+i!%7gwNu?AN-~*5*tYTIP1W*VA)yalx{<un@4C+ubGX>(_b&t0;|!H^+e&)oPq7 zZKP7kr6C)g6m1(mJ6gr!tYn}d;86Jq6pE+2nb}EoY;9%T3j`Ve=#E83qD4faz4U>^ z77Iyh*IEj0Y%k-ZqDKBi^&lmB8`44>pf0Z(Pm2l{7y#$$dQ+%c6`h#KLC=<==*t%v zIW^5X`@KP4@`nh441|ZMyDI>ci^N1Xf`e)5>Nv*>)BueC5-|`914Fa4h9o!YW(oG$ zjlFzaVCnR|`$ctqvN%wRXJZ5X^W)>=>FJ~*=_LmTe50cgJUq=Wb9)wTgUIujB9e-} zC>p7$aXxdM>%A~BGs~CGCT6l9{~?Lta0?f%w7t1#rls}q?s^N@wO6V3rFXAmV{fOX zM4o_%*irS(o9eH1!yOxf+Dp9!1;Gmo2Te^)1qI@Aa-(YO8hdC5%LN)hjr`<T?N@$& zP%jO<A`)<U2$Ml6E!l&A{Th%WsDsrLZP^JJ7}N+Os5I)Ui$huI1`1aS!T~cbSe%A% zP*MOU@Y6eQAO0=FZB*11Az~B-bi^+&2xz&nyF)wk^yp189kbt-HZC7dSL{OQQ5|lD z&CJRJbNv$XdHDFiK2|D9A|ofo>AIqTkSRhD@q!9AMaqbkHKxjGvaO9|Zq8kC{*8ZH zrOx#$U`OEZ&&;Z7ulq;apBF4(!LzwoSXj&!ZE|uElyh$-QZWsolY;c+`(|fz3kwzQ zQU>0m0A~eh#pv~Y^o7;cxTq-HBuh0lHEKc*Hd<~0lJMB*frNO~Lkfy0ngrmgW^H9v zSzMl*M<oEuI>DZ=Sj@)B$$Bfk)v?i0qW2*`zt_#JPG_(9>T2o(bH26{iAfKsiRmCu z#Y;skL)qoBla-lTQ@98$R8(bYX|hm3LE^e~huRL^vAJry)ZAPmDn_`%FBX724V$lA zo(RcMZ*YIl&E4KJ)7;uxS5^i~0D35Q78X=xe<sC;ks-mtzy6Llp;}hK1UU3gPFFar z&UD}b*45ShyM%T3O?931C5-(1Nh~A7Zz+k9)PKD^R8>&WrzfJo#54+A>AD#}v`Irj zF)%u~dhC=bj=#UN^FuiO=p4C~IlEJtyH%UAibaR!%Mv$;zIUfB+_A7w+%H!R($o2B z92$g4WWvqcODEM35X1)qBZ0`7>-BEb+qa->u77{K<pGwM!(}fEuxHP?>d=NOsmwQi z53DgYG@O{4I=Z{|$j;4`my%+&To7c>-EFwOPe@FxwePjLa=w~aC|qYUFE1*(IvvLs zzjOc7)@BZp&?p*>Pl6Ttr&nOX#JkwMUT*i0k&<${Eq5qrRl^z{kjgH*ck>`)CtYsG zZ^+KiovYghtE9A=T6Rjx(diw&p5Oz)g_4NKOll;|)2B%Ygeu7c1A-d!&)X$%xEwb; zOT$e}cM2*hB0b!%2*Q=l&!+d^qONFjOL2tjXT0`)#M>HWHZd<w6F&`<6%|!mUxMAJ zGw-D;26#@ZRGA<h!^3f{#v&p$K}buM)q=#*lA2`pk(D7H>gMuJPUMhpy?c!5abnSq zPJF=cOhsRw4bm|<7}LLOe|vd}%1a0+WguJxUI`E8Jma##_?fBTBUg)lg~k1QPoFfD z=6)4tj&M*5B0vjN%Cq-I3Kcv$IuQ~MXy+<jLtg=!ecFMq4Ayml-GEfbNaUD4m98Ko z@r}*-Gp|n|cV+dsLyeT0Iqe4EX=HA$fVw(UHM0OPId~0!0u);4G4%EHS`qWcH#V{a z8NHFPaBzNjq-qvV6>Bt4?$DqcFw4liNa~Nv>k5yM7kZ8iAuJ~2T4ZB#1UR9%jLh*- z#H$H&aCF)ocR3Ix^^|m1^Gdt5>;k_)@B<A~AECfY5<dIeN{%qp*3M2@S&;!l|NVO( z5UvA9WF-Gq>Fj3&KxGf4D&65g^F^E9q<Gi!`R7h@f3Wny65u777#pwctxZl&Ca)C8 zj7Vx2Xc;AF{4g=spB!wG2F-|cJphV8i<E!;x<{a9BmnF%lfX0Oc7Md982Jg9#xA$z zl}3!qU=}PcYGupjI7R^U2&g0?Ln_T@9d}0?K;!|oN3gJn>YM57vq3=Ey}7mF?0ng! zFfJro+qum7YW|nzY+bvova<KA3mDcIll?@H?2jaDRE(U$%#e>tpyL#T2CaDBsQCEj zOM!)(+t{`auK*YP=*UJ`I1mY<N)u<wt5oz(lFLN&5D(j9xJzs-n$pM=KS!()K~Fye zsMx&oE>NpES&MT48@q@|U~S#)Z&d`Q_Q)2k-0W-tKI*>CPSAOvP@oFJwHEcN=g+I+ zm|K@DS@P124Rz7bR&_eX)2omITPM=rz`?8{hGPw*h@WW-z<&J5tcm*#WD#I5b)c8_ z^Ya7q^WrI2kp9qMQ<wp9c;^ck7=C_%1IOB<)@@Rg+q)Bwn46{VRj>hIlgpA_uDm;< zm-k!@4K1v{QFpi1{B?i5f8MPt?G1V+_t&U%iw6y;<W<zvf>OWQxVs1cilfEDla~sG zt-hR4qOHSW2SqM6wg4nyk%rx^B^rqXeODZ&*8PQK=uGzp@NBT+oUKx#0}@j4aDO~! zmD@Ft<Jtb8Bc;%q2l_St@Lw=7jlFty6B>%_{UaoV`>WR7-dePm*Awr7%%t1f75~5r zrn8<aWp7C-DR(I;E(jUTp0uIipTjo|fJD5yqF+&7IW;v2v_Z+M)+EY7(w+Pl{w!^o zn|so!8zlA`HaQqU-ov9IJlsYZ3!6ZfH-pT5q0K$H6$2A1-JSx+*dnG#1(+9eP%#d5 zeCt`ZO2AQT<4#IR{W>}{b8;kNF~U3ovV>9bMTT_XYnGeK9syyXqf3)E+TG3XS_Y;z zqq$=sJwvDD7;hOE=m5RE9p4~KDL{hct(+cyTL(YtTMqR*%5+f@o#H7YSsl~L!UhR0 zZay*`fP8Q(*C9ay`q?lsaNZ#?;^%h>Q-CX)MHlCrk(yt+p3p#^C`h;&bjcKv;6|#y zs;r<85*eAXwRN3f0(K`9{}pwk>rQ^zOL9=1ZX>aUcH_b7jc!@(Xt{p-;;Cd-Syo4D zDDvP$K|l^z#NJ3dkCPi4YC1b#EgU+&det2{MgmYQ8=LOPND>(~qK_Xpy~YhnM5qPQ zhb}m1&T!unj7(1ta}P+Q&)vqdF@0>B9Vwzc0LFS?N-^dXXOrvfC%R1#;NXR{FYXy! zt$#q)oCAAwGZV3NXU73u1t$e2A8dA3j%E#K9p_OWDoqFjJw1d(rn=@iDg`wWgIJ<0 zdoDHEhI>d4>i&oKL6^GJ{X}Ii&CdH;o%6_a;UM4mKbjlN;@>uDmm8rl3K7@snR|)) zQc>q&z%xMe5MhmC__btbWogb5Lc{TdXH2MmXU=#pd!&s%dkrJ>9t9W>-gq#w<)oz0 zx9+q>=bg%=tt|cG)_BGzFVB>3)_cTMo01}`F6J#MA;COG;4?Tj6dbG$)=VAauA<_K z{5-0-yhf48yrN2nv^YA@+V?gS(|ST}f*;6bK?Fe-yI7=0A4A?^dK&wBO&`>!<ymml z)zoxEzc4Y`2Z)4swy#eqPM24F)WMa8C19!v>|X~YCT%zA+gk_HNNrlAOA`a26d)$% zR?_^H{L5dovIju`2DJ1>aJuZ-i-M<!R3NIXO!u;YBV(!Jh{qb-c2NBg52gVD5@YP4 zPoO~?FWBTW`*95DdVsnj`UNfgYkwB&lkr21^p$KNv;&fds*;kt<YKOdccf%=J6><$ zU%n&_J?Yc<eLs@8ut2Ag^xTK<G9p3`2f<~%FA6`pLy^T>w<}npSY4-+MDPSThvO8^ znq>!MPIB;}9+*FBY)H$itB2a!Kup5KNW668Gd$rC_L9~!IC!rwf!3-jzPdWLtIPUD z3&>6FoAaz-TS--;LN-6aYH6?xj+p0<RmgiI1?ijWn>!t^f!<0G8<4Rjd;qFW`oEk0 zkW`Q8q<*J9`1AfVY$r(-ws3bqJNG`kr=L&z;=aZ5q2tZ1S}UHPki`H@%)#5tv{k1p zCM{RAfYF$ph~GxTOlD>Y06NK7;|DxCtCmPVikp_$tH4`-$)T&;Dn&%|j5ZLU9;q{U z{}3ff*qLA2UA^uk)gaC!Mq61|t+q9vu26f!&%nrdb?7%A8;8wMIwT_<rW!vBNdFO0 zS}r?#A5EB4YwXEcSLJndTD<T{m3FO4rfyj;Lhmydv_2<2b`|S;Wn^Ud_~>a%b1*SK zA<)&-{B6E#Gg0=O#?MUHpo1tbMyaC`2;3%^QzZH6wH5ui=iuT8QAFYX)5D_Q>E%jy zM43219ATINsNI3CUU3Ntr{y3{rm+g(rA8Pkr~*RqukFjAd8pV-Kwv#1!xx*mK)Z&R zlM|s*MCds+RUX;}Od^*J<nAj4q@#86R-B)LDNtBNML<k!_wMBzH{rFT-zeEX#hF{{ z9f0T18=c{lrI%}B97XB@Rv8y|JW3IyLJ+0rZ!KANJUtge7qv{!k|HzEd?35q*Tdmx za<a0b-#5*6^EvRCNl9%0T2xT5_l7GN9kd^0XXKE0%;bHoTh{%+s)`UJTJW3Mwr{5A z3+)1t_s<!-fHY|#8JpCgpoD^8n!wTE_FN1s3}q!HW=3G3PSf4uQOaX#Ki=#^fQ9vJ zM{9_ePzb1&1iglfRyM{FM+YwNzKHL<J9N8rY_U9@g3>Yth{KA;NrLoKQc{{%t&t!& z2yx;Dn*ARIU}FZvCU=CUS~@MJI<byBl@tBU-q6AOVltuegET@o75qcwJ+UKRy?Kky z4sHdCzq5;rot;0J%?-GBn7M#XaGd6oq->KMUxI#p0+x_#n{1MLmM$4^OD2o70wW`t zn2P$E=3Zt_Kxe&Uq{=Cx+uttaZnrm*RUYOAEF6y7kBp3GZbdLA3Z(Huocy{gOQ4ej zl&6)vf7I7|`M%I{jrV<#ks2Q83gQHiC8ejO6(xIBIUU<yqFTfG7;9=O-mh;?XvT`V zranOVn!x~MkKZNaKyzUi0P(Q2^q*Dhq6PrUd3gef;x9-PG&E_LalHJzGGvU1h!z5V z*BbC}aMnQEZ)TPg;5{AR3{i}RMwNl~3H-@xRW;6{^@#7EGZ`w{_pI&h!Dx>T4gf^Z zmY6g&HfC(FzVQJ1U;ze@^j!Blq=TR!v7TP)pzj?(DuZ+jC1M1WR@q7P&D@}EY;C>8 znbU{GPETJK@$Q)7X36TjdE*Sg5qck(KOhK>{m`?jril@1n3eWhvvcV!ScPRN%qB}P z?CefUO2UdS#gf$niuz|FBga75NjOYediAA9Zta%<EUYaT=j!qNd0l;dEp6>;<I}5- ztoJ%>wj-k-nat+!u&|5_4Ry`TKscFkLoWFAi3Sf(%joFCe%#$X-q~qa63xnrSzrGI zRNqnIMq6gLtHg?JtI5HJ7)0&imXMh#AtDkE;$}g9C0rm1q5k@fn@h}6y1X~%lJ4o& zDG7<~ix$`3t=GN1ViUsyFMOcE9;!=k*SxQ64VF$+IJ?cTw~Vp=5fQz<uT?lWYBQp* zWprOmHD=buxVg4yTZ#54zi646nX$esiS})CHhrofZtt6<;Tac48Y6mm{L0eGsy{(j zH8CvCzNF2yBywGA`q}q}c?df@3|21-iGIE;VSYh2WWvN-H0YZmFNw_VE)G$1s?Bjp znzX+p84wvUFThhoOC~@Lf6sop26_3O_RNU>FN~GSu{tx;b5}oy$bA8XJzA%`&s(F^ z72@+Uzm3irTkLNv?&+DEAA;btQ+JDaaH_1l98})4qGR(_t4KIFw!F$s49cHBdj_^H zkSEvO-`#g6Eg6{Tcw8J9<@p_UjRwj`GJ)cLb$Ys;rsl@I+X-mvd<`LMc<0w@e0}g$ z0%s>dRc+?}ZZWg9_4yIPFbs(7=Pz$WxVR88I!{MpVwjNH9w}p*Xds$o*ftU1_k9aZ zNzpws!yzM$;^ew_d7Mc|nBwMoqm*~{CoS&iB`U~SpFJfYX8H0fTS-biOyh?RXD4d@ zqSl9SCD5=Ol8?g4&jZcy{v$afqqIWQ#PqP+?bX|zVlj}<f=6yJ<-K$^Bjq;2<{VtB zlhY)x+LG^SoS%TNNWd%XI1=}2*0!-Rbpe(3zOlK!F}zpgl(hbVHLlcq(%@lcuh`$) z-WC%VN*nyXnn^qx9HL&<Gd#Rrv)>>sO7Vf5i&)pOHDGjW3kyVuq#oS#jC-9+GTBin z06p)?W6xE{w=m6Vu-&}T6(Y|*(oL6>{>%sb0Z%rUK^-Pfqw=L+OL-Y%LSPLCN#DSa z1AxLJF9zP+q6hHufYEo6rrOySna|Xs;h}-l92Bv7I(y5??V{=Q<>a2@6_(JwBcr0q zDJ(o6%g3I;O<5_xPObN<GF1{?u6u$dCiWUcDR1UbWNJsiD!duPK$?P1JzHy3BTE9v zo8rR4zZH&zU0gB~`WqbCFC$$;yADCL){w-8g^Y|_W43;9V5z64)P;&?`@GSy&aDpI zQIm0VSs6K<v2hY&)%IqPd;x7^XlNcmUKEYS2FF9u+-6%kK4J6!Sb&+Am$kLWwn9%p zJqyS-1P2LjZEkXb>Y(fjiiL$ovLzie?JE&sLQGDZvp)d&<K%R!o=5<|yotO;G~Hx2 zGrBODQ?W!iz%=;6)o@n-Xdl+Qxy)SwB}lhRZZFSDkNfreyYulkZMBw%-$RjC!#&)= zUQ%tfOi`h{;rOv!Zr=5{b#Jy11=bsgSKF*hP{YGYtNRw#U+vtUb6xFCYp~#)CG)_T zn(Y)>zW(CdRHr4Qrk1c@cRog0SX)J*uO<<)uv0Z(Y$XR`aEt4?2h^heVoAlHH!L*t z?6`lPvU{ihz%d@!rGDNle6C5)f;D^7R1DhIP<<d~CNUQY*bi$tl&8}A^6vWH;_b8r zcdz~D#^KL$a%Q%+&!&Owj6xxC-Cf&WHsZ&p$7qkFjmM7w7ZXAxSU-fj#AwH3d+RS? z2N}*##0!}o8DW`TeJb(fZ$;?wy^Tbm%B|sgxw)rC3&KDl5}wt!>HGJ)W|u|eP(MAZ zT%dZMMn976AKtE+_|@)#^5L0@LIwLAD!N~D7VyrZ<r#)wK>h|bj|YW{HllMt^i+cS zH^-yLhVEZVFb{9(Vf>FVKtVCQzItqs`upid(XWqz?n3snSCA)AYYd7H$}t&l^J<vY zDop1N_vR3b8^+ZyMR+d=L1?%$0PyVM@?wuN-A&tJ1r7J^#>Rurh!f;nyM7q>HfTIG z3t@xWn)8+za&Q<ZD1H9FMNj-iUVMv&*%}R8d~p&Pu8H#xUY{IyQaCYMMs~is;rD;y ze|UE^k*q-t)Ekwzr8JxN%?k^SjOiNc>e7-w{aO|QAlKZS0{g5No4JrnKNbYuqWbxg zEEl}OEa(^4)MXVFoOV|epa=(Q-Om6G(x3(yWzd=E|9b7Mj|N4T)GLb3BG4{mHd(uT z+<#_bvMnle)tpR#7t+0I4YUHJrBQHk<3~q7;xY7sVny1@vrxekUg1ZxjfbH@9l*z> zE~lNj{a!!zaJ#)UxIVvi+dm14Y_|Mu%7Isyo7=q}xay^z$OV>ufe`#=d!8>u9sDc6 zq=C>|R#vvT1&x)JtsAMUN0gbla=~&UMro6ue<guk{p!x|R=e0xuBSRN5l`$XK#7e6 ziNV`)v#46afb#&50tU7r``f!>4dK%5d6+VIPd_uTkd2JBsq^rp*40syvnJQ5cp^!M zWh5rL+m1+s(4B?FlE{7Ni3ZrZwFr=}u6)&Y`chIjR#|EM)j`+07m~BXzTbF(MoxA% zJw36Xw|Cr7uP(h2ZYdM%>R3ld$FhdU!#Q&x{EzbF$|6XmK7ZEIB`T2w>snWLXVtYy zW?h1gp<-HnqPvBKgs`zRz?g4Pfd<^K1v-#8bp@3CNpp-5_4Sd-ZWBSH1*r}jJNwe| z@^20VG;>qYkN{=T)EHP8n75^%J`IwkqEd$u$#Fvyle!2;o_8Qb9V?h+8JI83G|)8C zbGx|!Qj-Xjl%Vm-5E{CrpfC953yzZzBO`2JY80T_5qV=_Z(GdNQlQP>$Ab=D;BeJ~ z1GF3`6dM4~LpJtsJ!v;-uU3$l(|cfKeTF(fRa?)<ZTD&wq*I`QhyFu`1V-;@Ykq#+ z>4F9KThuk0VD*AR3r{4#%F2~5pd=?}bKGdJz1ew7DZjn35zK1UxwJ|`lA*AC$Krl; zkfm#TIfSul1W+n-)doFTdgrU2!#~r9TFFu@IOeWS-{Ct=6fE*AG!t)b1)cbe3<cAU zaKdH6t*sf@YuFHOZq(e|5`d;!+iMkmUjgwXR`<h@Qh1qC&*x1twb~E&B$@=2ahjSI zjf^ToaPP&)a88cSTAQ<FrvRy7+c?*Q{l-RG8mQ0xe%STD2@>Zk)f8uu-8V|iude78 zsF$lNM14z05g1C1qX$J)&JTwfetwlTHBlT<pwJ~P9UhE(pYQR@;y7{_U<a@SC_)z7 zk)Ww04=~~9#KjdC@PAt_&i23Pj?7OP#srujxAn@nROd!lgvqK9;5sugj^MJ{0#<KW z5E*D|)uJ~6{RN83@;JzN)FEh?m}a`XTvkUNgE}z&#C5<mz^MLFjy?Lhjcxph8a-xg zmdol(dOAAzmk1Wd<^Wxc6?T2<wXm}T<YFh+*7&_8AMw?jG4Bu4N@fvqtFXzS<YghD z@kYlPl$sR$zO^hGo8-Rm`3f@fkH7-0MaSbLu*O{pG@ZmjE6V<C(7Hv#LGZhkWYvlV zk<!%E6kyxp;9>H^3K55`GnwLQ;5j(-2M3?AV`jq=AVi4~hCM}lM&4=Vs0b2bstDoL z<&j_<b~3cUG-+~3Rz^kF$cQP00w6pzGQNa`^)^U=vcSKuoyj{olJ-W5n>7+{0EIJs zhuedeacJmUSOPE4`N`4GnQ;JX0~8A!1W<Sc#U4p%Wmz>Da(oW}5}MEarU(_Ru4bdA z&clQ+4GV+pNb2i5tEs()Y)qAlSkzaIH#JoOh0Ez_uzJnZCwKxle8SjxOG+xx#+p7| zdNYC&T~=<CH-*4k^7H4tHL>C&M26QvJ<TbuR7w&O7HGND)VoZOZ!Mc3b^Yv>JVAgW zRhXKZ(6R}EO<=P#wMF&S|62UtOXoE(DKX``H|36NnLA%h+!UOjr)}(acmjca2#}cO zzlX#v`TP3vJ95;ge)ZW6Xw{~PV$kZTuUEgUkYo`Y7~zGrv$rcNW7?lO71q&lGcmC- zo1O4?fhC9$)i>8SGVY>#!0`-0vo#-|o~^BI3FGV6L5{9?00~0UE}kNx3JE2sD$V7o zpDsWW6AIS(UFAGrNOE=cf|0_kB;bLesM+?2B9^SwnC(&@nUe!hQbECi!be|IQ!sr9 zRB(|Y;6aXD%ZSo&POVQa00u`D6~gZ38XASXgiRGNFCM@<A6=E=*Lm#$kc@ZUhO#=X zA#bSU<48V-^A2tAp>^m+dK`gR;V&1UW2iZxiH?DeF-0oqEw?iK$@x4jM-1V;s1Fh- zKt@=suNoApUE=`scVq@=s}4^(-7`E8W1tc-ZOSCJz&_He@34Dq+0V!+3a8>AK@$Gb z2W&};(97KdCX1Gi-amM)8ya3<Gc$sS^yJ1zCd1Y@J-xiJ|I4q&fn`#}knCk&ySVbQ za!Lwe73EkUdpPwGJ5!Ql#(P@kJ5vOXovp1-<=)C+m8ia&ome_~f|iliY2z2ruOH2I zu+7;hdU0oNWK`#Vy9SgoecP@8@8DM>9hE9Y1VAd{o9KX$p!z}sC?79%3~CfF%9dp7 zd9{;sTz+Oc6pCXq8y*`Yr=&DDHvieFi_L86l+_FtU#w^t1XmFATWFbM)|e^Ck0pHX zDeHU%yGHakuo$gXci11<)EOQp@Y&0+X<t7k+5Q2-B4y>NBek7QG1z4DCmJN-gJPn^ zY9BuWzbE=r*N=>_sBmCK{&*|iHMk4|R4B?Lg0!E3V&aPyj=if@5Hw!-vVAOvalkrq zRONvt+UZ1qC1@j-+4{{9>|dPis(>eE6nxHY7#kClo0FZ;U|F43R+OGDBqCxGAos9I zG@dLT{kFZjJ$GR6eO|G+u>qX4ESK9xkB(5#aud=r{d|Cg0mUd_BeQ-yJxiW<Z(g(l z*biclPt)(~Vh|-p2-mR7$M)`}#nG==ZP?0$3IeP)H&=v_x%9X7DnwkIBwQ&sBZJ9k zk=0b@>K3)9hiYXS6%IIWfReX*y)^;rWn^Y%|JOo5Gy%^C)5G%tQn}%}nM7;c1S&DH z{2vRja4}oEy9S~RP0cVqU+wHZf*lV4irB-Vk+drB<5tj{UxLe4X*##Jv0(~QzqPIG z^z`2KV^kto9|#bMUD^Q?!BEeL`d&`Pzb)g+%j*vCbc`6^P>O5=0^LhL^N7f|!-j2O zuR^6C?d=_&>pS#f1wa8v4FGNqX5%B@4mxmcac_5Ff#X#9ani+t((~2ji{CXa(%Eef z@OBsV!y;#4Y6^O!jC6U`YaLk+=f3uA+P0ldsP**~fJFjO2EYyH;5zrJdWhXhZGH`Y z*U=smem?|Qyxx*pQd~a&KbbW+z}Q&DV|J~gsw&991T5n-Bn`nqgW-~BBB@o%ty{4u zBJ{Pjw>DOqm#vT?U~Obi^5|@DzqcyDc(}rA!K`c!7Gr?%M><mtTDP`VH)Uj0<kY2v z(+7%p4l9>Z2+`W}6p11_OG@^$vc<2q=N*H@PB%Bnn?5gAvsD9{!Qo4*ykPrQSdel6 z#1$}NZ5_@56N8>!1`yNOm5k3NsvOzaj5pWTwP9Xd70%a|SlvGBXIVdX@=#^NM#I`% zT^$~5s!p&rnT=ilxvnUqqGzyPWH#M5GBVxz{`pIPX2_QoKy$;2!#X;)$v7&dco=ww zoRJZ-*C*JQ!S4)><$p%4psy&ZOcHt@9hLZ3|9QR5j2HqRg^CVJ&^m|MSkdI!LdnUY zfZ{ioxVJrCSXL=<LoCeqKQcZVG*C7JMFdcz4h&EQt{Jqb2y1J4AYLH!CJq~9FpvPP z3sb|xnSrx0k%_hXr@k-4R}ZV!`;$QT?AhU=LGjd^aPuyMOJIcLez>$+JZ%qz0|5pK zNF+!QM-Fin0l#0L9Z?h>9l1&o1ybYs?J*PSCt46zT2d>_W`T}pgvJl{T%V^Bm~cK* zV?*?RSuUEN$pByV#Ws+2Y%Gf%-`?xh`#?FqWcfR9haFTk?JE#u;i$Q^a=OnRG)Vq= zJzGx0^D3bEKxi5oQ{@wzgB8-=*;73{&=J22@ydk%cj`vh{{Rk`Lj5}(>anr0eMqwY z^*Vt6n;iY~JKgZF$9k3{1;AhW?2*BaGuHD78@87UN|P%N;3i{0<?`=~j&$O}>`3K2 zJs{`mff)EQY;dtQaDQ|?A!hfB=jPLX78p&mMuxt><HoS)M$fm>@HsuiGN^f{DgF*i zDc_O#bmUsUR1JwvO>^&GvYDQ&pZVl)+0r~!@e7e(^m0!B9ne2t`oAZ7|M&cH;K7Lq ziX-BG&zfNWQYQa?hi1k<fI9fq)4;EM-)5}7zt<iRyAd<krXLrt$2TUzo6N7HnO`AH zn|E-t*Z4evB7=EU4gJs2&=KVE7&~TJfS<*TeLUl`k!G=Ziz|iMlZf39Mxozz&K)K% zEZn?p)X?kR)HIkh^Gw%kJ5k+EFTXX*k@xuVrtGvmrt=jC*W=dmcYx6-(AC}GFnS4> zfu3^YnsWLHmk+;V4yftZs3IcWPNi>*(>#ng8W-fv;6siSO<yDdcOD+xz2(=iQw1Kl z?=|HVFHIq^A6Jrg_p)%1%6jdq!22FjNc`(GkQNWl%|*JCD&eK%=3aM+Sm3f-eQVL` z*KW!%U-r!h6<U4yhr9lFL{Mwqi^=Lwauq)CHs&~%rJ>bXyW2VnHd5HYI|*@2xUHX$ z+rncciku_clIQD<m-O#O2=kLg-UZJ84s*ZZ^ZPaHtFP`hbJd)S?=Uud8_ZvPa;$pi zz$3$4TvS7_FS?n3OTS4LSt83e)o)U9Hv7|Mk+ZVZ#qKpV5~TRL#vFfUMk+i-5#CLQ zw81V3o1Ww9_iMiKJ95PK#RG&U+9~Rpf_w|`Q5unpoOCJ#cHPCQHfra>g5;{A%3O-m z_NkuKqtdLgSGVIH*<$p2St8x6l?qflZOw;{a`&ei%Gai-uWBe|5JqNLzxkM;7`dBp zF;u(??bOBn*m)UsPlL5U**R-B$X+0|zoPEiZ*nQH8}V{-{VdBQ>}K5UvqJ#ZTf{ZB ztAoKi^o2<#f%U!o0Hw_Qe1?Z5;O~nLUn=iLZnS(q-jR=L=jGg4xK2m6QxsR0FsJ5f z=^&S76i4j-mPDLLVFunD7uC+|c{l0t4ip03lqvo?YrMjgNH=o}o;#)StV%a|H*0Ra z?&oa2YgOoT%N3~liO!`pr8zaF6q`{&H)ANRPqUD}Nzo>aeq`)#I5}_oa(uU4{{!C| z!DE(v4WBxFd?=)DU|8ub&UGnX?-PPFfl|ad=T8Ibu_xU&VtnYgV|VQnG_vlI>m`WB z42a|F3G_B<YvoJ(N0!+4`NmjN;KYxng<Taqj92UM2+~q=kZ-s6O42o?W(?jRYG6$J z@YUPC@KcZrV~4;Nrfgx{Xdec7Fs}e7_2=z(rhD}%^p}2N7qqIWb7La}+@1GGjwC&U zR?;d=``_S0=FZRSzJ7%+ReMlTdwkja?B9|=hCGkrcJ5)(`3CdcXPoOZC;}rxlDOk- z?q>U{8RbvSu<xmT;T@b9_51eAG5wGsPvu*$Lb^?FE78>Md&p1T#^^Gh9t0=5BR~Xs zMCNHUU6h&?w6zc+hP)$D&W?Vv^k0y+);}V=azTb1J(0Iw+oOc7*1cTFUQC|z4ARi? z%Nh328YOmckR|l4W~ZR$7?-5Fb*VPC4WdFu7+17Roc+;i-eKIqK1^#EN*aCM&h;c0 z=i%;2<wLJ5-rlTzpVtt8Ess=Fxm2%q8z^XNex+|t`3-e@g=boER0x*f5Q>}S485Ai z(M4`aw~ENylEt-czffno+82%FY%!vf`zNVeAd)uoO5PoIkKc2h-a)QxH~hWJ8z5(J zH+iSD8L5ncw6nJ+^v<w^Rjm@m0`T{|kpS-*0nWzC9?+o7EP!61$kra(JMUT!HyoUJ zr939!RSNLq%jc|s^V#%S3zQ&0XU?XB^j7poouT$cORl*)yghZc>guOl`{Me_Iy!Y6 z*;7+n&+lFxI=af)@mUL}JTx5u4j`Ym!1Oe0m+lZaUU<aJRF}QhryrrnN@S>LQK&1c z>za!oSdu~xq^8a%mNw!9Ak9ZBM@L1W3*CrOKwSqAhM8VqOL9g=+l9)wpI<9%GK@UX z@ojvAj)Vl;&-MhWM}=YF1%%<cY=GJQK&B@X#o&9gJ59w0HhRE9!rQ8<p+w8c%IQwE zQh_UaJqTqXIgnwn<B2rHY=vwqs|~8<$-z^oH9qVoh6p=tINp-n4bQiKNC)$lhYP*m zxvF8-Qn<aXks`z#B*av?HYX0tKmDG71fej-f=#B;=ckRstiOI%Ll8F`J*(=9*{OR} zT2w%o2lc|1*@>lwVB5STwI#ky)#e;<kf5spCvjJMZkJqVH0_-?yy)yyE(&Qk?r?W@ zgNl1BE+i|JX4gEUwykNd4`vLj2N$5BeS=jlK|!b2Tr)iBm=E_8vu~<%u(f@9Umr4) z+`@h67#~47rnv}kd*ItzsCvEJGx=so>o6k-fV3k;JhBvGJUq)Q*{N?M(s>E3M!W3Z zzvqKNyp4`Z0<uiTxVW<)lpLL|s1%W+-APwBioe?ROvzD>Bg4i{5CDQTiofm7AB*uN znyTvGH7xUH<Y)r42GOx<b@qo#_y!<_&qCe02$LZj`IyU0w+-MB?w|3o7#JAFMn*wM z&C7?_V`f9|kbvT>+hx~tB6_{c5;@`K2w5g7#;$>Z4KP$vcWwwV3eT4oWQa^Q{XY}C z=X;5YM#SuuvHnr>@_xv1V{VQP4;&IgCI+BZ1|!C!_{doPzSfwli@fJFT}S>BETzH+ z8QZK}StMHW+SU-zi+6S_s_6xDxyNNQz~)>R?pDU5kCy<Q<4&C!4dIsjuCB4uCW+Xp zw)w0@<H<qZ1Nyla)`_=jckTF%SK7nF<FQ63Qk~%04hY1cHtfJ$*dpN3<ogP6bI-QA zEtFJ%Ly|m^_a8zjP<B6qV;*4svuIgfF88&$spKducFNe4I5ed><>ujkHwx<R_6yBO z^f92!`2{JgQx}A;^f9KIzZx<srhfL36_Sk(jeyoHHix_Ou?jTrf%5Gr4HvyH3P6YJ zZZm4XShuF;`A&g2z=33BzWVq?czF%RBsBo8ENpV__}#m3a@gcfa9tw>iS6u5SOA-F zW9M=n@P>iEJ=>puCJao&9Q0odoQweff&u#bE@V0v1sTHj0-l;Mzxd!OBr8r%Yq2=s zmku%30)e;a4pCZIXky=%(9jPpH%^@s`_Uy!$5=DE+$#XD=)WQ6)?F;FE?#gwtKtL? zw~T_*Z<0`b-L*++>+<v!pnE^&D?vfUA#XQ_oy~~p)J2hlh5Cxylts=#;5|Yir1Yis zC@~TEmKG$iCdY)$v~O(YH5DMrLlL$r2MWrlqtIpcY}=jx7czs{SDjN0EEBg|XA3_v zjRJvfkPHxcgJuv8Jp7u|yVM<EeI`WAX{tho^V5OV;r|25{3)FPmFU_!SCH`myb=I1 za;JOT+P@kk5`RjPF)}jp!eU}zfhfG7pavQjtT(`|r&$+NssSm3OgE?A>xqx3nL#;` zcNQv^Mq>+GA`%3k_2B2>v92hhbCBzC2Dx;4x_@WhuC{}CUDrR)^uhNJ=ifrVe**zZ zaB`s_G0`b&1Cck_Jc>`$(JPJ(&DM|!C%fDigQxORCtA|luy;0pvGYz{Sm?=-zCNAR zfUQrb>eHF5_gt?hm$*@u<7scRD82bnRM|2?Gcx0r9zfCbVTI3$Wpal7<Z?bo+G8tE zgjD4sE63z;x*JdNxftO`-RsZtb}3aZ--DB#gl?h~_X+~%UOMh=4|(4@zI|J{;qW{U zPTsBr+zAY%vJ&I41c(M6E*ipV@$Of9gup92*UwEH3<B3_T=(PSfHYB$crM!BlE%;P z3*-#m@__m{5`?Iw1va_9zMjX=qokzl19PP!=(dRJW_4IZMcZA;CJGyrx>QPWsbhVp z2wuL*6y1aeI0aw@efCOjm%zi532gKsP*<-9%uaAj92$e`idh+o^Q1O2am$(J8SCDy zAn<pw-q${SPOqT9?BmDj{#;9243`DYCX3@=xfQ1;Vi>5HEanm)`YpmgL_G8gKD-)j z4GU{G(drxqO+3i_bu^b`?M;;NUdcF~zL|cmg3F_^w>*-0gErl7!4G?CJ4$j}+ho!z z@C5rD5%Kir{9OU#VncYkWa3E>-e{l4tVc<I{nyu}&ER%g+?RA(%zD%+xX%pB#o4Xx zzPC_sL6~K|G#-e=|5Aa6v13mA`zqu>t-bhQ>}dNkipv((y@}w$Cz;FsFsOgKB!sgF zt~^Gd>_ikqjO1wc=&F|jGJ|~HKXiG2UJN_Wk0v=6-hke~DXH*yk4vH$TUnvKWxaUU zQIFfGKCQxl7neTccbgR(3E8UBbcH=&_Xpll?`OrMGu#1B28cVNm)n+yhSnfP0y7vC zI2e~}XJiO3p%foqd9ad9dmivVnW<WS@5bqdmqZ#N447{j883EFfmAkV06FwGF+@5! zIhmeP0Y9MCNZn~u%!D$o<cOPkYjb5IEW$0bhz^k;EkB*wgJx70*cOYDFnmY`&C`V5 zu+PN6iZ?RDLK6G6PR2$==O%x9f+m!A$&wX-&wh1{+>*e*gbIzw8x(NAYN<;pF)95H z>k8}q3D6rrt12ncrj@|=Xz-b2#r(TD9DFZ6oL;Hi6KQRq`Etoa&lc}+Sa(&+05VA^ zC<v@v=6wJXy`6dvvG`>Ets>+5lD^sqyM4Wci{lqgjsjv`{&nZ132K*wl801-Q0HS_ z<;yb5jH|8p7ONMQtv^4w#rtm0^GYbD?e*n&<7=<f9BISbSCZcRc6McfWRWaa#(tk~ zOOr{w5OZ2$KAN3*wZE$Fh&au4Nu!3xvPPw4VK7yU-WFwCGSj~D<stZ}vsu!+G&fP2 z;Vpl5JO%nvtF2F$PTs4_{@h>MIh$!S1COzGXh(B%SNHI_{E%3-Yyi^H$w7H(c}Rnu zn;_ZA(Fw9YAM{sf&@s6B_C3JFGSi6RsxJ#@_V&!xVLaI1?T?0~#zhw>m(y?&1o!UI z>nIu;8698Ney{?ybfz);U9)^g4lXh>_-+ONWCATaF+JOnA;4<@Ap&R<%R@JU|6JKP zJv8-Qiwjg+P7VmRP>K&S)_nKO@4DWa&@&8!3VSnz5MXj|BlN<30(p7D<?Mw{tdk`j zNg3q$_(q%N{M*;XiXWD_L>5IPWBbeeYx=$1BCffKq;HL`pBPJ&56vk~gnDT}B1@Jd zet+tvCJyE4NB_4`H&z~OnBkehzP`M?z5;-ue0(|cdpoKq6Og6oONSU4M-=i^a|;TZ z^c~cHJHFU<6s}G{B1Yl!rUmWEtg2_1ftjF{r=4_eLN+Ne5d{aeAUAb-diqTgQu~%6 z{+o6FoAOl=9Uy-<I6od0nJAjhbs=N{f?!^6fkM?{d6IC@Jl>V|rl*RMtOqP(YNgK0 z9UYcNO2w}4fMX=5$D*z7pQRw|3PEBNeK#{<;jl2v_Yrki4o096fI6<CTeoCwEhBBk zoBSatg>r1m%F5yK8>t;_H}NL0epq*wTLw4QO4VLKt>OL~{ee2z&^~t{?~8ysemw&P zCHltE%Im{Iq+`V*C=vhrr8)N>ZRMcg`wv9(&l~=Qh$IR>dE$i_3^MZmEYPTu9P=Ei z$KbyT=>S=wXA@;CiQSd<tomZ8`yLZF5&YLE?H^R5F}35NlNx9?H0H%TbW%?$g@TFo zc0U6|&i#NZ5dRJnx3A`6&NNCpF&1D!|Da0xe!)+m2^ilQ#_fIqpH-Dga>(G??=g*f z3Ps2B53tj?bD(sZ-Jc_YzpI*AqyS(K>iO_2;^2t$tBG5+YW_$W?y_CV$o8QI0&hbm zueiI`G<JSMZ`DUs<dvTXlSg-&;#K?JK7GY2053h9`!T}FBZmj72jSyWp`cIBWj4LD z^6;m{uQv+b*t2rhgVc=6{HtS;3meK~SNf-aK%jKZ&smqEfx4!;YjP1+;ebKo5E2ti z^(-#{d!A;o98FAM3F;rfC1bRw%&UJ5!}Q?`Jq@C(u7$l@%H?Mm&%YHPe9QiQo3KO> z^4?>ZNz-<O*kLR^nAN0&XIYBs7QMmhJ;=5b>^2>Es9c{WUh@a)_L%o{)*aBCVdU`@ z#zzSYTs!rS)yG-W){ZMWChlQ?ZAl?yjgDhPCCMd+agox=807y&h%-LzxvF;@nups_ zAN_xJC(-^vVYX97t-t2&vMAn_^VjM6@joDx?(S6L)Ds<A7Vla^!>zetxp06DfN0A; zAn0B`>f3nviRd*;&rzC%if|$4QNzQjL4_dxB}7TQS47$}O4DhCopsU$o1~`43tLj? z>Tp+P+jZof>~%!lwThIaamGfA%`BlYW-F4g{9?-z9|^&oLTxRFvq^^+&+^R&_q!yd ztPKNh#@wV5?nI<!GWqork!cg#a<jA+QU3#(2%~mwaY#Zsvz=kR6jnR4s@$lvf5N^( z{+qvU_J>Et!4x+#B*+KdHYg8%gJy!jCIn*;DoHM!o=XGlhfGoGVw|;ZiWAuN*ThT; zQcnElf%9fmEJ-$toMvvr3lkbepB@mpy!(>$6Xmu}h09$%g5n0OX&<f~J}4WQyayV} zFx)?YrsLQG5<;it`8iV9{t}Y;lFglHxL~T{#h5M*1h!mZ&N}cex9YkJTs35f{i`H= zOgvG}5*~0JD5|rP%`^eh!7kF7OiodK_A-|QlYo(p9<}JuB-Tt)Kn(7`K?LU63w<jG zgK|-}DRrmrHitK(`dVsdAE<o5u}v5dbfy6U<2rsbJ;TZ0m?J4AXTU;h)WJ;|9vs{s z6?4pPAL%Jqe78)ma-YvP&JExlvd%1~V_1fDV#v2&IvaII_|I^O2BG@jA5rV~`7dE7 z5qT?j7h(^n?LsH*=ZUyv1wPzwPg2-_&E5{rUqGnm_-K}|P#psM{;q5-8Rdh6O0Xr1 zxJ;sNMbjsTYf1d+8KM{4;X|oYb`G)uFD?{C?cFkJmxaI?YcuQXU{CC@a>f#kk&gCT zG_j>2K?F&{JJa?CUHoNLP$rez2Wo3dl@lTOnd<eN93#`}cHJ{>dI0o^W8uv~w#9zc zFA+^!nGQ9L^!nh%b2H~Q1jL@Kq;YRESQmDXb}2ijwm=9cmB%}V>_1c4gJSIR0iDjn zSwxHdozlRy<AaTcKN8%eyChzUP#OyPm|Oe{Z;&bu^nbaQNeT?(k+HGhKv#cG;QhnY z6<#KjPpc-l7`tSO@=eTSJ3!2Gh^qh&wpJsLF`!1pq3t{=>aMcsJ$P_&ouqJ>vjws= zILshQYy>}~oNf-~C^uC+5=>lqX^w|ch%#T;J&<S~QP$%(pQA*JPfT*ZNnGg>okh8s z(?U9$-QGg7{M2$Sc6bLqG!tS^zvz^Z1rx-uqUpTv^=A-jj(rc&*{iqyG!T0+e6@9= zQN2}KCdl~yrTqwTAk6cOK9P;!(D2t`5ZKP7D=<3;2#1`jjq#X>ya%!zEj{NUDN|>* zqnaMX0lnU{#tTMI{?-$|JhH36maIpVGUvzHI%CF);AfzZA4SXUhh!b(4DM<M)!{aP zKO@z*n;nv}y4kc1w?3C6{AdUBmqJ(CA7Fg8@I96+wbx4xXC*NSJ?zV=FJ0KnPdCoI z*nyt_)1Arz#g_2UPhtL8k%9>ruELDuX<0|DAqtm2g8aO0GcVc)6o|t@uj1$NnTSOB zju2llxt3cFJM2bOcA(9PYZZdnNrS8Vkx9kypNkNtq~&Vr7fO825psZpwKgYyxcyB1 zUIE}U#5vT3=?8uOQKKLI>rL+Rg;D^9SIH3!ZZbiHFaVdWVCQzLZlKjotd5eY-*AQ0 zQXR%+q;S{DyOwFTcuWSdK9#RJ(#3w&_r~^nH5NUL3mZw`Lkd7-LkrMe!WhQY$_aP( zV<KH|B<;2Mj=BT9$r)0^X$k#;?qgaHVh<8FN35o5;FLv|54!sPfSsM;$7`rh$PYw2 zqnHON5-3MofJ=+-xHY<dIQVqcCQf-58*jIEKV4%pCqGON-#B^hHveYY3dO)-2QXw2 ze<kZ)JpU<(`t2AS>E08CAT2psJBu9YEe=H%%)nrLxZ6BBY4U|A%7+vTN%f@fg}KM! zf==9<V=6OO@#~}>_uUo^m&1vQdoJ8}N9PSUi^oyTT*yzMpzgWnLA~Z(*-=0a?^&ti zS!r%*-MPoDT5$+86sp%gC^{i2w>R4E!8Bx9Y~C&xy8mpbqB^sJ@+2G(deWGyOR&(P z1|pj0(?YzTWl;;K?)(~V*LDx0xHabQ+LP|4_jhiN`y1|z=1DJFIk}#n?LDc@qI3B5 zNX_#cu$6{7piqK+{*&J297<g_nqBg-3iHX3?NKEMG7R=_R}+WJxX1#>Vu{aIWwx#R zN6f8U&!K9a<yyG_A*}&8lb<(;2W-ruTQuC4a?8q(qF%p4ZBn~i1Ahs03y?-%K(Ot7 znoiY&n+0?!F2?Ge&o34BxoFS8SEv^s)i(`lCp{4cy$t)~`}64651kT{jCX&@g~^+b zEJ0YYe-FzM$Qq0Vx;^tud1(n#t?wm`wuUhB7-k^F*11SN17`>huvGi+Pk;kHo(L2a zQY<)c_4lumJ*D;c@frh59&0b2`y?*szhHMB>Sn+GI6YR^9xn~}pm)Zjmc~2A1XQS6 zVKm5-^qx6RPjtP%9&+<yXM3NKCmyz`PyWY=k4+x`>yW9up9;s+xj@lU^x!H^jtrqK z^h5OnNF)IVADnUHHWLR2Js{aHwu}$9cXf4*jxyi6L1Sa%rwW;w?RIq;J1F#zjp;KQ znVR<KD@;vKIoMaE3IY1ykaR^=wv&YgbF8hsJvB|n_VyMc!da@2g~j~M4a83FbZ}6M z5fcX|HX(tMmXe#5TvZQP84V9J0L6X-gUmtVP>iHlVKog6HC0vK@XpR`fB(+o<I>#R zTtj*W24=2A4lb_hsw#hySFbi5If@$^qWafUg-A*{n9!!@=BgVSLP)A+raC${+C%VD zLRME-!I+?-zlMZwZN;jZmuF@=*w_%oj*K%?(G~(W4bao%3twA{6eR)nPSrIvZ^Wji z*@rek6J6WwZJpuJ>}+XK5fHj@adboyySj#1TU(=~pa{Nq^Fu@o>FMd2o1afgM8o4i z6G@XE2C3`%`uZSo43J)pum1h}cWv!=lI#&tdR8lIYtR#gD+WwDQTz|Te*Fp(4Z|>T z1MT9AzP_{BSv5u_^}e9sU^7!!S4YQhBw)}yUt93G(C9&{Wkh%W>FJq;DfmS}p|Uo9 zduz+R2bf^Wkd)4Vf`6%u;{mW-uw@$_87Zq&a6AAlE<QfCYHG8fCf@{fnAX?O0PhaS zMx}HP3>@_IsDl2~&Q2jlOzgmPX@*PJyPX}X*zX~vq@*$m3KE#nvBK}e!@<1>!HiBw z5Fri&Z7m^~imIvstxGO0H6fTC`ttnkZ9r%apP?w$g@NM;^)4VF;Nc0ml~^py&Q?-V z+TC-9^WfppVX7ILn>)m~1BA=;bW_m7r*i?UM$pltwzjeHTIPp`*|{5lRn0NR9ndqL zoV+|b$~*}9{#{(6p9|501JCFFYANN1m%l&R&ANhu54@;Ee{cwCNJxl<IUHtmlE(M; zH`mwKm#zfRA|jK;#S=i?{nm{D8h8TF!{09~43r)ytXrGZ)w%UIYczlhx3lAncDE*~ zUsYbdt8_6vyeX=)e0<<QOO<9~a?fxBe4g6dec<5{gTS5T;^2r+M59N-4$PDu210-9 z>pt+r?W826nKZQE^$Jr^OpFwG5oGo^bF(K2e#gh-dUdZ&f)=>Hx5web9fysJJ3TYw z2zS5btmHJQ^FsZb3Dea^tX*%lzFH}5`y40PQ?SB8L6KS2KXRM@YlZt~VE{4L!-Duf pW<B`zf0@$Yum8EG{J;F@uEuwaNh#JpO-Bzy6XFx+Er4i#`9B1L68``I literal 0 HcmV?d00001 diff --git a/documentation/operators/src/images/grafana/menu-data-sources.png b/documentation/operators/src/images/grafana/menu-data-sources.png new file mode 100644 index 0000000000000000000000000000000000000000..6073d2dae9c512857c9d716fdcf692f29510c003 GIT binary patch literal 24824 zcmbrm1z1&IyDvHs2?=RwP?3<7Zcw^GQo5wOyQD=xq=ZFCmvpzZba!`ybi*0`_p`ry z_Br3a=REf+Dl8^*&AHYX@B6FQPz5=0bQB^K2!hZhB}5b<2u=e0nM8gB9(gaOd<_19 zcMy_PMn*=SU6x;hpy!aJ$U9}%q`i3;Ev1WVq(9U@MIJq&d*VT%^!3GaS{6KNxppgy zeXDWz-L0X4+0;ho>Z)ob&D{lfanW~ny_hkLZ8}frUOagcuy)Z^8pT8S?$4hF-TSDd zt5?U%o`aHH7#(A+h?qia>C96I&jZFV{KGMy=$Bx<e1XOx^eS^h&&FYRdL=hw!Rlpz zyR>xp?95&+KP=-3)GAl_pz?dX#wb9c*mQ>(ZLI7?7*>pp)**R;_8EKcE2#wRnYE?# z9Q|VHyeQi7GW-Aqd4=n9?y9C|9V(HJpsSaZ!o(9A7K0q)o{ptNc_W|1;Czh|%EnYh z1uaC8&lGfnR(k0xtGG-HQmUN%?hS>|p|_cJH}C;N4ny&JtoMY5D*5spj+7iucp<p# z`%)`k1!k4$=0u{?p4`jyN1tim6+L?~M&b3O>Q7X_Mp&$cgAw~ahFs?CTF;oOk-0^1 z(=#Jj`GBQTzh~)0ig`nN(9p?Hd}KW%yOUp#;#qOFaP8iLpyIqXOsked&H3BpSx|CZ z)3c|)vE0e7?Nu6NpT=F|stKcrqS9!Ta1=z-d4Dxm3ljTTncZ9()LbeCBOx-9f@;R5 z@GP_6jR*9pHt<CZ`R=Z6PFel<p#TRR2Ywy7U9!K}6woLyBqNENtToGKGy5sIjqOa! zx#{S=QCM5wpt}xU_Vmb>b54Yz_t3A<9i%*On~F|LBqLf~w{$Hy2#!8{x(ZVd(L<Om zPUpRHSga5NS<&AsWWjY||Kzmrc34rdBBptr&Y~TH;@tmeztPH9Dr(68Z4-E_D)Ccg zq9-P*>eq-;nd6I66e8XOrZ1R83XM&!94@c+QW0_UKV9a`_!c}-$o(wOdT%Eqpo1c~ zMoXjIp{0f(jHF03rpPL^Md*%isfKgOC)6^e2C29`q?*GMLCQu>vuy>hl;4L?!qbl{ zFbd^TyW{U+2;t!-``kJhE(&%H*gX0i(HeXAhnC&y&(JsIG{1>@y;K_4H^|iYjkvZC zv$W%nTsOaU#*eP~O-Mnut8?VhNK<pVBmHQ_NiR;5P7hYp$s)f^iX4@`e{+iaBkM5( zrGL?5-xw5h1IB8+jR;j4`}ejmn(;zh$dy{?;MaTKxDmgM-xfnl94ju$m_)XXO|%16 znR`;hGBhK$Y)T&zX=pTh-Ub&Xs!Hi3BSOm6ir6UZ;3GtN@Fc34Y(`Q`Fvs*YZygQ( zN$Q`Am&h;9wpUZF9{FZP9T%VNqs`pGop+EF9%5IXm>)#$6H+Yo{~m~^cEpr_s7Xs! zE3ji0m!4X9NW>Bv9J<hh|JD0~lzbq{DfOjg&f2)?qqjd+{hKei;_}PQ$SVgu-XWi< zHd}{(?AT6Mc(5ykNd}f8K3uLA8&)%qBlFwbp;Rd#{&6V@+$Z{i6?ye`S5VyaZW=)- z7vq}HQVK?LOv@IjlR?%fWi%9fz+n%45Ul1Os>Ff5om2*5H=sofolF!v>{06v#TLs% z%b;w{T?#hNu{bRt<GmQefycHC7+PwTdyX81iAekcyH$@uM2NsLKmz$+<$-|%#yZ6g zDuzs0R~vEE3lR=3T=9^AH&g%pkNmAD0WD(x?x5Vs3&i{T`o+C{lIs#`#_Esr*FI<Z zqR{0^`M#SQx6i?JT4Jj{?7qqHA<?N=Svls+3O1M!SiAnMgUKy|NH%LkN(u#oWF|V+ z%cdmE{X49ntKP<^X5C+Qd_2})ySI&vjg6ydQHJkeXU80`Vr_jrGkac@rsVM2kgp5o ztrTRl2@w<54?f&jnVB8QH(SO_&H8`(RPBAdo-->TCE3V6mDNH`?xU)uSmClr4*gnX zpR4m~tgJKw&z9aUeZ*clo|vdX!a@DUwjnmQzjPHTwkM}jCsoiz-%EJ@j94v2EnHZr z*uU|hUkxe!slA8cS<qa=Ug5*t*Gnv!K?xib4YlU;!?B84`G+*m0V3FC^X++?p4t&x z;V0FVr;nVR*yqZ=#WFP>EHB6MpLPoPN4&D)NlHpmYiyVq9?q+*Je$+Cqn0Cm@yNk; zv77(q9vMB<*3ni<uJ&wpfE=9LMwk3yVj?cp`-+jDBK*UA$F$RWZ!zx_F9$nkvVg<N zUait#AFMdiN6tD<hRVy>%GmfBBcpY};)iK3m|ae!OV7HyV<X3VVkjU;g#LT;_kNDT zqP)3!8?~9_k5EZz>CMqiGP&pNK(mgzp+W0FPt(O6hHe##2AtjrFZnp<*!C{-C+dKT z%F2D-lHHN@FnJ$_#Kc7DXN4iikwnY}B0Am!HoQLhMMZN*yE?2&4&;Z-s2fZ=bp`_d zEw|v@sLw>hI?}0CL>mg453kwzEWe#d#P1~LlY8H0*VJG_TXm<C_mu;SKJ*AQ+k|<7 zx0jV7FW*njUecr~d{6cooVUWovcxe|wYAO73anJjqoHMNNOCMKFLxO48An76s;WBo zgIo2!Hmd(X@4jb%VKv<zfQQ8~-8YvmOjRGBV0SXXZcvw(=k`J3aj+p(RLJ2%eRQJp z1G;*>aa$nj=4WXXxVO^M7I)2y)Afgu*FikwHiG#07m10qhr>;rHrn#_(LW2MBava2 zCMJtn3Ng6&I!)h(hKJ!G$2uL6%a5AG^#cO~t?9SBoJG!#zad|#EU^G_?kV2)GzzMn z;mxiQ-|uBU*0^>WJ5*WS)#Y;ev}s!SES~iyO*5ZtGAQ?>qlVw!2NzE?9DQy~ZsXLw zcind%DZ@L7E_&5adBksJWd$vj$UYnj>SpHT6lp%pq}IF8f7a%3=u9#>aMT(Km_m@w z9W$vWaV&Ac4V|H->#di!#H%3Vs)0$I)%;lEoUr6`+t~_|EhyG%JY9%;sHqQEWZ-5u z?|ksOZUGNZTMqOx@z+RT5t7A5!zy<wjdJA3HLIPYYim13b$jz;3;d}AtR9wos~5e> zv$EEkHJj5F^N1HUV6k3I2d76_bQ^+fk9^!!%F{RZXPYg?Eqe3wX&1e2gi!(?K}^lJ ziIuVa^_mklt`_L9e)XnPJocvWNEJ=pHWqz2-?%u{zFW~`(qtrzeQxiSlGv=Xsb5c^ zlEYuAu_}0fm&9F}_Dd{5v(n(ch!iGEocq$<$r{!!uZFuM@w!Klf6JF}buBgB`omvE zbZSgjk%YtqZw?ah?76a)X`L4R1Rd;I+1c1O2E(&POvNKe`S4u&0y<JS*omN!ZK=TH zrL@MJ!IYAcl0*(Cs#5pg?Z}3P(ZazO2lLHgEqagTk@uH*PYks9;C<a33^)73z4m@? zE1ATq#q8g%;zKk{n<J(bYC1Yzx9!VCMT}6*ciX1AY!s+yv4N+PX{ocn0J6Q_>jv+U zEVr@Bc<gAlSWf1=fa6DUNLfvdh&VwefrSFRh&huETfdv8zEhT>#*y$e9Bw0#@bh~` zNt~X>KXci*3=C+7el(=_&Ga}QBq7wgO}Ed%2cM6PslxvXjSj|V(n`~yV`AF09}$H@ zc)dJ3E2bF-4k|0z<=q*;GF2WsmA^l{`%-TPmD~k0Q6mPwry&wbd&_tj)04@-(BGK9 zW6-MGzN%gCb8~VbOhrX6klJNzhZ1(&+am?H)QG`>)%DV;F+7s;Sy-qpihZr;<N+y5 zLQGAZs={{@Gc$B(e;->^P0hrFni<h;!~kP>(!{p5<I%f<w?o&v5#*u%nUU4x%~7e2 zlvvQEXG&F-v#CToYw<#N=14%htHIDmn?uu&AMLl|_uJ|Cy*3_)bs$2TnjSOA^Q@cR z)X#XyeT+NGR2=J4KF}My`3}k|pEo>2B2cHx7%ym~JKy*Qe-N9gBUQjb@oen(@5@z; z2WdX%5*K=!-zxn*Ouxq`Cr!$^oX#qtAu4R_(fT!eGY{UQ@0SUq6B92~U7XIiJpZsU zODhR039nAW6Ot9bI}@(;7#zr<e~n$ay}K)D#uzA6TJFH*YHD+Fjo-<*-$b$E_jV|M z(u%j;=lo8+Rn-6=ywn^VRT_yJS3b?sD1o0Y;r2aLd=9l~a3S9&GXKHNj%0zV_4!Cr zQt^ex_>?5iXo5rm?ZL&)u91vg$@)8<KP2okV`FneL%(ATdp1u}DkfO*r9l&OGOwtw zH!(7D(|<33WyvvHQB|c;DI;se9?tQpMNi;PBSYk+YVs$$schN)@cczxp)_CD3oc8g zI>x(jcH;Wt-+FI44BorDOP%()kwmDAimKb${q1k8i#V;Q4o5#LD`PcP)7_<RAE|D8 zi^=%uJRnL+@cFE)MImYWr|1mrblcCBVe@DYPE0g4Bo!o@{$l&i!+zbDfRld1wAK<w zb9aM2wK;jr)mX42=f2Zh@C@k^$<58(r)j^QqU$MG%@+w4?*<n-yI44@pMT5C$!T^x zk`9->U0F%L{iG$0O2?~tBOZUaYyiqF9ZjD@iA!0z1Bsx(+FCcoI-b#=LGp3|_g1RQ z@P?Wi!}%OcL4vumkwxd*!4|vB@Ywy<z}|1sHVbl1!_jwNmq}onsyizy+3q`gdsNt! z{OkDV!acM#PoK)6H@L5mTeTz4W7Q36h4pXHhp4~AMR`iPaB)g$VPS!SavaB`J<U&C zZqgwWkwl9f79(Zk#y#0Ft<B!sF&*2>u&;l_@5vAwi+9Xe8&*zN`aLM9^E7YR-TnGc zKx##kijjrI;`q4J@=7gJ)68{OYO`Dd-(3R2#jTZRjGx~!P2{kf+cczSWtEXt=yf{P z;*qe8hi6n*hjEWo|6uOXV?Ya9YuqzcS=sPBv+78a`N8$LntG2%P~@bZzIB>L-&~&% zZ8UbUR)Vrr&S>a%P>`5B?e{K=Hyp<A^ORR!N4K2XUOa{bQcXUZ&J9n$#zc86^iJG_ zdi2*<g5~lLmVt^<u}&9#wb5$DIz;>HqivkQXe|Oaldr++AFtYAZehsDVSC$4r^Aou zBC{|)S{~)Fxw2<TI?>RyFsz?hJop`BagoPtWXz-p@8%-XP<{aI;bN52x`-_Geo+ml zGx!TCinqt;je~L5?eQ!|`}6&&BVo`KKtG(Gn(9yFW_tB%rM<h2pS~%$SoD>7ShKD5 z*{;pCYh-D)gI2Y(Qr~Tdy&E+I7C0Brmx_uC@2$s~7%F!j``PF=O@=m`TYMwzuAZhw zDjlq-2jjEI5TXn`2h7mgczKuA`2Akl=bo~?BpJxm%sP8Vfq#xa{L2?{kE^;GzRTEG zSYg~GN)!}^D1pZ@9m<Z5jvIrTZ2F!dQBkFh$r*vQMoLN)&|ITSaEF0B+EbH+lH{Z$ zVXC0T+GwHn;=1e}pS};o7MiH2y-!w!Qck0!)ZNUarANPPm-ox`GcXhy%cSnFt)W3+ zr}+Iaaz5pwleS=G4I>;i4h$5*Bo0kvvoar(0T*j*yu7kEF*P<7?eawDN0^EH@Q_0D z`kid?PfxGT3iU^ROCRTk4-AJ*@(YURZx@2%b+0EkXPYc+;<aj>w+H8WQ)(yrH77mp zxn<o%r#q_`Kh#}jjThf(iU(_GDPG<O+n5*|VLI5%HRNYx;IR5I!#eWv@~%&t$=BD6 z&l>K@n&L=#eJpivN3MOE`3>4b<{FY14sBwjvLM^j%N7@o#)sy8-i5h88W*Wu0?KF8 z@u@$(_xqUyZsgJw78+f0sL4YwcB~%zhWw#{zV`BJYHA*2=FCaTt2F*Wed2>4k32px zu@M)WokhvZ!-ZA;P06M|Nx-AySjFSw{s_GEGqbbuNjxmfT$W#Se<;tSz~TWOBZeM- znrIV04-OK$cD<3Dp)_+*4B3Wk&t}$hyGM-&KVyZ?FjCzb*&JR@t>B?_3>zY~wNZ8T z>5h$$t7s{HkBO0x5wt&j`(Z0{x_m>4CgyX`@d@=HW&wC=7M7Rh@Ap`;6xDTf;#{wU zFcx!lIGYYVN_wS^dKr-U$s3<?2$^nCv~hC?ZN2!fgz5i<{ro#tCG8~50Hh9p^$=-% z|Nl^{f1Nx{=c3CyC098y_=X1h-Q9oShH4ZrG=$Cp>rcRD_wQeUe1n50uP#|#<&oKH z#N1pNG-_@W!brJlczLN$xW`U#g&k=Ij2)h})9bT*ufI3|OPo5oMGLe1@!?7U;$(VY z@BTh%XxI69M1I%&^epfBt6O+08nRNbeT0Q60)_l`XuJS2dHtRhoI+Ac3S5I?ug)_D zEgfxbr~PZAaa=0@tDXGHdgq6Uso!e7jF?xpwUn^MSqPdHxI=_Oy5_M)k><bh8hF%r z$b}}p_^0IN5P6)qq6a@c#6dw&N;h_`@px(-h>Y$fOgAMLF#sM}TQepDFet6Sh$Z24 zXxWRqHUT`!#m$4E8i?G888o3VH|c^Fxo9hJzh}7F^Ks<l$Yk15Nq3RCgEA0a`^*1| z_~T?`bOGWICsv!A69cW1l2SB2no&$dWO|l6q+=yO`pC#AtKDG3_*vQuEX%4qiLtnp zs5m=Ls~@Oh5=N$^rEp6L<QDv?gN+1e#+H36b=NaqNY2`|?%h6pQ@?!e@@o&QGgg?A z<|}VFIbh`<kE9V0+yHdtXA(5Iu22Vs9s2e0&E}wHI|JQ(qswOHuH?ISIG$d2slwC9 zSV0q5_4NnjE=QN>@JDuPz7JE-Luq94`s#j{%^J0~<lmy6Q&>n!gdLUWteK_&y;VJL z+}NOkX#Q!J^z=PQzNcR*O8r*R(a>OtM2(GiQnek`(KgUq2Z!jCl$7{*d3X1G_g(QV z$sp?z6Vbtp_h!}Bx=4_2Dl>Rp_ZG^P8tZ>|cgq}d2u)<{4knlTy7n2vCMHx1jK{}R zM@=cfZChBNLK0aQKnx8`&nS;}ouiD0hwR#o%Vinp=_d>4MfygDhJKhTjA`--$um3p z_kSb+eEV*r(4u|xM=8!&6Kbi*h!^g2!&}3z#meUvtJBj7W@gpomW8^+!nrQs!jSO) zqt&^aTN}TKl?)VmhoQE4;<mBz>{D|*C$s*0C~|7+iqIZ^Fen79<&qD3p)JewI91Wn z4!_&~@Pe9wvqx4mU|dQqDz|Lgx3@>K(WkSt&F%gcRV=sug-g5foA1iB`;zfZdCElo zEuK$xiSUs%FvzFLiHNpW_o>a|Gv_5G_c@BZvjOV{EFe$@O&7PmA|r!>NwE4xZEh&6 zcVWQq(mJ6r8J_RJ!}#3!>0GnmF^LGS5-O~vXc>-Ld{ce+B&BvLuf}k2*}*b^Ed5;Y z5n+ur3@mNvm$5_2eMi~KH=$crCXuJ`_<JunaW{{M-c%!>;pp%Q|2viCU!~w5areKG zV*YhdS{j)pZLC<<2x2`-fX*9X{;6`4{@w2WZ<s>!=(W7LjsQp+8kq_6<>u!T?Ac?w z>!WS!MWQA?$E<qvc4+EJFw*lWfd#{cMy~`J_|gwaFqjkXm6)1Z{LIC%4D$*8<d|}v z2F3F+pGLCJ;)6-jIlJg0uQ6UcovgOjZg$$OtBehgjZL(v<LYFxy{!o)Bs2q?ywPbl zF+Rt|b?T#ms;`fNytP>9(AV)@igQqX+JvdCynQl0&@0-!R;CT_H`Y|2QOINCfVF*O zF=8>ZlZ=v~LPtq_Lup?3_W9Bg(MJ|D6(@wqu3eK^Stj|z+3v~11!*MTnHi!`5f*E$ zl0+R8A%7XANd2J#JeGrOQSm|4Q;a(2RVfpbU?OQdCp#D^|Kdzf=hW1Pmsp?%<>ht% zB@=%x`G{hrGKPVc1y&8;Tw}X|owl~Dk2B{?Z*`&Uhxh7od_ZLy=&M78-bZHxn%O&K z0`QKtwVAo)8jPSkJw01oOy-Cj$JEqRSzTSO;xSMdgyYlc%tyw+B7L1#?b&cABuoJ? ziHZ2&?vCQvgzD(FyHZYHNFrPRqzRgT%g?+#s-WwcnVBdorEJ;Ib8;M-_+D`Q>`Z_w zmOerH=vlkL(Ob*f$rfufGgYIT+rTcD+(TkN1wE6^w>i6%uTq+mViXh=MJn<Upfm;W zSxhtxP_|@}<br&<B5nDdoo^Q=F7~y29}Q|knWY)yt1F+V?0e7_(89$eYG`;|+_h|S zg6pT(tSigPqP%aNZcX<T)b-KUb{91wgf4F)*Gst6inM_~^*Xi+mXJ_i@4>;zsV#9? zkew}+rT}D#8Ah|nX4|R&&9(JyLqkJNg|A2uxW|e&)qLbWRMgZKF~RW(dFt9;42T{C zL^XOBXDbPcPjJ~?5~8~^!BRm*4gZeK4iDMemy>DyYMXbE8vBwo*LQMcei`^JIT~Qv z&P#;8&nc7Rl!HA@E~^`r5l_{{gMVgZ2&XCJ4zN4#FT9AB3|+&=-B8!iDB$?!OkG=1 zaoHmMRSE}tHCBoenwsSu5!*`PzTiDN^}J2M>s1}zc9#ll?U>&GJ$wf=2gr6~E^oZJ zaQC72U2eS&((J;5-Rwj$u`4?0YCq1+KeD{WngRXrBa8ZlfPf{3cz7O_vTB@~YTWLY zLb7<>7h=xg_5iQ7t@|#<ZEo|5yu8}9w5ZozF@u|V*<m6NHABy%LSlVf7S~H;x9d)U zKC{;ZWQ?(~u^$RFXJ=0BF%eG*QwP;1>4ZXtcJ*v-PGLbo*Zqf93O60Bu}O257%oiP zg2mxji-Nt~{i-(yJUkz#xf9ONo#^5US>C*Pr7>HuwY|-xeXD4Q(_B+S)BJpLq_t;Y zqA6H&gY$T0B?73|*kOHreQ-Z+T*c>w$phRU>?ZyE>yg;T0X;E-hlKR$AkdTR>cbyF z>4zAwj`zKcVqb=|A2xU=CaUsZ^YHLML(|hwp!wM`P0d+TGYfKl=RZ2e?xLazMMc&a zE-jlUU(mvNd3X_o{NB=RZS8#|BA~_noSjXTrD%5Va$-ef1xUVXZ<vro)};7e&1e@= zdc*+%8Y1+D01;3I97!@xMy}Vd-#@nm0Kj}&)T2J2mmxub{Tg(W{(jlc&YwrCpTeY3 zLUlhFlur4Y{bJEaoqf#E->*!XA6#!@r5#=wTNoDR(YqLbni8R@`VzAO$VV=Bop^3) zlL2-(PEJk_bLHiY+TV1)^1e2Z5?XOn52iQWdz>JX9fu$IRjRo7vmlap)4fcPUvPa+ zgLF#F->vo0$cS~OH&`so$*G&XF?WJf%lb*I6zTr@D*sGm8*@L???%U~M|OcfYqPpr zTWPttl<A-0$KzIo&V1?$c8xq&p~3Cw2ow|RRG+?pel7Y~nwgdEj5H=Ba0eT@GqL)+ z<}1^Ng`qO^6?R6D9xe;y*Jf?cUDZTHJpC&*5fKt1g`+z=*)@AGCFcv{g^IeWc!FJ2 zup(R(&ItX~tbb1%y-?@W=n(|qoBt=Oq1=kYhl{i46G2~z&@=8q1Nz8<@aUb5$&1rg z!Wun{4#8PZDMw&UoV6<esGFPm|IrEff7;KBv6x7ytgGuU+XA9g(b*=MaK6Qng0WKj z0(ATog{chQm@i9T;93gmJ^(~OmiT-11bR--cAU12i-It#^z!tTFwIl|Q}ca{tDcb& z4sp2%``u8KSN`l>W93ofyIiz1{I0L4=MLqj%l4=a(vSje?92C>ud6R7_KCgfb?ZW( z>}IVOdp|T6lk@Y2q;P}M?aKZ79Xg(1Z#KH-Q}X#p7hcgfF*k;SNZi~Bf8lVwkJ?DA z2uH8u_Da0O$;i+f&VXw}oS#1rsv8U+$^{W&9R~|Pgc;hgpV&qI4hpLKHj+*mri+q5 z;C)ccb#{P|wpl#cvH*yhRjPNn)$XMEV3jg0g74J#ta<8u#A^MtXfo{&;dOO&){9Nd zR_3P&g%0+$Nn*sz`nMv~;wH4Q8rs^ifR#u~vqB1aV}Mm5c~GMu^z_sm;SV}F&K<7m z>+2I@lMLv+DafZ?VM<YI<i<szq-PuH9o3|Yo^Ooz=Dk8>))p2v1pSumAcco#EHN=( zS`uHS5s73k`BP^E08WyxzJZ&~%%*Hxgui$2>5xTxYOyq)%H`Jn>zA!!J1#0JUFnBY zwcG6jCTg$=nB;AUtVH08?}02B9zJzp<GSrsQagvOQZ-rl5Kkm6IVeFnGgt8YqvA?P zoyVbE`s>u5w@H!{<CCUlW`slpN5pRLqjQ)O5P`I6YGZ?ug2`jm)8~bB|Je6yC{|}D z6{z&FF5Nj|{m3bpiLS3xKFkktE*Y%2p`(X)M=1#lzZ^*66_o+X91VRRudQihn%{Ef z?>ud7`<J=;FQNchIl>?K++m=r`w)m4ci*(DmRFJ7ztNY%{?OS^XY%lwm04dll_PBN zHxnHlW!1*=f!ofhU6e#_Ru&$s&3i+fhov-r3P&elDlvuogM-bDo#oA4AE47_XLkY+ z4aj`s?%?9sy>nWcCGuI9s#RV5=y;H6l~C3&v;;gC4GoR<n&%W0R`(5}xG17|$}9wZ zb#+85_(RJXH|zGb=4Td@(a6`KssEV;*x9v!d(OSSQS(D@+%fb+(pLfu2p#>*{TfYh z(RZxkBW>))`nto)+H#paBa{>=SZ=;<j)5@<5Up!NP^!;e3fEF~1smtsWCBb*_mkJ_ zZG*pZ#TQ5Ww9##!gN5PYX*ft*TN_v}RB`%mz5~+$C`(dVEJq^<=;*gZBPFb0Ro`4+ z3SPUN9W?U7>0OPektKR_zkb0_q0)$esWy-~;{10vaZES^MIIC=lB(B%Lc?QYF}>^C z+pmXNH|@BL!8t+o0*xkrTvHPkiuAHHM2t8sQAbHL%Uw%Tvrv%vlT=oz%m*SOB4Dkx zI|9nBsn(_s!<Nre2346F*1^oiVo=UC&OV;ckjrCFOblb=V8_lw^i51e^62gzB->yA zd*{~blIn!<K$NVyKyG{<q~K#o6pjc5N9<9gl&L3`3`vY5-`XpFGXFtFTpsY@LnD13 z!`iW2y5RY3EvnP@X;M<(=g;<8irgm7Xr*Y?KToSk9~^8+%nXg{ZI{c|)?oP##_Kr2 zxEMhkL@_4hd{$O_Kw;<}9DGg3Bs(bKbt=t^QFRkZHH$%p8rTY)Z%dm^Q$s^yb~mEb zL0<d4U#u5lzcVLW1Z-_xR<cmxC&_OlsR#MI+kCx+3bL};Ic$aW-}`AXPEJl%mz7Ne z!fh9HxU!e8@ukBcOvFlE-KD(j0LUB&mq>Y^?p^`KFTV>=9IJGW1euwsb~PGYKtqA> z3B65I=#%L`G|Gne4J+4lL*Tq$;WofSjF$AgJ9rTuehYY~GHvWutA&wSVPc2g8#eaJ z&!17j$H9WMkJ(j05MmHRA%mB<!w{+o&3Tu%^;TUSz$^ag`lhC9oA^HpGaSx#D50+s zuUHbs+U8GE_}YBU-gs+;n8)Tyj=sX~K7*-&b802c6Tyg5Yw<}*lO>~+Sj$<^(8D_s zBjn|3pFoOvY^-z?ECy05S+1obd%OH%;^M(uj5Bj1dls7jOi;vyG>YFapAtsS(^vl# zd1VgcHXH!fs+0H^WE2!CcL?71VvCs~Icb$C#Ufq;faFY;Jkwv^SQ%+%m)<965FcLy z_yD^MmRnd+vE_U$8!CeKcd?5{k|trZxApc0Pb&DVZp0FfZvH#Hr<L{MTQn>yE34AB zrEFjzf_FO)fbr1n_-O3T$Xx(7g@JOWr0MkM&%*h+GgK3ul3rXa=%FfOVj^xlp}n#* zlL4xC1eqY$YlEIv1ZmOqDu>NggN^xSSLc%n6<QT)_f8U0QgdP9`O?*39$wy?2j?{W z-<akZyo@xL!zYp}G4(g`olgMW?h<_Tj;YSiB7-*|V#;NNys3vFRx0#lr&sa`hBkwT zqkh2G9!wqs3br}4;?4`?H1B_7;s0MLQvW(AXej&{nNZfq&!0c1=>b)Z)~DoX7t0L} zGAPMY*7#r=5L`bgJPIr_CTdE91}t|fS^l6Fy~#fqmK@a1E!Y-xv!`DGFr9VeuT!9r zkdnfc7RhMz)Yh8I&!-EGBSmi9+H!1!yVfVus1{3CH0zBo%zSS~y&8e#!fRO04ZWQc z=<Mk+26AYgOr6Kz;hms$!L?z5R@1ky3ptv3h1%uIt$_|evALsvg3j5tVjKivJ|k-R zNI=3<CO=N>>pI<j<*cHz-d$r@$}HU~L^05ny8m!sZ_hG%n4OpMd1mIiSvDZ(6F?N8 zf-WD#rbNv&t|CQupB|lG{P_c}MPzA|Rng1qcHF+Ka3?Yxvl}f<Pg8RmdaI(6WiIu> zG!vi`2=p-(>G}M8DP3|O3pyAa(REO;Y*|^wborr6ppd?$WtrzRT~`Eo{!jWyfGM)F z0>v@_Hg?Y)b#lqh-q3%6MG}z!Oqj|lMBl9h2hns6`0TX8!n=ETp9#(}w;B&b#4n?h zlQx!Xy3KZhTW9`XHPF%qOG8J^$Wxiy;i;mxcUM!RVQyQ$1!!aA0B4JqoVJXJ93&WT zg<qaIdqo?&v&)JIQHjd+_xBh5q^C9xKR?C_>)`c%xH_GVUdZse>v}9u!T4{zP&sy& zm|*<spC2a=7C}N`fI_=XhyuvNWhRT{2!U4)o9&7AeTZ9lY5Jzfq@_>tv!g`RzW!wy z7w@4T=7|NJRdaCnhVZvt`6>6uvlpPXBqt~1W8Z&HVa_R6vNqLoU0K5#fAmP7ZrB@a z@A_m<*5}V9oZeDhy51ZSUrDNA!}$(wnps!`2Z@0E234K8U9S}2?9_3m7vvu6GwYvP zJt0$b^NNxZ684?~4<#MYs*n+21ZFuoIY+MO%C!B%!|K5I==U07RYZ6MS1RM~o*0`I zt}zf!Ugw&9y_D9Fq^YHdONiyPb6R>}at!>z{4UU?uHCPdX$x;2Syq`@?fdIYfS$xQ zgN*1eS+Ri^N~V=$Sk49Bx)&|W?Mgtw@5w*DZ+;no3;^g~5(wa@wwB`78rL_mtnQB^ zfP-pQ7vtnneNa~~cy^GJqs7Pi=1oj5uTzCno&4UyyoM4`AerS4zTK4sv|sM*AmQV# z*}KV4ifpL|DU^f~faVK`0A4)qyW517Z|T8|UYhFDnA8jK*LSQygaauJrJP9lRE~m% zbeVCqxiU=*a{zGDN1ZP4+!_#39Z<)W99U8FWN2|wmaxLZ`3wzJt#vq##(H|Pv$E9h ziXWq^32&_sLRxZCxX7A7;RE|GzrZMe_oJ#R2VhiB0t!LJ8!zKc7p&SLPcA}&WDp%% zFNXk71SW59Z%s6{tO|pCmLj!$V(0Sr+L{^!#4q);Rs`}j9*0lEI#LKo23YiYxw(U7 z(3%~nMaQe^>SHQq0Yma`f}?*n>oB%;<$#|EQ|GHA5b|OL1rB;1Eh*nY3d7@P;xO(` zJ{`;7K>=a{Bq1+fUQuy=a)ytr3BIp1xtzEaS?DfRv60MYrU85vGc#rgl!!k)y~VZl z;V+*SA_Tgj1R5-V%EEA}Q^oq<1v^;}S3;q8?^3dZjDfuLCqN-h;VXdD@9q3FbZ~{< zj5R4r5hVIN#^!gh)`b1BS8V;UM;bL^dnNVy9aVHnq@V})>*1Lmu`}(Xo_v(sdd2{E zQyN4VxO_k`kC^B%cl^_Um~Z<1*WaS7^Xq@lRsE~p{-5|0+nE3SU5W{E8X3_}%Tv^F zG}LgCJz7ln7PQ*?DOyl;U4?R^Ggzbb0Z|JSf~)Efd&O#dR~l?u0z@1`!#D-Aif`Y9 z$eLTaho|S~%d=|1FUdw;V2bZfSeKQQ^xWJ$TZHrsS~X6tuYn?5R3xy_t}Cu-vfeW} zn}rQj<ZLOdC+J!w9{jkVl*QLPoc~HwG<*Mk)a^EC-osmv+~?f$c3RivmIfCENLosH zY-b0+{j4mFGBLC&;1#M)g`xbx(5SHGKB`e#P}kBL8k?Fre1x?Vri0`$+`2wn<<0+N zx~i%y?Y-IN>R_(5G;Oq`&3v6)#z=^2z4_YS9;k2QGczpqnPEhn1<JG_=ECu3XS_x> zz`bZv_y}YahKElc-T4>I*NjY0Gh?#X*42QW^6FK}p+ISEt(lgBt%I~uEKi*?)^{2I z&=!43H5`C0!z-=ite-J!tHmGi&u~(naWLav*j^+7tkJ&ohPo?CDD8*J5Q-1RB=D;? z`ok-$s!B_%&d6Eg(gvS@wzOO;)-F%W`ulQrcg-@fu_=lN^O#Hkfc4zV>+aZ|v6Mnq zw*OB__h^pj%?(mF@4BDg>X&etvCBupn4AGYD_Yjw8y6h5GW{Uq<Nh4QJw+=?JJ71N zQ_LF>{H&}q!{8V4HXrx@;UPx>?I-cYuc&h7eijtpZO88eF9O4=eQGM8`{TjF%}qi% zwYZxr=o;9g6m1zmkQ_+jb-HbT!OQEhckDlwReXV`Mms*8du<m|lnCGBmT6%oi3KUE zssK}yE7GywHIsC5lvrI?s%~n`@j;~SKcq39OMtlgVx_Vq#z1Jp#!NppIa)Gfcy69Q zGL=t;<kw&d@7Z<p1o~W<Xq!~Azm?5l4PdkA4M9M7A_)1!H^(0ucLAC(c``AZ^Cysf zAY#1;h8y*5W3KmJMS;L_u~rWa3!BYo@ph-Mh}vRi_KwMw&AqK}E)sdk%)x;O85-gM zdN(t3!(VO0LZ~AozBBSat6Q#nX?YKz#e;=NUHKaY><#pAW$BXS<atQ%AnC(6E^r-+ zix(#*&WFCikNr**8isriQgivMn5c!kfKEmZEU%-HKsYIOz@yp7iZPdt?pECz+&QHA z7vDJ9IRkA*R<2f(FH3<2WNdhN>*s5uN4!cG*vby<20fs^uCXF*>@#3pg6jXHu(02t zl<ug9P%&5si5CQP{BnhXpy6KQ!9QbOe)H&VG0e~J1<WeZk+QTjsyOk3a?IheM2XUf zwS0Ku>!=Vq+Fk(NDOxiCkv*G=tNx!vDwc%31ojZhmGtya-O<^UI!({5Y%q|K711ZL zc5+@!#@JjeB%=kvL0?c4e;L?)`-TlYXJh*|Xj9|1%L5??7J{b^D=+v!pTEQL3(*(Y zw}Ge)34K1E_md}L6QER5h}Y4pACJV+#UCuxk4Ccq%^(~Z#^-Pi0swBi=T24(`vRcR z)e+apUQJobS@vPC6d3<?*`mDQ$C@lL--E=80%>kMy?0*88>anKVMGywwgN#8zb=bQ zr>;o32nx6#HJKqX{iP-Y-+}6CJ>SF_-z&~jYde(<X!%p;_aSIO2Us3lLz5-}fg&2S zQ|1<CoE*p23w1g@3}k!hLno}Z;+CLh`Xk;LQUtie{VSjPe_coaWrGZ1HV!`uHr!c0 z=wAMAWU{y#7yERs5eMsK)(d<~9&MYux@vg%u6ZA_dKvm>9m(8wOG^ju3Q^PWyN6IX zl8Y|7BJSR%d0yP%1GDUN$4d{7t}Q|b{0>Hd4Hmr~I`r^EhQjns&$_%f3o*DzM!{x~ z7?hykxv#8Xqt2Pj+})N9Pi$deDl95eTs?4fa*AhAueILqT$k2;l7gA9OcS(}9BNvD z)qLMjUnrYvz8)-LxRiK|o<_kDY)C|ac{+cg3+&Q%T=2xAsBw8g>${VUcMP6UNuEj! z^%;tJsSg*tMB&cBfxW)wQB%8!WokAyHa-I3l6<3^J7%AQR%XLTi{2NDf4i;CVv~-# zy1<kuxIIjia~cdLsOHYanxd7ux%R*c!VD7yk<dsYcK4Xz$s3rUWP{^72E$_zIs*}w z-38A|*)c>YL7gyA^eWZ!bh@McWc;CF@p1`l3*LuIqmqKROy70TIx<WK?$$B}Sq>In zxX%GK{eH8}ibvU8U%yF1>IoVFr}@~{yod9`;-z>hKzfnMT(|^piu@+OM#Hv2Orz^i zus^jP6Do6HxhZD?X^f5LMFH<yg$oY7v$IN4(y~r5ful#sNlA-dyKR%Ynw)MUYyh2o zYUML1^}mrrdHhMG_@~avb#qrZD&uPgYisLAzWs-uYinyHd;+J1;hNbZ{g|OMJv~yP zDxiW)JlyO%S#b6zF$edrtl_UYIy*n|1(>~zlF4SK#OSDXos2A{gHlu|O>cfi)?t%g zuXHNx8Dnu#UVbjUV9nu2kh8KQ8kx<f!Tn4A78g$MM<|)DuCMX&@KGL{Z`JsY8AzOV z$u&5p`AwF9iV3tSkwMuX3fN5A3Tm%KRDrt=r}uu(9;$J?5}Mmy1*=L_<Z?~4v=@2~ z%8GP6lh|O=?4TDjfeeVb4lI(^Do3PpX=!MnL6#gQz;_7ye8SmKd48eY+?PPg>a!p; zZUErie+^ppERqI-UI9!K)yAs5v28<u20+*ff<V`j7r2&5Q)nn(?;mWsZ0{d8Y=a$Q z_ZDl^^0*33os&0t-pq4qYG~ZopV86A)}2JA0+m!(S*ygc!&AkAS%^G8k${AQ&V8YJ z(dTGqx0jB#XL0(}TX2!*RA@`Iq{CnsG(OB}Ri_b^Rq8(ALl}f|xp!(o$Y{ve((MJR zMG?rUNv_+i5sN;+!1|_S4fhr(1w7i31l1P_WZD>zNO~}_MZQcb4?w<_o8-+g@eVc% zb?0D(4@5)&0qWI;j?5(;CsTc1o*ketAlQb3^NgAQpR{8~T-*lm4z4^?!peD}OV`L@ zlQ&J5<`(MeX4X3A;EJ&b-V6*4g~&~YeNMbz9bBB3lwXgFwFF^SZJ&FwG*gLJ*k&H} zT8uVkW(QkaTP7-&966;?sR;?gQ@<b9s}C3FYU%_JiQV6y9+1F(pI6B@!}<DcWfJ4N zSOT!q-ceqd>Wzs-cD7Mhy<O+NoEF`VeFW|_z#8fN{!6E*0T#5i%UZ{|zB|yeQ2OJ! z+8JB(b2VMv)c%#R@ktQu@_Eo15=w)h(=!4Q3yX0_2oqWJ?CdO57Ko^%JeZSSH<r)D zm88LMx`)F?8r;vBbfNN0^%yFY+LB2`>?hT!7jxYb{l6s|qf@T?IFX{>7Bi)UcBDJm zH1S|&LBITjJ-A59!HxmMl+dAeJ<FifbeyiB16*aYAP3tRJQQpw6*HVl`XumEC)GWT z3)8sS8+{Nly<lMt8Fsyxh{yeLYT~lKKKI~#Zg=szpFvhmZoq3w*`{FS#I3lg$@7b@ zZ+y;09p?fq)28>I;n}H)=+mG%myYK7`>P2n^3Rkjzkb<;8N|Z{eoL~qn1>bT%WVM9 z_gynn%Inyk%*+682ZPfy!u(J`BY=PPl4r@jR|*IW%H>JP^CIaSD<yN9M(bLrs0Geu z9`MCYerk)1R-EkY(Y@>cE{O;I@DwW87f|jnD3z6w0WIfzlxcSHMsL)ViCjtPM4$oX z)PPWk+$HZ7_2TU_0Uw_eYQUnm)12qP#sw-TKxHo@7VhjWx9*v}{T4mXRzq=uVTr`r z+H)p@pF?>ak}iMl?&;=ai^%$zbreWSJ^_h)refDK<vC`z_y!DKDS7!qn_LfYUXSyK z;pyR0$L?Ohw7_UYsE8G4kA>cM{i!}zO<)RP;|sUIf_G><6ZF=?A}lX2p)i~@br46I zOpASASY<S)9|eWv;qIa788X6X&H#4kjD|+y^&i@yFe4g7VhCg&b?Q9rKny-(uJI|! zLfd+rEm!ukesqRO9~{d1?0)Kn558jFX>z{}qehMAyFP5H(H})ce+%%P(>)t=by}Kt z?+r{x9hfy{<&Ph=bk}51%aLu*MyzQcUkG~cj;l?0maOBTh*Hq)9=OalKSylib-tf! zy39Iz@b+jA!K!uR)?8Smi3JhinKQa~hW^c0J2`^RclPJSNYtBNx#kakf==Q?oXsc0 zAy{>kS)$~3Cak5XBG$rnuNTv&i~!Kzs&gEVS&PwJw0<CYm_m(e`?FsqnX?N*IbV+d ztQ-;l?Gl2I#7(ydn!pT7dr3GLNy7g>k*t4#ga2*}=D)y<AzKU%5CySV^#E~v_iF<f zhh=G*dmn!$J;Tq1nahP=G3Tu?evA9e->?0(JKnI*`R}jn%}o6+FRdCUP2-)aZ1~gH zPY;ev3F^Ef&o3(*>B;}x!eBN<bkO4L><lbgb1N%C?h&IBix)7D1VWGt`sX|%#E5+4 zGTDBwyY@V92@(CbSN5ElScTbp|5r!GVtSf8;Bhb^5z!>)n9)bRrY`N%zS_dVLJCth zeEe$Xywi>Tf_$;Le>;zmE!ICYG9uu0{umhF+ylwwOH-l3BD$q+4h9IV6F{j5cGfpH zCwqq7vix20)k^)vh|;Jv&Zv{qHkN+${@z|a?&p=2PoV0E^bSzRuC4BGuB_;M_)boM znF&no_*4h(*M3_jKhn~eL6#C2rP<l4PEJN6<09z}Tu@D|+ZS|#K|K~23}!u7qtV0Q z>~Qj(gOUgWV?9X;v3AVMp5RujtXhEr>XnOfHd-QJP|sD5G8+KY?U4}!Fqi>4#rL9r zY@4VCY41NnDIlu#0*6AGv_$rcx`S~?Ow6;x*=9OkY6k<`%V-XPp0@J*I(x9l7bWEr z_{<X1(y$;9Y3NHOE>NbyAe-^H-g^RyiJ6kgBdGdk`%GutR9JX;p$t`JRoRQU>WT{5 z^*Fu?J4Am%;_{lJCg(*zZ6IL*eeL=RF}F%SYdC_0mjK`8OaF?<VA93uH|W>DBW^%q z+utWy8A#%CbS?fV{0tbGnwrFr7*DNC3LC?|+;Njv{qb>GM#d&chT-GkkqFumK;HLf zH(-RprMSvQCGDPIqQ#kPTSG(fF$5S1DJkgy#o<L)d9_34=(fpVO1@1l9UWbxGrwfz z=lFORE2}dgs=M9>?d^Gh@c{W5S0`B&Yn`eO^q?SFS>OO+2J$T|<hKeqNN}JA9BXGM z9|%??q+%o6?x4QrKaK6@K!AuX>cJ8S)q}w_71-GF$+(ryj?Py(j{!?RzG_Hc`Gk`b zp{$~YJ<G|$!tJ#o0wOXhPDXPHI8_|ZB0eM3v5!T<TIoW8C+jAv{!YIsD-iE58)K4B z1?rZXn%eOtI#30``@uEE`{?c4w+im==BnrX-V{vxay{Fu)UU9kv>3q{7u?&IST2sg z>(pke^A&v17Sn3}cdDt`InM^Y;ovZ{G~e55SafUx8I;PnQ06dGG1=S$j@=g`(dM5- zUS@|Az(K&x(vH9HObnlo|M<@UL8TLW6-SkokRJ$UC!gX9HbbPOKt#}1F%mT~*%T%= zDVMddC{U3H!SE0yk}5MLhYT4imGS4;m8H|!B1o}aagU*Nj<o#J|75puPo#kb3ru8{ z0sti5Bp`yYmmQ!+MTt6!il>>JX@Y;>)26>A0p7RP!9Ya`bn~VrZ?G(mYHm&s=md;Z z<^K@7+1Yi~$zz3zLciAIKB&)tEcC>fYISur@cz^_KB#L><33v#bmo<}w7VN5^vW%% z2QfsDMQ}WcxhEZ<KE3i{sZ<S2F}r-)p`E0Cf@%*^4*r+bz@yERk;-f=jk2-)D3qlb zN?Ax>sA2(p+708l{G54{v&X4}tSoE?TYI?32#?Z!fP9~sUakTS<g2M_076b?W-2-Z z2)@UkSu8AwSwZ}of*Pa=R@py%7bGYHb|^@JV2_4}tLOI+q9G<1O;%H}gv*A5F^F!q z=Tdmc2vqbO?`cyP^%krSix>}pzxZdZq@a{`Ot_703XE|9iB@%D{x9^89NfgiTL(n| z4s6f=u!|x<f(DF6)!5;LlAA)m`|2#r&7ZL_f9hXxb$2h2>-7lv&wPi8kr|kPV>X=m zS@IRxfS_;lgolS0*jM*YIVRiYm7beg;Z+FKCI2tc!P76?^v{T)o*rpUjYQ!6S{a*z z8)i4WP68=nVEGF)h$@<SI1e-ey3QTxXjD3-pBBZMGYEt;=<7H4*+EV{kZKBj(hEM3 z8bc!`rG+HgUqU67rE1ziuX6vnOGlc6l|9;LVIin;w4iUI;=8gYAU=AxJG_cSEh?j4 zqX!bF&Ig`aeGMJ$EMNctbmFH81P80DYMPo3ueVp`rcvFSbOVL#*0%ggh9p6#FGqm} zFLr%XKIMJ?y1g_BY0_mlACy~AFg`T26vw||iw=R)FH_ur6fc;SYR9%SpV>b>RW`T* zz8M+@jD*z(h+<%zPNweL&@87oCD2Ze6wN-Ez5-(<T{c|qx4sg94gxL+-d&(}f&8a~ z(rR8!24HE>b4(O~<mLXV)t@}B`$7+jHNsWWQhr&(kkN_uszNb$5dKS#{qGv_h<6s- zMC`fuS1@05#V70iv&N#N_g$Nsc(4qk&n1Qp5|LTt)L~>6@hDq(F45to8HO{1=?98? zp$%?|eXQA#?02_MN?zbSoZ_SNW}-V6A3pZQ4E@SEg~F$hu^d*>;=PjWk4c0mL2OC# zIb-=tLrZ5G7g6Vbep&I)mje<c|9lr5u1cFy`s=~#Hle(n4k%im0lNSisv-5$>Z&Tf z$Q4W?J@6#*K`WAKj93hLKn?(1#CrC6Jnn+Cl8=2B(6Vdy$g8DQmvL2UA$Z@4MLZ<R z^_FI8Oq5@TGAjR>1<>rJ>!~ry0)m70ZMTP2dKG1u8ebPS77<M*zk#3w%{^wVmiKLY z6z9ax2cWlr%J1&(4wSdsuE!AsX&_N|(RHv0CSr9xoUFjx1(9$QRNn;`1FUOpWY%c9 z%%X<x5|~a$$#4ax1yl+*m4Pgw)^y4Q%q<jz10!QFn-K}-wIDr~?@Z07I{+BFsi~Ro z?1S-Bkkvr)4c}cfGdI6>7?d+OlYcnu1@O#dAf=+L?CLt~(C6|9Mj57R+bbpbU~h53 zkeNk!xNyT;iU61<7;+Q()K*dHbc||$v3KWh`sy-M3iImgWyt)#?qEy|?#|ZMcl$nQ zsZwo`fO`Z$RNaP~g`kLmh{}RV_+JN&K1p0|6`2*6<CAKc*;%F*yA2Nu)BwV^MJ~>t zcRbYA)(paMPPUBW8QrEwT6Z$!t1R6f7;tbvj#L`%t&);M??&XdV<VW)-P*MgD6cG? zt!WZ(yZO5Gr?_dl>f|D|-e$SLrb=CNwyD$@zO?VNQ8CD5-5KBDlY5nkzKrs`UCt4) zNa<4jBoSI6z9*oCM_u=E`0NzYyTQ=i-P#K2cnO6x+n(Psq=FV!Q7xTWcFtI<<rHo; zI=lM{+fGdlADWYDTHaYX-!fLG`U!lV&!1VK%a6NA$;qV9()zZQzV%h{q*@520d%=h z&*XipADo;ltggO28a7vHBJSjb2UzTl(_$-_wbZw=f`=Tn-GN$wZc|uTP=Mf@>OFnm zD_;*xa%<{ES4+x}7zvU+onn1GJ!I%*RLF-#hnV=VFj#FuU~(b<Kk*Gk8nWmBkeCoh zqE7eHU8f-3fm@o>&EYKanOs<4rrXt-NnTU5egaKR&wywzR>EV*o1!=?YkFYfJ^{o` zt*OZP>JZYm<6~pPfof7!s9T_#Hf(Ciu_+n*T=At<iHAo7Iz*AI1;UWR!lZ#h)5iy0 zh%)|}1)(6^EtPegT)p7q=q4<jF(`0XSC;=0wE1w&Nl=o-Jg)farsh4iEhY+&PtJf? zf4jD71!kdny;t7wUBfn?Fl3~TNL_c6mc?ocOpQ%nEftZr53PddJ$`Y-eO_Mt*#$)6 zS#9KG?0X79K#oF~!i6((U(nO(y006U{PTyt!*{U!e-cqV4|jWl_&5V5CMGO|eO=bm zoinP#<4)Vh9pLy%mxt7-<!HFS^OYm5QXuR6p|d@}$W%{)Z3r*4qkRevVq<5Yraw32 zycv4-f&Lsg3Mhe!+Ddr}G*k3XQwJ&TL0fiodYz*D<R#?@S*ZsLuE`rTORGKbV_;k4 z$cJSQi|z6Lp@xuW1Asj8(ZE&6fDhIm8m|6RL-e_+k%LTOp(XHUfpJ+^ce?Z>4LIW9 zx>r9@jZKUT)WuKgXwzZ-omBff1Hk6&=_HE>&Gq(yV(;cKuPGiuHZ(DzQ)VjaEJs!S z6Bh!LY&u>>PJaT1^7B7~@tGL;%ZZyd%@4PV78bqZ7V)Alhu7(zJh(gUAMo?;?wAV; zwF2>IqR>Z{Dq5flTSO|+9i)+q^xrmYw<>7kJ(Mb+Z#@D|skiri6xMq%9})3X4hTID zH`|(i3J`=6_>z;;0t`8Tro_(9E=cHNX}MH`Lmf$rs|{cl<3LduKBI+|m27?V$lP4T z8)vhzOc3SL&NJ%<sh9X@vV+^CWMF}_8s9erw%`cS()RewA7v=hs?f%QV>0;o@cVSx zIBY$2-W?1!do#uN!u=>K(~{TqndswQ?UI*~s};=|-6h@$`-}oCq3$T96*+S1&Z+ro zOoBIzOoE%$$%0s#zxx^ra&iPMHs)TxAFX6#_qn~Q&(H6nR$&=>z(R&n9FxDvP2z-g zz?X`ToOdy%8s)j~IhQ(N(!G;-iN)`H{p+lYY(m&B;P+?HHk!M{+6c}3!(9~KwGq1c zhl^XXeTm|j0w&=<4-4C|B}H*gxweb75tubA&b(5hiT$B0<bWhb^0!Z&Z;BT7vxrIu zAH!H0;vpg#Qqst)mDRTt`<#QAMAwK1FcZ)TDA<zz^<TRD8%8U9O_v2mW&Q$}OHUm; z$z{EG{~=UE;9GWoeB=vKq@NRk=LWr{jehn}{PjB{CNg5JKtNCfkj24#%5&o<;Zg-Z z^MAZI17PT}FVL&iG0WS52}&DHCQxSM+w{{P(+sV!K87WsuOm!V0b(g<0ag_F8;FeU z2F&4NfQd-R*30JXUIAzO*+%!rovV8W{}wRE7abU=qN8)J^lY|5Us}Z}OJORb<x@n} zKu>IOwKS!tK(S!&X=-5L`ZrO!8Y4=Pasjq6v^j05;5jUqSXP!vrjDG{mN)t0fxLgG zoWkk>u+oT$-8d$y>L?s3&CU6zUmwylGMbuO?rpN1Y%>0|$psFSRPj0468YNFlH<~n zHH3+R0D@}R-M+V5Khi8s5j3A;0@lLC6Y<J`<QdWS78f=Mn3n-`{uDYm$N>5GG1o*u zc7ZjyzP`<BpV`~khgNB+l&4IkExGr=ayJR4L0qp|-yR~MziTA;JNR(ZEuLyL*El*d zf(8NQ=;6v1_B2-G!}sDi#Uzqsd?pQj%a7k+FcsASFyDWAcEt4h_5Wz?yTY1^x@}dY zs5GS)sS1K9NbhJ+X+jhQM5^>EN(((AP3edM=^`cc7AXM&V(1_}p@$|tK#<<g@_#({ z;of_`^OgtpW@YcW<{ER%F=l|m6>waPmvagV04jd#@osNt$Hg8H*l$)Axsv{SFEha* z0hA`)%WgpRvBN1<8)&cr^erigcNi~&^#2Ph&~Nuc4rK{G???H$Nkqt@EWn_Kq_1V* zk^b}D<4Z<C;Xg4k0cv&@cJ}-%)iepm0Q38?4GqfuZO9|>bM%s)zqajB0+Dp()iBVC zM5x~Ybgi_M6exnZSQt~2JQ6#sO1%C3LDr~8m*er$2jpmh)}p+;WnfSMXavao^z;*M zGlm1P*l}B=^^!y@Ik`-=<oTb;!^241Y@m@o|8r=_Z()1%>dZ6KbV73SKV4vf=Ggd6 zpyC8KNli21U|#`>s(^;-JVA;#w+Iov<qV=GcGFT$<A;?POcn++2M!&wkk4Kk&XgCW zQ&f%b@Y4>1<OmF5pppd5`=hh9N&6SiVFXGN{MYBQoA*5-@5?so+G#K76@`0<=2hz0 z${QgU<vbTcVzw&W4h!6L7P|*MACDJUnm9OLm(f4}VE0k1zt%{ihzRc`4IXrFM4=D@ z=fGnM&lqGOr1+lgneKF94v-7uV|Y$R#t-zucZKRn8E!8+;}6?e{%o*(`>NM&HPFz& zWndr!nzVixFeG6nNbbsE2&m?n3B6j{9WN&$+swsiSa&zvGKOXF>tjhwoSdEqD=iU; z4YOP1aaWBJxI&uD2bQ<5oE@y}rg5u&z<vmVWQ_8N@yN;x3&@=Hpi3KLJ8t-TZm3e3 z)cOUywfmM?zPlx=BB88BNf|<@_sA-{H9Rozmz0_6J$Z~MWN|rut3AEK%#soeR(z+R zB%hUo`{cN**T=Vxg&QcC8vXZ|M)sF-x~9G;*Knh5-t~0+u!&pB`x=Iz>j~IF8{h33 zL%|UO_eq*w(Q5Ayn%;-q`Owo{Sp9boi1@q1ZlU_tO{V!pj=tgXD0+5I_P%9z5a3ZU zEA)_bh>L<k-4;vF%7O<KFUA!9rw_Vg@~XJ1p@D*TsPAb?aw=iO3!0y*Cv1CkSc~Q) z3}j71Cs{*<5U4bh>m_~<v>dl)Y3w8qiA3Vh_pI2m??(q#;%vN<GDzvAovp2{2zb~= zB4hhJl#l>-n<>&SY~rSuuNyNlnWTrvr|BaH*{DNv;CJ`8$WM<&5t={%SCwNkgx8zl zSA1jN>R8SFh3RblL`6<k765&g<2CY>r2~Q`2P%r*XE{GXUEs&7-=F3hTLpXB*;gaC ztePIY-uHDnJ}@rC)$a?MM!T!ghJ``3L9rWGGd!h2|Bplb(qUbT^w;875iK3GOYat& z^YCu{&CI;boWQI_mz}D|8nH9vAQjZ)WfQa;oj@vUpQ_)ZjH@vaVgA&78?UdjwjRJI zc_X#U<DIMPf@_UqPYG&tq955ypvsKve=Up)eVhe_LV1HD8BX2Y9D?Z)4rEOMIZAtf z0MI%n!3i=g`P<u`H0jqz_V5q<{uX_&pymx$2{h10%ta6g4XRi&gHjWpP3*w|IbSd> z5k6iM`j8JifbO22?-|v)DTnA6nNL%X4zEBntLy627NSjb^Z(Rsh?X`)U@+LtEJ15m zdngp9W}9-`jAxr<ymg<1=q{z(N@hap3SBUO9WO-EgRU8N%V`LYzs8;T5IJb(XE8A) z3fP3=+T06fH{#S?xaHOtSzel%@yBaeRtr46#dtjE8dx}fh0D=HlKuCuUlnyoR2_2b z*>h|M!-j&KytX#<^=<fIK}t$p4g$BcQ92#bpd1ikY8)W?$?C(#FPXcwq<!{co3xDX zAcJUcat_{XoCC10-J^~O54U&rH`YD;<5v3ZTVH7CD;F2D;@z8)jljNAK05JvfG_EZ zgE7$2%xwH;Mc4L(5hz37-9!~Xb4N=C?u^LBt5R_vNq4|M^d^Tb4z09*w2RWudLeWb z;(!Rp&d4iBkYae5K`>{(d=9p&THE7^i(IFt51vC+_@Cy#08zpmU;OpN(2iRQ7Z&y? z`vwv)IkNI{Il0+D9Q<{=_NRb&DST2&Lc(pQPRpHLiC5WBIPGI}_-m9L5CaK|KNe0? z{|L<;Try~^+tz(EER1lq^Lo44S+%RrH5{S?8(Q5Nb}{DV)!mJoTeepK(`>eVPOfmh zV`4(kQBbt_?h)aO`@SLqM@Jk6n-s*AF->2EBN+5Jw8LBp)ittj7chhQlkMCVlg>yr z0Vu&JQ4i0`7--~m1y6A?9;?l}5)y;M4Mz#RFeT4ztFfvzj~yvJ9Gy1onYmliT=f_B zv+}kuZoh|_Pd5=~`-@0meP~j-aQ@<7pB+n%tdtZO<yk#@h8SFkZsuG)ZTDt0%}>V* z4F;U&NSr()=jiD#a-6&H!JO>=eR`*JR8${m&YgcycAkfaO8VTzi%k^o-~T`VQLJ3R z;%F$afL+?uXlOVuEiE1IYUu3mp{6!2klsrPS43pMtC7`?487;+gA6HsUGRY*qX-mG zqADsny^pR}kfXoP2I}Ux!x$Qpk{-Ez8y?b6o_%}H=?03{Q)l<nwlkRVw8Q`0O5v__ zKaiasx47*mW`wu+YvP<-2dZ|X@uP-$#TQDe7MI!xULXhVt}C%}FqrL@xu4qaO?Fkd z+3Gtx&y&9Y!hHJlP9`wS!iK^n!E<I4wM*<(@1?#(t4b9W6*HSsJRoqLlQFr{7Ov@< z98+BixhJ6{5k+qyZn&CX^_Z%qxf%2a>%BH)y!5`7aE})SDM?A$cYD4$O-q!mD2{Tr zfM||luUYO$La4B1_^LLqf@R6W{#2OJIM<Y@P;5tbe*UsgP=J%uMP5b*hBk`|&8~Hj zA>2kLmX?aW)Q}l2KRMWvZsvsO;h20duWc8&%4?wcy1<qAC|K=Tkr4SKbXuA-MbJ#z z+=jNc_Wb<R^2$1h*z(Fs4pv5fs@>H#_a^C8wM{`WY7DVK>oOvoe!x!OiRa_TkLwIO z(>G<~<6V7ykIKq`o95Lq&U!rC(qdM#D_o&Yo*v?gj_ifeT)M=O!HR_$qQ=<YC$<*_ ztt~H~bhKsYs0-+1$nChQ;T<HYcsUAaPCdt_M9ud~{P(qDl2<lZSjt9?m8W*Fbf=M} zH{v^P{DrC*CpgF3pk(dy+44J<_q7rd5`t7uT1`x|!L1jq@lB_HT;LgBSylWOhO{yi zpZDh5B2X6sQy$6((qG$)=rL1_pdYK0xFXuDN(Cez!#F)Qm?5;<{q-{f>HGJ_kdTm^ z@#6{y$8+fshLlHt5m$1LY6>wJ>#l?v5E5v#T(N#3P7~<nS)b@XvX+CW3nOZ3NVe&O zq@*Xzmx?z%?+e6>u@+VBGW$K_d299x9)ZuRqL`i+TRqz%Hdep+dJ9LDS+ElJDr(_n zPY0>&R%V#(ix*G8Zs*6U`hVvN?#s&ck&eKeM5S@kLT_!4HEyWe+3l~8;fM4dskJ;* za|Uc>ChtrbtyLXqUrR<p-$+40;urS&@k!7VSMTW^8$8S@J~<<!(RIxN;^#`ldl@Oz z8HRk%sYHW}jTH;-+uj}mHKXqH0XKqj$>8#s0?<}O7;u-NP?H~=%B2L9<?K@+_nyB< zothj(yGvMtaWV*m`UD{R*Vg7OKi|Gsde3hBqWR$cae;Hwa`*pd+x!2TD7tIwy0Tp> zpjPW6Y4jPX^ckF7%*)gFIoP?H9bwA*b6^HWhZ#PzWwDN{%iG|_dRj_~?<n%v@6>Mv z9u`U&m2<Ppb^c1g(P@ToVW$kS=%+=gJuFe<sQfDA&K>QYsLC7HKFxGL(f<8S*Li)O z;L~)EDLg4Xy`;qiURqmxZ`0INIkD7ugvfBdx2cG`#jOJB_jeQN>A5SwZl)w77_X6| zt6^*4tD*7wJv_EjYM#6;H7)IqaF1EeI^BC3b3BYVXshG@x4IDyE<>Ij#x1Xp%YJhI z@I*jCR<?cq)m&%$$EChl(iThaOhku<y@<eSYs@e`gqfLnTz3kHEq;Nc_m&%MFIHVZ zSh(x!6FfLR&*m~R94eDBhLpKTq;uX2_}NdnsNC<f4;;rW{cdq{H)c1#P*W3Z>3(A9 z-7(;BUKl4Jbg!jtJO+|UO-IMXv^W>?pfGZIY3YZOrC^5W)BG=cfA#&g=`Uk+;|Ehy zS?3rmqoOJcx$n6hmBhxr4em2jmUlZ^k4Z~gdqQzr&O7Dy6b+VoQpu#{CV6X>gt>C} zVf3AAJL$@9;n;b9@I`Z#nbX!k(!V<6-{x3ON{5t=!(0gaGX+nV&`v3IkXtuo-R-<c zL<6%SnIYmxLsv%!8}Gxc{@r!CzM&zn-H9_CUT=+Xk^ta|go4fb$o%ZA&uR}Hi>N>5 zo7qUEgyYV=J9qBTad#W`i5jDQ%1HsH4w@A9==IkEL6v94Sd70?V#7&pPNm$uz08uP zn#g~{$^W^yGims@8QN#Fm2UWA$(wiO8mq_G$v8TSHb$Udzi}V2_4Gu7BXst(!K26P zS^f}!8XPL7s~ar5!C=_N!O>Je4KV@Buj-|3rmE`vqM4b63+~`B(3Jj|FRr$BOwR!~ zmyp|2LYt;@)Ey05CxE#(&D_fz9ILd~yLsc(y-xZnEPXCxKzZ6@CR>;?%o_}j_&8Oy z#B}J(m(5E{Zx67#!LbkJA0YeZEEo*rzUv@y%kC6GP5aFk=Lw}3QM6Udhvn~#EN3mM zn)!m&Zw&l2hrc1Dd8~uMP#so(mzJm+@^B6YD>bHyLLgn`NlQ~@mT&e4Hl3QCtibr5 zZA_cP4fe#D%veLwb(c&`$a{LIX;ZZL;zUG5NTvkqHqcQMM^i(kAYg`<-RRb9@t2l! zS*<NIk5Y<Vn{Dr-s}Cer%~MLaIl_9wEm?E*3pXzx;n*@bfb9sPUV64HsuVzJBpB56 z_T;Fm#4qsaQsqr~>3h8MvpJ<1=vGzA3g<QAE29)jio<)<<Bc06d7YRa#L{8(s82K% z_=cBJ0Wtmuo#cZ#>`G}&iCxyWb6#cjkBp76v24OnRGIl2a-pyNSPcC7J3E1Au=K2k z@iOA~0xb<)0wOWB(JSF0ADC7pO8D8-^nmAWquZX1vx$d`Sv3MTrUJJX7s4iKWGW`% zSc*u&A_xs*uaeeBb2f!sS0zq6U#?FMO^Au{R8>}*EZz*FvB5V<+pFyQL`FxAjEo2f z=9C+z=H;<+4U?Od>K4}4DZrejZZi68*4(WlOhhyunFuySIO^;woIn2nL{VQXm64GG z+PKP#tnyVc&VfYh49zsKfUG22hBsq0=biBBC&nca$iCaWyw;;(9~atUYK;E{bV|!5 znkdp1&C9Ki!idhe^>&L2z&3pGZ4~a7A4z%R<0ITS{RT8!b#^Z?$4?H7Ir#~dPWQC8 zKgF;6Q_|Vc(a=T5#1z9{#?@3872ObeHx6=#np(@B`6)KG>!$UArlpOiCros(UWSch z`Mc7auOBTZTdwRJf{}-@^g>7No7+FGgDviZ30SsqMH9ogOD`z}w?(H>Q&TmV>6R^A zRj3<l69kTC1vXZC3z0qLfbH!2)A|MmnA1WEj!TE-aNgs|{LRPy#HEgslHJ<FWNjrO zQusX+l`2DMdJ?Kg=}6;-uC?C5uU{X4UnlJM?=G{AZ25D!6fmM$dsARS!eMAiT^J$< z@kAg$Ph^8($7xq1&>(VoeFWf2>8RxoH1W3on`pCdm4lc{WB_?MVpvvI_IN%^0*Lic zI?LYImE9$ImAz5D7ryeNXm<%kWVx$-<nMoi7m*8?@%MS%hpS;S72Ll0`!(5ReN@6Y z8;H2+Q!l7MJYR6Tm8-6W!`r8MfE*){%sYbk>Z|0%`NpPHz|OkGr&#d4qQ0cT=QoAZ zwNH%KE2R`g1_({Bb?@FT_2Rj<!ydM>vhs0~9o%YM;njbv3u3^3s5xE*%(dsR)Sz2< zI}M$Pg!&ot#dqiy;s9oH%m^rMEG{;AJVu+@_uNHnd)J*Qk$J_vRu5n5UJiW5{7Qpe zgJBOL7Uj1}r|%M&YZpM6TfT<6O%UB)0(G9%Tvjc{m#($7d9i`$vPOI960k3l1zF6o zUk<r;y|VJ)U6y9fWojy&C+g@F-@@+|ku%*NqX}Tp-FtdX==l1~-TFir5{-_-&fjbn zlu>yj$x5x5uJ!ck(w}U_MiQaDJ+`=bt)B=36D%%AxZ)i2Y!=oN@HUEf9zTmSnw|X& zN*<uKR=?r;cq}@1p*19goU6B`SM+J-S9GGUua}qDO*!ox-PtMYgM}Uuu-o1c*6{c? z-lo@zcU_$P-0kelH_JdfV-4GuoXoM#!tzADRboIwP@omKkHGr?NQ)JMK7fI}OGc)u zsHmu*FmCXwv9rY{+qU8*G3D%}As>BD_STms^H0qfNp|PoS`@ti8yV!|jXF+^!GU)Y zynIxi_`QD#g+h^$Sx{rc*B9eEtb*x7Ab=V?K0IzDaTtJAO`Ywkf`KOBBnXbx&k_>p z#JUvs=tN3!lyR`H%Gb%01mnhP3xfBpm?NT)jMy?zzEWeqbdG`x3>v=WRF2|X@l&Ft zy45LKS{k0<H&d8{u&F!GJMY9j@!KqgPh)kowRIw6(4>8fcNt+}NR-6ZN@9k6C3|pR z@wm$LqYt->&E_raB@ahNKK_HhwVo$N^$swloGEkcSC2C7$rw!d|3O<|sCb#<fi6CV z`vmb$0*EE#PdfNxUKNW=pB5p{bMXEl{^4Xo17=H{P2}1qEBk{#F{*NfVzfE>g@8JN zv?n$3#HqJ_7E9B)jnGWIo&d?bNEuRL$SG)RD;*)BC>}{aTZaCt!Io|s91FP@wC7a% zBLETMY?n8h;t`9Tp`rfh>r>k**oudDm|Ol^<yef8N-3(U%Cx?9EcpX{^6)Y}<Z{UD z#ITvyWz6KHk~oa`S@Y(UKb&ofI56+B9kDVk1?4Xv@nJ7xn2qP>uLeCEclRHf*`Hz2 znCg<PQ^UF)@lxNKD|;A^nyf6niK*efmmJ)Q+k=j`^*)psGu0AX!khiil#igIE@rSm zHP2lI9F7Up$ir?O;KA(_)c_FL*4Cz|gefj6igY|axqx%PMOsk&12UYPc9TkJA&<O= zOW>>PcimmxKX+JD1O@8AQlE8CpWQPgT8}#nJN<l2MNV-MRB4GSB5TBzJ_pH&UMoXa zG$&S!g+;kRJ!eeBsB>+DWkiLi^LEYn*shnmQ}AQt-0IEGmned)Mfw1N(DWd)un4?h zLy@ZU5{d!GOS_ZY+=?~aT+HYmEeej-q9Esi0Ag#a{1x$o_8CiXA^|w|!`Y>|MIgaI z@#oq4<6sxLnltCXpJ^TDj~+jC{K1~1ncv@C`9pdQAhTYX_bnDkXJ3BDy@1OhweBPk zw^t$0pT`qS8#tvC+dRCteq*{$-@kNvqchn*TBT%(?86SWgf#jNn-+T}$&|-Gk2j|6 z)t&}(4#57ir<L@>)HJ#{Xg1jHDRT|C;PlGC2LM??Vsb4{8i#?I87($$UWyHkX5XIN zHTrk@TH;Z&0#Yg}Q@F{dc@iHs3+&h;kvm$NSH{PTNCs+;LjmSynElMhUv19nDYJ*~ z?v{k8Pl#5OmyfbDu&|YfJQ0}cstbWrx6Yy8%1-1iJoekmU+(ap^mB5W#eek*mB`v| zI>|x!pO9H_i%tbMGs0wEYis9(^`VeRM<1V+q|AxQkgBSxeMt{^WBX{*RqjO2Y3}X3 z{6GusX9Zt+yTfCmVlG}Ivj;yJ5c%&n0>JRtFMqbroqd~$<4w~+_S*r{hBb6&+Z`Y+ z28Pckeq^Dclvggh?oga)t{R|60-FLvMKgl;|9tytp8w*rnU_m|X>~eCIbxGVvS0q5 kFSGylh3@~GTsef_<SnrGk;~l&>pG|LNatY*#Qej50f}r3NdN!< literal 0 HcmV?d00001 diff --git a/documentation/operators/src/legal/landing-pages.md b/documentation/operators/src/legal/landing-pages.md index 5316fdbbc6..adcda45548 100644 --- a/documentation/operators/src/legal/landing-pages.md +++ b/documentation/operators/src/legal/landing-pages.md @@ -344,7 +344,7 @@ sudo nginx -t sudo systemctl restart nginx ``` -When done with the customization needs as described below, you'll need to upload the file and reference it as the 'landing_page_assets_path' on the '[http]' section of the config.toml file that you'll find in the .nym folder, +When done with the customization needs as described below, you'll need to upload the file and reference it as the `landing_page_assets_path` on the `[http]` section of the config.toml file that you'll find in the `~/.nym/gateways/<YOUR_GATEWAY_ID>/config/config.toml` file ``` nano ${HOME}/.nym/gateways/<YOUR_GATEWAY_ID>/config/config.toml ``` @@ -366,4 +366,4 @@ where you should read out ``` ... Started NymNodeHTTPServer on 0.0.0.0:8080 ``` -or just point your browser to the URI which you set above, such as https://nym-exit.<YOUR_DOMAIN> \ No newline at end of file +or just point your browser to the URI which you set above, such as https://nym-exit.<YOUR_DOMAIN> diff --git a/documentation/operators/src/nodes/troubleshooting.md b/documentation/operators/src/nodes/troubleshooting.md index fc201639c4..96640e45e6 100644 --- a/documentation/operators/src/nodes/troubleshooting.md +++ b/documentation/operators/src/nodes/troubleshooting.md @@ -15,7 +15,7 @@ warning: build failed, waiting for other jobs to finish... error: build failed ``` -Why does this happen? +Why does this happen? We have scripts which automatically include the Git commit hash and Git tag in the binary for easier debugging later. If you download a .zip and try building from that, it's not a Git repository and build will fail as above. @@ -26,7 +26,7 @@ What to do? ``` git clone https://github.com/nymtech/nym.git ``` -* Follow the instructions to build the platform +* Follow the instructions to build the platform * To upgrade, pause your nodes, in the same terminal window run `git pull`, follow the upgrade instructions and re-start your nodes. ## General Node Config @@ -53,21 +53,21 @@ bob@nym:~$ tree /home/nym/.nym/mixnodes/ > If you `cat` the `public_sphinx.pem` key, the output will be different from the public key you will see on Nym [dashboard](https://sandbox-explorer.nymtech.net/). The reason for this is that `.pem` files are encoded in **base64**, however on the web they are in **base58**. Don't be confused if your keys look different. They are the same keys, just with different encoding :) -## Mix Nodes +## Mix Nodes ### How can I tell my node is up and running and mixing traffic? -First of all check the 'Mixnodes' section of either the Nym Network Explorers: -* [Mainnet](https://explorer.nymtech.net/) -* [Sandbox testnet](https://sandbox-explorer.nymtech.net/) +First of all check the 'Mixnodes' section of either of the Nym Network Explorers: +* [Mainnet](https://explorer.nymtech.net/) +* [Sandbox testnet](https://sandbox-explorer.nymtech.net/) Enter your **identity key** to find your node. Check the contents of the `Mixnode stats` and `Routing score` sections. -There are 2 community explorers currently, which have been created by [Nodes Guru](https://nodes.guru): +There are 2 community explorers currently, which have been created by [Nodes Guru](https://nodes.guru): * [Mainnet](https://mixnet.explorers.guru/) * [Sandbox testnet](https://sandbox.mixnet.explorers.guru/) -[Here](https://github.com/cosmos/chain-registry/blob/master/nyx/chain.json#L158-L187) is a dictionary with Nyx chain registry entry regarding all explorers. +[Here](https://github.com/cosmos/chain-registry/blob/master/nyx/chain.json#L158-L187) is a dictionary with Nyx chain registry entry regarding all explorers. If you want more information, or if your node isn't showing up on the explorer of your choice and you want to double-check, here are some examples on how to check if the node is configured properly. @@ -151,7 +151,7 @@ PORT STATE SERVICE 1789/tcp open hello ``` -##### Query online nodes: +##### Query online nodes: ``` curl --location --request GET 'https://validator.nymtech.net/api/v1/mixnodes/' @@ -159,7 +159,7 @@ curl --location --request GET 'https://validator.nymtech.net/api/v1/mixnodes/' Will return a list all nodes currently online. -You can query Gateways by replacing `nym-mixnodes` with `nym-gateways` in the above command, and can query for the Mix Nodes and Gateways on the Sandbox testnet by replacing `validator` with `sandbox-validator`. +You can query Gateways by replacing `nym-mixnodes` with `nym-gateways` in the above command, and can query for the Mix Nodes and Gateways on the Sandbox testnet by replacing `validator` with `sandbox-validator`. #### Check with Network API @@ -297,16 +297,73 @@ You don't have to do any additional configuration for your node to implement thi ## Gateways & Network Requesters -### My Gateway seems to be running but appears offline +### My Gateway is running but appears offline in the explorer -Check your [firewall](./maintenance.md#configure-your-firewall) is active and if the necessary ports are open / allowed. +Let your Gateway run and follow these steps: + +1. Check if your [firewall configuration](./maintenance.md#configure-your-firewall) is active and if the necessary ports are open / allowed, including the ones for Swagger page and Reversed proxy/WSS if this is your case. +2. See if the Gateway is not on the [list of blacklisted Gateways](https://validator.nymtech.net/api/v1/gateways/blacklisted) +3. If it's blacklisted, check out the [point below](#my-gateway-is-blacklisted) + +### My Gateway is blacklisted + +Nym API measures performance by routing traffic through the Mixnet. If the average of a Gateway's routing score in past 24h is less than 50%, the Gateway gets blacklisted and remains so until this number is higher than 50%. + +In case your Gateway appeared on the [blacklist](https://validator.nymtech.net/api/v1/gateways/blacklisted), it's because there is some flaw in the configuration. The most common sources of problems are: + +- Bonding before starting the node/service +- Bonding before opening [the needed ports](maintenance.md#configure-your-firewall) +- VPS restarted without operator having a [systemd automation](maintenance.md#systemd) or some alert notification flow setup + +What to do: + +- Make sure your node is running and do not stop it if there is no need +- Open all needed ports +- Wait until your node gets above 50% of performance (average of last 24h) - this will likely take several hours, up to a day. During this time your node is tested by `nym-api` and every positive response picks up your Gateway's routing score. + +**Do not restart your Gateway without reason, your routing score will only get worse!** ### My exit Gateway "is still not online..." -The Nyx chain epoch takes up to 60 min. To prevent the Gateway getting blacklisted, it's important to run it before and during the bonding process. In case it already got blacklisted run it for at several hours. During this time your node is tested by `nym-api` and every positive response picks up your Gateway's routing score. +The Nyx chain epoch takes up to 60 min. To prevent the Gateway getting blacklisted, it's essential to start it before the bonding process and let it running. In case it already got [blacklisted](#my-gateway-is-backlisted) check the steps above. -You may want to disconnect the Network Requester and let it run as a Gateway alone for some time to regain better routing score and then return to the full [Exit Gateway finctionality](./gateway-setup.md#initialising-gateway-with-network-requester). +### When enabling `ip_packet_router` (IPR) I get a `client-core error` + +This error tells you that you already have IPR keys in your data storage, to activate them you have two options: + +1. Open `~/.nym/gateways/<ID>/config/config.toml` and **set the correct values** +```toml +[ip_packer_router_enabled] +enabled = true + +# UNDER [storage_paths] CHANGE +ip_packet_router_config = '~/.nym/gateways/<ID>/config/ip_packet_router_config.toml' +``` + +2. Or **remove the IPR data storage and initialise a new one** with these commands +```toml +rm -rf ~/.nym/gateways/<ID>/data/ip-packet-router-data + +./nym-gateway setup-ip-packet-router --id <ID> +``` + +### My `ip_packet_router` (IPR) seems to not work + +There are a few steps to mitigate problems with IPR: + +1. Check out the issue right above regarding the [Exit Gateway config](#when-enabling-ip_packet_router-ipr-i-get-a-client-core-error) +2. Open your browser and checkout the Swagger UI page and see if all the roles are enabled: +```sh +# in case of IP +http://<YOUR_LISTENING_IP_ADDRESS>:8080/api/v1/roles + +# in case of hostname domain +https://<YOUR_DOMAIN>/api/v1/roles +``` +3. Make sure all your [ports are open](https://nymtech.net/operators/nodes/maintenance.html#configure-your-firewall) properly +4. Make sure to run your Gateway with embedded IPR as root. Either in a root shell with your configs in `/root/.nym/` or with a command `sudo -E` which gives root privileges but looks for user config folder +5. If it's all good in the API but you don't see the right tick/badge in the [Performance testing list](https://nymtech.net/events/fast-and-furious), just wait some time and then try to refresh the page ## Validators @@ -324,4 +381,3 @@ If the `/dev/sda` partition is almost full, try pruning some of the `.gz` syslog The fastest way to reach one of us or get a help from the community, visit our [Telegram Node Setup Help Chat](https://t.me/nymchan_help_chat) or head to our [Discord](https://Discord.gg/nym). For more tech heavy question join our [Matrix core community channel](https://matrix.to/#/#general:nymtech.chat), where you can meet other builders and Nym core team members. - diff --git a/documentation/operators/src/testing/docker-monitor.md b/documentation/operators/src/testing/docker-monitor.md new file mode 100644 index 0000000000..78f1e17d7d --- /dev/null +++ b/documentation/operators/src/testing/docker-monitor.md @@ -0,0 +1,246 @@ +<!-- +TODO +1. Add a few points of advantages why to run it in this way (clean, remote from environment -> safer, can use dockerhub etc etc) +2. Explain in Prometheus setup (in config step) how to get the metrics key and how to add it to the node config (that will be documented in node-setup.md) +3. Add grafana setup +4. Add prometheus setup +5. Add node exporter setup +6. Add how to view it in the browser (possible to use the setup from explorenym guide +7. Additionally add how to spin up an ansible template +--> + +# Setup Prometheus and Grafana in a Docker + +This setup may seem more complex than running a few scripts, but it has certain advantages. +- Running things in a container +<!-- ADD DVANTEGES OF DOCKER SETUP --> + +## Docker, Prometheus and Grafana Metric SETUP + +This setup can be done from the same VPS like your node or on a completelly remote machine. In any case it's setup in a Docker container so it works remotely from the environment where your node runs. + +### Docker setup + +<!--INIT AND START DOCKER CONTAINER --> + +### Prometheus Setup + +This entire installation shall be done with `root` privileges. If you not `root`, start with `su` command before the following steps. + +1. Get the latets system updates +```sh +apt update +``` + +2. Create a system user for Prometheus +```sh +groupadd --system prometheus +useradd -s /sbin/nologin --system -g prometheus prometheus +``` + +3. Create directories for Prometheus +```sh +mkdir /etc/prometheus +mkdir /var/lib/prometheus +``` + +4. Download and extract Prometheus +```sh +wget https://github.com/prometheus/prometheus/releases/download/v{{prometheus_latest_version}}/prometheus-{{prometheus_latest_version}}.linux-amd64.tar.gz +tar vxf prometheus-{{prometheus_latest_version}}.linux-amd64.tar.gz +``` +In case of errors, check Prometheus [release page](https://github.com/prometheus/prometheus/releases/) and get the correct binary for your system. + +5. Navigate to Prometheus directory and configure Prometheus +```sh +# change directory +cd prometheus-{{prometheus_latest_version}}.linux-amd64 + +# move the binary files +mv prometheus /usr/local/bin +mv promtool /usr/local/bin + +# set owner +chown prometheus:prometheus /usr/local/bin/prometheus +chown prometheus:prometheus /usr/local/bin/promtool + +# move the config files +mv consoles /etc/prometheus +mv console_libraries /etc/prometheus +mv prometheus.yml /etc/prometheus + + +# set owner +chown prometheus:prometheus /etc/prometheus +chown -R prometheus:prometheus /etc/prometheus/consoles +chown -R prometheus:prometheus /etc/prometheus/console_libraries +chown -R prometheus:prometheus /var/lib/prometheus +``` + +6. Open the main Prometheus config file `prometheus.yml` +```sh +nano /etc/prometheus/prometheus.yml +``` + +7. Paste the block below to your config `prometheus.yml`, change the line `credentials` and save it (`ctrl` + `x`) + - `credentials` value must be the same like in your node `config.toml` config file under `[http]` header + - In case you haven't set up yet a `<NODE_METRICS_KEY>` in your node `config.toml`, add it by opening a machine with your node and run [this script](https://gist.github.com/benedettadavico/1299b2c7b8b8282c15eafb1914fb3594) with an arbitrary `<NODE_METRIC_KEY>` of your own choice as an argument, follow these commands with your own **strong passphrase** +```sh +# get the script +curl -L https://gist.githubusercontent.com/benedettadavico/1299b2c7b8b8282c15eafb1914fb3594/raw/500c36037615a515f2f3e007baa25e6a2c277d4a/update_config.sh -o update_config.sh + +# make executable +chmod u+x ./update_config.sh + +# run with your own key as argument +sh ./update_config.sh <NODE_METRIC_KEY> + +# for example if you chose my passhphrase to be: "makemoresecurekeythanthis1234" +# the command would look like this +# sh ./update_config.sh makemoresecurekeythanthis1234 +``` + - Add this `<NODE_METRIC_KEY>` string to your monitoring Prometheus config `prometheus.yml` as a value to `credentials`, paste the block below to your `prometheus.yml` as below + +```yaml +# my global config +global: + scrape_interval: 15s # Set the scrape interval to every 15 seconds. Default is every 1 minute. + evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute. + # scrape_timeout is set to the global default (10s). + +# Alertmanager configuration +alerting: + alertmanagers: + - static_configs: + - targets: + # - alertmanager:9093 + +# Load rules once and periodically evaluate them according to the global 'evaluation_interval'. +rule_files: + # - "first_rules.yml" + # - "second_rules.yml" + +# A scrape configuration containing exactly one endpoint to scrape: + +scrape_configs: + # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. + - job_name: "prometheus" + authorization: + # CHANGE THIS TO YOUR OWN STRING + credentials: <METRICS_KEY_SET_ON_THE_NODE> + + static_configs: + - targets: ["localhost:9090"] + + file_sd_configs: + - files: + - /tmp/prom_targets.json +``` + +8. Create Prometheus systemd service by saving the block below to as `/etc/systemd/system/prometheus.service`: + +```sh +nano /etc/systemd/system/prometheus.service +``` + +```sh +[Unit] +Description=Prometheus +Wants=network-online.target +After=network-online.target + +[Service] +User=prometheus +Group=prometheus +Type=simple +ExecStart=/usr/local/bin/prometheus \ + --config.file /etc/prometheus/prometheus.yml \ + --storage.tsdb.path /var/lib/prometheus/ \ + --web.console.templates=/etc/prometheus/consoles \ + --web.console.libraries=/etc/prometheus/console_libraries + +[Install] +WantedBy=multi-user.target +``` + +9. Reload, enable, start and check Prometheus service +```sh +systemctl daemon-reload +systemctl enable prometheus +systemctl start prometheus +systemctl status prometheus + +# to observe journal log, run +journalctl -f -u prometheus +``` + +10. Open port for Prometheus web interface +```sh +ufw allow 9090/tcp +``` +11. Finally you can access Prometheus on `localhost:9090` or `<IP_ADDRESS>:9090` + +Further reading on Prometheus functionalities: +- [Alerting overview](https://prometheus.io/docs/alerting/latest/overview/) +- [Exporters and Integration](https://prometheus.io/docs/instrumenting/exporters/) + +### Grafana Setup + +<!-- SETUP GRAFANA IN A DOCKER --> + +## Setup Access on your Node + +This part needs to be done on the machine where your node runs + +### Node Exporter Setup +<!-- PROMETHEUS NODE EXPORTER--> + + +## Grafana Dashboard Access + +Finally we need to access Grafana dashboards. + +1. Open a browser at `http://<YOUR_IP_ADDRESS>:3000` or `https://<YOUR_DOMAIN>` (depends on your setup), enter username `admin` and password `admin` and setup new credentials on prompt + +2. Setup *Data source* by opening menu -> `Connections` -> `Data sources` -> `+ Add new data source` -> `Prometheus` + +![](../images/grafana/add-data-sources.png) +![](../images/grafana/add-data-source-prometheus.png) + +3. In the field *Connection* next to `Prometheus server URL` enter `http://localhost:9090` (regardless if you accessing Grafana via `http` or `https` as this is for internal connection on the server). When you are done in the bottom confirm by `Save & Test` + +4. In the menu open: `Dashboards` -> `+ Create dashboard` -> `Import dashboard` + +![](../images/grafana/import-dashboard.png) + +5. ID field: enter `1860` -> `Load` + +![](../images/grafana/id-1860.png) + +6. In *Import dashboard* page select Prometheus in the bottom and finally `Import` + +![](../images/grafana/add-prometheus.png) + +Now you have your Prometheus panels displayed via Grafana dashboard for a simple monitoring of your node. + +<!-- +## Verification and Troubleshooting + +To ensure that your services are running correctly, you can verify that by running `systemctl status <SERVICE>` or run a `journalctl -f -u <SERVICE>` to print service logs. It shall return status `Active: active (running). For example: +```sh +# to check if Prometheus service is active +systemctl status prometheus + +# to check if Grafana service is active +systemctl status grafana-server + +# to check if node-exporter service is active +systemctl status node_exporter + +# to run journal log +journalctl -f -u prometheus # or any other service you want to see +``` +--> + + +## Grafana Setup diff --git a/documentation/operators/src/testing/explorenym-scripts.md b/documentation/operators/src/testing/explorenym-scripts.md new file mode 100644 index 0000000000..4b9ee6bdbe --- /dev/null +++ b/documentation/operators/src/testing/explorenym-scripts.md @@ -0,0 +1,131 @@ +# ExploreNym Monitoring Scripts + +## Community Monitoring Tools + +Individual operators, node families and squads are the foundation of distributed network. There has been a great number of tools coming out of this community some of which can be deployed for the node monitoring setup. + +```admonish warning +Make sure you understand and properly evaluate what degree of control you give permission to before granting access to your data to any tools running on someone else's servers. +``` + +## ExploreNYM Tools + +Long term involved operator Pawnflake, an author of [ExploreNYM](https://explorenym.net/) explorer, created a monitoring flow, which can be used by other operators called [`self-hosted-monitor`](https://github.com/ExploreNYM/self-hosted-monitor). It utilises bash scripts to enable operators setup [Prometheus](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/prometheus.sh) and [Grafana](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/grafana.sh) together with [Node Exporter](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/node-exporter.sh) and [Nginx](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/nginx-certbot.sh) to run their metrics monitoring stack locally. + +In collaboration with ExploreNYM we published a [step by step guide](#setup) to set this up. + +ExploreNYM also has a network measuring instance called `enym-monitor`. This setup is very simple for users, however it means that their data are all aggregated into one server and that is a design we would like to discourage from using as a primary one because such setup always brings a risk of centralisation of distributed node's data into one computer. + +## Setup + +```admonish warning +This setup and the scripts included were not written by Nym developers. As always do your own audit before installing any scripts on your machine and familiarize yourself with the security risks involved when opening ports or allowing http access. +``` + +According to ExploreNYM the system requirements of the monitor stack are: +- 2 CPU +- 4 GB RAM +- 20 GB of free disk space. + +### The monitoring part setup + +This can be setup on another VPS than the node if desired. We recommend to try to set this up on the same VPS, as your node as we expect the machine to be strong enough to handle the node with enough capacity reserve for monitor. + +1. Install git +```sh +apt install git +``` + +2. Clone the repository to `~/self-hosted-monitor` +```sh +git clone https://github.com/ExploreNYM/self-hosted-monitor ~/self-hosted-monitor +``` + +3. Give permissions to [`prometheus.sh`](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/prometheus.sh) script and run it to setup Prometheus +```sh +chmod +x ~/self-hosted-monitor/prometheus.sh && ~/self-hosted-monitor/prometheus.sh +``` + +4. Give permissions to [`grafana.sh`](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/grafana.sh) script and run it to setup Grafana +```sh +chmod +x ~/self-hosted-monitor/grafana.sh && ~/self-hosted-monitor/grafana.sh +``` + +5. Open port `3000` to allow access to Grafana +```sh +sudo ufw allow 3000 +``` + +6. You can now access Grafana at `http://<YOUR_IP_ADDRESS>:3000`. + +7. (*Optional step*) If you have a registered domain and prefer to use it with `https`, give permissions to [`nginx-certbot.sh`](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/nginx-certbot.sh) script and run it to setup Nginx and Certbot +```sh +chmod +x ~/self-hosted-monitor/nginx-certbot.sh && ~/self-hosted-monitor/nginx-certbot.sh +``` + +8. Give permissions to [`prometheus-target.sh`](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/prometheus-target.sh) script and run it to add a scrape target. This can be run multiple times to add a new server to be monitored via Prometheus/ +```sh +chmod +x ~/self-hosted-monitor/prometheus-target.sh && ~/self-hosted-monitor/prometheus-target.sh +``` + +### The target server (the part to be monitored) setup + +If you run a monitoring stack and your node on two different VPS, the steps 9 and 10 need to be done on the VPS with the running node. In case you do it on the same VPS, skip directly to step 11 and continue. + +9. Install git +```sh +apt install git +``` + +10. Clone the repository to `~/self-hosted-monitor` +```sh +git clone https://github.com/ExploreNYM/self-hosted-monitor ~/self-hosted-monitor +``` +11. Give permissions to [`node-exporter.sh`](https://github.com/ExploreNYM/self-hosted-monitor/blob/main/node-exporter.sh) script and run it to setup Node exporter. +```sh +chmod +x ~/self-hosted-monitor/node-exporter.sh && ~/self-hosted-monitor/node-exporter.sh +``` + +### Grafana dashboard setup + +Finally we need to access Grafana dashboards. + +12. Open a browser at `http://<YOUR_IP_ADDRESS>:3000` or `https://<YOUR_DOMAIN>` (depends on your setup), enter username `admin` and password `admin` and setup new credentials on prompt + +13. Setup *Data source* by opening menu -> `Connections` -> `Data sources` -> `+ Add new data source` -> `Prometheus` + +![](../images/grafana/add-data-sources.png) +![](../images/grafana/add-data-source-prometheus.png) + +14. In the field *Connection* next to `Prometheus server URL` enter `http://localhost:9090` (regardless if you accessing Grafana via `http` or `https` as this is for internal connection on the server). When you are done in the bottom confirm by `Save & Test` + +15. In the menu open: `Dashboards` -> `+ Create dashboard` -> `Import dashboard` + +![](../images/grafana/import-dashboard.png) + +16. ID field: enter `1860` -> `Load` + +![](../images/grafana/id-1860.png) + +17. In *Import dashboard* page select Prometheus in the bottom and finally `Import` + +![](../images/grafana/add-prometheus.png) + +Now you have your Prometheus panels displayed via Grafana dashboard for a simple monitoring of your node. + +## Verification and Troubleshooting + +To ensure that your services are running correctly, you can verify that by running `systemctl status <SERVICE>` or run a `journalctl -f -u <SERVICE>` to print service logs. It shall return status `Active: active (running)`. For example: +```sh +# to check if Prometheus service is active +systemctl status prometheus + +# to check if Grafana service is active +systemctl status grafana-server + +# to check if node-exporter service is active +systemctl status node_exporter + +# to run journal log +journalctl -f -u prometheus # or any other service you want to see +``` diff --git a/documentation/operators/src/testing/node-setup.md b/documentation/operators/src/testing/node-setup.md new file mode 100644 index 0000000000..3c1a1ca84c --- /dev/null +++ b/documentation/operators/src/testing/node-setup.md @@ -0,0 +1,79 @@ +# Node Setup for Performance Testing Event + +To join the [Performance testing event]({{performance_testing_webpage}}) node operators need to do proceed with the following tasks: + +1. **[Sign their node]({{performance_testing_webpage}}) into the testing environment** +2. **[Configure their node](#node-configuration) for the test** +3. (*Not mandatory*) [Setup metric monitoring system](templates.md) to observe node performance at any time + +## Node Configuration + +> Any syntax in `<>` brackets is a user's unique variable/version. Exchange with a corresponding name without the `<>` brackets. + +After you signed your node (or several) into the Performance testing environment, open the machine with (each of) your nodes and follow the steps below to configure your node for the event. + + +#### 1. Download and upgrade to `{{performance_testing_release}}` binary + - Download the binary from Nym [release page](https://github.com/nymtech/nym/releases/) (use `wget` or `curl` and binary download URL, don't compile from `master`) + - Follow the steps to upgrade node on the [maintenance page](../nodes/manual-upgrade.md) + - Before you re-start your node, follow the steps below + + +#### 2. If you run `nym-gateway` proceed with these steps. If not, go to the next point + - Make sure to have your `nym-gateway` setup as [Nym Exit Gateway](../legal/exit-gateway.md) following the commands [here](../nodes/gateway-setup.md#initialising-exit-gateway) + - Enable `[ip_packet_router]` (IPR) in your `~/.nym/gateways/*/config/config.toml` and IPv4 and IPv6 with [this script](https://gist.github.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77) by running the two command below +```sh +# command to enable IPR +./nym-gateway setup-ip-packet-router --id <GATEWAY_ID> --enabled true + +# script to enable IPv4 and IPv6 +curl -o enable_networking_for_nym_nodes.sh https://gist.githubusercontent.com/tommyv1987/ccf6ca00ffb3d7e13192edda61bb2a77/raw/0840e1d2ee9949716c45655457d198607dfd3107/enable_networking_for_nym_nodes.sh -L && chmod u+x enable_networking_for_nym_nodes.sh && sudo ./enable_networking_for_nym_nodes.sh +``` + +<!-- +3. If you run Prometheus for [monitoring](templates.md) add a `<NODE_METRICS_KEY>` to your node `config.toml` by running [this script](https://gist.github.com/benedettadavico/1299b2c7b8b8282c15eafb1914fb3594) with an arbitrary `<NODE_METRIC_KEY>` of your own choice as an argument, follow these commands with your own **strong passphrase** +```sh +# get the script +curl -L https://gist.githubusercontent.com/benedettadavico/1299b2c7b8b8282c15eafb1914fb3594/raw/500c36037615a515f2f3e007baa25e6a2c277d4a/update_config.sh -o update_config.sh + +# make executable +chmod u+x ./update_config.sh + +# run with your own key as argument +sh ./update_config.sh <NODE_METRIC_KEY> + +# for example if you chose my passhphrase to be: "makemoresecurekeythanthis1234" +# the command would look like this +# sh ./update_config.sh makemoresecurekeythanthis1234 +``` + - Add this `<NODE_METRIC_KEY>` string to your monitoring Prometheus config `prometheus.yml` as a value to `credentials` as below + +```yaml +scrape_configs: + # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config. + - job_name: "prometheus" + authorization: + credentials: <METRICS_KEY_SET_ON_THE_NODE> + + static_configs: + - targets: ["localhost:9090"] + + file_sd_configs: + - files: + - /tmp/prom_targets.json +``` + - Open ports for scraping the metrics +```sh +sudo ufw allow 9000, 9001 +``` +--> + + +#### 3. Restart your node with root privileges + - Either in a root shell or with `sudo -E` command + - In case you run your node as a [`systemd` service](../nodes/maintenance.md#systemd) make sure to run `systemctl daemon-reload` before the service restart + +## Troubleshooting + +If you come to any errors during the setup see troubleshooting page related to [Mix Nodes](../nodes/troubleshooting.md#mix-nodes) and [Gateways](../nodes/troubleshooting.md#gateways--network-requesters). In case your issue isn't documented ask in our Element [Node Operators channel](https://matrix.to/#/#operators:nymtech.chat) or raise an [issue](https://github.com/nymtech/nym/issues) on Github. + diff --git a/documentation/operators/src/testing/performance.md b/documentation/operators/src/testing/performance.md new file mode 100644 index 0000000000..ec4108d313 --- /dev/null +++ b/documentation/operators/src/testing/performance.md @@ -0,0 +1,32 @@ +# Performance Testing + +> To configure your node for a testing event, visit [node setup page](node-setup.md). + +Nym Mixnet has been running on mainnet for quite some time. There is still work to be done in order for the network to meet its full potential - mass adoption of privacy through fully distributed Mixnet. + +Nym asks its decentralised community of operators to join a series of performance testing events in order to **increase the overall quality of the Mixnet**. The main takeaways of such event are: + +1. Understanding of the network behavior under full load + - How many mixnet client users can all active set entry gateways handle simultaneously? + - How much sustained IP traffic can a subset of mainnet nodes sustain? +2. Needed improvements of Nym Node binaries to improve the throughput on mainnet +3. Measurement of required machine specs +4. Raw data record +5. Increase quality of Nym Nodes +6. Show each operator a way to monitor their nodes in a distributed fashion + +## Performance Testing Work Flow + +* Nym runs a paralel network environment [validator.performance.nymte.ch]({{performance_validator}}) with a chain ID `perf` +* Operators of Nym Nodes (currently `nym-mixnode` and `nym-gateway`) join by following easy steps on [performance testing web page]({{performance_testing_webpage}}), including simplified node authentication signature (while keep running their nodes on the mainnet) +* Once signed in, operators will be asked to swap their binary for the modified version with metrics endpoint to be able to connect their own [monitoring system](templates.md) +* Core node data will be fed to a unique mixnet contract for the `perf` side chain +* Nym starts a new API and start packet transition in high load through these nodes in both settings +* Nym tracks packet flow using Prometheus and Grafana +* Nym creates a large number of clients to the [performance validator network]({{performance_validator}}), intensifying the packet traffic +* Observe and record the metrics - this will probably put more strain on mainnet as well as many nodes spec is minimal + +## More Information + +* What happens after the test or what operators get for participating is shared up to date on the [performance testing web page]({{performance_testing_webpage}}) +* Visit our guides to [setup metrics template](templates.md) and learn how to operate them in self-custodial way diff --git a/documentation/operators/src/testing/prometheus-grafana.md b/documentation/operators/src/testing/prometheus-grafana.md new file mode 100644 index 0000000000..bd9f5af825 --- /dev/null +++ b/documentation/operators/src/testing/prometheus-grafana.md @@ -0,0 +1,36 @@ +# Prometheus & Grafana + +The combination of Prometheus and Grafana is a common stack used by Nym team for internal monitoring as well as by core community operators like [ExploreNym](https://github.com/ExploreNYM/vps-monitor) or [No Trust Verify](https://status.notrustverify.ch/d/CW3L7dVVk/nym-mixnet?orgId=1). + + + +## Prometheus + +[Prometheus](https://prometheus.io) is a free and open source monitoring systems. It allows operators to have their metrics, events, and alerts under full control. This ecosystem offers multiple advantages: + +- collects and records metrics from servers, containers, and applications +- provides a [flexible query language (PromQL)](https://prometheus.io/docs/prometheus/latest/querying/basics/) +- multiple modes visualization tools +- an alerting mechanism that sends notifications + +Prometheus collects and stores its metrics as time series data, i.e. metrics information is stored with the timestamp at which it was recorded, alongside optional key-value pairs called labels. + +## Grafana + +[Grafana](https://grafana.com/docs/grafana/latest/) is an open-source analytics and interactive front end. It is widely used for its easy to manage dashboards with visualizations like graphs, charts and alerts, all connected to live data sources. + +## Setup Guides + +There are various ways how to setup this stack. You can chose based on your preferences to do your own flow or follow some of the documented ones: + +- [ExploreNYM scripts](explorenym-scripts.md) for self-hosted monitoring +- Setup monitoring in a Docker container (*detailed guide will be published soon*) +<!--- [Run in a Docker](docker-monitor.md) --> + +## References and further reading + +* [Prometheus release page](https://prometheus.io/download/) +* [Prometheus documentation](https://prometheus.io/docs/introduction/overview/) +* Installation [guide to install Prometheus](https://www.cherryservers.com/blog/install-prometheus-ubuntu) on Ubuntu by cherryservers +* [Grafana installation guide](https://grafana.com/docs/grafana/latest/setup-grafana/installation/debian/) +* Nym's script [`prom_targets.py`](https://github.com/nymtech/nym/blob/promethus-is-our-friend/scripts/prom_targets.py) - a python program to request data from API and can be plugged to this stack diff --git a/documentation/operators/src/testing/templates.md b/documentation/operators/src/testing/templates.md new file mode 100644 index 0000000000..5bc922163f --- /dev/null +++ b/documentation/operators/src/testing/templates.md @@ -0,0 +1,17 @@ + Metrics of Performance Testing + +At Nym as well as several core community operators had setup metrics monitors for a clear overview of node performance. + +It is beneficial for a one time event or a limited period to connect nodes to the existing monitoring infrastructure system that Nym developers built to collect useful metrics. For the purpose of maximal privacy and decentralisation of the data - preventing Nym Mixnet from any global adversary takeover - we created these pages as a source of mutual empowerment, a place where operators can share and learn new skills to **setup metrics monitors on their own infrastructure**. + +## Collecting Testing Metrics + +For the purpose of the performance testing Nym core developers plan to run instances of Prometheus and Grafana connected to Node explorer in the house. The network overall key insights we seek from these tests are primarily internal. We're focused on pinpointing bottlenecks, capacity loads, and monitoring cpu usage on the nodes' machines. + +## Guides to Setup Own Metrics + +A list of different scripts, templates and guides for easier navigation: + +* [Prometheus and Grafana](prometheus-grafana.md) self-hosted setup +* [Nym-node CPU cron service](https://gist.github.com/tommyv1987/97e939a7adf491333d686a8eaa68d4bd) - an easy bash script by Nym core developer [@tommy1987](https://gist.github.com/tommyv1987), designed to monitor a CPU usage of your node, running locally +* Nym's script [`prom_targets.py`](https://github.com/nymtech/nym/blob/develop/scripts/prom_targets.py) - a useful python program to request data from API and can be run on its own or plugged to more sophisticated flows From f5e72cefcc1e18a04b89ebb8c529dedbfeea2188 Mon Sep 17 00:00:00 2001 From: fmtabbara <fmtabbara@hotmail.co.uk> Date: Wed, 27 Mar 2024 16:55:07 +0000 Subject: [PATCH 338/394] Update dependencies in yarn.lock file --- explorer/package.json | 2 +- yarn.lock | 120 +----------------------------------------- 2 files changed, 3 insertions(+), 119 deletions(-) diff --git a/explorer/package.json b/explorer/package.json index 97b7c03b76..278f971d18 100644 --- a/explorer/package.json +++ b/explorer/package.json @@ -38,7 +38,7 @@ "@mui/styles": "^5.0.1", "@mui/system": "^5.0.1", "@mui/x-data-grid": "^5.0.0-beta.5", - "@nymproject/contract-clients": "^1.2.4-rc.1", + "@nymproject/contract-clients": "1.2.4-rc.1", "@nymproject/mui-theme": "^1.0.0", "@nymproject/node-tester": "^1.0.0", "@nymproject/nym-validator-client": "^0.18.0", diff --git a/yarn.lock b/yarn.lock index a707191d80..7e4201e0d3 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1267,16 +1267,6 @@ bfs-path "^1.0.2" cross-fetch "^3.1.5" -"@chain-registry/cosmostation@^1.26.0": - version "1.32.1" - resolved "https://registry.yarnpkg.com/@chain-registry/cosmostation/-/cosmostation-1.32.1.tgz#bdf079a4f45b5c884a33c48fb0b8d4eeaa26a743" - integrity sha512-U8YUkXKWQWmBbAJILXYqEFMnYES4fs+t8iriy6LucSyhICUs1nniMlulm04PYuiIy+bX0BpP5nlNp/CK/yzQkw== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.18.1" - "@chain-registry/utils" "^1.18.2" - "@cosmostation/extension-client" "0.1.15" - "@chain-registry/keplr@1.28.0": version "1.28.0" resolved "https://registry.yarnpkg.com/@chain-registry/keplr/-/keplr-1.28.0.tgz#c53d52ff0487eb6798722eb1cf5bd4dc82a141be" @@ -1319,16 +1309,6 @@ bignumber.js "9.1.1" sha.js "^2.4.11" -"@chain-registry/utils@^1.18.2": - version "1.18.2" - resolved "https://registry.yarnpkg.com/@chain-registry/utils/-/utils-1.18.2.tgz#fa67e8179afad45011c031a1181824133412e6c6" - integrity sha512-X1vBFxdMVRGFW/6fLUQgJ4aG/2RaDYDDEeDA5/x/MlssGtdSBEyytd7M9zO0uS51QYy1ysIhkG3OyZLoyGdurg== - dependencies: - "@babel/runtime" "^7.21.0" - "@chain-registry/types" "^0.18.1" - bignumber.js "9.1.1" - sha.js "^2.4.11" - "@cnakazawa/watch@^1.0.3": version "1.0.4" resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" @@ -1920,15 +1900,6 @@ events "3.3.0" uuid "^9.0.1" -"@cosmos-kit/cosmostation-extension@^2.7.10": - version "2.7.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/cosmostation-extension/-/cosmostation-extension-2.7.10.tgz#2120fa826c692732e7c539a35141df0f8e832876" - integrity sha512-x0rBk4Ht6uicfZxIXRbwUi5WHrvKsI11oXbf9bYL9nRBfRTgpbO6zIW9791oTVjiJLzHbKaBQoqh1R233YcHbg== - dependencies: - "@chain-registry/cosmostation" "^1.26.0" - "@cosmos-kit/core" "^2.8.9" - cosmjs-types "^0.9.0" - "@cosmos-kit/keplr-extension@^2.7.9": version "2.7.9" resolved "https://registry.yarnpkg.com/@cosmos-kit/keplr-extension/-/keplr-extension-2.7.9.tgz#16586c94452a5e65713cdead07446447c511fa0e" @@ -1938,24 +1909,6 @@ "@cosmos-kit/core" "^2.8.9" "@keplr-wallet/types" "^0.12.58" -"@cosmos-kit/leap-extension@^2.7.10": - version "2.7.10" - resolved "https://registry.yarnpkg.com/@cosmos-kit/leap-extension/-/leap-extension-2.7.10.tgz#ff109ead4358f9cbe0b5a727733689d2bea3a60a" - integrity sha512-vVMkF+64oMFLbrw244AxoUR4vrFSKlOHhFHw7wOEHfeTSdvX4mcCsU8CC1LtVV5Bc0msVdkNWVbE04VEump8rg== - dependencies: - "@chain-registry/keplr" "1.28.0" - "@cosmos-kit/core" "^2.8.9" - -"@cosmos-kit/ledger@^2.6.9": - version "2.6.9" - resolved "https://registry.yarnpkg.com/@cosmos-kit/ledger/-/ledger-2.6.9.tgz#e37dfb2ac5941c825477210e091c2a745daf3d61" - integrity sha512-+zn2U6v2c7vDSz8vTe/4oR4lSO/LH/FkdcrstuFTJm1Mk4tpYmJkJGmUQhYV4ZfjSHXfbfccrCl1jgu4uQgiZQ== - dependencies: - "@cosmos-kit/core" "^2.8.9" - "@ledgerhq/hw-app-cosmos" "^6.28.1" - "@ledgerhq/hw-transport-webhid" "^6.27.15" - "@ledgerhq/hw-transport-webusb" "^6.27.15" - "@cosmos-kit/react-lite@^2.6.9": version "2.6.9" resolved "https://registry.yarnpkg.com/@cosmos-kit/react-lite/-/react-lite-2.6.9.tgz#11d1ad07fc087bad5cac5ee623596bdf70b80681" @@ -1974,11 +1927,6 @@ "@cosmos-kit/react-lite" "^2.6.9" "@react-icons/all-files" "^4.1.0" -"@cosmostation/extension-client@0.1.15": - version "0.1.15" - resolved "https://registry.yarnpkg.com/@cosmostation/extension-client/-/extension-client-0.1.15.tgz#cdc6d8fce42217704c1c0d5814f0ee7ce27e8dab" - integrity sha512-HlXYJjFrNpjiV/GUKhri1UL8/bhlOIFFLpRF78YDSqq16x0+plIqx5CAvEusFcKTDpVfpeD5sfUHiKvP7euNFg== - "@cspotcode/source-map-support@^0.8.0": version "0.8.1" resolved "https://registry.yarnpkg.com/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz#00629c35a688e05a88b1cda684fb9d5e73f000a1" @@ -2863,65 +2811,6 @@ big-integer "^1.6.48" utility-types "^3.10.0" -"@ledgerhq/devices@^8.2.0": - version "8.2.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/devices/-/devices-8.2.0.tgz#ef67bf49628252d1779acaa151b1a941acba790e" - integrity sha512-XROTW2gTmmuy+YPPDjdtKKTQ3mfxrPtKtV+a9QFbj8f5MnjVMV0Zpy1BIB4CyIMsVVi4z6+nI67auT7IlsM3SQ== - dependencies: - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/logs" "^6.12.0" - rxjs "^7.8.1" - semver "^7.3.5" - -"@ledgerhq/errors@^6.16.1": - version "6.16.1" - resolved "https://registry.yarnpkg.com/@ledgerhq/errors/-/errors-6.16.1.tgz#df650a9ba105397dee2e8c0ceddf6931c5b25ede" - integrity sha512-4D4wKecGzQpIu7sx03Sg4uE1e8g1oZUndWgw9gw776H8h9ov9c5TxPaldTn2j6orPECAERViLf7LTO4L5pE2Cw== - -"@ledgerhq/hw-app-cosmos@^6.28.1": - version "6.29.3" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-app-cosmos/-/hw-app-cosmos-6.29.3.tgz#5387b4a937392a42acf3c51c1d5464ea8e98e84c" - integrity sha512-fOGJHOdZBtkLW2woMLbLGaFO/BABXU0rriuNUjhj4wy1N0xcd5RhIU/3vnM1PE8UZcC/tBe52pIk5MaYlMj9uA== - dependencies: - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/hw-transport" "^6.30.3" - bip32-path "^0.4.2" - -"@ledgerhq/hw-transport-webhid@^6.27.15": - version "6.28.3" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webhid/-/hw-transport-webhid-6.28.3.tgz#4006788713944e083870101dd35de9a12aeb2be4" - integrity sha512-MNxdK1M+35QA9A+8e4ETSefK3iTO6MaHjB1tKClEngcmcJ2no+Mw8GuMyfaKkrKs2N7KbSQdVHcu9ouCL1NZhw== - dependencies: - "@ledgerhq/devices" "^8.2.0" - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/hw-transport" "^6.30.3" - "@ledgerhq/logs" "^6.12.0" - -"@ledgerhq/hw-transport-webusb@^6.27.15": - version "6.28.3" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport-webusb/-/hw-transport-webusb-6.28.3.tgz#6a73b7ae03dcd25e4ed18e38e74d097975645e74" - integrity sha512-Zb6UfXVuPOFUiIA9alGzE4wZfjmFfLGQR04Zc1qbdeZ9Tf89g+tgJp7zgLRVMaQF2DPO2oOwajgSiPCg8f9ZDA== - dependencies: - "@ledgerhq/devices" "^8.2.0" - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/hw-transport" "^6.30.3" - "@ledgerhq/logs" "^6.12.0" - -"@ledgerhq/hw-transport@^6.30.3": - version "6.30.3" - resolved "https://registry.yarnpkg.com/@ledgerhq/hw-transport/-/hw-transport-6.30.3.tgz#5904adb57ac4459e219551aa97ce2d0772393f2b" - integrity sha512-eqtTCGy8wFCxl+hZSEpjVqn1EDjQhFCne/qUyY0aA36efhWUF6bCRAhkq1e5i7g2P6TbxcIM5P5PW67dILuqIQ== - dependencies: - "@ledgerhq/devices" "^8.2.0" - "@ledgerhq/errors" "^6.16.1" - "@ledgerhq/logs" "^6.12.0" - events "^3.3.0" - -"@ledgerhq/logs@^6.12.0": - version "6.12.0" - resolved "https://registry.yarnpkg.com/@ledgerhq/logs/-/logs-6.12.0.tgz#ad903528bf3687a44da435d7b2479d724d374f5d" - integrity sha512-ExDoj1QV5eC6TEbMdLUMMk9cfvNKhhv5gXol4SmULRVCx/3iyCPhJ74nsb3S0Vb+/f+XujBEj3vQn5+cwS0fNA== - "@leichtgewicht/ip-codec@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" @@ -3412,7 +3301,7 @@ resolved "https://registry.yarnpkg.com/@nx/nx-win32-x64-msvc/-/nx-win32-x64-msvc-16.10.0.tgz#7410a51d0f8be631eec9552f01b2e5946285927c" integrity sha512-5iV2NKZnzxJwZZ4DM5JVbRG/nkhAbzEskKaLBB82PmYGKzaDHuMHP1lcPoD/rtYMlowZgNA/RQndfKvPBPwmXA== -"@nymproject/contract-clients@^1.2.4-rc.1": +"@nymproject/contract-clients@1.2.4-rc.1": version "1.2.4-rc.1" resolved "https://registry.yarnpkg.com/@nymproject/contract-clients/-/contract-clients-1.2.4-rc.1.tgz#10b385f63d8b33beea6bf47d948fc7cc0c6c2357" integrity sha512-WMiEIHNxc9oTZ8GxAE8278ifpNJ2AIZHEw4JifN1WRhn2XViYaDDJaPCA3o0p+WGRySmqdurHmployr3iUEz1Q== @@ -8445,11 +8334,6 @@ bindings@^1.3.0, bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" -bip32-path@^0.4.2: - version "0.4.2" - resolved "https://registry.yarnpkg.com/bip32-path/-/bip32-path-0.4.2.tgz#5db0416ad6822712f077836e2557b8697c0c7c99" - integrity sha512-ZBMCELjJfcNMkz5bDuJ1WrYvjlhEF5k6mQ8vUr4N7MbVRsXei7ZOg8VhhwMfNiW68NWmLkgkc6WvTickrLGprQ== - bip32@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/bip32/-/bip32-2.0.6.tgz#6a81d9f98c4cd57d05150c60d8f9e75121635134" @@ -19561,7 +19445,7 @@ run-queue@^1.0.0, run-queue@^1.0.3: dependencies: aproba "^1.1.1" -rxjs@^7.5.5, rxjs@^7.8.1: +rxjs@^7.5.5: version "7.8.1" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.1.tgz#6f6f3d99ea8044291efd92e7c7fcf562c4057543" integrity sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg== From 519d419bbfcd59423d004248cbb83e445aea2fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 14:47:53 +0000 Subject: [PATCH 339/394] bugfix: use OptionFuture for creating metrics server --- .../src/client/packet_statistics_control.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 630da1b8d7..499d5de092 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -7,6 +7,8 @@ use nym_metrics::{inc, inc_by}; use si_scale::helpers::bibytes2; // Metrics server +use futures::future::{FusedFuture, OptionFuture}; +use futures::FutureExt; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use http_body_util::Full; #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] @@ -535,6 +537,14 @@ impl PacketStatisticsControl { } loop { + // it seems at some point tokio changed its select precondition evaluation, + // and it's no longer checked before the future is evaluated. + let accept_future: OptionFuture<_> = listener + .as_ref() + .map(|l| l.accept()) + .map(FutureExt::fuse) + .into(); + tokio::select! { stats_event = self.stats_rx.recv() => match stats_event { Some(stats_event) => { @@ -548,10 +558,10 @@ impl PacketStatisticsControl { }, // conditional will disable the branch if we're in wasm32-unknown-unknown // use `_` to calm down clippy when running for wasm - _result = listener.as_ref().unwrap().accept(), if listener.is_some() => { + _result = accept_future, if !accept_future.is_terminated() => { cfg_if::cfg_if! { if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] { - if let Ok((stream, _)) = _result { + if let Some(Ok((stream, _))) = _result { let io = TokioIo::new(stream); tokio::task::spawn(async move { From 2aa5e25532d6e75dfc0de6e5282c84d23f77571e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Wed, 13 Mar 2024 10:18:03 +0000 Subject: [PATCH 340/394] removed the usage of allow.list --- common/types/src/gateway.rs | 9 +- gateway/src/commands/helpers.rs | 16 - gateway/src/commands/init.rs | 8 - gateway/src/commands/run.rs | 7 - .../src/commands/setup_network_requester.rs | 7 - gateway/src/http/mod.rs | 15 +- gateway/src/node/helpers.rs | 3 - .../network-requester/src/cli/init.rs | 7 - .../network-requester/src/cli/mod.rs | 5 - .../network-requester/src/cli/run.rs | 7 - .../network-requester/src/config/mod.rs | 7 +- .../src/config/persistence.rs | 2 + .../network-requester/src/core.rs | 25 +- .../request_filter/allowed_hosts/filter.rs | 559 ------------------ .../src/request_filter/allowed_hosts/group.rs | 61 -- .../src/request_filter/allowed_hosts/host.rs | 35 -- .../src/request_filter/allowed_hosts/hosts.rs | 203 ------- .../src/request_filter/allowed_hosts/mod.rs | 13 - .../allowed_hosts/standard_list.rs | 113 ---- .../allowed_hosts/stored_allowed_hosts.rs | 127 ---- .../src/request_filter/exit_policy/mod.rs | 25 +- .../src/request_filter/mod.rs | 133 +---- 22 files changed, 53 insertions(+), 1334 deletions(-) delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/filter.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/group.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/host.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/hosts.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/mod.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/standard_list.rs delete mode 100644 service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs diff --git a/common/types/src/gateway.rs b/common/types/src/gateway.rs index 90d012a5ff..834775c492 100644 --- a/common/types/src/gateway.rs +++ b/common/types/src/gateway.rs @@ -124,15 +124,12 @@ pub struct GatewayNetworkRequesterDetails { pub encryption_key: String, pub open_proxy: bool, - pub exit_policy: bool, pub enabled_statistics: bool, // just a convenience wrapper around all the keys pub address: String, pub config_path: String, - pub allow_list_path: String, - pub unknown_list_path: String, } impl fmt::Display for GatewayNetworkRequesterDetails { @@ -146,11 +143,7 @@ impl fmt::Display for GatewayNetworkRequesterDetails { writeln!(f, "\taddress: {}", self.address)?; writeln!(f, "\tuses open proxy: {}", self.open_proxy)?; - writeln!(f, "\tuses exit policy: {}", self.exit_policy)?; - writeln!(f, "\tsends statistics: {}", self.enabled_statistics)?; - - writeln!(f, "\tallow list path: {}", self.allow_list_path)?; - writeln!(f, "\tunknown list path: {}", self.unknown_list_path) + writeln!(f, "\tsends statistics: {}", self.enabled_statistics) } } diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 968b9b14c6..2bd3f3834c 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -109,7 +109,6 @@ pub(crate) struct OverrideNetworkRequesterConfig { pub(crate) medium_toggle: bool, pub(crate) open_proxy: Option<bool>, - pub(crate) enable_exit_policy: Option<bool>, pub(crate) enable_statistics: Option<bool>, pub(crate) statistics_recipient: Option<String>, @@ -229,10 +228,6 @@ pub(crate) fn override_network_requester_config( nym_network_requester::Config::with_open_proxy, opts.open_proxy, ) - .with_optional( - nym_network_requester::Config::with_old_allow_list, - opts.enable_exit_policy.map(|e| !e), - ) .with_optional( nym_network_requester::Config::with_enabled_statistics, opts.enable_statistics, @@ -314,21 +309,10 @@ pub(crate) async fn initialise_local_network_requester( enabled: gateway_config.network_requester.enabled, identity_key: address.identity().to_string(), encryption_key: address.encryption_key().to_string(), - exit_policy: !nr_cfg.network_requester.use_deprecated_allow_list, open_proxy: nr_cfg.network_requester.open_proxy, enabled_statistics: nr_cfg.network_requester.enabled_statistics, address: address.to_string(), config_path: nr_cfg_path.display().to_string(), - allow_list_path: nr_cfg - .storage_paths - .allowed_list_location - .display() - .to_string(), - unknown_list_path: nr_cfg - .storage_paths - .unknown_list_location - .display() - .to_string(), }) } diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index 010d270222..b2be9129d4 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -133,12 +133,6 @@ pub struct Init { )] medium_toggle: bool, - /// Specifies whether this network requester will run using the default ExitPolicy - /// as opposed to the allow list. - /// Note: this setting will become the default in the future releases. - #[clap(long)] - with_exit_policy: Option<bool>, - #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } @@ -173,7 +167,6 @@ impl<'a> From<&'a Init> for OverrideNetworkRequesterConfig { no_cover: value.no_cover, medium_toggle: value.medium_toggle, open_proxy: value.open_proxy, - enable_exit_policy: value.with_exit_policy, enable_statistics: value.enable_statistics, statistics_recipient: value.statistics_recipient.clone(), } @@ -303,7 +296,6 @@ mod tests { fastmode: false, no_cover: false, medium_toggle: false, - with_exit_policy: None, }; std::env::set_var(BECH32_PREFIX, "n"); diff --git a/gateway/src/commands/run.rs b/gateway/src/commands/run.rs index 34c1b6be8d..bc52ff056e 100644 --- a/gateway/src/commands/run.rs +++ b/gateway/src/commands/run.rs @@ -132,12 +132,6 @@ pub struct Run { #[arg(long, group = "network", hide = true)] custom_mixnet: Option<PathBuf>, - /// Specifies whether this network requester will run using the default ExitPolicy - /// as opposed to the allow list. - /// Note: this setting will become the default in the future releases. - #[arg(long)] - with_exit_policy: Option<bool>, - #[arg(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, @@ -175,7 +169,6 @@ impl<'a> From<&'a Run> for OverrideNetworkRequesterConfig { no_cover: value.no_cover, medium_toggle: value.medium_toggle, open_proxy: value.open_proxy, - enable_exit_policy: value.with_exit_policy, enable_statistics: value.enable_statistics, statistics_recipient: value.statistics_recipient.clone(), } diff --git a/gateway/src/commands/setup_network_requester.rs b/gateway/src/commands/setup_network_requester.rs index c9de302200..b9368ce2e0 100644 --- a/gateway/src/commands/setup_network_requester.rs +++ b/gateway/src/commands/setup_network_requester.rs @@ -59,12 +59,6 @@ pub struct CmdArgs { )] medium_toggle: bool, - /// Specifies whether this network requester will run using the default ExitPolicy - /// as opposed to the allow list. - /// Note: this setting will become the default in the future releases. - #[clap(long)] - with_exit_policy: Option<bool>, - #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } @@ -76,7 +70,6 @@ impl<'a> From<&'a CmdArgs> for OverrideNetworkRequesterConfig { no_cover: value.no_cover, medium_toggle: value.medium_toggle, open_proxy: value.open_proxy, - enable_exit_policy: value.with_exit_policy, enable_statistics: value.enable_statistics, statistics_recipient: value.statistics_recipient.clone(), } diff --git a/gateway/src/http/mod.rs b/gateway/src/http/mod.rs index 7b63a522fb..9fcaa10209 100644 --- a/gateway/src/http/mod.rs +++ b/gateway/src/http/mod.rs @@ -199,13 +199,11 @@ impl<'a> HttpApiBuilder<'a> { // once we start refreshing it, we'll have to change it, but at that point // the allow list will be probably be completely removed and thus the pointer management // will be much easier - let Some(exit_policy) = request_filter.current_exit_policy_filter() else { - warn!("this node does not use an exit policy. no changes will be made"); - return self; - }; + + let upstream = request_filter.current_exit_policy_filter().upstream(); // if there's no upstream (i.e. open proxy), we couldn't have possibly updated it : ) - let last_updated = if exit_policy.upstream().is_some() { + let last_updated = if upstream.is_some() { #[allow(clippy::expect_used)] std::time::SystemTime::now() .duration_since(std::time::UNIX_EPOCH) @@ -217,12 +215,9 @@ impl<'a> HttpApiBuilder<'a> { self.exit_policy = Some(UsedExitPolicy { enabled: true, - upstream_source: exit_policy - .upstream() - .map(|u| u.to_string()) - .unwrap_or_default(), + upstream_source: upstream.map(|u| u.to_string()).unwrap_or_default(), last_updated, - policy: Some(exit_policy.policy().clone()), + policy: Some(request_filter.current_exit_policy_filter().policy().clone()), }); self diff --git a/gateway/src/node/helpers.rs b/gateway/src/node/helpers.rs index 3e2d54417a..58a11e3f6c 100644 --- a/gateway/src/node/helpers.rs +++ b/gateway/src/node/helpers.rs @@ -64,12 +64,9 @@ pub(crate) async fn node_details( identity_key: nr_identity_public_key.to_base58_string(), encryption_key: nr_encryption_key.to_base58_string(), open_proxy: cfg.network_requester.open_proxy, - exit_policy: !cfg.network_requester.use_deprecated_allow_list, enabled_statistics: cfg.network_requester.enabled_statistics, address: address.to_string(), config_path: display_path(nr_cfg_path), - allow_list_path: display_path(&cfg.storage_paths.allowed_list_location), - unknown_list_path: display_path(&cfg.storage_paths.unknown_list_location), }) } else { None diff --git a/service-providers/network-requester/src/cli/init.rs b/service-providers/network-requester/src/cli/init.rs index b9cef1f16a..5f155bf144 100644 --- a/service-providers/network-requester/src/cli/init.rs +++ b/service-providers/network-requester/src/cli/init.rs @@ -57,12 +57,6 @@ pub(crate) struct Init { #[clap(long)] statistics_recipient: Option<String>, - /// Specifies whether this network requester will run using the default ExitPolicy - /// as opposed to the allow list. - /// Note: this setting will become the default in the future releases. - #[clap(long)] - with_exit_policy: Option<bool>, - #[clap(short, long, default_value_t = OutputFormat::default())] output: OutputFormat, } @@ -76,7 +70,6 @@ impl From<Init> for OverrideConfig { medium_toggle: false, nyxd_urls: init_config.common_args.nyxd_urls, enabled_credentials_mode: init_config.common_args.enabled_credentials_mode, - enable_exit_policy: init_config.with_exit_policy, open_proxy: init_config.open_proxy, enable_statistics: init_config.enable_statistics, statistics_recipient: init_config.statistics_recipient, diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 53f01c5c8a..5cfa1f046a 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -104,7 +104,6 @@ pub(crate) struct OverrideConfig { medium_toggle: bool, nyxd_urls: Option<Vec<url::Url>>, enabled_credentials_mode: Option<bool>, - enable_exit_policy: Option<bool>, open_proxy: Option<bool>, enable_statistics: Option<bool>, @@ -165,10 +164,6 @@ pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Confi args.enabled_credentials_mode.map(|b| !b), ) .with_optional(Config::with_open_proxy, args.open_proxy) - .with_optional( - Config::with_old_allow_list, - args.enable_exit_policy.map(|e| !e), - ) .with_optional(Config::with_enabled_statistics, args.enable_statistics) .with_optional(Config::with_statistics_recipient, args.statistics_recipient) } diff --git a/service-providers/network-requester/src/cli/run.rs b/service-providers/network-requester/src/cli/run.rs index cd3a5ad653..07d9612898 100644 --- a/service-providers/network-requester/src/cli/run.rs +++ b/service-providers/network-requester/src/cli/run.rs @@ -40,12 +40,6 @@ pub(crate) struct Run { conflicts_with = "fastmode" )] medium_toggle: bool, - - /// Specifies whether this network requester will run using the default ExitPolicy - /// as opposed to the allow list. - /// Note: this setting will become the default in the future releases. - #[clap(long)] - with_exit_policy: Option<bool>, } impl From<Run> for OverrideConfig { @@ -57,7 +51,6 @@ impl From<Run> for OverrideConfig { medium_toggle: run_config.medium_toggle, nyxd_urls: run_config.common_args.nyxd_urls, enabled_credentials_mode: run_config.common_args.enabled_credentials_mode, - enable_exit_policy: run_config.with_exit_policy, open_proxy: run_config.open_proxy, enable_statistics: run_config.enable_statistics, statistics_recipient: run_config.statistics_recipient, diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index 53cdc143f4..a1bc434d92 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -166,12 +166,6 @@ impl Config { self } - #[must_use] - pub fn with_old_allow_list(mut self, use_old_allow_list: bool) -> Self { - self.network_requester.use_deprecated_allow_list = use_old_allow_list; - self - } - #[must_use] pub fn with_enabled_statistics(mut self, enabled_statistics: bool) -> Self { self.network_requester.enabled_statistics = enabled_statistics; @@ -251,6 +245,7 @@ pub struct NetworkRequester { /// Specifies whether this network requester should be using the deprecated allow-list, /// as opposed to the new ExitPolicy. /// Note: this field will be removed in a near future. + #[deprecated] pub use_deprecated_allow_list: bool, /// Specifies the url for an upstream source of the exit policy used by this node. diff --git a/service-providers/network-requester/src/config/persistence.rs b/service-providers/network-requester/src/config/persistence.rs index cc3d4378ba..6d81c3c77e 100644 --- a/service-providers/network-requester/src/config/persistence.rs +++ b/service-providers/network-requester/src/config/persistence.rs @@ -16,10 +16,12 @@ pub struct NetworkRequesterPaths { /// Deprecated /// Location of the file containing our allow.list + #[deprecated] pub allowed_list_location: PathBuf, /// Deprecated /// Location of the file containing our unknown.list + #[deprecated] pub unknown_list_location: PathBuf, /// Location of the file containing our description diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index 7affa6c849..b84124aff0 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -327,9 +327,6 @@ impl NRServiceProviderBuilder { }); let request_filter = RequestFilter::new(&self.config).await?; - request_filter - .start_update_tasks(&self.config.network_requester_debug, &shutdown) - .await; let mut service_provider = NRServiceProvider { config: self.config, @@ -605,20 +602,14 @@ impl NRServiceProvider { QueryResponse::Description("Description (placeholder)".to_string()), ), QueryRequest::ExitPolicy => { - let response = match self.request_filter.current_exit_policy_filter() { - Some(exit_policy_filter) => QueryResponse::ExitPolicy { - enabled: true, - upstream: exit_policy_filter - .upstream() - .map(|u| u.to_string()) - .unwrap_or_default(), - policy: Some(exit_policy_filter.policy().clone()), - }, - None => QueryResponse::ExitPolicy { - enabled: false, - upstream: "".to_string(), - policy: None, - }, + let exit_policy_filter = self.request_filter.current_exit_policy_filter(); + let response = QueryResponse::ExitPolicy { + enabled: true, + upstream: exit_policy_filter + .upstream() + .map(|u| u.to_string()) + .unwrap_or_default(), + policy: Some(exit_policy_filter.policy().clone()), }; Socks5Response::new_query(protocol_version, response) diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/filter.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/filter.rs deleted file mode 100644 index a721c91089..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/filter.rs +++ /dev/null @@ -1,559 +0,0 @@ -// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use super::HostsStore; -use crate::request_filter::allowed_hosts::group::HostsGroup; -use crate::request_filter::allowed_hosts::standard_list::StandardList; -use crate::request_filter::allowed_hosts::stored_allowed_hosts::StoredAllowedHosts; -use publicsuffix::Psl; -use std::{ - net::{IpAddr, SocketAddr}, - str::FromStr, -}; -use tokio::sync::Mutex; -use url::Url; - -#[derive(Debug)] -enum RequestHost { - IpAddr(IpAddr), - SocketAddr(SocketAddr), - RootDomain(String), -} - -/// Filters outbound requests based on what's in an `allowed_hosts` list. -/// -/// Requests to unknown hosts are automatically written to an `unknown_hosts` -/// list so that they can be copy/pasted into the `allowed_hosts` list if desired. -/// This may be handy for service provider node operators who want to be able to look in the -/// `unknown_hosts` file and allow new hosts (e.g. if a wallet has added a new outbound request -/// which needs to be allowed). -/// -/// We rely on the list of domains at https://publicsuffix.org/ to figure out what the root -/// domain is for a given request. This allows us to distinguish all the rules for e.g. -/// .com, .co.uk, .co.jp, uk.com, etc, so that we can distinguish correct root-ish -/// domains as allowed. That list is loaded once at startup from Mozilla's canonical -/// publicsuffix list. -pub(crate) struct OutboundRequestFilter { - pub(super) allowed_hosts: StoredAllowedHosts, - pub(super) standard_list: StandardList, - root_domain_list: publicsuffix::List, - unknown_hosts: Mutex<HostsStore>, -} - -/// The official URL of the list -pub const LIST_URL: &str = "https://publicsuffix.org/list/public_suffix_list.dat"; - -async fn request(u: Url) -> String { - reqwest::get(u) - .await - .expect("failed to get LIST_URL") - .text() - .await - .expect("failed to get text") -} - -async fn fetch_list() -> publicsuffix::List { - let str = request(Url::parse(LIST_URL).unwrap()).await; - publicsuffix::List::from_str(&str).unwrap() -} - -impl OutboundRequestFilter { - /// Create a new `OutboundRequestFilter` with the given `allowed_hosts` and `unknown_hosts` lists. - /// - /// Automatically fetches the latest https://publicsuffix.org/ domain list from the internet so that - /// the requester can properly parse all of the world's top-level domains in an up-to-date fashion. - /// - /// Automatcially fetches the latest standard allowed list from the Nym website, so that all - /// requesters are able to support the same minimal functionality out of the box. - pub(crate) async fn new( - allowed_hosts: StoredAllowedHosts, - standard_list: StandardList, - unknown_hosts: HostsStore, - ) -> OutboundRequestFilter { - let domain_list = fetch_list().await; - - OutboundRequestFilter { - allowed_hosts, - standard_list, - root_domain_list: domain_list, - unknown_hosts: Mutex::new(unknown_hosts), - } - } - - pub(crate) fn standard_list(&self) -> StandardList { - self.standard_list.clone() - } - - pub(crate) fn allowed_hosts(&self) -> StoredAllowedHosts { - self.allowed_hosts.clone() - } - - async fn check_allowed_hosts(&self, host: &RequestHost) -> bool { - let guard = self.allowed_hosts.get().await; - self.check_group(&guard.data, host) - } - - async fn check_standard_list(&self, host: &RequestHost) -> bool { - let guard = self.standard_list.get().await; - self.check_group(&guard, host) - } - - fn check_group(&self, group: &HostsGroup, host: &RequestHost) -> bool { - match host { - RequestHost::IpAddr(ip_addr) => group.contains_ip_address(*ip_addr), - RequestHost::SocketAddr(socket_addr) => group.contains_ip_address(socket_addr.ip()), - RequestHost::RootDomain(domain) => group.contains_domain(domain), - } - } - - async fn add_to_unknown_hosts(&self, host: RequestHost) { - let mut guard = self.unknown_hosts.lock().await; - match host { - RequestHost::IpAddr(ip_addr) => guard.add_ip(ip_addr), - RequestHost::SocketAddr(socket_addr) => guard.add_ip(socket_addr.ip()), - RequestHost::RootDomain(domain) => guard.add_domain(&domain), - } - } - - fn parse_request_host(&self, host: &str) -> Option<RequestHost> { - // first check if it's a socket address (ip:port) - // (this check is performed to not incorrectly strip what we think might be a port - // from ipv6 address, as for example ::1 contains colons but has no port - if let Ok(socketaddr) = host.parse::<SocketAddr>() { - Some(RequestHost::SocketAddr(socketaddr)) - // then check if it was an ip address - } else if let Ok(ipaddr) = host.parse::<IpAddr>() { - Some(RequestHost::IpAddr(ipaddr)) - // finally, then assume it might be a domain - } else { - // check root - let trimmed = Self::trim_port(host); - // if this failed, it was probably some nonsense - self.get_domain_root(&trimmed).map(RequestHost::RootDomain) - } - } - - async fn check_request_host(&self, request_host: &RequestHost) -> bool { - // first check our own allow list - let local_allowed = self.check_allowed_hosts(request_host).await; - - // if it's locally allowed, no point in checking the standard list - if local_allowed { - return true; - } - - // if that failed, check the standard list - self.check_standard_list(request_host).await - } - - /// Returns `true` if a host's root domain is in the `allowed_hosts` list. - /// - /// If it's not in the list, return `false` and write it to the `unknown_hosts` storefile. - pub(crate) async fn check(&self, host: &str) -> bool { - let allowed = match self.parse_request_host(host) { - Some(request_host) => { - let res = self.check_request_host(&request_host).await; - if !res { - self.add_to_unknown_hosts(request_host).await - } - res - } - None => false, - }; - - if !allowed { - log::warn!("Blocked outbound connection to {host}, add it to allowed.list if needed",); - } - - allowed - } - - fn trim_port(host: &str) -> String { - let mut tmp: Vec<_> = host.split(':').collect(); - if tmp.len() > 1 { - tmp.pop(); // get rid of last element (port) - tmp.join(":") //rejoin - } else { - host.to_string() - } - } - - /// Attempts to get the root domain, shorn of subdomains, using publicsuffix. - /// If the domain is itself registered in publicsuffix (e.g. s3.amazonaws.com), - /// then just use the full address as root. - fn get_domain_root(&self, host: &str) -> Option<String> { - if let Some(domain) = self.root_domain_list.domain(host.as_bytes()) { - return String::from_utf8(domain.as_bytes().to_vec()).ok(); - } else if let Some(suffix) = self.root_domain_list.suffix(host.as_bytes()) { - if suffix.is_known() { - return String::from_utf8(suffix.as_bytes().to_vec()).ok(); - } else { - return None; - } - } - log::warn!("Error parsing domain: {:?}", host); - None // domain couldn't be parsed - } -} - -#[cfg(test)] -mod tests { - use super::*; - use std::ops::{Deref, DerefMut}; - - struct HostsStoreFixture { - inner: HostsStore, - // take ownership of temp file that will get cleaned up on drop (i.e. when test finishes) - _tmp_file: tempfile::NamedTempFile, - } - - impl Deref for HostsStoreFixture { - type Target = HostsStore; - - fn deref(&self) -> &Self::Target { - &self.inner - } - } - - impl DerefMut for HostsStoreFixture { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } - } - - impl HostsStoreFixture { - fn new() -> HostsStoreFixture { - let tmp_file = tempfile::NamedTempFile::new().unwrap(); - let inner = HostsStore::new(&tmp_file); - HostsStoreFixture { - inner, - _tmp_file: tmp_file, - } - } - } - - struct OutboundRequestFilterFixture { - inner: OutboundRequestFilter, - // take ownership of temp files that will get cleaned up on drop (i.e. when test finishes) - _allow_tmp_file: tempfile::NamedTempFile, - _unknown_tmp_file: tempfile::NamedTempFile, - } - - impl Deref for OutboundRequestFilterFixture { - type Target = OutboundRequestFilter; - - fn deref(&self) -> &Self::Target { - &self.inner - } - } - - impl DerefMut for OutboundRequestFilterFixture { - fn deref_mut(&mut self) -> &mut Self::Target { - &mut self.inner - } - } - - impl OutboundRequestFilterFixture { - async fn new() -> OutboundRequestFilterFixture { - let allow_tmp_file = tempfile::NamedTempFile::new().unwrap(); - let unknown_tmp_file = tempfile::NamedTempFile::new().unwrap(); - let allowed = HostsStore::new(&allow_tmp_file); - let unknown = HostsStore::new(&unknown_tmp_file); - let standard = StandardList::new(); - - let inner = OutboundRequestFilter::new(allowed.into(), standard, unknown).await; - OutboundRequestFilterFixture { - inner, - _allow_tmp_file: allow_tmp_file, - _unknown_tmp_file: unknown_tmp_file, - } - } - } - - async fn setup_empty() -> OutboundRequestFilterFixture { - OutboundRequestFilterFixture::new().await - } - - async fn setup_with_allowed(allowed: &[&str]) -> OutboundRequestFilterFixture { - let allow_tmp_file = tempfile::NamedTempFile::new().unwrap(); - let unknown_tmp_file = tempfile::NamedTempFile::new().unwrap(); - let mut allowed_store = HostsStore::new(&allow_tmp_file); - let unknown = HostsStore::new(&unknown_tmp_file); - let standard = StandardList::new(); - - for allow in allowed { - allowed_store.add_host(allow) - } - - let inner = OutboundRequestFilter::new(allowed_store.into(), standard, unknown).await; - OutboundRequestFilterFixture { - inner, - _allow_tmp_file: allow_tmp_file, - _unknown_tmp_file: unknown_tmp_file, - } - } - - #[cfg(test)] - mod trimming_port_information { - use super::*; - - #[test] - fn happens_when_port_exists() { - let host = "nymtech.net:9999"; - assert_eq!("nymtech.net", OutboundRequestFilter::trim_port(host)); - } - - #[test] - fn doesnt_happen_when_no_port_exists() { - let host = "nymtech.net"; - assert_eq!("nymtech.net", OutboundRequestFilter::trim_port(host)); - } - } - - #[cfg(test)] - mod getting_the_domain_root { - use super::*; - - #[tokio::test] - async fn leaves_a_com_alone() { - let filter = setup_empty().await; - assert_eq!( - Some("domain.com".to_string()), - filter.get_domain_root("domain.com") - ) - } - - #[tokio::test] - async fn trims_subdomains_from_com() { - let filter = setup_empty().await; - assert_eq!( - Some("domain.com".to_string()), - filter.get_domain_root("foomp.domain.com") - ) - } - - #[tokio::test] - async fn works_for_non_com_roots() { - let filter = setup_empty().await; - assert_eq!( - Some("domain.co.uk".to_string()), - filter.get_domain_root("domain.co.uk") - ) - } - - #[tokio::test] - async fn works_for_non_com_roots_with_subdomains() { - let filter = setup_empty().await; - assert_eq!( - Some("domain.co.uk".to_string()), - filter.get_domain_root("foomp.domain.co.uk") - ) - } - - #[tokio::test] - async fn returns_none_on_garbage() { - let filter = setup_empty().await; - assert_eq!(None, filter.get_domain_root("::/&&%@")); - } - - #[tokio::test] - async fn returns_full_on_suffix_domains() { - let filter = setup_empty().await; - dbg!(filter.get_domain_root("s3.amazonaws.com")); - assert_eq!( - Some("s3.amazonaws.com".to_string()), - filter.get_domain_root("s3.amazonaws.com") - ); - } - } - - #[cfg(test)] - mod requests_to_unknown_hosts { - use super::*; - - #[tokio::test] - async fn are_not_allowed() { - let host = "unknown.com"; - let filter = setup_empty().await; - assert!(!filter.check(host).await); - } - - #[tokio::test] - async fn get_appended_once_to_the_unknown_hosts_list() { - let host = "unknown.com"; - let filter = setup_empty().await; - filter.check(host).await; - assert_eq!(1, filter.unknown_hosts.lock().await.data.domains.len()); - assert!(filter - .unknown_hosts - .lock() - .await - .data - .domains - .contains("unknown.com")); - filter.check(host).await; - assert_eq!(1, filter.unknown_hosts.lock().await.data.domains.len()); - assert!(filter - .unknown_hosts - .lock() - .await - .data - .domains - .contains("unknown.com")); - } - } - - #[cfg(test)] - mod requests_to_allowed_hosts { - use super::*; - - #[tokio::test] - async fn are_allowed() { - let host = "nymtech.net"; - - let filter = setup_with_allowed(&["nymtech.net"]).await; - assert!(filter.check(host).await); - } - - #[tokio::test] - async fn are_allowed_for_subdomains() { - let host = "foomp.nymtech.net"; - - let filter = setup_with_allowed(&["nymtech.net"]).await; - assert!(filter.check(host).await); - } - - #[tokio::test] - async fn are_not_appended_to_file() { - let filter = setup_with_allowed(&["nymtech.net"]).await; - - // test initial state - let lines = - HostsStore::load_from_storefile(&filter.allowed_hosts.get().await.storefile) - .unwrap(); - assert_eq!(1, lines.len()); - - assert!(filter.check("nymtech.net").await); - - // test state after we've checked to make sure no unexpected changes - let lines = - HostsStore::load_from_storefile(&filter.allowed_hosts.get().await.storefile) - .unwrap(); - assert_eq!(1, lines.len()); - } - - #[tokio::test] - async fn are_allowed_for_ipv4_addresses() { - let address_good = "1.1.1.1"; - let address_good_port = "1.1.1.1:1234"; - let address_bad = "1.1.1.2"; - - let filter = setup_with_allowed(&["1.1.1.1"]).await; - assert!(filter.check(address_good).await); - assert!(filter.check(address_good_port).await); - assert!(!filter.check(address_bad).await); - } - - #[tokio::test] - async fn are_allowed_for_ipv6_addresses() { - let ip_v6_full = "2001:0db8:85a3:0000:0000:8a2e:0370:7334"; - let ip_v6_full_rendered = "2001:0db8:85a3::8a2e:0370:7334"; - let ip_v6_full_port = "[2001:0db8:85a3::8a2e:0370:7334]:1234"; - - let ip_v6_semi = "2001:0db8::0001:0000"; - let ip_v6_semi_rendered = "2001:db8::1:0"; - - let ip_v6_loopback_port = "[::1]:1234"; - - let filter1 = setup_with_allowed(&[ip_v6_full, ip_v6_semi, "::1"]).await; - let filter2 = - setup_with_allowed(&[ip_v6_full_rendered, ip_v6_semi_rendered, "::1"]).await; - - assert!(filter1.check(ip_v6_full).await); - assert!(filter1.check(ip_v6_full_rendered).await); - assert!(filter1.check(ip_v6_full_port).await); - assert!(filter1.check(ip_v6_semi).await); - assert!(filter1.check(ip_v6_semi_rendered).await); - assert!(filter1.check(ip_v6_loopback_port).await); - - assert!(filter2.check(ip_v6_full).await); - assert!(filter2.check(ip_v6_full_rendered).await); - assert!(filter2.check(ip_v6_full_port).await); - assert!(filter2.check(ip_v6_semi).await); - assert!(filter2.check(ip_v6_semi_rendered).await); - assert!(filter2.check(ip_v6_loopback_port).await); - } - - #[tokio::test] - async fn are_allowed_for_ipv4_address_ranges() { - let range1 = "127.0.0.1/32"; - let range2 = "1.2.3.4/24"; - - let bottom_range2 = "1.2.3.0"; - let top_range2 = "1.2.3.255"; - - let outside_range2 = "1.2.2.4"; - - let filter = setup_with_allowed(&[range1, range2]).await; - assert!(filter.check("127.0.0.1").await); - assert!(filter.check("127.0.0.1:1234").await); - assert!(filter.check(bottom_range2).await); - assert!(filter.check(top_range2).await); - assert!(!filter.check(outside_range2).await); - } - - #[tokio::test] - async fn are_allowed_for_ipv6_address_ranges() { - let range = "2620:0:2d0:200::7/32"; - - let bottom1 = "2620:0:0:0:0:0:0:0"; - let bottom2 = "2620::"; - - let top = "2620:0:ffff:ffff:ffff:ffff:ffff:ffff"; - let mid = "2620:0:42::42"; - - let filter = setup_with_allowed(&[range]).await; - assert!(filter.check(bottom1).await); - assert!(filter.check(bottom2).await); - assert!(filter.check(top).await); - assert!(filter.check(mid).await); - } - } - - #[cfg(test)] - mod creating_a_new_host_store { - use super::*; - - #[test] - fn loads_its_host_list_from_storefile() { - let mut host_store = HostsStoreFixture::new(); - - host_store.add_host("nymtech.net"); - host_store.add_host("edwardsnowden.com"); - host_store.add_host("1.2.3.4"); - host_store.add_host("5.6.7.8/16"); - host_store.add_host("1:2:3::"); - host_store.add_host("5:6:7::/48"); - - assert!(host_store.data.domains.contains("nymtech.net")); - assert!(host_store.data.domains.contains("edwardsnowden.com")); - - assert!(host_store - .data - .ip_nets - .contains(&"1.2.3.4".parse().unwrap())); - assert!(host_store - .data - .ip_nets - .contains(&"5.6.7.8/16".parse().unwrap())); - assert!(host_store - .data - .ip_nets - .contains(&"1:2:3::".parse().unwrap())); - assert!(host_store - .data - .ip_nets - .contains(&"5:6:7::/48".parse().unwrap())); - } - } -} diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs deleted file mode 100644 index 2c2da2732a..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/group.rs +++ /dev/null @@ -1,61 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use crate::request_filter::allowed_hosts::host::Host; -use ipnetwork::IpNetwork; -use std::collections::HashSet; -use std::net::IpAddr; - -/// A simpled grouped set of hosts. -/// It ignores any port information. -#[derive(Debug)] -pub(crate) struct HostsGroup { - pub(super) domains: HashSet<String>, - pub(super) ip_nets: HashSet<IpNetwork>, -} - -impl HostsGroup { - pub(crate) fn new(raw_hosts: Vec<Host>) -> HostsGroup { - let mut domains = HashSet::new(); - let mut ip_nets = HashSet::new(); - - for host in raw_hosts { - match host { - Host::Domain(domain) => { - domains.insert(domain); - } - Host::IpNetwork(ipnet) => { - ip_nets.insert(ipnet); - } - } - } - - HostsGroup { domains, ip_nets } - } - - pub(crate) fn contains_domain(&self, host: &str) -> bool { - self.domains.contains(host) - } - - pub(super) fn contains_ip_address(&self, address: IpAddr) -> bool { - for ip_net in &self.ip_nets { - if ip_net.contains(address) { - return true; - } - } - - false - } - - pub(super) fn contains_ip_network(&self, network: IpNetwork) -> bool { - self.ip_nets.contains(&network) - } - - pub(super) fn add_ipnet<N: Into<IpNetwork>>(&mut self, network: N) { - self.ip_nets.insert(network.into()); - } - - pub(super) fn add_domain(&mut self, domain: &str) { - self.domains.insert(domain.to_string()); - } -} diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/host.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/host.rs deleted file mode 100644 index 7f86e16aa8..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/host.rs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use ipnetwork::IpNetwork; -use std::str::FromStr; - -// used for parsing file content -#[derive(Debug)] -pub(crate) enum Host { - Domain(String), - IpNetwork(IpNetwork), -} - -impl<S: AsRef<str>> From<S> for Host { - fn from(raw: S) -> Self { - // SAFETY: unwrap here is fine as `FromStr` implementation returns `Infallible` error. - raw.as_ref().parse().unwrap() - } -} - -impl FromStr for Host { - type Err = core::convert::Infallible; - - fn from_str(s: &str) -> Result<Self, Self::Err> { - if let Ok(ipnet) = s.parse() { - Ok(Host::IpNetwork(ipnet)) - } else { - // TODO: perhaps in the future it should do some domain validation? - // - // So for example if somebody put some nonsense in the whitelist file like "foomp", - // it would get rejected? - Ok(Host::Domain(s.to_string())) - } - } -} diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/hosts.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/hosts.rs deleted file mode 100644 index b3dc697464..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/hosts.rs +++ /dev/null @@ -1,203 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use super::host::Host; -use crate::request_filter::allowed_hosts::group::HostsGroup; -use ipnetwork::IpNetwork; -use std::{ - fs::{self, File, OpenOptions}, - io::{self, BufRead, BufReader}, - net::IpAddr, - path::{Path, PathBuf}, -}; - -/// A simple file-backed store for information about allowed / unknown hosts. -/// It ignores any port information. -#[derive(Debug)] -pub(crate) struct HostsStore { - pub(super) storefile: PathBuf, - pub(super) data: HostsGroup, -} - -impl HostsStore { - /// Constructs a new HostsStore. If the storefile does not exist, it will be created. - /// - /// You can inject a list of standard hosts that you want to support, in addition to the ones - /// in the user-defined storefile. - pub(crate) fn new<P: AsRef<Path>>(storefile: P) -> HostsStore { - let storefile = storefile.as_ref().to_path_buf(); - if storefile.exists() && !storefile.is_file() { - // there's no error handling in here and I'm not going to be changing it right now. - panic!( - "the provided storefile {:?} is not a valid file!", - storefile - ) - } - - Self::setup_storefile(&storefile); - let hosts = Self::load_from_storefile(&storefile) - .unwrap_or_else(|_| panic!("Could not load hosts from storefile at {storefile:?}")); - - HostsStore { - storefile, - data: HostsGroup::new(hosts), - } - } - - pub(crate) fn try_reload(&mut self) -> io::Result<()> { - let hosts = Self::load_from_storefile(&self.storefile)?; - self.data = HostsGroup::new(hosts); - Ok(()) - } - - pub(crate) fn contains_domain(&self, host: &str) -> bool { - self.data.contains_domain(host) - } - - pub(super) fn contains_ip_address(&self, address: IpAddr) -> bool { - self.data.contains_ip_address(address) - } - - #[allow(unused)] - pub(super) fn contains_ipnetwork(&self, network: IpNetwork) -> bool { - self.data.contains_ip_network(network) - } - - #[allow(unused)] - pub(super) fn add_host<H: Into<Host>>(&mut self, host: H) { - match host.into() { - Host::Domain(domain) => self.add_domain(&domain), - Host::IpNetwork(ipnet) => self.add_ipnet(ipnet), - } - } - - #[allow(unused)] - pub(super) fn add_ipnet(&mut self, network: IpNetwork) { - if !self.contains_ipnetwork(network) { - self.data.add_ipnet(network); - self.append_to_file(&network.to_string()); - } - } - - pub(super) fn add_ip(&mut self, ip: IpAddr) { - if !self.contains_ip_address(ip) { - self.data.add_ipnet(ip); - self.append_to_file(&ip.to_string()); - } - } - - pub(super) fn add_domain(&mut self, domain: &str) { - if !self.contains_domain(domain) { - self.data.add_domain(domain); - self.append_to_file(domain); - } - } - - /// Appends a line of `text` to the storefile at `path` - pub(super) fn append(path: &Path, text: &str) { - use std::io::Write; - let mut file = OpenOptions::new().append(true).open(path).unwrap(); - - if let Err(e) = writeln!(file, "{text}") { - log::error!("Couldn't write to file: {e}"); - } - } - - fn append_to_file(&self, host: &str) { - HostsStore::append(&self.storefile, host); - } - - fn setup_storefile(file: &PathBuf) { - if !file.exists() { - let parent_dir = file - .parent() - .expect("parent dir does not exist for {file:?}"); - fs::create_dir_all(parent_dir) - .unwrap_or_else(|_| panic!("could not create storage directory at {parent_dir:?}")); - log::trace!("Creating: {file:?}"); - File::create(file).unwrap(); - } - } - - /// Loads the storefile contents into memory. - pub(super) fn load_from_storefile<P>(filename: P) -> io::Result<Vec<Host>> - where - P: AsRef<Path>, - { - log::trace!("Loading from storefile: {}", filename.as_ref().display()); - let file = File::open(filename)?; - let reader = BufReader::new(&file); - let hosts = reader - .lines() - .filter_map(|line| { - let line = line.expect("failed to read input file line!"); - trim_comment(&line) - }) - .map(Host::from) - .collect(); - Ok(hosts) - } -} - -fn trim_comment(line: &str) -> Option<String> { - if let Some(content) = line.split('#').next() { - let trim_content = content.trim().to_string(); - if trim_content.is_empty() { - None - } else { - Some(trim_content) - } - } else { - None - } -} - -#[cfg(test)] -mod constructor_tests { - use super::*; - - #[test] - fn works_with_no_standard_hosts() { - let temp_file = tempfile::NamedTempFile::new().unwrap(); - let store = HostsStore::new(temp_file); - assert_eq!(store.data.domains.len(), 0); - } - - #[test] - fn trim_comments() { - let entries = vec![ - "# keybase", - "keybaseapi.com", - "", - "gist.githubusercontent.com", - " ", - "# healthcheck # foo", - "nymtech.net", - "# blockstream green wallet", - "blockstream.info", - "greenaddress.it", - "91.108.56.0/22", - "2001:b28:f23d::/48", - "2001:67c:4e8::/48", - "# nym matrix server", - "# monero desktop - mainnet", - ]; - let filtered_entries: Vec<_> = entries - .iter() - .filter_map(|line| trim_comment(line)) - .collect(); - assert_eq!( - filtered_entries, - vec![ - "keybaseapi.com", - "gist.githubusercontent.com", - "nymtech.net", - "blockstream.info", - "greenaddress.it", - "91.108.56.0/22", - "2001:b28:f23d::/48", - "2001:67c:4e8::/48", - ] - ); - } -} diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/mod.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/mod.rs deleted file mode 100644 index 225f6418b5..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/mod.rs +++ /dev/null @@ -1,13 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -mod filter; -mod group; -mod host; -mod hosts; -pub(crate) mod standard_list; -pub(crate) mod stored_allowed_hosts; - -pub(crate) use filter::OutboundRequestFilter; -pub(crate) use hosts::HostsStore; -pub(crate) use standard_list::StandardList; diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/standard_list.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/standard_list.rs deleted file mode 100644 index 79b7c75901..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/standard_list.rs +++ /dev/null @@ -1,113 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use crate::request_filter::allowed_hosts::group::HostsGroup; -use crate::request_filter::allowed_hosts::host::Host; -use nym_task::TaskClient; -use regex::Regex; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::{RwLock, RwLockReadGuard}; - -const STANDARD_LIST_URL: &str = - "https://nymtech.net/.wellknown/network-requester/standard-allowed-list.txt"; - -fn remove_comments(text: String) -> String { - if let Ok(regex) = Regex::new(r"#.*\n") { - regex.replace_all(&text, "").into_owned() - } else { - log::warn!("Failed to strip comments from standard allowed list"); - text - } -} - -/// Fetch the standard allowed list from nymtech.net -pub(crate) async fn fetch() -> Vec<Host> { - log::info!("Refreshing standard allowed hosts"); - let text = get_standard_allowed_list().await; - remove_comments(text) - .split_whitespace() - .map(Into::into) - .collect() -} - -async fn get_standard_allowed_list() -> String { - reqwest::get(STANDARD_LIST_URL) - .await - .expect("failed to get allowed hosts") - .text() - .await - .expect("failed to get allowed hosts text") -} - -#[derive(Clone, Debug)] -pub(crate) struct StandardList { - inner: Arc<RwLock<HostsGroup>>, -} - -impl StandardList { - // note: standard list will be fetched immediately when `StandardListUpdater::run` is called - // (because first `tick()` of tokio interval fires up immediately) - pub(crate) fn new() -> Self { - StandardList { - inner: Arc::new(RwLock::new(HostsGroup::new(Vec::new()))), - } - } - - pub(crate) async fn update(&self) { - let raw_standard_list = fetch().await; - log::debug!("fetched allowed hosts: {:?}", raw_standard_list); - - let new_data = HostsGroup::new(raw_standard_list); - *self.inner.write().await = new_data - } - - pub(crate) async fn get(&self) -> RwLockReadGuard<'_, HostsGroup> { - self.inner.read().await - } -} - -pub(crate) struct StandardListUpdater { - update_interval: Duration, - standard_list: StandardList, - - // Listens to shutdown commands from higher up - shutdown_listener: TaskClient, -} - -impl StandardListUpdater { - pub(crate) fn new( - update_interval: Duration, - standard_list: StandardList, - shutdown_listener: TaskClient, - ) -> Self { - Self { - update_interval, - standard_list, - shutdown_listener, - } - } - - pub(crate) async fn run(&mut self) { - let mut update_interval = tokio::time::interval(self.update_interval); - - while !self.shutdown_listener.is_shutdown() { - tokio::select! { - biased; - _ = self.shutdown_listener.recv() => { - log::trace!("StandardListUpdater: Received shutdown"); - } - _ = update_interval.tick() => { - log::debug!("updating standard list"); - self.standard_list.update().await - } - } - } - - log::debug!("StandardListUpdater: Exiting"); - } - - pub(crate) fn start(mut self) { - tokio::spawn(async move { self.run().await }); - } -} diff --git a/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs b/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs deleted file mode 100644 index a2e2537dba..0000000000 --- a/service-providers/network-requester/src/request_filter/allowed_hosts/stored_allowed_hosts.rs +++ /dev/null @@ -1,127 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use crate::request_filter::allowed_hosts::HostsStore; -use futures::channel::mpsc; -use futures::StreamExt; -use nym_async_file_watcher::{AsyncFileWatcher, FileWatcherEventReceiver}; -use nym_task::TaskClient; -use std::io; -use std::path::Path; -use std::sync::Arc; -use tokio::sync::{RwLock, RwLockReadGuard}; - -#[derive(Debug, Clone)] -pub(crate) struct StoredAllowedHosts { - inner: Arc<RwLock<HostsStore>>, -} - -impl StoredAllowedHosts { - pub(crate) fn new<P: AsRef<Path>>(path: P) -> Self { - let allowed_hosts = HostsStore::new(path); - - StoredAllowedHosts { - inner: Arc::new(RwLock::new(allowed_hosts)), - } - } - - pub(crate) async fn reload(&self) -> io::Result<()> { - log::debug!("reloading stored allowed hosts"); - self.inner.write().await.try_reload() - } - - pub(crate) async fn get(&self) -> RwLockReadGuard<'_, HostsStore> { - self.inner.read().await - } -} - -impl From<HostsStore> for StoredAllowedHosts { - fn from(value: HostsStore) -> Self { - StoredAllowedHosts { - inner: Arc::new(RwLock::new(value)), - } - } -} - -pub(crate) struct StoredAllowedHostsReloader { - stored_hosts: StoredAllowedHosts, - events_receiver: FileWatcherEventReceiver, - - // Listens to shutdown commands from higher up - shutdown_listener: TaskClient, -} - -impl StoredAllowedHostsReloader { - pub(crate) fn new( - stored_hosts: StoredAllowedHosts, - events_receiver: FileWatcherEventReceiver, - shutdown_listener: TaskClient, - ) -> Self { - StoredAllowedHostsReloader { - events_receiver, - stored_hosts, - shutdown_listener, - } - } - - pub(crate) async fn run(&mut self) { - while !self.shutdown_listener.is_shutdown() { - tokio::select! { - biased; - _ = self.shutdown_listener.recv() => { - log::trace!("StoredAllowedHostsReloader: Received shutdown"); - } - event = self.events_receiver.next() => { - let Some(event) = event else { - log::trace!("StoredAllowedHostsReloader: sender channel has terminated"); - break - }; - log::debug!("the file has changed - {event:?}"); - log::debug!("reloading stored hosts"); - if let Err(err) = self.stored_hosts.reload().await { - log::error!("failed to reload stored hosts: {err}") - } - } - } - } - - log::debug!("StoredAllowedHostsReloader: Exiting"); - } - - pub(crate) fn start(mut self) { - tokio::spawn(async move { self.run().await }); - } -} - -async fn run_watcher(mut watcher: AsyncFileWatcher, mut shutdown: TaskClient) { - tokio::select! { - biased; - _ = shutdown.recv() => { - log::trace!("AsyncFileWatcher: Received shutdown"); - } - res = watcher.watch() => { - log::trace!("AsyncFileWatcher: finished with {res:?}"); - } - } - log::debug!("AsyncFileWatcher: Exiting"); -} - -fn start_watcher(watcher: AsyncFileWatcher, shutdown: TaskClient) { - tokio::spawn(async move { run_watcher(watcher, shutdown).await }); -} - -pub(crate) async fn start_allowed_list_reloader( - stored_list: StoredAllowedHosts, - shutdown_listener: TaskClient, -) { - let (events_sender, events_receiver) = mpsc::unbounded(); - let file = stored_list.get().await.storefile.clone(); - - let watcher = AsyncFileWatcher::new_file_changes_watcher(file, events_sender) - .expect("failed to create file watcher"); - let reloader = - StoredAllowedHostsReloader::new(stored_list, events_receiver, shutdown_listener.clone()); - - start_watcher(watcher, shutdown_listener); - reloader.start() -} diff --git a/service-providers/network-requester/src/request_filter/exit_policy/mod.rs b/service-providers/network-requester/src/request_filter/exit_policy/mod.rs index 5fdcc28b57..d3c3a99681 100644 --- a/service-providers/network-requester/src/request_filter/exit_policy/mod.rs +++ b/service-providers/network-requester/src/request_filter/exit_policy/mod.rs @@ -1,6 +1,7 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::config::Config; use crate::error::NetworkRequesterError; use log::trace; use nym_exit_policy::client::get_exit_policy; @@ -15,6 +16,12 @@ pub struct ExitPolicyRequestFilter { policy: ExitPolicy, } +impl From<ExitPolicy> for ExitPolicyRequestFilter { + fn from(value: ExitPolicy) -> Self { + ExitPolicyRequestFilter::new_from_policy(value) + } +} + impl ExitPolicyRequestFilter { pub(crate) async fn new_upstream(url: impl IntoUrl) -> Result<Self, NetworkRequesterError> { let url = url @@ -27,7 +34,21 @@ impl ExitPolicyRequestFilter { }) } - pub(crate) fn new(policy: ExitPolicy) -> Self { + pub(crate) async fn new(config: &Config) -> Result<Self, NetworkRequesterError> { + let policy_filter = if config.network_requester.open_proxy { + ExitPolicyRequestFilter::new_from_policy(ExitPolicy::new_open()) + } else { + let upstream_url = config + .network_requester + .upstream_exit_policy_url + .as_ref() + .ok_or(NetworkRequesterError::NoUpstreamExitPolicy)?; + ExitPolicyRequestFilter::new_upstream(upstream_url.clone()).await? + }; + Ok(policy_filter) + } + + pub fn new_from_policy(policy: ExitPolicy) -> Self { ExitPolicyRequestFilter { upstream: None, policy, diff --git a/service-providers/network-requester/src/request_filter/mod.rs b/service-providers/network-requester/src/request_filter/mod.rs index 25f34ae591..b1534ce7b8 100644 --- a/service-providers/network-requester/src/request_filter/mod.rs +++ b/service-providers/network-requester/src/request_filter/mod.rs @@ -1,143 +1,36 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::{self, Config}; +use crate::config::Config; use crate::error::NetworkRequesterError; -use crate::request_filter::allowed_hosts::standard_list::StandardListUpdater; -use crate::request_filter::allowed_hosts::stored_allowed_hosts::{ - start_allowed_list_reloader, StoredAllowedHosts, -}; -use crate::request_filter::allowed_hosts::{OutboundRequestFilter, StandardList}; -use crate::request_filter::exit_policy::ExitPolicyRequestFilter; -use log::{info, warn}; -use nym_exit_policy::ExitPolicy; +use log::warn; use nym_socks5_requests::RemoteAddress; -use nym_task::TaskHandle; use std::sync::Arc; -/// Old request filtering based on the allowed.list files. -pub mod allowed_hosts; pub mod exit_policy; -enum RequestFilterInner { - AllowList { - open_proxy: bool, - filter: OutboundRequestFilter, - }, - ExitPolicy { - policy_filter: ExitPolicyRequestFilter, - }, -} +pub use exit_policy::ExitPolicyRequestFilter; #[derive(Clone)] pub struct RequestFilter { - inner: Arc<RequestFilterInner>, + inner: Arc<ExitPolicyRequestFilter>, } impl RequestFilter { pub(crate) async fn new(config: &Config) -> Result<Self, NetworkRequesterError> { - if config.network_requester.use_deprecated_allow_list { - info!("setting up allow-list based 'OutboundRequestFilter'..."); - Ok(Self::new_allow_list_request_filter(config).await) - } else { - info!("setting up ExitPolicy based request filter..."); - Self::new_exit_policy_filter(config).await - } - } - - pub fn current_exit_policy_filter(&self) -> Option<&ExitPolicyRequestFilter> { - match &*self.inner { - RequestFilterInner::AllowList { .. } => None, - RequestFilterInner::ExitPolicy { policy_filter } => Some(policy_filter), - } - } - - pub(crate) async fn start_update_tasks( - &self, - config: &config::Debug, - task_handle: &TaskHandle, - ) { - match &*self.inner { - RequestFilterInner::AllowList { open_proxy, filter } => { - // if we're running in open proxy, we don't have to spawn any refreshers, - // after all, we're going to be accepting all requests regardless - // of the local allow list or the standard list - if *open_proxy { - return; - } - - // start the standard list updater - StandardListUpdater::new( - config.standard_list_update_interval, - filter.standard_list(), - task_handle.get_handle().named("StandardListUpdater"), - ) - .start(); - - // start the allowed.list watcher and updater - start_allowed_list_reloader( - filter.allowed_hosts(), - task_handle - .get_handle() - .named("stored_allowed_hosts_reloader"), - ) - .await; - } - RequestFilterInner::ExitPolicy { .. } => { - // nothing to do for the exit policy (yet; we might add a refresher at some point) - } - } - } - - async fn new_allow_list_request_filter(config: &Config) -> Self { - let standard_list = StandardList::new(); - let allowed_hosts = StoredAllowedHosts::new(&config.storage_paths.allowed_list_location); - let unknown_hosts = - allowed_hosts::HostsStore::new(&config.storage_paths.unknown_list_location); - - // TODO: technically if we're running open proxy, we don't have to be loading anything here - RequestFilter { - inner: Arc::new(RequestFilterInner::AllowList { - open_proxy: config.network_requester.open_proxy, - filter: OutboundRequestFilter::new(allowed_hosts, standard_list, unknown_hosts) - .await, - }), - } - } - - async fn new_exit_policy_filter(config: &Config) -> Result<Self, NetworkRequesterError> { - let policy_filter = if config.network_requester.open_proxy { - ExitPolicyRequestFilter::new(ExitPolicy::new_open()) - } else { - let upstream_url = config - .network_requester - .upstream_exit_policy_url - .as_ref() - .ok_or(NetworkRequesterError::NoUpstreamExitPolicy)?; - ExitPolicyRequestFilter::new_upstream(upstream_url.clone()).await? - }; Ok(RequestFilter { - inner: Arc::new(RequestFilterInner::ExitPolicy { policy_filter }), + inner: Arc::new(ExitPolicyRequestFilter::new(config).await?), }) } + pub fn current_exit_policy_filter(&self) -> &ExitPolicyRequestFilter { + &*self.inner + } + pub(crate) async fn check_address(&self, address: &RemoteAddress) -> bool { - match &*self.inner { - RequestFilterInner::AllowList { open_proxy, filter } => { - if *open_proxy { - return true; - } - filter.check(address).await - } - RequestFilterInner::ExitPolicy { policy_filter } => { - match policy_filter.check(address).await { - Err(err) => { - warn!("failed to validate '{address}' against the exit policy: {err}"); - false - } - Ok(res) => res, - } - } - } + self.inner.check(address).await.unwrap_or_else(|err| { + warn!("failed to validate '{address}' against the exit policy: {err}"); + false + }) } } From fb2b2c963b6b2f0d053d87c4fe931a40fd9d66b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 13:51:47 +0000 Subject: [PATCH 341/394] moved and renamed NR old config structs --- .../network-requester/src/config/helpers.rs | 22 ++-- .../network-requester/src/config/mod.rs | 11 +- .../network-requester/src/config/old/mod.rs | 22 ++++ .../{old_config_v1_1_13.rs => old/v1.rs} | 20 +-- .../{old_config_v1_1_20.rs => old/v2.rs} | 43 +++---- .../{old_config_v1_1_20_2.rs => old/v3.rs} | 60 ++++----- .../{old_config_v1_1_33.rs => old/v4.rs} | 45 +++---- .../src/config/old_config_v1_1_19.rs | 120 ------------------ .../{persistence.rs => persistence/mod.rs} | 2 + .../src/config/persistence/old/mod.rs | 5 + .../src/config/persistence/old/v1.rs | 18 +++ .../src/config/persistence/old/v2.rs | 21 +++ 12 files changed, 155 insertions(+), 234 deletions(-) create mode 100644 service-providers/network-requester/src/config/old/mod.rs rename service-providers/network-requester/src/config/{old_config_v1_1_13.rs => old/v1.rs} (60%) rename service-providers/network-requester/src/config/{old_config_v1_1_20.rs => old/v2.rs} (78%) rename service-providers/network-requester/src/config/{old_config_v1_1_20_2.rs => old/v3.rs} (66%) rename service-providers/network-requester/src/config/{old_config_v1_1_33.rs => old/v4.rs} (79%) delete mode 100644 service-providers/network-requester/src/config/old_config_v1_1_19.rs rename service-providers/network-requester/src/config/{persistence.rs => persistence/mod.rs} (99%) create mode 100644 service-providers/network-requester/src/config/persistence/old/mod.rs create mode 100644 service-providers/network-requester/src/config/persistence/old/v1.rs create mode 100644 service-providers/network-requester/src/config/persistence/old/v2.rs diff --git a/service-providers/network-requester/src/config/helpers.rs b/service-providers/network-requester/src/config/helpers.rs index e03281fa01..f3d540334c 100644 --- a/service-providers/network-requester/src/config/helpers.rs +++ b/service-providers/network-requester/src/config/helpers.rs @@ -2,10 +2,10 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::default_config_filepath; -use crate::config::old_config_v1_1_13::OldConfigV1_1_13; -use crate::config::old_config_v1_1_20::ConfigV1_1_20; -use crate::config::old_config_v1_1_20_2::ConfigV1_1_20_2; -use crate::config::old_config_v1_1_33::ConfigV1_1_33; +use crate::config::old_config_v1_1_13::OldConfigV1; +use crate::config::old_config_v1_1_20::ConfigV2; +use crate::config::old_config_v1_1_20_2::ConfigV3; +use crate::config::old_config_v1_1_33::ConfigV14; use crate::error::NetworkRequesterError; use log::{info, trace}; use nym_client_core::cli_helpers::CliClientConfig; @@ -19,7 +19,7 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.13 (which is incompatible with the next step, i.e. 1.1.19) - let Ok(old_config) = OldConfigV1_1_13::load_from_filepath(config_path.as_ref()) else { + let Ok(old_config) = OldConfigV1::load_from_filepath(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -27,8 +27,8 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( info!("It seems the client is using <= v1.1.13 config template."); info!("It is going to get updated to the current specification."); - let updated_step1: ConfigV1_1_20 = old_config.into(); - let updated_step2: ConfigV1_1_20_2 = updated_step1.into(); + let updated_step1: ConfigV2 = old_config.into(); + let updated_step2: ConfigV3 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; let old_paths = updated_step3.storage_paths.clone(); let updated = updated_step3.try_upgrade()?; @@ -51,7 +51,7 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( use nym_config::legacy_helpers::nym_config::MigrationNymConfig; // explicitly load it as v1.1.20 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20::load_from_filepath(config_path.as_ref()) else { + let Ok(old_config) = ConfigV2::load_from_filepath(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -60,7 +60,7 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( info!("It seems the client is using <= v1.1.20 config template."); info!("It is going to get updated to the current specification."); - let updated_step1: ConfigV1_1_20_2 = old_config.into(); + let updated_step1: ConfigV3 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; let old_paths = updated_step2.storage_paths.clone(); let updated = updated_step2.try_upgrade()?; @@ -82,7 +82,7 @@ async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( trace!("Trying to load as v1.1.20_2 config"); // explicitly load it as v1.1.20_2 (which is incompatible with the current one, i.e. +1.1.21) - let Ok(old_config) = ConfigV1_1_20_2::read_from_toml_file(config_path.as_ref()) else { + let Ok(old_config) = ConfigV3::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -111,7 +111,7 @@ async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( trace!("Trying to load as v1.1.33 config"); // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) - let Ok(old_config) = ConfigV1_1_33::read_from_toml_file(config_path.as_ref()) else { + let Ok(old_config) = ConfigV14::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index a1bc434d92..e4d701c537 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -24,13 +24,16 @@ use url::Url; pub use nym_client_core::config::Config as BaseClientConfig; pub mod helpers; -pub mod old_config_v1_1_13; -pub mod old_config_v1_1_20; -pub mod old_config_v1_1_20_2; -pub mod old_config_v1_1_33; +pub mod old; mod persistence; mod template; +// aliases for backwards compatibility +pub use old::v1 as old_config_v1_1_13; +pub use old::v2 as old_config_v1_1_20; +pub use old::v3 as old_config_v1_1_20_2; +pub use old::v4 as old_config_v1_1_33; + const DEFAULT_NETWORK_REQUESTERS_DIR: &str = "network-requester"; pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); diff --git a/service-providers/network-requester/src/config/old/mod.rs b/service-providers/network-requester/src/config/old/mod.rs new file mode 100644 index 0000000000..e19685b02c --- /dev/null +++ b/service-providers/network-requester/src/config/old/mod.rs @@ -0,0 +1,22 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1; +pub mod v2; +pub mod v3; +pub mod v4; + +// // aliases for backwards compatibility +// pub use v1 as old_config_v1_1_13; +// pub use v2 as old_config_v1_1_20; +// pub use v3 as old_config_v1_1_20_2; +// pub use v4 as old_config_v1_1_30; +// pub use v5 as old_config_v1_1_33; + +/* + deleted: src/config/old_config_v1_1_13.rs + deleted: src/config/old_config_v1_1_19.rs + deleted: src/config/old_config_v1_1_20.rs + deleted: src/config/old_config_v1_1_20_2.rs + deleted: src/config/old_config_v1_1_33.rs +*/ diff --git a/service-providers/network-requester/src/config/old_config_v1_1_13.rs b/service-providers/network-requester/src/config/old/v1.rs similarity index 60% rename from service-providers/network-requester/src/config/old_config_v1_1_13.rs rename to service-providers/network-requester/src/config/old/v1.rs index a57d9222a6..31dbff9bb5 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_13.rs +++ b/service-providers/network-requester/src/config/old/v1.rs @@ -1,7 +1,7 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 -use crate::config::old_config_v1_1_20::ConfigV1_1_20; +use crate::config::old_config_v1_1_20::ConfigV2; use nym_client_core::config::old_config_v1_1_13::OldConfigV1_1_13 as OldBaseConfigV1_1_13; use nym_config::legacy_helpers::nym_config::MigrationNymConfig; use serde::{Deserialize, Serialize}; @@ -9,24 +9,24 @@ use std::path::PathBuf; #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct OldConfigV1_1_13 { +pub struct OldConfigV1 { #[serde(flatten)] - pub base: OldBaseConfigV1_1_13<OldConfigV1_1_13>, + pub base: OldBaseConfigV1_1_13<OldConfigV1>, } -impl MigrationNymConfig for OldConfigV1_1_13 { +impl MigrationNymConfig for OldConfigV1 { fn default_root_directory() -> PathBuf { dirs::home_dir() .expect("Failed to evaluate $HOME value") .join(".nym") - .join("service-providers") + .join("../../../..") .join("network-requester") } } -impl From<OldConfigV1_1_13> for ConfigV1_1_20 { - fn from(value: OldConfigV1_1_13) -> Self { - ConfigV1_1_20 { +impl From<OldConfigV1> for ConfigV2 { + fn from(value: OldConfigV1) -> Self { + ConfigV2 { base: value.base.into(), network_requester: Default::default(), network_requester_debug: Default::default(), diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20.rs b/service-providers/network-requester/src/config/old/v2.rs similarity index 78% rename from service-providers/network-requester/src/config/old_config_v1_1_20.rs rename to service-providers/network-requester/src/config/old/v2.rs index 603b0f6d92..2747047a4e 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20.rs +++ b/service-providers/network-requester/src/config/old/v2.rs @@ -1,9 +1,8 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 -use crate::config::old_config_v1_1_20_2::{ - ConfigV1_1_20_2, DebugV1_1_20_2, NetworkRequesterPathsV1_1_20_2, -}; +use crate::config::old_config_v1_1_20_2::{ConfigV3, DebugV3}; +use crate::config::persistence::old::v1::NetworkRequesterPathsV1; use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::disk_persistence::old_v1_1_33::ClientKeysPathsV1_1_33; use nym_client_core::config::old_config_v1_1_20::ConfigV1_1_20 as BaseConfigV1_1_20; @@ -19,20 +18,20 @@ const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_20 { +pub struct ConfigV2 { #[serde(flatten)] - pub base: BaseConfigV1_1_20<ConfigV1_1_20>, + pub base: BaseConfigV1_1_20<ConfigV2>, #[serde(default)] pub network_requester: NetworkRequster, #[serde(default)] - pub network_requester_debug: DebugV1_1_20, + pub network_requester_debug: DebugV2, } -impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { - fn from(value: ConfigV1_1_20) -> Self { - ConfigV1_1_20_2 { +impl From<ConfigV2> for ConfigV3 { + fn from(value: ConfigV2) -> Self { + ConfigV3 { base: BaseClientConfigV1_1_20_2 { client: ClientV1_1_20_2 { version: value.base.client.version, @@ -45,7 +44,7 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { debug: Default::default(), }, network_requester: Default::default(), - storage_paths: NetworkRequesterPathsV1_1_20_2 { + storage_paths: NetworkRequesterPathsV1 { common_paths: CommonClientPathsV1_1_20_2 { keys: ClientKeysPathsV1_1_33 { private_identity_key_file: value.base.client.private_identity_key_file, @@ -67,12 +66,12 @@ impl From<ConfigV1_1_20> for ConfigV1_1_20_2 { } } -impl MigrationNymConfig for ConfigV1_1_20 { +impl MigrationNymConfig for ConfigV2 { fn default_root_directory() -> PathBuf { dirs::home_dir() .expect("Failed to evaluate $HOME value") .join(".nym") - .join("service-providers") + .join("../../../..") .join("network-requester") } } @@ -88,9 +87,9 @@ impl Default for NetworkRequster { fn default() -> Self { // same defaults as we had in <= v1.1.13 NetworkRequster { - allowed_list_location: <ConfigV1_1_20 as MigrationNymConfig>::default_root_directory() + allowed_list_location: <ConfigV2 as MigrationNymConfig>::default_root_directory() .join("allowed.list"), - unknown_list_location: <ConfigV1_1_20 as MigrationNymConfig>::default_root_directory() + unknown_list_location: <ConfigV2 as MigrationNymConfig>::default_root_directory() .join("unknown.list"), } } @@ -98,22 +97,22 @@ impl Default for NetworkRequster { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugV1_1_20 { +pub struct DebugV2 { #[serde(with = "humantime_serde")] pub standard_list_update_interval: Duration, } -impl From<DebugV1_1_20> for DebugV1_1_20_2 { - fn from(value: DebugV1_1_20) -> Self { - DebugV1_1_20_2 { +impl From<DebugV2> for DebugV3 { + fn from(value: DebugV2) -> Self { + DebugV3 { standard_list_update_interval: value.standard_list_update_interval, } } } -impl Default for DebugV1_1_20 { +impl Default for DebugV2 { fn default() -> Self { - DebugV1_1_20 { + DebugV2 { standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, } } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs b/service-providers/network-requester/src/config/old/v3.rs similarity index 66% rename from service-providers/network-requester/src/config/old_config_v1_1_20_2.rs rename to service-providers/network-requester/src/config/old/v3.rs index 8fe4c90232..37d7925fcf 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_20_2.rs +++ b/service-providers/network-requester/src/config/old/v3.rs @@ -1,56 +1,42 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use super::old_config_v1_1_33::{ - ConfigV1_1_33, DebugV1_1_33, NetworkRequesterPathsV1_1_33, NetworkRequesterV1_1_33, -}; +use super::v4::{ConfigV14, DebugV4, NetworkRequesterV4}; +use crate::config::persistence::old::v1::NetworkRequesterPathsV1; +use crate::config::persistence::old::v2::NetworkRequesterPathsV2; +use crate::config::persistence::DEFAULT_DESCRIPTION_FILENAME; use crate::{config::default_config_filepath, error::NetworkRequesterError}; use log::trace; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; use nym_client_core::config::old_config_v1_1_20_2::ConfigV1_1_20_2 as BaseClientConfigV1_1_20_2; use nym_client_core::config::old_config_v1_1_30::ConfigV1_1_30 as BaseConfigV1_1_30; use nym_client_core::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; use nym_config::read_config_from_toml_file; use serde::{Deserialize, Serialize}; use std::io; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::time::Duration; -use super::persistence::DEFAULT_DESCRIPTION_FILENAME; - pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] -pub struct NetworkRequesterPathsV1_1_20_2 { - #[serde(flatten)] - pub common_paths: CommonClientPathsV1_1_20_2, - - /// Location of the file containing our allow.list - pub allowed_list_location: PathBuf, - - /// Location of the file containing our unknown.list - pub unknown_list_location: PathBuf, -} - #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_20_2 { +pub struct ConfigV3 { #[serde(flatten)] pub base: BaseClientConfigV1_1_20_2, #[serde(default)] - pub network_requester: NetworkRequesterV1_1_20_2, + pub network_requester: NetworkRequesterV3, - pub storage_paths: NetworkRequesterPathsV1_1_20_2, + pub storage_paths: NetworkRequesterPathsV1, #[serde(default)] - pub network_requester_debug: DebugV1_1_20_2, + pub network_requester_debug: DebugV3, pub logging: LoggingSettings, } -impl ConfigV1_1_20_2 { +impl ConfigV3 { pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { read_config_from_toml_file(path) } @@ -64,7 +50,7 @@ impl ConfigV1_1_20_2 { // so its returned to be stored elsewhere. pub fn upgrade( self, - ) -> Result<(ConfigV1_1_33, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> { + ) -> Result<(ConfigV14, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> { trace!("Upgrading from v1.1.20_2"); let gateway_details = self.base.client.gateway_endpoint.clone().into(); let nr_description = self @@ -75,9 +61,9 @@ impl ConfigV1_1_20_2 { .parent() .expect("config paths upgrade failure") .join(DEFAULT_DESCRIPTION_FILENAME); - let config = ConfigV1_1_33 { + let config = ConfigV14 { base: BaseConfigV1_1_30::from(self.base).into(), - storage_paths: NetworkRequesterPathsV1_1_33 { + storage_paths: NetworkRequesterPathsV2 { common_paths: self.storage_paths.common_paths.upgrade_default()?, allowed_list_location: self.storage_paths.allowed_list_location, unknown_list_location: self.storage_paths.unknown_list_location, @@ -94,33 +80,33 @@ impl ConfigV1_1_20_2 { #[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct NetworkRequesterV1_1_20_2 {} +pub struct NetworkRequesterV3 {} -impl From<NetworkRequesterV1_1_20_2> for NetworkRequesterV1_1_33 { - fn from(_value: NetworkRequesterV1_1_20_2) -> Self { - NetworkRequesterV1_1_33::default() +impl From<NetworkRequesterV3> for NetworkRequesterV4 { + fn from(_value: NetworkRequesterV3) -> Self { + NetworkRequesterV4::default() } } #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugV1_1_20_2 { +pub struct DebugV3 { /// Defines how often the standard allow list should get updated #[serde(with = "humantime_serde")] pub standard_list_update_interval: Duration, } -impl From<DebugV1_1_20_2> for DebugV1_1_33 { - fn from(value: DebugV1_1_20_2) -> Self { - DebugV1_1_33 { +impl From<DebugV3> for DebugV4 { + fn from(value: DebugV3) -> Self { + DebugV4 { standard_list_update_interval: value.standard_list_update_interval, } } } -impl Default for DebugV1_1_20_2 { +impl Default for DebugV3 { fn default() -> Self { - DebugV1_1_20_2 { + DebugV3 { standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, } } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_33.rs b/service-providers/network-requester/src/config/old/v4.rs similarity index 79% rename from service-providers/network-requester/src/config/old_config_v1_1_33.rs rename to service-providers/network-requester/src/config/old/v4.rs index b3089b036f..8e13c7d5a9 100644 --- a/service-providers/network-requester/src/config/old_config_v1_1_33.rs +++ b/service-providers/network-requester/src/config/old/v4.rs @@ -1,56 +1,41 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::config::persistence::old::v2::NetworkRequesterPathsV2; use crate::config::persistence::NetworkRequesterPaths; use crate::config::Config; use crate::config::{default_config_filepath, Debug, NetworkRequester}; use crate::error::NetworkRequesterError; use nym_bin_common::logging::LoggingSettings; -use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33; use nym_config::read_config_from_toml_file; use nym_config::serde_helpers::de_maybe_stringified; use serde::{Deserialize, Serialize}; use std::io; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::time::Duration; use url::Url; pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); -#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] -pub struct NetworkRequesterPathsV1_1_33 { - #[serde(flatten)] - pub common_paths: CommonClientPathsV1_1_33, - - /// Location of the file containing our allow.list - pub allowed_list_location: PathBuf, - - /// Location of the file containing our unknown.list - pub unknown_list_location: PathBuf, - - #[serde(default)] - pub nr_description: PathBuf, -} - #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_33 { +pub struct ConfigV14 { #[serde(flatten)] pub base: BaseConfigV1_1_33, #[serde(default)] - pub network_requester: NetworkRequesterV1_1_33, + pub network_requester: NetworkRequesterV4, - pub storage_paths: NetworkRequesterPathsV1_1_33, + pub storage_paths: NetworkRequesterPathsV2, #[serde(default)] - pub network_requester_debug: DebugV1_1_33, + pub network_requester_debug: DebugV4, pub logging: LoggingSettings, } -impl ConfigV1_1_33 { +impl ConfigV14 { pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { read_config_from_toml_file(path) } @@ -78,7 +63,7 @@ impl ConfigV1_1_33 { #[derive(Debug, Default, Clone, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct NetworkRequesterV1_1_33 { +pub struct NetworkRequesterV4 { /// specifies whether this network requester should run in 'open-proxy' mode /// and thus would attempt to resolve **ANY** request it receives. pub open_proxy: bool, @@ -103,8 +88,8 @@ pub struct NetworkRequesterV1_1_33 { pub upstream_exit_policy_url: Option<Url>, } -impl From<NetworkRequesterV1_1_33> for NetworkRequester { - fn from(value: NetworkRequesterV1_1_33) -> Self { +impl From<NetworkRequesterV4> for NetworkRequester { + fn from(value: NetworkRequesterV4) -> Self { NetworkRequester { open_proxy: value.open_proxy, enabled_statistics: value.enabled_statistics, @@ -118,23 +103,23 @@ impl From<NetworkRequesterV1_1_33> for NetworkRequester { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugV1_1_33 { +pub struct DebugV4 { /// Defines how often the standard allow list should get updated #[serde(with = "humantime_serde")] pub standard_list_update_interval: Duration, } -impl From<DebugV1_1_33> for Debug { - fn from(value: DebugV1_1_33) -> Self { +impl From<DebugV4> for Debug { + fn from(value: DebugV4) -> Self { Debug { standard_list_update_interval: value.standard_list_update_interval, } } } -impl Default for DebugV1_1_33 { +impl Default for DebugV4 { fn default() -> Self { - DebugV1_1_33 { + DebugV4 { standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, } } diff --git a/service-providers/network-requester/src/config/old_config_v1_1_19.rs b/service-providers/network-requester/src/config/old_config_v1_1_19.rs deleted file mode 100644 index 0a0c159d02..0000000000 --- a/service-providers/network-requester/src/config/old_config_v1_1_19.rs +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use crate::config::old_config_v1_1_20::{ - ConfigV1_1_20, DebugV1_1_20, NetworkRequesterPathsV1_1_20, -}; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; -use nym_client_core::config::disk_persistence::old_v1_1_20::CommonClientPathsV1_1_20; -use nym_client_core::config::old_config_v1_1_19::ConfigV1_1_19 as BaseConfigV1_1_19; -use nym_client_core::config::old_config_v1_1_20::{ - ClientV1_1_20, ConfigV1_1_20 as BaseClientConfigV1_1_20, -}; -use nym_config::legacy_helpers::nym_config::MigrationNymConfig; -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; -use std::time::Duration; - -const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); - -#[derive(Debug, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct ConfigV1_1_19 { - #[serde(flatten)] - pub base: BaseConfigV1_1_19<ConfigV1_1_19>, - - #[serde(default)] - pub network_requester: NetworkRequster, - - #[serde(default)] - pub network_requester_debug: DebugV1_1_19, -} - -impl From<ConfigV1_1_19> for ConfigV1_1_20 { - fn from(value: ConfigV1_1_19) -> Self { - ConfigV1_1_20 { - base: BaseClientConfigV1_1_20 { - client: ClientV1_1_20 { - version: value.base.client.version, - id: value.base.client.id, - disabled_credentials_mode: value.base.client.disabled_credentials_mode, - nyxd_urls: value.base.client.nyxd_urls, - nym_api_urls: value.base.client.nym_api_urls, - gateway_endpoint: value.base.client.gateway_endpoint.into(), - }, - debug: Default::default(), - }, - network_requester: Default::default(), - storage_paths: NetworkRequesterPathsV1_1_20 { - common_paths: CommonClientPathsV1_1_20 { - keys: ClientKeysPaths { - private_identity_key_file: value.base.client.private_identity_key_file, - public_identity_key_file: value.base.client.public_identity_key_file, - private_encryption_key_file: value.base.client.private_encryption_key_file, - public_encryption_key_file: value.base.client.public_encryption_key_file, - gateway_shared_key_file: value.base.client.gateway_shared_key_file, - ack_key_file: value.base.client.ack_key_file, - }, - credentials_database: value.base.client.database_path, - reply_surb_database: value.base.client.reply_surb_database_path, - }, - allowed_list_location: value.network_requester.allowed_list_location, - unknown_list_location: value.network_requester.unknown_list_location, - }, - network_requester_debug: value.network_requester_debug.into(), - logging: Default::default(), - } - } -} - -impl MigrationNymConfig for ConfigV1_1_19 { - fn default_root_directory() -> PathBuf { - dirs::home_dir() - .expect("Failed to evaluate $HOME value") - .join(".nym") - .join("service-providers") - .join("network-requester") - } -} - -#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct NetworkRequster { - pub allowed_list_location: PathBuf, - pub unknown_list_location: PathBuf, -} - -impl Default for NetworkRequster { - fn default() -> Self { - // same defaults as we had in <= v1.1.13 - NetworkRequster { - allowed_list_location: <ConfigV1_1_19 as MigrationNymConfig>::default_root_directory() - .join("allowed.list"), - unknown_list_location: <ConfigV1_1_19 as MigrationNymConfig>::default_root_directory() - .join("unknown.list"), - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct DebugV1_1_19 { - #[serde(with = "humantime_serde")] - pub standard_list_update_interval: Duration, -} - -impl From<DebugV1_1_19> for DebugV1_1_20 { - fn from(value: DebugV1_1_19) -> Self { - DebugV1_1_20 { - standard_list_update_interval: value.standard_list_update_interval, - } - } -} - -impl Default for DebugV1_1_19 { - fn default() -> Self { - DebugV1_1_19 { - standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, - } - } -} diff --git a/service-providers/network-requester/src/config/persistence.rs b/service-providers/network-requester/src/config/persistence/mod.rs similarity index 99% rename from service-providers/network-requester/src/config/persistence.rs rename to service-providers/network-requester/src/config/persistence/mod.rs index 6d81c3c77e..e4f6384117 100644 --- a/service-providers/network-requester/src/config/persistence.rs +++ b/service-providers/network-requester/src/config/persistence/mod.rs @@ -5,6 +5,8 @@ use nym_client_core::config::disk_persistence::CommonClientPaths; use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; +pub mod old; + pub const DEFAULT_ALLOWED_LIST_FILENAME: &str = "allowed.list"; pub const DEFAULT_UNKNOWN_LIST_FILENAME: &str = "unknown.list"; pub const DEFAULT_DESCRIPTION_FILENAME: &str = "description.toml"; diff --git a/service-providers/network-requester/src/config/persistence/old/mod.rs b/service-providers/network-requester/src/config/persistence/old/mod.rs new file mode 100644 index 0000000000..03a73cb2a8 --- /dev/null +++ b/service-providers/network-requester/src/config/persistence/old/mod.rs @@ -0,0 +1,5 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1; +pub mod v2; diff --git a/service-providers/network-requester/src/config/persistence/old/v1.rs b/service-providers/network-requester/src/config/persistence/old/v1.rs new file mode 100644 index 0000000000..2c9a4bdc8d --- /dev/null +++ b/service-providers/network-requester/src/config/persistence/old/v1.rs @@ -0,0 +1,18 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_client_core::config::disk_persistence::old_v1_1_20_2::CommonClientPathsV1_1_20_2; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct NetworkRequesterPathsV1 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_20_2, + + /// Location of the file containing our allow.list + pub allowed_list_location: PathBuf, + + /// Location of the file containing our unknown.list + pub unknown_list_location: PathBuf, +} diff --git a/service-providers/network-requester/src/config/persistence/old/v2.rs b/service-providers/network-requester/src/config/persistence/old/v2.rs new file mode 100644 index 0000000000..927368e99c --- /dev/null +++ b/service-providers/network-requester/src/config/persistence/old/v2.rs @@ -0,0 +1,21 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct NetworkRequesterPathsV2 { + #[serde(flatten)] + pub common_paths: CommonClientPathsV1_1_33, + + /// Location of the file containing our allow.list + pub allowed_list_location: PathBuf, + + /// Location of the file containing our unknown.list + pub unknown_list_location: PathBuf, + + #[serde(default)] + pub nr_description: PathBuf, +} From bef0a537b27eee890bef7e56e782131972756b2e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 14:10:01 +0000 Subject: [PATCH 342/394] config migration for removing allow.list --- .../network-requester/src/config/helpers.rs | 67 +++++--- .../network-requester/src/config/mod.rs | 7 - .../network-requester/src/config/old/mod.rs | 16 +- .../network-requester/src/config/old/v3.rs | 9 +- .../network-requester/src/config/old/v4.rs | 24 +-- .../network-requester/src/config/old/v5.rs | 146 ++++++++++++++++++ .../src/config/persistence/mod.rs | 22 +-- .../src/config/persistence/old/mod.rs | 1 + .../src/config/persistence/old/v2.rs | 1 + .../src/config/persistence/old/v3.rs | 21 +++ 10 files changed, 236 insertions(+), 78 deletions(-) create mode 100644 service-providers/network-requester/src/config/old/v5.rs create mode 100644 service-providers/network-requester/src/config/persistence/old/v3.rs diff --git a/service-providers/network-requester/src/config/helpers.rs b/service-providers/network-requester/src/config/helpers.rs index f3d540334c..2b29776dea 100644 --- a/service-providers/network-requester/src/config/helpers.rs +++ b/service-providers/network-requester/src/config/helpers.rs @@ -2,17 +2,19 @@ // SPDX-License-Identifier: Apache-2.0 use crate::config::default_config_filepath; +use crate::config::old::v5::ConfigV5; use crate::config::old_config_v1_1_13::OldConfigV1; use crate::config::old_config_v1_1_20::ConfigV2; use crate::config::old_config_v1_1_20_2::ConfigV3; -use crate::config::old_config_v1_1_33::ConfigV14; +use crate::config::old_config_v1_1_33::ConfigV4; +use crate::config::Config; use crate::error::NetworkRequesterError; use log::{info, trace}; use nym_client_core::cli_helpers::CliClientConfig; use nym_client_core::client::base_client::storage::migration_helpers::v1_1_33; use std::path::Path; -async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( +async fn try_upgrade_v1_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.13 config"); @@ -31,20 +33,22 @@ async fn try_upgrade_v1_1_13_config<P: AsRef<Path>>( let updated_step2: ConfigV3 = updated_step1.into(); let (updated_step3, gateway_config) = updated_step2.upgrade()?; let old_paths = updated_step3.storage_paths.clone(); - let updated = updated_step3.try_upgrade()?; + let updated_step4 = updated_step3.try_upgrade()?; v1_1_33::migrate_gateway_details( &old_paths.common_paths, - &updated.storage_paths.common_paths, + &updated_step4.storage_paths.common_paths, Some(gateway_config), ) .await?; + let updated: Config = updated_step4.into(); + updated.save_to(config_path)?; Ok(true) } -async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( +async fn try_upgrade_v2_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.20 config"); @@ -63,20 +67,22 @@ async fn try_upgrade_v1_1_20_config<P: AsRef<Path>>( let updated_step1: ConfigV3 = old_config.into(); let (updated_step2, gateway_config) = updated_step1.upgrade()?; let old_paths = updated_step2.storage_paths.clone(); - let updated = updated_step2.try_upgrade()?; + let updated_step3 = updated_step2.try_upgrade()?; v1_1_33::migrate_gateway_details( &old_paths.common_paths, - &updated.storage_paths.common_paths, + &updated_step3.storage_paths.common_paths, Some(gateway_config), ) .await?; + let updated: Config = updated_step3.into(); + updated.save_to(config_path)?; Ok(true) } -async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( +async fn try_upgrade_v3_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.20_2 config"); @@ -92,26 +98,28 @@ async fn try_upgrade_v1_1_20_2_config<P: AsRef<Path>>( let (updated_step1, gateway_config) = old_config.upgrade()?; let old_paths = updated_step1.storage_paths.clone(); - let updated = updated_step1.try_upgrade()?; + let updated_step2 = updated_step1.try_upgrade()?; v1_1_33::migrate_gateway_details( &old_paths.common_paths, - &updated.storage_paths.common_paths, + &updated_step2.storage_paths.common_paths, Some(gateway_config), ) .await?; + let updated: Config = updated_step2.into(); + updated.save_to(config_path)?; Ok(true) } -async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( +async fn try_upgrade_v4_config<P: AsRef<Path>>( config_path: P, ) -> Result<bool, NetworkRequesterError> { trace!("Trying to load as v1.1.33 config"); // explicitly load it as v1.1.33 (which is incompatible with the current one, i.e. +1.1.34) - let Ok(old_config) = ConfigV14::read_from_toml_file(config_path.as_ref()) else { + let Ok(old_config) = ConfigV4::read_from_toml_file(config_path.as_ref()) else { // if we failed to load it, there might have been nothing to upgrade // or maybe it was an even older file. in either way. just ignore it and carry on with our day return Ok(false); @@ -120,33 +128,56 @@ async fn try_upgrade_v1_1_33_config<P: AsRef<Path>>( info!("It is going to get updated to the current specification."); let old_paths = old_config.storage_paths.clone(); - let updated = old_config.try_upgrade()?; + let updated_step1 = old_config.try_upgrade()?; v1_1_33::migrate_gateway_details( &old_paths.common_paths, - &updated.storage_paths.common_paths, + &updated_step1.storage_paths.common_paths, None, ) .await?; + let updated: Config = updated_step1.into(); + updated.save_to(config_path)?; Ok(true) } +async fn try_upgrade_v5_config<P: AsRef<Path>>( + config_path: P, +) -> Result<bool, NetworkRequesterError> { + // explicitly load it as v5 (which is incompatible with the current one) + let Ok(old_config) = ConfigV5::read_from_toml_file(config_path.as_ref()) else { + // if we failed to load it, there might have been nothing to upgrade + // or maybe it was an even older file. in either way. just ignore it and carry on with our day + return Ok(false); + }; + info!("It seems the client is using <= v5 config template."); + info!("It is going to get updated to the current specification."); + + let updated: Config = old_config.into(); + updated.save_to(config_path)?; + + Ok(true) +} + pub async fn try_upgrade_config<P: AsRef<Path>>( config_path: P, ) -> Result<(), NetworkRequesterError> { trace!("Attempting to upgrade config"); - if try_upgrade_v1_1_13_config(config_path.as_ref()).await? { + if try_upgrade_v1_config(config_path.as_ref()).await? { return Ok(()); } - if try_upgrade_v1_1_20_config(config_path.as_ref()).await? { + if try_upgrade_v2_config(config_path.as_ref()).await? { return Ok(()); } - if try_upgrade_v1_1_20_2_config(config_path.as_ref()).await? { + if try_upgrade_v3_config(config_path.as_ref()).await? { return Ok(()); } - if try_upgrade_v1_1_33_config(config_path).await? { + if try_upgrade_v4_config(config_path.as_ref()).await? { + return Ok(()); + } + if try_upgrade_v5_config(config_path).await? { return Ok(()); } diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index e4d701c537..27b0d70739 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -245,12 +245,6 @@ pub struct NetworkRequester { /// This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true, pub disable_poisson_rate: bool, - /// Specifies whether this network requester should be using the deprecated allow-list, - /// as opposed to the new ExitPolicy. - /// Note: this field will be removed in a near future. - #[deprecated] - pub use_deprecated_allow_list: bool, - /// Specifies the url for an upstream source of the exit policy used by this node. #[serde(deserialize_with = "de_maybe_stringified")] pub upstream_exit_policy_url: Option<Url>, @@ -263,7 +257,6 @@ impl Default for NetworkRequester { enabled_statistics: false, statistics_recipient: None, disable_poisson_rate: true, - use_deprecated_allow_list: true, upstream_exit_policy_url: Some( mainnet::EXIT_POLICY_URL .parse() diff --git a/service-providers/network-requester/src/config/old/mod.rs b/service-providers/network-requester/src/config/old/mod.rs index e19685b02c..3a529cd6c0 100644 --- a/service-providers/network-requester/src/config/old/mod.rs +++ b/service-providers/network-requester/src/config/old/mod.rs @@ -5,18 +5,4 @@ pub mod v1; pub mod v2; pub mod v3; pub mod v4; - -// // aliases for backwards compatibility -// pub use v1 as old_config_v1_1_13; -// pub use v2 as old_config_v1_1_20; -// pub use v3 as old_config_v1_1_20_2; -// pub use v4 as old_config_v1_1_30; -// pub use v5 as old_config_v1_1_33; - -/* - deleted: src/config/old_config_v1_1_13.rs - deleted: src/config/old_config_v1_1_19.rs - deleted: src/config/old_config_v1_1_20.rs - deleted: src/config/old_config_v1_1_20_2.rs - deleted: src/config/old_config_v1_1_33.rs -*/ +pub mod v5; diff --git a/service-providers/network-requester/src/config/old/v3.rs b/service-providers/network-requester/src/config/old/v3.rs index 37d7925fcf..aa86eb7819 100644 --- a/service-providers/network-requester/src/config/old/v3.rs +++ b/service-providers/network-requester/src/config/old/v3.rs @@ -1,10 +1,9 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use super::v4::{ConfigV14, DebugV4, NetworkRequesterV4}; +use super::v4::{ConfigV4, DebugV4, NetworkRequesterV4}; use crate::config::persistence::old::v1::NetworkRequesterPathsV1; -use crate::config::persistence::old::v2::NetworkRequesterPathsV2; -use crate::config::persistence::DEFAULT_DESCRIPTION_FILENAME; +use crate::config::persistence::old::v2::{NetworkRequesterPathsV2, DEFAULT_DESCRIPTION_FILENAME}; use crate::{config::default_config_filepath, error::NetworkRequesterError}; use log::trace; use nym_bin_common::logging::LoggingSettings; @@ -50,7 +49,7 @@ impl ConfigV3 { // so its returned to be stored elsewhere. pub fn upgrade( self, - ) -> Result<(ConfigV14, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> { + ) -> Result<(ConfigV4, OldGatewayEndpointConfigV1_1_33), NetworkRequesterError> { trace!("Upgrading from v1.1.20_2"); let gateway_details = self.base.client.gateway_endpoint.clone().into(); let nr_description = self @@ -61,7 +60,7 @@ impl ConfigV3 { .parent() .expect("config paths upgrade failure") .join(DEFAULT_DESCRIPTION_FILENAME); - let config = ConfigV14 { + let config = ConfigV4 { base: BaseConfigV1_1_30::from(self.base).into(), storage_paths: NetworkRequesterPathsV2 { common_paths: self.storage_paths.common_paths.upgrade_default()?, diff --git a/service-providers/network-requester/src/config/old/v4.rs b/service-providers/network-requester/src/config/old/v4.rs index 8e13c7d5a9..cf811825e6 100644 --- a/service-providers/network-requester/src/config/old/v4.rs +++ b/service-providers/network-requester/src/config/old/v4.rs @@ -1,10 +1,10 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use crate::config::default_config_filepath; +use crate::config::old::v5::{ConfigV5, DebugV5, NetworkRequesterV5}; use crate::config::persistence::old::v2::NetworkRequesterPathsV2; -use crate::config::persistence::NetworkRequesterPaths; -use crate::config::Config; -use crate::config::{default_config_filepath, Debug, NetworkRequester}; +use crate::config::persistence::old::v3::NetworkRequesterPathsV3; use crate::error::NetworkRequesterError; use nym_bin_common::logging::LoggingSettings; use nym_client_core::config::old_config_v1_1_33::ConfigV1_1_33 as BaseConfigV1_1_33; @@ -20,7 +20,7 @@ pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs( #[derive(Debug, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV14 { +pub struct ConfigV4 { #[serde(flatten)] pub base: BaseConfigV1_1_33, @@ -35,7 +35,7 @@ pub struct ConfigV14 { pub logging: LoggingSettings, } -impl ConfigV14 { +impl ConfigV4 { pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { read_config_from_toml_file(path) } @@ -45,11 +45,11 @@ impl ConfigV14 { Self::read_from_toml_file(default_config_filepath(id)) } - pub fn try_upgrade(self) -> Result<Config, NetworkRequesterError> { - Ok(Config { + pub fn try_upgrade(self) -> Result<ConfigV5, NetworkRequesterError> { + Ok(ConfigV5 { base: self.base.into(), network_requester: self.network_requester.into(), - storage_paths: NetworkRequesterPaths { + storage_paths: NetworkRequesterPathsV3 { common_paths: self.storage_paths.common_paths.upgrade_default()?, allowed_list_location: self.storage_paths.allowed_list_location, unknown_list_location: self.storage_paths.unknown_list_location, @@ -88,9 +88,9 @@ pub struct NetworkRequesterV4 { pub upstream_exit_policy_url: Option<Url>, } -impl From<NetworkRequesterV4> for NetworkRequester { +impl From<NetworkRequesterV4> for NetworkRequesterV5 { fn from(value: NetworkRequesterV4) -> Self { - NetworkRequester { + NetworkRequesterV5 { open_proxy: value.open_proxy, enabled_statistics: value.enabled_statistics, statistics_recipient: value.statistics_recipient, @@ -109,9 +109,9 @@ pub struct DebugV4 { pub standard_list_update_interval: Duration, } -impl From<DebugV4> for Debug { +impl From<DebugV4> for DebugV5 { fn from(value: DebugV4) -> Self { - Debug { + DebugV5 { standard_list_update_interval: value.standard_list_update_interval, } } diff --git a/service-providers/network-requester/src/config/old/v5.rs b/service-providers/network-requester/src/config/old/v5.rs new file mode 100644 index 0000000000..46151eabad --- /dev/null +++ b/service-providers/network-requester/src/config/old/v5.rs @@ -0,0 +1,146 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::config::persistence::old::v3::NetworkRequesterPathsV3; +use crate::config::persistence::NetworkRequesterPaths; +use crate::config::Config; +use crate::config::{default_config_filepath, Debug, NetworkRequester}; +use nym_bin_common::logging::LoggingSettings; +use nym_client_core::config::Config as BaseClientConfig; +use nym_config::read_config_from_toml_file; +use nym_config::serde_helpers::de_maybe_stringified; +use nym_network_defaults::mainnet; +use serde::{Deserialize, Serialize}; +use std::io; +use std::path::Path; +use std::time::Duration; +use url::Url; + +pub const DEFAULT_STANDARD_LIST_UPDATE_INTERVAL: Duration = Duration::from_secs(30 * 60); + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ConfigV5 { + // *sigh* currently we point to the most recent config because that's the one that's 'correct' + // but the moment we make breaking changes there, we'll have to update this config too. + // I think we should always keep versioned base config, i.e. `ConfigV1`, `ConfigV2`, etc, + // and then just make type alias for the current one, i.e. `type Config = ConfigV2`. + // then in 'old' configs we could simply use the underlying type as opposed to the alias for easier upgrades. + #[serde(flatten)] + pub base: BaseClientConfig, + + #[serde(default)] + pub network_requester: NetworkRequesterV5, + + pub storage_paths: NetworkRequesterPathsV3, + + #[serde(default)] + pub network_requester_debug: DebugV5, + + pub logging: LoggingSettings, +} + +impl ConfigV5 { + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { + read_config_from_toml_file(path) + } + + #[allow(dead_code)] + pub fn read_from_default_path<P: AsRef<Path>>(id: P) -> io::Result<Self> { + Self::read_from_toml_file(default_config_filepath(id)) + } +} + +impl From<ConfigV5> for Config { + fn from(value: ConfigV5) -> Self { + Config { + base: value.base, + network_requester: value.network_requester.into(), + storage_paths: NetworkRequesterPaths { + common_paths: value.storage_paths.common_paths, + }, + network_requester_debug: value.network_requester_debug.into(), + logging: value.logging, + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct NetworkRequesterV5 { + /// specifies whether this network requester should run in 'open-proxy' mode + /// and thus would attempt to resolve **ANY** request it receives. + pub open_proxy: bool, + + /// specifies whether this network requester would send anonymized statistics to a statistics aggregator server + pub enabled_statistics: bool, + + /// in case of enabled statistics, specifies mixnet client address where a statistics aggregator is running + pub statistics_recipient: Option<String>, + + /// Disable Poisson sending rate. + /// This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true, + pub disable_poisson_rate: bool, + + /// Specifies whether this network requester should be using the deprecated allow-list, + /// as opposed to the new ExitPolicy. + pub use_deprecated_allow_list: bool, + + /// Specifies the url for an upstream source of the exit policy used by this node. + #[serde(deserialize_with = "de_maybe_stringified")] + pub upstream_exit_policy_url: Option<Url>, +} + +impl Default for NetworkRequesterV5 { + fn default() -> Self { + NetworkRequesterV5 { + open_proxy: false, + enabled_statistics: false, + statistics_recipient: None, + disable_poisson_rate: true, + use_deprecated_allow_list: true, + upstream_exit_policy_url: Some( + mainnet::EXIT_POLICY_URL + .parse() + .expect("invalid default exit policy URL"), + ), + } + } +} + +impl From<NetworkRequesterV5> for NetworkRequester { + fn from(value: NetworkRequesterV5) -> Self { + NetworkRequester { + open_proxy: value.open_proxy, + enabled_statistics: value.enabled_statistics, + statistics_recipient: value.statistics_recipient, + disable_poisson_rate: value.disable_poisson_rate, + upstream_exit_policy_url: value.upstream_exit_policy_url, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct DebugV5 { + /// Defines how often the standard allow list should get updated + /// Deprecated + #[serde(with = "humantime_serde")] + pub standard_list_update_interval: Duration, +} + +impl From<DebugV5> for Debug { + fn from(value: DebugV5) -> Self { + Debug { + standard_list_update_interval: value.standard_list_update_interval, + } + } +} + +impl Default for DebugV5 { + fn default() -> Self { + DebugV5 { + standard_list_update_interval: DEFAULT_STANDARD_LIST_UPDATE_INTERVAL, + } + } +} diff --git a/service-providers/network-requester/src/config/persistence/mod.rs b/service-providers/network-requester/src/config/persistence/mod.rs index e4f6384117..42a23f8de7 100644 --- a/service-providers/network-requester/src/config/persistence/mod.rs +++ b/service-providers/network-requester/src/config/persistence/mod.rs @@ -3,31 +3,14 @@ use nym_client_core::config::disk_persistence::CommonClientPaths; use serde::{Deserialize, Serialize}; -use std::path::{Path, PathBuf}; +use std::path::Path; pub mod old; -pub const DEFAULT_ALLOWED_LIST_FILENAME: &str = "allowed.list"; -pub const DEFAULT_UNKNOWN_LIST_FILENAME: &str = "unknown.list"; -pub const DEFAULT_DESCRIPTION_FILENAME: &str = "description.toml"; - #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] pub struct NetworkRequesterPaths { #[serde(flatten)] pub common_paths: CommonClientPaths, - - /// Deprecated - /// Location of the file containing our allow.list - #[deprecated] - pub allowed_list_location: PathBuf, - - /// Deprecated - /// Location of the file containing our unknown.list - #[deprecated] - pub unknown_list_location: PathBuf, - - /// Location of the file containing our description - pub nr_description: PathBuf, } impl NetworkRequesterPaths { @@ -36,9 +19,6 @@ impl NetworkRequesterPaths { NetworkRequesterPaths { common_paths: CommonClientPaths::new_base(base_dir), - allowed_list_location: base_dir.join(DEFAULT_ALLOWED_LIST_FILENAME), - unknown_list_location: base_dir.join(DEFAULT_UNKNOWN_LIST_FILENAME), - nr_description: base_dir.join(DEFAULT_DESCRIPTION_FILENAME), } } } diff --git a/service-providers/network-requester/src/config/persistence/old/mod.rs b/service-providers/network-requester/src/config/persistence/old/mod.rs index 03a73cb2a8..e9f7e5fdba 100644 --- a/service-providers/network-requester/src/config/persistence/old/mod.rs +++ b/service-providers/network-requester/src/config/persistence/old/mod.rs @@ -3,3 +3,4 @@ pub mod v1; pub mod v2; +pub mod v3; diff --git a/service-providers/network-requester/src/config/persistence/old/v2.rs b/service-providers/network-requester/src/config/persistence/old/v2.rs index 927368e99c..a22158c8f9 100644 --- a/service-providers/network-requester/src/config/persistence/old/v2.rs +++ b/service-providers/network-requester/src/config/persistence/old/v2.rs @@ -4,6 +4,7 @@ use nym_client_core::config::disk_persistence::old_v1_1_33::CommonClientPathsV1_1_33; use serde::{Deserialize, Serialize}; use std::path::PathBuf; +pub const DEFAULT_DESCRIPTION_FILENAME: &str = "description.toml"; #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] pub struct NetworkRequesterPathsV2 { diff --git a/service-providers/network-requester/src/config/persistence/old/v3.rs b/service-providers/network-requester/src/config/persistence/old/v3.rs new file mode 100644 index 0000000000..a5a8f3855f --- /dev/null +++ b/service-providers/network-requester/src/config/persistence/old/v3.rs @@ -0,0 +1,21 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_client_core::config::disk_persistence::CommonClientPaths; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +#[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Clone)] +pub struct NetworkRequesterPathsV3 { + #[serde(flatten)] + pub common_paths: CommonClientPaths, + + /// Location of the file containing our allow.list + pub allowed_list_location: PathBuf, + + /// Location of the file containing our unknown.list + pub unknown_list_location: PathBuf, + + /// Location of the file containing our description + pub nr_description: PathBuf, +} From 7fce0a969223c29b8b0462b499e21a1d380c2458 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 26 Mar 2024 15:48:29 +0000 Subject: [PATCH 343/394] remove explicit deref --- service-providers/network-requester/src/request_filter/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/service-providers/network-requester/src/request_filter/mod.rs b/service-providers/network-requester/src/request_filter/mod.rs index b1534ce7b8..8000b6caed 100644 --- a/service-providers/network-requester/src/request_filter/mod.rs +++ b/service-providers/network-requester/src/request_filter/mod.rs @@ -24,7 +24,7 @@ impl RequestFilter { } pub fn current_exit_policy_filter(&self) -> &ExitPolicyRequestFilter { - &*self.inner + &self.inner } pub(crate) async fn check_address(&self, address: &RemoteAddress) -> bool { From 1ed087e801d832481cafe4cc63e1f608a3c57371 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 28 Mar 2024 12:34:30 +0000 Subject: [PATCH 344/394] fixed NR template --- service-providers/network-requester/src/config/template.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/service-providers/network-requester/src/config/template.rs b/service-providers/network-requester/src/config/template.rs index 84cb00e80c..78dda1beef 100644 --- a/service-providers/network-requester/src/config/template.rs +++ b/service-providers/network-requester/src/config/template.rs @@ -91,11 +91,6 @@ statistics_recipient = '{{ network_requester.statistics_recipient }}' # This is equivalent to setting debug.traffic.disable_main_poisson_packet_distribution = true, disable_poisson_rate = {{ network_requester.disable_poisson_rate }} -# Specifies whether this network requester should be using the deprecated allow-list, -# as opposed to the new ExitPolicy. -# Note: this field will be removed in a near future. -use_deprecated_allow_list = {{ network_requester.use_deprecated_allow_list }} - # Specifies the url for an upstream source of the exit policy used by this node. upstream_exit_policy_url = '{{ network_requester.upstream_exit_policy_url }}' From 1815a2d3a51a554d9200ec841c1b4e1611dcf71c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 28 Mar 2024 18:44:49 +0000 Subject: [PATCH 345/394] Bump express in /clients/native/examples/js-examples/websocket Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- .../js-examples/websocket/package-lock.json | 382 +++++++++++++----- 1 file changed, 291 insertions(+), 91 deletions(-) diff --git a/clients/native/examples/js-examples/websocket/package-lock.json b/clients/native/examples/js-examples/websocket/package-lock.json index 021a1a0de2..fac2f9c194 100644 --- a/clients/native/examples/js-examples/websocket/package-lock.json +++ b/clients/native/examples/js-examples/websocket/package-lock.json @@ -674,13 +674,13 @@ } }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -688,7 +688,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -793,13 +793,19 @@ } }, "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1030,18 +1036,18 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true, "engines": { "node": ">= 0.6" } }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true, "engines": { "node": ">= 0.6" @@ -1137,6 +1143,23 @@ "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==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -1358,6 +1381,27 @@ "node": ">=4" } }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", @@ -1463,17 +1507,17 @@ } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -1731,20 +1775,28 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -1824,6 +1876,18 @@ "node": ">=0.10.0" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", @@ -1855,10 +1919,22 @@ "node": ">=8" } }, - "node_modules/has-symbols": { + "node_modules/has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "dependencies": { + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true, "engines": { "node": ">= 0.4" @@ -1867,6 +1943,30 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -2650,9 +2750,9 @@ } }, "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3038,9 +3138,9 @@ } }, "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "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==", "dev": true, "dependencies": { "bytes": "3.1.2", @@ -3413,6 +3513,23 @@ "node": ">= 0.8.0" } }, + "node_modules/set-function-length": { + "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==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -3453,14 +3570,18 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "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==", "dev": true, "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -5030,13 +5151,13 @@ "dev": true }, "body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", "dev": true, "requires": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -5044,7 +5165,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -5122,13 +5243,16 @@ "dev": true }, "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" } }, "camel-case": { @@ -5294,15 +5418,15 @@ } }, "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", "dev": true }, "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", "dev": true }, "cookie-signature": { @@ -5377,6 +5501,17 @@ "execa": "^5.0.0" } }, + "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==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + } + }, "define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -5546,6 +5681,21 @@ "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", "dev": true }, + "es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dev": true, + "requires": { + "get-intrinsic": "^1.2.4" + } + }, + "es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "dev": true + }, "es-module-lexer": { "version": "0.9.3", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-0.9.3.tgz", @@ -5626,17 +5776,17 @@ } }, "express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", "dev": true, "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -5837,20 +5987,22 @@ "optional": true }, "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", "dev": true }, "get-intrinsic": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.1.tgz", - "integrity": "sha512-kWZrnVM42QCiEA2Ig1bG8zjoIMOgxWwYCEeNdwY6Tv/cOSeGpcoX4pXHfKUxNKVoArnrEr2e9srnAxxGIraS9Q==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dev": true, "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" } }, "get-stream": { @@ -5908,6 +6060,15 @@ } } }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, "graceful-fs": { "version": "4.2.9", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.9.tgz", @@ -5933,12 +6094,36 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, - "has-symbols": { + "has-property-descriptors": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.2.tgz", - "integrity": "sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw==", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "dev": true, + "requires": { + "es-define-property": "^1.0.0" + } + }, + "has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", "dev": true }, + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true + }, + "hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dev": true, + "requires": { + "function-bind": "^1.1.2" + } + }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -6515,9 +6700,9 @@ "dev": true }, "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", "dev": true }, "object-is": { @@ -6803,9 +6988,9 @@ "dev": true }, "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", + "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==", "dev": true, "requires": { "bytes": "3.1.2", @@ -7090,6 +7275,20 @@ "send": "0.18.0" } }, + "set-function-length": { + "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==", + "dev": true, + "requires": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + } + }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -7121,14 +7320,15 @@ "dev": true }, "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "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==", "dev": true, "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" } }, "signal-exit": { From d28783cb2a636807d7849b0ca34c507f0931beec Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:31:24 +0000 Subject: [PATCH 346/394] Bump express from 4.18.2 to 4.19.2 in /wasm/client/internal-dev Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/client/internal-dev/yarn.lock | 40 +++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/wasm/client/internal-dev/yarn.lock b/wasm/client/internal-dev/yarn.lock index e4a0f6c4c7..9fe42edf06 100644 --- a/wasm/client/internal-dev/yarn.lock +++ b/wasm/client/internal-dev/yarn.lock @@ -460,13 +460,13 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" @@ -474,7 +474,7 @@ body-parser@1.20.1: iconv-lite "0.4.24" on-finished "2.4.1" qs "6.11.0" - raw-body "2.5.1" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -622,7 +622,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -632,10 +632,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -827,16 +827,16 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.3: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -1597,10 +1597,10 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" http-errors "2.0.0" From 08e08923275ff79a8d018051760051e14973176a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:31:25 +0000 Subject: [PATCH 347/394] Bump express from 4.18.2 to 4.19.2 in /wasm/node-tester/internal-dev Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/node-tester/internal-dev/yarn.lock | 40 ++++++++++++------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/wasm/node-tester/internal-dev/yarn.lock b/wasm/node-tester/internal-dev/yarn.lock index 8b6306ff36..18e3c69291 100644 --- a/wasm/node-tester/internal-dev/yarn.lock +++ b/wasm/node-tester/internal-dev/yarn.lock @@ -460,13 +460,13 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" @@ -474,7 +474,7 @@ body-parser@1.20.1: iconv-lite "0.4.24" on-finished "2.4.1" qs "6.11.0" - raw-body "2.5.1" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -622,7 +622,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -632,10 +632,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -827,16 +827,16 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.3: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -1597,10 +1597,10 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" http-errors "2.0.0" From 2086946e1627be289ca1c04237214cdd78481a80 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 29 Mar 2024 08:31:27 +0000 Subject: [PATCH 348/394] Bump express from 4.18.2 to 4.19.2 in /wasm/mix-fetch/internal-dev Bumps [express](https://github.com/expressjs/express) from 4.18.2 to 4.19.2. - [Release notes](https://github.com/expressjs/express/releases) - [Changelog](https://github.com/expressjs/express/blob/master/History.md) - [Commits](https://github.com/expressjs/express/compare/4.18.2...4.19.2) --- updated-dependencies: - dependency-name: express dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/mix-fetch/internal-dev/yarn.lock | 40 +++++++++++++-------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/wasm/mix-fetch/internal-dev/yarn.lock b/wasm/mix-fetch/internal-dev/yarn.lock index f11847d0ee..a5b453c3cb 100644 --- a/wasm/mix-fetch/internal-dev/yarn.lock +++ b/wasm/mix-fetch/internal-dev/yarn.lock @@ -460,13 +460,13 @@ binary-extensions@^2.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" integrity sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA== -body-parser@1.20.1: - version "1.20.1" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.1.tgz#b1812a8912c195cd371a3ee5e66faa2338a5c668" - integrity sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw== +body-parser@1.20.2: + version "1.20.2" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" + integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== dependencies: bytes "3.1.2" - content-type "~1.0.4" + content-type "~1.0.5" debug "2.6.9" depd "2.0.0" destroy "1.2.0" @@ -474,7 +474,7 @@ body-parser@1.20.1: iconv-lite "0.4.24" on-finished "2.4.1" qs "6.11.0" - raw-body "2.5.1" + raw-body "2.5.2" type-is "~1.6.18" unpipe "1.0.0" @@ -622,7 +622,7 @@ content-disposition@0.5.4: dependencies: safe-buffer "5.2.1" -content-type@~1.0.4: +content-type@~1.0.4, content-type@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== @@ -632,10 +632,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.6.0.tgz#2798b04b071b0ecbff0dbb62a505a8efa4e19051" + integrity sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw== copy-webpack-plugin@^11.0.0: version "11.0.0" @@ -827,16 +827,16 @@ execa@^5.0.0: strip-final-newline "^2.0.0" express@^4.17.3: - version "4.18.2" - resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" - integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== + version "4.19.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.19.2.tgz#e25437827a3aa7f2a827bc8171bbbb664a356465" + integrity sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q== dependencies: accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.20.1" + body-parser "1.20.2" content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.5.0" + cookie "0.6.0" cookie-signature "1.0.6" debug "2.6.9" depd "2.0.0" @@ -1600,10 +1600,10 @@ range-parser@^1.2.1, range-parser@~1.2.1: resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.5.1: - version "2.5.1" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" - integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== +raw-body@2.5.2: + version "2.5.2" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.2.tgz#99febd83b90e08975087e8f1f9419a149366b68a" + integrity sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA== dependencies: bytes "3.1.2" http-errors "2.0.0" From fa1e9988b37d4c17c7175a9eb817652dff66ac5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Fri, 5 Apr 2024 15:51:48 +0200 Subject: [PATCH 349/394] Add credentials mode command to SDK mixnet builder (#4516) --- sdk/rust/nym-sdk/src/mixnet/client.rs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index ec438e40ef..b313391b6e 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -177,6 +177,13 @@ where self } + /// Enable paid coconut bandwidth credentials mode. + #[must_use] + pub fn credentials_mode(mut self, credentials_mode: bool) -> Self { + self.config.enabled_credentials_mode = credentials_mode; + self + } + /// Use a custom debugging configuration. #[must_use] pub fn debug_config(mut self, debug_config: DebugConfig) -> Self { From 098bd4eb3cc9e8ccc68490828226645f201882f5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:18:54 +0000 Subject: [PATCH 350/394] Bump h2 from 0.3.24 to 0.3.26 in /sdk/ffi/cpp Bumps [h2](https://github.com/hyperium/h2) from 0.3.24 to 0.3.26. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.26/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.24...v0.3.26) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/cpp/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/cpp/Cargo.lock b/sdk/ffi/cpp/Cargo.lock index 6b3f0b71d6..ca9506e337 100644 --- a/sdk/ffi/cpp/Cargo.lock +++ b/sdk/ffi/cpp/Cargo.lock @@ -1841,9 +1841,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", From 7fcc8cdd1975a5cc5ec46a534202878e04fd7d30 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:24:03 +0000 Subject: [PATCH 351/394] Bump h2 from 0.3.24 to 0.3.26 in /sdk/ffi/go Bumps [h2](https://github.com/hyperium/h2) from 0.3.24 to 0.3.26. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.26/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.24...v0.3.26) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/go/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/go/Cargo.lock b/sdk/ffi/go/Cargo.lock index f99f3151d2..186df3b324 100644 --- a/sdk/ffi/go/Cargo.lock +++ b/sdk/ffi/go/Cargo.lock @@ -1841,9 +1841,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", From 3a6058be60516ba38f3908db9ad29fa7cc12bc70 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 5 Apr 2024 16:24:23 +0000 Subject: [PATCH 352/394] Bump h2 from 0.3.24 to 0.3.26 in /sdk/ffi/shared Bumps [h2](https://github.com/hyperium/h2) from 0.3.24 to 0.3.26. - [Release notes](https://github.com/hyperium/h2/releases) - [Changelog](https://github.com/hyperium/h2/blob/v0.3.26/CHANGELOG.md) - [Commits](https://github.com/hyperium/h2/compare/v0.3.24...v0.3.26) --- updated-dependencies: - dependency-name: h2 dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/shared/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/shared/Cargo.lock b/sdk/ffi/shared/Cargo.lock index 56429c1de3..b2f9caeb0c 100644 --- a/sdk/ffi/shared/Cargo.lock +++ b/sdk/ffi/shared/Cargo.lock @@ -1841,9 +1841,9 @@ dependencies = [ [[package]] name = "h2" -version = "0.3.24" +version = "0.3.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" +checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" dependencies = [ "bytes", "fnv", From 4c5351ba60fd63b595e4da64d77dad5e3a0a5ab8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 5 Apr 2024 18:34:31 +0100 Subject: [PATCH 353/394] Feature/one binary to rule them all (#4500) --- .../workflows/ci-build-upload-binaries.yml | 2 + Cargo.lock | 463 ++++++++++--- Cargo.toml | 7 +- clients/native/src/error.rs | 3 + clients/socks5/src/error.rs | 3 + common/bin-common/Cargo.toml | 1 - common/bin-common/src/logging/mod.rs | 5 +- common/client-core/Cargo.toml | 4 +- common/client-core/config-types/Cargo.toml | 26 + .../src/disk_persistence/mod.rs} | 40 +- .../src/disk_persistence/old/mod.rs | 9 + .../src/disk_persistence/old/v1.rs | 37 + .../src/disk_persistence/old/v2.rs} | 31 +- common/client-core/config-types/src/error.rs | 10 + common/client-core/config-types/src/lib.rs | 602 +++++++++++++++++ .../client-core/config-types/src/old/mod.rs | 15 + .../src/old/v1.rs} | 75 ++- .../src/old/v2.rs} | 139 ++-- .../src/old/v3.rs} | 147 ++-- .../src/old/v4.rs} | 143 ++-- .../src/old/v5.rs} | 126 ++-- .../client-core/gateways-storage/src/types.rs | 15 + .../src/client/key_manager/persistence.rs | 2 +- .../topology_control/geo_aware_provider.rs | 161 +---- .../src/config/disk_persistence/mod.rs | 43 -- .../config/disk_persistence/old_v1_1_20_2.rs | 33 - common/client-core/src/config/mod.rs | 605 +---------------- common/commands/Cargo.toml | 2 +- common/country-group/Cargo.toml | 15 + common/country-group/src/lib.rs | 158 +++++ common/crypto/src/asymmetric/identity/mod.rs | 3 + .../src/asymmetric/identity/serde_helpers.rs | 18 + common/crypto/src/asymmetric/mod.rs | 3 + common/dkg/src/bte/proof_chunking.rs | 2 +- common/http-api-common/Cargo.toml | 20 + .../http-api-common/src/lib.rs | 23 +- common/mixnode-common/Cargo.toml | 8 +- .../mixnode-common/src/verloc/measurement.rs | 266 +------- common/mixnode-common/src/verloc/mod.rs | 37 +- common/mixnode-common/src/verloc/sender.rs | 8 +- common/nymsphinx/addressing/src/lib.rs | 3 + common/task/src/manager.rs | 2 +- common/topology/src/gateway.rs | 4 +- explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 16 +- gateway/src/commands/helpers.rs | 134 +--- gateway/src/commands/init.rs | 324 +-------- gateway/src/commands/mod.rs | 14 +- gateway/src/commands/node_details.rs | 2 +- gateway/src/commands/run.rs | 30 +- .../src/commands/setup_ip_packet_router.rs | 6 +- .../src/commands/setup_network_requester.rs | 16 +- gateway/src/commands/sign.rs | 11 +- gateway/src/commands/upgrade_helpers.rs | 12 +- gateway/src/config/mod.rs | 153 ++++- gateway/src/config/old_config_v1_1_29.rs | 3 +- gateway/src/config/old_config_v1_1_31.rs | 20 +- gateway/src/config/persistence/paths.rs | 46 +- gateway/src/error.rs | 35 +- gateway/src/helpers.rs | 231 +++++++ gateway/src/http/mod.rs | 31 +- gateway/src/lib.rs | 14 + gateway/src/main.rs | 10 +- .../connection_handler/authenticated.rs | 2 +- .../websocket/connection_handler/mod.rs | 2 +- gateway/src/node/helpers.rs | 148 +--- gateway/src/node/mod.rs | 167 +++-- gateway/src/node/storage/error.rs | 2 +- gateway/src/node/storage/mod.rs | 7 +- gateway/src/node/storage/models.rs | 8 +- gateway/src/support/config.rs | 14 - gateway/src/support/mod.rs | 4 - mixnode/Cargo.toml | 7 +- mixnode/src/commands/describe.rs | 4 +- mixnode/src/commands/init.rs | 130 +--- mixnode/src/commands/mod.rs | 38 +- mixnode/src/commands/node_details.rs | 2 +- mixnode/src/commands/run.rs | 12 +- mixnode/src/commands/sign.rs | 9 +- mixnode/src/commands/upgrade_helpers.rs | 8 +- mixnode/src/config/mod.rs | 85 ++- mixnode/src/config/old_config_v1_1_32.rs | 5 +- mixnode/src/config/persistence/paths.rs | 12 + mixnode/src/error.rs | 3 +- mixnode/src/lib.rs | 9 + mixnode/src/main.rs | 3 - mixnode/src/node/helpers.rs | 4 +- mixnode/src/node/http/legacy/description.rs | 2 +- mixnode/src/node/http/legacy/hardware.rs | 2 +- mixnode/src/node/http/legacy/state.rs | 11 +- mixnode/src/node/http/legacy/stats.rs | 15 +- mixnode/src/node/http/legacy/verloc.rs | 24 +- mixnode/src/node/http/mod.rs | 26 +- mixnode/src/node/mod.rs | 132 ++-- mixnode/src/node/node_description.rs | 29 +- mixnode/src/node/node_statistics.rs | 164 +---- nym-api/Cargo.toml | 2 +- nym-connect/desktop/Cargo.lock | 431 ++++++++---- nym-connect/desktop/src-tauri/src/error.rs | 3 + nym-node/Cargo.toml | 70 +- nym-node/build.rs | 36 + nym-node/nym-node-http-api/Cargo.toml | 50 ++ nym-node/nym-node-http-api/src/error.rs | 26 + nym-node/nym-node-http-api/src/lib.rs | 66 ++ .../src}/middleware/logging.rs | 0 .../src}/middleware/mod.rs | 0 .../http => nym-node-http-api/src}/mod.rs | 0 .../nym-node-http-api/src/router/api/mod.rs | 25 + .../api/v1/gateway/client_interfaces/mod.rs | 4 +- .../wireguard/client_registry.rs | 8 +- .../client_interfaces/wireguard/error.rs | 13 + .../client_interfaces/wireguard/mod.rs | 10 +- .../src}/router/api/v1/gateway/mod.rs | 2 +- .../src}/router/api/v1/gateway/root.rs | 2 +- .../src}/router/api/v1/health.rs | 4 +- .../router/api/v1/ip_packet_router/mod.rs | 0 .../router/api/v1/ip_packet_router/root.rs | 2 +- .../src/router/api/v1/metrics/mixing.rs | 33 + .../src/router/api/v1/metrics/mod.rs | 31 + .../src/router/api/v1/metrics/prometheus.rs | 45 ++ .../src/router/api/v1/metrics/verloc.rs | 32 + .../src}/router/api/v1/mixnode/mod.rs | 0 .../src}/router/api/v1/mixnode/root.rs | 2 +- .../src}/router/api/v1/mod.rs | 7 +- .../api/v1/network_requester/exit_policy.rs | 2 +- .../router/api/v1/network_requester/mod.rs | 2 +- .../router/api/v1/network_requester/root.rs | 2 +- .../router/api/v1/node/build_information.rs | 2 +- .../src/router/api/v1/node/description.rs | 31 + .../src/router/api/v1/node/hardware.rs | 41 ++ .../router/api/v1/node/host_information.rs | 2 +- .../src}/router/api/v1/node/mod.rs | 26 +- .../src}/router/api/v1/node/roles.rs | 2 +- .../src}/router/api/v1/openapi.rs | 41 +- .../src}/router/landing_page.rs | 0 .../src}/router/mod.rs | 87 ++- .../src}/router/types.rs | 0 .../nym-node-http-api/src/state/metrics.rs | 148 ++++ nym-node/nym-node-http-api/src/state/mod.rs | 46 ++ nym-node/nym-node-requests/Cargo.toml | 5 +- nym-node/nym-node-requests/src/api/mod.rs | 3 +- .../src/api/v1/metrics/mod.rs | 4 + .../src/api/v1/metrics/models.rs | 279 ++++++++ nym-node/nym-node-requests/src/api/v1/mod.rs | 1 + .../src/api/v1/node/models.rs | 97 ++- nym-node/nym-node-requests/src/lib.rs | 44 +- .../src/cli/commands/bonding_information.rs | 41 ++ nym-node/src/cli/commands/build_info.rs | 17 + nym-node/src/cli/commands/migrate.rs | 631 ++++++++++++++++++ nym-node/src/cli/commands/mod.rs | 9 + nym-node/src/cli/commands/node_details.rs | 29 + nym-node/src/cli/commands/run/args.rs | 148 ++++ nym-node/src/cli/commands/run/mod.rs | 77 +++ nym-node/src/cli/commands/sign.rs | 88 +++ nym-node/src/cli/helpers.rs | 434 ++++++++++++ nym-node/src/cli/mod.rs | 87 +++ nym-node/src/config/entry_gateway.rs | 83 +++ nym-node/src/config/exit_gateway.rs | 241 +++++++ nym-node/src/config/helpers.rs | 93 +++ nym-node/src/config/mixnode.rs | 214 ++++++ nym-node/src/config/mod.rs | 479 ++++++++++++- nym-node/src/config/persistence.rs | 368 +++++++++- nym-node/src/config/serde_helpers.rs | 29 - nym-node/src/config/template.rs | 252 +++++++ nym-node/src/config/upgrade_helpers.rs | 22 + nym-node/src/env.rs | 58 ++ nym-node/src/error.rs | 200 +++++- nym-node/src/http/state.rs | 38 -- nym-node/src/lib.rs | 7 +- nym-node/src/main.rs | 34 + nym-node/src/node/bonding_information.rs | 197 ++++++ nym-node/src/node/description.rs | 40 ++ nym-node/src/node/helpers.rs | 153 +++++ nym-node/src/node/http/mod.rs | 34 + nym-node/src/node/http/system_info.rs | 80 +++ nym-node/src/node/mod.rs | 589 ++++++++++++++++ nym-node/src/wireguard/types.rs | 4 +- nym-outfox/Cargo.toml | 2 +- nym-validator-rewarder/Cargo.toml | 2 +- nym-wallet/Cargo.lock | 9 +- sdk/rust/nym-sdk/src/mixnet/config.rs | 1 + sdk/rust/nym-sdk/src/mixnet/paths.rs | 2 +- .../ip-packet-router/src/config/mod.rs | 2 +- .../ip-packet-router/src/error.rs | 3 + .../ip-packet-router/src/ip_packet_router.rs | 8 +- .../network-requester/Cargo.toml | 2 +- .../network-requester/src/cli/mod.rs | 2 +- .../network-requester/src/config/mod.rs | 2 +- .../network-requester/src/error.rs | 3 + .../network-requester/src/lib.rs | 7 +- tools/nymvisor/Cargo.toml | 2 +- 191 files changed, 8988 insertions(+), 3123 deletions(-) create mode 100644 common/client-core/config-types/Cargo.toml rename common/client-core/{src/config/disk_persistence/keys_paths.rs => config-types/src/disk_persistence/mod.rs} (70%) create mode 100644 common/client-core/config-types/src/disk_persistence/old/mod.rs create mode 100644 common/client-core/config-types/src/disk_persistence/old/v1.rs rename common/client-core/{src/config/disk_persistence/old_v1_1_33.rs => config-types/src/disk_persistence/old/v2.rs} (78%) create mode 100644 common/client-core/config-types/src/error.rs create mode 100644 common/client-core/config-types/src/lib.rs create mode 100644 common/client-core/config-types/src/old/mod.rs rename common/client-core/{src/config/old_config_v1_1_13.rs => config-types/src/old/v1.rs} (80%) rename common/client-core/{src/config/old_config_v1_1_20.rs => config-types/src/old/v2.rs} (78%) rename common/client-core/{src/config/old_config_v1_1_20_2.rs => config-types/src/old/v3.rs} (77%) rename common/client-core/{src/config/old_config_v1_1_30.rs => config-types/src/old/v4.rs} (85%) rename common/client-core/{src/config/old_config_v1_1_33.rs => config-types/src/old/v5.rs} (87%) delete mode 100644 common/client-core/src/config/disk_persistence/mod.rs delete mode 100644 common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs create mode 100644 common/country-group/Cargo.toml create mode 100644 common/country-group/src/lib.rs create mode 100644 common/crypto/src/asymmetric/identity/serde_helpers.rs create mode 100644 common/http-api-common/Cargo.toml rename nym-node/src/http/router/api/mod.rs => common/http-api-common/src/lib.rs (80%) create mode 100644 gateway/src/helpers.rs create mode 100644 gateway/src/lib.rs delete mode 100644 gateway/src/support/config.rs delete mode 100644 gateway/src/support/mod.rs create mode 100644 mixnode/src/lib.rs create mode 100644 nym-node/build.rs create mode 100644 nym-node/nym-node-http-api/Cargo.toml create mode 100644 nym-node/nym-node-http-api/src/error.rs create mode 100644 nym-node/nym-node-http-api/src/lib.rs rename nym-node/{src/http => nym-node-http-api/src}/middleware/logging.rs (100%) rename nym-node/{src/http => nym-node-http-api/src}/middleware/mod.rs (100%) rename nym-node/{src/http => nym-node-http-api/src}/mod.rs (100%) create mode 100644 nym-node/nym-node-http-api/src/router/api/mod.rs rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/gateway/client_interfaces/mod.rs (96%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs (97%) create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/error.rs rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/gateway/client_interfaces/wireguard/mod.rs (96%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/gateway/mod.rs (91%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/gateway/root.rs (93%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/health.rs (91%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/ip_packet_router/mod.rs (100%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/ip_packet_router/root.rs (94%) create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/metrics/mixing.rs create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/metrics/mod.rs create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/metrics/prometheus.rs create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/metrics/verloc.rs rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/mixnode/mod.rs (100%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/mixnode/root.rs (93%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/mod.rs (85%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/network_requester/exit_policy.rs (93%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/network_requester/mod.rs (93%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/network_requester/root.rs (94%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/node/build_information.rs (93%) create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/node/description.rs create mode 100644 nym-node/nym-node-http-api/src/router/api/v1/node/hardware.rs rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/node/host_information.rs (93%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/node/mod.rs (59%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/node/roles.rs (92%) rename nym-node/{src/http => nym-node-http-api/src}/router/api/v1/openapi.rs (69%) rename nym-node/{src/http => nym-node-http-api/src}/router/landing_page.rs (100%) rename nym-node/{src/http => nym-node-http-api/src}/router/mod.rs (62%) rename nym-node/{src/http => nym-node-http-api/src}/router/types.rs (100%) create mode 100644 nym-node/nym-node-http-api/src/state/metrics.rs create mode 100644 nym-node/nym-node-http-api/src/state/mod.rs create mode 100644 nym-node/nym-node-requests/src/api/v1/metrics/mod.rs create mode 100644 nym-node/nym-node-requests/src/api/v1/metrics/models.rs create mode 100644 nym-node/src/cli/commands/bonding_information.rs create mode 100644 nym-node/src/cli/commands/build_info.rs create mode 100644 nym-node/src/cli/commands/migrate.rs create mode 100644 nym-node/src/cli/commands/mod.rs create mode 100644 nym-node/src/cli/commands/node_details.rs create mode 100644 nym-node/src/cli/commands/run/args.rs create mode 100644 nym-node/src/cli/commands/run/mod.rs create mode 100644 nym-node/src/cli/commands/sign.rs create mode 100644 nym-node/src/cli/helpers.rs create mode 100644 nym-node/src/cli/mod.rs create mode 100644 nym-node/src/config/entry_gateway.rs create mode 100644 nym-node/src/config/exit_gateway.rs create mode 100644 nym-node/src/config/helpers.rs create mode 100644 nym-node/src/config/mixnode.rs delete mode 100644 nym-node/src/config/serde_helpers.rs create mode 100644 nym-node/src/config/template.rs create mode 100644 nym-node/src/config/upgrade_helpers.rs create mode 100644 nym-node/src/env.rs delete mode 100644 nym-node/src/http/state.rs create mode 100644 nym-node/src/main.rs create mode 100644 nym-node/src/node/bonding_information.rs create mode 100644 nym-node/src/node/description.rs create mode 100644 nym-node/src/node/helpers.rs create mode 100644 nym-node/src/node/http/mod.rs create mode 100644 nym-node/src/node/http/system_info.rs create mode 100644 nym-node/src/node/mod.rs diff --git a/.github/workflows/ci-build-upload-binaries.yml b/.github/workflows/ci-build-upload-binaries.yml index a8ba53e9dd..5a0f325b45 100644 --- a/.github/workflows/ci-build-upload-binaries.yml +++ b/.github/workflows/ci-build-upload-binaries.yml @@ -112,6 +112,7 @@ jobs: target/release/nym-network-statistics target/release/nym-cli target/release/nymvisor + target/release/nym-node retention-days: 30 # If this was a pull_request or nightly, upload to build server @@ -130,6 +131,7 @@ jobs: cp target/release/nym-network-requester $OUTPUT_DIR cp target/release/nym-network-statistics $OUTPUT_DIR cp target/release/nymvisor $OUTPUT_DIR + cp target/release/nym-node $OUTPUT_DIR cp target/release/nym-cli $OUTPUT_DIR cp target/release/explorer-api $OUTPUT_DIR if [ ${{ github.event_name == 'workflow_dispatch' && inputs.enable_deb == true }} = true ]; then diff --git a/Cargo.lock b/Cargo.lock index a06f771ca2..3e44825198 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -437,7 +437,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -448,7 +448,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -547,6 +547,7 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", + "headers", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -772,7 +773,7 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "57a0e8073e8baa88212fb5823574c02ebccb395136ba9a164ab89379ec6072f0" dependencies = [ - "block-padding", + "block-padding 0.2.1", "cipher 0.2.5", ] @@ -782,6 +783,15 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "bls12_381" version = "0.8.0" @@ -861,6 +871,38 @@ dependencies = [ "serde", ] +[[package]] +name = "camino" +version = "1.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" +dependencies = [ + "camino", + "cargo-platform", + "semver 1.0.22", + "serde", + "serde_json", + "thiserror", +] + [[package]] name = "cast" version = "0.3.0" @@ -893,6 +935,15 @@ dependencies = [ "subtle 2.4.1", ] +[[package]] +name = "celes" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39b9a21273925d7cc9e8a9a5f068122341336813c607014f5ef64f82b6acba58" +dependencies = [ + "serde", +] + [[package]] name = "cesu8" version = "1.1.0" @@ -1071,9 +1122,9 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.4.3" +version = "4.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" +checksum = "885e4d7d5af40bfb99ae6f9433e292feac98d452dcb3ec3d25dfe7552b77da8c" dependencies = [ "clap 4.4.7", ] @@ -1097,7 +1148,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -1765,7 +1816,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -1817,7 +1868,7 @@ dependencies = [ "cosmwasm-std", "cw2", "schemars", - "semver 1.0.20", + "semver 1.0.22", "serde", "thiserror", ] @@ -1832,7 +1883,7 @@ dependencies = [ "cosmwasm-std", "cw-storage-plus", "schemars", - "semver 1.0.20", + "semver 1.0.22", "serde", "thiserror", ] @@ -1900,12 +1951,12 @@ dependencies = [ [[package]] name = "darling" -version = "0.20.5" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc5d6b04b3fd0ba9926f945895de7d806260a2d7431ba82e7edaecb043c4c6b8" +checksum = "0209d94da627ab5605dcccf08bb18afa5009cfbef48d8a8b7d7bdbc79be25c5e" dependencies = [ - "darling_core 0.20.5", - "darling_macro 0.20.5", + "darling_core 0.20.3", + "darling_macro 0.20.3", ] [[package]] @@ -1938,16 +1989,16 @@ dependencies = [ [[package]] name = "darling_core" -version = "0.20.5" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04e48a959bcd5c761246f5d090ebc2fbf7b9cd527a492b07a67510c108f1e7e3" +checksum = "177e3443818124b357d8e76f53be906d60937f0d3a90773a664fa63fa253e621" dependencies = [ "fnv", "ident_case", "proc-macro2", "quote", "strsim", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -1974,13 +2025,13 @@ dependencies = [ [[package]] name = "darling_macro" -version = "0.20.5" +version = "0.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d1545d67a2149e1d93b7e5c7752dce5a7426eb5d1357ddcfd89336b94444f77" +checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ - "darling_core 0.20.5", + "darling_core 0.20.3", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -2172,7 +2223,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -2254,7 +2305,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -2635,7 +2686,7 @@ dependencies = [ "atomic 0.6.0", "pear", "serde", - "toml 0.8.2", + "toml 0.8.12", "uncased", "version_check", ] @@ -2822,7 +2873,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -2978,7 +3029,7 @@ checksum = "ba330b70a5341d3bc730b8e205aaee97ddab5d9c448c4f51a7c2d924266fa8f9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -3150,6 +3201,30 @@ dependencies = [ "num-traits", ] +[[package]] +name = "headers" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06683b93020a07e3dbcf5f8c0f6d40080d725bea7936fc01ad345c01b97dc270" +dependencies = [ + "base64 0.21.4", + "bytes", + "headers-core", + "http 0.2.9", + "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.9", +] + [[package]] name = "heck" version = "0.3.3" @@ -3476,7 +3551,7 @@ dependencies = [ "iana-time-zone-haiku", "js-sys", "wasm-bindgen", - "windows-core", + "windows-core 0.51.1", ] [[package]] @@ -3628,6 +3703,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding 0.3.3", "generic-array 0.14.7", ] @@ -3960,9 +4036,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.149" +version = "0.2.153" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a08173bc88b7955d1b3145aa561539096c421ac8debde8cbc3612ec635fee29b" +checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" [[package]] name = "libm" @@ -5073,7 +5149,6 @@ dependencies = [ name = "nym-bin-common" version = "0.6.0" dependencies = [ - "atty", "clap 4.4.7", "clap_complete", "clap_complete_fig", @@ -5243,9 +5318,11 @@ dependencies = [ "hyper-util", "log", "nym-bandwidth-controller", + "nym-client-core-config-types", "nym-client-core-gateways-storage", "nym-client-core-surb-storage", "nym-config", + "nym-country-group", "nym-credential-storage", "nym-crypto", "nym-explorer-client", @@ -5281,6 +5358,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-client-core-config-types" +version = "0.1.0" +dependencies = [ + "humantime-serde", + "nym-config", + "nym-country-group", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-params", + "serde", + "thiserror", + "url", +] + [[package]] name = "nym-client-core-gateways-storage" version = "0.1.0" @@ -5420,6 +5512,14 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-country-group" +version = "0.1.0" +dependencies = [ + "serde", + "tracing", +] + [[package]] name = "nym-credential-storage" version = "0.1.0" @@ -5587,7 +5687,6 @@ version = "1.1.33" dependencies = [ "anyhow", "async-trait", - "atty", "bip39", "bs58 0.5.0", "clap 4.4.7", @@ -5598,7 +5697,6 @@ dependencies = [ "dotenvy", "futures", "humantime-serde", - "hyper 0.14.27", "ipnetwork 0.16.0", "log", "nym-api-requests", @@ -5613,7 +5711,7 @@ dependencies = [ "nym-mixnode-common", "nym-network-defaults", "nym-network-requester", - "nym-node", + "nym-node-http-api", "nym-pemstore", "nym-sphinx", "nym-statistics-common", @@ -5621,10 +5719,9 @@ dependencies = [ "nym-types", "nym-validator-client", "nym-wireguard", + "nym-wireguard-types", "once_cell", - "pretty_env_logger", "rand 0.7.3", - "rand 0.8.5", "serde", "serde_json", "sqlx", @@ -5635,7 +5732,6 @@ dependencies = [ "tokio-stream", "tokio-tungstenite", "tokio-util", - "tower", "url", "zeroize", ] @@ -5720,6 +5816,19 @@ dependencies = [ "wasmtimer", ] +[[package]] +name = "nym-http-api-common" +version = "0.1.0" +dependencies = [ + "axum", + "bytes", + "mime", + "serde", + "serde_json", + "serde_yaml", + "utoipa", +] + [[package]] name = "nym-id" version = "0.1.0" @@ -5884,10 +5993,11 @@ dependencies = [ "nym-config", "nym-contracts-common", "nym-crypto", + "nym-http-api-common", "nym-metrics", "nym-mixnet-client", "nym-mixnode-common", - "nym-node", + "nym-node-http-api", "nym-nonexhaustive-delayqueue", "nym-pemstore", "nym-sphinx", @@ -5900,8 +6010,9 @@ dependencies = [ "rand 0.7.3", "serde", "serde_json", - "sysinfo", + "sysinfo 0.27.8", "thiserror", + "time", "tokio", "tokio-util", "toml 0.5.11", @@ -5920,6 +6031,7 @@ dependencies = [ "nym-crypto", "nym-metrics", "nym-network-defaults", + "nym-node-http-api", "nym-sphinx-acknowledgements", "nym-sphinx-addressing", "nym-sphinx-forwarding", @@ -5931,6 +6043,7 @@ dependencies = [ "rand 0.8.5", "serde", "thiserror", + "time", "tokio", "tokio-util", "url", @@ -6054,26 +6167,64 @@ name = "nym-node" version = "0.1.0" dependencies = [ "anyhow", + "bip39", + "bs58 0.5.0", + "cargo_metadata", + "celes", + "clap 4.4.7", + "cupid", + "humantime-serde", + "ipnetwork 0.16.0", + "nym-bin-common", + "nym-client-core-config-types", + "nym-config", + "nym-crypto", + "nym-gateway", + "nym-ip-packet-router", + "nym-mixnode", + "nym-network-requester", + "nym-node-http-api", + "nym-pemstore", + "nym-sphinx-acknowledgements", + "nym-sphinx-addressing", + "nym-task", + "nym-types", + "nym-wireguard-types", + "rand 0.7.3", + "semver 1.0.22", + "serde", + "serde_json", + "sysinfo 0.30.7", + "thiserror", + "tokio", + "toml 0.8.12", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "nym-node-http-api" +version = "0.1.0" +dependencies = [ "axum", - "bytes", "colored", "dashmap", "fastrand 2.0.1", "hmac 0.12.1", "hyper 0.14.27", "ipnetwork 0.16.0", - "mime", - "nym-config", "nym-crypto", + "nym-http-api-common", + "nym-metrics", "nym-node-requests", "nym-task", "nym-wireguard", "nym-wireguard-types", "rand 0.7.3", - "serde", "serde_json", - "serde_yaml", "thiserror", + "time", "tokio", "tower", "tower-http", @@ -6089,6 +6240,8 @@ version = "0.1.0" dependencies = [ "async-trait", "base64 0.21.4", + "humantime 2.1.0", + "humantime-serde", "nym-bin-common", "nym-crypto", "nym-exit-policy", @@ -6098,6 +6251,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "time", "tokio", "utoipa", ] @@ -7184,7 +7338,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -7280,7 +7434,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -7321,7 +7475,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -7532,9 +7686,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.69" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "134c189feb4956b20f6f547d2cf727d4c0fe06722b20a0eec87ed445a97f92da" +checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" dependencies = [ "unicode-ident", ] @@ -7547,7 +7701,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", "version_check", "yansi", ] @@ -7587,7 +7741,7 @@ checksum = "440f724eba9f6996b75d63681b0a92b06947f1457076d503a4d2e2c8f56442b8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -7667,7 +7821,7 @@ dependencies = [ "itertools 0.11.0", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -7696,9 +7850,9 @@ checksum = "106dd99e98437432fed6519dedecfade6a06a73bb7b2a1e019fdd2bee5778d94" [[package]] name = "psl" -version = "2.1.22" +version = "2.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc74a6e6a56708be1cf5c4c4d1a0dc21d33b2dcaa24e731b7fa9c287ce4f916f" +checksum = "383703acfc34f7a00724846c14dc5ea4407c59e5aedcbbb18a1c0c1a23fe5013" dependencies = [ "psl-types", ] @@ -7762,9 +7916,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.33" +version = "1.0.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" +checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" dependencies = [ "proc-macro2", ] @@ -8089,18 +8243,18 @@ checksum = "7f7473c2cfcf90008193dd0e3e16599455cb601a9fce322b5bb55de799664925" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] name = "regex" -version = "1.10.3" +version = "1.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" +checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.6", + "regex-automata 0.4.3", "regex-syntax 0.8.2", ] @@ -8115,9 +8269,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.6" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86b83b8b9847f9bf95ef68afb0b8e6cdb80f498442f5179a29fad448fcc1eaea" +checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" dependencies = [ "aho-corasick", "memchr", @@ -8298,7 +8452,7 @@ dependencies = [ "proc-macro2", "quote", "rocket_http", - "syn 2.0.38", + "syn 2.0.58", "unicode-xid", "version_check", ] @@ -8436,7 +8590,7 @@ dependencies = [ "quote", "rust-embed-utils", "shellexpand", - "syn 2.0.38", + "syn 2.0.58", "walkdir", ] @@ -8477,7 +8631,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.20", + "semver 1.0.22", ] [[package]] @@ -8795,9 +8949,12 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.20" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090" +checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +dependencies = [ + "serde", +] [[package]] name = "semver-parser" @@ -8816,9 +8973,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.189" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e422a44e74ad4001bdc8eede9a4570ab52f71190e9c076d14369f38b9200537" +checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" dependencies = [ "serde_derive", ] @@ -8854,13 +9011,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.189" +version = "1.0.197" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e48d1f918009ce3145511378cf68d613e3b3d9137d67272562080d68a2b32d5" +checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -8882,7 +9039,7 @@ checksum = "e578a843d40b4189a4d66bba51d7684f57da5bd7c304c64e14bd63efbef49509" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -8914,14 +9071,14 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] name = "serde_spanned" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186" +checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" dependencies = [ "serde", ] @@ -8940,9 +9097,9 @@ dependencies = [ [[package]] name = "serde_with" -version = "3.6.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b0ed1662c5a68664f45b76d18deb0e234aff37207086803165c961eb695e981" +checksum = "64cd236ccc1b7a29e7e2739f27c0b2dd199804abc4290e32f59f3b68d6405c23" dependencies = [ "base64 0.21.4", "chrono", @@ -8957,14 +9114,14 @@ dependencies = [ [[package]] name = "serde_with_macros" -version = "3.6.0" +version = "3.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "568577ff0ef47b879f736cd66740e022f3672788cdf002a05a4e609ea5a6fb15" +checksum = "93634eb5f75a2323b16de4748022ac4297f9e76b6dced2be287a099f41b5e788" dependencies = [ - "darling 0.20.5", + "darling 0.20.3", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -9482,7 +9639,7 @@ dependencies = [ "proc-macro2", "quote", "rustversion", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -9553,9 +9710,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.38" +version = "2.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b" +checksum = "44cfb93f38070beee36b3fef7d4f5a16f27751d94b187b666a5cc5e9b0d30687" dependencies = [ "proc-macro2", "quote", @@ -9595,6 +9752,21 @@ dependencies = [ "winapi", ] +[[package]] +name = "sysinfo" +version = "0.30.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c385888ef380a852a16209afc8cfad22795dd8873d69c9a14d2e2088f118d18" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "windows 0.52.0", +] + [[package]] name = "system-configuration" version = "0.5.1" @@ -9724,7 +9896,7 @@ dependencies = [ "peg", "pin-project", "reqwest", - "semver 1.0.20", + "semver 1.0.22", "serde", "serde_bytes", "serde_json", @@ -9774,7 +9946,7 @@ checksum = "10712f02019e9288794769fba95cd6847df9874d49d871d062172f9dd41bc4cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -9904,7 +10076,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -10033,21 +10205,21 @@ dependencies = [ [[package]] name = "toml" -version = "0.8.2" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "185d8ab0dfbb35cf1399a6344d8484209c088f75f8f68230da55d48d95d43e3d" +checksum = "e9dd1545e8208b4a5af1aa9bbd0b4cf7e9ea08fabc5d0a5c67fcaafa17433aa3" dependencies = [ "serde", "serde_spanned", "toml_datetime", - "toml_edit 0.20.2", + "toml_edit 0.22.9", ] [[package]] name = "toml_datetime" -version = "0.6.3" +version = "0.6.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b" +checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" dependencies = [ "serde", ] @@ -10062,20 +10234,20 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.5.17", ] [[package]] name = "toml_edit" -version = "0.20.2" +version = "0.22.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "396e4d48bbb2b7554c944bde63101b5ae446cff6ec4a24227428f15eb72ef338" +checksum = "8e40bb779c5187258fd7aad0eb68cb8706a0a81fa712fbea808ab43c4b8374c4" dependencies = [ "indexmap 2.0.2", "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.5", ] [[package]] @@ -10183,7 +10355,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -10376,7 +10548,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", "termcolor", ] @@ -10403,7 +10575,7 @@ dependencies = [ "proc-macro2", "quote", "serde_derive_internals 0.28.0", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -10655,7 +10827,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] @@ -10793,7 +10965,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", "wasm-bindgen-shared", ] @@ -10827,7 +10999,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -11278,10 +11450,20 @@ version = "0.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca229916c5ee38c2f2bc1e9d8f04df975b4bd93f9955dc69fabb5d91270045c9" dependencies = [ - "windows-core", + "windows-core 0.51.1", "windows-targets 0.48.5", ] +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.4", +] + [[package]] name = "windows-core" version = "0.51.1" @@ -11291,6 +11473,15 @@ dependencies = [ "windows-targets 0.48.5", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.4", +] + [[package]] name = "windows-sys" version = "0.45.0" @@ -11339,6 +11530,21 @@ dependencies = [ "windows_x86_64_msvc 0.48.5", ] +[[package]] +name = "windows-targets" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +dependencies = [ + "windows_aarch64_gnullvm 0.52.4", + "windows_aarch64_msvc 0.52.4", + "windows_i686_gnu 0.52.4", + "windows_i686_msvc 0.52.4", + "windows_x86_64_gnu 0.52.4", + "windows_x86_64_gnullvm 0.52.4", + "windows_x86_64_msvc 0.52.4", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.42.2" @@ -11351,6 +11557,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" + [[package]] name = "windows_aarch64_msvc" version = "0.42.2" @@ -11363,6 +11575,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" + [[package]] name = "windows_i686_gnu" version = "0.42.2" @@ -11375,6 +11593,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" +[[package]] +name = "windows_i686_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" + [[package]] name = "windows_i686_msvc" version = "0.42.2" @@ -11387,6 +11611,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" +[[package]] +name = "windows_i686_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" + [[package]] name = "windows_x86_64_gnu" version = "0.42.2" @@ -11399,6 +11629,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" + [[package]] name = "windows_x86_64_gnullvm" version = "0.42.2" @@ -11411,6 +11647,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" + [[package]] name = "windows_x86_64_msvc" version = "0.42.2" @@ -11423,6 +11665,12 @@ version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" + [[package]] name = "winnow" version = "0.5.17" @@ -11432,6 +11680,15 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.6.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dffa400e67ed5a4dd237983829e66475f0a4a26938c4b04c21baede6262215b8" +dependencies = [ + "memchr", +] + [[package]] name = "winreg" version = "0.50.0" @@ -11590,7 +11847,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.38", + "syn 2.0.58", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index c0fbd003e2..1682869b0e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,6 +24,7 @@ members = [ "common/bandwidth-controller", "common/bin-common", "common/client-core", + "common/client-core/config-types", "common/client-core/surb-storage", "common/client-core/gateways-storage", "common/client-libs/gateway-client", @@ -41,6 +42,7 @@ members = [ "common/cosmwasm-smart-contracts/name-service", "common/cosmwasm-smart-contracts/service-provider-directory", "common/cosmwasm-smart-contracts/vesting-contract", + "common/country-group", "common/credential-storage", "common/credentials", "common/credential-utils", @@ -50,6 +52,7 @@ members = [ "common/execute", "common/exit-policy", "common/http-api-client", + "common/http-api-common", "common/inclusion-probability", "common/ip-packet-requests", "common/ledger", @@ -104,6 +107,7 @@ members = [ "nym-browser-extension/storage", "nym-api/nym-api-requests", "nym-node", + "nym-node/nym-node-http-api", "nym-node/nym-node-requests", "nym-outfox", "nym-validator-rewarder", @@ -118,7 +122,6 @@ members = [ # "wasm/full-nym-wasm", "wasm/mix-fetch", "wasm/node-tester", - "common/nym-metrics", ] default-members = [ @@ -132,6 +135,7 @@ default-members = [ "tools/nymvisor", "explorer-api", "nym-validator-rewarder", + "nym-node" ] exclude = [ @@ -167,6 +171,7 @@ dotenvy = "0.15.6" futures = "0.3.28" generic-array = "0.14.7" getrandom = "0.2.10" +humantime-serde = "1.1.1" hyper = "0.14.27" k256 = "0.13" lazy_static = "1.4.0" diff --git a/clients/native/src/error.rs b/clients/native/src/error.rs index 33daa1247d..23e30121f5 100644 --- a/clients/native/src/error.rs +++ b/clients/native/src/error.rs @@ -23,6 +23,9 @@ pub enum ClientError { #[error("Attempted to start the client in invalid socket mode")] InvalidSocketMode, + #[error(transparent)] + ConfigUpgradeFailure(#[from] nym_client_core::config::ConfigUpgradeFailure), + #[error(transparent)] NymIdError(#[from] NymIdError), } diff --git a/clients/socks5/src/error.rs b/clients/socks5/src/error.rs index de40ccfefa..a2f4d8379a 100644 --- a/clients/socks5/src/error.rs +++ b/clients/socks5/src/error.rs @@ -23,6 +23,9 @@ pub enum Socks5ClientError { #[error(transparent)] ClientCoreError(#[from] ClientCoreError), + #[error(transparent)] + ConfigUpgradeFailure(#[from] nym_client_core::config::ConfigUpgradeFailure), + #[error(transparent)] NymIdError(#[from] NymIdError), } diff --git a/common/bin-common/Cargo.toml b/common/bin-common/Cargo.toml index 738e708737..36ee1785d9 100644 --- a/common/bin-common/Cargo.toml +++ b/common/bin-common/Cargo.toml @@ -8,7 +8,6 @@ license = { workspace = true } repository = { workspace = true } [dependencies] -atty = "0.2" const-str = "0.5.6" clap = { workspace = true, features = ["derive"] } clap_complete = "4.0" diff --git a/common/bin-common/src/logging/mod.rs b/common/bin-common/src/logging/mod.rs index a2f6f36d9e..250fef793f 100644 --- a/common/bin-common/src/logging/mod.rs +++ b/common/bin-common/src/logging/mod.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 use serde::{Deserialize, Serialize}; +use std::io::IsTerminal; #[cfg(feature = "tracing")] pub use opentelemetry; @@ -14,7 +15,7 @@ pub use tracing_subscriber; #[cfg(feature = "tracing")] pub use tracing_tree; -#[derive(Debug, Default, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[derive(Debug, Default, Copy, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] pub struct LoggingSettings { // well, we need to implement something here at some point... @@ -120,7 +121,7 @@ pub fn banner(crate_name: &str, crate_version: &str) -> String { } pub fn maybe_print_banner(crate_name: &str, crate_version: &str) { - if atty::is(atty::Stream::Stdout) { + if std::io::stdout().is_terminal() { println!("{}", banner(crate_name, crate_version)) } } diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index b5c8aa5e2e..464cd9d25a 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -15,7 +15,7 @@ bs58 = { workspace = true } cfg-if = "1.0.0" clap = { workspace = true, optional = true } futures = { workspace = true } -humantime-serde = "1.0" +humantime-serde = { workspace = true } log = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } serde = { workspace = true, features = ["derive"] } @@ -34,6 +34,7 @@ zeroize = { workspace = true } nym-id = { path = "../nym-id" } nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } +nym-country-group = { path = "../country-group" } nym-crypto = { path = "../crypto" } nym-explorer-client = { path = "../../explorer-api/explorer-client" } nym-gateway-client = { path = "../client-libs/gateway-client" } @@ -47,6 +48,7 @@ nym-validator-client = { path = "../client-libs/validator-client", default-featu nym-task = { path = "../task" } nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } +nym-client-core-config-types = { path = "./config-types", features = ["disk-persistence"]} nym-client-core-surb-storage = { path = "./surb-storage" } nym-client-core-gateways-storage = { path = "./gateways-storage" } diff --git a/common/client-core/config-types/Cargo.toml b/common/client-core/config-types/Cargo.toml new file mode 100644 index 0000000000..c7d7f7fdf0 --- /dev/null +++ b/common/client-core/config-types/Cargo.toml @@ -0,0 +1,26 @@ +[package] +name = "nym-client-core-config-types" +version = "0.1.0" +edition = "2021" +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +humantime-serde = { workspace = true } +serde = { workspace = true, features = ["derive"] } +thiserror.workspace = true +url = { workspace = true, features = ["serde"] } + +nym-config = { path = "../../config" } + +nym-country-group = { path = "../../country-group" } +nym-pemstore = { path = "../../pemstore", optional = true } + +# those are pulling so many deps T.T +nym-sphinx-params = { path = "../../nymsphinx/params" } +nym-sphinx-addressing = { path = "../../nymsphinx/addressing" } + + +[features] +disk-persistence = ["nym-pemstore"] \ No newline at end of file diff --git a/common/client-core/src/config/disk_persistence/keys_paths.rs b/common/client-core/config-types/src/disk_persistence/mod.rs similarity index 70% rename from common/client-core/src/config/disk_persistence/keys_paths.rs rename to common/client-core/config-types/src/disk_persistence/mod.rs index cdffebe1e2..b9acff307c 100644 --- a/common/client-core/src/config/disk_persistence/keys_paths.rs +++ b/common/client-core/config-types/src/disk_persistence/mod.rs @@ -1,15 +1,53 @@ -// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; +pub mod old; + +// preserve old structure for easier migration +pub use old::{old_v1_1_20_2, old_v1_1_33}; + +pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite"; +pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db"; +pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.sqlite"; + pub const DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME: &str = "private_identity.pem"; pub const DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME: &str = "public_identity.pem"; pub const DEFAULT_PRIVATE_ENCRYPTION_KEY_FILENAME: &str = "private_encryption.pem"; pub const DEFAULT_PUBLIC_ENCRYPTION_KEY_FILENAME: &str = "public_encryption.pem"; pub const DEFAULT_ACK_KEY_FILENAME: &str = "ack_key.pem"; +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct CommonClientPaths { + pub keys: ClientKeysPaths, + + /// Path to the file containing information about gateways used by this client, + /// i.e. details such as their public keys, owner addresses or the network information. + pub gateway_registrations: PathBuf, + + /// Path to the database containing bandwidth credentials of this client. + pub credentials_database: PathBuf, + + /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + pub reply_surb_database: PathBuf, +} + +impl CommonClientPaths { + pub fn new_base<P: AsRef<Path>>(base_data_directory: P) -> Self { + let base_dir = base_data_directory.as_ref(); + + CommonClientPaths { + credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME), + reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME), + gateway_registrations: base_dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), + keys: ClientKeysPaths::new_base(base_data_directory), + } + } +} + #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] pub struct ClientKeysPaths { /// Path to file containing private identity key. diff --git a/common/client-core/config-types/src/disk_persistence/old/mod.rs b/common/client-core/config-types/src/disk_persistence/old/mod.rs new file mode 100644 index 0000000000..06f3ea2b7f --- /dev/null +++ b/common/client-core/config-types/src/disk_persistence/old/mod.rs @@ -0,0 +1,9 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1; +pub mod v2; + +// aliases for backwards compatibility +pub use v1 as old_v1_1_20_2; +pub use v2 as old_v1_1_33; diff --git a/common/client-core/config-types/src/disk_persistence/old/v1.rs b/common/client-core/config-types/src/disk_persistence/old/v1.rs new file mode 100644 index 0000000000..703ed87d7f --- /dev/null +++ b/common/client-core/config-types/src/disk_persistence/old/v1.rs @@ -0,0 +1,37 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use crate::disk_persistence::old::v2::{ + ClientKeysPathsV2, CommonClientPathsV2, DEFAULT_GATEWAY_DETAILS_FILENAME, +}; +use crate::error::ConfigUpgradeFailure; +use serde::{Deserialize, Serialize}; +use std::path::PathBuf; + +// aliases for backwards compatibility +pub type CommonClientPathsV1_1_20_2 = CommonClientPathsV1; + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct CommonClientPathsV1 { + pub keys: ClientKeysPathsV2, + pub credentials_database: PathBuf, + pub reply_surb_database: PathBuf, +} + +impl CommonClientPathsV1 { + pub fn upgrade_default(self) -> Result<CommonClientPathsV2, ConfigUpgradeFailure> { + let data_dir = self + .reply_surb_database + .parent() + .ok_or_else(|| ConfigUpgradeFailure { + current_version: "1.1.20-2".to_string(), + })?; + Ok(CommonClientPathsV2 { + keys: self.keys, + gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), + credentials_database: self.credentials_database, + reply_surb_database: self.reply_surb_database, + }) + } +} diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_33.rs b/common/client-core/config-types/src/disk_persistence/old/v2.rs similarity index 78% rename from common/client-core/src/config/disk_persistence/old_v1_1_33.rs rename to common/client-core/config-types/src/disk_persistence/old/v2.rs index f453b5e01a..779c243ed1 100644 --- a/common/client-core/src/config/disk_persistence/old_v1_1_33.rs +++ b/common/client-core/config-types/src/disk_persistence/old/v2.rs @@ -1,16 +1,20 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::disk_persistence::keys_paths::ClientKeysPaths; -use crate::config::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAYS_DETAILS_DB_FILENAME}; -use crate::error::ClientCoreError; +use crate::disk_persistence::ClientKeysPaths; +use crate::disk_persistence::{CommonClientPaths, DEFAULT_GATEWAYS_DETAILS_DB_FILENAME}; +use crate::error::ConfigUpgradeFailure; use serde::{Deserialize, Serialize}; use std::path::PathBuf; pub const DEFAULT_GATEWAY_DETAILS_FILENAME: &str = "gateway_details.json"; +// aliases for backwards compatibility +pub type CommonClientPathsV1_1_33 = CommonClientPathsV2; +pub type ClientKeysPathsV1_1_33 = ClientKeysPathsV2; + #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -pub struct ClientKeysPathsV1_1_33 { +pub struct ClientKeysPathsV2 { /// Path to file containing private identity key. pub private_identity_key_file: PathBuf, @@ -32,7 +36,7 @@ pub struct ClientKeysPathsV1_1_33 { pub ack_key_file: PathBuf, } -impl ClientKeysPathsV1_1_33 { +impl ClientKeysPathsV2 { pub fn upgrade(self) -> ClientKeysPaths { ClientKeysPaths { private_identity_key_file: self.private_identity_key_file, @@ -46,8 +50,8 @@ impl ClientKeysPathsV1_1_33 { #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] -pub struct CommonClientPathsV1_1_33 { - pub keys: ClientKeysPathsV1_1_33, +pub struct CommonClientPathsV2 { + pub keys: ClientKeysPathsV2, /// Path to the file containing information about gateway used by this client, /// i.e. details such as its public key, owner address or the network information. @@ -60,15 +64,16 @@ pub struct CommonClientPathsV1_1_33 { pub reply_surb_database: PathBuf, } -impl CommonClientPathsV1_1_33 { +impl CommonClientPathsV2 { // note that during the upgrade process, the caller will need to extract the key and gateway details // manually and resave them in the new database - pub fn upgrade_default(self) -> Result<CommonClientPaths, ClientCoreError> { - let data_dir = self.gateway_details.parent().ok_or_else(|| { - ClientCoreError::ConfigFileUpgradeFailure { + pub fn upgrade_default(self) -> Result<CommonClientPaths, ConfigUpgradeFailure> { + let data_dir = self + .gateway_details + .parent() + .ok_or_else(|| ConfigUpgradeFailure { current_version: "1.1.33".to_string(), - } - })?; + })?; Ok(CommonClientPaths { keys: self.keys.upgrade(), diff --git a/common/client-core/config-types/src/error.rs b/common/client-core/config-types/src/error.rs new file mode 100644 index 0000000000..bda078e1fa --- /dev/null +++ b/common/client-core/config-types/src/error.rs @@ -0,0 +1,10 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use thiserror::Error; + +#[derive(Debug, Error)] +#[error("unable to upgrade config file from `{current_version}`")] +pub struct ConfigUpgradeFailure { + pub current_version: String, +} diff --git a/common/client-core/config-types/src/lib.rs b/common/client-core/config-types/src/lib.rs new file mode 100644 index 0000000000..f68bb86c65 --- /dev/null +++ b/common/client-core/config-types/src/lib.rs @@ -0,0 +1,602 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_config::defaults::NymNetworkDetails; +use nym_sphinx_addressing::Recipient; +use nym_sphinx_params::{PacketSize, PacketType}; +use serde::{Deserialize, Serialize}; +use std::time::Duration; +use url::Url; + +#[cfg(feature = "disk-persistence")] +pub mod disk_persistence; +pub mod error; +pub mod old; + +pub use error::ConfigUpgradeFailure; + +// 'DEBUG' +const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5; + +const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500); +const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200); +const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20); +const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50); +const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min +const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000); +const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead + +// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause +// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the +// bandwidth bridging protocol, we can come back to a smaller timeout value +const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60); + +const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70; + +// reply-surbs related: + +// define when to request +// clients/client-core/src/client/replies/reply_storage/surb_storage.rs +const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200; + +// define how much to request at once +// clients/client-core/src/client/replies/reply_controller.rs +const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10; +const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100; + +const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500; + +const DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD: Duration = Duration::from_secs(10); +const DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD: Duration = Duration::from_secs(5 * 60); + +// 12 hours +const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60); + +// 24 hours +const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); + +pub use nym_country_group::CountryGroup; + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Config { + pub client: Client, + + #[serde(default)] + pub debug: DebugConfig, +} + +impl Config { + pub fn new<S1, S2>(id: S1, version: S2) -> Self + where + S1: Into<String>, + S2: Into<String>, + { + Config { + client: Client::new_default(id, version), + debug: Default::default(), + } + } + + pub fn from_client_config(client: Client, debug: DebugConfig) -> Self { + Config { client, debug } + } + + pub fn validate(&self) -> bool { + self.debug.validate() + } + + pub fn with_debug_config(mut self, debug: DebugConfig) -> Self { + self.debug = debug; + self + } + + pub fn with_disabled_credentials(mut self, disabled_credentials_mode: bool) -> Self { + self.client.disabled_credentials_mode = disabled_credentials_mode; + self + } + + pub fn with_custom_nyxd(mut self, urls: Vec<Url>) -> Self { + self.client.nyxd_urls = urls; + self + } + + pub fn set_custom_nyxd(&mut self, nyxd_urls: Vec<Url>) { + self.client.nyxd_urls = nyxd_urls; + } + + pub fn with_custom_nym_apis(mut self, nym_api_urls: Vec<Url>) -> Self { + self.client.nym_api_urls = nym_api_urls; + self + } + + pub fn set_custom_nym_apis(&mut self, nym_api_urls: Vec<Url>) { + self.client.nym_api_urls = nym_api_urls; + } + + pub fn with_high_default_traffic_volume(mut self, enabled: bool) -> Self { + if enabled { + self.set_high_default_traffic_volume(); + } + self + } + + pub fn with_packet_type(mut self, packet_type: PacketType) -> Self { + self.debug.traffic.packet_type = packet_type; + self + } + + pub fn set_high_default_traffic_volume(&mut self) { + self.debug.traffic.average_packet_delay = Duration::from_millis(10); + // basically don't really send cover messages + self.debug.cover_traffic.loop_cover_traffic_average_delay = + Duration::from_millis(2_000_000); + // 250 "real" messages / s + self.debug.traffic.message_sending_average_delay = Duration::from_millis(4); + } + + pub fn with_disabled_poisson_process(mut self, disabled: bool) -> Self { + if disabled { + self.set_no_poisson_process() + } + self + } + + pub fn set_no_poisson_process(&mut self) { + self.debug.traffic.disable_main_poisson_packet_distribution = true; + } + + pub fn with_disabled_cover_traffic(mut self, disabled: bool) -> Self { + if disabled { + self.set_no_cover_traffic() + } + self + } + + pub fn set_no_cover_traffic(&mut self) { + self.debug.cover_traffic.disable_loop_cover_traffic_stream = true; + self.debug.traffic.disable_main_poisson_packet_distribution = true; + } + + pub fn with_disabled_cover_traffic_with_keepalive(mut self, disabled: bool) -> Self { + if disabled { + self.set_no_cover_traffic_with_keepalive() + } + self + } + pub fn set_no_cover_traffic_with_keepalive(&mut self) { + self.debug.traffic.disable_main_poisson_packet_distribution = true; + self.debug.cover_traffic.loop_cover_traffic_average_delay = Duration::from_secs(5); + } + + pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self { + self.debug.topology.disable_refreshing = disable_topology_refresh; + self + } + + pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self { + self.set_topology_structure(topology_structure); + self + } + + pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) { + self.debug.topology.topology_structure = topology_structure; + } + + pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self { + if no_per_hop_delays { + self.set_no_per_hop_delays() + } + self + } + + pub fn set_no_per_hop_delays(&mut self) { + self.debug.traffic.average_packet_delay = Duration::ZERO; + self.debug.acknowledgements.average_ack_delay = Duration::ZERO; + } + + pub fn with_secondary_packet_size(mut self, secondary_packet_size: Option<PacketSize>) -> Self { + self.set_secondary_packet_size(secondary_packet_size); + self + } + + pub fn set_secondary_packet_size(&mut self, secondary_packet_size: Option<PacketSize>) { + self.debug.traffic.secondary_packet_size = secondary_packet_size; + } + + pub fn set_custom_version(&mut self, version: &str) { + self.client.version = version.to_string(); + } + + pub fn get_id(&self) -> String { + self.client.id.clone() + } + + pub fn get_disabled_credentials_mode(&self) -> bool { + self.client.disabled_credentials_mode + } + + pub fn get_validator_endpoints(&self) -> Vec<Url> { + self.client.nyxd_urls.clone() + } + + pub fn get_nym_api_endpoints(&self) -> Vec<Url> { + self.client.nym_api_urls.clone() + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +// note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 +#[serde(deny_unknown_fields)] +pub struct Client { + /// Version of the client for which this configuration was created. + pub version: String, + + /// ID specifies the human readable ID of this particular client. + pub id: String, + + /// Indicates whether this client is running in a disabled credentials mode, thus attempting + /// to claim bandwidth without presenting bandwidth credentials. + // TODO: this should be moved to `debug.gateway_connection` + #[serde(default)] + pub disabled_credentials_mode: bool, + + /// Addresses to nyxd validators via which the client can communicate with the chain. + #[serde(alias = "validator_urls")] + pub nyxd_urls: Vec<Url>, + + /// Addresses to APIs running on validator from which the client gets the view of the network. + #[serde(alias = "validator_api_urls")] + pub nym_api_urls: Vec<Url>, +} + +impl Client { + pub fn new_default<S1, S2>(id: S1, version: S2) -> Self + where + S1: Into<String>, + S2: Into<String>, + { + let network = NymNetworkDetails::new_mainnet(); + let nyxd_urls = network + .endpoints + .iter() + .map(|validator| validator.nyxd_url()) + .collect(); + let nym_api_urls = network + .endpoints + .iter() + .filter_map(|validator| validator.api_url()) + .collect::<Vec<_>>(); + + Client { + version: version.into(), + id: id.into(), + disabled_credentials_mode: true, + nyxd_urls, + nym_api_urls, + } + } + + pub fn new<S: Into<String>>( + id: S, + version: S, + disabled_credentials_mode: bool, + nyxd_urls: Vec<Url>, + nym_api_urls: Vec<Url>, + ) -> Self { + Client { + version: version.into(), + id: id.into(), + disabled_credentials_mode, + nyxd_urls, + nym_api_urls, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct Traffic { + /// The parameter of Poisson distribution determining how long, on average, + /// sent packet is going to be delayed at any given mix node. + /// So for a packet going through three mix nodes, on average, it will take three times this value + /// until the packet reaches its destination. + #[serde(with = "humantime_serde")] + pub average_packet_delay: Duration, + + /// The parameter of Poisson distribution determining how long, on average, + /// it is going to take another 'real traffic stream' message to be sent. + /// If no real packets are available and cover traffic is enabled, + /// a loop cover message is sent instead in order to preserve the rate. + #[serde(with = "humantime_serde")] + pub message_sending_average_delay: Duration, + + /// Controls whether the main packet stream constantly produces packets according to the predefined + /// poisson distribution. + pub disable_main_poisson_packet_distribution: bool, + + /// Specifies the packet size used for sent messages. + /// Do not override it unless you understand the consequences of that change. + pub primary_packet_size: PacketSize, + + /// Specifies the optional auxiliary packet size for optimizing message streams. + /// Note that its use decreases overall anonymity. + /// Do not set it it unless you understand the consequences of that change. + pub secondary_packet_size: Option<PacketSize>, + + pub packet_type: PacketType, +} + +impl Traffic { + pub fn validate(&self) -> bool { + if let Some(secondary_packet_size) = self.secondary_packet_size { + if secondary_packet_size == PacketSize::AckPacket + || secondary_packet_size == self.primary_packet_size + { + return false; + } + } + true + } +} + +impl Default for Traffic { + fn default() -> Self { + Traffic { + average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, + message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, + disable_main_poisson_packet_distribution: false, + primary_packet_size: PacketSize::RegularPacket, + secondary_packet_size: None, + packet_type: PacketType::Mix, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct CoverTraffic { + /// The parameter of Poisson distribution determining how long, on average, + /// it is going to take for another loop cover traffic message to be sent. + #[serde(with = "humantime_serde")] + pub loop_cover_traffic_average_delay: Duration, + + /// Specifies the ratio of `primary_packet_size` to `secondary_packet_size` used in cover traffic. + /// Only applicable if `secondary_packet_size` is enabled. + pub cover_traffic_primary_size_ratio: f64, + + /// Controls whether the dedicated loop cover traffic stream should be enabled. + /// (and sending packets, on average, every [Self::loop_cover_traffic_average_delay]) + pub disable_loop_cover_traffic_stream: bool, +} + +impl Default for CoverTraffic { + fn default() -> Self { + CoverTraffic { + loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, + cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, + disable_loop_cover_traffic_stream: false, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct GatewayConnection { + /// How long we're willing to wait for a response to a message sent to the gateway, + /// before giving up on it. + #[serde(with = "humantime_serde")] + pub gateway_response_timeout: Duration, +} + +impl Default for GatewayConnection { + fn default() -> Self { + GatewayConnection { + gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct Acknowledgements { + /// The parameter of Poisson distribution determining how long, on average, + /// sent acknowledgement is going to be delayed at any given mix node. + /// So for an ack going through three mix nodes, on average, it will take three times this value + /// until the packet reaches its destination. + #[serde(with = "humantime_serde")] + pub average_ack_delay: Duration, + + /// Value multiplied with the expected round trip time of an acknowledgement packet before + /// it is assumed it was lost and retransmission of the data packet happens. + /// In an ideal network with 0 latency, this value would have been 1. + pub ack_wait_multiplier: f64, + + /// Value added to the expected round trip time of an acknowledgement packet before + /// it is assumed it was lost and retransmission of the data packet happens. + /// In an ideal network with 0 latency, this value would have been 0. + #[serde(with = "humantime_serde")] + pub ack_wait_addition: Duration, +} + +impl Default for Acknowledgements { + fn default() -> Self { + Acknowledgements { + average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, + ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, + ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct Topology { + /// The uniform delay every which clients are querying the directory server + /// to try to obtain a compatible network topology to send sphinx packets through. + #[serde(with = "humantime_serde")] + pub topology_refresh_rate: Duration, + + /// During topology refresh, test packets are sent through every single possible network + /// path. This timeout determines waiting period until it is decided that the packet + /// did not reach its destination. + #[serde(with = "humantime_serde")] + pub topology_resolution_timeout: Duration, + + /// Specifies whether the client should not refresh the network topology after obtaining + /// the first valid instance. + /// Supersedes `topology_refresh_rate_ms`. + pub disable_refreshing: bool, + + /// Defines how long the client is going to wait on startup for its gateway to come online, + /// before abandoning the procedure. + #[serde(with = "humantime_serde")] + pub max_startup_gateway_waiting_period: Duration, + + /// Specifies the mixnode topology to be used for sending packets. + pub topology_structure: TopologyStructure, +} + +#[allow(clippy::large_enum_variant)] +#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum TopologyStructure { + #[default] + NymApi, + GeoAware(GroupBy), +} + +#[allow(clippy::large_enum_variant)] +#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] +pub enum GroupBy { + CountryGroup(CountryGroup), + NymAddress(Recipient), +} + +impl std::fmt::Display for GroupBy { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self { + GroupBy::CountryGroup(group) => write!(f, "group: {group}"), + GroupBy::NymAddress(address) => write!(f, "address: {address}"), + } + } +} + +impl Default for Topology { + fn default() -> Self { + Topology { + topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, + topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, + disable_refreshing: false, + max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, + topology_structure: TopologyStructure::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct ReplySurbs { + /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. + /// It can only allow to go below that value if its to request additional reply surbs. + pub minimum_reply_surb_storage_threshold: usize, + + /// Defines the maximum number of reply surbs the client wants to keep in its storage at any times. + pub maximum_reply_surb_storage_threshold: usize, + + /// Defines the minimum number of reply surbs the client would request. + pub minimum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs the client would request. + pub maximum_reply_surb_request_size: u32, + + /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. + pub maximum_allowed_reply_surb_request_size: u32, + + /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking + /// for more even though in theory they wouldn't need to. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_rerequest_waiting_period: Duration, + + /// Defines maximum amount of time the client is going to wait for reply surbs before + /// deciding it's never going to get them and would drop all pending messages + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_drop_waiting_period: Duration, + + /// Defines maximum amount of time given reply surb is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_surb_age: Duration, + + /// Defines maximum amount of time given reply key is going to be valid for. + /// This is going to be superseded by key rotation once implemented. + #[serde(with = "humantime_serde")] + pub maximum_reply_key_age: Duration, + + /// Specifies the number of mixnet hops the packet should go through. If not specified, then + /// the default value is used. + pub surb_mix_hops: Option<u8>, +} + +impl Default for ReplySurbs { + fn default() -> Self { + ReplySurbs { + minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, + maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, + minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, + maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, + maximum_reply_surb_rerequest_waiting_period: + DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD, + maximum_reply_surb_drop_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD, + maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE, + maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE, + surb_mix_hops: None, + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default, deny_unknown_fields)] +pub struct DebugConfig { + /// Defines all configuration options related to traffic streams. + pub traffic: Traffic, + + /// Defines all configuration options related to cover traffic stream(s). + pub cover_traffic: CoverTraffic, + + /// Defines all configuration options related to the gateway connection. + pub gateway_connection: GatewayConnection, + + /// Defines all configuration options related to acknowledgements, such as delays or wait timeouts. + pub acknowledgements: Acknowledgements, + + /// Defines all configuration options related topology, such as refresh rates or timeouts. + pub topology: Topology, + + /// Defines all configuration options related to reply SURBs. + pub reply_surbs: ReplySurbs, +} + +impl DebugConfig { + pub fn validate(&self) -> bool { + // no other sections have explicit requirements (yet) + self.traffic.validate() + } +} + +// it could be derived, sure, but I'd rather have an explicit implementation in case we had to change +// something manually at some point +#[allow(clippy::derivable_impls)] +impl Default for DebugConfig { + fn default() -> Self { + DebugConfig { + traffic: Default::default(), + cover_traffic: Default::default(), + gateway_connection: Default::default(), + acknowledgements: Default::default(), + topology: Default::default(), + reply_surbs: Default::default(), + } + } +} diff --git a/common/client-core/config-types/src/old/mod.rs b/common/client-core/config-types/src/old/mod.rs new file mode 100644 index 0000000000..80b49b41be --- /dev/null +++ b/common/client-core/config-types/src/old/mod.rs @@ -0,0 +1,15 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod v1; +pub mod v2; +pub mod v3; +pub mod v4; +pub mod v5; + +// aliases for backwards compatibility +pub use v1 as old_config_v1_1_13; +pub use v2 as old_config_v1_1_20; +pub use v3 as old_config_v1_1_20_2; +pub use v4 as old_config_v1_1_30; +pub use v5 as old_config_v1_1_33; diff --git a/common/client-core/src/config/old_config_v1_1_13.rs b/common/client-core/config-types/src/old/v1.rs similarity index 80% rename from common/client-core/src/config/old_config_v1_1_13.rs rename to common/client-core/config-types/src/old/v1.rs index df1246c88b..1c8c2380b3 100644 --- a/common/client-core/src/config/old_config_v1_1_13.rs +++ b/common/client-core/config-types/src/old/v1.rs @@ -1,23 +1,28 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::old_config_v1_1_20::{ - AcknowledgementsV1_1_20, ClientV1_1_20, ConfigV1_1_20, CoverTrafficV1_1_20, DebugConfigV1_1_20, - GatewayConnectionV1_1_20, LoggingV1_1_20, ReplySurbsV1_1_20, TopologyV1_1_20, TrafficV1_1_20, - DEFAULT_ACK_WAIT_ADDITION, DEFAULT_ACK_WAIT_MULTIPLIER, DEFAULT_AVERAGE_PACKET_DELAY, - DEFAULT_GATEWAY_RESPONSE_TIMEOUT, DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, - DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, DEFAULT_MAXIMUM_REPLY_KEY_AGE, - DEFAULT_MAXIMUM_REPLY_SURB_AGE, DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD, - DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD, +use crate::old::v2::{ + AcknowledgementsV2, ClientV2, ConfigV2, CoverTrafficV2, DebugConfigV2, GatewayConnectionV2, + LoggingV2, ReplySurbsV2, TopologyV2, TrafficV2, DEFAULT_ACK_WAIT_ADDITION, + DEFAULT_ACK_WAIT_MULTIPLIER, DEFAULT_AVERAGE_PACKET_DELAY, DEFAULT_GATEWAY_RESPONSE_TIMEOUT, + DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, + DEFAULT_MAXIMUM_REPLY_KEY_AGE, DEFAULT_MAXIMUM_REPLY_SURB_AGE, + DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD, DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, + DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD, DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, DEFAULT_TOPOLOGY_REFRESH_RATE, DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, }; -use nym_sphinx::params::PacketSize; +use nym_sphinx_params::PacketSize; use serde::{Deserialize, Serialize}; use std::marker::PhantomData; use std::time::Duration; +// aliases for backwards compatibility +pub type OldConfigV1_1_13<T> = ConfigV1<T>; +pub type OldLoggingV1_1_13 = LoggingV1; +pub type OldDebugConfigV1_1_13 = DebugConfigV1; + #[derive(Clone, Copy, Debug, Serialize, Deserialize, PartialEq, Eq)] #[serde(rename_all = "lowercase")] pub enum ExtendedPacketSize { @@ -38,28 +43,28 @@ impl From<ExtendedPacketSize> for PacketSize { #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct OldConfigV1_1_13<T> { - pub client: ClientV1_1_20<T>, +pub struct ConfigV1<T> { + pub client: ClientV2<T>, #[serde(default)] - pub logging: OldLoggingV1_1_13, + pub logging: LoggingV1, #[serde(default)] - pub debug: OldDebugConfigV1_1_13, + pub debug: DebugConfigV1, } #[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] -pub struct OldLoggingV1_1_13 {} +pub struct LoggingV1 {} -impl From<OldLoggingV1_1_13> for LoggingV1_1_20 { - fn from(_value: OldLoggingV1_1_13) -> Self { - LoggingV1_1_20 {} +impl From<LoggingV1> for LoggingV2 { + fn from(_value: LoggingV1) -> Self { + LoggingV2 {} } } #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct OldDebugConfigV1_1_13 { +pub struct DebugConfigV1 { #[serde(with = "humantime_serde")] pub average_packet_delay: Duration, @@ -114,10 +119,10 @@ pub struct OldDebugConfigV1_1_13 { pub maximum_reply_key_age: Duration, } -impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_20 { - fn from(value: OldDebugConfigV1_1_13) -> Self { - DebugConfigV1_1_20 { - traffic: TrafficV1_1_20 { +impl From<DebugConfigV1> for DebugConfigV2 { + fn from(value: DebugConfigV1) -> Self { + DebugConfigV2 { + traffic: TrafficV2 { average_packet_delay: value.average_packet_delay, message_sending_average_delay: value.message_sending_average_delay, disable_main_poisson_packet_distribution: value @@ -125,25 +130,25 @@ impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_20 { primary_packet_size: PacketSize::RegularPacket, secondary_packet_size: value.use_extended_packet_size.map(Into::into), }, - cover_traffic: CoverTrafficV1_1_20 { + cover_traffic: CoverTrafficV2 { loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay, disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream, - ..CoverTrafficV1_1_20::default() + ..CoverTrafficV2::default() }, - gateway_connection: GatewayConnectionV1_1_20 { + gateway_connection: GatewayConnectionV2 { gateway_response_timeout: value.gateway_response_timeout, }, - acknowledgements: AcknowledgementsV1_1_20 { + acknowledgements: AcknowledgementsV2 { average_ack_delay: value.average_ack_delay, ack_wait_multiplier: value.ack_wait_multiplier, ack_wait_addition: value.ack_wait_addition, }, - topology: TopologyV1_1_20 { + topology: TopologyV2 { topology_refresh_rate: value.topology_refresh_rate, topology_resolution_timeout: value.topology_resolution_timeout, disable_refreshing: false, }, - reply_surbs: ReplySurbsV1_1_20 { + reply_surbs: ReplySurbsV2 { minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold, maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold, minimum_reply_surb_request_size: value.minimum_reply_surb_request_size, @@ -161,9 +166,9 @@ impl From<OldDebugConfigV1_1_13> for DebugConfigV1_1_20 { } } -impl Default for OldDebugConfigV1_1_13 { +impl Default for DebugConfigV1 { fn default() -> Self { - OldDebugConfigV1_1_13 { + DebugConfigV1 { average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, @@ -190,10 +195,10 @@ impl Default for OldDebugConfigV1_1_13 { } } -impl<T, U> From<OldConfigV1_1_13<T>> for ConfigV1_1_20<U> { - fn from(value: OldConfigV1_1_13<T>) -> Self { - ConfigV1_1_20 { - client: ClientV1_1_20 { +impl<T, U> From<ConfigV1<T>> for ConfigV2<U> { + fn from(value: ConfigV1<T>) -> Self { + ConfigV2 { + client: ClientV2 { version: value.client.version, id: value.client.id, disabled_credentials_mode: value.client.disabled_credentials_mode, diff --git a/common/client-core/src/config/old_config_v1_1_20.rs b/common/client-core/config-types/src/old/v2.rs similarity index 78% rename from common/client-core/src/config/old_config_v1_1_20.rs rename to common/client-core/config-types/src/old/v2.rs index b3a4a189d8..ff09de3f2f 100644 --- a/common/client-core/src/config/old_config_v1_1_20.rs +++ b/common/client-core/config-types/src/old/v2.rs @@ -1,12 +1,11 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::old_config_v1_1_20_2::{ - AcknowledgementsV1_1_20_2, CoverTrafficV1_1_20_2, DebugConfigV1_1_20_2, - GatewayConnectionV1_1_20_2, GatewayEndpointConfigV1_1_20_2, ReplySurbsV1_1_20_2, - TopologyV1_1_20_2, TrafficV1_1_20_2, +use crate::old::v3::{ + AcknowledgementsV3, CoverTrafficV3, DebugConfigV3, GatewayConnectionV3, + GatewayEndpointConfigV3, ReplySurbsV3, TopologyV3, TrafficV3, }; -use nym_sphinx::params::{PacketSize, PacketType}; +use nym_sphinx_params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::marker::PhantomData; use std::path::PathBuf; @@ -54,27 +53,41 @@ pub(crate) const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs( // 24 hours pub(crate) const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +// aliases for backwards compatibility +pub type ConfigV1_1_20<T> = ConfigV2<T>; +pub type ClientV1_1_20<T> = ClientV2<T>; +pub type LoggingV1_1_20 = LoggingV2; +pub type DebugConfigV1_1_20 = DebugConfigV2; +pub type GatewayEndpointConfigV1_1_20 = GatewayEndpointConfigV2; + +pub type TrafficV1_1_20 = TrafficV2; +pub type CoverTrafficV1_1_20 = CoverTrafficV2; +pub type GatewayConnectionV1_1_20 = GatewayConnectionV2; +pub type AcknowledgementsV1_1_20 = AcknowledgementsV2; +pub type TopologyV1_1_20 = TopologyV2; +pub type ReplySurbsV1_1_20 = ReplySurbsV2; + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_20<T> { - pub client: ClientV1_1_20<T>, +pub struct ConfigV2<T> { + pub client: ClientV2<T>, #[serde(default)] - pub logging: LoggingV1_1_20, + pub logging: LoggingV2, #[serde(default)] - pub debug: DebugConfigV1_1_20, + pub debug: DebugConfigV2, } #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct GatewayEndpointConfigV1_1_20 { +pub struct GatewayEndpointConfigV2 { pub gateway_id: String, pub gateway_owner: String, pub gateway_listener: String, } -impl From<GatewayEndpointConfigV1_1_20> for GatewayEndpointConfigV1_1_20_2 { - fn from(value: GatewayEndpointConfigV1_1_20) -> Self { - GatewayEndpointConfigV1_1_20_2 { +impl From<GatewayEndpointConfigV2> for GatewayEndpointConfigV3 { + fn from(value: GatewayEndpointConfigV2) -> Self { + GatewayEndpointConfigV3 { gateway_id: value.gateway_id, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, @@ -83,7 +96,7 @@ impl From<GatewayEndpointConfigV1_1_20> for GatewayEndpointConfigV1_1_20_2 { } #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -pub struct ClientV1_1_20<T> { +pub struct ClientV2<T> { pub version: String, pub id: String, #[serde(default)] @@ -98,7 +111,7 @@ pub struct ClientV1_1_20<T> { pub public_encryption_key_file: PathBuf, pub gateway_shared_key_file: PathBuf, pub ack_key_file: PathBuf, - pub gateway_endpoint: GatewayEndpointConfigV1_1_20, + pub gateway_endpoint: GatewayEndpointConfigV2, pub database_path: PathBuf, #[serde(default)] pub reply_surb_database_path: PathBuf, @@ -110,11 +123,11 @@ pub struct ClientV1_1_20<T> { #[derive(Debug, Clone, Default, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] -pub struct LoggingV1_1_20 {} +pub struct LoggingV2 {} #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default)] -pub struct TrafficV1_1_20 { +pub struct TrafficV2 { #[serde(with = "humantime_serde")] pub average_packet_delay: Duration, #[serde(with = "humantime_serde")] @@ -124,9 +137,9 @@ pub struct TrafficV1_1_20 { pub secondary_packet_size: Option<PacketSize>, } -impl From<TrafficV1_1_20> for TrafficV1_1_20_2 { - fn from(value: TrafficV1_1_20) -> Self { - TrafficV1_1_20_2 { +impl From<TrafficV2> for TrafficV3 { + fn from(value: TrafficV2) -> Self { + TrafficV3 { average_packet_delay: value.average_packet_delay, message_sending_average_delay: value.message_sending_average_delay, disable_main_poisson_packet_distribution: value @@ -138,9 +151,9 @@ impl From<TrafficV1_1_20> for TrafficV1_1_20_2 { } } -impl Default for TrafficV1_1_20 { +impl Default for TrafficV2 { fn default() -> Self { - TrafficV1_1_20 { + TrafficV2 { average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, disable_main_poisson_packet_distribution: false, @@ -152,16 +165,16 @@ impl Default for TrafficV1_1_20 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct CoverTrafficV1_1_20 { +pub struct CoverTrafficV2 { #[serde(with = "humantime_serde")] pub loop_cover_traffic_average_delay: Duration, pub cover_traffic_primary_size_ratio: f64, pub disable_loop_cover_traffic_stream: bool, } -impl From<CoverTrafficV1_1_20> for CoverTrafficV1_1_20_2 { - fn from(value: CoverTrafficV1_1_20) -> Self { - CoverTrafficV1_1_20_2 { +impl From<CoverTrafficV2> for CoverTrafficV3 { + fn from(value: CoverTrafficV2) -> Self { + CoverTrafficV3 { loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay, cover_traffic_primary_size_ratio: value.cover_traffic_primary_size_ratio, disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream, @@ -169,9 +182,9 @@ impl From<CoverTrafficV1_1_20> for CoverTrafficV1_1_20_2 { } } -impl Default for CoverTrafficV1_1_20 { +impl Default for CoverTrafficV2 { fn default() -> Self { - CoverTrafficV1_1_20 { + CoverTrafficV2 { loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, disable_loop_cover_traffic_stream: false, @@ -181,22 +194,22 @@ impl Default for CoverTrafficV1_1_20 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct GatewayConnectionV1_1_20 { +pub struct GatewayConnectionV2 { #[serde(with = "humantime_serde")] pub gateway_response_timeout: Duration, } -impl From<GatewayConnectionV1_1_20> for GatewayConnectionV1_1_20_2 { - fn from(value: GatewayConnectionV1_1_20) -> Self { - GatewayConnectionV1_1_20_2 { +impl From<GatewayConnectionV2> for GatewayConnectionV3 { + fn from(value: GatewayConnectionV2) -> Self { + GatewayConnectionV3 { gateway_response_timeout: value.gateway_response_timeout, } } } -impl Default for GatewayConnectionV1_1_20 { +impl Default for GatewayConnectionV2 { fn default() -> Self { - GatewayConnectionV1_1_20 { + GatewayConnectionV2 { gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, } } @@ -204,7 +217,7 @@ impl Default for GatewayConnectionV1_1_20 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct AcknowledgementsV1_1_20 { +pub struct AcknowledgementsV2 { #[serde(with = "humantime_serde")] pub average_ack_delay: Duration, pub ack_wait_multiplier: f64, @@ -212,9 +225,9 @@ pub struct AcknowledgementsV1_1_20 { pub ack_wait_addition: Duration, } -impl From<AcknowledgementsV1_1_20> for AcknowledgementsV1_1_20_2 { - fn from(value: AcknowledgementsV1_1_20) -> Self { - AcknowledgementsV1_1_20_2 { +impl From<AcknowledgementsV2> for AcknowledgementsV3 { + fn from(value: AcknowledgementsV2) -> Self { + AcknowledgementsV3 { average_ack_delay: value.average_ack_delay, ack_wait_multiplier: value.ack_wait_multiplier, ack_wait_addition: value.ack_wait_addition, @@ -222,9 +235,9 @@ impl From<AcknowledgementsV1_1_20> for AcknowledgementsV1_1_20_2 { } } -impl Default for AcknowledgementsV1_1_20 { +impl Default for AcknowledgementsV2 { fn default() -> Self { - AcknowledgementsV1_1_20 { + AcknowledgementsV2 { average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, @@ -234,7 +247,7 @@ impl Default for AcknowledgementsV1_1_20 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TopologyV1_1_20 { +pub struct TopologyV2 { #[serde(with = "humantime_serde")] pub topology_refresh_rate: Duration, #[serde(with = "humantime_serde")] @@ -242,9 +255,9 @@ pub struct TopologyV1_1_20 { pub disable_refreshing: bool, } -impl From<TopologyV1_1_20> for TopologyV1_1_20_2 { - fn from(value: TopologyV1_1_20) -> Self { - TopologyV1_1_20_2 { +impl From<TopologyV2> for TopologyV3 { + fn from(value: TopologyV2) -> Self { + TopologyV3 { topology_refresh_rate: value.topology_refresh_rate, topology_resolution_timeout: value.topology_resolution_timeout, disable_refreshing: value.disable_refreshing, @@ -252,9 +265,9 @@ impl From<TopologyV1_1_20> for TopologyV1_1_20_2 { } } -impl Default for TopologyV1_1_20 { +impl Default for TopologyV2 { fn default() -> Self { - TopologyV1_1_20 { + TopologyV2 { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, @@ -264,7 +277,7 @@ impl Default for TopologyV1_1_20 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct ReplySurbsV1_1_20 { +pub struct ReplySurbsV2 { pub minimum_reply_surb_storage_threshold: usize, pub maximum_reply_surb_storage_threshold: usize, pub minimum_reply_surb_request_size: u32, @@ -280,9 +293,9 @@ pub struct ReplySurbsV1_1_20 { pub maximum_reply_key_age: Duration, } -impl From<ReplySurbsV1_1_20> for ReplySurbsV1_1_20_2 { - fn from(value: ReplySurbsV1_1_20) -> Self { - ReplySurbsV1_1_20_2 { +impl From<ReplySurbsV2> for ReplySurbsV3 { + fn from(value: ReplySurbsV2) -> Self { + ReplySurbsV3 { minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold, maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold, minimum_reply_surb_request_size: value.minimum_reply_surb_request_size, @@ -297,9 +310,9 @@ impl From<ReplySurbsV1_1_20> for ReplySurbsV1_1_20_2 { } } -impl Default for ReplySurbsV1_1_20 { +impl Default for ReplySurbsV2 { fn default() -> Self { - ReplySurbsV1_1_20 { + ReplySurbsV2 { minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, @@ -316,18 +329,18 @@ impl Default for ReplySurbsV1_1_20 { #[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugConfigV1_1_20 { - pub traffic: TrafficV1_1_20, - pub cover_traffic: CoverTrafficV1_1_20, - pub gateway_connection: GatewayConnectionV1_1_20, - pub acknowledgements: AcknowledgementsV1_1_20, - pub topology: TopologyV1_1_20, - pub reply_surbs: ReplySurbsV1_1_20, +pub struct DebugConfigV2 { + pub traffic: TrafficV2, + pub cover_traffic: CoverTrafficV2, + pub gateway_connection: GatewayConnectionV2, + pub acknowledgements: AcknowledgementsV2, + pub topology: TopologyV2, + pub reply_surbs: ReplySurbsV2, } -impl From<DebugConfigV1_1_20> for DebugConfigV1_1_20_2 { - fn from(value: DebugConfigV1_1_20) -> Self { - DebugConfigV1_1_20_2 { +impl From<DebugConfigV2> for DebugConfigV3 { + fn from(value: DebugConfigV2) -> Self { + DebugConfigV3 { traffic: value.traffic.into(), cover_traffic: value.cover_traffic.into(), gateway_connection: value.gateway_connection.into(), diff --git a/common/client-core/src/config/old_config_v1_1_20_2.rs b/common/client-core/config-types/src/old/v3.rs similarity index 77% rename from common/client-core/src/config/old_config_v1_1_20_2.rs rename to common/client-core/config-types/src/old/v3.rs index 5fe039fc82..34d40cf913 100644 --- a/common/client-core/src/config/old_config_v1_1_20_2.rs +++ b/common/client-core/config-types/src/old/v3.rs @@ -1,12 +1,12 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::config::old_config_v1_1_30::{ - AcknowledgementsV1_1_30, ClientV1_1_30, ConfigV1_1_30, CoverTrafficV1_1_30, DebugConfigV1_1_30, - GatewayConnectionV1_1_30, ReplySurbsV1_1_30, TopologyV1_1_30, TrafficV1_1_30, +use crate::old::v4::{ + AcknowledgementsV4, ClientV4, ConfigV4, CoverTrafficV4, DebugConfigV4, GatewayConnectionV4, + ReplySurbsV4, TopologyV4, TrafficV4, }; -use crate::config::old_config_v1_1_33::OldGatewayEndpointConfigV1_1_33; -use nym_sphinx::params::{PacketSize, PacketType}; +use crate::old::v5::GatewayEndpointConfigV5; +use nym_sphinx_params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; @@ -50,18 +50,31 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6 // 24 hours const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +// aliases for backwards compatibility +pub type ConfigV1_1_20_2 = ConfigV3; +pub type ClientV1_1_20_2 = ClientV3; +pub type DebugConfigV1_1_20_2 = DebugConfigV3; +pub type GatewayEndpointConfigV1_1_20_2 = GatewayEndpointConfigV3; + +pub type TrafficV1_1_20_2 = TrafficV3; +pub type CoverTrafficV1_1_20_2 = CoverTrafficV3; +pub type GatewayConnectionV1_1_20_2 = GatewayConnectionV3; +pub type AcknowledgementsV1_1_20_2 = AcknowledgementsV3; +pub type TopologyV1_1_20_2 = TopologyV3; +pub type ReplySurbsV1_1_20_2 = ReplySurbsV3; + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_20_2 { - pub client: ClientV1_1_20_2, +pub struct ConfigV3 { + pub client: ClientV3, #[serde(default)] - pub debug: DebugConfigV1_1_20_2, + pub debug: DebugConfigV3, } -impl From<ConfigV1_1_20_2> for ConfigV1_1_30 { - fn from(value: ConfigV1_1_20_2) -> Self { - ConfigV1_1_30 { +impl From<ConfigV3> for ConfigV4 { + fn from(value: ConfigV3) -> Self { + ConfigV4 { client: value.client.into(), debug: value.debug.into(), } @@ -69,7 +82,7 @@ impl From<ConfigV1_1_20_2> for ConfigV1_1_30 { } #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct GatewayEndpointConfigV1_1_20_2 { +pub struct GatewayEndpointConfigV3 { /// gateway_id specifies ID of the gateway to which the client should send messages. /// If initially omitted, a random gateway will be chosen from the available topology. pub gateway_id: String, @@ -81,9 +94,9 @@ pub struct GatewayEndpointConfigV1_1_20_2 { pub gateway_listener: String, } -impl From<GatewayEndpointConfigV1_1_20_2> for OldGatewayEndpointConfigV1_1_33 { - fn from(value: GatewayEndpointConfigV1_1_20_2) -> Self { - OldGatewayEndpointConfigV1_1_33 { +impl From<GatewayEndpointConfigV3> for GatewayEndpointConfigV5 { + fn from(value: GatewayEndpointConfigV3) -> Self { + GatewayEndpointConfigV5 { gateway_id: value.gateway_id, gateway_owner: value.gateway_owner, gateway_listener: value.gateway_listener, @@ -92,7 +105,7 @@ impl From<GatewayEndpointConfigV1_1_20_2> for OldGatewayEndpointConfigV1_1_33 { } #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -pub struct ClientV1_1_20_2 { +pub struct ClientV3 { pub version: String, pub id: String, @@ -105,12 +118,12 @@ pub struct ClientV1_1_20_2 { #[serde(alias = "validator_api_urls")] pub nym_api_urls: Vec<Url>, - pub gateway_endpoint: GatewayEndpointConfigV1_1_20_2, + pub gateway_endpoint: GatewayEndpointConfigV3, } -impl From<ClientV1_1_20_2> for ClientV1_1_30 { - fn from(value: ClientV1_1_20_2) -> Self { - ClientV1_1_30 { +impl From<ClientV3> for ClientV4 { + fn from(value: ClientV3) -> Self { + ClientV4 { version: value.version, id: value.id, disabled_credentials_mode: value.disabled_credentials_mode, @@ -122,7 +135,7 @@ impl From<ClientV1_1_20_2> for ClientV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default)] -pub struct TrafficV1_1_20_2 { +pub struct TrafficV3 { #[serde(with = "humantime_serde")] pub average_packet_delay: Duration, #[serde(with = "humantime_serde")] @@ -133,9 +146,9 @@ pub struct TrafficV1_1_20_2 { pub packet_type: PacketType, } -impl From<TrafficV1_1_20_2> for TrafficV1_1_30 { - fn from(value: TrafficV1_1_20_2) -> Self { - TrafficV1_1_30 { +impl From<TrafficV3> for TrafficV4 { + fn from(value: TrafficV3) -> Self { + TrafficV4 { average_packet_delay: value.average_packet_delay, message_sending_average_delay: value.message_sending_average_delay, disable_main_poisson_packet_distribution: value @@ -147,9 +160,9 @@ impl From<TrafficV1_1_20_2> for TrafficV1_1_30 { } } -impl Default for TrafficV1_1_20_2 { +impl Default for TrafficV3 { fn default() -> Self { - TrafficV1_1_20_2 { + TrafficV3 { average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, disable_main_poisson_packet_distribution: false, @@ -162,16 +175,16 @@ impl Default for TrafficV1_1_20_2 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct CoverTrafficV1_1_20_2 { +pub struct CoverTrafficV3 { #[serde(with = "humantime_serde")] pub loop_cover_traffic_average_delay: Duration, pub cover_traffic_primary_size_ratio: f64, pub disable_loop_cover_traffic_stream: bool, } -impl From<CoverTrafficV1_1_20_2> for CoverTrafficV1_1_30 { - fn from(value: CoverTrafficV1_1_20_2) -> Self { - CoverTrafficV1_1_30 { +impl From<CoverTrafficV3> for CoverTrafficV4 { + fn from(value: CoverTrafficV3) -> Self { + CoverTrafficV4 { loop_cover_traffic_average_delay: value.loop_cover_traffic_average_delay, cover_traffic_primary_size_ratio: value.cover_traffic_primary_size_ratio, disable_loop_cover_traffic_stream: value.disable_loop_cover_traffic_stream, @@ -179,9 +192,9 @@ impl From<CoverTrafficV1_1_20_2> for CoverTrafficV1_1_30 { } } -impl Default for CoverTrafficV1_1_20_2 { +impl Default for CoverTrafficV3 { fn default() -> Self { - CoverTrafficV1_1_20_2 { + CoverTrafficV3 { loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, disable_loop_cover_traffic_stream: false, @@ -191,22 +204,22 @@ impl Default for CoverTrafficV1_1_20_2 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct GatewayConnectionV1_1_20_2 { +pub struct GatewayConnectionV3 { #[serde(with = "humantime_serde")] pub gateway_response_timeout: Duration, } -impl From<GatewayConnectionV1_1_20_2> for GatewayConnectionV1_1_30 { - fn from(value: GatewayConnectionV1_1_20_2) -> Self { - GatewayConnectionV1_1_30 { +impl From<GatewayConnectionV3> for GatewayConnectionV4 { + fn from(value: GatewayConnectionV3) -> Self { + GatewayConnectionV4 { gateway_response_timeout: value.gateway_response_timeout, } } } -impl Default for GatewayConnectionV1_1_20_2 { +impl Default for GatewayConnectionV3 { fn default() -> Self { - GatewayConnectionV1_1_20_2 { + GatewayConnectionV3 { gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, } } @@ -214,7 +227,7 @@ impl Default for GatewayConnectionV1_1_20_2 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct AcknowledgementsV1_1_20_2 { +pub struct AcknowledgementsV3 { #[serde(with = "humantime_serde")] pub average_ack_delay: Duration, pub ack_wait_multiplier: f64, @@ -222,9 +235,9 @@ pub struct AcknowledgementsV1_1_20_2 { pub ack_wait_addition: Duration, } -impl From<AcknowledgementsV1_1_20_2> for AcknowledgementsV1_1_30 { - fn from(value: AcknowledgementsV1_1_20_2) -> Self { - AcknowledgementsV1_1_30 { +impl From<AcknowledgementsV3> for AcknowledgementsV4 { + fn from(value: AcknowledgementsV3) -> Self { + AcknowledgementsV4 { average_ack_delay: value.average_ack_delay, ack_wait_multiplier: value.ack_wait_multiplier, ack_wait_addition: value.ack_wait_addition, @@ -232,9 +245,9 @@ impl From<AcknowledgementsV1_1_20_2> for AcknowledgementsV1_1_30 { } } -impl Default for AcknowledgementsV1_1_20_2 { +impl Default for AcknowledgementsV3 { fn default() -> Self { - AcknowledgementsV1_1_20_2 { + AcknowledgementsV3 { average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, @@ -244,7 +257,7 @@ impl Default for AcknowledgementsV1_1_20_2 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TopologyV1_1_20_2 { +pub struct TopologyV3 { #[serde(with = "humantime_serde")] pub topology_refresh_rate: Duration, #[serde(with = "humantime_serde")] @@ -252,9 +265,9 @@ pub struct TopologyV1_1_20_2 { pub disable_refreshing: bool, } -impl Default for TopologyV1_1_20_2 { +impl Default for TopologyV3 { fn default() -> Self { - TopologyV1_1_20_2 { + TopologyV3 { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, @@ -262,9 +275,9 @@ impl Default for TopologyV1_1_20_2 { } } -impl From<TopologyV1_1_20_2> for TopologyV1_1_30 { - fn from(value: TopologyV1_1_20_2) -> Self { - TopologyV1_1_30 { +impl From<TopologyV3> for TopologyV4 { + fn from(value: TopologyV3) -> Self { + TopologyV4 { topology_refresh_rate: value.topology_refresh_rate, topology_resolution_timeout: value.topology_resolution_timeout, disable_refreshing: value.disable_refreshing, @@ -275,7 +288,7 @@ impl From<TopologyV1_1_20_2> for TopologyV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct ReplySurbsV1_1_20_2 { +pub struct ReplySurbsV3 { pub minimum_reply_surb_storage_threshold: usize, pub maximum_reply_surb_storage_threshold: usize, pub minimum_reply_surb_request_size: u32, @@ -291,9 +304,9 @@ pub struct ReplySurbsV1_1_20_2 { pub maximum_reply_key_age: Duration, } -impl Default for ReplySurbsV1_1_20_2 { +impl Default for ReplySurbsV3 { fn default() -> Self { - ReplySurbsV1_1_20_2 { + ReplySurbsV3 { minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, @@ -308,9 +321,9 @@ impl Default for ReplySurbsV1_1_20_2 { } } -impl From<ReplySurbsV1_1_20_2> for ReplySurbsV1_1_30 { - fn from(value: ReplySurbsV1_1_20_2) -> Self { - ReplySurbsV1_1_30 { +impl From<ReplySurbsV3> for ReplySurbsV4 { + fn from(value: ReplySurbsV3) -> Self { + ReplySurbsV4 { minimum_reply_surb_storage_threshold: value.minimum_reply_surb_storage_threshold, maximum_reply_surb_storage_threshold: value.maximum_reply_surb_storage_threshold, minimum_reply_surb_request_size: value.minimum_reply_surb_request_size, @@ -327,18 +340,18 @@ impl From<ReplySurbsV1_1_20_2> for ReplySurbsV1_1_30 { #[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugConfigV1_1_20_2 { - pub traffic: TrafficV1_1_20_2, - pub cover_traffic: CoverTrafficV1_1_20_2, - pub gateway_connection: GatewayConnectionV1_1_20_2, - pub acknowledgements: AcknowledgementsV1_1_20_2, - pub topology: TopologyV1_1_20_2, - pub reply_surbs: ReplySurbsV1_1_20_2, +pub struct DebugConfigV3 { + pub traffic: TrafficV3, + pub cover_traffic: CoverTrafficV3, + pub gateway_connection: GatewayConnectionV3, + pub acknowledgements: AcknowledgementsV3, + pub topology: TopologyV3, + pub reply_surbs: ReplySurbsV3, } -impl From<DebugConfigV1_1_20_2> for DebugConfigV1_1_30 { - fn from(value: DebugConfigV1_1_20_2) -> Self { - DebugConfigV1_1_30 { +impl From<DebugConfigV3> for DebugConfigV4 { + fn from(value: DebugConfigV3) -> Self { + DebugConfigV4 { traffic: value.traffic.into(), cover_traffic: value.cover_traffic.into(), gateway_connection: value.gateway_connection.into(), diff --git a/common/client-core/src/config/old_config_v1_1_30.rs b/common/client-core/config-types/src/old/v4.rs similarity index 85% rename from common/client-core/src/config/old_config_v1_1_30.rs rename to common/client-core/config-types/src/old/v4.rs index 17aeba6bfd..d293709c0c 100644 --- a/common/client-core/src/config/old_config_v1_1_30.rs +++ b/common/client-core/config-types/src/old/v4.rs @@ -1,16 +1,13 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::topology_control::geo_aware_provider::CountryGroup; -use crate::config::old_config_v1_1_33::{ - AcknowledgementsV1_1_33, ClientV1_1_33, ConfigV1_1_33, CoverTrafficV1_1_33, DebugConfigV1_1_33, - GatewayConnectionV1_1_33, GroupByV1_1_33, ReplySurbsV1_1_33, TopologyStructureV1_1_33, - TopologyV1_1_33, TrafficV1_1_33, -}; -use nym_sphinx::{ - addressing::clients::Recipient, - params::{PacketSize, PacketType}, +use crate::old::v5::{ + AcknowledgementsV5, ClientV5, ConfigV5, CoverTrafficV5, DebugConfigV5, GatewayConnectionV5, + GroupByV5, ReplySurbsV5, TopologyStructureV5, TopologyV5, TrafficV5, }; +use crate::CountryGroup; +use nym_sphinx_addressing::Recipient; +use nym_sphinx_params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; @@ -56,27 +53,39 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6 // 24 hours const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +// aliases for backwards compatibility +pub type ConfigV1_1_30 = ConfigV4; +pub type ClientV1_1_30 = ClientV4; +pub type DebugConfigV1_1_30 = DebugConfigV4; + +pub type TrafficV1_1_30 = TrafficV4; +pub type CoverTrafficV1_1_30 = CoverTrafficV4; +pub type GatewayConnectionV1_1_30 = GatewayConnectionV4; +pub type AcknowledgementsV1_1_30 = AcknowledgementsV4; +pub type TopologyV1_1_30 = TopologyV4; +pub type ReplySurbsV1_1_30 = ReplySurbsV4; + #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_30 { - pub client: ClientV1_1_30, +pub struct ConfigV4 { + pub client: ClientV4, #[serde(default)] - pub debug: DebugConfigV1_1_30, + pub debug: DebugConfigV4, } -impl From<ConfigV1_1_30> for ConfigV1_1_33 { - fn from(value: ConfigV1_1_30) -> Self { - ConfigV1_1_33 { - client: ClientV1_1_33 { +impl From<ConfigV4> for ConfigV5 { + fn from(value: ConfigV4) -> Self { + ConfigV5 { + client: ClientV5 { version: value.client.version, id: value.client.id, disabled_credentials_mode: value.client.disabled_credentials_mode, nyxd_urls: value.client.nyxd_urls, nym_api_urls: value.client.nym_api_urls, }, - debug: DebugConfigV1_1_33 { - traffic: TrafficV1_1_33 { + debug: DebugConfigV5 { + traffic: TrafficV5 { average_packet_delay: value.debug.traffic.average_packet_delay, message_sending_average_delay: value .debug @@ -90,7 +99,7 @@ impl From<ConfigV1_1_30> for ConfigV1_1_33 { secondary_packet_size: value.debug.traffic.secondary_packet_size, packet_type: value.debug.traffic.packet_type, }, - cover_traffic: CoverTrafficV1_1_33 { + cover_traffic: CoverTrafficV5 { loop_cover_traffic_average_delay: value .debug .cover_traffic @@ -104,18 +113,18 @@ impl From<ConfigV1_1_30> for ConfigV1_1_33 { .cover_traffic .disable_loop_cover_traffic_stream, }, - gateway_connection: GatewayConnectionV1_1_33 { + gateway_connection: GatewayConnectionV5 { gateway_response_timeout: value .debug .gateway_connection .gateway_response_timeout, }, - acknowledgements: AcknowledgementsV1_1_33 { + acknowledgements: AcknowledgementsV5 { average_ack_delay: value.debug.acknowledgements.average_ack_delay, ack_wait_multiplier: value.debug.acknowledgements.ack_wait_multiplier, ack_wait_addition: value.debug.acknowledgements.ack_wait_addition, }, - topology: TopologyV1_1_33 { + topology: TopologyV5 { topology_refresh_rate: value.debug.topology.topology_refresh_rate, topology_resolution_timeout: value.debug.topology.topology_resolution_timeout, disable_refreshing: value.debug.topology.disable_refreshing, @@ -125,7 +134,7 @@ impl From<ConfigV1_1_30> for ConfigV1_1_33 { .max_startup_gateway_waiting_period, topology_structure: value.debug.topology.topology_structure.into(), }, - reply_surbs: ReplySurbsV1_1_33 { + reply_surbs: ReplySurbsV5 { minimum_reply_surb_storage_threshold: value .debug .reply_surbs @@ -169,7 +178,7 @@ impl From<ConfigV1_1_30> for ConfigV1_1_33 { #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] // note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 #[serde(deny_unknown_fields)] -pub struct ClientV1_1_30 { +pub struct ClientV4 { /// Version of the client for which this configuration was created. pub version: String, @@ -193,7 +202,7 @@ pub struct ClientV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TrafficV1_1_30 { +pub struct TrafficV4 { /// The parameter of Poisson distribution determining how long, on average, /// sent packet is going to be delayed at any given mix node. /// So for a packet going through three mix nodes, on average, it will take three times this value @@ -224,9 +233,9 @@ pub struct TrafficV1_1_30 { pub packet_type: PacketType, } -impl Default for TrafficV1_1_30 { +impl Default for TrafficV4 { fn default() -> Self { - TrafficV1_1_30 { + TrafficV4 { average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, disable_main_poisson_packet_distribution: false, @@ -239,7 +248,7 @@ impl Default for TrafficV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct CoverTrafficV1_1_30 { +pub struct CoverTrafficV4 { /// The parameter of Poisson distribution determining how long, on average, /// it is going to take for another loop cover traffic message to be sent. #[serde(with = "humantime_serde")] @@ -254,9 +263,9 @@ pub struct CoverTrafficV1_1_30 { pub disable_loop_cover_traffic_stream: bool, } -impl Default for CoverTrafficV1_1_30 { +impl Default for CoverTrafficV4 { fn default() -> Self { - CoverTrafficV1_1_30 { + CoverTrafficV4 { loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, disable_loop_cover_traffic_stream: false, @@ -266,16 +275,16 @@ impl Default for CoverTrafficV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct GatewayConnectionV1_1_30 { +pub struct GatewayConnectionV4 { /// How long we're willing to wait for a response to a message sent to the gateway, /// before giving up on it. #[serde(with = "humantime_serde")] pub gateway_response_timeout: Duration, } -impl Default for GatewayConnectionV1_1_30 { +impl Default for GatewayConnectionV4 { fn default() -> Self { - GatewayConnectionV1_1_30 { + GatewayConnectionV4 { gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, } } @@ -283,7 +292,7 @@ impl Default for GatewayConnectionV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct AcknowledgementsV1_1_30 { +pub struct AcknowledgementsV4 { /// The parameter of Poisson distribution determining how long, on average, /// sent acknowledgement is going to be delayed at any given mix node. /// So for an ack going through three mix nodes, on average, it will take three times this value @@ -303,9 +312,9 @@ pub struct AcknowledgementsV1_1_30 { pub ack_wait_addition: Duration, } -impl Default for AcknowledgementsV1_1_30 { +impl Default for AcknowledgementsV4 { fn default() -> Self { - AcknowledgementsV1_1_30 { + AcknowledgementsV4 { average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, @@ -315,7 +324,7 @@ impl Default for AcknowledgementsV1_1_30 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TopologyV1_1_30 { +pub struct TopologyV4 { /// The uniform delay every which clients are querying the directory server /// to try to obtain a compatible network topology to send sphinx packets through. #[serde(with = "humantime_serde")] @@ -338,23 +347,23 @@ pub struct TopologyV1_1_30 { pub max_startup_gateway_waiting_period: Duration, /// Specifies the mixnode topology to be used for sending packets. - pub topology_structure: TopologyStructureV1_1_30, + pub topology_structure: TopologyStructureV4, } #[allow(clippy::large_enum_variant)] #[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum TopologyStructureV1_1_30 { +pub enum TopologyStructureV4 { #[default] NymApi, - GeoAware(GroupByV1_1_30), + GeoAware(GroupByV4), } -impl From<TopologyStructureV1_1_30> for TopologyStructureV1_1_33 { - fn from(value: TopologyStructureV1_1_30) -> Self { +impl From<TopologyStructureV4> for TopologyStructureV5 { + fn from(value: TopologyStructureV4) -> Self { match value { - TopologyStructureV1_1_30::NymApi => TopologyStructureV1_1_33::NymApi, - TopologyStructureV1_1_30::GeoAware(group_by) => { - TopologyStructureV1_1_33::GeoAware(group_by.into()) + TopologyStructureV4::NymApi => TopologyStructureV5::NymApi, + TopologyStructureV4::GeoAware(group_by) => { + TopologyStructureV5::GeoAware(group_by.into()) } } } @@ -362,44 +371,44 @@ impl From<TopologyStructureV1_1_30> for TopologyStructureV1_1_33 { #[allow(clippy::large_enum_variant)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum GroupByV1_1_30 { +pub enum GroupByV4 { CountryGroup(CountryGroup), NymAddress(Recipient), } -impl From<GroupByV1_1_30> for GroupByV1_1_33 { - fn from(value: GroupByV1_1_30) -> Self { +impl From<GroupByV4> for GroupByV5 { + fn from(value: GroupByV4) -> Self { match value { - GroupByV1_1_30::CountryGroup(country) => GroupByV1_1_33::CountryGroup(country), - GroupByV1_1_30::NymAddress(addr) => GroupByV1_1_33::NymAddress(addr), + GroupByV4::CountryGroup(country) => GroupByV5::CountryGroup(country), + GroupByV4::NymAddress(addr) => GroupByV5::NymAddress(addr), } } } -impl std::fmt::Display for GroupByV1_1_30 { +impl std::fmt::Display for GroupByV4 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - GroupByV1_1_30::CountryGroup(group) => write!(f, "group: {}", group), - GroupByV1_1_30::NymAddress(address) => write!(f, "address: {}", address), + GroupByV4::CountryGroup(group) => write!(f, "group: {}", group), + GroupByV4::NymAddress(address) => write!(f, "address: {}", address), } } } -impl Default for TopologyV1_1_30 { +impl Default for TopologyV4 { fn default() -> Self { - TopologyV1_1_30 { + TopologyV4 { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, - topology_structure: TopologyStructureV1_1_30::default(), + topology_structure: TopologyStructureV4::default(), } } } #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct ReplySurbsV1_1_30 { +pub struct ReplySurbsV4 { /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. /// It can only allow to go below that value if its to request additional reply surbs. pub minimum_reply_surb_storage_threshold: usize, @@ -437,9 +446,9 @@ pub struct ReplySurbsV1_1_30 { pub maximum_reply_key_age: Duration, } -impl Default for ReplySurbsV1_1_30 { +impl Default for ReplySurbsV4 { fn default() -> Self { - ReplySurbsV1_1_30 { + ReplySurbsV4 { minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, @@ -456,22 +465,22 @@ impl Default for ReplySurbsV1_1_30 { #[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugConfigV1_1_30 { +pub struct DebugConfigV4 { /// Defines all configuration options related to traffic streams. - pub traffic: TrafficV1_1_30, + pub traffic: TrafficV4, /// Defines all configuration options related to cover traffic stream(s). - pub cover_traffic: CoverTrafficV1_1_30, + pub cover_traffic: CoverTrafficV4, /// Defines all configuration options related to the gateway connection. - pub gateway_connection: GatewayConnectionV1_1_30, + pub gateway_connection: GatewayConnectionV4, /// Defines all configuration options related to acknowledgements, such as delays or wait timeouts. - pub acknowledgements: AcknowledgementsV1_1_30, + pub acknowledgements: AcknowledgementsV4, /// Defines all configuration options related topology, such as refresh rates or timeouts. - pub topology: TopologyV1_1_30, + pub topology: TopologyV4, /// Defines all configuration options related to reply SURBs. - pub reply_surbs: ReplySurbsV1_1_30, + pub reply_surbs: ReplySurbsV4, } diff --git a/common/client-core/src/config/old_config_v1_1_33.rs b/common/client-core/config-types/src/old/v5.rs similarity index 87% rename from common/client-core/src/config/old_config_v1_1_33.rs rename to common/client-core/config-types/src/old/v5.rs index 028b35fb52..34c3f8144e 100644 --- a/common/client-core/src/config/old_config_v1_1_33.rs +++ b/common/client-core/config-types/src/old/v5.rs @@ -1,15 +1,12 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::topology_control::geo_aware_provider::CountryGroup; -use crate::config::{ - Acknowledgements, Client, Config, CoverTraffic, DebugConfig, GatewayConnection, GroupBy, - ReplySurbs, Topology, TopologyStructure, Traffic, -}; -use nym_sphinx::{ - addressing::clients::Recipient, - params::{PacketSize, PacketType}, +use crate::{ + Acknowledgements, Client, Config, CountryGroup, CoverTraffic, DebugConfig, GatewayConnection, + GroupBy, ReplySurbs, Topology, TopologyStructure, Traffic, }; +use nym_sphinx_addressing::Recipient; +use nym_sphinx_params::{PacketSize, PacketType}; use serde::{Deserialize, Serialize}; use std::time::Duration; use url::Url; @@ -55,8 +52,21 @@ const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 6 // 24 hours const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); +// aliases for backwards compatibility +pub type ConfigV1_1_33 = ConfigV5; +pub type ClientV1_1_33 = ClientV5; +pub type DebugConfigV1_1_33 = DebugConfigV5; +pub type OldGatewayEndpointConfigV1_1_33 = GatewayEndpointConfigV5; + +pub type TrafficV1_1_33 = TrafficV5; +pub type CoverTrafficV1_1_33 = CoverTrafficV5; +pub type GatewayConnectionV1_1_33 = GatewayConnectionV5; +pub type AcknowledgementsV1_1_33 = AcknowledgementsV5; +pub type TopologyV1_1_33 = TopologyV5; +pub type ReplySurbsV1_1_33 = ReplySurbsV5; + #[derive(Clone, Debug, Default, Deserialize, PartialEq, Eq, Serialize)] -pub struct OldGatewayEndpointConfigV1_1_33 { +pub struct GatewayEndpointConfigV5 { /// gateway_id specifies ID of the gateway to which the client should send messages. /// If initially omitted, a random gateway will be chosen from the available topology. pub gateway_id: String, @@ -70,15 +80,15 @@ pub struct OldGatewayEndpointConfigV1_1_33 { #[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(deny_unknown_fields)] -pub struct ConfigV1_1_33 { - pub client: ClientV1_1_33, +pub struct ConfigV5 { + pub client: ClientV5, #[serde(default)] - pub debug: DebugConfigV1_1_33, + pub debug: DebugConfigV5, } -impl From<ConfigV1_1_33> for Config { - fn from(value: ConfigV1_1_33) -> Self { +impl From<ConfigV5> for Config { + fn from(value: ConfigV5) -> Self { Config { client: Client { version: value.client.version, @@ -178,7 +188,7 @@ impl From<ConfigV1_1_33> for Config { #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] // note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 #[serde(deny_unknown_fields)] -pub struct ClientV1_1_33 { +pub struct ClientV5 { /// Version of the client for which this configuration was created. pub version: String, @@ -202,7 +212,7 @@ pub struct ClientV1_1_33 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TrafficV1_1_33 { +pub struct TrafficV5 { /// The parameter of Poisson distribution determining how long, on average, /// sent packet is going to be delayed at any given mix node. /// So for a packet going through three mix nodes, on average, it will take three times this value @@ -233,9 +243,9 @@ pub struct TrafficV1_1_33 { pub packet_type: PacketType, } -impl Default for TrafficV1_1_33 { +impl Default for TrafficV5 { fn default() -> Self { - TrafficV1_1_33 { + TrafficV5 { average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, disable_main_poisson_packet_distribution: false, @@ -248,7 +258,7 @@ impl Default for TrafficV1_1_33 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct CoverTrafficV1_1_33 { +pub struct CoverTrafficV5 { /// The parameter of Poisson distribution determining how long, on average, /// it is going to take for another loop cover traffic message to be sent. #[serde(with = "humantime_serde")] @@ -263,9 +273,9 @@ pub struct CoverTrafficV1_1_33 { pub disable_loop_cover_traffic_stream: bool, } -impl Default for CoverTrafficV1_1_33 { +impl Default for CoverTrafficV5 { fn default() -> Self { - CoverTrafficV1_1_33 { + CoverTrafficV5 { loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, disable_loop_cover_traffic_stream: false, @@ -275,16 +285,16 @@ impl Default for CoverTrafficV1_1_33 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct GatewayConnectionV1_1_33 { +pub struct GatewayConnectionV5 { /// How long we're willing to wait for a response to a message sent to the gateway, /// before giving up on it. #[serde(with = "humantime_serde")] pub gateway_response_timeout: Duration, } -impl Default for GatewayConnectionV1_1_33 { +impl Default for GatewayConnectionV5 { fn default() -> Self { - GatewayConnectionV1_1_33 { + GatewayConnectionV5 { gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, } } @@ -292,7 +302,7 @@ impl Default for GatewayConnectionV1_1_33 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct AcknowledgementsV1_1_33 { +pub struct AcknowledgementsV5 { /// The parameter of Poisson distribution determining how long, on average, /// sent acknowledgement is going to be delayed at any given mix node. /// So for an ack going through three mix nodes, on average, it will take three times this value @@ -312,9 +322,9 @@ pub struct AcknowledgementsV1_1_33 { pub ack_wait_addition: Duration, } -impl Default for AcknowledgementsV1_1_33 { +impl Default for AcknowledgementsV5 { fn default() -> Self { - AcknowledgementsV1_1_33 { + AcknowledgementsV5 { average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, @@ -324,7 +334,7 @@ impl Default for AcknowledgementsV1_1_33 { #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct TopologyV1_1_33 { +pub struct TopologyV5 { /// The uniform delay every which clients are querying the directory server /// to try to obtain a compatible network topology to send sphinx packets through. #[serde(with = "humantime_serde")] @@ -347,68 +357,66 @@ pub struct TopologyV1_1_33 { pub max_startup_gateway_waiting_period: Duration, /// Specifies the mixnode topology to be used for sending packets. - pub topology_structure: TopologyStructureV1_1_33, + pub topology_structure: TopologyStructureV5, } #[allow(clippy::large_enum_variant)] #[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum TopologyStructureV1_1_33 { +pub enum TopologyStructureV5 { #[default] NymApi, - GeoAware(GroupByV1_1_33), + GeoAware(GroupByV5), } -impl From<TopologyStructureV1_1_33> for TopologyStructure { - fn from(value: TopologyStructureV1_1_33) -> Self { +impl From<TopologyStructureV5> for TopologyStructure { + fn from(value: TopologyStructureV5) -> Self { match value { - TopologyStructureV1_1_33::NymApi => TopologyStructure::NymApi, - TopologyStructureV1_1_33::GeoAware(group_by) => { - TopologyStructure::GeoAware(group_by.into()) - } + TopologyStructureV5::NymApi => TopologyStructure::NymApi, + TopologyStructureV5::GeoAware(group_by) => TopologyStructure::GeoAware(group_by.into()), } } } #[allow(clippy::large_enum_variant)] #[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum GroupByV1_1_33 { +pub enum GroupByV5 { CountryGroup(CountryGroup), NymAddress(Recipient), } -impl From<GroupByV1_1_33> for GroupBy { - fn from(value: GroupByV1_1_33) -> Self { +impl From<GroupByV5> for GroupBy { + fn from(value: GroupByV5) -> Self { match value { - GroupByV1_1_33::CountryGroup(country) => GroupBy::CountryGroup(country), - GroupByV1_1_33::NymAddress(addr) => GroupBy::NymAddress(addr), + GroupByV5::CountryGroup(country) => GroupBy::CountryGroup(country), + GroupByV5::NymAddress(addr) => GroupBy::NymAddress(addr), } } } -impl std::fmt::Display for GroupByV1_1_33 { +impl std::fmt::Display for GroupByV5 { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - GroupByV1_1_33::CountryGroup(group) => write!(f, "group: {}", group), - GroupByV1_1_33::NymAddress(address) => write!(f, "address: {}", address), + GroupByV5::CountryGroup(group) => write!(f, "group: {}", group), + GroupByV5::NymAddress(address) => write!(f, "address: {}", address), } } } -impl Default for TopologyV1_1_33 { +impl Default for TopologyV5 { fn default() -> Self { - TopologyV1_1_33 { + TopologyV5 { topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, disable_refreshing: false, max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, - topology_structure: TopologyStructureV1_1_33::default(), + topology_structure: TopologyStructureV5::default(), } } } #[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct ReplySurbsV1_1_33 { +pub struct ReplySurbsV5 { /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. /// It can only allow to go below that value if its to request additional reply surbs. pub minimum_reply_surb_storage_threshold: usize, @@ -450,9 +458,9 @@ pub struct ReplySurbsV1_1_33 { pub surb_mix_hops: Option<u8>, } -impl Default for ReplySurbsV1_1_33 { +impl Default for ReplySurbsV5 { fn default() -> Self { - ReplySurbsV1_1_33 { + ReplySurbsV5 { minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, @@ -470,22 +478,22 @@ impl Default for ReplySurbsV1_1_33 { #[derive(Debug, Default, Clone, Copy, Deserialize, PartialEq, Serialize)] #[serde(default, deny_unknown_fields)] -pub struct DebugConfigV1_1_33 { +pub struct DebugConfigV5 { /// Defines all configuration options related to traffic streams. - pub traffic: TrafficV1_1_33, + pub traffic: TrafficV5, /// Defines all configuration options related to cover traffic stream(s). - pub cover_traffic: CoverTrafficV1_1_33, + pub cover_traffic: CoverTrafficV5, /// Defines all configuration options related to the gateway connection. - pub gateway_connection: GatewayConnectionV1_1_33, + pub gateway_connection: GatewayConnectionV5, /// Defines all configuration options related to acknowledgements, such as delays or wait timeouts. - pub acknowledgements: AcknowledgementsV1_1_33, + pub acknowledgements: AcknowledgementsV5, /// Defines all configuration options related topology, such as refresh rates or timeouts. - pub topology: TopologyV1_1_33, + pub topology: TopologyV5, /// Defines all configuration options related to reply SURBs. - pub reply_surbs: ReplySurbsV1_1_33, + pub reply_surbs: ReplySurbsV5, } diff --git a/common/client-core/gateways-storage/src/types.rs b/common/client-core/gateways-storage/src/types.rs index 3755cb6127..8eb5c8753c 100644 --- a/common/client-core/gateways-storage/src/types.rs +++ b/common/client-core/gateways-storage/src/types.rs @@ -27,6 +27,12 @@ pub struct GatewayRegistration { pub registration_timestamp: OffsetDateTime, } +impl GatewayRegistration { + pub fn gateway_id(&self) -> identity::PublicKey { + self.details.gateway_id() + } +} + impl<'a> From<&'a GatewayRegistration> for RawRegisteredGateway { fn from(value: &'a GatewayRegistration) -> Self { RawRegisteredGateway { @@ -298,3 +304,12 @@ pub struct CustomGatewayDetails { pub gateway_id: identity::PublicKey, pub data: Option<Vec<u8>>, } + +impl CustomGatewayDetails { + pub fn new(gateway_id: identity::PublicKey) -> CustomGatewayDetails { + Self { + gateway_id, + data: None, + } + } +} diff --git a/common/client-core/src/client/key_manager/persistence.rs b/common/client-core/src/client/key_manager/persistence.rs index a4711e3d39..2bff78ee36 100644 --- a/common/client-core/src/client/key_manager/persistence.rs +++ b/common/client-core/src/client/key_manager/persistence.rs @@ -7,7 +7,7 @@ use std::error::Error; use tokio::sync::Mutex; #[cfg(not(target_arch = "wasm32"))] -use crate::config::disk_persistence::keys_paths::ClientKeysPaths; +use crate::config::disk_persistence::ClientKeysPaths; #[cfg(not(target_arch = "wasm32"))] use nym_crypto::asymmetric::{encryption, identity}; #[cfg(not(target_arch = "wasm32"))] diff --git a/common/client-core/src/client/topology_control/geo_aware_provider.rs b/common/client-core/src/client/topology_control/geo_aware_provider.rs index 71de0327b5..96d52fd8d5 100644 --- a/common/client-core/src/client/topology_control/geo_aware_provider.rs +++ b/common/client-core/src/client/topology_control/geo_aware_provider.rs @@ -1,6 +1,5 @@ -use std::{collections::HashMap, fmt}; - -use log::{debug, error, info}; +use crate::config::GroupBy; +use log::{debug, error}; use nym_explorer_client::{ExplorerClient, PrettyDetailedMixNodeBond}; use nym_network_defaults::var_names::EXPLORER_API; use nym_topology::{ @@ -10,11 +9,11 @@ use nym_topology::{ }; use nym_validator_client::client::MixId; use rand::{prelude::SliceRandom, thread_rng}; -use serde::{Deserialize, Serialize}; +use std::collections::HashMap; use tap::TapOptional; use url::Url; -use crate::config::GroupBy; +pub use nym_country_group::CountryGroup; const MIN_NODES_PER_LAYER: usize = 1; @@ -38,158 +37,6 @@ fn create_explorer_client() -> Option<ExplorerClient> { Some(client) } -#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)] -pub enum CountryGroup { - Europe, - NorthAmerica, - SouthAmerica, - Oceania, - Asia, - Africa, - Unknown, -} - -impl CountryGroup { - // We map contry codes into group, which initially are continent codes to a first approximation, - // but we do it manually to reserve the right to tweak this distribution for our purposes. - // NOTE: I did this quickly and it's not a complete list of all countries, but only those that - // were present in the network at the time. Please add more as needed. - fn new(country_code: &str) -> Self { - let country_code = country_code.to_uppercase(); - use CountryGroup::*; - match country_code.as_ref() { - // Europe - "AT" => Europe, - "BG" => Europe, - "CH" => Europe, - "CY" => Europe, - "CZ" => Europe, - "DE" => Europe, - "DK" => Europe, - "ES" => Europe, - "FI" => Europe, - "FR" => Europe, - "GB" => Europe, - "GR" => Europe, - "IE" => Europe, - "IT" => Europe, - "LT" => Europe, - "LU" => Europe, - "LV" => Europe, - "MD" => Europe, - "MT" => Europe, - "NL" => Europe, - "NO" => Europe, - "PL" => Europe, - "RO" => Europe, - "SE" => Europe, - "SK" => Europe, - "TR" => Europe, - "UA" => Europe, - - // North America - "CA" => NorthAmerica, - "MX" => NorthAmerica, - "US" => NorthAmerica, - - // South America - "AR" => SouthAmerica, - "BR" => SouthAmerica, - "CL" => SouthAmerica, - "CO" => SouthAmerica, - "CR" => SouthAmerica, - "GT" => SouthAmerica, - - // Oceania - "AU" => Oceania, - - // Asia - "AM" => Asia, - "BH" => Asia, - "CN" => Asia, - "GE" => Asia, - "HK" => Asia, - "ID" => Asia, - "IL" => Asia, - "IN" => Asia, - "JP" => Asia, - "KH" => Asia, - "KR" => Asia, - "KZ" => Asia, - "MY" => Asia, - "RU" => Asia, - "SG" => Asia, - "TH" => Asia, - "VN" => Asia, - - // Africa - "SC" => Africa, - "UG" => Africa, - "ZA" => Africa, - - // And group level codes work too - "EU" => Europe, - "NA" => NorthAmerica, - "SA" => SouthAmerica, - "OC" => Oceania, - "AS" => Asia, - "AF" => Africa, - - // And some aliases - "EUROPE" => Europe, - "NORTHAMERICA" => NorthAmerica, - "SOUTHAMERICA" => SouthAmerica, - "OCEANIA" => Oceania, - "ASIA" => Asia, - "AFRICA" => Africa, - - _ => { - info!("Unknown country code: {}", country_code); - Unknown - } - } - } -} - -impl fmt::Display for CountryGroup { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - use CountryGroup::*; - match self { - Europe => write!(f, "EU"), - NorthAmerica => write!(f, "NA"), - SouthAmerica => write!(f, "SA"), - Oceania => write!(f, "OC"), - Asia => write!(f, "AS"), - Africa => write!(f, "AF"), - Unknown => write!(f, "Unknown"), - } - } -} - -impl std::str::FromStr for CountryGroup { - type Err = (); - - fn from_str(s: &str) -> Result<Self, Self::Err> { - let group = CountryGroup::new(s); - if group == CountryGroup::Unknown { - Err(()) - } else { - Ok(group) - } - } -} - -impl CountryGroup { - #[allow(unused)] - fn known(self) -> Option<CountryGroup> { - use CountryGroup::*; - match self { - Europe | NorthAmerica | SouthAmerica | Oceania | Asia | Africa => Some(self), - Unknown => None, - } - } -} - fn group_mixnodes_by_country_code( mixnodes: Vec<PrettyDetailedMixNodeBond>, ) -> HashMap<CountryGroup, Vec<MixId>> { diff --git a/common/client-core/src/config/disk_persistence/mod.rs b/common/client-core/src/config/disk_persistence/mod.rs deleted file mode 100644 index c086696a4b..0000000000 --- a/common/client-core/src/config/disk_persistence/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: Apache-2.0 - -use crate::config::disk_persistence::keys_paths::ClientKeysPaths; -use serde::{Deserialize, Serialize}; -use std::path::{Path, PathBuf}; - -pub mod keys_paths; -pub mod old_v1_1_20_2; -pub mod old_v1_1_33; - -pub const DEFAULT_REPLY_SURB_DB_FILENAME: &str = "persistent_reply_store.sqlite"; -pub const DEFAULT_CREDENTIALS_DB_FILENAME: &str = "credentials_database.db"; -pub const DEFAULT_GATEWAYS_DETAILS_DB_FILENAME: &str = "gateways_registrations.sqlite"; - -#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct CommonClientPaths { - pub keys: ClientKeysPaths, - - /// Path to the file containing information about gateways used by this client, - /// i.e. details such as their public keys, owner addresses or the network information. - pub gateway_registrations: PathBuf, - - /// Path to the database containing bandwidth credentials of this client. - pub credentials_database: PathBuf, - - /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. - pub reply_surb_database: PathBuf, -} - -impl CommonClientPaths { - pub fn new_base<P: AsRef<Path>>(base_data_directory: P) -> Self { - let base_dir = base_data_directory.as_ref(); - - CommonClientPaths { - credentials_database: base_dir.join(DEFAULT_CREDENTIALS_DB_FILENAME), - reply_surb_database: base_dir.join(DEFAULT_REPLY_SURB_DB_FILENAME), - gateway_registrations: base_dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), - keys: ClientKeysPaths::new_base(base_data_directory), - } - } -} diff --git a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs b/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs deleted file mode 100644 index e1863bb567..0000000000 --- a/common/client-core/src/config/disk_persistence/old_v1_1_20_2.rs +++ /dev/null @@ -1,33 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: Apache-2.0 - -use crate::config::disk_persistence::old_v1_1_33::{ - ClientKeysPathsV1_1_33, CommonClientPathsV1_1_33, DEFAULT_GATEWAY_DETAILS_FILENAME, -}; -use crate::error::ClientCoreError; -use serde::{Deserialize, Serialize}; -use std::path::PathBuf; - -#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct CommonClientPathsV1_1_20_2 { - pub keys: ClientKeysPathsV1_1_33, - pub credentials_database: PathBuf, - pub reply_surb_database: PathBuf, -} - -impl CommonClientPathsV1_1_20_2 { - pub fn upgrade_default(self) -> Result<CommonClientPathsV1_1_33, ClientCoreError> { - let data_dir = self.reply_surb_database.parent().ok_or_else(|| { - ClientCoreError::ConfigFileUpgradeFailure { - current_version: "1.1.20-2".to_string(), - } - })?; - Ok(CommonClientPathsV1_1_33 { - keys: self.keys, - gateway_details: data_dir.join(DEFAULT_GATEWAY_DETAILS_FILENAME), - credentials_database: self.credentials_database, - reply_surb_database: self.reply_surb_database, - }) - } -} diff --git a/common/client-core/src/config/mod.rs b/common/client-core/src/config/mod.rs index 2333c58df4..69c30c69ae 100644 --- a/common/client-core/src/config/mod.rs +++ b/common/client-core/src/config/mod.rs @@ -1,602 +1,9 @@ -// Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::client::topology_control::geo_aware_provider::CountryGroup; -use nym_config::defaults::NymNetworkDetails; -use nym_sphinx::{ - addressing::clients::Recipient, - params::{PacketSize, PacketType}, +pub use nym_client_core_config_types::disk_persistence; +pub use nym_client_core_config_types::old::{ + old_config_v1_1_13, old_config_v1_1_20, old_config_v1_1_20_2, old_config_v1_1_30, + old_config_v1_1_33, }; -use serde::{Deserialize, Serialize}; -use std::time::Duration; -use url::Url; - -pub mod disk_persistence; -pub mod old_config_v1_1_13; -pub mod old_config_v1_1_20; -pub mod old_config_v1_1_20_2; -pub mod old_config_v1_1_30; -pub mod old_config_v1_1_33; - -// 'DEBUG' -const DEFAULT_ACK_WAIT_MULTIPLIER: f64 = 1.5; - -const DEFAULT_ACK_WAIT_ADDITION: Duration = Duration::from_millis(1_500); -const DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(200); -const DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY: Duration = Duration::from_millis(20); -const DEFAULT_AVERAGE_PACKET_DELAY: Duration = Duration::from_millis(50); -const DEFAULT_TOPOLOGY_REFRESH_RATE: Duration = Duration::from_secs(5 * 60); // every 5min -const DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT: Duration = Duration::from_millis(5_000); -const DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD: Duration = Duration::from_secs(70 * 60); // 70min -> full epoch (1h) + a bit of overhead - -// Set this to a high value for now, so that we don't risk sporadic timeouts that might cause -// bought bandwidth tokens to not have time to be spent; Once we remove the gateway from the -// bandwidth bridging protocol, we can come back to a smaller timeout value -const DEFAULT_GATEWAY_RESPONSE_TIMEOUT: Duration = Duration::from_secs(5 * 60); - -const DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO: f64 = 0.70; - -// reply-surbs related: - -// define when to request -// clients/client-core/src/client/replies/reply_storage/surb_storage.rs -const DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 10; -const DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD: usize = 200; - -// define how much to request at once -// clients/client-core/src/client/replies/reply_controller.rs -const DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 10; -const DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE: u32 = 100; - -const DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE: u32 = 500; - -const DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD: Duration = Duration::from_secs(10); -const DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD: Duration = Duration::from_secs(5 * 60); - -// 12 hours -const DEFAULT_MAXIMUM_REPLY_SURB_AGE: Duration = Duration::from_secs(12 * 60 * 60); - -// 24 hours -const DEFAULT_MAXIMUM_REPLY_KEY_AGE: Duration = Duration::from_secs(24 * 60 * 60); - -#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] -#[serde(deny_unknown_fields)] -pub struct Config { - pub client: Client, - - #[serde(default)] - pub debug: DebugConfig, -} - -impl Config { - pub fn new<S1, S2>(id: S1, version: S2) -> Self - where - S1: Into<String>, - S2: Into<String>, - { - Config { - client: Client::new_default(id, version), - debug: Default::default(), - } - } - - pub fn from_client_config(client: Client, debug: DebugConfig) -> Self { - Config { client, debug } - } - - pub fn validate(&self) -> bool { - self.debug.validate() - } - - pub fn with_debug_config(mut self, debug: DebugConfig) -> Self { - self.debug = debug; - self - } - - pub fn with_disabled_credentials(mut self, disabled_credentials_mode: bool) -> Self { - self.client.disabled_credentials_mode = disabled_credentials_mode; - self - } - - pub fn with_custom_nyxd(mut self, urls: Vec<Url>) -> Self { - self.client.nyxd_urls = urls; - self - } - - pub fn set_custom_nyxd(&mut self, nyxd_urls: Vec<Url>) { - self.client.nyxd_urls = nyxd_urls; - } - - pub fn with_custom_nym_apis(mut self, nym_api_urls: Vec<Url>) -> Self { - self.client.nym_api_urls = nym_api_urls; - self - } - - pub fn set_custom_nym_apis(&mut self, nym_api_urls: Vec<Url>) { - self.client.nym_api_urls = nym_api_urls; - } - - pub fn with_high_default_traffic_volume(mut self, enabled: bool) -> Self { - if enabled { - self.set_high_default_traffic_volume(); - } - self - } - - pub fn with_packet_type(mut self, packet_type: PacketType) -> Self { - self.debug.traffic.packet_type = packet_type; - self - } - - pub fn set_high_default_traffic_volume(&mut self) { - self.debug.traffic.average_packet_delay = Duration::from_millis(10); - // basically don't really send cover messages - self.debug.cover_traffic.loop_cover_traffic_average_delay = - Duration::from_millis(2_000_000); - // 250 "real" messages / s - self.debug.traffic.message_sending_average_delay = Duration::from_millis(4); - } - - pub fn with_disabled_poisson_process(mut self, disabled: bool) -> Self { - if disabled { - self.set_no_poisson_process() - } - self - } - - pub fn set_no_poisson_process(&mut self) { - self.debug.traffic.disable_main_poisson_packet_distribution = true; - } - - pub fn with_disabled_cover_traffic(mut self, disabled: bool) -> Self { - if disabled { - self.set_no_cover_traffic() - } - self - } - - pub fn set_no_cover_traffic(&mut self) { - self.debug.cover_traffic.disable_loop_cover_traffic_stream = true; - self.debug.traffic.disable_main_poisson_packet_distribution = true; - } - - pub fn with_disabled_cover_traffic_with_keepalive(mut self, disabled: bool) -> Self { - if disabled { - self.set_no_cover_traffic_with_keepalive() - } - self - } - pub fn set_no_cover_traffic_with_keepalive(&mut self) { - self.debug.traffic.disable_main_poisson_packet_distribution = true; - self.debug.cover_traffic.loop_cover_traffic_average_delay = Duration::from_secs(5); - } - - pub fn with_disabled_topology_refresh(mut self, disable_topology_refresh: bool) -> Self { - self.debug.topology.disable_refreshing = disable_topology_refresh; - self - } - - pub fn with_topology_structure(mut self, topology_structure: TopologyStructure) -> Self { - self.set_topology_structure(topology_structure); - self - } - - pub fn set_topology_structure(&mut self, topology_structure: TopologyStructure) { - self.debug.topology.topology_structure = topology_structure; - } - - pub fn with_no_per_hop_delays(mut self, no_per_hop_delays: bool) -> Self { - if no_per_hop_delays { - self.set_no_per_hop_delays() - } - self - } - - pub fn set_no_per_hop_delays(&mut self) { - self.debug.traffic.average_packet_delay = Duration::ZERO; - self.debug.acknowledgements.average_ack_delay = Duration::ZERO; - } - - pub fn with_secondary_packet_size(mut self, secondary_packet_size: Option<PacketSize>) -> Self { - self.set_secondary_packet_size(secondary_packet_size); - self - } - - pub fn set_secondary_packet_size(&mut self, secondary_packet_size: Option<PacketSize>) { - self.debug.traffic.secondary_packet_size = secondary_packet_size; - } - - pub fn set_custom_version(&mut self, version: &str) { - self.client.version = version.to_string(); - } - - pub fn get_id(&self) -> String { - self.client.id.clone() - } - - pub fn get_disabled_credentials_mode(&self) -> bool { - self.client.disabled_credentials_mode - } - - pub fn get_validator_endpoints(&self) -> Vec<Url> { - self.client.nyxd_urls.clone() - } - - pub fn get_nym_api_endpoints(&self) -> Vec<Url> { - self.client.nym_api_urls.clone() - } -} - -#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] -// note: the deny_unknown_fields is VITAL here to allow upgrades from v1.1.20_2 -#[serde(deny_unknown_fields)] -pub struct Client { - /// Version of the client for which this configuration was created. - pub version: String, - - /// ID specifies the human readable ID of this particular client. - pub id: String, - - /// Indicates whether this client is running in a disabled credentials mode, thus attempting - /// to claim bandwidth without presenting bandwidth credentials. - // TODO: this should be moved to `debug.gateway_connection` - #[serde(default)] - pub disabled_credentials_mode: bool, - - /// Addresses to nyxd validators via which the client can communicate with the chain. - #[serde(alias = "validator_urls")] - pub nyxd_urls: Vec<Url>, - - /// Addresses to APIs running on validator from which the client gets the view of the network. - #[serde(alias = "validator_api_urls")] - pub nym_api_urls: Vec<Url>, -} - -impl Client { - pub fn new_default<S1, S2>(id: S1, version: S2) -> Self - where - S1: Into<String>, - S2: Into<String>, - { - let network = NymNetworkDetails::new_mainnet(); - let nyxd_urls = network - .endpoints - .iter() - .map(|validator| validator.nyxd_url()) - .collect(); - let nym_api_urls = network - .endpoints - .iter() - .filter_map(|validator| validator.api_url()) - .collect::<Vec<_>>(); - - Client { - version: version.into(), - id: id.into(), - disabled_credentials_mode: true, - nyxd_urls, - nym_api_urls, - } - } - - pub fn new<S: Into<String>>( - id: S, - disabled_credentials_mode: bool, - nyxd_urls: Vec<Url>, - nym_api_urls: Vec<Url>, - ) -> Self { - Client { - version: env!("CARGO_PKG_VERSION").to_string(), - id: id.into(), - disabled_credentials_mode, - nyxd_urls, - nym_api_urls, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct Traffic { - /// The parameter of Poisson distribution determining how long, on average, - /// sent packet is going to be delayed at any given mix node. - /// So for a packet going through three mix nodes, on average, it will take three times this value - /// until the packet reaches its destination. - #[serde(with = "humantime_serde")] - pub average_packet_delay: Duration, - - /// The parameter of Poisson distribution determining how long, on average, - /// it is going to take another 'real traffic stream' message to be sent. - /// If no real packets are available and cover traffic is enabled, - /// a loop cover message is sent instead in order to preserve the rate. - #[serde(with = "humantime_serde")] - pub message_sending_average_delay: Duration, - - /// Controls whether the main packet stream constantly produces packets according to the predefined - /// poisson distribution. - pub disable_main_poisson_packet_distribution: bool, - - /// Specifies the packet size used for sent messages. - /// Do not override it unless you understand the consequences of that change. - pub primary_packet_size: PacketSize, - - /// Specifies the optional auxiliary packet size for optimizing message streams. - /// Note that its use decreases overall anonymity. - /// Do not set it it unless you understand the consequences of that change. - pub secondary_packet_size: Option<PacketSize>, - - pub packet_type: PacketType, -} - -impl Traffic { - pub fn validate(&self) -> bool { - if let Some(secondary_packet_size) = self.secondary_packet_size { - if secondary_packet_size == PacketSize::AckPacket - || secondary_packet_size == self.primary_packet_size - { - return false; - } - } - true - } -} - -impl Default for Traffic { - fn default() -> Self { - Traffic { - average_packet_delay: DEFAULT_AVERAGE_PACKET_DELAY, - message_sending_average_delay: DEFAULT_MESSAGE_STREAM_AVERAGE_DELAY, - disable_main_poisson_packet_distribution: false, - primary_packet_size: PacketSize::RegularPacket, - secondary_packet_size: None, - packet_type: PacketType::Mix, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct CoverTraffic { - /// The parameter of Poisson distribution determining how long, on average, - /// it is going to take for another loop cover traffic message to be sent. - #[serde(with = "humantime_serde")] - pub loop_cover_traffic_average_delay: Duration, - - /// Specifies the ratio of `primary_packet_size` to `secondary_packet_size` used in cover traffic. - /// Only applicable if `secondary_packet_size` is enabled. - pub cover_traffic_primary_size_ratio: f64, - - /// Controls whether the dedicated loop cover traffic stream should be enabled. - /// (and sending packets, on average, every [Self::loop_cover_traffic_average_delay]) - pub disable_loop_cover_traffic_stream: bool, -} - -impl Default for CoverTraffic { - fn default() -> Self { - CoverTraffic { - loop_cover_traffic_average_delay: DEFAULT_LOOP_COVER_STREAM_AVERAGE_DELAY, - cover_traffic_primary_size_ratio: DEFAULT_COVER_TRAFFIC_PRIMARY_SIZE_RATIO, - disable_loop_cover_traffic_stream: false, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct GatewayConnection { - /// How long we're willing to wait for a response to a message sent to the gateway, - /// before giving up on it. - #[serde(with = "humantime_serde")] - pub gateway_response_timeout: Duration, -} - -impl Default for GatewayConnection { - fn default() -> Self { - GatewayConnection { - gateway_response_timeout: DEFAULT_GATEWAY_RESPONSE_TIMEOUT, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct Acknowledgements { - /// The parameter of Poisson distribution determining how long, on average, - /// sent acknowledgement is going to be delayed at any given mix node. - /// So for an ack going through three mix nodes, on average, it will take three times this value - /// until the packet reaches its destination. - #[serde(with = "humantime_serde")] - pub average_ack_delay: Duration, - - /// Value multiplied with the expected round trip time of an acknowledgement packet before - /// it is assumed it was lost and retransmission of the data packet happens. - /// In an ideal network with 0 latency, this value would have been 1. - pub ack_wait_multiplier: f64, - - /// Value added to the expected round trip time of an acknowledgement packet before - /// it is assumed it was lost and retransmission of the data packet happens. - /// In an ideal network with 0 latency, this value would have been 0. - #[serde(with = "humantime_serde")] - pub ack_wait_addition: Duration, -} - -impl Default for Acknowledgements { - fn default() -> Self { - Acknowledgements { - average_ack_delay: DEFAULT_AVERAGE_PACKET_DELAY, - ack_wait_multiplier: DEFAULT_ACK_WAIT_MULTIPLIER, - ack_wait_addition: DEFAULT_ACK_WAIT_ADDITION, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct Topology { - /// The uniform delay every which clients are querying the directory server - /// to try to obtain a compatible network topology to send sphinx packets through. - #[serde(with = "humantime_serde")] - pub topology_refresh_rate: Duration, - - /// During topology refresh, test packets are sent through every single possible network - /// path. This timeout determines waiting period until it is decided that the packet - /// did not reach its destination. - #[serde(with = "humantime_serde")] - pub topology_resolution_timeout: Duration, - - /// Specifies whether the client should not refresh the network topology after obtaining - /// the first valid instance. - /// Supersedes `topology_refresh_rate_ms`. - pub disable_refreshing: bool, - - /// Defines how long the client is going to wait on startup for its gateway to come online, - /// before abandoning the procedure. - #[serde(with = "humantime_serde")] - pub max_startup_gateway_waiting_period: Duration, - - /// Specifies the mixnode topology to be used for sending packets. - pub topology_structure: TopologyStructure, -} - -#[allow(clippy::large_enum_variant)] -#[derive(Default, Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum TopologyStructure { - #[default] - NymApi, - GeoAware(GroupBy), -} - -#[allow(clippy::large_enum_variant)] -#[derive(Copy, Clone, Debug, PartialEq, Serialize, Deserialize)] -pub enum GroupBy { - CountryGroup(CountryGroup), - NymAddress(Recipient), -} - -impl std::fmt::Display for GroupBy { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - match self { - GroupBy::CountryGroup(group) => write!(f, "group: {}", group), - GroupBy::NymAddress(address) => write!(f, "address: {}", address), - } - } -} - -impl Default for Topology { - fn default() -> Self { - Topology { - topology_refresh_rate: DEFAULT_TOPOLOGY_REFRESH_RATE, - topology_resolution_timeout: DEFAULT_TOPOLOGY_RESOLUTION_TIMEOUT, - disable_refreshing: false, - max_startup_gateway_waiting_period: DEFAULT_MAX_STARTUP_GATEWAY_WAITING_PERIOD, - topology_structure: TopologyStructure::default(), - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct ReplySurbs { - /// Defines the minimum number of reply surbs the client wants to keep in its storage at all times. - /// It can only allow to go below that value if its to request additional reply surbs. - pub minimum_reply_surb_storage_threshold: usize, - - /// Defines the maximum number of reply surbs the client wants to keep in its storage at any times. - pub maximum_reply_surb_storage_threshold: usize, - - /// Defines the minimum number of reply surbs the client would request. - pub minimum_reply_surb_request_size: u32, - - /// Defines the maximum number of reply surbs the client would request. - pub maximum_reply_surb_request_size: u32, - - /// Defines the maximum number of reply surbs a remote party is allowed to request from this client at once. - pub maximum_allowed_reply_surb_request_size: u32, - - /// Defines maximum amount of time the client is going to wait for reply surbs before explicitly asking - /// for more even though in theory they wouldn't need to. - #[serde(with = "humantime_serde")] - pub maximum_reply_surb_rerequest_waiting_period: Duration, - - /// Defines maximum amount of time the client is going to wait for reply surbs before - /// deciding it's never going to get them and would drop all pending messages - #[serde(with = "humantime_serde")] - pub maximum_reply_surb_drop_waiting_period: Duration, - - /// Defines maximum amount of time given reply surb is going to be valid for. - /// This is going to be superseded by key rotation once implemented. - #[serde(with = "humantime_serde")] - pub maximum_reply_surb_age: Duration, - - /// Defines maximum amount of time given reply key is going to be valid for. - /// This is going to be superseded by key rotation once implemented. - #[serde(with = "humantime_serde")] - pub maximum_reply_key_age: Duration, - - /// Specifies the number of mixnet hops the packet should go through. If not specified, then - /// the default value is used. - pub surb_mix_hops: Option<u8>, -} - -impl Default for ReplySurbs { - fn default() -> Self { - ReplySurbs { - minimum_reply_surb_storage_threshold: DEFAULT_MINIMUM_REPLY_SURB_STORAGE_THRESHOLD, - maximum_reply_surb_storage_threshold: DEFAULT_MAXIMUM_REPLY_SURB_STORAGE_THRESHOLD, - minimum_reply_surb_request_size: DEFAULT_MINIMUM_REPLY_SURB_REQUEST_SIZE, - maximum_reply_surb_request_size: DEFAULT_MAXIMUM_REPLY_SURB_REQUEST_SIZE, - maximum_allowed_reply_surb_request_size: DEFAULT_MAXIMUM_ALLOWED_SURB_REQUEST_SIZE, - maximum_reply_surb_rerequest_waiting_period: - DEFAULT_MAXIMUM_REPLY_SURB_REREQUEST_WAITING_PERIOD, - maximum_reply_surb_drop_waiting_period: DEFAULT_MAXIMUM_REPLY_SURB_DROP_WAITING_PERIOD, - maximum_reply_surb_age: DEFAULT_MAXIMUM_REPLY_SURB_AGE, - maximum_reply_key_age: DEFAULT_MAXIMUM_REPLY_KEY_AGE, - surb_mix_hops: None, - } - } -} - -#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] -#[serde(default, deny_unknown_fields)] -pub struct DebugConfig { - /// Defines all configuration options related to traffic streams. - pub traffic: Traffic, - - /// Defines all configuration options related to cover traffic stream(s). - pub cover_traffic: CoverTraffic, - - /// Defines all configuration options related to the gateway connection. - pub gateway_connection: GatewayConnection, - - /// Defines all configuration options related to acknowledgements, such as delays or wait timeouts. - pub acknowledgements: Acknowledgements, - - /// Defines all configuration options related topology, such as refresh rates or timeouts. - pub topology: Topology, - - /// Defines all configuration options related to reply SURBs. - pub reply_surbs: ReplySurbs, -} - -impl DebugConfig { - pub fn validate(&self) -> bool { - // no other sections have explicit requirements (yet) - self.traffic.validate() - } -} - -// it could be derived, sure, but I'd rather have an explicit implementation in case we had to change -// something manually at some point -#[allow(clippy::derivable_impls)] -impl Default for DebugConfig { - fn default() -> Self { - DebugConfig { - traffic: Default::default(), - cover_traffic: Default::default(), - gateway_connection: Default::default(), - acknowledgements: Default::default(), - topology: Default::default(), - reply_surbs: Default::default(), - } - } -} +pub use nym_client_core_config_types::*; diff --git a/common/commands/Cargo.toml b/common/commands/Cargo.toml index 6c96a3f93d..d977b49121 100644 --- a/common/commands/Cargo.toml +++ b/common/commands/Cargo.toml @@ -17,7 +17,7 @@ csv = "1.3.0" cw-utils = { workspace = true } futures = { workspace = true } handlebars = "3.0.1" -humantime-serde = "1.0" +humantime-serde = { workspace = true } inquire = "0.6.2" k256 = { workspace = true, features = ["ecdsa", "sha256"] } log = { workspace = true } diff --git a/common/country-group/Cargo.toml b/common/country-group/Cargo.toml new file mode 100644 index 0000000000..ec96820852 --- /dev/null +++ b/common/country-group/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "nym-country-group" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +serde = { workspace = true, features = ["derive"] } +tracing.workspace = true diff --git a/common/country-group/src/lib.rs b/common/country-group/src/lib.rs new file mode 100644 index 0000000000..3e57ae7d21 --- /dev/null +++ b/common/country-group/src/lib.rs @@ -0,0 +1,158 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use serde::{Deserialize, Serialize}; +use std::fmt; +use tracing::info; + +#[derive(Copy, Clone, Hash, PartialEq, Eq, Serialize, Deserialize, Debug)] +pub enum CountryGroup { + Europe, + NorthAmerica, + SouthAmerica, + Oceania, + Asia, + Africa, + Unknown, +} + +impl CountryGroup { + // We map country codes into group, which initially are continent codes to a first approximation, + // but we do it manually to reserve the right to tweak this distribution for our purposes. + // NOTE: I did this quickly, and it's not a complete list of all countries, but only those that + // were present in the network at the time. Please add more as needed. + pub fn new(country_code: &str) -> Self { + let country_code = country_code.to_uppercase(); + use CountryGroup::*; + match country_code.as_ref() { + // Europe + "AT" => Europe, + "BG" => Europe, + "CH" => Europe, + "CY" => Europe, + "CZ" => Europe, + "DE" => Europe, + "DK" => Europe, + "ES" => Europe, + "FI" => Europe, + "FR" => Europe, + "GB" => Europe, + "GR" => Europe, + "IE" => Europe, + "IT" => Europe, + "LT" => Europe, + "LU" => Europe, + "LV" => Europe, + "MD" => Europe, + "MT" => Europe, + "NL" => Europe, + "NO" => Europe, + "PL" => Europe, + "RO" => Europe, + "SE" => Europe, + "SK" => Europe, + "TR" => Europe, + "UA" => Europe, + + // North America + "CA" => NorthAmerica, + "MX" => NorthAmerica, + "US" => NorthAmerica, + + // South America + "AR" => SouthAmerica, + "BR" => SouthAmerica, + "CL" => SouthAmerica, + "CO" => SouthAmerica, + "CR" => SouthAmerica, + "GT" => SouthAmerica, + + // Oceania + "AU" => Oceania, + + // Asia + "AM" => Asia, + "BH" => Asia, + "CN" => Asia, + "GE" => Asia, + "HK" => Asia, + "ID" => Asia, + "IL" => Asia, + "IN" => Asia, + "JP" => Asia, + "KH" => Asia, + "KR" => Asia, + "KZ" => Asia, + "MY" => Asia, + "RU" => Asia, + "SG" => Asia, + "TH" => Asia, + "VN" => Asia, + + // Africa + "SC" => Africa, + "UG" => Africa, + "ZA" => Africa, + + // And group level codes work too + "EU" => Europe, + "NA" => NorthAmerica, + "SA" => SouthAmerica, + "OC" => Oceania, + "AS" => Asia, + "AF" => Africa, + + // And some aliases + "EUROPE" => Europe, + "NORTHAMERICA" => NorthAmerica, + "SOUTHAMERICA" => SouthAmerica, + "OCEANIA" => Oceania, + "ASIA" => Asia, + "AFRICA" => Africa, + + _ => { + info!("Unknown country code: {country_code}"); + Unknown + } + } + } +} + +impl fmt::Display for CountryGroup { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + use CountryGroup::*; + match self { + Europe => write!(f, "EU"), + NorthAmerica => write!(f, "NA"), + SouthAmerica => write!(f, "SA"), + Oceania => write!(f, "OC"), + Asia => write!(f, "AS"), + Africa => write!(f, "AF"), + Unknown => write!(f, "Unknown"), + } + } +} + +impl std::str::FromStr for CountryGroup { + type Err = (); + + fn from_str(s: &str) -> Result<Self, Self::Err> { + let group = CountryGroup::new(s); + if group == CountryGroup::Unknown { + Err(()) + } else { + Ok(group) + } + } +} + +impl CountryGroup { + #[allow(unused)] + fn known(self) -> Option<CountryGroup> { + use CountryGroup::*; + match self { + Europe | NorthAmerica | SouthAmerica | Oceania | Asia | Africa => Some(self), + Unknown => None, + } + } +} diff --git a/common/crypto/src/asymmetric/identity/mod.rs b/common/crypto/src/asymmetric/identity/mod.rs index 7d1db5a8c1..a48fb78a82 100644 --- a/common/crypto/src/asymmetric/identity/mod.rs +++ b/common/crypto/src/asymmetric/identity/mod.rs @@ -10,6 +10,9 @@ use std::str::FromStr; use thiserror::Error; use zeroize::{Zeroize, ZeroizeOnDrop}; +#[cfg(feature = "serde")] +pub mod serde_helpers; + #[cfg(feature = "sphinx")] use nym_sphinx_types::{DestinationAddressBytes, DESTINATION_ADDRESS_LENGTH}; diff --git a/common/crypto/src/asymmetric/identity/serde_helpers.rs b/common/crypto/src/asymmetric/identity/serde_helpers.rs new file mode 100644 index 0000000000..67f9dece70 --- /dev/null +++ b/common/crypto/src/asymmetric/identity/serde_helpers.rs @@ -0,0 +1,18 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use super::PublicKey; + +pub mod bs58_pubkey { + use super::*; + use serde_crate::{Deserialize, Deserializer, Serializer}; + + pub fn serialize<S: Serializer>(key: &PublicKey, serializer: S) -> Result<S::Ok, S::Error> { + serializer.serialize_str(&key.to_base58_string()) + } + + pub fn deserialize<'de, D: Deserializer<'de>>(deserializer: D) -> Result<PublicKey, D::Error> { + let s = String::deserialize(deserializer)?; + PublicKey::from_base58_string(s).map_err(serde::de::Error::custom) + } +} diff --git a/common/crypto/src/asymmetric/mod.rs b/common/crypto/src/asymmetric/mod.rs index 6e8836809c..4f6b8eb4bf 100644 --- a/common/crypto/src/asymmetric/mod.rs +++ b/common/crypto/src/asymmetric/mod.rs @@ -3,3 +3,6 @@ pub mod encryption; pub mod identity; + +pub use encryption as x25519; +pub use identity as ed25519; diff --git a/common/dkg/src/bte/proof_chunking.rs b/common/dkg/src/bte/proof_chunking.rs index 27bc04894a..6829a53660 100644 --- a/common/dkg/src/bte/proof_chunking.rs +++ b/common/dkg/src/bte/proof_chunking.rs @@ -836,7 +836,7 @@ mod tests { let share3 = chunks3.clone().try_into().unwrap(); let shares = vec![share1, share2, share3]; - let chunks = &[chunks1, chunks2, chunks3]; + let chunks = [chunks1, chunks2, chunks3]; for (i, pk_i) in pks.iter().enumerate() { let mut ciphertext_chunk_i = Vec::with_capacity(NUM_CHUNKS); diff --git a/common/http-api-common/Cargo.toml b/common/http-api-common/Cargo.toml new file mode 100644 index 0000000000..5104b27d13 --- /dev/null +++ b/common/http-api-common/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "nym-http-api-common" +version = "0.1.0" +authors.workspace = true +repository.workspace = true +homepage.workspace = true +documentation.workspace = true +edition.workspace = true +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum.workspace = true +bytes = "1.5.0" +mime = "0.3.17" +serde = { workspace = true, features = ["derive"] } +serde_json.workspace = true +serde_yaml = "0.9.25" +utoipa = { workspace = true } diff --git a/nym-node/src/http/router/api/mod.rs b/common/http-api-common/src/lib.rs similarity index 80% rename from nym-node/src/http/router/api/mod.rs rename to common/http-api-common/src/lib.rs index 5e8a4160ca..83b9c685d8 100644 --- a/nym-node/src/http/router/api/mod.rs +++ b/common/http-api-common/src/lib.rs @@ -1,32 +1,13 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only +// SPDX-License-Identifier: Apache-2.0 use axum::http::{header, HeaderValue, StatusCode}; use axum::response::{IntoResponse, Response}; -use axum::{Json, Router}; +use axum::Json; use bytes::{BufMut, BytesMut}; use serde::{Deserialize, Serialize}; use utoipa::{IntoParams, ToSchema}; -pub mod v1; - -use crate::http::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; -use crate::http::state::AppState; -pub use nym_node_requests::api as api_requests; -use nym_node_requests::routes; - -#[derive(Debug, Clone)] -pub struct Config { - pub v1_config: v1::Config, -} - -pub(super) fn routes(config: Config, initial_wg_state: WireguardAppState) -> Router<AppState> { - Router::new().nest( - routes::api::V1, - v1::routes(config.v1_config, initial_wg_state), - ) -} - #[derive(Debug, Clone, ToSchema)] pub enum FormattedResponse<T> { Json(Json<T>), diff --git a/common/mixnode-common/Cargo.toml b/common/mixnode-common/Cargo.toml index 0ee39302e3..a19fc70332 100644 --- a/common/mixnode-common/Cargo.toml +++ b/common/mixnode-common/Cargo.toml @@ -10,11 +10,11 @@ license.workspace = true [dependencies] bytes = "1.0" futures = { workspace = true } -humantime-serde = "1.0" +humantime-serde = { workspace = true } log = { workspace = true } rand = "0.8" -serde = { version = "1.0", features = ["derive"] } -tokio = { version = "1.24.1", features = [ +serde = { workspace = true, features = ["derive"] } +tokio = { workspace = true, features = [ "time", "macros", "rt", @@ -23,6 +23,7 @@ tokio = { version = "1.24.1", features = [ ] } tokio-util = { workspace = true, features = ["codec"] } url = { workspace = true } +time.workspace = true thiserror = { workspace = true } nym-crypto = { path = "../crypto" } @@ -37,3 +38,4 @@ nym-task = { path = "../task" } nym-validator-client = { path = "../client-libs/validator-client" } nym-bin-common = { path = "../bin-common" } nym-metrics = { path = "../nym-metrics" } +nym-node-http-api = { path = "../../nym-node/nym-node-http-api" } \ No newline at end of file diff --git a/common/mixnode-common/src/verloc/measurement.rs b/common/mixnode-common/src/verloc/measurement.rs index 0e7d312f84..cacf72080a 100644 --- a/common/mixnode-common/src/verloc/measurement.rs +++ b/common/mixnode-common/src/verloc/measurement.rs @@ -1,259 +1,35 @@ -// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use nym_crypto::asymmetric::identity; -use serde::{Serialize, Serializer}; -use std::cmp::Ordering; -use std::fmt::{self, Display, Formatter}; -use std::sync::Arc; -use std::time::Duration; -use tokio::sync::RwLock; +use nym_node_http_api::state::metrics::{SharedVerlocStats, VerlocNodeResult}; +use std::mem; +use time::OffsetDateTime; -#[derive(Clone, Default)] -pub struct AtomicVerlocResult { - inner: Arc<RwLock<VerlocResult>>, +pub(crate) trait VerlocStatsUpdateExt { + async fn start_new_measurements(&self, nodes_to_test: usize); + + async fn append_measurement_results(&self, new_data: Vec<VerlocNodeResult>); + + async fn finish_measurements(&self); } -#[derive(Debug, Clone, Serialize, Default)] -pub struct VerlocResult { - total_tested: usize, - #[serde(with = "humantime_serde")] - run_started: Option<std::time::SystemTime>, - #[serde(with = "humantime_serde")] - run_finished: Option<std::time::SystemTime>, - results: Vec<Verloc>, -} - -impl AtomicVerlocResult { - pub(crate) fn new() -> Self { - AtomicVerlocResult { - inner: Arc::new(RwLock::new(VerlocResult { - total_tested: 0, - run_started: None, - run_finished: None, - results: Vec::new(), - })), - } +impl VerlocStatsUpdateExt for SharedVerlocStats { + async fn start_new_measurements(&self, nodes_to_test: usize) { + let mut guard = self.write().await; + guard.previous_run_data = mem::take(&mut guard.current_run_data); + guard.current_run_data.nodes_tested = nodes_to_test; } - pub(crate) async fn reset_results(&self, new_tested: usize) { - let mut write_permit = self.inner.write().await; - write_permit.total_tested = new_tested; - write_permit.run_started = Some(std::time::SystemTime::now()); - write_permit.run_finished = None; - write_permit.results = Vec::new() - } - - pub(crate) async fn append_results(&self, mut new_data: Vec<Verloc>) { - let mut write_permit = self.inner.write().await; - write_permit.results.append(&mut new_data); + async fn append_measurement_results(&self, mut new_data: Vec<VerlocNodeResult>) { + let mut write_permit = self.write().await; + write_permit.current_run_data.results.append(&mut new_data); // make sure the data always stays in order. // TODO: considering the front of the results is guaranteed to be sorted, should perhaps // a non-default sorting algorithm be used? - write_permit.results.sort() + write_permit.current_run_data.results.sort() } - pub(crate) async fn finish_measurements(&self) { - self.inner.write().await.run_finished = Some(std::time::SystemTime::now()); - } - - // Considering that on every read we will need to clone data regardless, let's make our - // lives simpler and clone it here rather than deal with lifetime of the permit - pub async fn clone_data(&self) -> VerlocResult { - self.inner.read().await.clone() - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize)] -pub struct Verloc { - #[serde(serialize_with = "serialize_identity_as_string")] - pub identity: identity::PublicKey, - pub latest_measurement: Option<Measurement>, -} - -fn serialize_identity_as_string<S>( - identity: &identity::PublicKey, - serializer: S, -) -> Result<S::Ok, S::Error> -where - S: Serializer, -{ - serializer.serialize_str(&identity.to_base58_string()) -} - -impl Display for Verloc { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - if let Some(measurement) = self.latest_measurement { - write!(f, "{} - {}", self.identity, measurement) - } else { - write!(f, "{} - COULD NOT MEASURE", self.identity) - } - } -} - -impl PartialOrd for Verloc { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for Verloc { - fn cmp(&self, other: &Self) -> Ordering { - // if both have measurement, compare measurements - // then if only one have measurement, prefer that one - // completely ignore identity as it makes no sense to order by it - if let Some(self_measurement) = &self.latest_measurement { - if let Some(other_measurement) = &other.latest_measurement { - self_measurement.cmp(other_measurement) - } else { - Ordering::Less - } - } else if other.latest_measurement.is_some() { - Ordering::Greater - } else { - Ordering::Equal - } - } -} - -impl Verloc { - pub(crate) fn new( - identity: identity::PublicKey, - latest_measurement: Option<Measurement>, - ) -> Self { - Verloc { - identity, - latest_measurement, - } - } -} - -#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize)] -pub struct Measurement { - #[serde(serialize_with = "humantime_serde::serialize")] - pub minimum: Duration, - #[serde(serialize_with = "humantime_serde::serialize")] - pub mean: Duration, - #[serde(serialize_with = "humantime_serde::serialize")] - pub maximum: Duration, - #[serde(serialize_with = "humantime_serde::serialize")] - pub standard_deviation: Duration, -} - -impl Measurement { - pub(crate) fn new(raw_results: &[Duration]) -> Self { - let minimum = *raw_results.iter().min().expect("didn't get any results!"); - let maximum = *raw_results.iter().max().expect("didn't get any results!"); - - let mean = Self::duration_mean(raw_results); - let standard_deviation = Self::duration_standard_deviation(raw_results, mean); - - Measurement { - minimum, - mean, - maximum, - standard_deviation, - } - } - - fn duration_mean(data: &[Duration]) -> Duration { - let sum = data.iter().sum::<Duration>(); - let count = data.len() as u32; - - sum / count - } - - fn duration_standard_deviation(data: &[Duration], mean: Duration) -> Duration { - let variance_micros = data - .iter() - .map(|&value| { - // make sure we don't underflow - let diff = if mean > value { - mean - value - } else { - value - mean - }; - // we don't need nanos precision - let diff_micros = diff.as_micros(); - diff_micros * diff_micros - }) - .sum::<u128>() - / data.len() as u128; - - // we shouldn't really overflow as our differences shouldn't be larger than couple seconds at the worst possible case scenario - let std_deviation_micros = (variance_micros as f64).sqrt() as u64; - Duration::from_micros(std_deviation_micros) - } -} - -impl Display for Measurement { - fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { - write!( - f, - "rtt min/avg/max/mdev = {:?} / {:?} / {:?} / {:?}", - self.minimum, self.mean, self.maximum, self.standard_deviation - ) - } -} - -impl PartialOrd for Measurement { - fn partial_cmp(&self, other: &Self) -> Option<Ordering> { - Some(self.cmp(other)) - } -} - -impl Ord for Measurement { - fn cmp(&self, other: &Self) -> Ordering { - // minimum value is most important, then look at standard deviation, then mean and finally maximum - let min_cmp = self.minimum.cmp(&other.minimum); - if min_cmp != Ordering::Equal { - return min_cmp; - } - let std_dev_cmp = self.standard_deviation.cmp(&other.standard_deviation); - if std_dev_cmp != Ordering::Equal { - return std_dev_cmp; - } - let std_dev_cmp = self.mean.cmp(&other.mean); - if std_dev_cmp != Ordering::Equal { - return std_dev_cmp; - } - self.maximum.cmp(&other.maximum) - } -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn sorting_vec_of_verlocs() { - let some_identity = - identity::PublicKey::from_base58_string("Be9wH7xuXBRJAuV1pC7MALZv6a61RvWQ3SypsNarqTt") - .unwrap(); - let no_measurement = Verloc::new(some_identity, None); - let low_min = Verloc::new( - some_identity, - Some(Measurement { - minimum: Duration::from_millis(42), - mean: Duration::from_millis(43), - maximum: Duration::from_millis(44), - standard_deviation: Duration::from_millis(45), - }), - ); - let higher_min = Verloc::new( - some_identity, - Some(Measurement { - minimum: Duration::from_millis(420), - mean: Duration::from_millis(430), - maximum: Duration::from_millis(440), - standard_deviation: Duration::from_millis(450), - }), - ); - - let mut vec_verloc = vec![no_measurement, low_min, no_measurement, higher_min]; - vec_verloc.sort(); - - let expected_sorted = vec![low_min, higher_min, no_measurement, no_measurement]; - assert_eq!(expected_sorted, vec_verloc); + async fn finish_measurements(&self) { + self.write().await.current_run_data.run_finished = Some(OffsetDateTime::now_utc()) } } diff --git a/common/mixnode-common/src/verloc/mod.rs b/common/mixnode-common/src/verloc/mod.rs index 8fa66e3445..25c7bd8881 100644 --- a/common/mixnode-common/src/verloc/mod.rs +++ b/common/mixnode-common/src/verloc/mod.rs @@ -1,4 +1,4 @@ -// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use crate::verloc::listener::PacketListener; @@ -9,6 +9,7 @@ use log::*; use nym_bin_common::version_checker::{self, parse_version}; use nym_crypto::asymmetric::identity; use nym_network_defaults::mainnet::NYM_API; +use nym_node_http_api::state::metrics::{SharedVerlocStats, VerlocNodeResult}; use nym_task::TaskClient; use rand::seq::SliceRandom; use rand::thread_rng; @@ -20,7 +21,9 @@ use tokio::task::JoinHandle; use tokio::time::sleep; use url::Url; -pub use crate::verloc::measurement::{AtomicVerlocResult, Verloc, VerlocResult}; +use measurement::VerlocStatsUpdateExt; + +// pub use crate::verloc::measurement::{AtomicVerlocResult, Verloc, VerlocResult}; pub mod error; pub(crate) mod listener; @@ -179,7 +182,7 @@ pub struct VerlocMeasurer { // then it definitely cannot be constructed here and probably will need to be passed from outside, // as mixnodes/gateways would already be using an instance of said client. validator_client: nym_validator_client::NymApiClient, - results: AtomicVerlocResult, + state: SharedVerlocStats, } impl VerlocMeasurer { @@ -210,10 +213,14 @@ impl VerlocMeasurer { config.nym_api_urls[0].clone(), ), config, - results: AtomicVerlocResult::new(), + state: SharedVerlocStats::default(), } } + pub fn set_shared_state(&mut self, state: SharedVerlocStats) { + self.state = state; + } + fn use_next_nym_api(&mut self) { if self.config.nym_api_urls.len() == 1 { warn!("There's only a single validator API available - it won't be possible to use a different one"); @@ -225,10 +232,6 @@ impl VerlocMeasurer { .change_nym_api(self.config.nym_api_urls[self.currently_used_api].clone()) } - pub fn get_verloc_results_pointer(&self) -> AtomicVerlocResult { - self.results.clone() - } - fn start_listening(&self) -> JoinHandle<()> { let packet_listener = Arc::clone(&self.packet_listener); tokio::spawn(packet_listener.run()) @@ -270,7 +273,7 @@ impl VerlocMeasurer { while !shutdown_listener.is_shutdown() { tokio::select! { measurement_result = measurement_chunk.next() => { - let Some(result) = measurement_result else { + let Some(result) = measurement_result else { // if the stream has finished, it means we got everything we could have gotten break }; @@ -278,18 +281,16 @@ impl VerlocMeasurer { // if we receive JoinError it means the task failed to get executed, so either there's a bigger issue with tokio // or there was a panic inside the task itself. In either case, we should just terminate ourselves. let execution_result = result.expect("the measurement task panicked!"); + let identity = execution_result.1; + let measurement_result = match execution_result.0 { Err(err) => { - debug!( - "Failed to perform measurement for {} - {}", - execution_result.1.to_base58_string(), - err - ); + debug!("Failed to perform measurement for {identity}: {err}"); None } Ok(result) => Some(result), }; - chunk_results.push(Verloc::new(execution_result.1, measurement_result)); + chunk_results.push(VerlocNodeResult::new(identity, measurement_result)); }, _ = shutdown_listener.recv() => { trace!("Shutdown received while measuring"); @@ -299,7 +300,7 @@ impl VerlocMeasurer { } // update the results vector with chunks as they become available (by default every 50 nodes) - self.results.append_results(chunk_results).await; + self.state.append_measurement_results(chunk_results).await; } MeasurementOutcome::Done @@ -358,7 +359,7 @@ impl VerlocMeasurer { .collect::<Vec<_>>(); // on start of each run remove old results - self.results.reset_results(tested_nodes.len()).await; + self.state.start_new_measurements(tested_nodes.len()).await; if let MeasurementOutcome::Shutdown = self.perform_measurement(tested_nodes).await { log::trace!("Shutting down after aborting measurements"); @@ -366,7 +367,7 @@ impl VerlocMeasurer { } // write current time to "run finished" field - self.results.finish_measurements().await; + self.state.finish_measurements().await; info!( "Finished performing verloc measurements. The next one will happen in {:?}", diff --git a/common/mixnode-common/src/verloc/sender.rs b/common/mixnode-common/src/verloc/sender.rs index 8940738bcf..1549af972f 100644 --- a/common/mixnode-common/src/verloc/sender.rs +++ b/common/mixnode-common/src/verloc/sender.rs @@ -1,11 +1,11 @@ -// Copyright 2021 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 use crate::verloc::error::RttError; -use crate::verloc::measurement::Measurement; use crate::verloc::packet::{EchoPacket, ReplyPacket}; use log::*; use nym_crypto::asymmetric::identity; +use nym_node_http_api::state::metrics::VerlocMeasurement; use nym_task::TaskClient; use rand::{thread_rng, Rng}; use std::net::SocketAddr; @@ -82,7 +82,7 @@ impl PacketSender { pub(super) async fn send_packets_to_node( self: Arc<Self>, tested_node: TestedNode, - ) -> Result<Measurement, RttError> { + ) -> Result<VerlocMeasurement, RttError> { let mut shutdown_listener = self.shutdown_listener.fork(tested_node.address.to_string()); shutdown_listener.mark_as_success(); @@ -208,6 +208,6 @@ impl PacketSender { sleep(self.delay_between_packets).await; } - Ok(Measurement::new(&results)) + Ok(VerlocMeasurement::new(&results)) } } diff --git a/common/nymsphinx/addressing/src/lib.rs b/common/nymsphinx/addressing/src/lib.rs index d30f0bde57..0d5e26b92a 100644 --- a/common/nymsphinx/addressing/src/lib.rs +++ b/common/nymsphinx/addressing/src/lib.rs @@ -3,3 +3,6 @@ pub mod clients; pub mod nodes; + +pub use clients::Recipient; +pub use nodes::NodeIdentity; diff --git a/common/task/src/manager.rs b/common/task/src/manager.rs index 5cd0254a79..523d22aae5 100644 --- a/common/task/src/manager.rs +++ b/common/task/src/manager.rs @@ -348,7 +348,7 @@ impl TaskClient { "unnamed-TaskClient".to_string() }; - log!(target: target, level, "{msg}") + log!(target: target, level, "{}", format!("[{target}] {msg}")) } #[must_use] diff --git a/common/topology/src/gateway.rs b/common/topology/src/gateway.rs index e8b61eedf6..60624796c6 100644 --- a/common/topology/src/gateway.rs +++ b/common/topology/src/gateway.rs @@ -205,10 +205,10 @@ impl<'a> TryFrom<&'a DescribedGateway> for Node { clients_ws_port: self_described.mixnet_websockets.ws_port, clients_wss_port: self_described.mixnet_websockets.wss_port, identity_key: identity::PublicKey::from_base58_string( - &self_described.host_information.keys.ed25519, + &self_described.host_information.keys.ed25519_identity, )?, sphinx_key: encryption::PublicKey::from_base58_string( - &self_described.host_information.keys.x25519, + &self_described.host_information.keys.x25519_sphinx, )?, version: self_described .build_information diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index f4c034c0d0..7eb2a26b58 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -10,7 +10,7 @@ license.workspace = true chrono = { version = "0.4.31", features = ["serde"] } clap = { workspace = true, features = ["cargo", "derive"] } dotenvy = { workspace = true } -humantime-serde = "1.0" +humantime-serde = { workspace = true } isocountry = "0.3.2" itertools = "0.10.3" log = { workspace = true } diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 01d1aaf9c8..4ec9d74844 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -18,7 +18,6 @@ rust-version = "1.70" [dependencies] anyhow = { workspace = true } async-trait = { workspace = true } -atty = "0.2" bip39 = { workspace = true } bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"] } @@ -27,11 +26,10 @@ dashmap = { workspace = true } dirs = "4.0" dotenvy = { workspace = true } futures = { workspace = true } -humantime-serde = "1.0.1" +humantime-serde = { workspace = true } ipnetwork = "0.16" log = { workspace = true } once_cell = "1.7.2" -pretty_env_logger = "0.4" rand = "0.7" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } @@ -51,14 +49,13 @@ tokio = { workspace = true, features = [ "time", ] } tokio-stream = { version = "0.1.11", features = ["fs"] } -tokio-tungstenite = { version = "0.20.1" } +tokio-tungstenite = { vworkspace = true } tokio-util = { workspace = true, features = ["codec"] } url = { workspace = true, features = ["serde"] } time = { workspace = true } zeroize = { workspace = true } # internal -nym-node = { path = "../nym-node" } nym-api-requests = { path = "../nym-api/nym-api-requests" } nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } @@ -71,6 +68,7 @@ nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } nym-mixnode-common = { path = "../common/mixnode-common" } nym-network-defaults = { path = "../common/network-defaults" } nym-network-requester = { path = "../service-providers/network-requester" } +nym-node-http-api = { path = "../nym-node/nym-node-http-api" } nym-pemstore = { path = "../common/pemstore" } nym-sphinx = { path = "../common/nymsphinx" } nym-statistics-common = { path = "../common/statistics" } @@ -80,15 +78,13 @@ nym-validator-client = { path = "../common/client-libs/validator-client" } nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } nym-wireguard = { path = "../common/wireguard", optional = true } +nym-wireguard-types = { path = "../common/wireguard-types", default-features = false } + defguard_wireguard_rs = { git = "https://github.com/neacsu/wireguard-rs.git", rev = "c2cd0c1119f699f4bc43f5e6ffd6fc242caa42ed", optional = true } -[dev-dependencies] -tower = "0.4.13" -rand = "0.8.5" -hyper = "0.14.27" [build-dependencies] -tokio = { version = "1.24.1", features = ["rt-multi-thread", "macros"] } +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } sqlx = { workspace = true, features = [ "runtime-tokio-rustls", "sqlite", diff --git a/gateway/src/commands/helpers.rs b/gateway/src/commands/helpers.rs index 2bd3f3834c..ff487dc7c2 100644 --- a/gateway/src/commands/helpers.rs +++ b/gateway/src/commands/helpers.rs @@ -2,20 +2,23 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::upgrade_helpers; -use crate::config::default_config_filepath; -use crate::config::persistence::paths::{ - default_ip_packet_router_data_dir, default_network_requester_data_dir, -}; -use crate::config::Config; -use crate::error::GatewayError; use log::{error, info}; -use nym_bin_common::version_checker; use nym_config::{save_formatted_config_to_file, OptionalSet}; use nym_crypto::asymmetric::identity; +use nym_gateway::config::default_config_filepath; +use nym_gateway::config::persistence::paths::{ + default_ip_packet_router_data_dir, default_network_requester_data_dir, +}; +use nym_gateway::config::Config; +use nym_gateway::error::GatewayError; +use nym_gateway::helpers::{ + override_ip_packet_router_config, override_network_requester_config, + OverrideIpPacketRouterConfig, OverrideNetworkRequesterConfig, +}; use nym_network_defaults::mainnet; use nym_network_defaults::var_names::NYXD; use nym_network_defaults::var_names::{BECH32_PREFIX, NYM_API, STATISTICS_SERVICE_DOMAIN_ADDRESS}; -use nym_network_requester::config::BaseClientConfig; + use nym_network_requester::{ generate_new_client_keys, set_active_gateway, setup_fs_gateways_storage, setup_gateway, GatewaySetup, OnDiskKeys, @@ -102,21 +105,11 @@ impl OverrideConfig { } } -#[derive(Default, Debug)] -pub(crate) struct OverrideNetworkRequesterConfig { - pub(crate) fastmode: bool, - pub(crate) no_cover: bool, - pub(crate) medium_toggle: bool, - - pub(crate) open_proxy: Option<bool>, - - pub(crate) enable_statistics: Option<bool>, - pub(crate) statistics_recipient: Option<String>, -} - -#[derive(Default, Debug)] -pub(crate) struct OverrideIpPacketRouterConfig { - // TODO +pub(crate) fn try_override_config<O: Into<OverrideConfig>>( + config: Config, + override_args: O, +) -> Result<Config, GatewayError> { + override_args.into().do_override(config) } /// Ensures that a given bech32 address is valid @@ -136,30 +129,6 @@ pub(crate) fn ensure_correct_bech32_prefix(address: &AccountId) -> Result<(), Ga Ok(()) } -// this only checks compatibility between config the binary. It does not take into consideration -// network version. It might do so in the future. -pub(crate) fn ensure_config_version_compatibility(cfg: &Config) -> Result<(), GatewayError> { - let binary_version = env!("CARGO_PKG_VERSION"); - let config_version = &cfg.gateway.version; - - if binary_version == config_version { - Ok(()) - } else if version_checker::is_minor_version_compatible(binary_version, config_version) { - log::warn!( - "The gateway binary has different version than what is specified in config file! {binary_version} and {config_version}. \ - But, they are still semver compatible. However, consider running the `upgrade` command."); - Ok(()) - } else { - log::error!( - "The gateway binary has different version than what is specified in config file! {binary_version} and {config_version}. \ - And they are semver incompatible! - please run the `upgrade` command before attempting `run` again"); - Err(GatewayError::LocalVersionCheckFailure { - binary_version: binary_version.to_owned(), - config_version: config_version.to_owned(), - }) - } -} - pub(crate) fn try_load_current_config(id: &str) -> Result<Config, GatewayError> { upgrade_helpers::try_upgrade_config(id)?; @@ -183,77 +152,6 @@ fn make_ip_id(gateway_id: &str) -> String { format!("{gateway_id}-ip-packet-router") } -// NOTE: make sure this is in sync with service-providers/network-requester/src/cli/mod.rs::override_config -pub(crate) fn override_network_requester_config( - mut cfg: nym_network_requester::Config, - opts: Option<OverrideNetworkRequesterConfig>, -) -> nym_network_requester::Config { - let Some(opts) = opts else { return cfg }; - - // as of 12.09.23 the below is true (not sure how this comment will rot in the future) - // medium_toggle: - // - sets secondary packet size to 16kb - // - disables poisson distribution of the main traffic stream - // - sets the cover traffic stream to 1 packet / 5s (on average) - // - disables per hop delay - // - // fastmode (to be renamed to `fast-poisson`): - // - sets average per hop delay to 10ms - // - sets the cover traffic stream to 1 packet / 2000s (on average); for all intents and purposes it disables the stream - // - sets the poisson distribution of the main traffic stream to 4ms, i.e. 250 packets / s on average - // - // no_cover: - // - disables poisson distribution of the main traffic stream - // - disables the secondary cover traffic stream - - // disable poisson rate in the BASE client if the NR option is enabled - if cfg.network_requester.disable_poisson_rate { - cfg.set_no_poisson_process(); - } - - // those should be enforced by `clap` when parsing the arguments - if opts.medium_toggle { - assert!(!opts.fastmode); - assert!(!opts.no_cover); - - cfg.set_medium_toggle(); - } - - cfg.with_base( - BaseClientConfig::with_high_default_traffic_volume, - opts.fastmode, - ) - .with_base(BaseClientConfig::with_disabled_cover_traffic, opts.no_cover) - .with_optional( - nym_network_requester::Config::with_open_proxy, - opts.open_proxy, - ) - .with_optional( - nym_network_requester::Config::with_enabled_statistics, - opts.enable_statistics, - ) - .with_optional( - nym_network_requester::Config::with_statistics_recipient, - opts.statistics_recipient, - ) -} - -// NOTE: make sure this is in sync with service-providers/ip-packet-router/src/cli/mod.rs::override_config -pub(crate) fn override_ip_packet_router_config( - mut cfg: nym_ip_packet_router::Config, - opts: Option<OverrideIpPacketRouterConfig>, -) -> nym_ip_packet_router::Config { - let Some(_opts) = opts else { return cfg }; - - // disable poisson rate in the BASE client if the IPR option is enabled - if cfg.ip_packet_router.disable_poisson_rate { - info!("Disabling poisson rate for ip packet router"); - cfg.set_no_poisson_process(); - } - - cfg -} - pub(crate) async fn initialise_local_network_requester( gateway_config: &Config, opts: OverrideNetworkRequesterConfig, diff --git a/gateway/src/commands/init.rs b/gateway/src/commands/init.rs index b2be9129d4..4c43236b7b 100644 --- a/gateway/src/commands/init.rs +++ b/gateway/src/commands/init.rs @@ -1,326 +1,22 @@ -// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2020-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::commands::helpers::{ - initialise_local_ip_packet_router, initialise_local_network_requester, - OverrideNetworkRequesterConfig, -}; -use crate::config::{default_config_directory, default_config_filepath, default_data_directory}; -use crate::node::helpers::node_details; -use crate::{commands::helpers::OverrideConfig, config::Config, OutputFormat}; use anyhow::bail; use clap::Args; -use nym_crypto::asymmetric::{encryption, identity}; -use std::net::IpAddr; -use std::path::PathBuf; -use std::{fs, io}; - -use super::helpers::OverrideIpPacketRouterConfig; +use colored::Colorize; +#[allow(dead_code)] #[derive(Args, Clone, Debug)] pub struct Init { /// Id of the gateway we want to create config for #[clap(long)] - id: String, - - /// The listening address on which the gateway will be receiving sphinx packets and listening for client data - #[clap(long, alias = "host")] - listening_address: IpAddr, - - /// Comma separated list of public ip addresses that will announced to the nym-api and subsequently to the clients. - /// In nearly all circumstances, it's going to be identical to the address you're going to use for bonding. - #[clap(long, value_delimiter = ',')] - public_ips: Option<Vec<IpAddr>>, - - /// Optional hostname associated with this gateway that will announced to the nym-api and subsequently to the clients - #[clap(long)] - hostname: Option<String>, - - /// The port on which the gateway will be listening for sphinx packets - #[clap(long)] - mix_port: Option<u16>, - - /// The port on which the gateway will be listening for clients gateway-requests - #[clap(long)] - clients_port: Option<u16>, - - /// Path to sqlite database containing all gateway persistent data - #[clap(long)] - datastore: Option<PathBuf>, - - /// Comma separated list of endpoints of nym APIs - #[clap(long, alias = "validator_apis", value_delimiter = ',')] - // the alias here is included for backwards compatibility (1.1.4 and before) - nym_apis: Option<Vec<url::Url>>, - - /// Comma separated list of endpoints of the validator - #[clap( - long, - alias = "validators", - alias = "nyxd_validators", - value_delimiter = ',', - hide = true - )] - // the alias here is included for backwards compatibility (1.1.4 and before) - nyxd_urls: Option<Vec<url::Url>>, - - /// Cosmos wallet mnemonic needed for double spending protection - #[clap(long)] - mnemonic: Option<bip39::Mnemonic>, - - /// Set this gateway to work only with coconut credentials; that would disallow clients to - /// bypass bandwidth credential requirement - #[clap(long, hide = true)] - only_coconut_credentials: Option<bool>, - - /// Enable/disable gateway anonymized statistics that get sent to a statistics aggregator server - #[clap(long)] - enabled_statistics: Option<bool>, - - /// URL where a statistics aggregator is running. The default value is a Nym aggregator server - #[clap(long)] - statistics_service_url: Option<url::Url>, - - /// Allows this gateway to run an embedded network requester for minimal network overhead - #[clap(long)] - with_network_requester: bool, - - /// Allows this gateway to run an embedded network requester for minimal network overhead - #[clap(long, hide = true)] - with_ip_packet_router: bool, - - // ##### NETWORK REQUESTER FLAGS ##### - /// Specifies whether this network requester should run in 'open-proxy' mode - #[clap(long, requires = "with_network_requester")] - open_proxy: Option<bool>, - - /// Enable service anonymized statistics that get sent to a statistics aggregator server - #[clap(long, requires = "with_network_requester")] - enable_statistics: Option<bool>, - - /// Mixnet client address where a statistics aggregator is running. The default value is a Nym - /// aggregator client - #[clap(long, requires = "with_network_requester")] - statistics_recipient: Option<String>, - - /// Mostly debug-related option to increase default traffic rate so that you would not need to - /// modify config post init - #[clap( - long, - hide = true, - conflicts_with = "medium_toggle", - requires = "with_network_requester" - )] - fastmode: bool, - - /// Disable loop cover traffic and the Poisson rate limiter (for debugging only) - #[clap( - long, - hide = true, - conflicts_with = "medium_toggle", - requires = "with_network_requester" - )] - no_cover: bool, - - /// Enable medium mixnet traffic, for experiments only. - /// This includes things like disabling cover traffic, no per hop delays, etc. - #[clap( - long, - hide = true, - conflicts_with = "no_cover", - conflicts_with = "fastmode", - requires = "with_network_requester" - )] - medium_toggle: bool, - - #[clap(short, long, default_value_t = OutputFormat::default())] - output: OutputFormat, + id: Option<String>, } -impl From<Init> for OverrideConfig { - fn from(init_config: Init) -> Self { - OverrideConfig { - listening_address: Some(init_config.listening_address), - public_ips: init_config.public_ips, - hostname: init_config.hostname, - mix_port: init_config.mix_port, - clients_port: init_config.clients_port, - datastore: init_config.datastore, - nym_apis: init_config.nym_apis, - mnemonic: init_config.mnemonic, - - enabled_statistics: init_config.enabled_statistics, - statistics_service_url: init_config.statistics_service_url, - - nyxd_urls: init_config.nyxd_urls, - only_coconut_credentials: init_config.only_coconut_credentials, - with_network_requester: Some(init_config.with_network_requester), - with_ip_packet_router: Some(init_config.with_ip_packet_router), - } - } -} - -impl<'a> From<&'a Init> for OverrideNetworkRequesterConfig { - fn from(value: &'a Init) -> Self { - OverrideNetworkRequesterConfig { - fastmode: value.fastmode, - no_cover: value.no_cover, - medium_toggle: value.medium_toggle, - open_proxy: value.open_proxy, - enable_statistics: value.enable_statistics, - statistics_recipient: value.statistics_recipient.clone(), - } - } -} - -impl From<&Init> for OverrideIpPacketRouterConfig { - fn from(_value: &Init) -> Self { - OverrideIpPacketRouterConfig {} - } -} - -fn init_paths(id: &str) -> io::Result<()> { - fs::create_dir_all(default_data_directory(id))?; - fs::create_dir_all(default_config_directory(id)) -} - -pub async fn execute(args: Init) -> anyhow::Result<()> { - eprintln!("Initialising gateway {}...", args.id); - let output = args.output; - - let already_init = if default_config_filepath(&args.id).exists() { - eprintln!( - "Gateway \"{}\" was already initialised before! Config information will be \ - overwritten (but keys will be kept)!", - args.id - ); - true - } else { - init_paths(&args.id)?; - false - }; - - // Initialising the config structure is just overriding a default constructed one - let fresh_config = Config::new(&args.id); - let nr_opts = (&args).into(); - let ip_opts = (&args).into(); - let mut config = OverrideConfig::from(args).do_override(fresh_config)?; - - // if gateway was already initialised, don't generate new keys, et al. - if !already_init { - let mut rng = rand::rngs::OsRng; - - let identity_keys = identity::KeyPair::new(&mut rng); - let sphinx_keys = encryption::KeyPair::new(&mut rng); - - if let Err(err) = nym_pemstore::store_keypair( - &identity_keys, - &nym_pemstore::KeyPairPath::new( - config.storage_paths.private_identity_key(), - config.storage_paths.public_identity_key(), - ), - ) { - bail!("failed to save the identity keys: {err}") - } - - if let Err(err) = nym_pemstore::store_keypair( - &sphinx_keys, - &nym_pemstore::KeyPairPath::new( - config.storage_paths.private_encryption_key(), - config.storage_paths.public_encryption_key(), - ), - ) { - bail!("failed to save the sphinx keys: {err}") - } - - if config.network_requester.enabled { - initialise_local_network_requester(&config, nr_opts, *identity_keys.public_key()) - .await?; - } - - if config.ip_packet_router.enabled { - initialise_local_ip_packet_router(&config, ip_opts, *identity_keys.public_key()) - .await?; - } - - eprintln!("Saved identity and mixnet sphinx keypairs"); - } - - let config_save_location = config.default_location(); - if let Err(err) = config.save_to_default_location() { - bail!("failed to save the config file: {err}") - } - config.save_path = Some(config_save_location.clone()); - - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); - eprintln!("Gateway configuration completed.\n\n\n"); - - output.to_stdout(&node_details(&config).await?); - - Ok(()) -} - -#[cfg(test)] -mod tests { - use nym_network_defaults::var_names::BECH32_PREFIX; - - use crate::node::{storage::InMemStorage, Gateway}; - - use super::*; - - #[tokio::test] - async fn create_gateway_with_in_mem_storage() { - let args = Init { - id: "foo-id".to_string(), - listening_address: "1.1.1.1".parse().unwrap(), - public_ips: None, - hostname: None, - mix_port: Some(42), - clients_port: Some(43), - datastore: Some("/foo-datastore".parse().unwrap()), - nym_apis: None, - mnemonic: None, - statistics_service_url: None, - enabled_statistics: None, - nyxd_urls: None, - only_coconut_credentials: None, - output: Default::default(), - with_network_requester: false, - with_ip_packet_router: false, - open_proxy: None, - enable_statistics: None, - statistics_recipient: None, - fastmode: false, - no_cover: false, - medium_toggle: false, - }; - std::env::set_var(BECH32_PREFIX, "n"); - - let fresh_config = Config::new(&args.id); - let config = OverrideConfig::from(args) - .do_override(fresh_config) - .unwrap(); - - let (identity_keys, sphinx_keys) = { - let mut rng = rand::rngs::OsRng; - ( - identity::KeyPair::new(&mut rng), - encryption::KeyPair::new(&mut rng), - ) - }; - - // The test is really if this instantiates with InMemStorage without panics - let _gateway = Gateway::new_from_keys_and_storage( - config, - None, - None, - identity_keys, - sphinx_keys, - InMemStorage, - ) - .await; - } +pub async fn execute(_args: Init) -> anyhow::Result<()> { + bail!( + "standalone mixnode initialisation has been removed - please initialise a `nym-node` instead" + .red() + .bold() + ) } diff --git a/gateway/src/commands/mod.rs b/gateway/src/commands/mod.rs index 4f9d46d7df..3cd84a1c0a 100644 --- a/gateway/src/commands/mod.rs +++ b/gateway/src/commands/mod.rs @@ -4,7 +4,10 @@ use crate::Cli; use clap::CommandFactory; use clap::Subcommand; +use log::warn; use nym_bin_common::completions::{fig_generate, ArgShell}; +use std::io::IsTerminal; +use std::time::Duration; pub(crate) mod build_info; pub(crate) mod helpers; @@ -25,7 +28,7 @@ pub(crate) enum Commands { NodeDetails(node_details::NodeDetails), /// Starts the gateway - Run(run::Run), + Run(Box<run::Run>), /// Add network requester support to this gateway // essentially an option to include NR without having to setup fresh gateway @@ -52,10 +55,17 @@ pub(crate) enum Commands { pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { let bin_name = "nym-gateway"; + warn!("standalone gateways have been deprecated - please consider migrating it to a `nym-node` via `nym-node migrate gateway` command"); + if std::io::stdout().is_terminal() { + // if user is running it in terminal session, + // introduce the delay, so they'd notice the message + tokio::time::sleep(Duration::from_secs(1)).await + } + match args.command { Commands::Init(m) => init::execute(m).await?, Commands::NodeDetails(m) => node_details::execute(m).await?, - Commands::Run(m) => run::execute(m).await?, + Commands::Run(m) => run::execute(*m).await?, Commands::SetupNetworkRequester(m) => setup_network_requester::execute(m).await?, Commands::SetupIpPacketRouter(m) => setup_ip_packet_router::execute(m).await?, Commands::Sign(m) => sign::execute(m)?, diff --git a/gateway/src/commands/node_details.rs b/gateway/src/commands/node_details.rs index 72840a8a7a..6bf2f6f330 100644 --- a/gateway/src/commands/node_details.rs +++ b/gateway/src/commands/node_details.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::helpers::try_load_current_config; -use crate::node::helpers::node_details; use clap::Args; use nym_bin_common::output_format::OutputFormat; +use nym_gateway::helpers::node_details; #[derive(Args, Clone)] pub struct NodeDetails { diff --git a/gateway/src/commands/run.rs b/gateway/src/commands/run.rs index bc52ff056e..547045ebb7 100644 --- a/gateway/src/commands/run.rs +++ b/gateway/src/commands/run.rs @@ -1,22 +1,17 @@ // Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::commands::helpers::{ - ensure_config_version_compatibility, OverrideConfig, OverrideNetworkRequesterConfig, -}; -use crate::node::helpers::node_details; -use crate::support::config::build_config; +use crate::commands::helpers::{try_load_current_config, try_override_config, OverrideConfig}; use anyhow::bail; use clap::Args; use log::warn; use nym_bin_common::output_format::OutputFormat; use nym_config::helpers::SPECIAL_ADDRESSES; -use nym_node::error::NymNodeError; +use nym_gateway::helpers::{OverrideIpPacketRouterConfig, OverrideNetworkRequesterConfig}; +use nym_gateway::GatewayError; use std::net::IpAddr; use std::path::PathBuf; -use super::helpers::OverrideIpPacketRouterConfig; - #[derive(Args, Clone)] pub struct Run { /// Id of the gateway we want to run @@ -27,12 +22,12 @@ pub struct Run { #[arg(long, alias = "host")] listening_address: Option<IpAddr>, - /// Comma separated list of public ip addresses that will announced to the nym-api and subsequently to the clients. + /// Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. /// In nearly all circumstances, it's going to be identical to the address you're going to use for bonding. #[arg(long, value_delimiter = ',')] public_ips: Option<Vec<IpAddr>>, - /// Optional hostname associated with this gateway that will announced to the nym-api and subsequently to the clients + /// Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients #[arg(long)] hostname: Option<String>, @@ -196,7 +191,7 @@ fn check_public_ips(ips: &[IpAddr], local: bool) -> anyhow::Result<()> { for ip in ips { if SPECIAL_ADDRESSES.contains(ip) { if !local { - return Err(NymNodeError::InvalidPublicIp { address: *ip }.into()); + return Err(GatewayError::InvalidPublicIp { address: *ip }.into()); } suspicious_ip.push(ip); } @@ -225,12 +220,12 @@ pub async fn execute(args: Run) -> anyhow::Result<()> { let nr_opts = (&args).into(); let ip_opts = (&args).into(); - let config = build_config(id, args)?; - ensure_config_version_compatibility(&config)?; + let mut config = try_load_current_config(&args.id)?; + config = try_override_config(config, args)?; let public_ips = &config.host.public_ips; if public_ips.is_empty() { - return Err(NymNodeError::NoPublicIps.into()); + return Err(GatewayError::NoPublicIps.into()); } check_public_ips(public_ips, local)?; if config.gateway.clients_wss_port.is_some() && config.host.hostname.is_none() { @@ -241,13 +236,14 @@ pub async fn execute(args: Run) -> anyhow::Result<()> { show_binding_warning(config.gateway.listening_address); } - let node_details = node_details(&config).await?; let gateway = - crate::node::create_gateway(config, Some(nr_opts), Some(ip_opts), custom_mixnet).await?; + nym_gateway::create_gateway(config, Some(nr_opts), Some(ip_opts), custom_mixnet).await?; + let node_details = gateway.node_details().await?; eprintln!( "\nTo bond your gateway you will need to install the Nym wallet, go to https://nymtech.net/get-involved and select the Download button.\n\ Select the correct version and install it to your machine. You will need to provide some of the following: \n "); output.to_stdout(&node_details); - gateway.run().await + gateway.run().await?; + Ok(()) } diff --git a/gateway/src/commands/setup_ip_packet_router.rs b/gateway/src/commands/setup_ip_packet_router.rs index a08f94dea3..5f22e794e4 100644 --- a/gateway/src/commands/setup_ip_packet_router.rs +++ b/gateway/src/commands/setup_ip_packet_router.rs @@ -1,12 +1,10 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::commands::helpers::{ - initialise_local_ip_packet_router, try_load_current_config, OverrideIpPacketRouterConfig, -}; -use crate::node::helpers::load_public_key; +use crate::commands::helpers::{initialise_local_ip_packet_router, try_load_current_config}; use clap::Args; use nym_bin_common::output_format::OutputFormat; +use nym_gateway::helpers::{load_public_key, OverrideIpPacketRouterConfig}; use std::path::PathBuf; #[derive(Args, Clone)] diff --git a/gateway/src/commands/setup_network_requester.rs b/gateway/src/commands/setup_network_requester.rs index b9368ce2e0..ef87889139 100644 --- a/gateway/src/commands/setup_network_requester.rs +++ b/gateway/src/commands/setup_network_requester.rs @@ -1,13 +1,14 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::commands::helpers::{ - initialise_local_network_requester, try_load_current_config, OverrideNetworkRequesterConfig, -}; -use crate::node::helpers::load_public_key; +use crate::commands::helpers::{initialise_local_network_requester, try_load_current_config}; use clap::Args; +use log::warn; use nym_bin_common::output_format::OutputFormat; +use nym_gateway::helpers::{load_public_key, OverrideNetworkRequesterConfig}; +use std::io::IsTerminal; use std::path::PathBuf; +use std::time::Duration; #[derive(Args, Clone)] pub struct CmdArgs { @@ -77,6 +78,13 @@ impl<'a> From<&'a CmdArgs> for OverrideNetworkRequesterConfig { } pub async fn execute(args: CmdArgs) -> anyhow::Result<()> { + warn!("standalone gateways have been deprecated - please consider migrating it to a `nym-node` via `nym-node migrate gateway` command"); + if std::io::stdout().is_terminal() { + // if user is running it in terminal session, + // introduce the delay, so they'd notice the message + tokio::time::sleep(Duration::from_secs(1)).await + } + let mut config = try_load_current_config(&args.id)?; let opts = (&args).into(); diff --git a/gateway/src/commands/sign.rs b/gateway/src/commands/sign.rs index 552315614c..4aa5e16d1f 100644 --- a/gateway/src/commands/sign.rs +++ b/gateway/src/commands/sign.rs @@ -2,15 +2,14 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::helpers::{ - ensure_config_version_compatibility, ensure_correct_bech32_prefix, OverrideConfig, + ensure_correct_bech32_prefix, try_load_current_config, try_override_config, OverrideConfig, }; -use crate::error::GatewayError; -use crate::node::helpers::load_identity_keys; -use crate::support::config::build_config; use anyhow::{bail, Result}; use clap::{ArgGroup, Args}; use nym_bin_common::output_format::OutputFormat; use nym_crypto::asymmetric::identity; +use nym_gateway::error::GatewayError; +use nym_gateway::helpers::load_identity_keys; use nym_types::helpers::ConsoleSigningOutput; use nym_validator_client::nyxd; @@ -120,8 +119,8 @@ fn print_signed_contract_msg( } pub fn execute(args: Sign) -> anyhow::Result<()> { - let config = build_config(args.id.clone(), OverrideConfig::default())?; - ensure_config_version_compatibility(&config)?; + let mut config = try_load_current_config(&args.id)?; + config = try_override_config(config, OverrideConfig::default())?; let output = args.output; let signed_target = SignedTarget::try_from(args)?; diff --git a/gateway/src/commands/upgrade_helpers.rs b/gateway/src/commands/upgrade_helpers.rs index f93350caaa..2de3e6ec32 100644 --- a/gateway/src/commands/upgrade_helpers.rs +++ b/gateway/src/commands/upgrade_helpers.rs @@ -1,13 +1,13 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::old_config_v1_1_20::ConfigV1_1_20; -use crate::config::old_config_v1_1_28::ConfigV1_1_28; -use crate::config::old_config_v1_1_29::ConfigV1_1_29; -use crate::config::old_config_v1_1_31::ConfigV1_1_31; -use crate::config::{default_config_filepath, Config}; -use crate::error::GatewayError; use log::info; +use nym_gateway::config::old_config_v1_1_20::ConfigV1_1_20; +use nym_gateway::config::old_config_v1_1_28::ConfigV1_1_28; +use nym_gateway::config::old_config_v1_1_29::ConfigV1_1_29; +use nym_gateway::config::old_config_v1_1_31::ConfigV1_1_31; +use nym_gateway::config::{default_config_filepath, Config}; +use nym_gateway::error::GatewayError; fn try_upgrade_v1_1_20_config(id: &str) -> Result<bool, GatewayError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; diff --git a/gateway/src/config/mod.rs b/gateway/src/config/mod.rs index b872a1dffd..5a345279d1 100644 --- a/gateway/src/config/mod.rs +++ b/gateway/src/config/mod.rs @@ -1,30 +1,31 @@ // Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::persistence::paths::GatewayPaths; use crate::config::template::CONFIG_TEMPLATE; use log::{debug, warn}; use nym_bin_common::logging::LoggingSettings; use nym_config::defaults::{DEFAULT_CLIENT_LISTENING_PORT, DEFAULT_MIX_LISTENING_PORT}; use nym_config::helpers::inaddr_any; +use nym_config::serde_helpers::{de_maybe_port, de_maybe_stringified}; use nym_config::{ must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, }; -use nym_network_defaults::mainnet; -use nym_node::config; -use serde::{Deserialize, Deserializer, Serialize}; +use nym_network_defaults::{mainnet, DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT}; +use serde::{Deserialize, Serialize}; use std::io; -use std::net::{IpAddr, SocketAddr}; +use std::net::{IpAddr, Ipv4Addr, SocketAddr}; use std::path::{Path, PathBuf}; use std::time::Duration; use url::Url; use zeroize::{Zeroize, ZeroizeOnDrop}; -pub(crate) mod old_config_v1_1_20; -pub(crate) mod old_config_v1_1_28; -pub(crate) mod old_config_v1_1_29; -pub(crate) mod old_config_v1_1_31; +pub use crate::config::persistence::paths::{GatewayPaths, WireguardPaths}; + +pub mod old_config_v1_1_20; +pub mod old_config_v1_1_28; +pub mod old_config_v1_1_29; +pub mod old_config_v1_1_31; pub mod persistence; mod template; @@ -41,18 +42,6 @@ const DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE: usize = 2000; const DEFAULT_STORED_MESSAGE_FILENAME_LENGTH: u16 = 16; const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: i64 = 100; -fn de_maybe_port<'de, D>(deserializer: D) -> Result<Option<u16>, D::Error> -where - D: Deserializer<'de>, -{ - let port = u16::deserialize(deserializer)?; - if port == 0 { - Ok(None) - } else { - Ok(Some(port)) - } -} - /// Derive default path to gateway's config directory. /// It should get resolved to `$HOME/.nym/gateways/<id>/config` pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf { @@ -86,16 +75,16 @@ pub struct Config { #[serde(skip)] pub(crate) save_path: Option<PathBuf>, - pub host: config::Host, + pub host: Host, #[serde(default)] - pub http: config::Http, + pub http: Http, pub gateway: Gateway, - #[serde(default)] // currently not really used for anything useful - pub wireguard: config::Wireguard, + #[serde(default)] + pub wireguard: Wireguard, pub storage_paths: GatewayPaths, @@ -122,7 +111,7 @@ impl Config { let default_gateway = Gateway::new_default(id.as_ref()); Config { save_path: None, - host: config::Host { + host: Host { // this is a very bad default! public_ips: vec![default_gateway.listening_address], hostname: None, @@ -138,6 +127,32 @@ impl Config { } } + #[allow(clippy::too_many_arguments)] + pub fn externally_loaded( + host: impl Into<Host>, + http: impl Into<Http>, + gateway: impl Into<Gateway>, + wireguard: impl Into<Wireguard>, + storage_paths: impl Into<GatewayPaths>, + network_requester: impl Into<NetworkRequester>, + ip_packet_router: impl Into<IpPacketRouter>, + logging: impl Into<LoggingSettings>, + debug: impl Into<Debug>, + ) -> Self { + Config { + save_path: None, + host: host.into(), + http: http.into(), + gateway: gateway.into(), + wireguard: wireguard.into(), + storage_paths: storage_paths.into(), + network_requester: network_requester.into(), + ip_packet_router: ip_packet_router.into(), + logging: logging.into(), + debug: debug.into(), + } + } + // simple wrapper that reads config file and assigns path location fn read_from_path<P: AsRef<Path>>(path: P) -> io::Result<Self> { let path = path.as_ref(); @@ -147,9 +162,6 @@ impl Config { Ok(loaded) } - // currently this is dead code, but once we allow loading configs from custom paths - // well, we will have to be using it - #[allow(dead_code)] pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { Self::read_from_path(path) } @@ -285,6 +297,87 @@ impl Config { } } +// TODO: this is very much a WIP. we need proper ssl certificate support here +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Host { + /// Ip address(es) of this host, such as 1.1.1.1 that external clients will use for connections. + pub public_ips: Vec<IpAddr>, + + /// Optional hostname of this node, for example nymtech.net. + // TODO: this is temporary. to be replaced by pulling the data directly from the certs. + #[serde(deserialize_with = "de_maybe_stringified")] + pub hostname: Option<String>, +} + +impl Host { + pub fn validate(&self) -> bool { + if self.public_ips.is_empty() { + return false; + } + + true + } +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Http { + /// Socket address this node will use for binding its http API. + /// default: `0.0.0.0:8000` + pub bind_address: SocketAddr, + + /// Path to assets directory of custom landing page of this node. + #[serde(deserialize_with = "de_maybe_stringified")] + pub landing_page_assets_path: Option<PathBuf>, +} + +impl Default for Http { + fn default() -> Self { + Http { + bind_address: SocketAddr::new( + IpAddr::V4(Ipv4Addr::UNSPECIFIED), + DEFAULT_NYM_NODE_HTTP_PORT, + ), + landing_page_assets_path: None, + } + } +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Wireguard { + /// Specifies whether the wireguard service is enabled on this node. + pub enabled: bool, + + /// Socket address this node will use for binding its wireguard interface. + /// default: `0.0.0.0:51822` + pub bind_address: SocketAddr, + + /// Port announced to external clients wishing to connect to the wireguard interface. + /// Useful in the instances where the node is behind a proxy. + pub announced_port: u16, + + /// The prefix denoting the maximum number of the clients that can be connected via Wireguard. + /// The maximum value for IPv4 is 32 and for IPv6 is 128 + pub private_network_prefix: u8, + + /// Paths for wireguard keys, client registries, etc. + pub storage_paths: WireguardPaths, +} + +impl Default for Wireguard { + fn default() -> Self { + Wireguard { + enabled: false, + bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT), + announced_port: WG_PORT, + private_network_prefix: 16, + storage_paths: WireguardPaths {}, + } + } +} + // we only really care about the mnemonic being zeroized #[derive(Debug, Deserialize, PartialEq, Eq, Serialize, Zeroize, ZeroizeOnDrop)] pub struct Gateway { @@ -413,9 +506,11 @@ pub struct Debug { /// Delay between each subsequent presence data being sent. #[serde(with = "humantime_serde")] + // DEAD FIELD pub presence_sending_delay: Duration, /// Length of filenames for new client messages. + // DEAD FIELD pub stored_messages_filename_length: u16, /// Number of messages from offline client that can be pulled at once from the storage. diff --git a/gateway/src/config/old_config_v1_1_29.rs b/gateway/src/config/old_config_v1_1_29.rs index 48ca3d14fb..e3fd44a8c9 100644 --- a/gateway/src/config/old_config_v1_1_29.rs +++ b/gateway/src/config/old_config_v1_1_29.rs @@ -1,6 +1,7 @@ // Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::config::Host; use nym_config::{ must_get_home, read_config_from_toml_file, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR, }; @@ -113,7 +114,7 @@ impl From<ConfigV1_1_29> for ConfigV1_1_31 { save_path: value.save_path, // \/ ADDED - host: nym_node::config::Host { + host: Host { // this is a very bad default! public_ips: vec![value.gateway.listening_address], hostname: None, diff --git a/gateway/src/config/old_config_v1_1_31.rs b/gateway/src/config/old_config_v1_1_31.rs index 18841a4993..b0797a9eaf 100644 --- a/gateway/src/config/old_config_v1_1_31.rs +++ b/gateway/src/config/old_config_v1_1_31.rs @@ -1,11 +1,12 @@ // Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::persistence::paths::GatewayPaths; +use crate::config::persistence::paths::{GatewayPaths, WireguardPaths}; use nym_bin_common::logging::LoggingSettings; use nym_config::{ must_get_home, read_config_from_toml_file, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, NYM_DIR, }; +use nym_network_defaults::WG_PORT; use serde::{Deserialize, Deserializer, Serialize}; use std::io; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; @@ -14,7 +15,7 @@ use std::time::Duration; use url::Url; use super::persistence::paths::KeysPaths; -use super::{Config, Debug, Gateway, NetworkRequester}; +use super::{Config, Debug, Gateway, Host, Http, NetworkRequester, Wireguard}; const DEFAULT_GATEWAYS_DIR: &str = "gateways"; @@ -76,10 +77,10 @@ pub struct ConfigV1_1_31 { #[serde(skip)] pub(crate) save_path: Option<PathBuf>, - pub host: nym_node::config::Host, + pub host: Host, #[serde(default)] - pub http: nym_node::config::Http, + pub http: Http, pub gateway: GatewayV1_1_31, @@ -124,12 +125,12 @@ impl From<ConfigV1_1_31> for Config { nyxd_urls: value.gateway.nyxd_urls, cosmos_mnemonic: value.gateway.cosmos_mnemonic, }, - wireguard: nym_node::config::Wireguard { + wireguard: Wireguard { enabled: value.wireguard.enabled, bind_address: value.wireguard.bind_address, announced_port: value.wireguard.announced_port, private_network_prefix: Default::default(), - storage_paths: nym_node::config::persistence::WireguardPaths { + storage_paths: WireguardPaths { // no fields (yet) }, }, @@ -241,11 +242,8 @@ impl Default for WireguardV1_1_31 { fn default() -> Self { Self { enabled: false, - bind_address: SocketAddr::new( - IpAddr::V4(Ipv4Addr::UNSPECIFIED), - nym_node::config::DEFAULT_WIREGUARD_PORT, - ), - announced_port: nym_node::config::DEFAULT_WIREGUARD_PORT, + bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), WG_PORT), + announced_port: WG_PORT, storage_paths: WireguardPathsV1_1_31 {}, } } diff --git a/gateway/src/config/persistence/paths.rs b/gateway/src/config/persistence/paths.rs index b4b79241c6..1a35263ef0 100644 --- a/gateway/src/config/persistence/paths.rs +++ b/gateway/src/config/persistence/paths.rs @@ -2,7 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::config::{default_config_directory, default_data_directory}; -use serde::{Deserialize, Deserializer, Serialize}; +use nym_config::serde_helpers::de_maybe_stringified; +use serde::{Deserialize, Serialize}; use std::path::{Path, PathBuf}; pub const DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME: &str = "private_identity.pem"; @@ -28,19 +29,6 @@ pub fn default_ip_packet_router_data_dir<P: AsRef<Path>>(id: P) -> PathBuf { default_data_directory(id).join(DEFAULT_IP_PACKET_ROUTER_DATA_DIR) } -/// makes sure that an empty path is converted into a `None` as opposed to `Some("")` -fn de_maybe_path<'de, D>(deserializer: D) -> Result<Option<PathBuf>, D::Error> -where - D: Deserializer<'de>, -{ - let path = PathBuf::deserialize(deserializer)?; - if path.as_os_str().is_empty() { - Ok(None) - } else { - Ok(Some(path)) - } -} - #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] pub struct GatewayPaths { @@ -52,13 +40,13 @@ pub struct GatewayPaths { pub clients_storage: PathBuf, /// Path to the configuration of the embedded network requester. - #[serde(deserialize_with = "de_maybe_path")] + #[serde(deserialize_with = "de_maybe_stringified")] pub network_requester_config: Option<PathBuf>, // pub node_description: PathBuf, // pub cosmos_bip39_mnemonic: PathBuf, /// Path to the configuration of the embedded ip packet router. - #[serde(deserialize_with = "de_maybe_path")] + #[serde(deserialize_with = "de_maybe_stringified")] pub ip_packet_router_config: Option<PathBuf>, } @@ -73,6 +61,20 @@ impl GatewayPaths { } } + pub fn new_empty() -> Self { + GatewayPaths { + keys: KeysPaths { + private_identity_key_file: Default::default(), + public_identity_key_file: Default::default(), + private_sphinx_key_file: Default::default(), + public_sphinx_key_file: Default::default(), + }, + clients_storage: Default::default(), + network_requester_config: None, + ip_packet_router_config: None, + } + } + #[must_use] pub fn with_network_requester_config<P: AsRef<Path>>(mut self, path: P) -> Self { self.network_requester_config = Some(path.as_ref().into()); @@ -167,3 +169,15 @@ impl KeysPaths { &self.public_sphinx_key_file } } + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct WireguardPaths { + // pub keys: +} + +impl WireguardPaths { + pub fn new_empty() -> Self { + WireguardPaths {} + } +} diff --git a/gateway/src/error.rs b/gateway/src/error.rs index 61f75981ef..87037d5e35 100644 --- a/gateway/src/error.rs +++ b/gateway/src/error.rs @@ -5,14 +5,17 @@ use crate::node::storage::error::StorageError; use nym_ip_packet_router::error::IpPacketRouterError; use nym_network_requester::error::{ClientCoreError, NetworkRequesterError}; use nym_validator_client::nyxd::error::NyxdError; -use nym_validator_client::nyxd::AccountId; +use nym_validator_client::nyxd::{AccountId, Coin}; use nym_validator_client::ValidatorClientError; use std::io; +use std::net::IpAddr; use std::path::PathBuf; use thiserror::Error; +pub use crate::node::client_handling::websocket::connection_handler::authenticated::RequestHandlingError; + #[derive(Debug, Error)] -pub(crate) enum GatewayError { +pub enum GatewayError { #[error("failed to load {keys} keys from '{}' (private key) and '{}' (public key): {err}", .paths.private_key_path.display(), .paths.public_key_path.display())] KeyPairLoadFailure { keys: String, @@ -89,6 +92,9 @@ pub(crate) enum GatewayError { actual_prefix: String, }, + #[error("this node has insufficient balance to run as zk-nym entry node since it won't be capable of redeeming received credentials. it's account ({account}) has a balance of only {balance}")] + InsufficientNodeBalance { account: AccountId, balance: Coin }, + #[error("storage failure: {source}")] StorageError { #[from] @@ -131,15 +137,36 @@ pub(crate) enum GatewayError { source: NyxdError, }, - // TODO: in the future this should work the other way, i.e. NymNode depending on Gateway errors #[error(transparent)] - NymNodeError(#[from] nym_node::error::NymNodeError), + ClientRequestFailure { + #[from] + source: RequestHandlingError, + }, + + #[error("failed to catch an interrupt: {source}")] + ShutdownFailure { + #[source] + source: Box<dyn std::error::Error + Send + Sync>, + }, + + #[error("this node hasn't set any valid public addresses to announce. Please modify [host.public_ips] section of your config")] + NoPublicIps, + + #[error("this node attempted to announce an invalid public address: {address}. Please modify [host.public_ips] section of your config. Alternatively, if you wanted to use it in the local setting, run the node with the '--local' flag.")] + InvalidPublicIp { address: IpAddr }, + + #[error(transparent)] + NymNodeHttpError(#[from] nym_node_http_api::NymNodeHttpError), #[error("there was an issue with wireguard IP network: {source}")] IpNetworkError { #[from] source: ipnetwork::IpNetworkError, }, + + #[cfg(all(feature = "wireguard", target_os = "linux"))] + #[error("failed to remove wireguard interface: {0}")] + WireguardInterfaceError(#[from] defguard_wireguard_rs::error::WireguardInterfaceError), } impl From<ClientCoreError> for GatewayError { diff --git a/gateway/src/helpers.rs b/gateway/src/helpers.rs new file mode 100644 index 0000000000..f117889473 --- /dev/null +++ b/gateway/src/helpers.rs @@ -0,0 +1,231 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use crate::node::helpers::load_keypair; +use crate::GatewayError; +use nym_config::OptionalSet; +use nym_crypto::asymmetric::{encryption, identity}; +use nym_ip_packet_router::config::BaseClientConfig; +use nym_pemstore::traits::PemStorableKey; +use nym_pemstore::KeyPairPath; +use nym_sphinx::addressing::clients::Recipient; +use nym_types::gateway::{ + GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails, GatewayNodeDetailsResponse, +}; +use std::path::Path; + +pub use crate::node::helpers::{load_ip_packet_router_config, load_network_requester_config}; + +fn display_maybe_path<P: AsRef<Path>>(path: Option<P>) -> String { + path.as_ref() + .map(|p| p.as_ref().display().to_string()) + .unwrap_or_default() +} + +fn display_path<P: AsRef<Path>>(path: P) -> String { + path.as_ref().display().to_string() +} + +#[derive(Default)] +pub struct OverrideNetworkRequesterConfig { + pub fastmode: bool, + pub no_cover: bool, + pub medium_toggle: bool, + + pub open_proxy: Option<bool>, + pub enable_statistics: Option<bool>, + pub statistics_recipient: Option<String>, +} + +#[derive(Default)] +pub struct OverrideIpPacketRouterConfig { + // TODO +} + +// NOTE: make sure this is in sync with service-providers/network-requester/src/cli/mod.rs::override_config +pub fn override_network_requester_config( + mut cfg: nym_network_requester::Config, + opts: Option<OverrideNetworkRequesterConfig>, +) -> nym_network_requester::Config { + let Some(opts) = opts else { return cfg }; + + // as of 12.09.23 the below is true (not sure how this comment will rot in the future) + // medium_toggle: + // - sets secondary packet size to 16kb + // - disables poisson distribution of the main traffic stream + // - sets the cover traffic stream to 1 packet / 5s (on average) + // - disables per hop delay + // + // fastmode (to be renamed to `fast-poisson`): + // - sets average per hop delay to 10ms + // - sets the cover traffic stream to 1 packet / 2000s (on average); for all intents and purposes it disables the stream + // - sets the poisson distribution of the main traffic stream to 4ms, i.e. 250 packets / s on average + // + // no_cover: + // - disables poisson distribution of the main traffic stream + // - disables the secondary cover traffic stream + + // disable poisson rate in the BASE client if the NR option is enabled + if cfg.network_requester.disable_poisson_rate { + cfg.set_no_poisson_process(); + } + + // those should be enforced by `clap` when parsing the arguments + if opts.medium_toggle { + assert!(!opts.fastmode); + assert!(!opts.no_cover); + + cfg.set_medium_toggle(); + } + + cfg.with_base( + BaseClientConfig::with_high_default_traffic_volume, + opts.fastmode, + ) + .with_base(BaseClientConfig::with_disabled_cover_traffic, opts.no_cover) + .with_optional( + nym_network_requester::Config::with_open_proxy, + opts.open_proxy, + ) + .with_optional( + nym_network_requester::Config::with_enabled_statistics, + opts.enable_statistics, + ) + .with_optional( + nym_network_requester::Config::with_statistics_recipient, + opts.statistics_recipient, + ) +} + +// NOTE: make sure this is in sync with service-providers/ip-packet-router/src/cli/mod.rs::override_config +pub fn override_ip_packet_router_config( + mut cfg: nym_ip_packet_router::Config, + opts: Option<OverrideIpPacketRouterConfig>, +) -> nym_ip_packet_router::Config { + let Some(_opts) = opts else { return cfg }; + + // disable poisson rate in the BASE client if the IPR option is enabled + if cfg.ip_packet_router.disable_poisson_rate { + log::info!("Disabling poisson rate for ip packet router"); + cfg.set_no_poisson_process(); + } + + cfg +} + +pub fn load_public_key<T, P, S>(path: P, name: S) -> Result<T, GatewayError> +where + T: PemStorableKey, + P: AsRef<Path>, + S: Into<String>, +{ + nym_pemstore::load_key(path.as_ref()).map_err(|err| GatewayError::PublicKeyLoadFailure { + key: name.into(), + path: path.as_ref().to_path_buf(), + err, + }) +} + +/// Loads identity keys stored on disk +pub fn load_identity_keys(config: &Config) -> Result<identity::KeyPair, GatewayError> { + let identity_paths = KeyPairPath::new( + config.storage_paths.keys.private_identity_key(), + config.storage_paths.keys.public_identity_key(), + ); + load_keypair(identity_paths, "gateway identity") +} + +pub async fn node_details(config: &Config) -> Result<GatewayNodeDetailsResponse, GatewayError> { + let gateway_identity_public_key: identity::PublicKey = load_public_key( + &config.storage_paths.keys.public_identity_key_file, + "gateway identity", + )?; + + let gateway_sphinx_public_key: encryption::PublicKey = load_public_key( + &config.storage_paths.keys.public_sphinx_key_file, + "gateway sphinx", + )?; + + let network_requester = + if let Some(nr_cfg_path) = &config.storage_paths.network_requester_config { + let cfg = load_network_requester_config(&config.gateway.id, nr_cfg_path).await?; + + let nr_identity_public_key: identity::PublicKey = load_public_key( + &cfg.storage_paths.common_paths.keys.public_identity_key_file, + "network requester identity", + )?; + + let nr_encryption_key: encryption::PublicKey = load_public_key( + &cfg.storage_paths + .common_paths + .keys + .public_encryption_key_file, + "network requester encryption", + )?; + + let address = Recipient::new( + nr_identity_public_key, + nr_encryption_key, + gateway_identity_public_key, + ); + + Some(GatewayNetworkRequesterDetails { + enabled: config.network_requester.enabled, + identity_key: nr_identity_public_key.to_base58_string(), + encryption_key: nr_encryption_key.to_base58_string(), + open_proxy: cfg.network_requester.open_proxy, + enabled_statistics: cfg.network_requester.enabled_statistics, + address: address.to_string(), + config_path: display_path(nr_cfg_path), + }) + } else { + None + }; + + let ip_packet_router = if let Some(nr_cfg_path) = &config.storage_paths.ip_packet_router_config + { + let cfg = load_ip_packet_router_config(&config.gateway.id, nr_cfg_path).await?; + + let nr_identity_public_key: identity::PublicKey = load_public_key( + &cfg.storage_paths.common_paths.keys.public_identity_key_file, + "ip packet router identity", + )?; + + let nr_encryption_key: encryption::PublicKey = load_public_key( + &cfg.storage_paths + .common_paths + .keys + .public_encryption_key_file, + "ip packet router encryption", + )?; + + let address = Recipient::new( + nr_identity_public_key, + nr_encryption_key, + gateway_identity_public_key, + ); + + Some(GatewayIpPacketRouterDetails { + enabled: config.ip_packet_router.enabled, + identity_key: nr_identity_public_key.to_base58_string(), + encryption_key: nr_encryption_key.to_base58_string(), + address: address.to_string(), + config_path: display_path(nr_cfg_path), + }) + } else { + None + }; + + Ok(GatewayNodeDetailsResponse { + identity_key: gateway_identity_public_key.to_base58_string(), + sphinx_key: gateway_sphinx_public_key.to_base58_string(), + bind_address: config.gateway.listening_address.to_string(), + mix_port: config.gateway.mix_port, + clients_port: config.gateway.clients_port, + config_path: display_maybe_path(config.save_path.as_ref()), + data_store: display_path(&config.storage_paths.clients_storage), + network_requester, + ip_packet_router, + }) +} diff --git a/gateway/src/http/mod.rs b/gateway/src/http/mod.rs index 9fcaa10209..1d81f4a457 100644 --- a/gateway/src/http/mod.rs +++ b/gateway/src/http/mod.rs @@ -1,22 +1,22 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only use crate::config::Config; use crate::error::GatewayError; -use crate::node::helpers::load_public_key; +use crate::helpers::load_public_key; use ipnetwork::IpNetwork; -use log::warn; +use log::{debug, warn}; use nym_bin_common::bin_info_owned; use nym_crypto::asymmetric::{encryption, identity}; use nym_network_requester::RequestFilter; -use nym_node::error::NymNodeError; -use nym_node::http::api::api_requests; -use nym_node::http::api::api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy; -use nym_node::http::api::api_requests::SignedHostInformation; -use nym_node::http::router::WireguardAppState; -use nym_node::wireguard::types::GatewayClientRegistry; +use nym_node_http_api::api::api_requests; +use nym_node_http_api::api::api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy; +use nym_node_http_api::api::api_requests::SignedHostInformation; +use nym_node_http_api::router::WireguardAppState; +use nym_node_http_api::NymNodeHttpError; use nym_sphinx::addressing::clients::Recipient; use nym_task::TaskClient; +use nym_wireguard_types::registration::GatewayClientRegistry; use std::net::{IpAddr, Ipv4Addr}; use std::sync::Arc; @@ -52,13 +52,14 @@ fn load_host_details( ip_address: config.host.public_ips.clone(), hostname: config.host.hostname.clone(), keys: api_requests::v1::node::models::HostKeys { - ed25519: identity_keypair.public_key().to_base58_string(), - x25519: sphinx_key.to_base58_string(), + ed25519_identity: identity_keypair.public_key().to_base58_string(), + x25519_sphinx: sphinx_key.to_base58_string(), + x25519_noise: "".to_string(), }, }; let signed_info = SignedHostInformation::new(host_info, identity_keypair.private_key()) - .map_err(NymNodeError::from)?; + .map_err(NymNodeHttpError::from)?; Ok(signed_info) } @@ -242,13 +243,15 @@ impl<'a> HttpApiBuilder<'a> { } pub(crate) fn start(self, task_client: TaskClient) -> Result<(), GatewayError> { + debug!("starting http API"); + // is it suboptimal to load all the keys, etc for the second time after they've already been // retrieved during startup of the rest of the components? // yes, a bit. // but in the grand scheme of things performance penalty is negligible since it's only happening on startup // and makes the code a bit nicer to manage. on top of it, all of it will refactored anyway at some point // (famous last words, eh? - 22.09.23) - let mut config = nym_node::http::Config::new( + let mut config = nym_node_http_api::Config::new( bin_info_owned!(), load_host_details( self.gateway_config, @@ -291,7 +294,7 @@ impl<'a> HttpApiBuilder<'a> { .ok() }); - let router = nym_node::http::NymNodeRouter::new(config, wg_state); + let router = nym_node_http_api::NymNodeRouter::new(config, None, wg_state); let server = router .build_server(&self.gateway_config.http.bind_address)? diff --git a/gateway/src/lib.rs b/gateway/src/lib.rs new file mode 100644 index 0000000000..f6181ac62a --- /dev/null +++ b/gateway/src/lib.rs @@ -0,0 +1,14 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + +pub mod config; +pub mod error; +pub mod helpers; +pub(crate) mod http; +pub mod node; + +pub use error::GatewayError; +pub use node::{create_gateway, Gateway}; diff --git a/gateway/src/main.rs b/gateway/src/main.rs index 44e33aec73..81c9d329d4 100644 --- a/gateway/src/main.rs +++ b/gateway/src/main.rs @@ -9,16 +9,11 @@ use colored::Colorize; use log::error; use nym_bin_common::bin_info; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; -use nym_bin_common::output_format::OutputFormat; use nym_network_defaults::setup_env; +use std::io::IsTerminal; use std::sync::OnceLock; mod commands; -mod config; -pub(crate) mod error; -mod http; -mod node; -pub(crate) mod support; fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); @@ -52,11 +47,12 @@ async fn main() -> anyhow::Result<()> { } commands::execute(args).await.map_err(|err| { - if atty::is(atty::Stream::Stdout) { + if std::io::stdout().is_terminal() { let error_message = format!("{err}").red(); error!("{error_message}"); error!("Exiting..."); } + err }) } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 24e0393f9d..9ff8882a3a 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -38,7 +38,7 @@ use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; #[derive(Debug, Error)] -pub(crate) enum RequestHandlingError { +pub enum RequestHandlingError { #[error("Internal gateway storage error")] StorageError(#[from] StorageError), diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index 1bc27a6e2f..67ec3e4316 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -15,7 +15,7 @@ use zeroize::{Zeroize, ZeroizeOnDrop}; pub(crate) use self::authenticated::AuthenticatedHandler; pub(crate) use self::fresh::FreshHandler; -mod authenticated; +pub(crate) mod authenticated; pub(crate) mod coconut; mod fresh; diff --git a/gateway/src/node/helpers.rs b/gateway/src/node/helpers.rs index 58a11e3f6c..0c920181e0 100644 --- a/gateway/src/node/helpers.rs +++ b/gateway/src/node/helpers.rs @@ -3,123 +3,15 @@ use crate::config::Config; use crate::error::GatewayError; + use crate::node::storage::PersistentStorage; -use nym_crypto::asymmetric::{encryption, identity}; -use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; +use nym_crypto::asymmetric::encryption; +use nym_pemstore::traits::PemStorableKeyPair; use nym_pemstore::KeyPairPath; -use nym_sphinx::addressing::clients::Recipient; -use nym_types::gateway::{ - GatewayIpPacketRouterDetails, GatewayNetworkRequesterDetails, GatewayNodeDetailsResponse, -}; + use std::path::Path; -fn display_maybe_path<P: AsRef<Path>>(path: Option<P>) -> String { - path.as_ref() - .map(|p| p.as_ref().display().to_string()) - .unwrap_or_default() -} - -fn display_path<P: AsRef<Path>>(path: P) -> String { - path.as_ref().display().to_string() -} - -pub(crate) async fn node_details( - config: &Config, -) -> Result<GatewayNodeDetailsResponse, GatewayError> { - let gateway_identity_public_key: identity::PublicKey = load_public_key( - &config.storage_paths.keys.public_identity_key_file, - "gateway identity", - )?; - - let gateway_sphinx_public_key: encryption::PublicKey = load_public_key( - &config.storage_paths.keys.public_sphinx_key_file, - "gateway sphinx", - )?; - - let network_requester = - if let Some(nr_cfg_path) = &config.storage_paths.network_requester_config { - let cfg = load_network_requester_config(&config.gateway.id, nr_cfg_path).await?; - - let nr_identity_public_key: identity::PublicKey = load_public_key( - &cfg.storage_paths.common_paths.keys.public_identity_key_file, - "network requester identity", - )?; - - let nr_encryption_key: encryption::PublicKey = load_public_key( - &cfg.storage_paths - .common_paths - .keys - .public_encryption_key_file, - "network requester encryption", - )?; - - let address = Recipient::new( - nr_identity_public_key, - nr_encryption_key, - gateway_identity_public_key, - ); - - Some(GatewayNetworkRequesterDetails { - enabled: config.network_requester.enabled, - identity_key: nr_identity_public_key.to_base58_string(), - encryption_key: nr_encryption_key.to_base58_string(), - open_proxy: cfg.network_requester.open_proxy, - enabled_statistics: cfg.network_requester.enabled_statistics, - address: address.to_string(), - config_path: display_path(nr_cfg_path), - }) - } else { - None - }; - - let ip_packet_router = if let Some(nr_cfg_path) = &config.storage_paths.ip_packet_router_config - { - let cfg = load_ip_packet_router_config(&config.gateway.id, nr_cfg_path).await?; - - let nr_identity_public_key: identity::PublicKey = load_public_key( - &cfg.storage_paths.common_paths.keys.public_identity_key_file, - "ip packet router identity", - )?; - - let nr_encryption_key: encryption::PublicKey = load_public_key( - &cfg.storage_paths - .common_paths - .keys - .public_encryption_key_file, - "ip packet router encryption", - )?; - - let address = Recipient::new( - nr_identity_public_key, - nr_encryption_key, - gateway_identity_public_key, - ); - - Some(GatewayIpPacketRouterDetails { - enabled: config.ip_packet_router.enabled, - identity_key: nr_identity_public_key.to_base58_string(), - encryption_key: nr_encryption_key.to_base58_string(), - address: address.to_string(), - config_path: display_path(nr_cfg_path), - }) - } else { - None - }; - - Ok(GatewayNodeDetailsResponse { - identity_key: gateway_identity_public_key.to_base58_string(), - sphinx_key: gateway_sphinx_public_key.to_base58_string(), - bind_address: config.gateway.listening_address.to_string(), - mix_port: config.gateway.mix_port, - clients_port: config.gateway.clients_port, - config_path: display_maybe_path(config.save_path.as_ref()), - data_store: display_path(&config.storage_paths.clients_storage), - network_requester, - ip_packet_router, - }) -} - -pub(crate) async fn load_network_requester_config<P: AsRef<Path>>( +pub async fn load_network_requester_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_network_requester::Config, GatewayError> { @@ -132,7 +24,7 @@ pub(crate) async fn load_network_requester_config<P: AsRef<Path>>( read_network_requester_config(id, path) } -pub(crate) async fn load_ip_packet_router_config<P: AsRef<Path>>( +pub async fn load_ip_packet_router_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_ip_packet_router::Config, GatewayError> { @@ -145,7 +37,7 @@ pub(crate) async fn load_ip_packet_router_config<P: AsRef<Path>>( read_ip_packet_router_config(id, path) } -fn read_network_requester_config<P: AsRef<Path>>( +pub fn read_network_requester_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_network_requester::Config, GatewayError> { @@ -159,7 +51,7 @@ fn read_network_requester_config<P: AsRef<Path>>( }) } -fn read_ip_packet_router_config<P: AsRef<Path>>( +pub fn read_ip_packet_router_config<P: AsRef<Path>>( id: &str, path: P, ) -> Result<nym_ip_packet_router::Config, GatewayError> { @@ -182,7 +74,7 @@ pub(crate) async fn initialise_main_storage( Ok(PersistentStorage::init(path, retrieval_limit).await?) } -pub(crate) fn load_keypair<T: PemStorableKeyPair>( +pub fn load_keypair<T: PemStorableKeyPair>( paths: KeyPairPath, name: impl Into<String>, ) -> Result<T, GatewayError> { @@ -193,28 +85,6 @@ pub(crate) fn load_keypair<T: PemStorableKeyPair>( }) } -pub(crate) fn load_public_key<T, P, S>(path: P, name: S) -> Result<T, GatewayError> -where - T: PemStorableKey, - P: AsRef<Path>, - S: Into<String>, -{ - nym_pemstore::load_key(path.as_ref()).map_err(|err| GatewayError::PublicKeyLoadFailure { - key: name.into(), - path: path.as_ref().to_path_buf(), - err, - }) -} - -/// Loads identity keys stored on disk -pub(crate) fn load_identity_keys(config: &Config) -> Result<identity::KeyPair, GatewayError> { - let identity_paths = KeyPairPath::new( - config.storage_paths.keys.private_identity_key(), - config.storage_paths.keys.public_identity_key(), - ); - load_keypair(identity_paths, "gateway identity") -} - /// Loads Sphinx keys stored on disk pub(crate) fn load_sphinx_keys(config: &Config) -> Result<encryption::KeyPair, GatewayError> { let sphinx_paths = KeyPairPath::new( diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 26ad47b689..08af357093 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -2,13 +2,12 @@ // SPDX-License-Identifier: GPL-3.0-only use self::helpers::load_ip_packet_router_config; -use self::storage::PersistentStorage; -use crate::commands::helpers::{ - override_ip_packet_router_config, override_network_requester_config, - OverrideIpPacketRouterConfig, OverrideNetworkRequesterConfig, -}; use crate::config::Config; use crate::error::GatewayError; +use crate::helpers::{ + load_identity_keys, override_ip_packet_router_config, override_network_requester_config, + OverrideIpPacketRouterConfig, OverrideNetworkRequesterConfig, +}; use crate::http::HttpApiBuilder; use crate::node::client_handling::active_clients::ActiveClientsStore; use crate::node::client_handling::embedded_clients::{LocalEmbeddedClientHandle, MessageRouter}; @@ -17,8 +16,6 @@ use crate::node::client_handling::websocket::connection_handler::coconut::Coconu use crate::node::helpers::{initialise_main_storage, load_network_requester_config}; use crate::node::mixnet_handling::receiver::connection_handler::ConnectionHandler; use crate::node::statistics::collector::GatewayStatisticsCollector; -use crate::node::storage::Storage; -use anyhow::bail; use dashmap::DashMap; use futures::channel::{mpsc, oneshot}; use log::*; @@ -26,13 +23,14 @@ use nym_crypto::asymmetric::{encryption, identity}; use nym_mixnet_client::forwarder::{MixForwardingSender, PacketForwarder}; use nym_network_defaults::NymNetworkDetails; use nym_network_requester::{LocalGateway, NRServiceProviderBuilder, RequestFilter}; -use nym_node::wireguard::types::GatewayClientRegistry; use nym_statistics_common::collector::StatisticsSender; -use nym_task::{TaskClient, TaskManager}; +use nym_task::{TaskClient, TaskHandle, TaskManager}; +use nym_types::gateway::GatewayNodeDetailsResponse; +use nym_validator_client::nyxd::{Coin, CosmWasmClient}; use nym_validator_client::{nyxd, DirectSigningHttpRpcNyxdClient}; +use nym_wireguard_types::registration::GatewayClientRegistry; use rand::seq::SliceRandom; use rand::thread_rng; -use std::error::Error; use std::net::SocketAddr; use std::path::PathBuf; use std::sync::Arc; @@ -43,6 +41,8 @@ pub(crate) mod mixnet_handling; pub(crate) mod statistics; pub(crate) mod storage; +pub use storage::{InMemStorage, PersistentStorage, Storage}; + // TODO: should this struct live here? struct StartedNetworkRequester { /// Request filter, either an exit policy or the allow list, used by the network requester. @@ -53,7 +53,7 @@ struct StartedNetworkRequester { } /// Wire up and create Gateway instance -pub(crate) async fn create_gateway( +pub async fn create_gateway( config: Config, nr_config_override: Option<OverrideNetworkRequesterConfig>, ip_config_override: Option<OverrideIpPacketRouterConfig>, @@ -102,19 +102,19 @@ pub(crate) async fn create_gateway( #[derive(Debug, Clone)] pub struct LocalNetworkRequesterOpts { - config: nym_network_requester::Config, + pub config: nym_network_requester::Config, - custom_mixnet_path: Option<PathBuf>, + pub custom_mixnet_path: Option<PathBuf>, } #[derive(Debug, Clone)] pub struct LocalIpPacketRouterOpts { - config: nym_ip_packet_router::Config, + pub config: nym_ip_packet_router::Config, - custom_mixnet_path: Option<PathBuf>, + pub custom_mixnet_path: Option<PathBuf>, } -pub(crate) struct Gateway<St = PersistentStorage> { +pub struct Gateway<St = PersistentStorage> { config: Config, network_requester_opts: Option<LocalNetworkRequesterOpts>, @@ -129,6 +129,9 @@ pub(crate) struct Gateway<St = PersistentStorage> { storage: St, client_registry: Arc<GatewayClientRegistry>, + + run_http_server: bool, + task_client: Option<TaskClient>, } impl<St> Gateway<St> { @@ -141,35 +144,59 @@ impl<St> Gateway<St> { ) -> Result<Self, GatewayError> { Ok(Gateway { storage, - identity_keypair: Arc::new(helpers::load_identity_keys(&config)?), + identity_keypair: Arc::new(load_identity_keys(&config)?), sphinx_keypair: Arc::new(helpers::load_sphinx_keys(&config)?), config, network_requester_opts, ip_packet_router_opts, client_registry: Arc::new(DashMap::new()), + run_http_server: false, + task_client: None, }) } - #[cfg(test)] - pub async fn new_from_keys_and_storage( + pub fn new_loaded( config: Config, network_requester_opts: Option<LocalNetworkRequesterOpts>, ip_packet_router_opts: Option<LocalIpPacketRouterOpts>, - identity_keypair: identity::KeyPair, - sphinx_keypair: encryption::KeyPair, + identity_keypair: Arc<identity::KeyPair>, + sphinx_keypair: Arc<encryption::KeyPair>, storage: St, ) -> Self { Gateway { config, network_requester_opts, ip_packet_router_opts, - identity_keypair: Arc::new(identity_keypair), - sphinx_keypair: Arc::new(sphinx_keypair), + identity_keypair, + sphinx_keypair, storage, client_registry: Arc::new(DashMap::new()), + run_http_server: false, + task_client: None, } } + pub fn disable_http_server(&mut self) { + self.run_http_server = false + } + + pub fn set_task_client(&mut self, task_client: TaskClient) { + self.task_client = Some(task_client) + } + + pub fn set_wireguard_client_registry(&mut self, client_registry: Arc<GatewayClientRegistry>) { + // sanity check: + if Arc::strong_count(&self.client_registry) != 1 { + panic!("the client registry is already being used elsewhere") + } + self.client_registry = client_registry + } + + pub async fn node_details(&self) -> Result<GatewayNodeDetailsResponse, GatewayError> { + // TODO: this is doing redundant key loads, but I guess that's fine for now + crate::helpers::node_details(&self.config).await + } + fn start_mix_socket_listener( &self, ack_sender: MixForwardingSender, @@ -202,7 +229,7 @@ impl<St> Gateway<St> { async fn start_wireguard( &self, shutdown: TaskClient, - ) -> Result<defguard_wireguard_rs::WGApi, Box<dyn Error + Send + Sync>> { + ) -> Result<defguard_wireguard_rs::WGApi, Box<dyn std::error::Error + Send + Sync>> { nym_wireguard::start_wireguard(shutdown, Arc::clone(&self.client_registry)).await } @@ -382,14 +409,6 @@ impl<St> Gateway<St> { Ok(LocalEmbeddedClientHandle::new(address, ipr_mix_sender)) } - async fn wait_for_interrupt( - mut shutdown: TaskManager, - ) -> Result<(), Box<dyn Error + Send + Sync>> { - let res = shutdown.catch_interrupt().await; - log::info!("Stopping nym gateway"); - res - } - fn random_api_client(&self) -> Result<nym_validator_client::NymApiClient, GatewayError> { let endpoints = self.config.get_nym_api_endpoints(); let nym_api = endpoints @@ -433,7 +452,7 @@ impl<St> Gateway<St> { })) } - pub async fn run(self) -> anyhow::Result<()> + pub async fn run(mut self) -> Result<(), GatewayError> where St: Storage + Clone + 'static, { @@ -443,21 +462,43 @@ impl<St> Gateway<St> { warn!("You seem to have bonded your gateway before starting it - that's highly unrecommended as in the future it might result in slashing"); } - let shutdown = TaskManager::new(10); + let shutdown = self + .task_client + .take() + .map(Into::<TaskHandle>::into) + .unwrap_or_else(|| TaskHandle::Internal(TaskManager::new(10))) + .name_if_unnamed("gateway"); - let coconut_verifier = { - let nyxd_client = self.random_nyxd_client()?; - CoconutVerifier::new(nyxd_client, self.config.gateway.only_coconut_credentials).await - }?; + let nyxd_client = self.random_nyxd_client()?; - let mix_forwarding_channel = - self.start_packet_forwarder(shutdown.subscribe().named("PacketForwarder")); + if self.config.gateway.only_coconut_credentials { + debug!("the gateway is running in coconut-only mode - making sure it has enough tokens for credential redemption"); + let mix_denom_base = nyxd_client.current_chain_details().mix_denom.base.clone(); + + let account = nyxd_client.address(); + let balance = nyxd_client + .get_balance(&account, mix_denom_base.clone()) + .await? + .unwrap_or(Coin::new(0, mix_denom_base)); + + error!("this gateway does not have enough tokens for covering transaction fees for credential redemption"); + + // see if we have at least 1nym (i.e. 1'000'000unym) + if balance.amount < 1_000_000 { + return Err(GatewayError::InsufficientNodeBalance { account, balance }); + } + } + + let coconut_verifier = + CoconutVerifier::new(nyxd_client, self.config.gateway.only_coconut_credentials).await?; + + let mix_forwarding_channel = self.start_packet_forwarder(shutdown.fork("PacketForwarder")); let active_clients_store = ActiveClientsStore::new(); self.start_mix_socket_listener( mix_forwarding_channel.clone(), active_clients_store.clone(), - shutdown.subscribe().named("mixnet_handling::Listener"), + shutdown.fork("mixnet_handling::Listener"), ); if self.config.gateway.enabled_statistics { @@ -476,7 +517,7 @@ impl<St> Gateway<St> { self.start_client_websocket_listener( mix_forwarding_channel.clone(), active_clients_store.clone(), - shutdown.subscribe().named("websocket::Listener"), + shutdown.fork("websocket::Listener"), Arc::new(coconut_verifier), ); @@ -484,7 +525,7 @@ impl<St> Gateway<St> { let embedded_nr = self .start_network_requester( mix_forwarding_channel.clone(), - shutdown.subscribe().named("NetworkRequester"), + shutdown.fork("NetworkRequester"), ) .await?; // insert information about embedded NR to the active clients store @@ -499,40 +540,40 @@ impl<St> Gateway<St> { let embedded_ip_sp = self .start_ip_packet_router( mix_forwarding_channel, - shutdown.subscribe().named("ip_service_provider"), + shutdown.fork("ip_service_provider"), ) .await?; active_clients_store.insert_embedded(embedded_ip_sp); - } + } else { + info!("embedded ip packet router is disabled"); + }; - HttpApiBuilder::new( - &self.config, - self.identity_keypair.as_ref(), - self.sphinx_keypair.clone(), - ) - .with_wireguard_client_registry(self.client_registry.clone()) - .with_maybe_network_requester(self.network_requester_opts.as_ref().map(|o| &o.config)) - .with_maybe_network_request_filter(nr_request_filter) - .with_maybe_ip_packet_router(self.ip_packet_router_opts.as_ref().map(|o| &o.config)) - .start(shutdown.subscribe().named("http-api"))?; + if self.run_http_server { + HttpApiBuilder::new( + &self.config, + self.identity_keypair.as_ref(), + self.sphinx_keypair.clone(), + ) + .with_wireguard_client_registry(self.client_registry.clone()) + .with_maybe_network_requester(self.network_requester_opts.as_ref().map(|o| &o.config)) + .with_maybe_network_request_filter(nr_request_filter) + .with_maybe_ip_packet_router(self.ip_packet_router_opts.as_ref().map(|o| &o.config)) + .start(shutdown.fork("http-api"))?; + } // Once this is a bit more mature, make this a commandline flag instead of a compile time // flag #[cfg(all(feature = "wireguard", target_os = "linux"))] - let wg_api = self - .start_wireguard(shutdown.subscribe().named("wireguard")) - .await - .ok(); + let wg_api = self.start_wireguard(shutdown.fork("wireguard")).await.ok(); #[cfg(all(feature = "wireguard", not(target_os = "linux")))] - self.start_wireguard(shutdown.subscribe().named("wireguard")) - .await; + self.start_wireguard(shutdown.fork("wireguard")).await; info!("Finished nym gateway startup procedure - it should now be able to receive mix and client traffic!"); - if let Err(err) = Self::wait_for_interrupt(shutdown).await { + if let Err(source) = shutdown.wait_for_shutdown().await { // that's a nasty workaround, but anyhow errors are generally nicer, especially on exit - bail!("{err}") + return Err(GatewayError::ShutdownFailure { source }); } #[cfg(all(feature = "wireguard", target_os = "linux"))] if let Some(wg_api) = wg_api { diff --git a/gateway/src/node/storage/error.rs b/gateway/src/node/storage/error.rs index b2feb1becf..f908eac083 100644 --- a/gateway/src/node/storage/error.rs +++ b/gateway/src/node/storage/error.rs @@ -4,7 +4,7 @@ use thiserror::Error; #[derive(Error, Debug)] -pub(crate) enum StorageError { +pub enum StorageError { #[error("Database experienced an internal error: {0}")] InternalDatabaseError(#[from] sqlx::Error), diff --git a/gateway/src/node/storage/mod.rs b/gateway/src/node/storage/mod.rs index 5349686a86..bb7330c2f6 100644 --- a/gateway/src/node/storage/mod.rs +++ b/gateway/src/node/storage/mod.rs @@ -21,7 +21,7 @@ mod models; mod shared_keys; #[async_trait] -pub(crate) trait Storage: Send + Sync { +pub trait Storage: Send + Sync { /// Inserts provided derived shared keys into the database. /// If keys previously existed for the provided client, they are overwritten with the new data. /// @@ -162,7 +162,7 @@ pub(crate) trait Storage: Send + Sync { // note that clone here is fine as upon cloning the same underlying pool will be used #[derive(Clone)] -pub(crate) struct PersistentStorage { +pub struct PersistentStorage { shared_key_manager: SharedKeysManager, inbox_manager: InboxManager, bandwidth_manager: BandwidthManager, @@ -359,9 +359,8 @@ impl Storage for PersistentStorage { } /// In-memory implementation of `Storage`. The intention is primarily in testing environments. -#[cfg(test)] #[derive(Clone)] -pub(crate) struct InMemStorage; +pub struct InMemStorage; //#[cfg(test)] //impl InMemStorage { diff --git a/gateway/src/node/storage/models.rs b/gateway/src/node/storage/models.rs index 2bef3b7265..b3fde7d37a 100644 --- a/gateway/src/node/storage/models.rs +++ b/gateway/src/node/storage/models.rs @@ -3,26 +3,26 @@ use sqlx::FromRow; -pub(crate) struct PersistedSharedKeys { +pub struct PersistedSharedKeys { pub(crate) client_address_bs58: String, pub(crate) derived_aes128_ctr_blake3_hmac_keys_bs58: String, } -pub(crate) struct StoredMessage { +pub struct StoredMessage { pub(crate) id: i64, #[allow(dead_code)] pub(crate) client_address_bs58: String, pub(crate) content: Vec<u8>, } -pub(crate) struct PersistedBandwidth { +pub struct PersistedBandwidth { #[allow(dead_code)] pub(crate) client_address_bs58: String, pub(crate) available: i64, } #[derive(Debug, Clone, FromRow)] -pub(crate) struct SpentCredential { +pub struct SpentCredential { #[allow(dead_code)] pub(crate) blinded_serial_number_bs58: String, #[allow(dead_code)] diff --git a/gateway/src/support/config.rs b/gateway/src/support/config.rs deleted file mode 100644 index deae3240de..0000000000 --- a/gateway/src/support/config.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use crate::commands::helpers::{try_load_current_config, OverrideConfig}; -use crate::config::Config; -use crate::error::GatewayError; - -pub(crate) fn build_config<O: Into<OverrideConfig>>( - id: String, - override_args: O, -) -> Result<Config, GatewayError> { - let config = try_load_current_config(&id)?; - override_args.into().do_override(config) -} diff --git a/gateway/src/support/mod.rs b/gateway/src/support/mod.rs deleted file mode 100644 index 42dab6772b..0000000000 --- a/gateway/src/support/mod.rs +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -pub(crate) mod config; diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index af2442fd02..647a54c193 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -25,13 +25,14 @@ colored = "2.0" cupid = "0.6.1" dirs = "4.0" futures = { workspace = true } -humantime-serde = "1.0" +humantime-serde = { workspace = true } lazy_static = "1.4" log = { workspace = true } rand = "0.7.3" serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } sysinfo = "0.27.7" +time.workspace = true tokio = { workspace = true, features = ["rt-multi-thread", "net", "signal"] } tokio-util = { workspace = true, features = ["codec"] } toml = "0.5.8" @@ -39,15 +40,15 @@ url = { workspace = true, features = ["serde"] } thiserror = { workspace = true } # internal -nym-node = { path = "../nym-node" } - nym-config = { path = "../common/config" } nym-crypto = { path = "../common/crypto" } nym-contracts-common = { path = "../common/cosmwasm-smart-contracts/contracts-common" } +nym-http-api-common = { path = "../common/http-api-common" } nym-mixnet-client = { path = "../common/client-libs/mixnet-client" } nym-mixnode-common = { path = "../common/mixnode-common" } nym-metrics = { path = "../common/nym-metrics" } nym-nonexhaustive-delayqueue = { path = "../common/nonexhaustive-delayqueue" } +nym-node-http-api = { path = "../nym-node/nym-node-http-api" } nym-sphinx = { path = "../common/nymsphinx" } nym-sphinx-params = { path = "../common/nymsphinx/params" } nym-pemstore = { path = "../common/pemstore", version = "0.3.0" } diff --git a/mixnode/src/commands/describe.rs b/mixnode/src/commands/describe.rs index 5576296bcd..d5b17682e2 100644 --- a/mixnode/src/commands/describe.rs +++ b/mixnode/src/commands/describe.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::try_load_current_config; -use crate::node::node_description::NodeDescription; use clap::Args; use colored::Colorize; +use nym_mixnode::node::node_description::NodeDescription; use std::io; use std::io::Write; @@ -74,6 +74,6 @@ pub(crate) fn execute(args: Describe) -> anyhow::Result<()> { }; // save the struct - NodeDescription::save_to_file(&node_description, config.storage_paths.node_description)?; + node_description.save_to_file(config.storage_paths.node_description)?; Ok(()) } diff --git a/mixnode/src/commands/init.rs b/mixnode/src/commands/init.rs index cc1f5fe5c8..a60663768a 100644 --- a/mixnode/src/commands/init.rs +++ b/mixnode/src/commands/init.rs @@ -1,127 +1,21 @@ -// Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2020-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use super::OverrideConfig; -use crate::commands::override_config; -use crate::config::{ - default_config_directory, default_config_filepath, default_data_directory, Config, -}; -use crate::node::MixNode; -use clap::Args; -use nym_bin_common::output_format::OutputFormat; -use nym_crypto::asymmetric::{encryption, identity}; -use std::net::IpAddr; -use std::{fs, io}; +use anyhow::bail; +use colored::Colorize; -#[derive(Args, Clone)] +#[allow(dead_code)] +#[derive(clap::Args, Clone)] pub(crate) struct Init { /// Id of the mixnode we want to create config for #[clap(long)] - id: String, - - /// The host on which the mixnode will be running - #[clap(long)] - host: IpAddr, - - /// The port on which the mixnode will be listening for mix packets - #[clap(long)] - mix_port: Option<u16>, - - /// The port on which the mixnode will be listening for verloc packets - #[clap(long)] - verloc_port: Option<u16>, - - /// The port on which the mixnode will be listening for http requests - #[clap(long)] - http_api_port: Option<u16>, - - /// Comma separated list of nym-api endpoints of the validators - // the alias here is included for backwards compatibility (1.1.4 and before) - #[clap(long, alias = "validators", value_delimiter = ',')] - nym_apis: Option<Vec<url::Url>>, - - #[clap(short, long, default_value_t = OutputFormat::default())] - output: OutputFormat, - - #[clap(long)] - metrics_key: Option<String>, + id: Option<String>, } -impl From<Init> for OverrideConfig { - fn from(init_config: Init) -> Self { - OverrideConfig { - id: init_config.id, - host: Some(init_config.host), - mix_port: init_config.mix_port, - verloc_port: init_config.verloc_port, - http_api_port: init_config.http_api_port, - nym_apis: init_config.nym_apis, - metrics_key: init_config.metrics_key, - } - } -} - -fn init_paths(id: &str) -> io::Result<()> { - fs::create_dir_all(default_data_directory(id))?; - fs::create_dir_all(default_config_directory(id)) -} - -pub(crate) fn execute(args: &Init) -> anyhow::Result<()> { - let override_config_fields = OverrideConfig::from(args.clone()); - let id = override_config_fields.id.clone(); - eprintln!("Initialising mixnode {id}..."); - - let already_init = if default_config_filepath(&id).exists() { - eprintln!("Mixnode \"{id}\" was already initialised before! Config information will be overwritten (but keys will be kept)!"); - true - } else { - init_paths(&id).expect("failed to initialise storage paths"); - false - }; - - let mut config = Config::new(&id); - config = override_config(config, override_config_fields); - - // if node was already initialised, don't generate new keys - if !already_init { - let mut rng = rand::rngs::OsRng; - - let identity_keys = identity::KeyPair::new(&mut rng); - let sphinx_keys = encryption::KeyPair::new(&mut rng); - - nym_pemstore::store_keypair( - &identity_keys, - &nym_pemstore::KeyPairPath::new( - config.storage_paths.private_identity_key(), - config.storage_paths.public_identity_key(), - ), - ) - .expect("Failed to save identity keys"); - - nym_pemstore::store_keypair( - &sphinx_keys, - &nym_pemstore::KeyPairPath::new( - config.storage_paths.private_encryption_key(), - config.storage_paths.public_encryption_key(), - ), - ) - .expect("Failed to save sphinx keys"); - eprintln!("Saved mixnet identity and sphinx keypairs"); - } - - let config_save_location = config.default_location(); - config.save_to_default_location().unwrap_or_else(|_| { - panic!( - "Failed to save the config file to {}", - config_save_location.display() - ) - }); - eprintln!( - "Saved configuration file to {}", - config_save_location.display() - ); - eprintln!("Mixnode configuration completed.\n\n\n"); - - MixNode::new(config)?.print_node_details(args.output); - Ok(()) +pub(crate) fn execute(_args: &Init) -> anyhow::Result<()> { + bail!( + "standalone mixnode initialisation has been removed - please initialise a `nym-node` instead" + .red() + .bold() + ) } diff --git a/mixnode/src/commands/mod.rs b/mixnode/src/commands/mod.rs index 34b75e701a..4891cd2798 100644 --- a/mixnode/src/commands/mod.rs +++ b/mixnode/src/commands/mod.rs @@ -1,20 +1,21 @@ // Copyright 2020 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::default_config_filepath; -use crate::error::MixnodeError; -use crate::{config::Config, Cli}; +use crate::Cli; use clap::CommandFactory; use clap::Subcommand; use colored::Colorize; -use log::{error, info, warn}; +use log::{error, warn}; use nym_bin_common::completions::{fig_generate, ArgShell}; -use nym_bin_common::version_checker; use nym_config::defaults::var_names::{BECH32_PREFIX, NYM_API}; use nym_config::OptionalSet; use nym_crypto::bech32_address_validation; +use nym_mixnode::config::{default_config_filepath, Config}; +use nym_mixnode::error::MixnodeError; +use std::io::IsTerminal; use std::net::IpAddr; use std::process; +use std::time::Duration; mod build_info; mod describe; @@ -52,6 +53,7 @@ pub(crate) enum Commands { } // Configuration that can be overridden. +#[allow(dead_code)] struct OverrideConfig { id: String, host: Option<IpAddr>, @@ -65,6 +67,13 @@ struct OverrideConfig { pub(crate) async fn execute(args: Cli) -> anyhow::Result<()> { let bin_name = "nym-mixnode"; + warn!("standalone mixnodes have been deprecated - please consider migrating it to a `nym-node` via `nym-node migrate mixnode` command"); + if std::io::stdout().is_terminal() { + // if user is running it in terminal session, + // introduce the delay, so they'd notice the message + tokio::time::sleep(Duration::from_secs(1)).await + } + match args.command { Commands::Describe(m) => describe::execute(m)?, Commands::Init(m) => init::execute(&m)?, @@ -115,25 +124,6 @@ pub(crate) fn validate_bech32_address_or_exit(address: &str) { } } -// this only checks compatibility between config the binary. It does not take into consideration -// network version. It might do so in the future. -pub(crate) fn version_check(cfg: &Config) -> bool { - let binary_version = env!("CARGO_PKG_VERSION"); - let config_version = &cfg.mixnode.version; - if binary_version == config_version { - true - } else { - warn!("The mixnode binary has different version than what is specified in config file! {} and {}", binary_version, config_version); - if version_checker::is_minor_version_compatible(binary_version, config_version) { - info!("but they are still semver compatible. However, consider running the `upgrade` command"); - true - } else { - error!("and they are semver incompatible! - please run the `upgrade` command before attempting `run` again"); - false - } - } -} - fn try_load_current_config(id: &str) -> Result<Config, MixnodeError> { upgrade_helpers::try_upgrade_config(id)?; diff --git a/mixnode/src/commands/node_details.rs b/mixnode/src/commands/node_details.rs index 24dc71cb2f..cddf41a04f 100644 --- a/mixnode/src/commands/node_details.rs +++ b/mixnode/src/commands/node_details.rs @@ -2,9 +2,9 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::try_load_current_config; -use crate::node::MixNode; use clap::Args; use nym_bin_common::output_format::OutputFormat; +use nym_mixnode::MixNode; #[derive(Args)] pub(crate) struct NodeDetails { diff --git a/mixnode/src/commands/run.rs b/mixnode/src/commands/run.rs index 178ff31cc3..bef1ef3049 100644 --- a/mixnode/src/commands/run.rs +++ b/mixnode/src/commands/run.rs @@ -2,15 +2,14 @@ // SPDX-License-Identifier: GPL-3.0-only use super::OverrideConfig; -use crate::commands::{override_config, try_load_current_config, version_check}; -use crate::node::MixNode; -use anyhow::bail; +use crate::commands::{override_config, try_load_current_config}; use clap::Args; -use log::error; use nym_bin_common::output_format::OutputFormat; use nym_config::helpers::SPECIAL_ADDRESSES; +use nym_mixnode::MixNode; use nym_validator_client::nyxd; use std::net::IpAddr; + #[derive(Args, Clone)] pub(crate) struct Run { /// Id of the nym-mixnode we want to run @@ -79,11 +78,6 @@ pub(crate) async fn execute(args: &Run) -> anyhow::Result<()> { let mut config = try_load_current_config(&args.id)?; config = override_config(config, OverrideConfig::from(args.clone())); - if !version_check(&config) { - error!("failed the local version check"); - bail!("failed the local version check") - } - if SPECIAL_ADDRESSES.contains(&config.mixnode.listening_address) { show_binding_warning(&config.mixnode.listening_address.to_string()); } diff --git a/mixnode/src/commands/sign.rs b/mixnode/src/commands/sign.rs index b178718fc1..405f9845e2 100644 --- a/mixnode/src/commands/sign.rs +++ b/mixnode/src/commands/sign.rs @@ -2,17 +2,15 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::commands::{try_load_current_config, validate_bech32_address_or_exit}; -use crate::node::helpers::load_identity_keys; use anyhow::{bail, Result}; use clap::{ArgGroup, Args}; use log::error; use nym_bin_common::output_format::OutputFormat; use nym_crypto::asymmetric::identity; +use nym_mixnode::node::helpers::load_identity_keys; use nym_types::helpers::ConsoleSigningOutput; use nym_validator_client::nyxd; -use super::version_check; - #[derive(Args, Clone)] #[clap(group(ArgGroup::new("sign").required(true).args(&["wallet_address", "text", "contract_msg"])))] pub(crate) struct Sign { @@ -114,11 +112,6 @@ fn print_signed_contract_msg( pub(crate) fn execute(args: &Sign) -> anyhow::Result<()> { let config = try_load_current_config(&args.id)?; - if !version_check(&config) { - error!("failed the local version check"); - bail!("failed the local version check") - } - let signed_target = match SignedTarget::try_from(args.clone()) { Ok(s) => s, Err(err) => { diff --git a/mixnode/src/commands/upgrade_helpers.rs b/mixnode/src/commands/upgrade_helpers.rs index 66b4a6ef4d..bf5e1a3882 100644 --- a/mixnode/src/commands/upgrade_helpers.rs +++ b/mixnode/src/commands/upgrade_helpers.rs @@ -1,11 +1,11 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::old_config_v1_1_21::ConfigV1_1_21; -use crate::config::old_config_v1_1_32::ConfigV1_1_32; -use crate::config::{default_config_filepath, Config}; -use crate::error::MixnodeError; use log::info; +use nym_mixnode::config::old_config_v1_1_21::ConfigV1_1_21; +use nym_mixnode::config::old_config_v1_1_32::ConfigV1_1_32; +use nym_mixnode::config::{default_config_filepath, Config}; +use nym_mixnode::error::MixnodeError; fn try_upgrade_v1_1_21_config(id: &str) -> Result<bool, MixnodeError> { use nym_config::legacy_helpers::nym_config::MigrationNymConfig; diff --git a/mixnode/src/config/mod.rs b/mixnode/src/config/mod.rs index 03ac439a59..21a2e3949d 100644 --- a/mixnode/src/config/mod.rs +++ b/mixnode/src/config/mod.rs @@ -1,7 +1,6 @@ // Copyright 2020-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::persistence::paths::MixNodePaths; use crate::config::template::CONFIG_TEMPLATE; use log::{debug, warn}; use nym_bin_common::logging::LoggingSettings; @@ -11,10 +10,10 @@ use nym_config::defaults::{ }; use nym_config::helpers::inaddr_any; use nym_config::{ - must_get_home, read_config_from_toml_file, save_formatted_config_to_file, NymConfigTemplate, - DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, + must_get_home, read_config_from_toml_file, save_formatted_config_to_file, + serde_helpers::de_maybe_stringified, NymConfigTemplate, DEFAULT_CONFIG_DIR, + DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, }; -use nym_node::config; use serde::{Deserialize, Serialize}; use std::io; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; @@ -23,11 +22,13 @@ use std::str::FromStr; use std::time::Duration; use url::Url; -pub(crate) mod old_config_v1_1_21; -pub(crate) mod old_config_v1_1_32; +pub mod old_config_v1_1_21; +pub mod old_config_v1_1_32; pub mod persistence; mod template; +pub use crate::config::persistence::paths::MixNodePaths; + const DEFAULT_MIXNODES_DIR: &str = "mixnodes"; // 'RTT MEASUREMENT' @@ -73,8 +74,8 @@ pub fn default_data_directory<P: AsRef<Path>>(id: P) -> PathBuf { .join(DEFAULT_DATA_DIR) } -fn default_mixnode_http_config() -> config::Http { - config::Http { +fn default_mixnode_http_config() -> Http { + Http { bind_address: SocketAddr::new( IpAddr::V4(Ipv4Addr::UNSPECIFIED), DEFAULT_HTTP_API_LISTENING_PORT, @@ -91,10 +92,10 @@ pub struct Config { #[serde(skip)] pub(crate) save_path: Option<PathBuf>, - pub host: config::Host, + pub host: Host, #[serde(default = "default_mixnode_http_config")] - pub http: config::Http, + pub http: Http, pub mixnode: MixNode, @@ -122,7 +123,7 @@ impl Config { Config { save_path: None, - host: config::Host { + host: Host { // this is a very bad default! public_ips: vec![default_mixnode.listening_address], hostname: None, @@ -136,6 +137,27 @@ impl Config { } } + pub fn externally_loaded( + host: impl Into<Host>, + http: impl Into<Http>, + mixnode: impl Into<MixNode>, + storage_paths: impl Into<MixNodePaths>, + verloc: impl Into<Verloc>, + logging: impl Into<LoggingSettings>, + debug: impl Into<Debug>, + ) -> Self { + Config { + save_path: None, + host: host.into(), + http: http.into(), + mixnode: mixnode.into(), + storage_paths: storage_paths.into(), + verloc: verloc.into(), + logging: logging.into(), + debug: debug.into(), + } + } + // simple wrapper that reads config file and assigns path location fn read_from_path<P: AsRef<Path>>(path: P) -> io::Result<Self> { let path = path.as_ref(); @@ -145,9 +167,6 @@ impl Config { Ok(loaded) } - // currently this is dead code, but once we allow loading configs from custom paths - // well, we will have to be using it - #[allow(dead_code)] pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> io::Result<Self> { Self::read_from_path(path) } @@ -220,6 +239,44 @@ impl Config { } } +// TODO: this is very much a WIP. we need proper ssl certificate support here +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Host { + /// Ip address(es) of this host, such as 1.1.1.1 that external clients will use for connections. + pub public_ips: Vec<IpAddr>, + + /// Optional hostname of this node, for example nymtech.net. + // TODO: this is temporary. to be replaced by pulling the data directly from the certs. + #[serde(deserialize_with = "de_maybe_stringified")] + pub hostname: Option<String>, +} + +impl Host { + pub fn validate(&self) -> bool { + if self.public_ips.is_empty() { + return false; + } + + true + } +} + +#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Http { + /// Socket address this node will use for binding its http API. + /// default: `0.0.0.0:8000` + pub bind_address: SocketAddr, + + /// Path to assets directory of custom landing page of this node. + #[serde(deserialize_with = "de_maybe_stringified")] + pub landing_page_assets_path: Option<PathBuf>, + + #[serde(default)] + pub metrics_key: Option<String>, +} + #[derive(Debug, Deserialize, PartialEq, Serialize)] pub struct MixNode { /// Version of the mixnode for which this configuration was created. diff --git a/mixnode/src/config/old_config_v1_1_32.rs b/mixnode/src/config/old_config_v1_1_32.rs index f72fb49fd2..1c2f2340d5 100644 --- a/mixnode/src/config/old_config_v1_1_32.rs +++ b/mixnode/src/config/old_config_v1_1_32.rs @@ -1,6 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::config; use crate::config::persistence::paths::MixNodePaths; use crate::config::{Config, Debug, MixNode, Verloc}; use nym_bin_common::logging::LoggingSettings; @@ -81,7 +82,7 @@ impl From<ConfigV1_1_32> for Config { // /\ ADDED // \/ ADDED - host: nym_node::config::Host { + host: config::Host { // this is a very bad default! public_ips: vec![value.mixnode.listening_address], hostname: None, @@ -89,7 +90,7 @@ impl From<ConfigV1_1_32> for Config { // /\ ADDED // \/ ADDED - http: nym_node::config::Http { + http: config::Http { bind_address: SocketAddr::new( value.mixnode.listening_address, value.mixnode.http_api_port, diff --git a/mixnode/src/config/persistence/paths.rs b/mixnode/src/config/persistence/paths.rs index ca5a571b35..d8b81634c7 100644 --- a/mixnode/src/config/persistence/paths.rs +++ b/mixnode/src/config/persistence/paths.rs @@ -32,6 +32,18 @@ impl MixNodePaths { } } + pub fn new_empty() -> Self { + MixNodePaths { + keys: KeysPaths { + private_identity_key_file: Default::default(), + public_identity_key_file: Default::default(), + private_sphinx_key_file: Default::default(), + public_sphinx_key_file: Default::default(), + }, + node_description: Default::default(), + } + } + pub fn private_identity_key(&self) -> &Path { self.keys.private_identity_key() } diff --git a/mixnode/src/error.rs b/mixnode/src/error.rs index 57c4594747..a12979e86e 100644 --- a/mixnode/src/error.rs +++ b/mixnode/src/error.rs @@ -44,7 +44,6 @@ pub enum MixnodeError { source: io::Error, }, - // TODO: in the future this should work the other way, i.e. NymNode depending on Gateway errors #[error(transparent)] - NymNodeError(#[from] nym_node::error::NymNodeError), + NymNodeHttpError(#[from] nym_node_http_api::NymNodeHttpError), } diff --git a/mixnode/src/lib.rs b/mixnode/src/lib.rs new file mode 100644 index 0000000000..18d0a47309 --- /dev/null +++ b/mixnode/src/lib.rs @@ -0,0 +1,9 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +pub mod config; +pub mod error; +pub mod node; + +pub use error::MixnodeError; +pub use node::MixNode; diff --git a/mixnode/src/main.rs b/mixnode/src/main.rs index 9f9cf24176..0530072993 100644 --- a/mixnode/src/main.rs +++ b/mixnode/src/main.rs @@ -10,9 +10,6 @@ use std::sync::OnceLock; use nym_bin_common::logging::{maybe_print_banner, setup_logging}; mod commands; -mod config; -pub(crate) mod error; -mod node; fn pretty_build_info_static() -> &'static str { static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); diff --git a/mixnode/src/node/helpers.rs b/mixnode/src/node/helpers.rs index 54515c053b..612e301dc2 100644 --- a/mixnode/src/node/helpers.rs +++ b/mixnode/src/node/helpers.rs @@ -34,7 +34,7 @@ where } /// Loads identity keys stored on disk -pub(crate) fn load_identity_keys(config: &Config) -> Result<identity::KeyPair, MixnodeError> { +pub fn load_identity_keys(config: &Config) -> Result<identity::KeyPair, MixnodeError> { let identity_paths = KeyPairPath::new( config.storage_paths.keys.private_identity_key(), config.storage_paths.keys.public_identity_key(), @@ -43,7 +43,7 @@ pub(crate) fn load_identity_keys(config: &Config) -> Result<identity::KeyPair, M } /// Loads Sphinx keys stored on disk -pub(crate) fn load_sphinx_keys(config: &Config) -> Result<encryption::KeyPair, MixnodeError> { +pub fn load_sphinx_keys(config: &Config) -> Result<encryption::KeyPair, MixnodeError> { let sphinx_paths = KeyPairPath::new( config.storage_paths.keys.private_encryption_key(), config.storage_paths.keys.public_encryption_key(), diff --git a/mixnode/src/node/http/legacy/description.rs b/mixnode/src/node/http/legacy/description.rs index 29a648c0f2..8921551339 100644 --- a/mixnode/src/node/http/legacy/description.rs +++ b/mixnode/src/node/http/legacy/description.rs @@ -3,7 +3,7 @@ use crate::node::node_description::NodeDescription; use axum::extract::Query; -use nym_node::http::api::{FormattedResponse, OutputParams}; +use nym_http_api_common::{FormattedResponse, OutputParams}; /// Returns a description of the node and why someone might want to delegate stake to it. pub(crate) async fn description( diff --git a/mixnode/src/node/http/legacy/hardware.rs b/mixnode/src/node/http/legacy/hardware.rs index 496d034b0b..a64ca3f5b5 100644 --- a/mixnode/src/node/http/legacy/hardware.rs +++ b/mixnode/src/node/http/legacy/hardware.rs @@ -3,7 +3,7 @@ use axum::extract::Query; use cupid::TopologyType; -use nym_node::http::api::{FormattedResponse, OutputParams}; +use nym_http_api_common::{FormattedResponse, OutputParams}; use serde::Serialize; use sysinfo::{System, SystemExt}; diff --git a/mixnode/src/node/http/legacy/state.rs b/mixnode/src/node/http/legacy/state.rs index 914f6a856a..d51d8741b2 100644 --- a/mixnode/src/node/http/legacy/state.rs +++ b/mixnode/src/node/http/legacy/state.rs @@ -1,25 +1,24 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::node::http::legacy::verloc::VerlocState; -use crate::node::node_statistics::SharedNodeStats; use axum::extract::FromRef; +use nym_node_http_api::state::metrics::{SharedMixingStats, SharedVerlocStats}; // this is a temporary thing for the transition period #[derive(Clone, Default)] pub(crate) struct MixnodeAppState { - pub(crate) verloc: VerlocState, - pub(crate) stats: SharedNodeStats, + pub(crate) verloc: SharedVerlocStats, + pub(crate) stats: SharedMixingStats, pub(crate) metrics_key: Option<String>, } -impl FromRef<MixnodeAppState> for VerlocState { +impl FromRef<MixnodeAppState> for SharedVerlocStats { fn from_ref(app_state: &MixnodeAppState) -> Self { app_state.verloc.clone() } } -impl FromRef<MixnodeAppState> for SharedNodeStats { +impl FromRef<MixnodeAppState> for SharedMixingStats { fn from_ref(app_state: &MixnodeAppState) -> Self { app_state.stats.clone() } diff --git a/mixnode/src/node/http/legacy/stats.rs b/mixnode/src/node/http/legacy/stats.rs index c986acee2b..8898b8ab74 100644 --- a/mixnode/src/node/http/legacy/stats.rs +++ b/mixnode/src/node/http/legacy/stats.rs @@ -1,14 +1,14 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::node::node_statistics::{NodeStatsSimple, SharedNodeStats}; - use axum::{ extract::{Query, State}, http::HeaderMap, }; +use nym_http_api_common::{FormattedResponse, Output}; use nym_metrics::metrics; -use nym_node::http::api::{FormattedResponse, Output}; +use nym_node_http_api::api::api_requests::v1::metrics::models::MixingStats; +use nym_node_http_api::state::metrics::SharedMixingStats; use serde::{Deserialize, Serialize}; use super::state::MixnodeAppState; @@ -17,7 +17,7 @@ use super::state::MixnodeAppState; #[serde(untagged)] pub enum NodeStatsResponse { Full(String), - Simple(NodeStatsSimple), + Simple(MixingStats), } pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: HeaderMap) -> String { @@ -38,7 +38,7 @@ pub(crate) async fn metrics(State(state): State<MixnodeAppState>, headers: Heade pub(crate) async fn stats( Query(params): Query<StatsQueryParams>, - State(stats): State<SharedNodeStats>, + State(stats): State<SharedMixingStats>, ) -> MixnodeStatsResponse { let output = params.output.unwrap_or_default(); @@ -47,12 +47,11 @@ pub(crate) async fn stats( output.to_response(response) } -async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse { - let snapshot_data = stats.clone_data().await; +async fn generate_stats(full: bool, stats: SharedMixingStats) -> NodeStatsResponse { if full { NodeStatsResponse::Full(metrics!()) } else { - NodeStatsResponse::Simple(snapshot_data.simplify()) + NodeStatsResponse::Simple(stats.read().await.as_response()) } } diff --git a/mixnode/src/node/http/legacy/verloc.rs b/mixnode/src/node/http/legacy/verloc.rs index eb5800bccc..8376081b4e 100644 --- a/mixnode/src/node/http/legacy/verloc.rs +++ b/mixnode/src/node/http/legacy/verloc.rs @@ -2,30 +2,18 @@ // SPDX-License-Identifier: GPL-3.0-only use axum::extract::{Query, State}; -use nym_mixnode_common::verloc::{AtomicVerlocResult, VerlocResult}; -use nym_node::http::api::{FormattedResponse, OutputParams}; - -#[derive(Clone, Default)] -pub(crate) struct VerlocState { - shared: AtomicVerlocResult, -} - -impl VerlocState { - pub fn new(atomic_verloc_result: AtomicVerlocResult) -> Self { - VerlocState { - shared: atomic_verloc_result, - } - } -} +use nym_http_api_common::{FormattedResponse, OutputParams}; +use nym_node_http_api::api::api_requests::v1::metrics::models::VerlocResultData; +use nym_node_http_api::state::metrics::SharedVerlocStats; /// Provides verifiable location (verloc) measurements for this mixnode - a list of the /// round-trip times, in milliseconds, for all other mixnodes that this node knows about. pub(crate) async fn verloc( - State(verloc): State<VerlocState>, + State(verloc): State<SharedVerlocStats>, Query(output): Query<OutputParams>, ) -> MixnodeVerlocResponse { let output = output.output.unwrap_or_default(); - output.to_response(verloc.shared.clone_data().await) + output.to_response(verloc.read().await.current_run_data.clone()) } -pub type MixnodeVerlocResponse = FormattedResponse<VerlocResult>; +pub type MixnodeVerlocResponse = FormattedResponse<VerlocResultData>; diff --git a/mixnode/src/node/http/mod.rs b/mixnode/src/node/http/mod.rs index 55ca880e63..bb4fc37cc9 100644 --- a/mixnode/src/node/http/mod.rs +++ b/mixnode/src/node/http/mod.rs @@ -1,17 +1,16 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only use crate::config::Config; use crate::error::MixnodeError; -use crate::node::http::legacy::verloc::VerlocState; use crate::node::node_description::NodeDescription; -use crate::node::node_statistics::SharedNodeStats; use log::info; use nym_bin_common::bin_info_owned; use nym_crypto::asymmetric::{encryption, identity}; -use nym_node::error::NymNodeError; -use nym_node::http::api::api_requests; -use nym_node::http::api::api_requests::SignedHostInformation; +use nym_node_http_api::api::api_requests; +use nym_node_http_api::api::api_requests::SignedHostInformation; +use nym_node_http_api::state::metrics::{SharedMixingStats, SharedVerlocStats}; +use nym_node_http_api::NymNodeHttpError; use nym_task::TaskClient; pub(crate) mod legacy; @@ -25,13 +24,14 @@ fn load_host_details( ip_address: config.host.public_ips.clone(), hostname: config.host.hostname.clone(), keys: api_requests::v1::node::models::HostKeys { - ed25519: identity_keypair.public_key().to_base58_string(), - x25519: sphinx_key.to_base58_string(), + ed25519_identity: identity_keypair.public_key().to_base58_string(), + x25519_sphinx: sphinx_key.to_base58_string(), + x25519_noise: "".to_string(), }, }; let signed_info = SignedHostInformation::new(host_info, identity_keypair.private_key()) - .map_err(NymNodeError::from)?; + .map_err(NymNodeHttpError::from)?; Ok(signed_info) } @@ -71,13 +71,13 @@ impl<'a> HttpApiBuilder<'a> { } #[must_use] - pub(crate) fn with_verloc(mut self, verloc: VerlocState) -> Self { + pub(crate) fn with_verloc(mut self, verloc: SharedVerlocStats) -> Self { self.legacy_mixnode.verloc = verloc; self } #[must_use] - pub(crate) fn with_mixing_stats(mut self, stats: SharedNodeStats) -> Self { + pub(crate) fn with_mixing_stats(mut self, stats: SharedMixingStats) -> Self { self.legacy_mixnode.stats = stats; self } @@ -92,7 +92,7 @@ impl<'a> HttpApiBuilder<'a> { let bind_address = self.mixnode_config.http.bind_address; info!("Starting HTTP API on http://{bind_address}",); - let config = nym_node::http::Config::new( + let config = nym_node_http_api::Config::new( bin_info_owned!(), load_host_details( self.mixnode_config, @@ -103,7 +103,7 @@ impl<'a> HttpApiBuilder<'a> { .with_mixnode(load_mixnode_details(self.mixnode_config)?) .with_landing_page_assets(self.mixnode_config.http.landing_page_assets_path.as_ref()); - let router = nym_node::http::NymNodeRouter::new(config, None); + let router = nym_node_http_api::NymNodeRouter::new(config, None, None); let server = router .with_merged(legacy::routes(self.legacy_mixnode, self.legacy_descriptor)) .build_server(&bind_address)? diff --git a/mixnode/src/node/mod.rs b/mixnode/src/node/mod.rs index 045c83211f..8674d6ffe0 100644 --- a/mixnode/src/node/mod.rs +++ b/mixnode/src/node/mod.rs @@ -4,30 +4,29 @@ use crate::config::Config; use crate::error::MixnodeError; use crate::node::helpers::{load_identity_keys, load_sphinx_keys}; -use crate::node::http::legacy::verloc::VerlocState; use crate::node::http::HttpApiBuilder; use crate::node::listener::connection_handler::packet_processing::PacketProcessor; use crate::node::listener::connection_handler::ConnectionHandler; use crate::node::listener::Listener; use crate::node::node_description::NodeDescription; -use crate::node::node_statistics::SharedNodeStats; use crate::node::packet_delayforwarder::{DelayForwarder, PacketDelayForwardSender}; use log::{error, info, warn}; use nym_bin_common::output_format::OutputFormat; -use nym_bin_common::version_checker::parse_version; use nym_crypto::asymmetric::{encryption, identity}; -use nym_mixnode_common::verloc::{self, AtomicVerlocResult, VerlocMeasurer}; -use nym_task::{TaskClient, TaskManager}; +use nym_mixnode_common::verloc; +use nym_mixnode_common::verloc::VerlocMeasurer; +use nym_node_http_api::state::metrics::{SharedMixingStats, SharedVerlocStats}; +use nym_task::{TaskClient, TaskHandle}; use rand::seq::SliceRandom; use rand::thread_rng; use std::net::SocketAddr; use std::process; use std::sync::Arc; -pub(crate) mod helpers; +pub mod helpers; mod http; mod listener; -pub(crate) mod node_description; +pub mod node_description; mod node_statistics; mod packet_delayforwarder; @@ -37,24 +36,67 @@ pub struct MixNode { descriptor: NodeDescription, identity_keypair: Arc<identity::KeyPair>, sphinx_keypair: Arc<encryption::KeyPair>, + + run_http_server: bool, + task_client: Option<TaskClient>, + mixing_stats: Option<SharedMixingStats>, + verloc_stats: Option<SharedVerlocStats>, } impl MixNode { pub fn new(config: Config) -> Result<Self, MixnodeError> { Ok(MixNode { + run_http_server: false, descriptor: Self::load_node_description(&config), identity_keypair: Arc::new(load_identity_keys(&config)?), sphinx_keypair: Arc::new(load_sphinx_keys(&config)?), config, + task_client: None, + mixing_stats: None, + verloc_stats: None, }) } + pub fn new_loaded( + config: Config, + descriptor: NodeDescription, + identity_keypair: Arc<identity::KeyPair>, + sphinx_keypair: Arc<encryption::KeyPair>, + ) -> Self { + MixNode { + run_http_server: false, + task_client: None, + config, + descriptor, + identity_keypair, + sphinx_keypair, + mixing_stats: None, + verloc_stats: None, + } + } + + pub fn disable_http_server(&mut self) { + self.run_http_server = false + } + + pub fn set_task_client(&mut self, task_client: TaskClient) { + self.task_client = Some(task_client) + } + + pub fn set_mixing_stats(&mut self, mixing_stats: SharedMixingStats) { + self.mixing_stats = Some(mixing_stats); + } + + pub fn set_verloc_stats(&mut self, verloc_stats: SharedVerlocStats) { + self.verloc_stats = Some(verloc_stats) + } + fn load_node_description(config: &Config) -> NodeDescription { NodeDescription::load_from_file(&config.storage_paths.node_description).unwrap_or_default() } /// Prints relevant node details to the console - pub(crate) fn print_node_details(&self, output: OutputFormat) { + pub fn print_node_details(&self, output: OutputFormat) { let node_details = nym_types::mixnode::MixnodeNodeDetailsResponse { identity_key: self.identity_keypair.public_key().to_base58_string(), sphinx_key: self.sphinx_keypair.public_key().to_base58_string(), @@ -70,13 +112,13 @@ impl MixNode { fn start_http_api( &self, - atomic_verloc_result: AtomicVerlocResult, - node_stats_pointer: SharedNodeStats, + atomic_verloc_result: SharedVerlocStats, + node_stats_pointer: SharedMixingStats, metrics_key: Option<&String>, task_client: TaskClient, ) -> Result<(), MixnodeError> { HttpApiBuilder::new(&self.config, &self.identity_keypair, &self.sphinx_keypair) - .with_verloc(VerlocState::new(atomic_verloc_result)) + .with_verloc(atomic_verloc_result) .with_mixing_stats(node_stats_pointer) .with_metrics_key(metrics_key) .with_descriptor(self.descriptor.clone()) @@ -84,19 +126,21 @@ impl MixNode { } fn start_node_stats_controller( - &self, + &mut self, shutdown: TaskClient, - ) -> (SharedNodeStats, node_statistics::UpdateSender) { + ) -> (SharedMixingStats, node_statistics::UpdateSender) { info!("Starting node stats controller..."); + let mixing_stats = self.mixing_stats.take().unwrap_or_default(); + let controller = node_statistics::Controller::new( self.config.debug.node_stats_logging_delay, self.config.debug.node_stats_updating_delay, + mixing_stats.clone(), shutdown, ); - let node_stats_pointer = controller.get_node_stats_data_pointer(); let update_sender = controller.start(); - (node_stats_pointer, update_sender) + (mixing_stats, update_sender) } fn start_socket_listener( @@ -147,22 +191,10 @@ impl MixNode { packet_sender } - fn start_verloc_measurements(&self, shutdown: TaskClient) -> AtomicVerlocResult { + fn start_verloc_measurements(&mut self, shutdown: TaskClient) -> SharedVerlocStats { info!("Starting the round-trip-time measurer..."); - // this is a sanity check to make sure we didn't mess up with the minimum version at some point - // and whether the user has run update if they're using old config - // if this code exists in the node, it MUST BE compatible - let config_version = parse_version(&self.config.mixnode.version) - .expect("malformed version in the config file"); - let minimum_version = parse_version(verloc::MINIMUM_NODE_VERSION).unwrap(); - if config_version < minimum_version { - error!("You seem to have not updated your mixnode configuration file - please run `upgrade` before attempting again"); - process::exit(1) - } - // use the same binding address with the HARDCODED port for time being (I don't like that approach personally) - let listening_address = SocketAddr::new( self.config.mixnode.listening_address, self.config.mixnode.verloc_port, @@ -180,11 +212,13 @@ impl MixNode { .nym_api_urls(self.config.get_nym_api_endpoints()) .build(); + let verloc_state = self.verloc_stats.take().unwrap_or_default(); let mut verloc_measurer = VerlocMeasurer::new(config, Arc::clone(&self.identity_keypair), shutdown); - let atomic_verloc_results = verloc_measurer.get_verloc_results_pointer(); + verloc_measurer.set_shared_state(verloc_state.clone()); + tokio::spawn(async move { verloc_measurer.run().await }); - atomic_verloc_results + verloc_state } fn random_api_client(&self) -> nym_validator_client::NymApiClient { @@ -217,8 +251,8 @@ impl MixNode { }) } - async fn wait_for_interrupt(&self, mut shutdown: TaskManager) { - let _res = shutdown.catch_interrupt().await; + async fn wait_for_interrupt(&self, shutdown: TaskHandle) { + let _res = shutdown.wait_for_shutdown().await; log::info!("Stopping nym mixnode"); } @@ -229,34 +263,42 @@ impl MixNode { warn!("You seem to have bonded your mixnode before starting it - that's highly unrecommended as in the future it might result in slashing"); } - let shutdown = TaskManager::default(); + // Shutdown notifier for signalling tasks to stop + let shutdown = self + .task_client + .take() + .map(Into::<TaskHandle>::into) + .unwrap_or_default() + .name_if_unnamed("mixnode"); - let (node_stats_pointer, node_stats_update_sender) = self - .start_node_stats_controller(shutdown.subscribe().named("node_statistics::Controller")); + let (node_stats_pointer, node_stats_update_sender) = + self.start_node_stats_controller(shutdown.fork("node_statistics::Controller")); let delay_forwarding_channel = self.start_packet_delay_forwarder( node_stats_update_sender.clone(), - shutdown.subscribe().named("DelayForwarder"), + shutdown.fork("DelayForwarder"), ); self.start_socket_listener( node_stats_update_sender, delay_forwarding_channel, - shutdown.subscribe().named("Listener"), + shutdown.fork("Listener"), ); - let atomic_verloc_results = - self.start_verloc_measurements(shutdown.subscribe().named("VerlocMeasurer")); + let atomic_verloc_results = self.start_verloc_measurements(shutdown.fork("VerlocMeasurer")); // Rocket handles shutdown on it's own, but its shutdown handling should be incorporated // with that of the rest of the tasks. // Currently it's runtime is forcefully terminated once the mixnode exits. - self.start_http_api( - atomic_verloc_results, - node_stats_pointer, - self.config.metrics_key(), - shutdown.subscribe().named("http-api"), - )?; + if self.run_http_server { + self.start_http_api( + atomic_verloc_results, + node_stats_pointer, + self.config.metrics_key(), + shutdown.fork("http-api"), + )?; + } info!("Finished nym mixnode startup procedure - it should now be able to receive mix traffic!"); self.wait_for_interrupt(shutdown).await; + Ok(()) } } diff --git a/mixnode/src/node/node_description.rs b/mixnode/src/node/node_description.rs index 6c41b28f24..c2d6bbacf4 100644 --- a/mixnode/src/node/node_description.rs +++ b/mixnode/src/node/node_description.rs @@ -3,15 +3,23 @@ use serde::Deserialize; use serde::Serialize; +use std::fs::create_dir_all; use std::path::Path; use std::{fs, io}; #[derive(Clone, Debug, Deserialize, PartialEq, Eq, Serialize)] pub struct NodeDescription { - pub(crate) name: String, - pub(crate) description: String, - pub(crate) link: String, - pub(crate) location: String, + #[serde(default)] + pub name: String, + + #[serde(default)] + pub description: String, + + #[serde(default)] + pub link: String, + + #[serde(default)] + pub location: String, } impl Default for NodeDescription { @@ -26,7 +34,7 @@ impl Default for NodeDescription { } impl NodeDescription { - pub(crate) fn load_from_file<P: AsRef<Path>>(path: P) -> io::Result<NodeDescription> { + pub fn load_from_file<P: AsRef<Path>>(path: P) -> io::Result<NodeDescription> { // let description_file_path: PathBuf = [config_path.to_str().unwrap(), DESCRIPTION_FILE] // .iter() // .collect(); @@ -36,15 +44,14 @@ impl NodeDescription { toml::from_str(&toml).map_err(|toml_err| io::Error::new(io::ErrorKind::Other, toml_err)) } - pub(crate) fn save_to_file<P: AsRef<Path>>( - description: &NodeDescription, - path: P, - ) -> io::Result<()> { + pub fn save_to_file<P: AsRef<Path>>(&self, path: P) -> io::Result<()> { // let description_file_path: PathBuf = [config_path.to_str().unwrap(), DESCRIPTION_FILE] // .iter() // .collect(); - let description_toml = - toml::to_string(description).expect("could not encode description to toml"); + let description_toml = toml::to_string(self).expect("could not encode description to toml"); + if let Some(parent) = path.as_ref().parent() { + create_dir_all(parent)?; + } fs::write(path, description_toml)?; Ok(()) } diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 9ee8d6b850..7b84f89529 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -8,50 +8,27 @@ use futures::channel::mpsc; use futures::lock::Mutex; use futures::StreamExt; use log::{debug, info, trace}; -use serde::Serialize; +use nym_node_http_api::state::metrics::SharedMixingStats; use std::collections::HashMap; use std::ops::DerefMut; use std::sync::atomic::{AtomicU64, Ordering}; use std::sync::Arc; -use std::time::{Duration, SystemTime}; -use tokio::sync::{RwLock, RwLockReadGuard}; +use std::time::Duration; +use time::OffsetDateTime; // convenience aliases type PacketsMap = HashMap<String, u64>; type PacketDataReceiver = mpsc::UnboundedReceiver<PacketEvent>; type PacketDataSender = mpsc::UnboundedSender<PacketEvent>; -#[derive(Clone, Default)] -pub(crate) struct SharedNodeStats { - inner: Arc<RwLock<NodeStats>>, +trait MixingStatsUpdateExt { + async fn update(&self, new_received: u64, new_sent: PacketsMap, new_dropped: PacketsMap); } -impl SharedNodeStats { - pub(crate) fn new() -> Self { - let now = SystemTime::now(); - - SharedNodeStats { - inner: Arc::new(RwLock::new(NodeStats { - update_time: now, - previous_update_time: now, - packets_received_since_startup: 0, - packets_sent_since_startup_all: 0, - packets_dropped_since_startup_all: 0, - packets_received_since_last_update: 0, - packets_sent_since_last_update: HashMap::new(), - packets_explicitly_dropped_since_last_update: HashMap::new(), - })), - } - } - - pub(crate) async fn update( - &self, - new_received: u64, - new_sent: PacketsMap, - new_dropped: PacketsMap, - ) { - let mut guard = self.inner.write().await; - let snapshot_time = SystemTime::now(); +impl MixingStatsUpdateExt for SharedMixingStats { + async fn update(&self, new_received: u64, new_sent: PacketsMap, new_dropped: PacketsMap) { + let mut guard = self.write().await; + let snapshot_time = OffsetDateTime::now_utc(); guard.previous_update_time = guard.update_time; guard.update_time = snapshot_time; @@ -79,88 +56,6 @@ impl SharedNodeStats { guard.packets_sent_since_last_update = new_sent; guard.packets_explicitly_dropped_since_last_update = new_dropped; } - - pub(crate) async fn clone_data(&self) -> NodeStats { - self.inner.read().await.clone() - } - - async fn read(&self) -> RwLockReadGuard<'_, NodeStats> { - self.inner.read().await - } -} - -#[derive(Clone)] -pub struct NodeStats { - update_time: SystemTime, - - previous_update_time: SystemTime, - - packets_received_since_startup: u64, - packets_sent_since_startup_all: u64, - packets_dropped_since_startup_all: u64, - packets_received_since_last_update: u64, - // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_last_update: PacketsMap, - // we know for sure we dropped packets to those destinations - packets_explicitly_dropped_since_last_update: PacketsMap, -} - -impl Default for NodeStats { - fn default() -> Self { - NodeStats { - update_time: SystemTime::UNIX_EPOCH, - previous_update_time: SystemTime::UNIX_EPOCH, - packets_received_since_startup: 0, - packets_sent_since_startup_all: 0, - packets_dropped_since_startup_all: 0, - packets_received_since_last_update: 0, - packets_sent_since_last_update: Default::default(), - packets_explicitly_dropped_since_last_update: Default::default(), - } - } -} - -impl NodeStats { - pub(crate) fn simplify(&self) -> NodeStatsSimple { - NodeStatsSimple { - update_time: self.update_time, - previous_update_time: self.previous_update_time, - packets_received_since_startup: self.packets_received_since_startup, - packets_sent_since_startup: self.packets_sent_since_startup_all, - packets_explicitly_dropped_since_startup: self.packets_dropped_since_startup_all, - packets_received_since_last_update: self.packets_received_since_last_update, - packets_sent_since_last_update: self.packets_sent_since_last_update.values().sum(), - packets_explicitly_dropped_since_last_update: self - .packets_explicitly_dropped_since_last_update - .values() - .sum(), - } - } -} - -#[derive(Serialize, Clone)] -pub struct NodeStatsSimple { - #[serde(serialize_with = "humantime_serde::serialize")] - update_time: SystemTime, - - #[serde(serialize_with = "humantime_serde::serialize")] - previous_update_time: SystemTime, - - packets_received_since_startup: u64, - - // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_startup: u64, - - // we know for sure we dropped those packets - packets_explicitly_dropped_since_startup: u64, - - packets_received_since_last_update: u64, - - // note: sent does not imply forwarded. We don't know if it was delivered successfully - packets_sent_since_last_update: u64, - - // we know for sure we dropped those packets - packets_explicitly_dropped_since_last_update: u64, } pub(crate) enum PacketEvent { @@ -305,7 +200,7 @@ impl UpdateSender { struct StatsUpdater { updating_delay: Duration, current_packet_data: CurrentPacketData, - current_stats: SharedNodeStats, + current_stats: SharedMixingStats, shutdown: TaskClient, } @@ -313,7 +208,7 @@ impl StatsUpdater { fn new( updating_delay: Duration, current_packet_data: CurrentPacketData, - current_stats: SharedNodeStats, + current_stats: SharedMixingStats, shutdown: TaskClient, ) -> Self { StatsUpdater { @@ -347,12 +242,12 @@ impl StatsUpdater { // since we have the http endpoint now? struct PacketStatsConsoleLogger { logging_delay: Duration, - stats: SharedNodeStats, + stats: SharedMixingStats, shutdown: TaskClient, } impl PacketStatsConsoleLogger { - fn new(logging_delay: Duration, stats: SharedNodeStats, shutdown: TaskClient) -> Self { + fn new(logging_delay: Duration, stats: SharedMixingStats, shutdown: TaskClient) -> Self { PacketStatsConsoleLogger { logging_delay, stats, @@ -365,9 +260,10 @@ impl PacketStatsConsoleLogger { // it's super unlikely this will ever fail, but anything involving time is super weird // so let's just guard against it - if let Ok(time_difference) = stats.update_time.duration_since(stats.previous_update_time) { + let time_difference = stats.update_time - stats.previous_update_time; + if time_difference.is_positive() { // we honestly don't care if it was 30.000828427s or 30.002461449s, 30s is enough - let difference_secs = time_difference.as_secs(); + let difference_secs = time_difference.whole_seconds(); info!( "Since startup mixed {} packets! ({} in last {} seconds)", @@ -449,20 +345,17 @@ pub struct Controller { /// Responsible for updating stats at given interval stats_updater: StatsUpdater, - - /// Pointer to the current node stats - node_stats: SharedNodeStats, } impl Controller { pub(crate) fn new( logging_delay: Duration, stats_updating_delay: Duration, + mixing_stats: SharedMixingStats, shutdown: TaskClient, ) -> Self { let (sender, receiver) = mpsc::unbounded(); let shared_packet_data = CurrentPacketData::new(); - let shared_node_stats = SharedNodeStats::new(); Controller { update_handler: UpdateHandler::new( @@ -473,22 +366,15 @@ impl Controller { update_sender: UpdateSender::new(sender), console_logger: PacketStatsConsoleLogger::new( logging_delay, - shared_node_stats.clone(), + mixing_stats.clone(), shutdown.clone(), ), stats_updater: StatsUpdater::new( stats_updating_delay, shared_packet_data, - shared_node_stats.clone(), + mixing_stats.clone(), shutdown, ), - node_stats: shared_node_stats, - } - } - - pub(crate) fn get_node_stats_data_pointer(&self) -> SharedNodeStats { - SharedNodeStats { - inner: Arc::clone(&self.node_stats.inner), } } @@ -518,10 +404,14 @@ mod tests { let logging_delay = Duration::from_millis(20); let stats_updating_delay = Duration::from_millis(10); let shutdown = TaskManager::default(); - let node_stats_controller = - Controller::new(logging_delay, stats_updating_delay, shutdown.subscribe()); + let stats = SharedMixingStats::new(); + let node_stats_controller = Controller::new( + logging_delay, + stats_updating_delay, + stats.clone(), + shutdown.subscribe(), + ); - let node_stats_pointer = node_stats_controller.get_node_stats_data_pointer(); let update_sender = node_stats_controller.start(); tokio::time::pause(); @@ -534,7 +424,7 @@ mod tests { tokio::task::yield_now().await; // Get output (stats) - let stats = node_stats_pointer.read().await; + let stats = stats.read().await; assert_eq!(&stats.packets_sent_since_startup_all, &2); assert_eq!(&stats.packets_sent_since_last_update.get("foo"), &Some(&2)); assert_eq!(&stats.packets_sent_since_last_update.len(), &1); diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 68b94fdc0a..83401e0e65 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -25,7 +25,7 @@ console-subscriber = { version = "0.1.1", optional = true } # validator-api need dirs = "4.0" futures = { workspace = true } itertools = "0.12.0" -humantime-serde = "1.0" +humantime-serde = { workspace = true } k256 = { version = "*", features = ["ecdsa-core"] } # needed for the Verifier trait; pull whatever version is used by other dependencies log = { workspace = true } pin-project = "1.0" diff --git a/nym-connect/desktop/Cargo.lock b/nym-connect/desktop/Cargo.lock index 5bf10c86c9..be63448ae5 100644 --- a/nym-connect/desktop/Cargo.lock +++ b/nym-connect/desktop/Cargo.lock @@ -301,7 +301,7 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -318,7 +318,7 @@ checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -392,6 +392,12 @@ dependencies = [ "rustc-demangle", ] +[[package]] +name = "base16ct" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "349a06037c7bf932dd7e7d1f653678b2038b9ad46a74102f1fc7bd7872678cce" + [[package]] name = "base16ct" version = "0.2.0" @@ -433,7 +439,7 @@ checksum = "7e141fb0f8be1c7b45887af94c88b182472b57c96b56773250ae00cd6a14a164" dependencies = [ "bs58 0.5.0", "hmac 0.12.1", - "k256", + "k256 0.13.1", "once_cell", "pbkdf2", "rand_core 0.6.4", @@ -537,6 +543,15 @@ dependencies = [ "generic-array 0.14.7", ] +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array 0.14.7", +] + [[package]] name = "blocking" version = "1.3.1" @@ -558,8 +573,8 @@ version = "0.8.0" source = "git+https://github.com/jstuczyn/bls12_381?branch=feature/gt-serialization-0.8.0#c4543fde7d02efea6ecfcf22e14476ddb516b483" dependencies = [ "digest 0.9.0", - "ff", - "group", + "ff 0.13.0", + "group 0.13.0", "pairing", "rand_core 0.6.4", "subtle 2.4.1", @@ -568,9 +583,9 @@ dependencies = [ [[package]] name = "bnum" -version = "0.8.1" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab9008b6bb9fc80b5277f2fe481c09e828743d9151203e804583eb4c9e15b31d" +checksum = "845141a4fade3f790628b7daaaa298a25b204fb28907eb54febe5142db6ce653" [[package]] name = "brotli" @@ -854,7 +869,7 @@ dependencies = [ "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1028,9 +1043,9 @@ source = "git+https://github.com/jstuczyn/cosmos-rust?branch=nym-temp/all-valida dependencies = [ "bip32", "cosmos-sdk-proto", - "ecdsa", + "ecdsa 0.16.8", "eyre", - "k256", + "k256 0.13.1", "rand_core 0.6.4", "serde", "serde_json", @@ -1043,32 +1058,31 @@ dependencies = [ [[package]] name = "cosmwasm-crypto" -version = "1.5.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9934c79e58d9676edfd592557dee765d2a6ef54c09d5aa2edb06156b00148966" +checksum = "7e272708a9745dad8b591ef8a718571512130f2b39b33e3d7a27c558e3069394" dependencies = [ "digest 0.10.7", - "ecdsa", "ed25519-zebra", - "k256", + "k256 0.11.6", "rand_core 0.6.4", "thiserror", ] [[package]] name = "cosmwasm-derive" -version = "1.5.3" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc5e72e330bd3bdab11c52b5ecbdeb6a8697a004c57964caeb5d876f0b088b3c" +checksum = "296db6a3caca5283425ae0cf347f4e46999ba3f6620dbea8939a0e00347831ce" dependencies = [ "syn 1.0.109", ] [[package]] name = "cosmwasm-schema" -version = "1.4.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11ae2e971fb831d0c4fa3c8c3d2291cdbdd73786a73d65196dbf983d9b2468af" +checksum = "bb6b2fb76758ef59cddc77f2e2ae91c22f77da49037e9f182e9c2833f0e959b1" dependencies = [ "cosmwasm-schema-derive", "schemars", @@ -1079,9 +1093,9 @@ dependencies = [ [[package]] name = "cosmwasm-schema-derive" -version = "1.4.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cadc57fd0825b85bc2f9b972c17da718b9efb4bc17e5935cc2d6036324f853d" +checksum = "2bfa39422f0d9f1c9a6fd3711573258495314dfa3aae738ea825ecd9964bc659" dependencies = [ "proc-macro2", "quote", @@ -1090,11 +1104,11 @@ dependencies = [ [[package]] name = "cosmwasm-std" -version = "1.4.3" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e98e19fae6c3f468412f731274b0f9434602722009d6a77432d39c7c4bb09202" +checksum = "1f6dc2ee23313add5ecacc3ccac217b9967ad9d2d11bd56e5da6aa65a9da6138" dependencies = [ - "base64 0.21.4", + "base64 0.13.1", "bnum", "cosmwasm-crypto", "cosmwasm-derive", @@ -1194,6 +1208,18 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "crypto-bigint" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef2b4b23cddf68b89b8f8069890e8c270d54e2d5fe1b143820234805e4cb17ef" +dependencies = [ + "generic-array 0.14.7", + "rand_core 0.6.4", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "crypto-bigint" version = "0.5.2" @@ -1261,7 +1287,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13b588ba4ac1a99f7f2964d24b3d896ddc6bf847ee3855dbd4366f058cfcd331" dependencies = [ "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1330,7 +1356,7 @@ checksum = "83fdaf97f4804dcebfa5862639bc9ce4121e82140bec2a987ac5140294865b5b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1363,9 +1389,9 @@ dependencies = [ [[package]] name = "cw-storage-plus" -version = "1.2.0" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5ff29294ee99373e2cd5fd21786a3c0ced99a52fec2ca347d565489c61b723c" +checksum = "3f0e92a069d62067f3472c62e30adedb4cab1754725c0f2a682b3128d2bf3c79" dependencies = [ "cosmwasm-std", "schemars", @@ -1382,31 +1408,30 @@ dependencies = [ "cosmwasm-std", "cw2", "schemars", - "semver 1.0.22", + "semver 1.0.18", "serde", "thiserror", ] [[package]] name = "cw2" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6c120b24fbbf5c3bedebb97f2cc85fbfa1c3287e09223428e7e597b5293c1fa" +checksum = "29ac2dc7a55ad64173ca1e0a46697c31b7a5c51342f55a1e84a724da4eb99908" dependencies = [ "cosmwasm-schema", "cosmwasm-std", "cw-storage-plus", "schemars", - "semver 1.0.22", "serde", "thiserror", ] [[package]] name = "cw20" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "526e39bb20534e25a1cd0386727f0038f4da294e5e535729ba3ef54055246abd" +checksum = "011c45920f8200bd5d32d4fe52502506f64f2f75651ab408054d4cfc75ca3a9b" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1417,9 +1442,9 @@ dependencies = [ [[package]] name = "cw3" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2967fbd073d4b626dd9e7148e05a84a3bebd9794e71342e12351110ffbb12395" +checksum = "171af3d9127de6805a7dd819fb070c7d2f6c3ea85f4193f42cef259f0a7f33d5" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1432,9 +1457,9 @@ dependencies = [ [[package]] name = "cw4" -version = "1.1.2" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24754ff6e45f2a1c60adc409d9b2eb87666012c44021329141ffaab3388fccd2" +checksum = "a398696307efadaaa2d0850076f865fa706c959d493cb4203314f72be6b77a64" dependencies = [ "cosmwasm-schema", "cosmwasm-std", @@ -1464,7 +1489,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1475,7 +1500,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5" dependencies = [ "darling_core", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1507,6 +1532,16 @@ dependencies = [ "uuid 1.4.1", ] +[[package]] +name = "der" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1a467a65c5e759bce6e65eaf91cc29f466cdc57cb65777bd646872a8a1fd4de" +dependencies = [ + "const-oid", + "zeroize", +] + [[package]] name = "der" version = "0.7.8" @@ -1682,19 +1717,31 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "304e6508efa593091e97a9abbc10f90aa7ca635b6d2784feff3c89d41dd12272" +[[package]] +name = "ecdsa" +version = "0.14.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413301934810f597c1d19ca71c8710e99a3f1ba28a0d2ebc01551a2daeea3c5c" +dependencies = [ + "der 0.6.1", + "elliptic-curve 0.12.3", + "rfc6979 0.3.1", + "signature 1.6.4", +] + [[package]] name = "ecdsa" version = "0.16.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" dependencies = [ - "der", + "der 0.7.8", "digest 0.10.7", - "elliptic-curve", - "rfc6979", + "elliptic-curve 0.13.5", + "rfc6979 0.4.0", "serdect", "signature 2.1.0", - "spki", + "spki 0.7.2", ] [[package]] @@ -1713,7 +1760,7 @@ version = "2.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "60f6d271ca33075c88028be6f04d502853d63a5ece419d269c15315d4fc1cf1d" dependencies = [ - "pkcs8", + "pkcs8 0.10.2", "signature 2.1.0", ] @@ -1766,21 +1813,41 @@ version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +[[package]] +name = "elliptic-curve" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7bb888ab5300a19b8e5bceef25ac745ad065f3c9f7efc6de1b91958110891d3" +dependencies = [ + "base16ct 0.1.1", + "crypto-bigint 0.4.9", + "der 0.6.1", + "digest 0.10.7", + "ff 0.12.1", + "generic-array 0.14.7", + "group 0.12.1", + "pkcs8 0.9.0", + "rand_core 0.6.4", + "sec1 0.3.0", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "elliptic-curve" version = "0.13.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "968405c8fdc9b3bf4df0a6638858cc0b52462836ab6b1c87377785dd09cf1c0b" dependencies = [ - "base16ct", - "crypto-bigint", + "base16ct 0.2.0", + "crypto-bigint 0.5.2", "digest 0.10.7", - "ff", + "ff 0.13.0", "generic-array 0.14.7", - "group", - "pkcs8", + "group 0.13.0", + "pkcs8 0.10.2", "rand_core 0.6.4", - "sec1", + "sec1 0.7.3", "serdect", "subtle 2.4.1", "zeroize", @@ -1832,7 +1899,7 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -1925,6 +1992,16 @@ dependencies = [ "log", ] +[[package]] +name = "ff" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d013fc25338cc558c5c2cfbad646908fb23591e2404481826742b651c9af7160" +dependencies = [ + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "ff" version = "0.13.0" @@ -2151,7 +2228,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -2508,13 +2585,24 @@ dependencies = [ "system-deps 6.1.1", ] +[[package]] +name = "group" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfbfb3a6cfbd390d5c9564ab283a0349b9b9fcd46a706c1eb10e0db70bfbac7" +dependencies = [ + "ff 0.12.1", + "rand_core 0.6.4", + "subtle 2.4.1", +] + [[package]] name = "group" version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ - "ff", + "ff 0.13.0", "rand_core 0.6.4", "subtle 2.4.1", ] @@ -2765,6 +2853,20 @@ dependencies = [ "itoa 1.0.9", ] +[[package]] +name = "http-api-client" +version = "0.1.0" +dependencies = [ + "async-trait", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tracing", + "url", + "wasmtimer", +] + [[package]] name = "http-body" version = "0.4.5" @@ -3050,6 +3152,7 @@ version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" dependencies = [ + "block-padding", "generic-array 0.14.7", ] @@ -3175,6 +3278,18 @@ dependencies = [ "treediff", ] +[[package]] +name = "k256" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72c1e0b51e7ec0a97369623508396067a486bd0cbed95a2659a4b863d28cfc8b" +dependencies = [ + "cfg-if", + "ecdsa 0.14.8", + "elliptic-curve 0.12.3", + "sha2 0.10.8", +] + [[package]] name = "k256" version = "0.13.1" @@ -3182,11 +3297,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa", - "elliptic-curve", - "once_cell", + "ecdsa 0.16.8", + "elliptic-curve 0.13.5", "sha2 0.10.8", - "signature 2.1.0", ] [[package]] @@ -3662,7 +3775,7 @@ dependencies = [ "bs58 0.5.0", "cosmrs", "cosmwasm-std", - "ecdsa", + "ecdsa 0.16.8", "getset", "nym-credentials-interface", "nym-crypto", @@ -3696,7 +3809,6 @@ dependencies = [ name = "nym-bin-common" version = "0.6.0" dependencies = [ - "atty", "clap", "clap_complete", "clap_complete_fig", @@ -3725,9 +3837,11 @@ dependencies = [ "hyper-util", "log", "nym-bandwidth-controller", + "nym-client-core-config-types", "nym-client-core-gateways-storage", "nym-client-core-surb-storage", "nym-config", + "nym-country-group", "nym-credential-storage", "nym-crypto", "nym-explorer-client", @@ -3762,6 +3876,21 @@ dependencies = [ "zeroize", ] +[[package]] +name = "nym-client-core-config-types" +version = "0.1.0" +dependencies = [ + "humantime-serde", + "nym-config", + "nym-country-group", + "nym-pemstore", + "nym-sphinx-addressing", + "nym-sphinx-params", + "serde", + "thiserror", + "url", +] + [[package]] name = "nym-client-core-gateways-storage" version = "0.1.0" @@ -3803,9 +3932,9 @@ dependencies = [ "bls12_381", "bs58 0.5.0", "digest 0.9.0", - "ff", + "ff 0.13.0", "getrandom 0.2.10", - "group", + "group 0.13.0", "itertools", "nym-dkg", "nym-pemstore", @@ -3914,6 +4043,14 @@ dependencies = [ "thiserror", ] +[[package]] +name = "nym-country-group" +version = "0.1.0" +dependencies = [ + "serde", + "tracing", +] + [[package]] name = "nym-credential-storage" version = "0.1.0" @@ -3986,8 +4123,8 @@ dependencies = [ "bitvec", "bls12_381", "bs58 0.5.0", - "ff", - "group", + "ff 0.13.0", + "group 0.13.0", "lazy_static", "nym-pemstore", "rand 0.8.5", @@ -4108,20 +4245,6 @@ dependencies = [ "serde", ] -[[package]] -name = "nym-http-api-client" -version = "0.1.0" -dependencies = [ - "async-trait", - "reqwest", - "serde", - "serde_json", - "thiserror", - "tracing", - "url", - "wasmtimer", -] - [[package]] name = "nym-id" version = "0.1.0" @@ -4210,6 +4333,8 @@ name = "nym-node-requests" version = "0.1.0" dependencies = [ "base64 0.21.4", + "humantime 2.1.0", + "humantime-serde", "nym-bin-common", "nym-crypto", "nym-exit-policy", @@ -4218,6 +4343,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "time", ] [[package]] @@ -4547,6 +4673,7 @@ dependencies = [ "eyre", "flate2", "futures", + "http-api-client", "itertools", "log", "nym-api-requests", @@ -4557,7 +4684,6 @@ dependencies = [ "nym-contracts-common", "nym-ephemera-common", "nym-group-contract-common", - "nym-http-api-client", "nym-mixnet-contract-common", "nym-multisig-contract-common", "nym-name-service-common", @@ -4701,7 +4827,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -4761,7 +4887,7 @@ version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "81fec4625e73cf41ef4bb6846cafa6d44736525f442ba45e407c4a000a13996f" dependencies = [ - "group", + "group 0.13.0", ] [[package]] @@ -4939,7 +5065,7 @@ dependencies = [ "pest_meta", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -5068,7 +5194,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -5083,14 +5209,24 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs8" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9eca2c590a5f85da82668fa685c09ce2888b9430e83299debf1f34b65fd4a4ba" +dependencies = [ + "der 0.6.1", + "spki 0.6.0", +] + [[package]] name = "pkcs8" version = "0.10.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" dependencies = [ - "der", - "spki", + "der 0.7.8", + "spki 0.7.2", ] [[package]] @@ -5229,9 +5365,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.79" +version = "1.0.66" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e835ff2298f5721608eb1a980ecaee1aef2c132bf95ecc026a11b7bf3c01c02e" +checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9" dependencies = [ "unicode-ident", ] @@ -5271,7 +5407,7 @@ dependencies = [ "itertools", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -5321,9 +5457,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.35" +version = "1.0.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" +checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" dependencies = [ "proc-macro2", ] @@ -5572,6 +5708,17 @@ dependencies = [ "winreg 0.50.0", ] +[[package]] +name = "rfc6979" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7743f17af12fa0b03b803ba12cd6a8d9483a587e89c69445e3909655c0b9fabb" +dependencies = [ + "crypto-bigint 0.4.9", + "hmac 0.12.1", + "zeroize", +] + [[package]] name = "rfc6979" version = "0.4.0" @@ -5650,7 +5797,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.55", + "syn 2.0.28", "walkdir", ] @@ -5677,7 +5824,7 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" dependencies = [ - "semver 1.0.22", + "semver 1.0.18", ] [[package]] @@ -5800,9 +5947,9 @@ dependencies = [ [[package]] name = "schemars" -version = "0.8.16" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a28f4c49489add4ce10783f7911893516f15afe45d015608d41faca6bc4d29" +checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f" dependencies = [ "dyn-clone", "indexmap 1.9.3", @@ -5813,9 +5960,9 @@ dependencies = [ [[package]] name = "schemars_derive" -version = "0.8.16" +version = "0.8.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c767fd6fa65d9ccf9cf026122c1b555f2ef9a4f0cea69da4d7dbc3e258d30967" +checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c" dependencies = [ "proc-macro2", "quote", @@ -5845,16 +5992,30 @@ dependencies = [ "untrusted", ] +[[package]] +name = "sec1" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be24c1842290c45df0a7bf069e0c268a747ad05a192f2fd7dcfdbc1cba40928" +dependencies = [ + "base16ct 0.1.1", + "der 0.6.1", + "generic-array 0.14.7", + "pkcs8 0.9.0", + "subtle 2.4.1", + "zeroize", +] + [[package]] name = "sec1" version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" dependencies = [ - "base16ct", - "der", + "base16ct 0.2.0", + "der 0.7.8", "generic-array 0.14.7", - "pkcs8", + "pkcs8 0.10.2", "serdect", "subtle 2.4.1", "zeroize", @@ -5914,9 +6075,9 @@ dependencies = [ [[package]] name = "semver" -version = "1.0.22" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca" +checksum = "b0293b4b29daaf487284529cc2f5675b8e57c61f70167ba415a463651fd6a918" dependencies = [ "serde", ] @@ -6062,9 +6223,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.197" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fb1c873e1b9b056a4dc4c0c198b24c3ffa059243875552b2bd0933b1aee4ce2" +checksum = "91d3c334ca1ee894a2c6f6ad698fe8c435b76d504b13d436f0685d648d6d96f7" dependencies = [ "serde_derive", ] @@ -6089,13 +6250,13 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.197" +version = "1.0.190" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" +checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -6128,7 +6289,7 @@ checksum = "8725e1dfadb3a50f7e5ce0b1a540466f6ed3fe7a0fca2ac2b8b831d31316bd00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -6178,7 +6339,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -6187,7 +6348,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" dependencies = [ - "base16ct", + "base16ct 0.2.0", "serde", ] @@ -6297,6 +6458,10 @@ name = "signature" version = "1.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74233d3b3b2f6d4b006dc19dee745e73e2a6bfb6f93607cd3b02bd5b00797d7c" +dependencies = [ + "digest 0.10.7", + "rand_core 0.6.4", +] [[package]] name = "signature" @@ -6422,6 +6587,16 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67cf02bbac7a337dc36e4f5a693db6c21e7863f45070f7064577eb4367a3212b" +dependencies = [ + "base64ct", + "der 0.6.1", +] + [[package]] name = "spki" version = "0.7.2" @@ -6429,7 +6604,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" dependencies = [ "base64ct", - "der", + "der 0.7.8", ] [[package]] @@ -6642,9 +6817,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.55" +version = "2.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "002a1b3dbf967edfafc32655d0f377ab0bb7b994aa1d32c8cc7e9b8bf3ebb8f0" +checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" dependencies = [ "proc-macro2", "quote", @@ -6813,7 +6988,7 @@ dependencies = [ "regex", "reqwest", "rfd", - "semver 1.0.22", + "semver 1.0.18", "serde", "serde_json", "serde_repr", @@ -6846,7 +7021,7 @@ dependencies = [ "cargo_toml", "heck 0.4.1", "json-patch", - "semver 1.0.22", + "semver 1.0.18", "serde", "serde_json", "tauri-utils", @@ -6868,7 +7043,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "semver 1.0.22", + "semver 1.0.18", "serde", "serde_json", "sha2 0.10.8", @@ -6953,7 +7128,7 @@ dependencies = [ "phf 0.10.1", "proc-macro2", "quote", - "semver 1.0.22", + "semver 1.0.18", "serde", "serde_json", "serde_with", @@ -7008,7 +7183,7 @@ dependencies = [ "ed25519-consensus", "flex-error", "futures", - "k256", + "k256 0.13.1", "num-traits", "once_cell", "prost", @@ -7073,7 +7248,7 @@ dependencies = [ "peg", "pin-project", "reqwest", - "semver 1.0.22", + "semver 1.0.18", "serde", "serde_bytes", "serde_json", @@ -7119,22 +7294,22 @@ checksum = "8eaa81235c7058867fa8c0e7314f33dcce9c215f535d1913822a2b3f5e289f3c" [[package]] name = "thiserror" -version = "1.0.58" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" +checksum = "9d6d7a740b8a666a7e828dd00da9c0dc290dff53154ea77ac109281de90589b7" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.58" +version = "1.0.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" +checksum = "49922ecae66cc8a249b77e68d1d0623c1b2c514f0060c27cdc68bd62a1219d35" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -7220,7 +7395,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -7377,7 +7552,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] @@ -7453,7 +7628,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", "termcolor", ] @@ -7751,7 +7926,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", "wasm-bindgen-shared", ] @@ -7785,7 +7960,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -8466,7 +8641,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.55", + "syn 2.0.28", ] [[package]] diff --git a/nym-connect/desktop/src-tauri/src/error.rs b/nym-connect/desktop/src-tauri/src/error.rs index 5b324a8850..e8fb548942 100644 --- a/nym-connect/desktop/src-tauri/src/error.rs +++ b/nym-connect/desktop/src-tauri/src/error.rs @@ -113,6 +113,9 @@ pub enum BackendError { source: Box<dyn std::error::Error + Send + Sync>, }, + #[error(transparent)] + ConfigUpgradeFailure(#[from] nym_client_core::config::ConfigUpgradeFailure), + #[error("HTTP get request failed: {status_code}")] RequestFail { url: reqwest::Url, diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 745be5d884..e7e4ae1eda 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -14,46 +14,48 @@ license = "GPL-3.0" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -anyhow = { workspace = true } -bytes = "1.5.0" -colored = "2" -ipnetwork = "0.16" +anyhow.workspace = true +bip39 = { workspace = true, features = ["zeroize"] } +bs58.workspace = true +celes = "2.4.0" # country codes +clap = { workspace = true, features = ["cargo", "env"] } +humantime-serde = { workspace = true } +ipnetwork = "0.16.0" rand = "0.7.3" serde = { workspace = true, features = ["derive"] } -serde_yaml = "0.9.25" -serde_json = { workspace = true } -thiserror = { workspace = true } -tracing = { workspace = true } +serde_json.workspace = true +thiserror.workspace = true +tracing.workspace = true tokio = { workspace = true, features = ["macros", "sync"] } +toml = "0.8.12" +url = { workspace = true, features = ["serde"] } +zeroize = { workspace = true, features = ["zeroize_derive"] } -# Wireguard: -fastrand = "2" +# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions) +semver = "1.0.22" -# HTTP API: -axum = { workspace = true } -# useful for `#[axum_macros::debug_handler]` -#axum-macros = "0.3.8" -mime = "0.3.17" -hyper = { workspace = true } -tower = { version = "0.4.13" } -tower-http = { version = "0.4.4", features = ["fs"] } -utoipa = { workspace = true, features = ["axum_extras"] } -utoipa-swagger-ui = { workspace = true, features = ["axum"] } - -# if we ever wanted redoc/rapidoc bridges: -#utoipa-redoc = { version = "0.1.0", features = ["axum"] } -#utoipa-rapidoc = { version = "0.1.0", features = ["axum"] } +# system info: +cupid = "0.6.1" +sysinfo = "0.30.7" +nym-bin-common = { path = "../common/bin-common", features = ["basic_tracing", "output_format"] } +nym-client-core-config-types = { path = "../common/client-core/config-types" } nym-config = { path = "../common/config" } -nym-crypto = { path = "../common/crypto", features = ["asymmetric" ]} -nym-node-requests = { path = "nym-node-requests", default-features = false, features = ["openapi"]} +nym-crypto = { path = "../common/crypto", features = ["asymmetric", "rand"] } +nym-node-http-api = { path = "nym-node-http-api" } +nym-pemstore = { path = "../common/pemstore" } +nym-sphinx-acknowledgements = { path = "../common/nymsphinx/acknowledgements" } +nym-sphinx-addressing = { path = "../common/nymsphinx/addressing" } nym-task = { path = "../common/task" } -nym-wireguard = { path = "../common/wireguard" } -nym-wireguard-types = { path = "../common/wireguard-types", features = ["verify"] } +nym-types = { path = "../common/types" } +nym-wireguard-types = { path = "../common/wireguard-types", default-features = false } -[dev-dependencies] -dashmap = { workspace = true } -rand = "0.7.3" -nym-crypto = { path = "../common/crypto", features = ["rand"]} -hmac = "0.12.1" -x25519-dalek = { version = "2.0.0" } +# nodes: +nym-mixnode = { path = "../mixnode" } +nym-gateway = { path = "../gateway" } +nym-network-requester = { path = "../service-providers/network-requester" } +nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } + +[build-dependencies] +# temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions) +cargo_metadata = "0.18.1" \ No newline at end of file diff --git a/nym-node/build.rs b/nym-node/build.rs new file mode 100644 index 0000000000..f705ff54e1 --- /dev/null +++ b/nym-node/build.rs @@ -0,0 +1,36 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use cargo_metadata::MetadataCommand; +use std::fs; +use std::path::PathBuf; + +// that's disgusting, but it works, so it's good enough for now ¯\_(ツ)_/¯ +fn main() { + let out_dir: PathBuf = std::env::var("OUT_DIR").unwrap().into(); + + let path: PathBuf = std::env::var("CARGO_MANIFEST_DIR").unwrap().into(); + + let mix_path = path.parent().unwrap().join("mixnode"); + let gateway_path = path.parent().unwrap().join("gateway"); + + let mix_meta = MetadataCommand::new() + .manifest_path("./Cargo.toml") + .current_dir(&mix_path) + .exec() + .unwrap(); + let mix_version = &mix_meta.root_package().unwrap().version; + + let gateway_meta = MetadataCommand::new() + .manifest_path("./Cargo.toml") + .current_dir(&gateway_path) + .exec() + .unwrap(); + + let gateway_version = &gateway_meta.root_package().unwrap().version; + + fs::write(out_dir.join("mixnode_version"), mix_version.to_string()).unwrap(); + fs::write(out_dir.join("gateway_version"), gateway_version.to_string()).unwrap(); + + println!("cargo::rerun-if-changed=build.rs"); +} diff --git a/nym-node/nym-node-http-api/Cargo.toml b/nym-node/nym-node-http-api/Cargo.toml new file mode 100644 index 0000000000..a1150a0a52 --- /dev/null +++ b/nym-node/nym-node-http-api/Cargo.toml @@ -0,0 +1,50 @@ +[package] +name = "nym-node-http-api" +version = "0.1.0" +edition = "2021" +license.workspace = true + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +axum = { workspace = true, features = ["headers"] } +# \/ will be needed once we update axum to 0.7 +#axum-extra = { version = "0.9.3", features = ["typed-header"] } +#headers = "0.4" + +# useful for `#[axum_macros::debug_handler]` +#axum-macros = "0.3.8" +hyper.workspace = true +thiserror.workspace = true +time = { workspace = true, features = ["serde"] } +tokio = { workspace = true, features = ["macros"] } +tower-http = { version = "0.4.4", features = ["fs"] } +tracing.workspace = true +utoipa = { workspace = true, features = ["axum_extras", "time"] } +utoipa-swagger-ui = { workspace = true, features = ["axum"] } + +colored = "2" +ipnetwork = "0.16" +rand = "0.7.3" + +# Wireguard: +fastrand = "2" + +nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "rand"] } +nym-http-api-common = { path = "../../common/http-api-common" } +nym-node-requests = { path = "../nym-node-requests", default-features = false, features = ["openapi"] } +nym-task = { path = "../../common/task" } + +nym-metrics = { path = "../../common/nym-metrics" } +nym-wireguard = { path = "../../common/wireguard" } +nym-wireguard-types = { path = "../../common/wireguard-types", features = ["verify"] } + +[dev-dependencies] +dashmap.workspace = true +serde_json.workspace = true + +hmac = "0.12.1" +tower = { version = "0.4.13" } +x25519-dalek = { version = "2.0.0" } + +nym-crypto = { path = "../../common/crypto", features = ["rand"] } diff --git a/nym-node/nym-node-http-api/src/error.rs b/nym-node/nym-node-http-api/src/error.rs new file mode 100644 index 0000000000..b19b8e429b --- /dev/null +++ b/nym-node/nym-node-http-api/src/error.rs @@ -0,0 +1,26 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use std::net::SocketAddr; +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum NymNodeHttpError { + #[error("failed to bind the HTTP API to {bind_address}: {source}")] + HttpBindFailure { + bind_address: SocketAddr, + source: hyper::Error, + }, + + #[error("failed to use nym-node requests: {source}")] + RequestError { + #[from] + source: nym_node_requests::error::Error, + }, + + #[error(transparent)] + KeyRecoveryError { + #[from] + source: nym_crypto::asymmetric::encryption::KeyRecoveryError, + }, +} diff --git a/nym-node/nym-node-http-api/src/lib.rs b/nym-node/nym-node-http-api/src/lib.rs new file mode 100644 index 0000000000..7c690b3ea0 --- /dev/null +++ b/nym-node/nym-node-http-api/src/lib.rs @@ -0,0 +1,66 @@ +// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use axum::extract::connect_info::IntoMakeServiceWithConnectInfo; +use axum::Router; +use hyper::server::conn::AddrIncoming; +use hyper::Server; +use nym_task::TaskClient; +use std::net::SocketAddr; +use tracing::{debug, error, info}; + +pub mod error; +pub mod middleware; +pub mod router; +pub mod state; + +pub use error::NymNodeHttpError; +pub use router::{api, landing_page, Config, NymNodeRouter}; + +pub struct NymNodeHTTPServer { + task_client: Option<TaskClient>, + inner: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>, +} + +impl NymNodeHTTPServer { + pub(crate) fn new( + inner: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>, + ) -> Self { + NymNodeHTTPServer { + task_client: None, + inner, + } + } + + #[must_use] + pub fn with_task_client(mut self, task_client: TaskClient) -> Self { + self.task_client = Some(task_client); + self + } + + async fn run_server_forever( + server: Server<AddrIncoming, IntoMakeServiceWithConnectInfo<Router, SocketAddr>>, + ) { + if let Err(err) = server.await { + error!("the HTTP server has terminated with the error: {err}"); + } else { + error!("the HTTP server has terminated with producing any errors"); + } + } + + pub async fn run(self) { + info!("Started NymNodeHTTPServer on {}", self.inner.local_addr()); + if let Some(mut task_client) = self.task_client { + tokio::select! { + _ = task_client.recv_with_delay() => { + debug!("NymNodeHTTPServer: Received shutdown"); + } + _ = Self::run_server_forever(self.inner) => { } + } + } else { + Self::run_server_forever(self.inner).await + } + + debug!("NymNodeHTTPServer: Exiting"); + } +} diff --git a/nym-node/src/http/middleware/logging.rs b/nym-node/nym-node-http-api/src/middleware/logging.rs similarity index 100% rename from nym-node/src/http/middleware/logging.rs rename to nym-node/nym-node-http-api/src/middleware/logging.rs diff --git a/nym-node/src/http/middleware/mod.rs b/nym-node/nym-node-http-api/src/middleware/mod.rs similarity index 100% rename from nym-node/src/http/middleware/mod.rs rename to nym-node/nym-node-http-api/src/middleware/mod.rs diff --git a/nym-node/src/http/mod.rs b/nym-node/nym-node-http-api/src/mod.rs similarity index 100% rename from nym-node/src/http/mod.rs rename to nym-node/nym-node-http-api/src/mod.rs diff --git a/nym-node/nym-node-http-api/src/router/api/mod.rs b/nym-node/nym-node-http-api/src/router/api/mod.rs new file mode 100644 index 0000000000..70e1cc433f --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/mod.rs @@ -0,0 +1,25 @@ +// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; +use crate::state::AppState; +use axum::Router; +use nym_node_requests::routes; + +pub mod v1; + +pub(crate) use nym_http_api_common::{FormattedResponse, Output, OutputParams}; + +pub use nym_node_requests::api as api_requests; + +#[derive(Debug, Clone)] +pub struct Config { + pub v1_config: v1::Config, +} + +pub(super) fn routes(config: Config, initial_wg_state: WireguardAppState) -> Router<AppState> { + Router::new().nest( + routes::api::V1, + v1::routes(config.v1_config, initial_wg_state), + ) +} diff --git a/nym-node/src/http/router/api/v1/gateway/client_interfaces/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/mod.rs similarity index 96% rename from nym-node/src/http/router/api/v1/gateway/client_interfaces/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/mod.rs index 3bd789a248..1de50f5f8c 100644 --- a/nym-node/src/http/router/api/v1/gateway/client_interfaces/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/mod.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; -use crate::http::api::{FormattedResponse, OutputParams}; +use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; +use crate::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use axum::http::StatusCode; use axum::routing::get; diff --git a/nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs similarity index 97% rename from nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs rename to nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs index d214d6304f..1b28e29206 100644 --- a/nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/client_registry.rs @@ -1,12 +1,12 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::gateway::client_interfaces::wireguard::{ +use super::error::WireguardError; +use crate::api::v1::gateway::client_interfaces::wireguard::{ WireguardAppState, WireguardAppStateInner, }; -use crate::http::api::{FormattedResponse, OutputParams}; -use crate::http::router::types::RequestError; -use crate::wireguard::error::WireguardError; +use crate::api::{FormattedResponse, OutputParams}; +use crate::router::types::RequestError; use axum::extract::{Path, Query, State}; use axum::http::StatusCode; use axum::Json; diff --git a/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/error.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/error.rs new file mode 100644 index 0000000000..04895b0e4c --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/error.rs @@ -0,0 +1,13 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use thiserror::Error; + +#[derive(Debug, Error)] +pub enum WireguardError { + #[error("the client is currently not in the process of being registered")] + RegistrationNotInProgress, + + #[error("the client mac failed to get verified correctly")] + MacVerificationFailure, +} diff --git a/nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/mod.rs similarity index 96% rename from nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/mod.rs index eec31b244c..775b1a69b5 100644 --- a/nym-node/src/http/router/api/v1/gateway/client_interfaces/wireguard/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/client_interfaces/wireguard/mod.rs @@ -1,10 +1,10 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::gateway::client_interfaces::wireguard::client_registry::{ +use crate::api::v1::gateway::client_interfaces::wireguard::client_registry::{ get_all_clients, get_client, register_client, }; -use crate::wireguard::types::{GatewayClientRegistry, PendingRegistrations}; +use crate::error::NymNodeHttpError; use axum::routing::{get, post}; use axum::Router; use ipnetwork::IpNetwork; @@ -12,9 +12,11 @@ use nym_crypto::asymmetric::encryption::PrivateKey; use nym_node_requests::routes::api::v1::gateway::client_interfaces::wireguard; use nym_wireguard::setup; use nym_wireguard_types::registration::PrivateIPs; +use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations}; use std::sync::Arc; pub(crate) mod client_registry; +mod error; // I don't see any reason why this state should be accessible to any routes outside /wireguard // if anyone finds compelling reason, it could be moved to the `AppState` struct instead @@ -29,7 +31,7 @@ impl WireguardAppState { registration_in_progress: Arc<PendingRegistrations>, binding_port: u16, private_ip_network: IpNetwork, - ) -> Result<Self, crate::error::NymNodeError> { + ) -> Result<Self, NymNodeHttpError> { Ok(WireguardAppState { inner: Some(WireguardAppStateInner { private_key: Arc::new(PrivateKey::from_bytes( @@ -99,7 +101,7 @@ pub(crate) fn routes<S>(initial_state: WireguardAppState) -> Router<S> { #[cfg(test)] mod test { - use crate::http::api::v1::gateway::client_interfaces::wireguard::{ + use crate::api::v1::gateway::client_interfaces::wireguard::{ routes, WireguardAppState, WireguardAppStateInner, }; use axum::body::Body; diff --git a/nym-node/src/http/router/api/v1/gateway/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/mod.rs similarity index 91% rename from nym-node/src/http/router/api/v1/gateway/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/gateway/mod.rs index 6b9ee71d14..e95f79d643 100644 --- a/nym-node/src/http/router/api/v1/gateway/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/mod.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; +use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; use axum::routing::get; use axum::Router; use nym_node_requests::api::v1::gateway::models; diff --git a/nym-node/src/http/router/api/v1/gateway/root.rs b/nym-node/nym-node-http-api/src/router/api/v1/gateway/root.rs similarity index 93% rename from nym-node/src/http/router/api/v1/gateway/root.rs rename to nym-node/nym-node-http-api/src/router/api/v1/gateway/root.rs index 04edf2681a..cb6fc6cbfd 100644 --- a/nym-node/src/http/router/api/v1/gateway/root.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/gateway/root.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use axum::http::StatusCode; use nym_node_requests::api::v1::gateway::models::Gateway; diff --git a/nym-node/src/http/router/api/v1/health.rs b/nym-node/nym-node-http-api/src/router/api/v1/health.rs similarity index 91% rename from nym-node/src/http/router/api/v1/health.rs rename to nym-node/nym-node-http-api/src/router/api/v1/health.rs index 7b26a61c35..4beb5f6af5 100644 --- a/nym-node/src/http/router/api/v1/health.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/health.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::{FormattedResponse, OutputParams}; -use crate::http::state::AppState; +use crate::api::{FormattedResponse, OutputParams}; +use crate::state::AppState; use axum::extract::{Query, State}; use nym_node_requests::api::v1::health::models::NodeHealth; diff --git a/nym-node/src/http/router/api/v1/ip_packet_router/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/ip_packet_router/mod.rs similarity index 100% rename from nym-node/src/http/router/api/v1/ip_packet_router/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/ip_packet_router/mod.rs diff --git a/nym-node/src/http/router/api/v1/ip_packet_router/root.rs b/nym-node/nym-node-http-api/src/router/api/v1/ip_packet_router/root.rs similarity index 94% rename from nym-node/src/http/router/api/v1/ip_packet_router/root.rs rename to nym-node/nym-node-http-api/src/router/api/v1/ip_packet_router/root.rs index 498bf7c084..41fc8e536c 100644 --- a/nym-node/src/http/router/api/v1/ip_packet_router/root.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/ip_packet_router/root.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use axum::http::StatusCode; use nym_node_requests::api::v1::ip_packet_router::models::IpPacketRouter; diff --git a/nym-node/nym-node-http-api/src/router/api/v1/metrics/mixing.rs b/nym-node/nym-node-http-api/src/router/api/v1/metrics/mixing.rs new file mode 100644 index 0000000000..8ae07c61e6 --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/metrics/mixing.rs @@ -0,0 +1,33 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::metrics::MetricsAppState; +use axum::extract::{Query, State}; +use nym_http_api_common::{FormattedResponse, OutputParams}; +use nym_node_requests::api::v1::metrics::models::MixingStats; + +/// If applicable, returns mixing statistics information of this node. +/// This information is **PURELY** self-reported and in no way validated. +#[utoipa::path( + get, + path = "/mixing", + context_path = "/api/v1/metrics", + tag = "Metrics", + responses( + (status = 200, content( + ("application/json" = MixingStats), + ("application/yaml" = MixingStats) + )) + ), + params(OutputParams), +)] +pub(crate) async fn mixing_stats( + Query(output): Query<OutputParams>, + State(metrics_state): State<MetricsAppState>, +) -> MixingStatsResponse { + let output = output.output.unwrap_or_default(); + let response = metrics_state.mixing_stats.read().await.as_response(); + output.to_response(response) +} + +pub type MixingStatsResponse = FormattedResponse<MixingStats>; diff --git a/nym-node/nym-node-http-api/src/router/api/v1/metrics/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/metrics/mod.rs new file mode 100644 index 0000000000..7f3dc9151e --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/metrics/mod.rs @@ -0,0 +1,31 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::api::v1::metrics::mixing::mixing_stats; +use crate::api::v1::metrics::prometheus::prometheus_metrics; +use crate::api::v1::metrics::verloc::verloc_stats; +use crate::state::metrics::MetricsAppState; +use axum::extract::FromRef; +use axum::routing::get; +use axum::Router; +use nym_node_requests::routes::api::v1::metrics; + +pub mod mixing; +pub mod prometheus; +pub mod verloc; + +#[derive(Debug, Clone, Default)] +pub struct Config { + // +} + +pub(super) fn routes<S>(_config: Config) -> Router<S> +where + S: Send + Sync + 'static + Clone, + MetricsAppState: FromRef<S>, +{ + Router::new() + .route(metrics::MIXING, get(mixing_stats)) + .route(metrics::VERLOC, get(verloc_stats)) + .route(metrics::PROMETHEUS, get(prometheus_metrics)) +} diff --git a/nym-node/nym-node-http-api/src/router/api/v1/metrics/prometheus.rs b/nym-node/nym-node-http-api/src/router/api/v1/metrics/prometheus.rs new file mode 100644 index 0000000000..eae64267bd --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/metrics/prometheus.rs @@ -0,0 +1,45 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::metrics::MetricsAppState; +use axum::extract::State; +use axum::headers::authorization::Bearer; +use axum::headers::Authorization; +use axum::http::StatusCode; +use axum::TypedHeader; +use nym_metrics::metrics; + +/// Returns `prometheus` compatible metrics +#[utoipa::path( + get, + path = "/prometheus", + context_path = "/api/v1/metrics", + tag = "Metrics", + responses( + (status = 200, body = String), + (status = 400, description = "`Authorization` header was missing"), + (status = 401, description = "Access token is missing or invalid"), + (status = 500, description = "No access token has been specified on the node"), + ), + security( + ("prometheus_token" = []) + ) +)] +pub(crate) async fn prometheus_metrics<'a>( + TypedHeader(authorization): TypedHeader<Authorization<Bearer>>, + State(state): State<MetricsAppState>, +) -> Result<String, StatusCode> { + if authorization.token().is_empty() { + return Err(StatusCode::UNAUTHORIZED); + } + // TODO: is 500 the correct error code here? + let Some(metrics_key) = state.prometheus_access_token else { + return Err(StatusCode::INTERNAL_SERVER_ERROR); + }; + + if metrics_key != authorization.token() { + return Err(StatusCode::UNAUTHORIZED); + } + + Ok(metrics!()) +} diff --git a/nym-node/nym-node-http-api/src/router/api/v1/metrics/verloc.rs b/nym-node/nym-node-http-api/src/router/api/v1/metrics/verloc.rs new file mode 100644 index 0000000000..c622ccf123 --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/metrics/verloc.rs @@ -0,0 +1,32 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::metrics::MetricsAppState; +use axum::extract::{Query, State}; +use nym_http_api_common::{FormattedResponse, OutputParams}; +use nym_node_requests::api::v1::metrics::models::VerlocStats; + +/// If applicable, returns verloc statistics information of this node. +#[utoipa::path( + get, + path = "/verloc", + context_path = "/api/v1/metrics", + tag = "Metrics", + responses( + (status = 200, content( + ("application/json" = VerlocStats), + ("application/yaml" = VerlocStats) + )) + ), + params(OutputParams), +)] +pub(crate) async fn verloc_stats( + Query(output): Query<OutputParams>, + State(metrics_state): State<MetricsAppState>, +) -> VerlocStatsResponse { + let output = output.output.unwrap_or_default(); + let response = metrics_state.verloc.read().await.as_response(); + output.to_response(response) +} + +pub type VerlocStatsResponse = FormattedResponse<VerlocStats>; diff --git a/nym-node/src/http/router/api/v1/mixnode/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/mixnode/mod.rs similarity index 100% rename from nym-node/src/http/router/api/v1/mixnode/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/mixnode/mod.rs diff --git a/nym-node/src/http/router/api/v1/mixnode/root.rs b/nym-node/nym-node-http-api/src/router/api/v1/mixnode/root.rs similarity index 93% rename from nym-node/src/http/router/api/v1/mixnode/root.rs rename to nym-node/nym-node-http-api/src/router/api/v1/mixnode/root.rs index 1ca216b55d..d7f56ba3e0 100644 --- a/nym-node/src/http/router/api/v1/mixnode/root.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/mixnode/root.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use axum::http::StatusCode; use nym_node_requests::api::v1::mixnode::models::Mixnode; diff --git a/nym-node/src/http/router/api/v1/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/mod.rs similarity index 85% rename from nym-node/src/http/router/api/v1/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/mod.rs index 97d7aff172..cae97ac05d 100644 --- a/nym-node/src/http/router/api/v1/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/mod.rs @@ -1,8 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; -use crate::http::state::AppState; +use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; +use crate::state::AppState; use axum::routing::get; use axum::Router; use nym_node_requests::routes::api::v1; @@ -10,6 +10,7 @@ use nym_node_requests::routes::api::v1; pub mod gateway; pub mod health; pub mod ip_packet_router; +pub mod metrics; pub mod mixnode; pub mod network_requester; pub mod node; @@ -18,6 +19,7 @@ pub mod openapi; #[derive(Debug, Clone)] pub struct Config { pub node: node::Config, + pub metrics: metrics::Config, pub gateway: gateway::Config, pub mixnode: mixnode::Config, pub network_requester: network_requester::Config, @@ -27,6 +29,7 @@ pub struct Config { pub(super) fn routes(config: Config, initial_wg_state: WireguardAppState) -> Router<AppState> { Router::new() .route(v1::HEALTH, get(health::root_health)) + .nest(v1::METRICS, metrics::routes(config.metrics)) .nest( v1::GATEWAY, gateway::routes(config.gateway, initial_wg_state), diff --git a/nym-node/src/http/router/api/v1/network_requester/exit_policy.rs b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/exit_policy.rs similarity index 93% rename from nym-node/src/http/router/api/v1/network_requester/exit_policy.rs rename to nym-node/nym-node-http-api/src/router/api/v1/network_requester/exit_policy.rs index ab649711f4..70bc69ec62 100644 --- a/nym-node/src/http/router/api/v1/network_requester/exit_policy.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/exit_policy.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::{FormattedResponse, OutputParams}; +use crate::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use nym_node_requests::api::v1::network_requester::exit_policy::models::UsedExitPolicy; diff --git a/nym-node/src/http/router/api/v1/network_requester/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/mod.rs similarity index 93% rename from nym-node/src/http/router/api/v1/network_requester/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/network_requester/mod.rs index 19f08cb368..917b5a668b 100644 --- a/nym-node/src/http/router/api/v1/network_requester/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/mod.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::network_requester::exit_policy::node_exit_policy; +use crate::api::v1::network_requester::exit_policy::node_exit_policy; use axum::routing::get; use axum::Router; use nym_node_requests::api::v1::network_requester::exit_policy::models::UsedExitPolicy; diff --git a/nym-node/src/http/router/api/v1/network_requester/root.rs b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/root.rs similarity index 94% rename from nym-node/src/http/router/api/v1/network_requester/root.rs rename to nym-node/nym-node-http-api/src/router/api/v1/network_requester/root.rs index 4294a4d348..ac92133e53 100644 --- a/nym-node/src/http/router/api/v1/network_requester/root.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/network_requester/root.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use axum::http::StatusCode; use nym_node_requests::api::v1::network_requester::models::NetworkRequester; diff --git a/nym-node/src/http/router/api/v1/node/build_information.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/build_information.rs similarity index 93% rename from nym-node/src/http/router/api/v1/node/build_information.rs rename to nym-node/nym-node-http-api/src/router/api/v1/node/build_information.rs index 98bd47e691..b877f43d17 100644 --- a/nym-node/src/http/router/api/v1/node/build_information.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/build_information.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned; diff --git a/nym-node/nym-node-http-api/src/router/api/v1/node/description.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/description.rs new file mode 100644 index 0000000000..f49d311505 --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/description.rs @@ -0,0 +1,31 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::api::{FormattedResponse, OutputParams}; +use crate::router::types::RequestError; +use axum::extract::Query; +use nym_node_requests::api::v1::node::models::NodeDescription; + +/// Returns human-readable description of this node. +#[utoipa::path( + get, + path = "/description", + context_path = "/api/v1", + tag = "Node", + responses( + (status = 200, content( + ("application/json" = NodeDescription), + ("application/yaml" = NodeDescription) + )), + ), + params(OutputParams) +)] +pub(crate) async fn description( + description: NodeDescription, + Query(output): Query<OutputParams>, +) -> Result<NodeDescriptionResponse, RequestError> { + let output = output.output.unwrap_or_default(); + Ok(output.to_response(description)) +} + +pub type NodeDescriptionResponse = FormattedResponse<NodeDescription>; diff --git a/nym-node/nym-node-http-api/src/router/api/v1/node/hardware.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/hardware.rs new file mode 100644 index 0000000000..2d17b9e3a2 --- /dev/null +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/hardware.rs @@ -0,0 +1,41 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::api::{FormattedResponse, OutputParams}; +use crate::router::types::RequestError; +use axum::extract::Query; +use axum::http::StatusCode; +use nym_node_requests::api::v1::node::models::HostSystem; + +/// Returns build system information of the host running the binary. +#[utoipa::path( + get, + path = "/system-info", + context_path = "/api/v1", + tag = "Node", + responses( + (status = 200, content( + ("application/json" = HostSystem), + ("application/yaml" = HostSystem) + )), + (status = 403, body = ErrorResponse, description = "the node does not wish to expose the system information") + ), + params(OutputParams) +)] +pub(crate) async fn host_system( + system_info: Option<HostSystem>, + Query(output): Query<OutputParams>, +) -> Result<HostSystemResponse, RequestError> { + let output = output.output.unwrap_or_default(); + + let Some(system_info) = system_info else { + return Err(RequestError::new( + "this nym-node does not wish to expose the system information", + StatusCode::FORBIDDEN, + )); + }; + + Ok(output.to_response(system_info)) +} + +pub type HostSystemResponse = FormattedResponse<HostSystem>; diff --git a/nym-node/src/http/router/api/v1/node/host_information.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/host_information.rs similarity index 93% rename from nym-node/src/http/router/api/v1/node/host_information.rs rename to nym-node/nym-node-http-api/src/router/api/v1/node/host_information.rs index c52f00a58b..b4d7f6d363 100644 --- a/nym-node/src/http/router/api/v1/node/host_information.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/host_information.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::{FormattedResponse, OutputParams}; +use crate::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use nym_node_requests::api::v1::node::models::SignedHostInformation; diff --git a/nym-node/src/http/router/api/v1/node/mod.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/mod.rs similarity index 59% rename from nym-node/src/http/router/api/v1/node/mod.rs rename to nym-node/nym-node-http-api/src/router/api/v1/node/mod.rs index 620a446090..c9d228d781 100644 --- a/nym-node/src/http/router/api/v1/node/mod.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/mod.rs @@ -1,15 +1,19 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::api::v1::node::build_information::build_information; -use crate::http::api::v1::node::host_information::host_information; -use crate::http::api::v1::node::roles::roles; +use crate::api::v1::node::build_information::build_information; +use crate::api::v1::node::description::description; +use crate::api::v1::node::hardware::host_system; +use crate::api::v1::node::host_information::host_information; +use crate::api::v1::node::roles::roles; use axum::routing::get; use axum::Router; use nym_node_requests::api::v1::node::models; use nym_node_requests::routes::api::v1; pub mod build_information; +pub mod description; +pub mod hardware; pub mod host_information; pub mod roles; @@ -17,7 +21,9 @@ pub mod roles; pub struct Config { pub build_information: models::BinaryBuildInformationOwned, pub host_information: models::SignedHostInformation, + pub system_info: Option<models::HostSystem>, pub roles: models::NodeRoles, + pub description: models::NodeDescription, } pub(super) fn routes<S: Send + Sync + 'static + Clone>(config: Config) -> Router<S> { @@ -43,4 +49,18 @@ pub(super) fn routes<S: Send + Sync + 'static + Clone>(config: Config) -> Router move |query| host_information(host_info, query) }), ) + .route( + v1::SYSTEM_INFO, + get({ + let system_info = config.system_info; + move |query| host_system(system_info, query) + }), + ) + .route( + v1::NODE_DESCRIPTION, + get({ + let node_description = config.description; + move |query| description(node_description, query) + }), + ) } diff --git a/nym-node/src/http/router/api/v1/node/roles.rs b/nym-node/nym-node-http-api/src/router/api/v1/node/roles.rs similarity index 92% rename from nym-node/src/http/router/api/v1/node/roles.rs rename to nym-node/nym-node-http-api/src/router/api/v1/node/roles.rs index 43648e77c0..145b13798d 100644 --- a/nym-node/src/http/router/api/v1/node/roles.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/node/roles.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api::{FormattedResponse, OutputParams}; +use crate::router::api::{FormattedResponse, OutputParams}; use axum::extract::Query; use nym_node_requests::api::v1::node::models::NodeRoles; diff --git a/nym-node/src/http/router/api/v1/openapi.rs b/nym-node/nym-node-http-api/src/router/api/v1/openapi.rs similarity index 69% rename from nym-node/src/http/router/api/v1/openapi.rs rename to nym-node/nym-node-http-api/src/router/api/v1/openapi.rs index e23eca84f3..bd82c3e3a7 100644 --- a/nym-node/src/http/router/api/v1/openapi.rs +++ b/nym-node/nym-node-http-api/src/router/api/v1/openapi.rs @@ -1,12 +1,13 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::http::router::api; -use crate::http::router::types::{ErrorResponse, RequestError}; +use crate::router::api; +use crate::router::types::{ErrorResponse, RequestError}; use axum::Router; use nym_node_requests::api as api_requests; use nym_node_requests::routes::api::v1; -use utoipa::OpenApi; +use utoipa::openapi::security::{Http, HttpAuthScheme}; +use utoipa::{openapi::security::SecurityScheme, Modify, OpenApi}; use utoipa_swagger_ui::SwaggerUi; #[derive(OpenApi)] @@ -16,6 +17,11 @@ use utoipa_swagger_ui::SwaggerUi; api::v1::node::build_information::build_information, api::v1::node::host_information::host_information, api::v1::node::roles::roles, + api::v1::node::hardware::host_system, + api::v1::node::description::description, + api::v1::metrics::mixing::mixing_stats, + api::v1::metrics::verloc::verloc_stats, + api::v1::metrics::prometheus::prometheus_metrics, api::v1::health::root_health, api::v1::gateway::root::root_gateway, api::v1::gateway::client_interfaces::client_interfaces, @@ -41,6 +47,17 @@ use utoipa_swagger_ui::SwaggerUi; api_requests::v1::node::models::HostInformation, api_requests::v1::node::models::HostKeys, api_requests::v1::node::models::NodeRoles, + api_requests::v1::node::models::HostSystem, + api_requests::v1::node::models::Hardware, + api_requests::v1::node::models::Cpu, + api_requests::v1::node::models::CryptoHardware, + api_requests::v1::node::models::NodeDescription, + api_requests::v1::metrics::models::MixingStats, + api_requests::v1::metrics::models::VerlocStats, + api_requests::v1::metrics::models::VerlocResult, + api_requests::v1::metrics::models::VerlocResultData, + api_requests::v1::metrics::models::VerlocNodeResult, + api_requests::v1::metrics::models::VerlocMeasurement, api_requests::v1::gateway::models::Gateway, api_requests::v1::gateway::models::Wireguard, api_requests::v1::gateway::models::ClientInterfaces, @@ -59,11 +76,25 @@ use utoipa_swagger_ui::SwaggerUi; api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy, api_requests::v1::ip_packet_router::models::IpPacketRouter, ), - responses(RequestError) - ) + responses(RequestError), + ), + modifiers(&SecurityAddon), )] pub(crate) struct ApiDoc; +struct SecurityAddon; + +impl Modify for SecurityAddon { + fn modify(&self, openapi: &mut utoipa::openapi::OpenApi) { + if let Some(components) = openapi.components.as_mut() { + components.add_security_scheme( + "prometheus_token", + SecurityScheme::Http(Http::new(HttpAuthScheme::Bearer)), + ) + } + } +} + pub(crate) fn route<S: Send + Sync + 'static + Clone>() -> Router<S> { // provide absolute path to the openapi.json let config = utoipa_swagger_ui::Config::from("/api/v1/api-docs/openapi.json"); diff --git a/nym-node/src/http/router/landing_page.rs b/nym-node/nym-node-http-api/src/router/landing_page.rs similarity index 100% rename from nym-node/src/http/router/landing_page.rs rename to nym-node/nym-node-http-api/src/router/landing_page.rs diff --git a/nym-node/src/http/router/mod.rs b/nym-node/nym-node-http-api/src/router/mod.rs similarity index 62% rename from nym-node/src/http/router/mod.rs rename to nym-node/nym-node-http-api/src/router/mod.rs index 71de3c3c8d..a32f441afa 100644 --- a/nym-node/src/http/router/mod.rs +++ b/nym-node/nym-node-http-api/src/router/mod.rs @@ -1,11 +1,13 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::error::NymNodeError; -pub use crate::http::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; -use crate::http::middleware::logging; -use crate::http::state::AppState; -use crate::http::NymNodeHTTPServer; +pub use crate::api::v1::gateway::client_interfaces::wireguard::WireguardAppState; +use crate::error::NymNodeHttpError; +use crate::middleware::logging; +use crate::state::AppState; +use crate::NymNodeHTTPServer; +use axum::response::Redirect; +use axum::routing::get; use axum::Router; use nym_node_requests::api::v1::gateway::models::{Gateway, Wireguard}; use nym_node_requests::api::v1::ip_packet_router::models::IpPacketRouter; @@ -13,6 +15,7 @@ use nym_node_requests::api::v1::mixnode::models::Mixnode; use nym_node_requests::api::v1::network_requester::exit_policy::models::UsedExitPolicy; use nym_node_requests::api::v1::network_requester::models::NetworkRequester; use nym_node_requests::api::v1::node::models; +use nym_node_requests::api::v1::node::models::{HostSystem, NodeDescription}; use nym_node_requests::api::SignedHostInformation; use nym_node_requests::routes; use std::net::SocketAddr; @@ -41,8 +44,11 @@ impl Config { node: api::v1::node::Config { build_information, host_information, + system_info: None, roles: Default::default(), + description: Default::default(), }, + metrics: Default::default(), gateway: Default::default(), mixnode: Default::default(), network_requester: Default::default(), @@ -70,9 +76,26 @@ impl Config { self } + #[must_use] + pub fn with_system_info(mut self, info: HostSystem) -> Self { + self.api.v1_config.node.system_info = Some(info); + self + } + + #[must_use] + pub fn with_description(mut self, description: NodeDescription) -> Self { + self.api.v1_config.node.description = description; + self + } + #[must_use] pub fn with_gateway(mut self, gateway: Gateway) -> Self { self.api.v1_config.node.roles.gateway_enabled = true; + self.with_gateway_details(gateway) + } + + #[must_use] + pub fn with_gateway_details(mut self, gateway: Gateway) -> Self { self.api.v1_config.gateway.details = Some(gateway); self } @@ -80,6 +103,11 @@ impl Config { #[must_use] pub fn with_mixnode(mut self, mixnode: Mixnode) -> Self { self.api.v1_config.node.roles.mixnode_enabled = true; + self.with_mixnode_details(mixnode) + } + + #[must_use] + pub fn with_mixnode_details(mut self, mixnode: Mixnode) -> Self { self.api.v1_config.mixnode.details = Some(mixnode); self } @@ -87,6 +115,11 @@ impl Config { #[must_use] pub fn with_network_requester(mut self, network_requester: NetworkRequester) -> Self { self.api.v1_config.node.roles.network_requester_enabled = true; + self.with_network_requester_details(network_requester) + } + + #[must_use] + pub fn with_network_requester_details(mut self, network_requester: NetworkRequester) -> Self { self.api.v1_config.network_requester.details = Some(network_requester); self } @@ -100,6 +133,11 @@ impl Config { #[must_use] pub fn with_ip_packet_router(mut self, ip_packet_router: IpPacketRouter) -> Self { self.api.v1_config.node.roles.ip_packet_router_enabled = true; + self.with_ip_packet_router_details(ip_packet_router) + } + + #[must_use] + pub fn with_ip_packet_router_details(mut self, ip_packet_router: IpPacketRouter) -> Self { self.api.v1_config.ip_packet_router.details = Some(ip_packet_router); self } @@ -111,11 +149,42 @@ pub struct NymNodeRouter { impl NymNodeRouter { // TODO: move the wg state to a builder - pub fn new(config: Config, initial_wg_state: Option<WireguardAppState>) -> NymNodeRouter { - let state = AppState::new(); + pub fn new( + config: Config, + app_state: Option<AppState>, + initial_wg_state: Option<WireguardAppState>, + ) -> NymNodeRouter { + let state = app_state.unwrap_or(AppState::new()); NymNodeRouter { inner: Router::new() + // redirection for old legacy mixnode routes + .route( + "/hardware", + get(|| async { Redirect::permanent(&routes::api::v1::system_info_absolute()) }), + ) + .route( + "/description", + get(|| async { Redirect::permanent(&routes::api::v1::description_absolute()) }), + ) + .route( + "/stats", + get(|| async { + Redirect::permanent(&routes::api::v1::metrics::mixing_absolute()) + }), + ) + .route( + "/verloc", + get(|| async { + Redirect::permanent(&routes::api::v1::metrics::verloc_absolute()) + }), + ) + .route( + "/metrics", + get(|| async { + Redirect::permanent(&routes::api::v1::metrics::prometheus_absolute()) + }), + ) .nest(routes::LANDING_PAGE, landing_page::routes(config.landing)) .nest( routes::API, @@ -142,9 +211,9 @@ impl NymNodeRouter { pub fn build_server( self, bind_address: &SocketAddr, - ) -> Result<NymNodeHTTPServer, NymNodeError> { + ) -> Result<NymNodeHTTPServer, NymNodeHttpError> { let axum_server = axum::Server::try_bind(bind_address) - .map_err(|source| NymNodeError::HttpBindFailure { + .map_err(|source| NymNodeHttpError::HttpBindFailure { bind_address: *bind_address, source, })? diff --git a/nym-node/src/http/router/types.rs b/nym-node/nym-node-http-api/src/router/types.rs similarity index 100% rename from nym-node/src/http/router/types.rs rename to nym-node/nym-node-http-api/src/router/types.rs diff --git a/nym-node/nym-node-http-api/src/state/metrics.rs b/nym-node/nym-node-http-api/src/state/metrics.rs new file mode 100644 index 0000000000..d4691727d9 --- /dev/null +++ b/nym-node/nym-node-http-api/src/state/metrics.rs @@ -0,0 +1,148 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::AppState; +use axum::extract::FromRef; +use nym_node_requests::api::v1::metrics::models::{ + MixingStats, VerlocResult, VerlocResultData, VerlocStats, +}; +use std::collections::HashMap; +use std::sync::Arc; +use time::OffsetDateTime; +use tokio::sync::{RwLock, RwLockReadGuard, RwLockWriteGuard}; + +pub use nym_node_requests::api::v1::metrics::models::{VerlocMeasurement, VerlocNodeResult}; + +type PacketsMap = HashMap<String, u64>; + +#[derive(Clone, Debug, Default)] +pub struct SharedMixingStats { + inner: Arc<RwLock<MixingStatsState>>, +} + +impl SharedMixingStats { + pub fn new() -> SharedMixingStats { + let now = OffsetDateTime::now_utc(); + + SharedMixingStats { + inner: Arc::new(RwLock::new(MixingStatsState { + update_time: now, + previous_update_time: now, + ..Default::default() + })), + } + } + + pub async fn read(&self) -> RwLockReadGuard<'_, MixingStatsState> { + self.inner.read().await + } + + pub async fn write(&self) -> RwLockWriteGuard<'_, MixingStatsState> { + self.inner.write().await + } +} + +#[derive(Debug)] +pub struct MixingStatsState { + pub update_time: OffsetDateTime, + + pub previous_update_time: OffsetDateTime, + + pub packets_received_since_startup: u64, + pub packets_sent_since_startup_all: u64, + pub packets_dropped_since_startup_all: u64, + pub packets_received_since_last_update: u64, + + // note: sent does not imply forwarded. We don't know if it was delivered successfully + pub packets_sent_since_last_update: PacketsMap, + + // we know for sure we dropped packets to those destinations + pub packets_explicitly_dropped_since_last_update: PacketsMap, +} + +impl MixingStatsState { + pub fn as_response(&self) -> MixingStats { + MixingStats { + update_time: self.update_time, + previous_update_time: self.previous_update_time, + received_since_startup: self.packets_received_since_startup, + sent_since_startup: self.packets_sent_since_startup_all, + dropped_since_startup: self.packets_dropped_since_startup_all, + received_since_last_update: self.packets_received_since_last_update, + sent_since_last_update: self.packets_sent_since_last_update.values().sum(), + dropped_since_last_update: self + .packets_explicitly_dropped_since_last_update + .values() + .sum(), + } + } +} + +impl Default for MixingStatsState { + fn default() -> Self { + MixingStatsState { + update_time: OffsetDateTime::UNIX_EPOCH, + previous_update_time: OffsetDateTime::UNIX_EPOCH, + packets_received_since_startup: 0, + packets_sent_since_startup_all: 0, + packets_dropped_since_startup_all: 0, + packets_received_since_last_update: 0, + packets_sent_since_last_update: Default::default(), + packets_explicitly_dropped_since_last_update: Default::default(), + } + } +} + +#[derive(Clone, Debug, Default)] +pub struct SharedVerlocStats { + inner: Arc<RwLock<VerlocStatsState>>, +} + +#[derive(Clone, Debug, Default)] +pub struct VerlocStatsState { + pub current_run_data: VerlocResultData, + pub previous_run_data: VerlocResultData, +} + +impl SharedVerlocStats { + pub async fn read(&self) -> RwLockReadGuard<'_, VerlocStatsState> { + self.inner.read().await + } + + pub async fn write(&self) -> RwLockWriteGuard<'_, VerlocStatsState> { + self.inner.write().await + } +} + +impl VerlocStatsState { + pub fn as_response(&self) -> VerlocStats { + let previous = if !self.previous_run_data.run_finished() { + VerlocResult::Unavailable + } else { + VerlocResult::Data(self.previous_run_data.clone()) + }; + + let current = if !self.current_run_data.run_finished() { + VerlocResult::MeasurementInProgress + } else { + VerlocResult::Data(self.current_run_data.clone()) + }; + + VerlocStats { previous, current } + } +} + +#[derive(Debug, Clone, Default)] +pub struct MetricsAppState { + pub(crate) prometheus_access_token: Option<String>, + + pub(crate) mixing_stats: SharedMixingStats, + + pub(crate) verloc: SharedVerlocStats, +} + +impl FromRef<AppState> for MetricsAppState { + fn from_ref(app_state: &AppState) -> Self { + app_state.metrics.clone() + } +} diff --git a/nym-node/nym-node-http-api/src/state/mod.rs b/nym-node/nym-node-http-api/src/state/mod.rs new file mode 100644 index 0000000000..077ca782b6 --- /dev/null +++ b/nym-node/nym-node-http-api/src/state/mod.rs @@ -0,0 +1,46 @@ +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::state::metrics::{MetricsAppState, SharedMixingStats, SharedVerlocStats}; +use tokio::time::Instant; + +pub mod metrics; + +#[derive(Debug, Clone)] +pub struct AppState { + pub(crate) startup_time: Instant, + + pub(crate) metrics: MetricsAppState, +} + +impl AppState { + #[allow(clippy::new_without_default)] + pub fn new() -> Self { + AppState { + // is it 100% accurate? + // no. + // does it have to be? + // also no. + startup_time: Instant::now(), + metrics: Default::default(), + } + } + + #[must_use] + pub fn with_mixing_stats(mut self, mixing_stats: SharedMixingStats) -> Self { + self.metrics.mixing_stats = mixing_stats; + self + } + + #[must_use] + pub fn with_verloc_stats(mut self, verloc_stats: SharedVerlocStats) -> Self { + self.metrics.verloc = verloc_stats; + self + } + + #[must_use] + pub fn with_metrics_key(mut self, bearer_token: impl Into<Option<String>>) -> Self { + self.metrics.prometheus_access_token = bearer_token.into(); + self + } +} diff --git a/nym-node/nym-node-requests/Cargo.toml b/nym-node/nym-node-requests/Cargo.toml index 2761a1c9ec..e8fc8c089b 100644 --- a/nym-node/nym-node-requests/Cargo.toml +++ b/nym-node/nym-node-requests/Cargo.toml @@ -12,12 +12,15 @@ license.workspace = true [dependencies] base64 = { workspace = true } +humantime = "2.1.0" +humantime-serde = { workspace = true } schemars = { workspace = true, features = ["preserve_order"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } +time = { workspace = true, features = ["serde", "formatting", "parsing"] } thiserror = { workspace = true } -nym-crypto = { path = "../../common/crypto", features = ["asymmetric"] } +nym-crypto = { path = "../../common/crypto", features = ["asymmetric", "serde"] } nym-exit-policy = { path = "../../common/exit-policy" } nym-wireguard-types = { path = "../../common/wireguard-types", default-features = false } diff --git a/nym-node/nym-node-requests/src/api/mod.rs b/nym-node/nym-node-requests/src/api/mod.rs index 8da95074a9..180685e284 100644 --- a/nym-node/nym-node-requests/src/api/mod.rs +++ b/nym-node/nym-node-requests/src/api/mod.rs @@ -56,7 +56,8 @@ impl<T> SignedData<T> { impl SignedHostInformation { pub fn verify_host_information(&self) -> bool { - let Ok(pub_key) = identity::PublicKey::from_base58_string(&self.keys.ed25519) else { + let Ok(pub_key) = identity::PublicKey::from_base58_string(&self.keys.ed25519_identity) + else { return false; }; diff --git a/nym-node/nym-node-requests/src/api/v1/metrics/mod.rs b/nym-node/nym-node-requests/src/api/v1/metrics/mod.rs new file mode 100644 index 0000000000..5c45219d84 --- /dev/null +++ b/nym-node/nym-node-requests/src/api/v1/metrics/mod.rs @@ -0,0 +1,4 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +pub mod models; diff --git a/nym-node/nym-node-requests/src/api/v1/metrics/models.rs b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs new file mode 100644 index 0000000000..3374b1b0c4 --- /dev/null +++ b/nym-node/nym-node-requests/src/api/v1/metrics/models.rs @@ -0,0 +1,279 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: Apache-2.0 + +use nym_crypto::asymmetric::identity::{self, serde_helpers::bs58_pubkey}; +use serde::{Deserialize, Serialize}; +use std::cmp::Ordering; +use std::fmt; +use std::fmt::{Display, Formatter}; +use std::time::Duration; +use time::OffsetDateTime; + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct MixingStats { + #[serde(with = "time::serde::rfc3339")] + pub update_time: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339")] + pub previous_update_time: OffsetDateTime, + + pub received_since_startup: u64, + + // note: sent does not imply forwarded. We don't know if it was delivered successfully + pub sent_since_startup: u64, + + // we know for sure we dropped those packets + pub dropped_since_startup: u64, + + pub received_since_last_update: u64, + + // note: sent does not imply forwarded. We don't know if it was delivered successfully + pub sent_since_last_update: u64, + + // we know for sure we dropped those packets + pub dropped_since_last_update: u64, +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct VerlocStats { + pub previous: VerlocResult, + pub current: VerlocResult, +} + +#[derive(Serialize, Deserialize, Default, Debug, Clone)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +#[serde(rename_all = "camelCase")] +pub enum VerlocResult { + Data(VerlocResultData), + MeasurementInProgress, + #[default] + Unavailable, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct VerlocResultData { + pub nodes_tested: usize, + + #[serde(with = "time::serde::rfc3339")] + pub run_started: OffsetDateTime, + + #[serde(with = "time::serde::rfc3339::option")] + pub run_finished: Option<OffsetDateTime>, + + pub results: Vec<VerlocNodeResult>, +} + +impl Default for VerlocResultData { + fn default() -> Self { + VerlocResultData { + nodes_tested: 0, + run_started: OffsetDateTime::now_utc(), + run_finished: None, + results: vec![], + } + } +} + +impl VerlocResultData { + pub fn run_finished(&self) -> bool { + self.run_finished.is_some() + } +} + +#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, PartialEq)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct VerlocNodeResult { + #[serde(with = "bs58_pubkey")] + pub node_identity: identity::PublicKey, + + pub latest_measurement: Option<VerlocMeasurement>, +} + +impl VerlocNodeResult { + pub fn new( + node_identity: identity::PublicKey, + latest_measurement: Option<VerlocMeasurement>, + ) -> Self { + VerlocNodeResult { + node_identity, + latest_measurement, + } + } +} + +impl PartialOrd for VerlocNodeResult { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for VerlocNodeResult { + fn cmp(&self, other: &Self) -> Ordering { + // if both have measurement, compare measurements + // then if only one have measurement, prefer that one + // completely ignore identity as it makes no sense to order by it + if let Some(self_measurement) = &self.latest_measurement { + if let Some(other_measurement) = &other.latest_measurement { + self_measurement.cmp(other_measurement) + } else { + Ordering::Less + } + } else if other.latest_measurement.is_some() { + Ordering::Greater + } else { + Ordering::Equal + } + } +} + +#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct VerlocMeasurement { + /// Minimum RTT duration it took to receive an echo packet. + #[serde(serialize_with = "humantime_serde::serialize")] + pub minimum: Duration, + + /// Average RTT duration it took to receive the echo packets. + #[serde(serialize_with = "humantime_serde::serialize")] + pub mean: Duration, + + /// Maximum RTT duration it took to receive an echo packet. + #[serde(serialize_with = "humantime_serde::serialize")] + pub maximum: Duration, + + /// The standard deviation of the RTT duration it took to receive the echo packets. + #[serde(serialize_with = "humantime_serde::serialize")] + pub standard_deviation: Duration, +} + +impl VerlocMeasurement { + pub fn new(raw_results: &[Duration]) -> Self { + let minimum = raw_results.iter().min().copied().unwrap_or_default(); + let maximum = raw_results.iter().max().copied().unwrap_or_default(); + + let mean = Self::duration_mean(raw_results); + let standard_deviation = Self::duration_standard_deviation(raw_results, mean); + + VerlocMeasurement { + minimum, + mean, + maximum, + standard_deviation, + } + } + + fn duration_mean(data: &[Duration]) -> Duration { + if data.is_empty() { + return Default::default(); + } + + let sum = data.iter().sum::<Duration>(); + let count = data.len() as u32; + + sum / count + } + + fn duration_standard_deviation(data: &[Duration], mean: Duration) -> Duration { + if data.is_empty() { + return Default::default(); + } + + let variance_micros = data + .iter() + .map(|&value| { + // make sure we don't underflow + let diff = if mean > value { + mean - value + } else { + value - mean + }; + // we don't need nanos precision + let diff_micros = diff.as_micros(); + diff_micros * diff_micros + }) + .sum::<u128>() + / data.len() as u128; + + // we shouldn't really overflow as our differences shouldn't be larger than couple seconds at the worst possible case scenario + let std_deviation_micros = (variance_micros as f64).sqrt() as u64; + Duration::from_micros(std_deviation_micros) + } +} + +impl Display for VerlocMeasurement { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!( + f, + "rtt min/avg/max/mdev = {} / {} / {} / {}", + humantime::format_duration(self.minimum), + humantime::format_duration(self.mean), + humantime::format_duration(self.maximum), + humantime::format_duration(self.standard_deviation) + ) + } +} + +impl PartialOrd for VerlocMeasurement { + fn partial_cmp(&self, other: &Self) -> Option<Ordering> { + Some(self.cmp(other)) + } +} + +impl Ord for VerlocMeasurement { + fn cmp(&self, other: &Self) -> Ordering { + // minimum value is most important, then look at standard deviation, then mean and finally maximum + let min_cmp = self.minimum.cmp(&other.minimum); + if min_cmp != Ordering::Equal { + return min_cmp; + } + let std_dev_cmp = self.standard_deviation.cmp(&other.standard_deviation); + if std_dev_cmp != Ordering::Equal { + return std_dev_cmp; + } + let std_dev_cmp = self.mean.cmp(&other.mean); + if std_dev_cmp != Ordering::Equal { + return std_dev_cmp; + } + self.maximum.cmp(&other.maximum) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn sorting_vec_of_verlocs() { + let some_identity = + identity::PublicKey::from_base58_string("Be9wH7xuXBRJAuV1pC7MALZv6a61RvWQ3SypsNarqTt") + .unwrap(); + let no_measurement = VerlocNodeResult::new(some_identity, None); + let low_min = VerlocNodeResult::new( + some_identity, + Some(VerlocMeasurement { + minimum: Duration::from_millis(42), + mean: Duration::from_millis(43), + maximum: Duration::from_millis(44), + standard_deviation: Duration::from_millis(45), + }), + ); + let higher_min = VerlocNodeResult::new( + some_identity, + Some(VerlocMeasurement { + minimum: Duration::from_millis(420), + mean: Duration::from_millis(430), + maximum: Duration::from_millis(440), + standard_deviation: Duration::from_millis(450), + }), + ); + + let mut vec_verloc = vec![no_measurement, low_min, no_measurement, higher_min]; + vec_verloc.sort(); + + let expected_sorted = vec![low_min, higher_min, no_measurement, no_measurement]; + assert_eq!(expected_sorted, vec_verloc); + } +} diff --git a/nym-node/nym-node-requests/src/api/v1/mod.rs b/nym-node/nym-node-requests/src/api/v1/mod.rs index 33d67d598e..1c6e698940 100644 --- a/nym-node/nym-node-requests/src/api/v1/mod.rs +++ b/nym-node/nym-node-requests/src/api/v1/mod.rs @@ -4,6 +4,7 @@ pub mod gateway; pub mod health; pub mod ip_packet_router; +pub mod metrics; pub mod mixnode; pub mod network_requester; pub mod node; diff --git a/nym-node/nym-node-requests/src/api/v1/node/models.rs b/nym-node/nym-node-requests/src/api/v1/node/models.rs index 3b79601a00..66ca13d99d 100644 --- a/nym-node/nym-node-requests/src/api/v1/node/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/node/models.rs @@ -35,10 +35,99 @@ pub struct HostInformation { #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct HostKeys { - /// Base58-encoded ed25519 public key of this node. Currently it corresponds to either mixnode's or gateway's identity. - pub ed25519: String, + /// Base58-encoded ed25519 public key of this node. Currently, it corresponds to either mixnode's or gateway's identity. + #[serde(alias = "ed25519")] + pub ed25519_identity: String, /// Base58-encoded x25519 public key of this node used for sphinx/outfox packet creation. - /// Currently it corresponds to either mixnode's or gateway's key. - pub x25519: String, + /// Currently, it corresponds to either mixnode's or gateway's key. + #[serde(alias = "x25519")] + pub x25519_sphinx: String, + + /// Base58-encoded x25519 public key of this node used for the noise protocol. + #[serde(default)] + pub x25519_noise: String, +} + +#[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct HostSystem { + /// Name of the operating system of the host machine. + pub system_name: Option<String>, + + /// Version of the kernel of the host machine, if applicable. + pub kernel_version: Option<String>, + + /// Version of the operating system of the host machine, if applicable. + pub os_version: Option<String>, + + /// The CPU architecture of the host machine (eg. x86, amd64, aarch64, ...). + pub cpu_arch: Option<String>, + + /// Hardware information of the host machine. + pub hardware: Option<Hardware>, +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct Hardware { + /// The information of the host CPU. + pub cpu: Vec<Cpu>, + + /// Total memory, in bytes, available on the host. + pub total_memory: u64, + + /// Detailed information about availability of crypto-specific instructions for future optimisations. + pub crypto: Option<CryptoHardware>, +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct Cpu { + pub name: String, + + /// The CPU frequency in MHz. + pub frequency: u64, + + pub vendor_id: String, + + pub brand: String, +} + +#[derive(Clone, Debug, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct CryptoHardware { + /// Flag to indicate whether the host machine supports AES-NI x86 extension instruction set + pub aesni: bool, + + /// Flag to indicate whether the host machine supports AVX2 x86 extension instruction set + pub avx2: bool, + + /// Number of SMT logical processors available. + pub smt_logical_processor_count: Vec<u32>, + + /// Flag to indicate whether the host machine supports OSXSAVE instruction + pub osxsave: bool, + + /// Flag to indicate whether the host machine supports Intel Software Guard Extensions (SGX) set of instruction codes + pub sgx: bool, + + /// Flag to indicate whether the host machine supports XSAVE instruction + pub xsave: bool, +} + +#[derive(Clone, Debug, Default, Serialize, Deserialize, JsonSchema)] +#[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] +pub struct NodeDescription { + /// moniker defines a human-readable name for the node. + pub moniker: String, + + /// website defines an optional website link. + pub website: String, + + /// security contact defines an optional email for security contact. + pub security_contact: String, + + /// details define other optional details. + pub details: String, } diff --git a/nym-node/nym-node-requests/src/lib.rs b/nym-node/nym-node-requests/src/lib.rs index 9bb345eca9..d5ae5d5368 100644 --- a/nym-node/nym-node-requests/src/lib.rs +++ b/nym-node/nym-node-requests/src/lib.rs @@ -7,17 +7,21 @@ pub mod api; pub mod error; +macro_rules! absolute_route { + ( $name:ident, $parent:expr, $suffix:expr ) => { + pub fn $name() -> String { + format!("{}{}", $parent, $suffix) + } + }; +} + // still thinking how to nicely organise it pub mod routes { - use crate::absolute_route; - pub const LANDING_PAGE: &str = "/"; pub const ROOT: &str = "/"; pub const API: &str = "/api"; pub mod api { - use super::*; - pub const V1: &str = "/v1"; absolute_route!(v1_absolute, super::API, V1); @@ -28,25 +32,44 @@ pub mod routes { pub const ROLES: &str = "/roles"; pub const BUILD_INFO: &str = "/build-information"; pub const HOST_INFO: &str = "/host-information"; - + pub const SYSTEM_INFO: &str = "/system-info"; + pub const NODE_DESCRIPTION: &str = "/description"; pub const HEALTH: &str = "/health"; + pub const SWAGGER: &str = "/swagger"; + pub const GATEWAY: &str = "/gateway"; pub const MIXNODE: &str = "/mixnode"; + pub const METRICS: &str = "/metrics"; pub const NETWORK_REQUESTER: &str = "/network-requester"; pub const IP_PACKET_ROUTER: &str = "/ip-packet-router"; - pub const SWAGGER: &str = "/swagger"; // define helper functions to get absolute routes absolute_route!(health_absolute, v1_absolute(), HEALTH); absolute_route!(roles_absolute, v1_absolute(), ROLES); absolute_route!(build_info_absolute, v1_absolute(), BUILD_INFO); absolute_route!(host_info_absolute, v1_absolute(), HOST_INFO); + absolute_route!(system_info_absolute, v1_absolute(), SYSTEM_INFO); + absolute_route!(description_absolute, v1_absolute(), NODE_DESCRIPTION); + absolute_route!(gateway_absolute, v1_absolute(), GATEWAY); absolute_route!(mixnode_absolute, v1_absolute(), MIXNODE); + absolute_route!(metrics_absolute, v1_absolute(), METRICS); absolute_route!(network_requester_absolute, v1_absolute(), NETWORK_REQUESTER); absolute_route!(ip_packet_router_absolute, v1_absolute(), IP_PACKET_ROUTER); absolute_route!(swagger_absolute, v1_absolute(), SWAGGER); + pub mod metrics { + use super::*; + + pub const MIXING: &str = "/mixing"; + pub const VERLOC: &str = "/verloc"; + pub const PROMETHEUS: &str = "/prometheus"; + + absolute_route!(mixing_absolute, metrics_absolute(), MIXING); + absolute_route!(verloc_absolute, metrics_absolute(), VERLOC); + absolute_route!(prometheus_absolute, metrics_absolute(), PROMETHEUS); + } + pub mod gateway { use super::*; @@ -106,15 +129,6 @@ pub mod routes { } } -#[macro_export] -macro_rules! absolute_route { - ( $name:ident, $parent:expr, $suffix:expr ) => { - pub fn $name() -> String { - format!("{}{}", $parent, $suffix) - } - }; -} - #[cfg(test)] mod tests { use super::*; diff --git a/nym-node/src/cli/commands/bonding_information.rs b/nym-node/src/cli/commands/bonding_information.rs new file mode 100644 index 0000000000..cefa4da954 --- /dev/null +++ b/nym-node/src/cli/commands/bonding_information.rs @@ -0,0 +1,41 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::helpers::ConfigArgs; +use crate::env::vars::NYMNODE_MODE_ARG; +use crate::node::bonding_information::BondingInformationV1; +use nym_bin_common::output_format::OutputFormat; +use nym_node::config::upgrade_helpers::try_load_current_config; +use nym_node::config::NodeMode; +use nym_node::error::NymNodeError; + +#[derive(Debug, clap::Args)] +pub struct Args { + #[clap(flatten)] + pub(crate) config: ConfigArgs, + + #[clap( + long, + value_enum, + env = NYMNODE_MODE_ARG + )] + pub(crate) mode: Option<NodeMode>, + + /// Specify the output format of the bonding information (`text` or `json`) + #[clap( + short, + long, + default_value_t = OutputFormat::default(), + )] + pub(crate) output: OutputFormat, +} + +pub async fn execute(args: Args) -> Result<(), NymNodeError> { + let config = try_load_current_config(args.config.config_path()).await?; + let mut info = BondingInformationV1::try_load(&config)?; + if let Some(mode) = args.mode { + info = info.with_mode(mode) + } + args.output.to_stdout(&info); + Ok(()) +} diff --git a/nym-node/src/cli/commands/build_info.rs b/nym-node/src/cli/commands/build_info.rs new file mode 100644 index 0000000000..e8f28ba3c4 --- /dev/null +++ b/nym-node/src/cli/commands/build_info.rs @@ -0,0 +1,17 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use nym_bin_common::bin_info_owned; +use nym_bin_common::output_format::OutputFormat; +use nym_node::error::NymNodeError; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +pub(crate) fn execute(args: Args) -> Result<(), NymNodeError> { + println!("{}", args.output.format(&bin_info_owned!())); + Ok(()) +} diff --git a/nym-node/src/cli/commands/migrate.rs b/nym-node/src/cli/commands/migrate.rs new file mode 100644 index 0000000000..5b34d6e903 --- /dev/null +++ b/nym-node/src/cli/commands/migrate.rs @@ -0,0 +1,631 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::helpers::{ + EntryGatewayArgs, ExitGatewayArgs, HostArgs, HttpArgs, MixnetArgs, MixnodeArgs, WireguardArgs, +}; +use crate::node::description::save_node_description; +use crate::node::helpers::{load_ed25519_identity_public_key, store_x25519_noise_keypair}; +use clap::ValueEnum; +use nym_crypto::asymmetric::x25519; +use nym_gateway::helpers::{load_ip_packet_router_config, load_network_requester_config}; +use nym_gateway::GatewayError; +use nym_mixnode::MixnodeError; +use nym_network_requester::{CustomGatewayDetails, GatewayDetails}; +use nym_node::config; +use nym_node::config::mixnode::DEFAULT_VERLOC_PORT; +use nym_node::config::{default_config_filepath, ConfigBuilder, NodeMode}; +use nym_node::config::{Config, DEFAULT_WIREGUARD_NETWORK_IP}; +use nym_node::error::{EntryGatewayError, ExitGatewayError, NymNodeError}; +use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription; +use rand::rngs::OsRng; +use std::fmt::{Display, Formatter}; +use std::fs::create_dir_all; +use std::net::SocketAddr; +use std::path::{Path, PathBuf}; +use std::{fs, io}; +use tracing::{info, trace, warn}; +use zeroize::Zeroizing; + +#[derive(Debug, Clone, Copy, ValueEnum)] +enum NodeType { + Mixnode, + Gateway, +} + +impl Display for NodeType { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + NodeType::Mixnode => write!(f, "mixnode"), + NodeType::Gateway => write!(f, "gateway"), + } + } +} + +#[derive(clap::Args, Debug)] +#[clap(group = clap::ArgGroup::new("old-config").required(true))] +pub(crate) struct Args { + /// Type of node (mixnode or gateway) to migrate into a nym-node. + node_type: NodeType, + + /// Id of the node that's going to get migrated + #[clap(long, group = "old-config")] + id: Option<String>, + + /// Path to a configuration file of the node that's going to get migrated. + #[clap(long, group = "old-config")] + config_file: Option<PathBuf>, + + /// Specify whether to preserve id of the imported node. + #[clap(long)] + preserve_id: bool, + + // totally optional arguments for overriding any defaults: + #[clap(flatten)] + host: HostArgs, + + #[clap(flatten)] + http: HttpArgs, + + #[clap(flatten)] + mixnet: MixnetArgs, + + #[clap(flatten)] + wireguard: WireguardArgs, + + #[clap(flatten)] + mixnode: MixnodeArgs, + + #[clap(flatten)] + entry_gateway: EntryGatewayArgs, + + #[clap(flatten)] + exit_gateway: ExitGatewayArgs, +} + +impl Args { + fn take_mnemonic(&mut self) -> Option<Zeroizing<bip39::Mnemonic>> { + self.entry_gateway.mnemonic.take().map(Zeroizing::new) + } + + fn config_path(&self) -> PathBuf { + // SAFETY: + // if `config_file` hasn't been specified, `id` MUST be available due to clap's ArgGroup + #[allow(clippy::unwrap_used)] + self.config_file.clone().unwrap_or_else(|| { + let id = self.id.as_ref().unwrap(); + match self.node_type { + NodeType::Mixnode => nym_mixnode::config::default_config_filepath(id), + NodeType::Gateway => nym_gateway::config::default_config_filepath(id), + } + }) + } +} + +fn nym_node_id( + typ: NodeType, + original_id: &str, + preserve_id: bool, +) -> Result<String, NymNodeError> { + if preserve_id { + let path = default_config_filepath(original_id); + if path.exists() { + return Err(NymNodeError::MigrationFailure { + node_type: typ.to_string(), + message: format!("nym-node with id '{original_id}' already exists"), + }); + } + } + + let mut candidate = original_id.to_string(); + let mut counter = 0; + loop { + let path = default_config_filepath(&candidate); + if path.exists() { + warn!("nym-node with id '{candidate}' already exists") + } else { + return Ok(candidate); + } + + candidate = format!("{original_id}-{counter}"); + counter += 1; + } +} + +fn copy_old_data<P: AsRef<Path>, Q: AsRef<Path>>( + node_type: NodeType, + from: P, + to: Q, +) -> Result<(), NymNodeError> { + fn copy_inner<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> { + if let Some(parent) = to.as_ref().parent() { + create_dir_all(parent)?; + } + fs::copy(from, to)?; + Ok(()) + } + + if let Err(err) = copy_inner(from.as_ref(), to.as_ref()) { + return Err(NymNodeError::MigrationFailure { + node_type: node_type.to_string(), + message: format!( + "failed to move '{}' to '{}': {err}", + from.as_ref().display(), + to.as_ref().display() + ), + }); + } + Ok(()) +} + +async fn migrate_mixnode(mut args: Args) -> Result<(), NymNodeError> { + let maybe_custom_mnemonic = args.take_mnemonic(); + let config_file = args.config_path(); + let preserve_id = args.preserve_id; + + info!( + "attempting to migrate mixnode from '{}'", + config_file.display() + ); + let cfg = nym_mixnode::config::Config::read_from_toml_file(&config_file).map_err(|source| { + MixnodeError::ConfigLoadFailure { + id: "???".to_string(), + path: config_file, + source, + } + })?; + + let old_description = if cfg.storage_paths.node_description.exists() { + Some( + nym_mixnode::node::node_description::NodeDescription::load_from_file( + &cfg.storage_paths.node_description, + ) + .map_err(|source| { + nym_node::error::MixnodeError::DescriptionLoadFailure { + path: cfg.storage_paths.node_description, + source, + } + })?, + ) + } else { + None + }; + + let nymnode_id = nym_node_id(NodeType::Mixnode, &cfg.mixnode.id, preserve_id)?; + let nym_node_config_path = default_config_filepath(&nymnode_id); + let data_dir = Config::default_data_directory(&nym_node_config_path)?; + + let ip = cfg.mixnode.listening_address; + + let location = old_description + .as_ref() + .and_then(|d| d.location.parse().ok()); + + // generate nym-node config + let config = ConfigBuilder::new(nymnode_id, nym_node_config_path, data_dir.clone()) + .with_mode(NodeMode::Mixnode) + .with_host(args.host.override_config_section(config::Host { + public_ips: cfg.host.public_ips, + hostname: cfg.host.hostname, + location, + })) + .with_http(args.http.override_config_section(config::Http { + bind_address: cfg.http.bind_address, + landing_page_assets_path: cfg.http.landing_page_assets_path, + access_token: cfg.http.metrics_key, + ..Default::default() + })) + .with_mixnet(args.mixnet.override_config_section(config::Mixnet { + bind_address: SocketAddr::new(ip, cfg.mixnode.mix_port), + nym_api_urls: cfg.mixnode.nym_api_urls, + debug: config::MixnetDebug { + packet_forwarding_initial_backoff: cfg.debug.packet_forwarding_initial_backoff, + packet_forwarding_maximum_backoff: cfg.debug.packet_forwarding_maximum_backoff, + initial_connection_timeout: cfg.debug.initial_connection_timeout, + maximum_connection_buffer_size: cfg.debug.maximum_connection_buffer_size, + }, + ..Default::default() + })) + .with_mixnode(args.mixnode.override_config_section(config::MixnodeConfig { + verloc: config::mixnode::Verloc { + bind_address: SocketAddr::new(ip, cfg.mixnode.verloc_port), + debug: config::mixnode::VerlocDebug { + packets_per_node: cfg.verloc.packets_per_node, + connection_timeout: cfg.verloc.connection_timeout, + packet_timeout: cfg.verloc.packet_timeout, + delay_between_packets: cfg.verloc.delay_between_packets, + tested_nodes_batch_size: cfg.verloc.tested_nodes_batch_size, + testing_interval: cfg.verloc.testing_interval, + retry_timeout: cfg.verloc.retry_timeout, + }, + }, + debug: config::mixnode::Debug { + node_stats_logging_delay: cfg.debug.node_stats_logging_delay, + node_stats_updating_delay: cfg.debug.node_stats_updating_delay, + }, + ..config::MixnodeConfig::new_default() + })) + .with_wireguard(args.wireguard.build_config_section(&data_dir)) + .with_entry_gateway(args.entry_gateway.build_config_section(&data_dir)) + .with_exit_gateway(args.exit_gateway.build_config_section(&data_dir)) + .build(); + + let d_ref = old_description.as_ref(); + + // update description + let node_description = NodeDescription { + moniker: d_ref.map(|d| &d.name).cloned().unwrap_or_default(), + website: d_ref.map(|d| &d.link).cloned().unwrap_or_default(), + security_contact: "".to_string(), + details: d_ref.map(|d| &d.description).cloned().unwrap_or_default(), + }; + save_node_description(&config.storage_paths.description, &node_description)?; + + // create noise keypair + let mut rng = OsRng; + let x25519_noise_keys = x25519::KeyPair::new(&mut rng); + trace!("attempting to store x25519 noise keypair"); + store_x25519_noise_keypair( + &x25519_noise_keys, + config.storage_paths.keys.x25519_noise_storage_paths(), + )?; + + // move existing keys and generate missing data + info!("attempting to copy mixnode keys to their new locations"); + copy_old_data( + NodeType::Mixnode, + cfg.storage_paths.keys.public_identity_key_file, + &config.storage_paths.keys.public_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Mixnode, + cfg.storage_paths.keys.private_identity_key_file, + &config.storage_paths.keys.private_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Mixnode, + cfg.storage_paths.keys.public_sphinx_key_file, + &config.storage_paths.keys.public_x25519_sphinx_key_file, + )?; + copy_old_data( + NodeType::Mixnode, + cfg.storage_paths.keys.private_sphinx_key_file, + &config.storage_paths.keys.private_x25519_sphinx_key_file, + )?; + + let ed25519_public_key = load_ed25519_identity_public_key( + &config.storage_paths.keys.public_ed25519_identity_key_file, + )?; + + // entry gateway initialisation + crate::node::EntryGatewayData::initialise(&config.entry_gateway, maybe_custom_mnemonic)?; + + // exit gateway initialisation + crate::node::ExitGatewayData::initialise(&config.exit_gateway, ed25519_public_key).await?; + + config.save()?; + + info!( + "mixnode {} has been migrated into a nym-node! all of its data can now be deleted", + cfg.mixnode.id + ); + + Ok(()) +} + +async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> { + let config_file = args.config_path(); + let preserve_id = args.preserve_id; + + info!( + "attempting to migrate gateway from '{}'", + config_file.display() + ); + let cfg = nym_gateway::config::Config::read_from_toml_file(&config_file) + .map_err(|source| GatewayError::ConfigLoadFailure { + id: "???".to_string(), + path: config_file, + source, + }) + .map_err(EntryGatewayError::from)?; + + let nr_cfg = match &cfg.storage_paths.network_requester_config { + None => None, + Some(nr_cfg) => Some( + load_network_requester_config("???", nr_cfg) + .await + .map_err(ExitGatewayError::from)?, + ), + }; + + let ipr_cfg = match &cfg.storage_paths.ip_packet_router_config { + None => None, + Some(ipr_cfg) => Some( + load_ip_packet_router_config("???", ipr_cfg) + .await + .map_err(ExitGatewayError::from)?, + ), + }; + + let nymnode_id = nym_node_id(NodeType::Gateway, &cfg.gateway.id, preserve_id)?; + let nym_node_config_path = default_config_filepath(&nymnode_id); + let data_dir = Config::default_data_directory(&nym_node_config_path)?; + + let mode = if cfg.network_requester.enabled && cfg.ip_packet_router.enabled { + NodeMode::ExitGateway + } else { + NodeMode::EntryGateway + }; + + let ip = cfg.gateway.listening_address; + + // prefer new mnemonic explicitly passed with cli; otherwise use the one already present + let mnemonic = args + .take_mnemonic() + .unwrap_or(Zeroizing::new(cfg.gateway.cosmos_mnemonic.clone())); + + let config = ConfigBuilder::new(nymnode_id, nym_node_config_path, data_dir.clone()) + .with_mode(mode) + .with_host(args.host.override_config_section(config::Host { + public_ips: cfg.host.public_ips, + hostname: cfg.host.hostname, + ..Default::default() + })) + .with_http(args.http.override_config_section(config::Http { + bind_address: cfg.http.bind_address, + landing_page_assets_path: cfg.http.landing_page_assets_path, + ..Default::default() + })) + .with_mixnet(args.mixnet.override_config_section(config::Mixnet { + bind_address: SocketAddr::new(ip, cfg.gateway.mix_port), + nym_api_urls: cfg.gateway.nym_api_urls.clone(), + nyxd_urls: cfg.gateway.nyxd_urls.clone(), + debug: config::MixnetDebug { + packet_forwarding_initial_backoff: cfg.debug.packet_forwarding_initial_backoff, + packet_forwarding_maximum_backoff: cfg.debug.packet_forwarding_maximum_backoff, + initial_connection_timeout: cfg.debug.initial_connection_timeout, + maximum_connection_buffer_size: cfg.debug.maximum_connection_buffer_size, + }, + })) + .with_mixnode(args.mixnode.override_config_section(config::MixnodeConfig { + verloc: config::mixnode::Verloc { + bind_address: SocketAddr::new(ip, DEFAULT_VERLOC_PORT), + ..Default::default() + }, + ..config::MixnodeConfig::new_default() + })) + .with_wireguard(args.wireguard.override_config_section(config::Wireguard { + enabled: cfg.wireguard.enabled, + bind_address: cfg.wireguard.bind_address, + private_network_ip: DEFAULT_WIREGUARD_NETWORK_IP, + announced_port: cfg.wireguard.announced_port, + private_network_prefix: cfg.wireguard.private_network_prefix, + // this is fine as currently the paths stored inside gateway itself are empty + storage_paths: config::persistence::WireguardPaths::new(&data_dir), + })) + .with_entry_gateway(args.entry_gateway.override_config_section( + config::EntryGatewayConfig { + storage_paths: config::persistence::EntryGatewayPaths::new(&data_dir), + enforce_zk_nyms: cfg.gateway.only_coconut_credentials, + bind_address: SocketAddr::new(ip, cfg.gateway.clients_port), + announce_ws_port: None, + announce_wss_port: cfg.gateway.clients_wss_port, + debug: config::entry_gateway::Debug { + message_retrieval_limit: cfg.debug.message_retrieval_limit, + }, + }, + )) + .with_exit_gateway( + args.exit_gateway + .override_config_section(config::ExitGatewayConfig { + storage_paths: config::persistence::ExitGatewayPaths::new(&data_dir), + open_proxy: false, + upstream_exit_policy_url: nr_cfg + .as_ref() + .and_then(|c| c.network_requester.upstream_exit_policy_url.clone()) + .unwrap_or( + config::ExitGatewayConfig::new_default(".").upstream_exit_policy_url, + ), + network_requester: config::exit_gateway::NetworkRequester { + debug: config::exit_gateway::NetworkRequesterDebug { + enabled: cfg.network_requester.enabled, + disable_poisson_rate: nr_cfg + .as_ref() + .map(|c| c.network_requester.disable_poisson_rate) + .unwrap_or( + config::exit_gateway::NetworkRequesterDebug::default() + .disable_poisson_rate, + ), + client_debug: nr_cfg.as_ref().map(|c| c.base.debug).unwrap_or_default(), + }, + }, + ip_packet_router: config::exit_gateway::IpPacketRouter { + debug: config::exit_gateway::IpPacketRouterDebug { + enabled: cfg.ip_packet_router.enabled, + disable_poisson_rate: ipr_cfg + .as_ref() + .map(|c| c.ip_packet_router.disable_poisson_rate) + .unwrap_or( + config::exit_gateway::IpPacketRouterDebug::default() + .disable_poisson_rate, + ), + client_debug: ipr_cfg + .as_ref() + .map(|c| c.base.debug) + .unwrap_or_default(), + }, + }, + }), + ) + .build(); + + // create noise keypair + let mut rng = OsRng; + let x25519_noise_keys = x25519::KeyPair::new(&mut rng); + trace!("attempting to store x25519 noise keypair"); + store_x25519_noise_keypair( + &x25519_noise_keys, + config.storage_paths.keys.x25519_noise_storage_paths(), + )?; + + // move existing keys and generate missing data + info!("attempting to copy gateway keys to their new locations"); + + copy_old_data( + NodeType::Gateway, + cfg.storage_paths.keys.public_identity_key_file, + &config.storage_paths.keys.public_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + cfg.storage_paths.keys.private_identity_key_file, + &config.storage_paths.keys.private_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + cfg.storage_paths.keys.public_sphinx_key_file, + &config.storage_paths.keys.public_x25519_sphinx_key_file, + )?; + copy_old_data( + NodeType::Gateway, + cfg.storage_paths.keys.private_sphinx_key_file, + &config.storage_paths.keys.private_x25519_sphinx_key_file, + )?; + + let ed25519_public_key = load_ed25519_identity_public_key( + &config.storage_paths.keys.public_ed25519_identity_key_file, + )?; + + // mixnode data initialisation + crate::node::MixnodeData::initialise(&config.mixnode)?; + + // selectively initialise exit gateway + let gateway_details = + GatewayDetails::Custom(CustomGatewayDetails::new(ed25519_public_key)).into(); + let mut rng = OsRng; + + if let Some(nr_cfg) = nr_cfg { + let nr_paths = nr_cfg.storage_paths.common_paths; + let new_nr_paths = &config.exit_gateway.storage_paths.network_requester; + + copy_old_data( + NodeType::Gateway, + nr_paths.keys.public_identity_key_file, + &new_nr_paths.public_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.keys.private_identity_key_file, + &new_nr_paths.private_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.keys.public_encryption_key_file, + &new_nr_paths.public_x25519_diffie_hellman_key_file, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.keys.private_encryption_key_file, + &new_nr_paths.private_x25519_diffie_hellman_key_file, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.keys.ack_key_file, + &new_nr_paths.ack_key_file, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.gateway_registrations, + &new_nr_paths.gateway_registrations, + )?; + copy_old_data( + NodeType::Gateway, + nr_paths.reply_surb_database, + &new_nr_paths.reply_surb_database, + )?; + } else { + crate::node::ExitGatewayData::initialise_network_requester( + &mut rng, + &config.exit_gateway, + &gateway_details, + ) + .await?; + } + + if let Some(ipr_cfg) = ipr_cfg { + let ipr_paths = ipr_cfg.storage_paths.common_paths; + let new_ipr_paths = &config.exit_gateway.storage_paths.ip_packet_router; + + copy_old_data( + NodeType::Gateway, + ipr_paths.keys.public_identity_key_file, + &new_ipr_paths.public_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.keys.private_identity_key_file, + &new_ipr_paths.private_ed25519_identity_key_file, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.keys.public_encryption_key_file, + &new_ipr_paths.public_x25519_diffie_hellman_key_file, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.keys.private_encryption_key_file, + &new_ipr_paths.private_x25519_diffie_hellman_key_file, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.keys.ack_key_file, + &new_ipr_paths.ack_key_file, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.gateway_registrations, + &new_ipr_paths.gateway_registrations, + )?; + copy_old_data( + NodeType::Gateway, + ipr_paths.reply_surb_database, + &new_ipr_paths.reply_surb_database, + )?; + } else { + crate::node::ExitGatewayData::initialise_ip_packet_router_requester( + &mut rng, + &config.exit_gateway, + &gateway_details, + ) + .await?; + } + + save_node_description( + &config.storage_paths.description, + &NodeDescription::default(), + )?; + + // finally move the mnemonic + config + .entry_gateway + .storage_paths + .save_mnemonic_to_file(&mnemonic)?; + + config.save()?; + + info!( + "gateway {} has been migrated into a nym-node! all of its data can now be deleted", + cfg.gateway.id + ); + + Ok(()) +} + +pub(crate) async fn execute(args: Args) -> Result<(), NymNodeError> { + trace!("args: {args:#?}"); + + match args.node_type { + NodeType::Mixnode => migrate_mixnode(args).await, + NodeType::Gateway => migrate_gateway(args).await, + } +} diff --git a/nym-node/src/cli/commands/mod.rs b/nym-node/src/cli/commands/mod.rs new file mode 100644 index 0000000000..16d6e3611b --- /dev/null +++ b/nym-node/src/cli/commands/mod.rs @@ -0,0 +1,9 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +pub(crate) mod bonding_information; +pub(super) mod build_info; +pub(super) mod migrate; +pub(crate) mod node_details; +pub(super) mod run; +pub(super) mod sign; diff --git a/nym-node/src/cli/commands/node_details.rs b/nym-node/src/cli/commands/node_details.rs new file mode 100644 index 0000000000..64e6a4f3ac --- /dev/null +++ b/nym-node/src/cli/commands/node_details.rs @@ -0,0 +1,29 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::helpers::ConfigArgs; +use crate::node::NymNode; +use nym_bin_common::output_format::OutputFormat; +use nym_node::config::upgrade_helpers::try_load_current_config; +use nym_node::error::NymNodeError; + +#[derive(Debug, clap::Args)] +pub(crate) struct Args { + #[clap(flatten)] + pub(crate) config: ConfigArgs, + + /// Specify the output format of the node details (`text` or `json`) + #[clap( + short, + long, + default_value_t = OutputFormat::default(), + )] + pub(crate) output: OutputFormat, +} + +pub async fn execute(args: Args) -> Result<(), NymNodeError> { + let config = try_load_current_config(args.config.config_path()).await?; + let details = NymNode::new(config).await?.display_details(); + args.output.to_stdout(&details); + Ok(()) +} diff --git a/nym-node/src/cli/commands/run/args.rs b/nym-node/src/cli/commands/run/args.rs new file mode 100644 index 0000000000..9746f883b7 --- /dev/null +++ b/nym-node/src/cli/commands/run/args.rs @@ -0,0 +1,148 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::helpers::{ + ConfigArgs, EntryGatewayArgs, ExitGatewayArgs, HostArgs, HttpArgs, MixnetArgs, MixnodeArgs, + WireguardArgs, +}; +use crate::env::vars::*; +use nym_bin_common::output_format::OutputFormat; +use nym_node::config::persistence::NymNodePaths; +use nym_node::config::{Config, ConfigBuilder, NodeMode}; +use nym_node::error::NymNodeError; +use std::path::PathBuf; +use zeroize::Zeroizing; + +#[derive(clap::Args, Debug)] +pub(crate) struct Args { + #[clap(flatten)] + pub(crate) config: ConfigArgs, + + /// Forbid a new node from being initialised if configuration file for the provided specification doesn't already exist + #[clap( + long, + default_value_t = false, + env = NYMNODE_DENY_INIT_ARG, + conflicts_with = "init_only" + )] + pub(crate) deny_init: bool, + + /// If this is a brand new nym-node, specify whether it should only be initialised without actually running the subprocesses. + #[clap( + long, + default_value_t = false, + env = NYMNODE_INIT_ONLY_ARG, + conflicts_with = "deny_init" + )] + pub(crate) init_only: bool, + + /// Specifies the current mode of this nym-node. + #[clap( + long, + value_enum, + env = NYMNODE_MODE_ARG + )] + pub(crate) mode: Option<NodeMode>, + + /// If this node has been initialised before, specify whether to write any new changes to the config file. + #[clap( + short, + long, + default_value_t = false, + env = NYMMONDE_WRITE_CONFIG_CHANGES_ARG, + )] + pub(crate) write_changes: bool, + + /// Specify output file for bonding information of this nym-node, i.e. its encoded keys. + /// NOTE: the required bonding information is still a subject to change and this argument should be treated + /// only as a preview of future features. + #[clap( + long, + env = NYMNODE_BONDING_INFORMATION_OUTPUT_ARG + )] + pub(crate) bonding_information_output: Option<PathBuf>, + + /// Specify the output format of the bonding information (`text` or `json`) + #[clap( + short, + long, + default_value_t = OutputFormat::default(), + env = NYMNODE_OUTPUT_ARG + )] + pub(crate) output: OutputFormat, + + #[clap(flatten)] + host: HostArgs, + + #[clap(flatten)] + http: HttpArgs, + + #[clap(flatten)] + mixnet: MixnetArgs, + + #[clap(flatten)] + wireguard: WireguardArgs, + + #[clap(flatten)] + mixnode: MixnodeArgs, + + #[clap(flatten)] + entry_gateway: EntryGatewayArgs, + + #[clap(flatten)] + exit_gateway: ExitGatewayArgs, +} + +impl Args { + pub(super) fn take_mnemonic(&mut self) -> Option<Zeroizing<bip39::Mnemonic>> { + self.entry_gateway.mnemonic.take().map(Zeroizing::new) + } +} + +impl Args { + pub(crate) fn build_config(self) -> Result<Config, NymNodeError> { + let config_path = self.config.config_path(); + let data_dir = Config::default_data_directory(&config_path)?; + + let id = self + .config + .id() + .clone() + .ok_or(NymNodeError::MissingInitArg { + section: "global".to_string(), + name: "id".to_string(), + })?; + + let config = ConfigBuilder::new(id, config_path.clone(), data_dir.clone()) + .with_mode(self.mode.unwrap_or_default()) + .with_host(self.host.build_config_section()) + .with_http(self.http.build_config_section()) + .with_mixnet(self.mixnet.build_config_section()) + .with_wireguard(self.wireguard.build_config_section(&data_dir)) + .with_storage_paths(NymNodePaths::new(&data_dir)) + .with_mixnode(self.mixnode.build_config_section()) + .with_entry_gateway(self.entry_gateway.build_config_section(&data_dir)) + .with_exit_gateway(self.exit_gateway.build_config_section(&data_dir)) + .build(); + + Ok(config) + } + + pub(crate) fn override_config(self, mut config: Config) -> Config { + if let Some(mode) = self.mode { + config.mode = mode; + } + config.host = self.host.override_config_section(config.host); + config.http = self.http.override_config_section(config.http); + config.mixnet = self.mixnet.override_config_section(config.mixnet); + config.wireguard = self.wireguard.override_config_section(config.wireguard); + config.mixnode = self.mixnode.override_config_section(config.mixnode); + config.entry_gateway = self + .entry_gateway + .override_config_section(config.entry_gateway); + config.exit_gateway = self + .exit_gateway + .override_config_section(config.exit_gateway); + config + } +} diff --git a/nym-node/src/cli/commands/run/mod.rs b/nym-node/src/cli/commands/run/mod.rs new file mode 100644 index 0000000000..74d4d369a8 --- /dev/null +++ b/nym-node/src/cli/commands/run/mod.rs @@ -0,0 +1,77 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node::bonding_information::BondingInformationV1; +use crate::node::NymNode; +use nym_node::config::upgrade_helpers::try_load_current_config; +use nym_node::error::NymNodeError; +use std::fs; +use tracing::{debug, info, trace}; + +mod args; + +pub(crate) use args::Args; + +pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> { + trace!("passed arguments: {args:#?}"); + + let config_path = args.config.config_path(); + let output = args.output; + let bonding_info_path = args.bonding_information_output.clone(); + + let config = if !config_path.exists() { + debug!("no configuration file found at '{}'", config_path.display()); + info!("initialising new nym-node"); + if args.deny_init { + return Err(NymNodeError::ForbiddenInitialisation { config_path }); + } + let init_only = args.init_only; + + let maybe_custom_mnemonic = args.take_mnemonic(); + + let config = args.build_config()?; + NymNode::initialise(&config, maybe_custom_mnemonic).await?; + if init_only { + debug!("returning due to the 'init-only' flag"); + return Ok(()); + } + + config + } else { + info!( + "attempting to load nym-node configuration from {}", + config_path.display() + ); + let write_changes = args.write_changes; + let config = args.override_config(try_load_current_config(config_path).await?); + + if write_changes { + config.save()?; + } + config + }; + + let nym_node = NymNode::new(config).await?; + + // if requested, write bonding info + if let Some(bonding_info_path) = bonding_info_path { + info!( + "writing bonding information to '{}'", + bonding_info_path.display() + ); + let info = BondingInformationV1::from_data( + nym_node.mode(), + nym_node.ed25519_identity_key().to_base58_string(), + nym_node.x25519_sphinx_key().to_base58_string(), + ); + let data = output.format(&info); + fs::write(&bonding_info_path, data).map_err(|source| { + NymNodeError::BondingInfoWriteFailure { + path: bonding_info_path, + source, + } + })?; + } + + nym_node.run().await +} diff --git a/nym-node/src/cli/commands/sign.rs b/nym-node/src/cli/commands/sign.rs new file mode 100644 index 0000000000..67c44977cf --- /dev/null +++ b/nym-node/src/cli/commands/sign.rs @@ -0,0 +1,88 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::helpers::ConfigArgs; +use crate::node::helpers::load_ed25519_identity_keypair; +use nym_bin_common::output_format::OutputFormat; +use nym_crypto::asymmetric::identity; +use nym_node::config::upgrade_helpers::try_load_current_config; +use nym_node::error::NymNodeError; +use nym_types::helpers::ConsoleSigningOutput; + +// I don't think it makes sense to expose 'text' and 'contract-msg' as env variables +#[derive(Debug, clap::Args)] +#[clap(group = clap::ArgGroup::new("message").required(true))] +pub struct Args { + #[clap(flatten)] + config: ConfigArgs, + + /// Signs an arbitrary piece of text with your identity key + #[clap(long, group = "message")] + text: Option<String>, + + /// Signs a transaction-specific payload, that is going to be sent to the smart contract, with your identity key + #[clap(long, group = "message")] + contract_msg: Option<String>, + + #[clap(short, long, default_value_t = OutputFormat::default())] + output: OutputFormat, +} + +fn print_signed_text(private_key: &identity::PrivateKey, text: &str, output: OutputFormat) { + eprintln!("Signing the text {text:?} using your node's Ed25519 identity key...",); + + let signature = private_key.sign_text(text); + let sign_output = ConsoleSigningOutput::new(text, signature); + output.to_stdout(&sign_output); +} + +fn print_signed_contract_msg( + private_key: &identity::PrivateKey, + raw_msg: &str, + output: OutputFormat, +) { + let trimmed = raw_msg.trim(); + eprintln!(">>> attempting to sign {trimmed}"); + + let Ok(decoded) = bs58::decode(trimmed).into_vec() else { + println!("it seems you have incorrectly copied the message to sign. Make sure you didn't accidentally skip any characters"); + return; + }; + + eprintln!(">>> decoding the message..."); + + // we don't really care about what particular information is embedded inside of it, + // we just want to know if user correctly copied the string, i.e. whether it's a valid bs58 encoded json + if serde_json::from_slice::<serde_json::Value>(&decoded).is_err() { + println!("it seems you have incorrectly copied the message to sign. Make sure you didn't accidentally skip any characters"); + return; + }; + + // SAFETY: + // if this is a valid json, it MUST be a valid string + #[allow(clippy::unwrap_used)] + let decoded_string = String::from_utf8(decoded.clone()).unwrap(); + let signature = private_key.sign(&decoded).to_base58_string(); + + let sign_output = ConsoleSigningOutput::new(decoded_string, signature); + println!("{}", output.format(&sign_output)); +} + +pub async fn execute(args: Args) -> Result<(), NymNodeError> { + println!("args: {args:?}"); + + let config = try_load_current_config(args.config.config_path()).await?; + let identity_keypair = + load_ed25519_identity_keypair(config.storage_paths.keys.ed25519_identity_storage_paths())?; + + // note: due to clap's ArgGroup, one (and only one) of those branches will be called + if let Some(text) = args.text { + print_signed_text(identity_keypair.private_key(), &text, args.output); + Ok(()) + } else if let Some(contract_msg) = args.contract_msg { + print_signed_contract_msg(identity_keypair.private_key(), &contract_msg, args.output); + Ok(()) + } else { + unreachable!() + } +} diff --git a/nym-node/src/cli/helpers.rs b/nym-node/src/cli/helpers.rs new file mode 100644 index 0000000000..ad4e923269 --- /dev/null +++ b/nym-node/src/cli/helpers.rs @@ -0,0 +1,434 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use super::DEFAULT_NYMNODE_ID; +use crate::env::vars::*; +use celes::Country; +use clap::builder::ArgPredicate; +use clap::Args; +use nym_node::config; +use nym_node::config::default_config_filepath; +use std::net::{IpAddr, SocketAddr}; +use std::path::{Path, PathBuf}; +use url::Url; +use zeroize::{Zeroize, ZeroizeOnDrop}; + +#[derive(Args, Debug)] +pub(crate) struct ConfigArgs { + /// Id of the nym-node to use + #[clap( + long, + default_value = DEFAULT_NYMNODE_ID, + default_value_if("config_file", ArgPredicate::IsPresent, None), + env = NYMNODE_ID_ARG, + group = "config" + )] + id: Option<String>, + + /// Path to a configuration file of this node. + #[clap( + long, + env = NYMNODE_CONFIG_PATH_ARG, + group = "config" + )] + config_file: Option<PathBuf>, +} + +impl ConfigArgs { + pub(crate) fn id(&self) -> &Option<String> { + &self.id + } + + pub(crate) fn config_path(&self) -> PathBuf { + // SAFETY: + // if `config_file` hasn't been specified, `id` will default to "DEFAULT_NYMNODE_ID", + // so some value will always be available to use + #[allow(clippy::unwrap_used)] + self.config_file + .clone() + .unwrap_or_else(|| default_config_filepath(self.id.as_ref().unwrap())) + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct HostArgs { + /// Comma separated list of public ip addresses that will be announced to the nym-api and subsequently to the clients. + /// In nearly all circumstances, it's going to be identical to the address you're going to use for bonding. + #[clap( + long, + value_delimiter = ',', + env = NYMNODE_PUBLIC_IPS_ARG + )] + pub(crate) public_ips: Option<Vec<IpAddr>>, + + /// Optional hostname associated with this gateway that will be announced to the nym-api and subsequently to the clients + #[clap( + long, + env = NYMNODE_HOSTNAME_ARG + )] + pub(crate) hostname: Option<String>, + + /// Optional **physical** location of this node's server. + /// Either full country name (e.g. 'Poland'), two-letter alpha2 (e.g. 'PL'), + /// three-letter alpha3 (e.g. 'POL') or three-digit numeric-3 (e.g. '616') can be provided. + #[clap( + long, + env = NYMNODE_LOCATION_ARG + )] + pub(crate) location: Option<Country>, +} + +impl HostArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section(self) -> config::Host { + self.override_config_section(config::Host::default()) + } + + pub(crate) fn override_config_section(self, mut section: config::Host) -> config::Host { + if let Some(public_ips) = self.public_ips { + section.public_ips = public_ips + } + if let Some(hostname) = self.hostname { + section.hostname = Some(hostname) + } + if let Some(location) = self.location { + section.location = Some(location) + } + section + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct HttpArgs { + /// Socket address this node will use for binding its http API. + /// default: `0.0.0.0:8080` + #[clap( + long, + env = NYMNODE_HTTP_BIND_ADDRESS_ARG + )] + pub(crate) http_bind_address: Option<SocketAddr>, + + /// Path to assets directory of custom landing page of this node. + #[clap( + long, + env = NYMNODE_HTTP_LANDING_ASSETS_ARG + )] + pub(crate) landing_page_assets_path: Option<PathBuf>, + + /// An optional bearer token for accessing certain http endpoints. + /// Currently only used for prometheus metrics. + #[clap( + long, + env = NYMNODE_HTTP_ACCESS_TOKEN_ARG, + alias = "http-bearer-token" + )] + pub(crate) http_access_token: Option<String>, + + /// Specify whether basic system information should be exposed. + /// default: true + #[clap( + long, + env = NYMNODE_HTTP_EXPOSE_SYSTEM_INFO_ARG, + )] + pub(crate) expose_system_info: Option<bool>, + + /// Specify whether basic system hardware information should be exposed. + /// default: true + #[clap( + long, + env = NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE_ARG + )] + pub(crate) expose_system_hardware: Option<bool>, + + /// Specify whether detailed system crypto hardware information should be exposed. + /// default: true + #[clap( + long, + env = NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE_ARG + )] + pub(crate) expose_crypto_hardware: Option<bool>, +} + +impl HttpArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section(self) -> config::Http { + self.override_config_section(config::Http::default()) + } + + pub(crate) fn override_config_section(self, mut section: config::Http) -> config::Http { + if let Some(bind_address) = self.http_bind_address { + section.bind_address = bind_address + } + if let Some(landing_page_assets_path) = self.landing_page_assets_path { + section.landing_page_assets_path = Some(landing_page_assets_path) + } + if let Some(access_token) = self.http_access_token { + section.access_token = Some(access_token) + } + if let Some(expose_system_info) = self.expose_system_info { + section.expose_system_info = expose_system_info + } + if let Some(expose_hardware_info) = self.expose_system_hardware { + section.expose_system_hardware = expose_hardware_info + } + if let Some(expose_crypto_hardware) = self.expose_crypto_hardware { + section.expose_crypto_hardware = expose_crypto_hardware + } + section + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct MixnetArgs { + /// Address this node will bind to for listening for mixnet packets + /// default: `0.0.0.0:1789` + #[clap( + long, + env = NYMNODE_MIXNET_BIND_ADDRESS_ARG + )] + pub(crate) mixnet_bind_address: Option<SocketAddr>, + + /// Addresses to nym APIs from which the node gets the view of the network. + #[clap( + long, + value_delimiter = ',', + env = NYMNODE_NYM_APIS_ARG + )] + pub(crate) nym_api_urls: Option<Vec<Url>>, +} + +impl MixnetArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section(self) -> config::Mixnet { + self.override_config_section(config::Mixnet::default()) + } + + pub(crate) fn override_config_section(self, mut section: config::Mixnet) -> config::Mixnet { + if let Some(bind_address) = self.mixnet_bind_address { + section.bind_address = bind_address + } + if let Some(nym_api_urls) = self.nym_api_urls { + section.nym_api_urls = nym_api_urls + } + section + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct WireguardArgs { + /// Specifies whether the wireguard service is enabled on this node. + #[clap( + long, + env = NYMNODE_WG_ENABLED_ARG + )] + pub(crate) wireguard_enabled: Option<bool>, + + /// Socket address this node will use for binding its wireguard interface. + /// default: `0.0.0.0:51822` + #[clap( + long, + env = NYMNODE_WG_BIND_ADDRESS_ARG + )] + pub(crate) wireguard_bind_address: Option<SocketAddr>, + + /// Ip address of the private wireguard network. + /// default: `10.1.0.0` + #[clap( + long, + env = NYMNODE_WG_IP_NETWORK_ARG, + )] + pub(crate) wireguard_private_network_ip: Option<IpAddr>, + + /// Port announced to external clients wishing to connect to the wireguard interface. + /// Useful in the instances where the node is behind a proxy. + #[clap( + long, + env = NYMNODE_WG_ANNOUNCED_PORT_ARG + )] + pub(crate) wireguard_announced_port: Option<u16>, + + /// The prefix denoting the maximum number of the clients that can be connected via Wireguard. + /// The maximum value for IPv4 is 32 and for IPv6 is 128 + #[clap( + long, + env = NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG + )] + pub(crate) wireguard_private_network_prefix: Option<u8>, +} + +impl WireguardArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section<P: AsRef<Path>>(self, data_dir: P) -> config::Wireguard { + self.override_config_section(config::Wireguard::new_default(data_dir)) + } + + pub(crate) fn override_config_section( + self, + mut section: config::Wireguard, + ) -> config::Wireguard { + if let Some(enabled) = self.wireguard_enabled { + section.enabled = enabled + } + + if let Some(bind_address) = self.wireguard_bind_address { + section.bind_address = bind_address + } + + if let Some(announced_port) = self.wireguard_announced_port { + section.announced_port = announced_port + } + + if let Some(private_network_ip) = self.wireguard_private_network_ip { + section.private_network_ip = private_network_ip + } + + if let Some(private_network_prefix) = self.wireguard_private_network_prefix { + section.private_network_prefix = private_network_prefix + } + + section + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct MixnodeArgs { + /// Socket address this node will use for binding its verloc API. + /// default: `0.0.0.0:1790` + #[clap( + long, + env = NYMNODE_VERLOC_BIND_ADDRESS_ARG + )] + pub(crate) verloc_bind_address: Option<SocketAddr>, +} + +impl MixnodeArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section(self) -> config::MixnodeConfig { + self.override_config_section(config::MixnodeConfig::new_default()) + } + + pub(crate) fn override_config_section( + self, + mut section: config::MixnodeConfig, + ) -> config::MixnodeConfig { + if let Some(bind_address) = self.verloc_bind_address { + section.verloc.bind_address = bind_address + } + section + } +} + +#[derive(clap::Args, Debug, Zeroize, ZeroizeOnDrop)] +pub(crate) struct EntryGatewayArgs { + /// Socket address this node will use for binding its client websocket API. + /// default: `0.0.0.0:9000` + #[clap( + long, + env = NYMNODE_ENTRY_BIND_ADDRESS_ARG + )] + #[zeroize(skip)] + pub(crate) entry_bind_address: Option<SocketAddr>, + + /// Custom announced port for listening for websocket client traffic. + /// If unspecified, the value from the `bind_address` will be used instead + #[clap( + long, + env = NYMNODE_ENTRY_ANNOUNCE_WS_PORT_ARG + )] + pub(crate) announce_ws_port: Option<u16>, + + /// If applicable, announced port for listening for secure websocket client traffic. + #[clap( + long, + env = NYMNODE_ENTRY_ANNOUNCE_WSS_PORT_ARG + )] + pub(crate) announce_wss_port: Option<u16>, + + /// Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet + /// or if it also accepts non-paying clients + #[clap( + long, + env = NYMNODE_ENFORCE_ZK_NYMS_ARG + )] + pub(crate) enforce_zk_nyms: Option<bool>, + + /// Custom cosmos wallet mnemonic used for zk-nym redemption. + /// If no value is provided, a fresh mnemonic is going to be generated. + #[clap( + long, + env = NYMNODE_MNEMONIC_ARG + )] + pub(crate) mnemonic: Option<bip39::Mnemonic>, +} + +impl EntryGatewayArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section<P: AsRef<Path>>( + self, + data_dir: P, + ) -> config::EntryGatewayConfig { + self.override_config_section(config::EntryGatewayConfig::new_default(data_dir)) + } + + pub(crate) fn override_config_section( + self, + mut section: config::EntryGatewayConfig, + ) -> config::EntryGatewayConfig { + if let Some(bind_address) = self.entry_bind_address { + section.bind_address = bind_address + } + if let Some(ws_port) = self.announce_ws_port { + section.announce_ws_port = Some(ws_port) + } + if let Some(wss_port) = self.announce_wss_port { + section.announce_wss_port = Some(wss_port) + } + if let Some(enforce_zk_nyms) = self.enforce_zk_nyms { + section.enforce_zk_nyms = enforce_zk_nyms + } + + section + } +} + +#[derive(clap::Args, Debug)] +pub(crate) struct ExitGatewayArgs { + /// Specifies the url for an upstream source of the exit policy used by this node. + #[clap( + long, + env = NYMNODE_UPSTREAM_EXIT_POLICY_ARG, + )] + pub(crate) upstream_exit_policy_url: Option<Url>, + + /// Specifies whether this exit node should run in 'open-proxy' mode + /// and thus would attempt to resolve **ANY** request it receives. + #[clap( + long, + env = NYMNODE_OPEN_PROXY_ARG, + )] + pub(crate) open_proxy: Option<bool>, +} + +impl ExitGatewayArgs { + // TODO: could we perhaps make a clap error here and call `safe_exit` instead? + pub(crate) fn build_config_section<P: AsRef<Path>>( + self, + data_dir: P, + ) -> config::ExitGatewayConfig { + self.override_config_section(config::ExitGatewayConfig::new_default(data_dir)) + } + + pub(crate) fn override_config_section( + self, + mut section: config::ExitGatewayConfig, + ) -> config::ExitGatewayConfig { + if let Some(upstream_exit_policy) = self.upstream_exit_policy_url { + section.upstream_exit_policy_url = upstream_exit_policy + } + if let Some(open_proxy) = self.open_proxy { + section.open_proxy = open_proxy + } + + section + } +} diff --git a/nym-node/src/cli/mod.rs b/nym-node/src/cli/mod.rs new file mode 100644 index 0000000000..762e2d9bce --- /dev/null +++ b/nym-node/src/cli/mod.rs @@ -0,0 +1,87 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::cli::commands::{bonding_information, build_info, migrate, node_details, run, sign}; +use crate::env::vars::{NYMNODE_CONFIG_ENV_FILE_ARG, NYMNODE_NO_BANNER_ARG}; +use clap::{Parser, Subcommand}; +use nym_bin_common::bin_info; +use nym_node::error::NymNodeError; +use std::sync::OnceLock; + +mod commands; +mod helpers; + +pub const DEFAULT_NYMNODE_ID: &str = "default-nym-node"; + +// Helper for passing LONG_VERSION to clap +fn pretty_build_info_static() -> &'static str { + static PRETTY_BUILD_INFORMATION: OnceLock<String> = OnceLock::new(); + PRETTY_BUILD_INFORMATION.get_or_init(|| bin_info!().pretty_print()) +} + +#[derive(Parser, Debug)] +#[clap(author = "Nymtech", version, long_version = pretty_build_info_static(), about)] +pub(crate) struct Cli { + /// Path pointing to an env file that configures the nym-node and overrides any preconfigured values. + #[clap( + short, + long, + env = NYMNODE_CONFIG_ENV_FILE_ARG + )] + pub(crate) config_env_file: Option<std::path::PathBuf>, + + /// Flag used for disabling the printed banner in tty. + #[clap( + long, + env = NYMNODE_NO_BANNER_ARG + )] + pub(crate) no_banner: bool, + + #[clap(subcommand)] + command: Commands, +} + +impl Cli { + pub(crate) async fn execute(self) -> Result<(), NymNodeError> { + match self.command { + Commands::BuildInfo(args) => build_info::execute(args), + Commands::BondingInformation(args) => bonding_information::execute(args).await, + Commands::NodeDetails(args) => node_details::execute(args).await, + Commands::Run(args) => run::execute(*args).await, + Commands::Migrate(args) => migrate::execute(*args).await, + Commands::Sign(args) => sign::execute(args).await, + } + } +} + +#[derive(Subcommand, Debug)] +pub(crate) enum Commands { + /// Show build information of this binary + BuildInfo(build_info::Args), + + /// Show bonding information of this node depending on its currently selected mode. + BondingInformation(bonding_information::Args), + + /// Show details of this node. + NodeDetails(node_details::Args), + + /// Attempt to migrate an existing mixnode or gateway into a nym-node. + Migrate(Box<migrate::Args>), + + /// Start this nym-node + Run(Box<run::Args>), + + /// Use identity key of this node to sign provided message. + Sign(sign::Args), +} + +#[cfg(test)] +mod tests { + use super::*; + use clap::CommandFactory; + + #[test] + fn verify_cli() { + Cli::command().debug_assert(); + } +} diff --git a/nym-node/src/config/entry_gateway.rs b/nym-node/src/config/entry_gateway.rs new file mode 100644 index 0000000000..e0db9aca64 --- /dev/null +++ b/nym-node/src/config/entry_gateway.rs @@ -0,0 +1,83 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::helpers::ephemeral_gateway_config; +use crate::config::persistence::EntryGatewayPaths; +use crate::config::Config; +use crate::error::EntryGatewayError; +use nym_config::defaults::DEFAULT_CLIENT_LISTENING_PORT; +use nym_config::helpers::inaddr_any; +use nym_config::serde_helpers::de_maybe_port; +use serde::{Deserialize, Serialize}; +use std::net::SocketAddr; +use std::path::Path; + +pub const DEFAULT_WS_PORT: u16 = DEFAULT_CLIENT_LISTENING_PORT; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct EntryGatewayConfig { + pub storage_paths: EntryGatewayPaths, + + /// Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet + /// or if it also accepts non-paying clients + pub enforce_zk_nyms: bool, + + /// Socket address this node will use for binding its client websocket API. + /// default: `0.0.0.0:9000` + pub bind_address: SocketAddr, + + /// Custom announced port for listening for websocket client traffic. + /// If unspecified, the value from the `bind_address` will be used instead + /// default: None + #[serde(deserialize_with = "de_maybe_port")] + pub announce_ws_port: Option<u16>, + + /// If applicable, announced port for listening for secure websocket client traffic. + /// (default: None) + #[serde(deserialize_with = "de_maybe_port")] + pub announce_wss_port: Option<u16>, + + #[serde(default)] + pub debug: Debug, +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Debug { + /// Number of messages from offline client that can be pulled at once (i.e. with a single SQL query) from the storage. + pub message_retrieval_limit: i64, +} + +impl Debug { + const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: i64 = 100; +} + +impl Default for Debug { + fn default() -> Self { + Debug { + message_retrieval_limit: Self::DEFAULT_MESSAGE_RETRIEVAL_LIMIT, + } + } +} + +impl EntryGatewayConfig { + pub fn new_default<P: AsRef<Path>>(data_dir: P) -> Self { + EntryGatewayConfig { + storage_paths: EntryGatewayPaths::new(data_dir), + enforce_zk_nyms: false, + bind_address: SocketAddr::new(inaddr_any(), DEFAULT_WS_PORT), + announce_ws_port: None, + announce_wss_port: None, + debug: Default::default(), + } + } +} + +// a temporary solution until all nodes are even more tightly integrated +pub fn ephemeral_entry_gateway_config( + config: Config, + mnemonic: &bip39::Mnemonic, +) -> Result<nym_gateway::config::Config, EntryGatewayError> { + Ok(ephemeral_gateway_config(config, mnemonic)?) +} diff --git a/nym-node/src/config/exit_gateway.rs b/nym-node/src/config/exit_gateway.rs new file mode 100644 index 0000000000..699264ad63 --- /dev/null +++ b/nym-node/src/config/exit_gateway.rs @@ -0,0 +1,241 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::helpers::ephemeral_gateway_config; +use crate::config::persistence::ExitGatewayPaths; +use crate::config::Config; +use crate::error::ExitGatewayError; +use clap::crate_version; +use nym_client_core_config_types::DebugConfig as ClientDebugConfig; +use nym_config::defaults::mainnet; +use nym_gateway::node::{LocalIpPacketRouterOpts, LocalNetworkRequesterOpts}; +use serde::{Deserialize, Serialize}; +use std::path::Path; +use url::Url; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct ExitGatewayConfig { + pub storage_paths: ExitGatewayPaths, + + /// specifies whether this exit node should run in 'open-proxy' mode + /// and thus would attempt to resolve **ANY** request it receives. + pub open_proxy: bool, + + /// Specifies the url for an upstream source of the exit policy used by this node. + pub upstream_exit_policy_url: Url, + + pub network_requester: NetworkRequester, + + pub ip_packet_router: IpPacketRouter, +} + +impl ExitGatewayConfig { + pub fn new_default<P: AsRef<Path>>(data_dir: P) -> Self { + #[allow(clippy::expect_used)] + // SAFETY: + // we expect our default values to be well-formed + ExitGatewayConfig { + storage_paths: ExitGatewayPaths::new(data_dir), + open_proxy: false, + upstream_exit_policy_url: mainnet::EXIT_POLICY_URL + .parse() + .expect("invalid default exit policy URL"), + network_requester: Default::default(), + ip_packet_router: Default::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +pub struct NetworkRequester { + #[serde(default)] + pub debug: NetworkRequesterDebug, +} + +#[allow(clippy::derivable_impls)] +impl Default for NetworkRequester { + fn default() -> Self { + NetworkRequester { + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +pub struct NetworkRequesterDebug { + /// Specifies whether network requester service is enabled in this process. + /// This is only here for debugging purposes as exit gateway should always run **both** + /// network requester and an ip packet router. + pub enabled: bool, + + /// Disable Poisson sending rate. + /// This is equivalent to setting client_debug.traffic.disable_main_poisson_packet_distribution = true + /// (or is it (?)) + pub disable_poisson_rate: bool, + + /// Shared detailed client configuration options + #[serde(flatten)] + pub client_debug: ClientDebugConfig, +} + +impl Default for NetworkRequesterDebug { + fn default() -> Self { + NetworkRequesterDebug { + enabled: true, + disable_poisson_rate: true, + client_debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +pub struct IpPacketRouter { + #[serde(default)] + pub debug: IpPacketRouterDebug, +} + +#[allow(clippy::derivable_impls)] +impl Default for IpPacketRouter { + fn default() -> Self { + IpPacketRouter { + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Copy, Deserialize, PartialEq, Serialize)] +#[serde(default)] +pub struct IpPacketRouterDebug { + /// Specifies whether ip packet routing service is enabled in this process. + /// This is only here for debugging purposes as exit gateway should always run **both** + /// network requester and an ip packet router. + pub enabled: bool, + + /// Disable Poisson sending rate. + /// This is equivalent to setting client_debug.traffic.disable_main_poisson_packet_distribution = true + /// (or is it (?)) + pub disable_poisson_rate: bool, + + /// Shared detailed client configuration options + #[serde(flatten)] + pub client_debug: ClientDebugConfig, +} + +impl Default for IpPacketRouterDebug { + fn default() -> Self { + IpPacketRouterDebug { + enabled: true, + disable_poisson_rate: true, + client_debug: Default::default(), + } + } +} + +pub struct EphemeralConfig { + pub gateway: nym_gateway::config::Config, + pub nr_opts: LocalNetworkRequesterOpts, + pub ipr_opts: LocalIpPacketRouterOpts, +} + +fn base_client_config(config: &Config) -> nym_client_core_config_types::Client { + nym_client_core_config_types::Client { + version: format!("{}-nym-node", crate_version!()), + id: config.id.clone(), + // irrelevant field - no need for credentials in embedded mode + disabled_credentials_mode: true, + nyxd_urls: config.mixnet.nyxd_urls.clone(), + nym_api_urls: config.mixnet.nym_api_urls.clone(), + } +} + +// that function is rather disgusting, but I hope it's not going to live for too long +pub fn ephemeral_exit_gateway_config( + config: Config, + mnemonic: &bip39::Mnemonic, +) -> Result<EphemeralConfig, ExitGatewayError> { + let nr_opts = LocalNetworkRequesterOpts { + config: nym_network_requester::Config { + base: nym_client_core_config_types::Config { + client: base_client_config(&config), + debug: config.exit_gateway.network_requester.debug.client_debug, + }, + network_requester: nym_network_requester::config::NetworkRequester { + open_proxy: config.exit_gateway.open_proxy, + enabled_statistics: false, + statistics_recipient: None, + disable_poisson_rate: config + .exit_gateway + .network_requester + .debug + .disable_poisson_rate, + upstream_exit_policy_url: Some( + config.exit_gateway.upstream_exit_policy_url.clone(), + ), + }, + storage_paths: nym_network_requester::config::NetworkRequesterPaths { + common_paths: config + .exit_gateway + .storage_paths + .network_requester + .to_common_client_paths(), + }, + network_requester_debug: Default::default(), + logging: config.logging, + }, + custom_mixnet_path: None, + }; + + let ipr_opts = LocalIpPacketRouterOpts { + config: nym_ip_packet_router::Config { + base: nym_client_core_config_types::Config { + client: base_client_config(&config), + debug: config.exit_gateway.ip_packet_router.debug.client_debug, + }, + ip_packet_router: nym_ip_packet_router::config::IpPacketRouter { + disable_poisson_rate: config + .exit_gateway + .ip_packet_router + .debug + .disable_poisson_rate, + upstream_exit_policy_url: Some( + config.exit_gateway.upstream_exit_policy_url.clone(), + ), + }, + storage_paths: nym_ip_packet_router::config::IpPacketRouterPaths { + common_paths: config + .exit_gateway + .storage_paths + .ip_packet_router + .to_common_client_paths(), + ip_packet_router_description: Default::default(), + }, + + logging: config.logging, + }, + custom_mixnet_path: None, + }; + + let pub_id_path = config + .storage_paths + .keys + .public_ed25519_identity_key_file + .clone(); + let ipr_enabled = config.exit_gateway.ip_packet_router.debug.enabled; + let nr_enabled = config.exit_gateway.network_requester.debug.enabled; + + let mut gateway = ephemeral_gateway_config(config, mnemonic)?; + gateway.ip_packet_router.enabled = ipr_enabled; + gateway.network_requester.enabled = nr_enabled; + + // this is temporary until http api is fully managed by nymnode itself + // (because currently gateway is loading its public key for the second time when starting the API to determine addresses of its clients. + // Obviously this doesn't work properly without the valid paths) + gateway.storage_paths.keys.public_identity_key_file = pub_id_path; + + Ok(EphemeralConfig { + nr_opts, + ipr_opts, + gateway, + }) +} diff --git a/nym-node/src/config/helpers.rs b/nym-node/src/config/helpers.rs new file mode 100644 index 0000000000..7ca4dcac97 --- /dev/null +++ b/nym-node/src/config/helpers.rs @@ -0,0 +1,93 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use clap::crate_version; +use std::net::IpAddr; +use thiserror::Error; + +#[derive(Debug, Error)] +#[error("currently it's not supported to have different ip addresses for clients and mixnet ({clients_bind_ip} and {mix_bind_ip} were used)")] +pub struct UnsupportedGatewayAddresses { + clients_bind_ip: IpAddr, + mix_bind_ip: IpAddr, +} + +// a temporary solution until all nodes are even more tightly integrated +pub fn ephemeral_gateway_config( + config: Config, + mnemonic: &bip39::Mnemonic, +) -> Result<nym_gateway::config::Config, UnsupportedGatewayAddresses> { + let host = nym_gateway::config::Host { + public_ips: config.host.public_ips, + hostname: config.host.hostname, + }; + + let http = nym_gateway::config::Http { + bind_address: config.http.bind_address, + landing_page_assets_path: config.http.landing_page_assets_path, + }; + + let clients_bind_ip = config.entry_gateway.bind_address.ip(); + let mix_bind_ip = config.mixnet.bind_address.ip(); + if clients_bind_ip != mix_bind_ip { + return Err(UnsupportedGatewayAddresses { + clients_bind_ip, + mix_bind_ip, + }); + } + + // SAFETY: we're using hardcoded valid url here (that won't be used anyway) + #[allow(clippy::unwrap_used)] + let gateway = nym_gateway::config::Gateway { + // that field is very much irrelevant, but I guess let's keep them for now + version: format!("{}-nym-node", crate_version!()), + id: config.id, + only_coconut_credentials: config.entry_gateway.enforce_zk_nyms, + listening_address: clients_bind_ip, + mix_port: config.mixnet.bind_address.port(), + clients_port: config.entry_gateway.bind_address.port(), + clients_wss_port: config.entry_gateway.announce_wss_port, + enabled_statistics: false, + statistics_service_url: "https://nymtech.net/foobar".parse().unwrap(), + nym_api_urls: config.mixnet.nym_api_urls, + nyxd_urls: config.mixnet.nyxd_urls, + + // that's nasty but can't do anything about it for this temporary solution : ( + cosmos_mnemonic: mnemonic.clone(), + }; + + let wireguard = nym_gateway::config::Wireguard { + enabled: config.wireguard.enabled, + bind_address: config.wireguard.bind_address, + announced_port: config.wireguard.announced_port, + private_network_prefix: config.wireguard.private_network_prefix, + storage_paths: nym_gateway::config::WireguardPaths::new_empty(), + }; + + Ok(nym_gateway::config::Config::externally_loaded( + host, + http, + gateway, + wireguard, + nym_gateway::config::GatewayPaths::new_empty(), + nym_gateway::config::NetworkRequester { enabled: false }, + nym_gateway::config::IpPacketRouter { enabled: false }, + config.logging, + nym_gateway::config::Debug { + packet_forwarding_initial_backoff: config + .mixnet + .debug + .packet_forwarding_initial_backoff, + packet_forwarding_maximum_backoff: config + .mixnet + .debug + .packet_forwarding_maximum_backoff, + initial_connection_timeout: config.mixnet.debug.initial_connection_timeout, + maximum_connection_buffer_size: config.mixnet.debug.maximum_connection_buffer_size, + message_retrieval_limit: config.entry_gateway.debug.message_retrieval_limit, + use_legacy_framed_packet_version: false, + ..Default::default() + }, + )) +} diff --git a/nym-node/src/config/mixnode.rs b/nym-node/src/config/mixnode.rs new file mode 100644 index 0000000000..684ea7129b --- /dev/null +++ b/nym-node/src/config/mixnode.rs @@ -0,0 +1,214 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::persistence::MixnodePaths; +use crate::config::Config; +use crate::error::MixnodeError; +use clap::crate_version; +use nym_config::defaults::DEFAULT_VERLOC_LISTENING_PORT; +use nym_config::helpers::inaddr_any; +use serde::{Deserialize, Serialize}; +use std::net::SocketAddr; +use std::time::Duration; + +pub const DEFAULT_VERLOC_PORT: u16 = DEFAULT_VERLOC_LISTENING_PORT; + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct MixnodeConfig { + pub storage_paths: MixnodePaths, + + pub verloc: Verloc, + + #[serde(default)] + pub debug: Debug, +} + +impl MixnodeConfig { + pub fn new_default() -> Self { + MixnodeConfig { + storage_paths: MixnodePaths {}, + verloc: Default::default(), + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Verloc { + /// Socket address this node will use for binding its verloc API. + /// default: `0.0.0.0:1790` + pub bind_address: SocketAddr, + + #[serde(default)] + pub debug: VerlocDebug, +} + +impl Default for Verloc { + fn default() -> Self { + Verloc { + bind_address: SocketAddr::new(inaddr_any(), DEFAULT_VERLOC_PORT), + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct VerlocDebug { + /// Specifies number of echo packets sent to each node during a measurement run. + pub packets_per_node: usize, + + /// Specifies maximum amount of time to wait for the connection to get established. + #[serde(with = "humantime_serde")] + pub connection_timeout: Duration, + + /// Specifies maximum amount of time to wait for the reply packet to arrive before abandoning the test. + #[serde(with = "humantime_serde")] + pub packet_timeout: Duration, + + /// Specifies delay between subsequent test packets being sent (after receiving a reply). + #[serde(with = "humantime_serde")] + pub delay_between_packets: Duration, + + /// Specifies number of nodes being tested at once. + pub tested_nodes_batch_size: usize, + + /// Specifies delay between subsequent test runs. + #[serde(with = "humantime_serde")] + pub testing_interval: Duration, + + /// Specifies delay between attempting to run the measurement again if the previous run failed + /// due to being unable to get the list of nodes. + #[serde(with = "humantime_serde")] + pub retry_timeout: Duration, +} + +impl VerlocDebug { + const DEFAULT_PACKETS_PER_NODE: usize = 100; + const DEFAULT_CONNECTION_TIMEOUT: Duration = Duration::from_millis(5000); + const DEFAULT_PACKET_TIMEOUT: Duration = Duration::from_millis(1500); + const DEFAULT_DELAY_BETWEEN_PACKETS: Duration = Duration::from_millis(50); + const DEFAULT_BATCH_SIZE: usize = 50; + const DEFAULT_TESTING_INTERVAL: Duration = Duration::from_secs(60 * 60 * 12); + const DEFAULT_RETRY_TIMEOUT: Duration = Duration::from_secs(60 * 30); +} + +impl Default for VerlocDebug { + fn default() -> Self { + VerlocDebug { + packets_per_node: VerlocDebug::DEFAULT_PACKETS_PER_NODE, + connection_timeout: VerlocDebug::DEFAULT_CONNECTION_TIMEOUT, + packet_timeout: VerlocDebug::DEFAULT_PACKET_TIMEOUT, + delay_between_packets: VerlocDebug::DEFAULT_DELAY_BETWEEN_PACKETS, + tested_nodes_batch_size: VerlocDebug::DEFAULT_BATCH_SIZE, + testing_interval: VerlocDebug::DEFAULT_TESTING_INTERVAL, + retry_timeout: VerlocDebug::DEFAULT_RETRY_TIMEOUT, + } + } +} + +impl From<VerlocDebug> for nym_mixnode::config::Verloc { + fn from(value: VerlocDebug) -> Self { + nym_mixnode::config::Verloc { + packets_per_node: value.packets_per_node, + connection_timeout: value.connection_timeout, + packet_timeout: value.packet_timeout, + delay_between_packets: value.delay_between_packets, + tested_nodes_batch_size: value.tested_nodes_batch_size, + testing_interval: value.testing_interval, + retry_timeout: value.retry_timeout, + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Debug { + /// Delay between each subsequent node statistics being logged to the console + #[serde(with = "humantime_serde")] + pub node_stats_logging_delay: Duration, + + /// Delay between each subsequent node statistics being updated + #[serde(with = "humantime_serde")] + pub node_stats_updating_delay: Duration, +} + +impl Debug { + const DEFAULT_NODE_STATS_LOGGING_DELAY: Duration = Duration::from_millis(60_000); + const DEFAULT_NODE_STATS_UPDATING_DELAY: Duration = Duration::from_millis(30_000); +} + +impl Default for Debug { + fn default() -> Self { + Debug { + node_stats_logging_delay: Debug::DEFAULT_NODE_STATS_LOGGING_DELAY, + node_stats_updating_delay: Debug::DEFAULT_NODE_STATS_UPDATING_DELAY, + } + } +} + +// a temporary solution until all nodes are even more tightly integrated +pub fn ephemeral_mixnode_config( + config: Config, +) -> Result<nym_mixnode::config::Config, MixnodeError> { + let host = nym_mixnode::config::Host { + public_ips: config.host.public_ips, + hostname: config.host.hostname, + }; + + let http = nym_mixnode::config::Http { + bind_address: config.http.bind_address, + landing_page_assets_path: config.http.landing_page_assets_path, + metrics_key: config.http.access_token, + }; + + let verloc_bind_ip = config.mixnode.verloc.bind_address.ip(); + let mix_bind_ip = config.mixnet.bind_address.ip(); + if verloc_bind_ip != mix_bind_ip { + return Err(MixnodeError::UnsupportedAddresses { + verloc_bind_ip, + mix_bind_ip, + }); + } + + let listening_address = mix_bind_ip; + let mix_port = config.mixnet.bind_address.port(); + let verloc_port = config.mixnode.verloc.bind_address.port(); + let nym_api_urls = config.mixnet.nym_api_urls; + + let mixnode = nym_mixnode::config::MixNode { + // that field is very much irrelevant, but I guess let's keep them for now + version: format!("{}-nym-node", crate_version!()), + id: config.id, + listening_address, + mix_port, + verloc_port, + nym_api_urls, + }; + + Ok(nym_mixnode::config::Config::externally_loaded( + host, + http, + mixnode, + nym_mixnode::config::MixNodePaths::new_empty(), + config.mixnode.verloc.debug, + config.logging, + nym_mixnode::config::Debug { + node_stats_logging_delay: config.mixnode.debug.node_stats_logging_delay, + node_stats_updating_delay: config.mixnode.debug.node_stats_updating_delay, + packet_forwarding_initial_backoff: config + .mixnet + .debug + .packet_forwarding_initial_backoff, + packet_forwarding_maximum_backoff: config + .mixnet + .debug + .packet_forwarding_maximum_backoff, + initial_connection_timeout: config.mixnet.debug.initial_connection_timeout, + maximum_connection_buffer_size: config.mixnet.debug.maximum_connection_buffer_size, + use_legacy_framed_packet_version: false, + }, + )) +} diff --git a/nym-node/src/config/mod.rs b/nym-node/src/config/mod.rs index 51bfe10c67..4ff8519993 100644 --- a/nym-node/src/config/mod.rs +++ b/nym-node/src/config/mod.rs @@ -1,72 +1,492 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use nym_config::defaults::{DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT}; +use crate::config::persistence::NymNodePaths; +use crate::config::template::CONFIG_TEMPLATE; +use crate::error::NymNodeError; +use celes::Country; +use clap::ValueEnum; +use nym_bin_common::logging::LoggingSettings; +use nym_config::defaults::{ + mainnet, var_names, DEFAULT_MIX_LISTENING_PORT, DEFAULT_NYM_NODE_HTTP_PORT, WG_PORT, +}; +use nym_config::helpers::inaddr_any; +use nym_config::serde_helpers::de_maybe_stringified; +use nym_config::{ + must_get_home, parse_urls, read_config_from_toml_file, save_formatted_config_to_file, + NymConfigTemplate, DEFAULT_CONFIG_DIR, DEFAULT_CONFIG_FILENAME, DEFAULT_DATA_DIR, NYM_DIR, +}; use serde::{Deserialize, Serialize}; -use serde_helpers::*; +use std::env; +use std::fmt::{Display, Formatter}; use std::net::{IpAddr, Ipv4Addr, SocketAddr}; -use std::path::PathBuf; +use std::path::{Path, PathBuf}; +use std::time::Duration; +use tracing::{debug, error}; +use url::Url; +pub mod entry_gateway; +pub mod exit_gateway; +pub mod helpers; +pub mod mixnode; pub mod persistence; -mod serde_helpers; +mod template; +pub mod upgrade_helpers; + +pub use crate::config::entry_gateway::EntryGatewayConfig; +pub use crate::config::exit_gateway::ExitGatewayConfig; +pub use crate::config::mixnode::MixnodeConfig; + +const DEFAULT_NYMNODES_DIR: &str = "nym-nodes"; pub const DEFAULT_WIREGUARD_PORT: u16 = WG_PORT; +pub const DEFAULT_WIREGUARD_NETWORK_IP: IpAddr = IpAddr::V4(Ipv4Addr::new(10, 1, 0, 0)); pub const DEFAULT_WIREGUARD_PREFIX: u8 = 16; pub const DEFAULT_HTTP_PORT: u16 = DEFAULT_NYM_NODE_HTTP_PORT; +pub const DEFAULT_MIXNET_PORT: u16 = DEFAULT_MIX_LISTENING_PORT; + +/// Derive default path to nym-node's config directory. +/// It should get resolved to `$HOME/.nym/nym-nodes/<id>/config` +pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf { + must_get_home() + .join(NYM_DIR) + .join(DEFAULT_NYMNODES_DIR) + .join(id) + .join(DEFAULT_CONFIG_DIR) +} + +/// Derive default path to nym-node's config file. +/// It should get resolved to `$HOME/.nym/nym-nodes/<id>/config/config.toml` +pub fn default_config_filepath<P: AsRef<Path>>(id: P) -> PathBuf { + default_config_directory(id).join(DEFAULT_CONFIG_FILENAME) +} + +// a temporary solution until all "types" are run at the same time +#[derive(Debug, Default, Serialize, Deserialize, ValueEnum, Clone, Copy)] +#[serde(rename_all = "snake_case")] +pub enum NodeMode { + #[default] + #[clap(alias = "mix")] + Mixnode, + + #[clap(alias = "entry", alias = "gateway")] + EntryGateway, + + #[clap(alias = "exit")] + ExitGateway, +} + +impl Display for NodeMode { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + NodeMode::Mixnode => "mixnode".fmt(f), + NodeMode::EntryGateway => "entry-gateway".fmt(f), + NodeMode::ExitGateway => "exit-gateway".fmt(f), + } + } +} + +pub struct ConfigBuilder { + pub id: String, + + pub config_path: PathBuf, + + pub data_dir: PathBuf, + + pub mode: NodeMode, + + pub mixnet: Option<Mixnet>, + + pub host: Option<Host>, + + pub http: Option<Http>, + + pub wireguard: Option<Wireguard>, + + pub storage_paths: Option<NymNodePaths>, + + pub mixnode: Option<MixnodeConfig>, + + pub entry_gateway: Option<EntryGatewayConfig>, + + pub exit_gateway: Option<ExitGatewayConfig>, + + pub logging: Option<LoggingSettings>, +} + +impl ConfigBuilder { + pub fn new(id: String, config_path: PathBuf, data_dir: PathBuf) -> Self { + ConfigBuilder { + id, + config_path, + data_dir, + host: None, + http: None, + mixnet: None, + wireguard: None, + mode: NodeMode::default(), + storage_paths: None, + mixnode: None, + entry_gateway: None, + exit_gateway: None, + logging: None, + } + } + + pub fn with_mode(mut self, mode: impl Into<NodeMode>) -> Self { + self.mode = mode.into(); + self + } + + pub fn with_host(mut self, section: impl Into<Option<Host>>) -> Self { + self.host = section.into(); + self + } + + pub fn with_http(mut self, section: impl Into<Option<Http>>) -> Self { + self.http = section.into(); + self + } + + pub fn with_mixnet(mut self, section: impl Into<Option<Mixnet>>) -> Self { + self.mixnet = section.into(); + self + } + + pub fn with_wireguard(mut self, section: impl Into<Option<Wireguard>>) -> Self { + self.wireguard = section.into(); + self + } + + pub fn with_storage_paths(mut self, section: impl Into<Option<NymNodePaths>>) -> Self { + self.storage_paths = section.into(); + self + } + + pub fn with_mixnode(mut self, section: impl Into<Option<MixnodeConfig>>) -> Self { + self.mixnode = section.into(); + self + } + + pub fn with_entry_gateway(mut self, section: impl Into<Option<EntryGatewayConfig>>) -> Self { + self.entry_gateway = section.into(); + self + } + + pub fn with_exit_gateway(mut self, section: impl Into<Option<ExitGatewayConfig>>) -> Self { + self.exit_gateway = section.into(); + self + } + + pub fn with_logging(mut self, section: impl Into<Option<LoggingSettings>>) -> Self { + self.logging = section.into(); + self + } + + pub fn build(self) -> Config { + Config { + id: self.id, + mode: self.mode, + host: self.host.unwrap_or_default(), + http: self.http.unwrap_or_default(), + mixnet: self.mixnet.unwrap_or_default(), + wireguard: self + .wireguard + .unwrap_or_else(|| Wireguard::new_default(&self.data_dir)), + storage_paths: self + .storage_paths + .unwrap_or_else(|| NymNodePaths::new(&self.data_dir)), + mixnode: self.mixnode.unwrap_or_else(MixnodeConfig::new_default), + entry_gateway: self + .entry_gateway + .unwrap_or_else(|| EntryGatewayConfig::new_default(&self.data_dir)), + exit_gateway: self + .exit_gateway + .unwrap_or_else(|| ExitGatewayConfig::new_default(&self.data_dir)), + logging: self.logging.unwrap_or_default(), + save_path: Some(self.config_path), + } + } +} + +#[derive(Debug, Clone, Serialize, Deserialize)] +#[serde(deny_unknown_fields)] +pub struct Config { + // additional metadata holding on-disk location of this config file + #[serde(skip)] + pub(crate) save_path: Option<PathBuf>, + + /// Human-readable ID of this particular node. + pub id: String, + + /// Current mode of this nym-node. + /// Expect this field to be changed in the future to allow running the node in multiple modes (i.e. mixnode + gateway) + pub mode: NodeMode, + + pub host: Host, + + pub mixnet: Mixnet, + + /// Storage paths to persistent nym-node data, such as its long term keys. + pub storage_paths: NymNodePaths, + + #[serde(default)] + pub http: Http, + + pub wireguard: Wireguard, + + pub mixnode: MixnodeConfig, + + pub entry_gateway: EntryGatewayConfig, + + pub exit_gateway: ExitGatewayConfig, + + #[serde(default)] + pub logging: LoggingSettings, +} + +impl NymConfigTemplate for Config { + fn template(&self) -> &'static str { + CONFIG_TEMPLATE + } +} + +impl Config { + pub fn save(&self) -> Result<(), NymNodeError> { + let save_location = self.save_location(); + debug!( + "attempting to save config file to '{}'", + save_location.display() + ); + save_formatted_config_to_file(self, &save_location).map_err(|source| { + NymNodeError::ConfigSaveFailure { + id: self.id.clone(), + path: save_location, + source, + } + }) + } + + pub fn save_location(&self) -> PathBuf { + self.save_path + .clone() + .unwrap_or(self.default_save_location()) + } + + pub fn default_save_location(&self) -> PathBuf { + default_config_filepath(&self.id) + } + + pub fn default_data_directory<P: AsRef<Path>>(config_path: P) -> Result<PathBuf, NymNodeError> { + let config_path = config_path.as_ref(); + + // we got a proper path to the .toml file + let Some(config_dir) = config_path.parent() else { + error!( + "'{}' does not have a parent directory. Have you pointed to the fs root?", + config_path.display() + ); + return Err(NymNodeError::DataDirDerivationFailure); + }; + + let Some(config_dir_name) = config_dir.file_name() else { + error!( + "could not obtain parent directory name of '{}'. Have you used relative paths?", + config_path.display() + ); + return Err(NymNodeError::DataDirDerivationFailure); + }; + + if config_dir_name != DEFAULT_CONFIG_DIR { + error!( + "the parent directory of '{}' ({}) is not {DEFAULT_CONFIG_DIR}. currently this is not supported", + config_path.display(), config_dir_name.to_str().unwrap_or("UNKNOWN") + ); + return Err(NymNodeError::DataDirDerivationFailure); + } + + let Some(node_dir) = config_dir.parent() else { + error!( + "'{}' does not have a parent directory. Have you pointed to the fs root?", + config_dir.display() + ); + return Err(NymNodeError::DataDirDerivationFailure); + }; + + Ok(node_dir.join(DEFAULT_DATA_DIR)) + } + + // simple wrapper that reads config file and assigns path location + fn read_from_path<P: AsRef<Path>>(path: P) -> Result<Self, NymNodeError> { + let path = path.as_ref(); + let mut loaded: Config = + read_config_from_toml_file(path).map_err(|source| NymNodeError::ConfigLoadFailure { + path: path.to_path_buf(), + source, + })?; + loaded.save_path = Some(path.to_path_buf()); + debug!("loaded config file from {}", path.display()); + Ok(loaded) + } + + pub fn read_from_toml_file<P: AsRef<Path>>(path: P) -> Result<Self, NymNodeError> { + Self::read_from_path(path) + } +} // TODO: this is very much a WIP. we need proper ssl certificate support here -#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[derive(Debug, Clone, Default, Deserialize, PartialEq, Serialize)] +#[serde(default)] #[serde(deny_unknown_fields)] pub struct Host { /// Ip address(es) of this host, such as 1.1.1.1 that external clients will use for connections. + /// If no values are provided, when this node gets included in the network, + /// its ip addresses will be populated by whatever value is resolved by associated nym-api. pub public_ips: Vec<IpAddr>, /// Optional hostname of this node, for example nymtech.net. // TODO: this is temporary. to be replaced by pulling the data directly from the certs. - #[serde(deserialize_with = "de_maybe_string")] + #[serde(deserialize_with = "de_maybe_stringified")] pub hostname: Option<String>, + + /// Optional ISO 3166 alpha-2 two-letter country code of the node's **physical** location + #[serde(deserialize_with = "de_maybe_stringified")] + pub location: Option<Country>, } -impl Host { - pub fn validate(&self) -> bool { - if self.public_ips.is_empty() { - return false; - } - - true - } -} - -#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(default)] #[serde(deny_unknown_fields)] pub struct Http { /// Socket address this node will use for binding its http API. /// default: `0.0.0.0:8080` - /// note: for legacy reasons, it defaults to port `8000` for mixnodes. pub bind_address: SocketAddr, /// Path to assets directory of custom landing page of this node. - #[serde(deserialize_with = "de_maybe_path")] + #[serde(deserialize_with = "de_maybe_stringified")] pub landing_page_assets_path: Option<PathBuf>, + /// An optional bearer token for accessing certain http endpoints. + /// Currently only used for obtaining mixnode's stats. #[serde(default)] - pub metrics_key: Option<String>, + pub access_token: Option<String>, + + /// Specify whether basic system information should be exposed. + /// default: true + pub expose_system_info: bool, + + /// Specify whether basic system hardware information should be exposed. + /// This option is superseded by `expose_system_info` + /// default: true + pub expose_system_hardware: bool, + + /// Specify whether detailed system crypto hardware information should be exposed. + /// This option is superseded by `expose_system_hardware` + /// default: true + pub expose_crypto_hardware: bool, } impl Default for Http { fn default() -> Self { Http { - bind_address: SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), DEFAULT_HTTP_PORT), + bind_address: SocketAddr::new(inaddr_any(), DEFAULT_HTTP_PORT), landing_page_assets_path: None, - metrics_key: None, + access_token: None, + expose_system_info: true, + expose_system_hardware: true, + expose_crypto_hardware: true, } } } -#[derive(Debug, Deserialize, PartialEq, Serialize)] +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] #[serde(default)] #[serde(deny_unknown_fields)] +pub struct Mixnet { + /// Address this node will bind to for listening for mixnet packets + /// default: `0.0.0.0:1789` + pub bind_address: SocketAddr, + + /// Addresses to nym APIs from which the node gets the view of the network. + pub nym_api_urls: Vec<Url>, + + /// Addresses to nyxd which the node uses to interact with the nyx chain. + pub nyxd_urls: Vec<Url>, + + #[serde(default)] + pub debug: MixnetDebug, +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(default)] +#[serde(deny_unknown_fields)] +pub struct MixnetDebug { + /// Initial value of an exponential backoff to reconnect to dropped TCP connection when + /// forwarding sphinx packets. + #[serde(with = "humantime_serde")] + pub packet_forwarding_initial_backoff: Duration, + + /// Maximum value of an exponential backoff to reconnect to dropped TCP connection when + /// forwarding sphinx packets. + #[serde(with = "humantime_serde")] + pub packet_forwarding_maximum_backoff: Duration, + + /// Timeout for establishing initial connection when trying to forward a sphinx packet. + #[serde(with = "humantime_serde")] + pub initial_connection_timeout: Duration, + + /// Maximum number of packets that can be stored waiting to get sent to a particular connection. + pub maximum_connection_buffer_size: usize, +} + +impl MixnetDebug { + const DEFAULT_PACKET_FORWARDING_INITIAL_BACKOFF: Duration = Duration::from_millis(10_000); + const DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF: Duration = Duration::from_millis(300_000); + const DEFAULT_INITIAL_CONNECTION_TIMEOUT: Duration = Duration::from_millis(1_500); + const DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE: usize = 2000; +} + +impl Default for MixnetDebug { + fn default() -> Self { + MixnetDebug { + packet_forwarding_initial_backoff: Self::DEFAULT_PACKET_FORWARDING_INITIAL_BACKOFF, + packet_forwarding_maximum_backoff: Self::DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF, + initial_connection_timeout: Self::DEFAULT_INITIAL_CONNECTION_TIMEOUT, + maximum_connection_buffer_size: Self::DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE, + } + } +} + +impl Default for Mixnet { + fn default() -> Self { + // SAFETY: + // our hardcoded values should always be valid + #[allow(clippy::expect_used)] + // is if there's anything set in the environment, otherwise fallback to mainnet + let nym_api_urls = if let Ok(env_value) = env::var(var_names::NYM_API) { + parse_urls(&env_value) + } else { + vec![mainnet::NYM_API.parse().expect("Invalid default API URL")] + }; + + #[allow(clippy::expect_used)] + let nyxd_urls = if let Ok(env_value) = env::var(var_names::NYXD) { + parse_urls(&env_value) + } else { + vec![mainnet::NYXD_URL.parse().expect("Invalid default nyxd URL")] + }; + + Mixnet { + bind_address: SocketAddr::new(inaddr_any(), DEFAULT_MIXNET_PORT), + nym_api_urls, + nyxd_urls, + debug: Default::default(), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Serialize)] +#[serde(deny_unknown_fields)] pub struct Wireguard { /// Specifies whether the wireguard service is enabled on this node. pub enabled: bool, @@ -75,6 +495,10 @@ pub struct Wireguard { /// default: `0.0.0.0:51822` pub bind_address: SocketAddr, + /// Ip address of the private wireguard network. + /// default: `10.1.0.0` + pub private_network_ip: IpAddr, + /// Port announced to external clients wishing to connect to the wireguard interface. /// Useful in the instances where the node is behind a proxy. pub announced_port: u16, @@ -87,17 +511,18 @@ pub struct Wireguard { pub storage_paths: persistence::WireguardPaths, } -impl Default for Wireguard { - fn default() -> Self { +impl Wireguard { + pub fn new_default<P: AsRef<Path>>(data_dir: P) -> Self { Wireguard { enabled: false, bind_address: SocketAddr::new( IpAddr::V4(Ipv4Addr::UNSPECIFIED), DEFAULT_WIREGUARD_PORT, ), + private_network_ip: DEFAULT_WIREGUARD_NETWORK_IP, announced_port: DEFAULT_WIREGUARD_PORT, private_network_prefix: DEFAULT_WIREGUARD_PREFIX, - storage_paths: persistence::WireguardPaths {}, + storage_paths: persistence::WireguardPaths::new(data_dir), } } } diff --git a/nym-node/src/config/persistence.rs b/nym-node/src/config/persistence.rs index c1cf1824ab..530f815aef 100644 --- a/nym-node/src/config/persistence.rs +++ b/nym-node/src/config/persistence.rs @@ -1,10 +1,376 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::error::EntryGatewayError; +use nym_client_core_config_types::disk_persistence::{ClientKeysPaths, CommonClientPaths}; +use nym_mixnode::config::persistence::paths::DEFAULT_DESCRIPTION_FILENAME; use serde::{Deserialize, Serialize}; +use std::fs::create_dir_all; +use std::path::{Path, PathBuf}; +use std::{fs, io}; +use tracing::info; +use zeroize::Zeroizing; + +// Global: +pub const DEFAULT_ED25519_PRIVATE_IDENTITY_KEY_FILENAME: &str = "ed25519_identity"; +pub const DEFAULT_ED25519_PUBLIC_IDENTITY_KEY_FILENAME: &str = "ed25519_identity.pub"; +pub const DEFAULT_X25519_PRIVATE_SPHINX_KEY_FILENAME: &str = "x25519_sphinx"; +pub const DEFAULT_X25519_PUBLIC_SPHINX_KEY_FILENAME: &str = "x25519_sphinx.pub"; +pub const DEFAULT_X25519_PRIVATE_NOISE_KEY_FILENAME: &str = "x25519_noise"; +pub const DEFAULT_X25519_PUBLIC_NOISE_KEY_FILENAME: &str = "x25519_noise.pub"; +pub const DEFAULT_NYMNODE_DESCRIPTION_FILENAME: &str = "description.toml"; + +// Mixnode: + +// Entry Gateway: +pub const DEFAULT_CLIENTS_STORAGE_FILENAME: &str = "clients.sqlite"; +pub const DEFAULT_MNEMONIC_FILENAME: &str = "cosmos_mnemonic"; + +// Exit Gateway: +pub const DEFAULT_ED25519_NR_PRIVATE_IDENTITY_KEY_FILENAME: &str = "ed25519_nr_identity"; +pub const DEFAULT_ED25519_NR_PUBLIC_IDENTITY_KEY_FILENAME: &str = "ed25519_nr_identity.pub"; +pub const DEFAULT_X25519_NR_PRIVATE_DH_KEY_FILENAME: &str = "x25519_nr_dh"; +pub const DEFAULT_X25519_NR_PUBLIC_DH_KEY_FILENAME: &str = "x25519_nr_dh.pub"; +pub const DEFAULT_NR_ACK_KEY_FILENAME: &str = "aes128ctr_nr_ack"; +pub const DEFAULT_NR_REPLY_SURB_DB_FILENAME: &str = "nr_persistent_reply_store.sqlite"; +pub const DEFAULT_NR_GATEWAYS_DB_FILENAME: &str = "nr_gateways_info_store.sqlite"; + +pub const DEFAULT_ED25519_IPR_PRIVATE_IDENTITY_KEY_FILENAME: &str = "ed25519_ipr_identity"; +pub const DEFAULT_ED25519_IPR_PUBLIC_IDENTITY_KEY_FILENAME: &str = "ed25519_ipr_identity.pub"; +pub const DEFAULT_X25519_IPR_PRIVATE_DH_KEY_FILENAME: &str = "x25519_ipr_dh"; +pub const DEFAULT_X25519_IPR_PUBLIC_DH_KEY_FILENAME: &str = "x25519_ipr_dh.pub"; +pub const DEFAULT_IPR_ACK_KEY_FILENAME: &str = "aes128ctr_ipr_ack"; +pub const DEFAULT_IPR_REPLY_SURB_DB_FILENAME: &str = "ipr_persistent_reply_store.sqlite"; +pub const DEFAULT_IPR_GATEWAYS_DB_FILENAME: &str = "ipr_gateways_info_store.sqlite"; + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct NymNodePaths { + pub keys: KeysPaths, + + /// Path to a file containing basic node description: human-readable name, website, details, etc. + pub description: PathBuf, +} + +impl NymNodePaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + let data_dir = data_dir.as_ref(); + + NymNodePaths { + keys: KeysPaths::new(data_dir), + description: data_dir.join(DEFAULT_DESCRIPTION_FILENAME), + } + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct KeysPaths { + /// Path to file containing ed25519 identity private key. + pub private_ed25519_identity_key_file: PathBuf, + + /// Path to file containing ed25519 identity public key. + pub public_ed25519_identity_key_file: PathBuf, + + /// Path to file containing x25519 sphinx private key. + pub private_x25519_sphinx_key_file: PathBuf, + + /// Path to file containing x25519 sphinx public key. + pub public_x25519_sphinx_key_file: PathBuf, + + /// Path to file containing x25519 noise private key. + pub private_x25519_noise_key_file: PathBuf, + + /// Path to file containing x25519 noise public key. + pub public_x25519_noise_key_file: PathBuf, +} + +impl KeysPaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + let data_dir = data_dir.as_ref(); + + KeysPaths { + private_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_PRIVATE_IDENTITY_KEY_FILENAME), + public_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_PUBLIC_IDENTITY_KEY_FILENAME), + private_x25519_sphinx_key_file: data_dir + .join(DEFAULT_X25519_PRIVATE_SPHINX_KEY_FILENAME), + public_x25519_sphinx_key_file: data_dir.join(DEFAULT_X25519_PUBLIC_SPHINX_KEY_FILENAME), + private_x25519_noise_key_file: data_dir.join(DEFAULT_X25519_PRIVATE_NOISE_KEY_FILENAME), + public_x25519_noise_key_file: data_dir.join(DEFAULT_X25519_PUBLIC_NOISE_KEY_FILENAME), + } + } + + pub fn ed25519_identity_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_ed25519_identity_key_file, + &self.public_ed25519_identity_key_file, + ) + } + + pub fn x25519_sphinx_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_x25519_sphinx_key_file, + &self.public_x25519_sphinx_key_file, + ) + } + + pub fn x25519_noise_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_x25519_noise_key_file, + &self.public_x25519_noise_key_file, + ) + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct MixnodePaths {} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct EntryGatewayPaths { + /// Path to sqlite database containing all persistent data: messages for offline clients, + /// derived shared keys and available client bandwidths. + pub clients_storage: PathBuf, + + /// Path to file containing cosmos account mnemonic used for zk-nym redemption. + pub cosmos_mnemonic: PathBuf, +} + +impl EntryGatewayPaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + EntryGatewayPaths { + clients_storage: data_dir.as_ref().join(DEFAULT_CLIENTS_STORAGE_FILENAME), + cosmos_mnemonic: data_dir.as_ref().join(DEFAULT_MNEMONIC_FILENAME), + } + } + + pub fn load_mnemonic_from_file(&self) -> Result<Zeroizing<bip39::Mnemonic>, EntryGatewayError> { + let stringified = + Zeroizing::new(fs::read_to_string(&self.cosmos_mnemonic).map_err(|source| { + EntryGatewayError::MnemonicLoadFailure { + path: self.cosmos_mnemonic.clone(), + source, + } + })?); + + Ok(Zeroizing::new(bip39::Mnemonic::parse::<&str>( + stringified.as_ref(), + )?)) + } + + pub fn save_mnemonic_to_file( + &self, + mnemonic: &bip39::Mnemonic, + ) -> Result<(), EntryGatewayError> { + // wrapper for io errors + fn _save_to_file(path: &Path, mnemonic: &bip39::Mnemonic) -> io::Result<()> { + if let Some(parent) = path.parent() { + create_dir_all(parent)?; + } + info!("saving entry gateway mnemonic to '{}'", path.display()); + + let stringified = Zeroizing::new(mnemonic.to_string()); + fs::write(path, &stringified) + } + + _save_to_file(&self.cosmos_mnemonic, mnemonic).map_err(|source| { + EntryGatewayError::MnemonicSaveFailure { + path: self.cosmos_mnemonic.clone(), + source, + } + }) + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct ExitGatewayPaths { + pub network_requester: NetworkRequesterPaths, + + pub ip_packet_router: IpPacketRouterPaths, +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct NetworkRequesterPaths { + /// Path to file containing network requester ed25519 identity private key. + pub private_ed25519_identity_key_file: PathBuf, + + /// Path to file containing network requester ed25519 identity public key. + pub public_ed25519_identity_key_file: PathBuf, + + /// Path to file containing network requester x25519 diffie hellman private key. + pub private_x25519_diffie_hellman_key_file: PathBuf, + + /// Path to file containing network requester x25519 diffie hellman public key. + pub public_x25519_diffie_hellman_key_file: PathBuf, + + /// Path to file containing key used for encrypting and decrypting the content of an + /// acknowledgement so that nobody besides the client knows which packet it refers to. + pub ack_key_file: PathBuf, + + /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + pub reply_surb_database: PathBuf, + + /// Normally this is a path to the file containing information about gateways used by this client, + /// i.e. details such as their public keys, owner addresses or the network information. + /// but in this case it just has the basic information of "we're using custom gateway". + /// Due to how clients are started up, this file has to exist. + pub gateway_registrations: PathBuf, + // it's possible we might have to add credential storage here for return tickets +} + +impl NetworkRequesterPaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + let data_dir = data_dir.as_ref(); + NetworkRequesterPaths { + private_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_NR_PRIVATE_IDENTITY_KEY_FILENAME), + public_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_NR_PUBLIC_IDENTITY_KEY_FILENAME), + private_x25519_diffie_hellman_key_file: data_dir + .join(DEFAULT_X25519_NR_PRIVATE_DH_KEY_FILENAME), + public_x25519_diffie_hellman_key_file: data_dir + .join(DEFAULT_X25519_NR_PUBLIC_DH_KEY_FILENAME), + ack_key_file: data_dir.join(DEFAULT_NR_ACK_KEY_FILENAME), + reply_surb_database: data_dir.join(DEFAULT_NR_REPLY_SURB_DB_FILENAME), + gateway_registrations: data_dir.join(DEFAULT_NR_GATEWAYS_DB_FILENAME), + } + } + + pub fn to_common_client_paths(&self) -> CommonClientPaths { + CommonClientPaths { + keys: ClientKeysPaths { + private_identity_key_file: self.private_ed25519_identity_key_file.clone(), + public_identity_key_file: self.public_ed25519_identity_key_file.clone(), + private_encryption_key_file: self.private_x25519_diffie_hellman_key_file.clone(), + public_encryption_key_file: self.public_x25519_diffie_hellman_key_file.clone(), + ack_key_file: self.ack_key_file.clone(), + }, + gateway_registrations: self.gateway_registrations.clone(), + + // not needed for embedded providers + credentials_database: Default::default(), + reply_surb_database: self.reply_surb_database.clone(), + } + } + + pub fn ed25519_identity_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_ed25519_identity_key_file, + &self.public_ed25519_identity_key_file, + ) + } + + pub fn x25519_diffie_hellman_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_x25519_diffie_hellman_key_file, + &self.public_x25519_diffie_hellman_key_file, + ) + } +} + +#[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] +#[serde(deny_unknown_fields)] +pub struct IpPacketRouterPaths { + /// Path to file containing ip packet router ed25519 identity private key. + pub private_ed25519_identity_key_file: PathBuf, + + /// Path to file containing ip packet router ed25519 identity public key. + pub public_ed25519_identity_key_file: PathBuf, + + /// Path to file containing ip packet router x25519 diffie hellman private key. + pub private_x25519_diffie_hellman_key_file: PathBuf, + + /// Path to file containing ip packet router x25519 diffie hellman public key. + pub public_x25519_diffie_hellman_key_file: PathBuf, + + /// Path to file containing key used for encrypting and decrypting the content of an + /// acknowledgement so that nobody besides the client knows which packet it refers to. + pub ack_key_file: PathBuf, + + /// Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. + pub reply_surb_database: PathBuf, + + /// Normally this is a path to the file containing information about gateways used by this client, + /// i.e. details such as their public keys, owner addresses or the network information. + /// but in this case it just has the basic information of "we're using custom gateway". + /// Due to how clients are started up, this file has to exist. + pub gateway_registrations: PathBuf, + // it's possible we might have to add credential storage here for return tickets +} + +impl IpPacketRouterPaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + let data_dir = data_dir.as_ref(); + IpPacketRouterPaths { + private_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_IPR_PRIVATE_IDENTITY_KEY_FILENAME), + public_ed25519_identity_key_file: data_dir + .join(DEFAULT_ED25519_IPR_PUBLIC_IDENTITY_KEY_FILENAME), + private_x25519_diffie_hellman_key_file: data_dir + .join(DEFAULT_X25519_IPR_PRIVATE_DH_KEY_FILENAME), + public_x25519_diffie_hellman_key_file: data_dir + .join(DEFAULT_X25519_IPR_PUBLIC_DH_KEY_FILENAME), + ack_key_file: data_dir.join(DEFAULT_IPR_ACK_KEY_FILENAME), + reply_surb_database: data_dir.join(DEFAULT_IPR_REPLY_SURB_DB_FILENAME), + gateway_registrations: data_dir.join(DEFAULT_IPR_GATEWAYS_DB_FILENAME), + } + } + + pub fn to_common_client_paths(&self) -> CommonClientPaths { + CommonClientPaths { + keys: ClientKeysPaths { + private_identity_key_file: self.private_ed25519_identity_key_file.clone(), + public_identity_key_file: self.public_ed25519_identity_key_file.clone(), + private_encryption_key_file: self.private_x25519_diffie_hellman_key_file.clone(), + public_encryption_key_file: self.public_x25519_diffie_hellman_key_file.clone(), + ack_key_file: self.ack_key_file.clone(), + }, + gateway_registrations: self.gateway_registrations.clone(), + + // not needed for embedded providers + credentials_database: Default::default(), + reply_surb_database: self.reply_surb_database.clone(), + } + } + + pub fn ed25519_identity_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_ed25519_identity_key_file, + &self.public_ed25519_identity_key_file, + ) + } + + pub fn x25519_diffie_hellman_storage_paths(&self) -> nym_pemstore::KeyPairPath { + nym_pemstore::KeyPairPath::new( + &self.private_x25519_diffie_hellman_key_file, + &self.public_x25519_diffie_hellman_key_file, + ) + } +} + +impl ExitGatewayPaths { + pub fn new<P: AsRef<Path>>(data_dir: P) -> Self { + let data_dir = data_dir.as_ref(); + ExitGatewayPaths { + network_requester: NetworkRequesterPaths::new(data_dir), + ip_packet_router: IpPacketRouterPaths::new(data_dir), + } + } +} #[derive(Debug, Clone, Deserialize, PartialEq, Eq, Serialize)] #[serde(deny_unknown_fields)] pub struct WireguardPaths { // pub keys: } + +impl WireguardPaths { + pub fn new<P: AsRef<Path>>(_data_dir: P) -> Self { + WireguardPaths {} + } +} diff --git a/nym-node/src/config/serde_helpers.rs b/nym-node/src/config/serde_helpers.rs deleted file mode 100644 index 75bfef8bb9..0000000000 --- a/nym-node/src/config/serde_helpers.rs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use serde::{Deserialize, Deserializer}; -use std::path::PathBuf; - -pub(super) fn de_maybe_path<'de, D>(deserializer: D) -> Result<Option<PathBuf>, D::Error> -where - D: Deserializer<'de>, -{ - let path = PathBuf::deserialize(deserializer)?; - if path.as_os_str().is_empty() { - Ok(None) - } else { - Ok(Some(path)) - } -} - -pub(super) fn de_maybe_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error> -where - D: Deserializer<'de>, -{ - let path = String::deserialize(deserializer)?; - if path.is_empty() { - Ok(None) - } else { - Ok(Some(path)) - } -} diff --git a/nym-node/src/config/template.rs b/nym-node/src/config/template.rs new file mode 100644 index 0000000000..2b053b759c --- /dev/null +++ b/nym-node/src/config/template.rs @@ -0,0 +1,252 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +// While using normal toml marshalling would have been way simpler with less overhead, +// I think it's useful to have comments attached to the saved config file to explain behaviour of +// particular fields. +// Note: any changes to the template must be reflected in the appropriate structs. +pub(crate) const CONFIG_TEMPLATE: &str = r#" +# This is a TOML config file. +# For more information, see https://github.com/toml-lang/toml + +# do note that some of the configuration options are not explicitly exposed in this template, +# but can still be manually adjusted. in particular delays, rates, etc. +# look at nym-node/src/config/mod.rs file for more details. + +##### main base nym-node config options ##### + +# Human-readable ID of this particular node. +id = '{{ id }}' + +# Current mode of this nym-node. +# Expect this field to be changed in the future to allow running the node in multiple modes (i.e. mixnode + gateway) +mode = '{{ mode }}' + +[host] +# Ip address(es) of this host, such as 1.1.1.1 that external clients will use for connections. +# If no values are provided, when this node gets included in the network, +# its ip addresses will be populated by whatever value is resolved by associated nym-api. +public_ips = [ +{{#each host.public_ips }}'{{this}}',{{/each}} +] + +# (temporary) Optional hostname of this node, for example nymtech.net. +hostname = '{{ host.hostname }}' + +# Optional ISO 3166 alpha-2 two-letter country code of the node's **physical** location +location = '{{ host.location }}' + +[mixnet] +# Address this node will bind to for listening for mixnet packets +# default: `0.0.0.0:1789` +bind_address = '{{ mixnet.bind_address }}' + +# Addresses to nym APIs from which the node gets the view of the network. +nym_api_urls = [ +{{#each mixnet.nym_api_urls }}'{{this}}',{{/each}} +] + +# Addresses to nyxd which the node uses to interact with the nyx chain. +nyxd_urls = [ + {{#each mixnet.nyxd_urls }}'{{this}}',{{/each}} +] + +# Storage paths to persistent nym-node data, such as its long term keys. +[storage_paths] + +# Path to a file containing basic node description: human-readable name, website, details, etc. +description = '{{ storage_paths.description }}' + +[storage_paths.keys] +# Path to file containing ed25519 identity private key. +private_ed25519_identity_key_file = '{{ storage_paths.keys.private_ed25519_identity_key_file }}' + +# Path to file containing ed25519 identity public key. +public_ed25519_identity_key_file = '{{ storage_paths.keys.public_ed25519_identity_key_file }}' + +# Path to file containing x25519 sphinx private key. +private_x25519_sphinx_key_file = '{{ storage_paths.keys.private_x25519_sphinx_key_file }}' + +# Path to file containing x25519 sphinx public key. +public_x25519_sphinx_key_file = '{{ storage_paths.keys.public_x25519_sphinx_key_file }}' + +# Path to file containing x25519 noise private key. +private_x25519_noise_key_file = '{{ storage_paths.keys.private_x25519_noise_key_file }}' + +# Path to file containing x25519 noise public key. +public_x25519_noise_key_file = '{{ storage_paths.keys.public_x25519_noise_key_file }}' + + +##### http-API nym-node config options ##### + +[http] +# Socket address this node will use for binding its http API. +# default: `0.0.0.0:8080` +bind_address = '{{ http.bind_address }}' + +# Path to assets directory of custom landing page of this node +landing_page_assets_path = '{{ http.landing_page_assets_path }}' + +# An optional bearer token for accessing certain http endpoints. +# Currently only used for obtaining mixnode's stats. +access_token = '{{ http.access_token }}' + +# Specify whether basic system information should be exposed. +# default: true +expose_system_info = {{ http.expose_system_info }} + +# Specify whether basic system hardware information should be exposed. +# This option is superseded by `expose_system_info` +# default: true +expose_system_hardware = {{ http.expose_system_hardware }} + +# Specify whether detailed system crypto hardware information should be exposed. +# This option is superseded by `expose_system_hardware` +# default: true +expose_crypto_hardware = {{ http.expose_crypto_hardware }} + +##### wireguard-API nym-node config options ##### + +[wireguard] +# Specifies whether the wireguard service is enabled on this node. +enabled = {{ wireguard.enabled }} + +# Socket address this node will use for binding its wireguard interface. +# default: `0.0.0.0:51822` +bind_address = '{{ wireguard.bind_address }}' + +# Ip address of the private wireguard network. +# default: `10.1.0.0` +private_network_ip = '{{ wireguard.private_network_ip }}' + +# Port announced to external clients wishing to connect to the wireguard interface. +# Useful in the instances where the node is behind a proxy. +announced_port = {{ wireguard.announced_port }} + +# The prefix denoting the maximum number of the clients that can be connected via Wireguard. +# The maximum value for IPv4 is 32 and for IPv6 is 128 +private_network_prefix = {{ wireguard.private_network_prefix }} + +# Paths for wireguard keys, client registries, etc. +[wireguard.storage_paths] +# currently empty + + +##### mixnode mode nym-node config options ##### + +[mixnode] + +[mixnode.verloc] +# Socket address this node will use for binding its verloc API. +# default: `0.0.0.0:1790` +bind_address = '{{ mixnode.verloc.bind_address }}' + +[mixnode.storage_paths] +# currently empty + +##### entry-gateway mode nym-node config options ##### + +[entry_gateway] +# Indicates whether this gateway is accepting only coconut credentials for accessing the mixnet +# or if it also accepts non-paying clients +enforce_zk_nyms = {{ entry_gateway.enforce_zk_nyms }} + +# Socket address this node will use for binding its client websocket API. +# default: `0.0.0.0:9000` +bind_address = '{{ entry_gateway.bind_address }}' + +# Custom announced port for listening for websocket client traffic. +# If unspecified, the value from the `bind_address` will be used instead +# (default: 0 - unspecified) +announce_ws_port = {{#if entry_gateway.announce_ws_port }} {{ entry_gateway.announce_ws_port }} {{else}} 0 {{/if}} + +# If applicable, announced port for listening for secure websocket client traffic. +# (default: 0 - disabled) +announce_wss_port = {{#if entry_gateway.announce_wss_port }} {{ entry_gateway.announce_wss_port }} {{else}} 0 {{/if}} + +[entry_gateway.storage_paths] +# Path to sqlite database containing all persistent data: messages for offline clients, +# derived shared keys and available client bandwidths. +clients_storage = '{{ entry_gateway.storage_paths.clients_storage }}' + +# Path to file containing cosmos account mnemonic used for zk-nym redemption. +cosmos_mnemonic = '{{ entry_gateway.storage_paths.cosmos_mnemonic }}' + +##### exit-gateway mode nym-node config options ##### + +[exit_gateway] + +# specifies whether this exit node should run in 'open-proxy' mode +# and thus would attempt to resolve **ANY** request it receives. +open_proxy = {{ exit_gateway.open_proxy }} + +# Specifies the custom url for an upstream source of the exit policy used by this node. +upstream_exit_policy_url = '{{ exit_gateway.upstream_exit_policy_url }}' + +[exit_gateway.network_requester] +# currently empty (there are some debug options one might want to configure) + +[exit_gateway.ip_packet_router] +# currently empty (there are some debug options one might want to configure) + +[exit_gateway.storage_paths] + +[exit_gateway.storage_paths.network_requester] +# Path to file containing network requester ed25519 identity private key. +private_ed25519_identity_key_file = '{{ exit_gateway.storage_paths.network_requester.private_ed25519_identity_key_file }}' + +# Path to file containing network requester ed25519 identity public key. +public_ed25519_identity_key_file = '{{ exit_gateway.storage_paths.network_requester.public_ed25519_identity_key_file }}' + +# Path to file containing network requester x25519 diffie hellman private key. +private_x25519_diffie_hellman_key_file = '{{ exit_gateway.storage_paths.network_requester.private_x25519_diffie_hellman_key_file }}' + +# Path to file containing network requester x25519 diffie hellman public key. +public_x25519_diffie_hellman_key_file = '{{ exit_gateway.storage_paths.network_requester.public_x25519_diffie_hellman_key_file }}' + +# Path to file containing key used for encrypting and decrypting the content of an +# acknowledgement so that nobody besides the client knows which packet it refers to. +ack_key_file = '{{ exit_gateway.storage_paths.network_requester.ack_key_file }}' + +# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. +reply_surb_database = '{{ exit_gateway.storage_paths.network_requester.reply_surb_database }}' + +# Normally this is a path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +# but in this case it just has the basic information of "we're using custom gateway". +# Due to how clients are started up, this file has to exist. +gateway_registrations = '{{ exit_gateway.storage_paths.network_requester.gateway_registrations }}' + +[exit_gateway.storage_paths.ip_packet_router] +# Path to file containing ip packet router ed25519 identity private key. +private_ed25519_identity_key_file = '{{ exit_gateway.storage_paths.ip_packet_router.private_ed25519_identity_key_file }}' + +# Path to file containing ip packet router ed25519 identity public key. +public_ed25519_identity_key_file = '{{ exit_gateway.storage_paths.ip_packet_router.public_ed25519_identity_key_file }}' + +# Path to file containing ip packet router x25519 diffie hellman private key. +private_x25519_diffie_hellman_key_file = '{{ exit_gateway.storage_paths.ip_packet_router.private_x25519_diffie_hellman_key_file }}' + +# Path to file containing ip packet router x25519 diffie hellman public key. +public_x25519_diffie_hellman_key_file = '{{ exit_gateway.storage_paths.ip_packet_router.public_x25519_diffie_hellman_key_file }}' + +# Path to file containing key used for encrypting and decrypting the content of an +# acknowledgement so that nobody besides the client knows which packet it refers to. +ack_key_file = '{{ exit_gateway.storage_paths.ip_packet_router.ack_key_file }}' + +# Path to the persistent store for received reply surbs, unused encryption keys and used sender tags. +reply_surb_database = '{{ exit_gateway.storage_paths.ip_packet_router.reply_surb_database }}' + +# Normally this is a path to the file containing information about gateways used by this client, +# i.e. details such as their public keys, owner addresses or the network information. +# but in this case it just has the basic information of "we're using custom gateway". +# Due to how clients are started up, this file has to exist. +gateway_registrations = '{{ exit_gateway.storage_paths.ip_packet_router.gateway_registrations }}' + +##### logging configuration options ##### + +[logging] + +# TODO + +"#; diff --git a/nym-node/src/config/upgrade_helpers.rs b/nym-node/src/config/upgrade_helpers.rs new file mode 100644 index 0000000000..ea92ad2414 --- /dev/null +++ b/nym-node/src/config/upgrade_helpers.rs @@ -0,0 +1,22 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::config::Config; +use crate::error::NymNodeError; +use std::path::Path; + +// currently there are no upgrades +async fn try_upgrade_config<P: AsRef<Path>>(_path: P) -> Result<(), NymNodeError> { + Ok(()) +} + +pub async fn try_load_current_config<P: AsRef<Path>>( + config_path: P, +) -> Result<Config, NymNodeError> { + if let Ok(cfg) = Config::read_from_toml_file(config_path.as_ref()) { + return Ok(cfg); + } + + try_upgrade_config(config_path.as_ref()).await?; + Config::read_from_toml_file(config_path) +} diff --git a/nym-node/src/env.rs b/nym-node/src/env.rs new file mode 100644 index 0000000000..a8e785499e --- /dev/null +++ b/nym-node/src/env.rs @@ -0,0 +1,58 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +pub mod vars { + pub const NYMNODE_NO_BANNER_ARG: &str = "NYMNODE_NO_BANNER"; + pub const NYMNODE_CONFIG_ENV_FILE_ARG: &str = "NYMNODE_CONFIG_ENV_FILE_ARG"; + pub const NYMNODE_ID_ARG: &str = "NYMNODE_ID"; + pub const NYMNODE_OUTPUT_ARG: &str = "NYMNODE_OUTPUT"; + pub const NYMNODE_CONFIG_PATH_ARG: &str = "NYMNODE_CONFIG"; + + pub const NYMNODE_DENY_INIT_ARG: &str = "NYMNODE_DENY_INIT"; + + pub const NYMNODE_INIT_ONLY_ARG: &str = "NYMNODE_INIT_ONLY"; + + pub const NYMMONDE_WRITE_CONFIG_CHANGES_ARG: &str = "NYMNODE_WRITE_CONFIG_CHANGES"; + + pub const NYMNODE_BONDING_INFORMATION_OUTPUT_ARG: &str = "NYMNODE_BONDING_INFORMATION_OUTPUT"; + + pub const NYMNODE_MODE_ARG: &str = "NYMNODE_MODE"; + + // host: + pub const NYMNODE_PUBLIC_IPS_ARG: &str = "NYMNODE_PUBLIC_IPS"; + pub const NYMNODE_HOSTNAME_ARG: &str = "NYMNODE_HOSTNAME"; + pub const NYMNODE_LOCATION_ARG: &str = "NYMNODE_LOCATION"; + + // http: + pub const NYMNODE_HTTP_BIND_ADDRESS_ARG: &str = "NYMNODE_HTTP_BIND_ADDRESS"; + pub const NYMNODE_HTTP_LANDING_ASSETS_ARG: &str = "NYMNODE_HTTP_LANDING_ASSETS"; + pub const NYMNODE_HTTP_ACCESS_TOKEN_ARG: &str = "NYMNODE_HTTP_ACCESS_TOKEN"; + pub const NYMNODE_HTTP_EXPOSE_SYSTEM_INFO_ARG: &str = "NYMNODE_HTTP_EXPOSE_SYSTEM_INFO"; + pub const NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE_ARG: &str = "NYMNODE_HTTP_EXPOSE_SYSTEM_HARDWARE"; + pub const NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE_ARG: &str = "NYMNODE_HTTP_EXPOSE_CRYPTO_HARDWARE"; + + // mixnet: + pub const NYMNODE_MIXNET_BIND_ADDRESS_ARG: &str = "NYMNODE_MIXNET_BIND_ADDRESS"; + pub const NYMNODE_NYM_APIS_ARG: &str = "NYMNODE_NYM_APIS"; + + // wireguard: + pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED"; + pub const NYMNODE_WG_BIND_ADDRESS_ARG: &str = "NYMNODE_WG_BIND_ADDRESS"; + pub const NYMNODE_WG_IP_NETWORK_ARG: &str = "NYMNODE_WG_IP_NETWORK"; + pub const NYMNODE_WG_ANNOUNCED_PORT_ARG: &str = "NYMNODE_WG_ANNOUNCED_PORT"; + pub const NYMNODE_WG_PRIVATE_NETWORK_PREFIX_ARG: &str = "NYMNODE_WG_PRIVATE_NETWORK_PREFIX"; + + // mixnode: + pub const NYMNODE_VERLOC_BIND_ADDRESS_ARG: &str = "NYMNODE_VERLOC_BIND_ADDRESS"; + + // entry gateway: + pub const NYMNODE_ENTRY_BIND_ADDRESS_ARG: &str = "NYMNODE_ENTRY_BIND_ADDRESS"; + pub const NYMNODE_ENTRY_ANNOUNCE_WS_PORT_ARG: &str = "NYMNODE_ENTRY_ANNOUNCE_WS_PORT"; + pub const NYMNODE_ENTRY_ANNOUNCE_WSS_PORT_ARG: &str = "NYMNODE_ENTRY_ANNOUNCE_WSS_PORT"; + pub const NYMNODE_ENFORCE_ZK_NYMS_ARG: &str = "NYMNODE_ENFORCE_ZK_NYMS"; + pub const NYMNODE_MNEMONIC_ARG: &str = "NYMNODE_MNEMONIC"; + + // exit gateway: + pub const NYMNODE_UPSTREAM_EXIT_POLICY_ARG: &str = "NYMNODE_UPSTREAM_EXIT_POLICY"; + pub const NYMNODE_OPEN_PROXY_ARG: &str = "NYMNODE_OPEN_PROXY"; +} diff --git a/nym-node/src/error.rs b/nym-node/src/error.rs index e5a14cf018..c7b42294c1 100644 --- a/nym-node/src/error.rs +++ b/nym-node/src/error.rs @@ -1,16 +1,104 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::config::helpers::UnsupportedGatewayAddresses; use crate::wireguard::error::WireguardError; -use std::net::{IpAddr, SocketAddr}; +use nym_ip_packet_router::error::ClientCoreError; +use nym_node_http_api::NymNodeHttpError; +use std::io; +use std::net::IpAddr; +use std::path::PathBuf; use thiserror::Error; +#[derive(Debug, Error)] +pub enum KeyIOFailure { + #[error("failed to load {keys} keys from {:?} (private key) and {:?} (public key): {err}", .paths.private_key_path, .paths.public_key_path)] + KeyPairLoadFailure { + keys: String, + paths: nym_pemstore::KeyPairPath, + #[source] + err: io::Error, + }, + + #[error("failed to load {key} key from '{}': {err}", path.display())] + KeyLoadFailure { + key: String, + path: PathBuf, + #[source] + err: io::Error, + }, + + #[error("failed to store {keys} keys to {:?} (private key) and {:?} (public key): {err}", .paths.private_key_path, .paths.public_key_path)] + KeyPairStoreFailure { + keys: String, + paths: nym_pemstore::KeyPairPath, + #[source] + err: io::Error, + }, + + #[error("failed to store {key} key to '{}': {err}", path.display())] + KeyStoreFailure { + key: String, + path: PathBuf, + #[source] + err: io::Error, + }, +} + #[derive(Debug, Error)] pub enum NymNodeError { - #[error("failed to bind the HTTP API to {bind_address}: {source}")] - HttpBindFailure { - bind_address: SocketAddr, - source: hyper::Error, + #[error("could not find an existing config file at '{}' and fresh node initialisation has been disabled", config_path.display())] + ForbiddenInitialisation { config_path: PathBuf }, + + #[error("could not derive path to data directory of this nym node")] + DataDirDerivationFailure, + + #[error("could not derive path to config directory of this nym node")] + ConfigDirDerivationFailure, + + #[error(transparent)] + HttpFailure(#[from] NymNodeHttpError), + + #[error("failed to load config file using path '{}'. detailed message: {source}", path.display())] + ConfigLoadFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("failed to save config file for id {id} using path '{}'. detailed message: {source}", path.display())] + ConfigSaveFailure { + id: String, + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("the node description file is malformed: {source}")] + MalformedDescriptionFile { + #[source] + source: toml::de::Error, + }, + + #[error("failed to load description file using path '{}'. detailed message: {source}", path.display())] + DescriptionLoadFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("failed to save description file using path '{}'. detailed message: {source}", path.display())] + DescriptionSaveFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("failed to write bonding information to '{}': {source}", path.display())] + BondingInfoWriteFailure { + path: PathBuf, + #[source] + source: io::Error, }, #[error("this node hasn't set any valid public addresses to announce. Please modify [host.public_ips] section of your config")] @@ -19,24 +107,110 @@ pub enum NymNodeError { #[error("this node attempted to announce an invalid public address: {address}. Please modify [host.public_ips] section of your config. Alternatively, if you wanted to use it in the local setting, run the node with the '--local' flag.")] InvalidPublicIp { address: IpAddr }, - #[error("failed to use nym-node requests: {source}")] - RequestError { - #[from] - source: nym_node_requests::error::Error, - }, - #[error(transparent)] WireguardError { #[from] source: WireguardError, }, + #[deprecated] #[error(transparent)] KeyRecoveryError { #[from] source: nym_crypto::asymmetric::encryption::KeyRecoveryError, }, - #[error("unimplemented")] - Unimplemented, + #[error(transparent)] + KeyFailure(#[from] KeyIOFailure), + + #[error("could not initialise nym-node as '--{name}' has not been specified which is required for a first time setup. (config section: {section})")] + MissingInitArg { section: String, name: String }, + + #[error("failed to migrate {node_type}: {message}")] + MigrationFailure { node_type: String, message: String }, + + #[error("there was an issue with wireguard IP network: {source}")] + IpNetworkError { + #[from] + source: ipnetwork::IpNetworkError, + }, + + #[error(transparent)] + MixnodeFailure(#[from] MixnodeError), + + #[error(transparent)] + EntryGatewayFailure(#[from] EntryGatewayError), + + #[error(transparent)] + ExitGatewayFailure(#[from] ExitGatewayError), +} + +impl From<nym_mixnode::error::MixnodeError> for NymNodeError { + fn from(value: nym_mixnode::error::MixnodeError) -> Self { + MixnodeError::from(value).into() + } +} + +#[derive(Debug, Error)] +pub enum MixnodeError { + #[error("failed to load mixnode description from {}: {source}", path.display())] + DescriptionLoadFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("currently it's not supported to have different ip addresses for verloc and mixnet ({verloc_bind_ip} and {mix_bind_ip} were used)")] + UnsupportedAddresses { + verloc_bind_ip: IpAddr, + mix_bind_ip: IpAddr, + }, + + #[error("mixnode failure: {0}")] + External(#[from] nym_mixnode::error::MixnodeError), +} + +#[derive(Debug, Error)] +pub enum EntryGatewayError { + #[error("failed to load entry gateway account mnemonic from {}: {source}", path.display())] + MnemonicLoadFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("failed to save entry gateway account mnemonic from {}: {source}", path.display())] + MnemonicSaveFailure { + path: PathBuf, + #[source] + source: io::Error, + }, + + #[error("the stored mnemonic is malformed: {source}")] + MalformedBip39Mnemonic { + #[from] + source: bip39::Error, + }, + + #[error(transparent)] + UnsupportedAddresses(#[from] UnsupportedGatewayAddresses), + + #[error("entry gateway failure: {0}")] + External(#[from] nym_gateway::GatewayError), +} + +#[derive(Debug, Error)] +pub enum ExitGatewayError { + #[error(transparent)] + KeyFailure(#[from] KeyIOFailure), + + #[error(transparent)] + UnsupportedAddresses(#[from] UnsupportedGatewayAddresses), + + // TODO: more granular errors + #[error(transparent)] + ExternalClientCore(#[from] ClientCoreError), + + #[error("exit gateway failure: {0}")] + External(#[from] nym_gateway::GatewayError), } diff --git a/nym-node/src/http/state.rs b/nym-node/src/http/state.rs deleted file mode 100644 index e6141fd238..0000000000 --- a/nym-node/src/http/state.rs +++ /dev/null @@ -1,38 +0,0 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use tokio::time::Instant; - -#[derive(Debug, Clone)] -pub(crate) struct AppState { - pub(crate) startup_time: Instant, - // wireguard: WireguardAppState, -} - -// #[derive(Debug, Clone)] -// pub struct WireguardAppState { -// // inner: Option<WireguardAppStateInner>, -// } -// -// #[derive(Debug)] -// pub(crate) struct WireguardAppStateInner { -// // -// } -// -// impl FromRef<AppState> for WireguardAppState { -// fn from_ref(app_state: &AppState) -> Self { -// app_state.wireguard.clone() -// } -// } - -impl AppState { - pub fn new() -> Self { - AppState { - // is it 100% accurate? - // no. - // does it have to be? - // also no. - startup_time: Instant::now(), - } - } -} diff --git a/nym-node/src/lib.rs b/nym-node/src/lib.rs index 70e48aeec1..320d22559d 100644 --- a/nym-node/src/lib.rs +++ b/nym-node/src/lib.rs @@ -1,12 +1,11 @@ -// Copyright 2023 - Nym Technologies SA <contact@nymtech.net> +// Copyright 2023-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only #![warn(clippy::expect_used)] #![warn(clippy::unwrap_used)] -// this crate will eventually get converted into proper binary - pub mod config; pub mod error; -pub mod http; pub mod wireguard; + +pub use nym_node_http_api as http; diff --git a/nym-node/src/main.rs b/nym-node/src/main.rs new file mode 100644 index 0000000000..adef6eeed0 --- /dev/null +++ b/nym-node/src/main.rs @@ -0,0 +1,34 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +#![warn(clippy::expect_used)] +#![warn(clippy::unwrap_used)] + +use crate::cli::Cli; +use clap::{crate_name, crate_version, Parser}; +use nym_bin_common::logging::{maybe_print_banner, setup_tracing_logger}; +use nym_config::defaults::setup_env; + +mod cli; +mod env; +pub(crate) mod node; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + // std::env::set_var( + // "RUST_LOG", + // "trace,handlebars=warn,tendermint_rpc=warn,h2=warn,hyper=warn,rustls=warn,reqwest=warn,tungstenite=warn,async_tungstenite=warn,tokio_util=warn,tokio_tungstenite=warn,tokio-util=warn", + // ); + + let cli = Cli::parse(); + setup_env(cli.config_env_file.as_ref()); + setup_tracing_logger(); + + if !cli.no_banner { + maybe_print_banner(crate_name!(), crate_version!()); + } + + cli.execute().await?; + + Ok(()) +} diff --git a/nym-node/src/node/bonding_information.rs b/nym-node/src/node/bonding_information.rs new file mode 100644 index 0000000000..1f405b4a06 --- /dev/null +++ b/nym-node/src/node/bonding_information.rs @@ -0,0 +1,197 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node::helpers::{load_ed25519_identity_public_key, load_x25519_sphinx_public_key}; +use nym_node::config::{Config, NodeMode}; +use nym_node::error::NymNodeError; +use semver::{BuildMetadata, Version}; +use serde::{Deserialize, Serialize}; +use std::fmt::{Display, Formatter}; + +#[derive(Serialize, Deserialize, Debug)] +#[serde(tag = "node_type")] +pub enum BondingInformationV1 { + Mixnode(MixnodeBondingInformation), + Gateway(GatewayBondingInformation), +} + +impl Display for BondingInformationV1 { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + BondingInformationV1::Mixnode(m) => m.fmt(f), + BondingInformationV1::Gateway(g) => g.fmt(f), + } + } +} + +// TODO: work in progress, I'm not 100% sure yet what will be needed +// #[derive(Serialize, Deserialize, Debug)] +// pub struct BondingInformationV2 { +// pub(crate) ed25519_identity_key: ed25519::PublicKey, +// pub(crate) x25519_sphinx_key: x25519::PublicKey, +// } +// +// impl Display for BondingInformationV2 { +// fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { +// writeln!( +// f, +// "ed25519 identity key: {}", +// self.ed25519_identity_key.to_base58_string() +// )?; +// write!( +// f, +// "x25519 sphinx key: {}", +// self.x25519_sphinx_key.to_base58_string() +// ) +// } +// } + +#[derive(Serialize, Deserialize, Debug)] +pub struct MixnodeBondingInformation { + pub(crate) version: String, + pub(crate) host: String, + pub(crate) identity_key: String, + pub(crate) sphinx_key: String, +} + +impl MixnodeBondingInformation { + pub fn from_data( + ed25519_identity_key: String, + x25519_sphinx_key: String, + ) -> MixnodeBondingInformation { + MixnodeBondingInformation { + version: Self::get_version(), + host: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), + identity_key: ed25519_identity_key, + sphinx_key: x25519_sphinx_key, + } + } + + #[allow(clippy::unwrap_used)] + fn get_version() -> String { + // SAFETY: + // 1. the value has been put into the environment during build.rs, so it must exist, + // 2. and the obtained version has already been parsed into semver in build.rs, so it must be a valid semver + let raw = include_str!(concat!(env!("OUT_DIR"), "/mixnode_version")); + let mut semver: Version = raw.parse().unwrap(); + + // if it's not empty, then we messed up our own versioning + assert!(semver.build.is_empty()); + semver.build = BuildMetadata::new("nymnode").unwrap(); + semver.to_string() + } +} + +impl Display for MixnodeBondingInformation { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Node type: Mixnode")?; + writeln!(f, "Identity Key: {}", self.identity_key)?; + writeln!(f, "Sphinx Key: {}", self.sphinx_key)?; + writeln!(f, "Host: {}", self.host)?; + writeln!(f, "Version: {}", self.version)?; + Ok(()) + } +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct GatewayBondingInformation { + pub(crate) version: String, + pub(crate) host: String, + pub(crate) location: String, + pub(crate) identity_key: String, + pub(crate) sphinx_key: String, +} + +impl GatewayBondingInformation { + pub fn from_data( + ed25519_identity_key: String, + x25519_sphinx_key: String, + ) -> GatewayBondingInformation { + GatewayBondingInformation { + version: Self::get_version(), + host: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), + location: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), + identity_key: ed25519_identity_key, + sphinx_key: x25519_sphinx_key, + } + } + + #[allow(clippy::unwrap_used)] + fn get_version() -> String { + // SAFETY: + // 1. the value has been put into the file during build.rs, so it must exist, + // 2. and the obtained version has already been parsed into semver in build.rs, so it must be a valid semver + let raw = include_str!(concat!(env!("OUT_DIR"), "/gateway_version")); + let mut semver: Version = raw.parse().unwrap(); + + // if it's not empty, then we messed up our own versioning + assert!(semver.build.is_empty()); + semver.build = BuildMetadata::new("nymnode").unwrap(); + semver.to_string() + } +} + +impl Display for GatewayBondingInformation { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + writeln!(f, "Node type: Gateway")?; + writeln!(f, "Identity Key: {}", self.identity_key)?; + writeln!(f, "Sphinx Key: {}", self.sphinx_key)?; + writeln!(f, "Location: {}", self.location)?; + writeln!(f, "Host: {}", self.host)?; + writeln!(f, "Version: {}", self.version)?; + Ok(()) + } +} + +impl BondingInformationV1 { + pub fn from_data( + mode: NodeMode, + ed25519_identity_key: String, + x25519_sphinx_key: String, + ) -> BondingInformationV1 { + match mode { + NodeMode::Mixnode => BondingInformationV1::Mixnode( + MixnodeBondingInformation::from_data(ed25519_identity_key, x25519_sphinx_key), + ), + NodeMode::EntryGateway | NodeMode::ExitGateway => BondingInformationV1::Gateway( + GatewayBondingInformation::from_data(ed25519_identity_key, x25519_sphinx_key), + ), + } + } + + fn ed25519_identity_key(&self) -> String { + match self { + BondingInformationV1::Mixnode(m) => m.identity_key.clone(), + BondingInformationV1::Gateway(g) => g.identity_key.clone(), + } + } + + fn x25519_sphinx_key(&self) -> String { + match self { + BondingInformationV1::Mixnode(m) => m.sphinx_key.clone(), + BondingInformationV1::Gateway(g) => g.sphinx_key.clone(), + } + } + + pub fn try_load(config: &Config) -> Result<BondingInformationV1, NymNodeError> { + let ed25519_identity_key = load_ed25519_identity_public_key( + &config.storage_paths.keys.public_ed25519_identity_key_file, + )?; + let x25519_sphinx_key = load_x25519_sphinx_public_key( + &config.storage_paths.keys.public_x25519_sphinx_key_file, + )?; + let mode = config.mode; + + Ok(Self::from_data( + mode, + ed25519_identity_key.to_base58_string(), + x25519_sphinx_key.to_base58_string(), + )) + } + + pub fn with_mode(self, mode: NodeMode) -> Self { + let identity_key = self.ed25519_identity_key(); + let sphinx_key = self.x25519_sphinx_key(); + Self::from_data(mode, identity_key, sphinx_key) + } +} diff --git a/nym-node/src/node/description.rs b/nym-node/src/node/description.rs new file mode 100644 index 0000000000..0f5b713727 --- /dev/null +++ b/nym-node/src/node/description.rs @@ -0,0 +1,40 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use nym_node::error::NymNodeError; +use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription; +use std::fs; +use std::fs::create_dir_all; +use std::path::Path; + +pub fn load_node_description<P: AsRef<Path>>(path: P) -> Result<NodeDescription, NymNodeError> { + let raw = fs::read_to_string(path.as_ref()).map_err(|source| { + NymNodeError::DescriptionLoadFailure { + path: path.as_ref().to_path_buf(), + source, + } + })?; + + toml::from_str(&raw).map_err(|source| NymNodeError::MalformedDescriptionFile { source }) +} + +pub fn save_node_description<P: AsRef<Path>>( + path: P, + description: &NodeDescription, +) -> Result<(), NymNodeError> { + // SAFETY: + // the unwrap is fine as our description format can be serialised as toml + #[allow(clippy::unwrap_used)] + let serialised = toml::to_string_pretty(description).unwrap(); + if let Some(parent) = path.as_ref().parent() { + create_dir_all(parent).map_err(|source| NymNodeError::DescriptionSaveFailure { + path: path.as_ref().to_path_buf(), + source, + })? + } + + fs::write(path.as_ref(), serialised).map_err(|source| NymNodeError::DescriptionSaveFailure { + path: path.as_ref().to_path_buf(), + source, + }) +} diff --git a/nym-node/src/node/helpers.rs b/nym-node/src/node/helpers.rs new file mode 100644 index 0000000000..a5c23cfb17 --- /dev/null +++ b/nym-node/src/node/helpers.rs @@ -0,0 +1,153 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_node::config::NodeMode; +use nym_node::error::{KeyIOFailure, NymNodeError}; +use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription; +use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; +use nym_pemstore::KeyPairPath; +use serde::Serialize; +use std::fmt::{Display, Formatter}; +use std::path::Path; + +#[derive(Debug, Serialize)] +pub(crate) struct DisplayDetails { + pub(crate) current_mode: NodeMode, + + pub(crate) description: NodeDescription, + + pub(crate) ed25519_identity_key: String, + pub(crate) x25519_sphinx_key: String, + pub(crate) x25519_noise_key: String, + + pub(crate) exit_network_requester_address: String, + pub(crate) exit_ip_packet_router_address: String, +} + +impl Display for DisplayDetails { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + writeln!(f, "current mode: {}", self.current_mode)?; + writeln!(f, "moniker: '{}'", self.description.moniker)?; + writeln!(f, "website: '{}'", self.description.website)?; + writeln!( + f, + "security contact: '{}'", + self.description.security_contact + )?; + writeln!(f, "details: '{}'", self.description.details)?; + writeln!(f, "ed25519 identity: {}", self.ed25519_identity_key)?; + writeln!(f, "x25519 sphinx: {}", self.x25519_sphinx_key)?; + writeln!(f, "x25519 noise: {}", self.x25519_noise_key)?; + writeln!( + f, + "exit network requester address: {}", + self.exit_network_requester_address + )?; + writeln!( + f, + "exit ip packet router address: {}", + self.exit_ip_packet_router_address + )?; + Ok(()) + } +} + +pub(crate) fn load_keypair<T: PemStorableKeyPair>( + paths: KeyPairPath, + name: impl Into<String>, +) -> Result<T, KeyIOFailure> { + nym_pemstore::load_keypair(&paths).map_err(|err| KeyIOFailure::KeyPairLoadFailure { + keys: name.into(), + paths, + err, + }) +} + +pub(crate) fn store_keypair<T: PemStorableKeyPair>( + keys: &T, + paths: KeyPairPath, + name: impl Into<String>, +) -> Result<(), KeyIOFailure> { + nym_pemstore::store_keypair(keys, &paths).map_err(|err| KeyIOFailure::KeyPairStoreFailure { + keys: name.into(), + paths, + err, + }) +} + +pub(crate) fn load_key<T, P>(path: P, name: impl Into<String>) -> Result<T, KeyIOFailure> +where + T: PemStorableKey, + P: AsRef<Path>, +{ + nym_pemstore::load_key(path.as_ref()).map_err(|err| KeyIOFailure::KeyLoadFailure { + key: name.into(), + path: path.as_ref().to_path_buf(), + err, + }) +} + +pub(crate) fn store_key<T, P>(key: &T, path: P, name: impl Into<String>) -> Result<(), KeyIOFailure> +where + T: PemStorableKey, + P: AsRef<Path>, +{ + nym_pemstore::store_key(key, path.as_ref()).map_err(|err| KeyIOFailure::KeyStoreFailure { + key: name.into(), + path: path.as_ref().to_path_buf(), + err, + }) +} + +pub(crate) fn load_ed25519_identity_keypair( + paths: KeyPairPath, +) -> Result<ed25519::KeyPair, NymNodeError> { + Ok(load_keypair(paths, "ed25519-identity")?) +} + +#[allow(dead_code)] +pub(crate) fn load_ed25519_identity_public_key<P: AsRef<Path>>( + path: P, +) -> Result<ed25519::PublicKey, NymNodeError> { + Ok(load_key(path, "ed25519-identity-public-key")?) +} + +pub(crate) fn load_x25519_sphinx_keypair( + paths: KeyPairPath, +) -> Result<x25519::KeyPair, NymNodeError> { + Ok(load_keypair(paths, "x25519-sphinx")?) +} + +pub(crate) fn load_x25519_noise_keypair( + paths: KeyPairPath, +) -> Result<x25519::KeyPair, NymNodeError> { + Ok(load_keypair(paths, "x25519-noise")?) +} + +pub(crate) fn load_x25519_sphinx_public_key<P: AsRef<Path>>( + path: P, +) -> Result<x25519::PublicKey, NymNodeError> { + Ok(load_key(path, "x25519-sphinx-public-key")?) +} + +pub(crate) fn store_ed25519_identity_keypair( + keys: &ed25519::KeyPair, + paths: KeyPairPath, +) -> Result<(), NymNodeError> { + Ok(store_keypair(keys, paths, "ed25519-identity")?) +} + +pub(crate) fn store_x25519_sphinx_keypair( + keys: &x25519::KeyPair, + paths: KeyPairPath, +) -> Result<(), NymNodeError> { + Ok(store_keypair(keys, paths, "x25519-sphinx")?) +} + +pub(crate) fn store_x25519_noise_keypair( + keys: &x25519::KeyPair, + paths: KeyPairPath, +) -> Result<(), NymNodeError> { + Ok(store_keypair(keys, paths, "x25519-noise")?) +} diff --git a/nym-node/src/node/http/mod.rs b/nym-node/src/node/http/mod.rs new file mode 100644 index 0000000000..ca26a8b292 --- /dev/null +++ b/nym-node/src/node/http/mod.rs @@ -0,0 +1,34 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_node::config::Config; +use nym_node::error::NymNodeError; +use nym_node_http_api::api::api_requests; +use nym_node_http_api::api::api_requests::SignedHostInformation; +use nym_node_http_api::NymNodeHttpError; + +pub(crate) mod system_info; + +pub(crate) fn sign_host_details( + config: &Config, + x22519_sphinx: &x25519::PublicKey, + x25519_noise: &x25519::PublicKey, + ed22519_identity: &ed25519::KeyPair, +) -> Result<api_requests::v1::node::models::SignedHostInformation, NymNodeError> { + let host_info = api_requests::v1::node::models::HostInformation { + ip_address: config.host.public_ips.clone(), + hostname: config.host.hostname.clone(), + keys: api_requests::v1::node::models::HostKeys { + ed25519_identity: ed22519_identity.public_key().to_base58_string(), + x25519_sphinx: x22519_sphinx.to_base58_string(), + x25519_noise: x25519_noise.to_base58_string(), + }, + }; + + let signed_info = SignedHostInformation::new(host_info, ed22519_identity.private_key()) + .map_err(NymNodeHttpError::from)?; + Ok(signed_info) +} + +// pub(crate) fn run_http_api(config: &Config, task_client: TaskClient) diff --git a/nym-node/src/node/http/system_info.rs b/nym-node/src/node/http/system_info.rs new file mode 100644 index 0000000000..128ce37229 --- /dev/null +++ b/nym-node/src/node/http/system_info.rs @@ -0,0 +1,80 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use cupid::TopologyType; +use nym_node_http_api::api::api_requests::v1::node::models::{ + Cpu, CryptoHardware, Hardware, HostSystem, +}; +use sysinfo::System; + +fn crypto_hardware() -> Option<CryptoHardware> { + let info = cupid::master()?; + let extended_topology = info.extended_topology_enumeration()?; + + let smt_logical_processor_count = extended_topology + .clone() + .filter_map(|leaf| { + if leaf.level_type() == TopologyType::SMT { + Some(leaf.logical_processor_count()) + } else { + None + } + }) + .collect(); + + Some(CryptoHardware { + aesni: info.aesni(), + avx2: info.avx2(), + smt_logical_processor_count, + osxsave: info.osxsave(), + sgx: info.sgx(), + xsave: info.xsave(), + }) +} + +pub(crate) fn get_system_info( + allow_hardware_info: bool, + allow_crypto_hardware_info: bool, +) -> HostSystem { + if !sysinfo::IS_SUPPORTED_SYSTEM { + return Default::default(); + } + + let mut system = sysinfo::System::new_all(); + // TODO: do we actually need to refresh all here? + system.refresh_all(); + + let crypto_hardware = if allow_crypto_hardware_info && allow_hardware_info { + crypto_hardware() + } else { + None + }; + + let hardware = if allow_hardware_info { + let cpu = system + .cpus() + .iter() + .map(|cpu| Cpu { + name: cpu.name().to_string(), + frequency: cpu.frequency(), + vendor_id: cpu.vendor_id().to_string(), + brand: cpu.brand().to_string(), + }) + .collect(); + Some(Hardware { + cpu, + total_memory: system.total_memory(), + crypto: crypto_hardware, + }) + } else { + None + }; + + HostSystem { + system_name: System::name(), + kernel_version: System::kernel_version(), + os_version: System::os_version(), + cpu_arch: System::cpu_arch(), + hardware, + } +} diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs new file mode 100644 index 0000000000..7127a03a15 --- /dev/null +++ b/nym-node/src/node/mod.rs @@ -0,0 +1,589 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node::description::{load_node_description, save_node_description}; +use crate::node::helpers::{ + load_ed25519_identity_keypair, load_key, load_x25519_noise_keypair, load_x25519_sphinx_keypair, + store_ed25519_identity_keypair, store_key, store_keypair, store_x25519_noise_keypair, + store_x25519_sphinx_keypair, DisplayDetails, +}; +use crate::node::http::{sign_host_details, system_info::get_system_info}; +use ipnetwork::IpNetwork; +use nym_bin_common::bin_info_owned; +use nym_crypto::asymmetric::{ed25519, x25519}; +use nym_gateway::Gateway; +use nym_mixnode::MixNode; +use nym_network_requester::{ + set_active_gateway, setup_fs_gateways_storage, store_gateway_details, CustomGatewayDetails, + GatewayDetails, GatewayRegistration, +}; +use nym_node::config::entry_gateway::ephemeral_entry_gateway_config; +use nym_node::config::exit_gateway::ephemeral_exit_gateway_config; +use nym_node::config::mixnode::ephemeral_mixnode_config; +use nym_node::config::{Config, EntryGatewayConfig, ExitGatewayConfig, MixnodeConfig, NodeMode}; +use nym_node::error::{EntryGatewayError, ExitGatewayError, MixnodeError, NymNodeError}; +use nym_node_http_api::api::api_requests; +use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription; +use nym_node_http_api::router::WireguardAppState; +use nym_node_http_api::state::metrics::{SharedMixingStats, SharedVerlocStats}; +use nym_node_http_api::state::AppState; +use nym_node_http_api::{NymNodeHTTPServer, NymNodeRouter}; +use nym_sphinx_acknowledgements::AckKey; +use nym_sphinx_addressing::Recipient; +use nym_task::{TaskClient, TaskManager}; +use nym_wireguard_types::registration::GatewayClientRegistry; +use rand::rngs::OsRng; +use rand::{CryptoRng, RngCore}; +use std::path::Path; +use std::sync::Arc; +use tracing::{debug, error, info, trace}; +use zeroize::Zeroizing; + +pub mod bonding_information; +pub mod description; +pub mod helpers; +pub(crate) mod http; + +pub struct MixnodeData { + mixing_stats: SharedMixingStats, +} + +impl MixnodeData { + pub fn initialise(_config: &MixnodeConfig) -> Result<(), MixnodeError> { + Ok(()) + } + + fn new(_config: &MixnodeConfig) -> Result<MixnodeData, MixnodeError> { + Ok(MixnodeData { + mixing_stats: SharedMixingStats::new(), + }) + } +} + +pub struct EntryGatewayData { + mnemonic: Zeroizing<bip39::Mnemonic>, + client_storage: nym_gateway::node::PersistentStorage, + client_registry: Arc<GatewayClientRegistry>, +} + +impl EntryGatewayData { + pub fn initialise( + config: &EntryGatewayConfig, + custom_mnemonic: Option<Zeroizing<bip39::Mnemonic>>, + ) -> Result<(), EntryGatewayError> { + // SAFETY: + // this unwrap is fine as 24 word count is a valid argument for generating entropy for a new bip39 mnemonic + #[allow(clippy::unwrap_used)] + let mnemonic = custom_mnemonic + .unwrap_or_else(|| Zeroizing::new(bip39::Mnemonic::generate(24).unwrap())); + config.storage_paths.save_mnemonic_to_file(&mnemonic)?; + + Ok(()) + } + + async fn new(config: &EntryGatewayConfig) -> Result<EntryGatewayData, EntryGatewayError> { + Ok(EntryGatewayData { + mnemonic: config.storage_paths.load_mnemonic_from_file()?, + client_storage: nym_gateway::node::PersistentStorage::init( + &config.storage_paths.clients_storage, + config.debug.message_retrieval_limit, + ) + .await + .map_err(nym_gateway::GatewayError::from)?, + client_registry: Arc::new(Default::default()), + }) + } +} + +pub struct ExitGatewayData { + // ideally we'd be storing all the keys here, but unfortunately due to how the service providers + // are currently implemented, they will be loading the data themselves from the provided paths + + // those public keys are just convenience wrappers for http builder and details displayer + nr_ed25519: ed25519::PublicKey, + nr_x25519: x25519::PublicKey, + + ipr_ed25519: ed25519::PublicKey, + ipr_x25519: x25519::PublicKey, +} + +impl ExitGatewayData { + fn initialise_client_keys<R: RngCore + CryptoRng>( + rng: &mut R, + typ: &str, + ed25519_paths: nym_pemstore::KeyPairPath, + x25519_paths: nym_pemstore::KeyPairPath, + ack_key_path: &Path, + ) -> Result<(), ExitGatewayError> { + let ed25519_keys = ed25519::KeyPair::new(rng); + let x25519_keys = x25519::KeyPair::new(rng); + let aes128ctr_key = AckKey::new(rng); + + store_keypair( + &ed25519_keys, + ed25519_paths, + format!("{typ}-ed25519-identity"), + )?; + store_keypair(&x25519_keys, x25519_paths, format!("{typ}-x25519-dh"))?; + store_key(&aes128ctr_key, ack_key_path, format!("{typ}-ack-key"))?; + + Ok(()) + } + + async fn initialise_client_gateway_storage( + storage_path: &Path, + registration: &GatewayRegistration, + ) -> Result<(), ExitGatewayError> { + // insert all required information into the gateways store + // (I hate that we have to do it, but that's currently the simplest thing to do) + let storage = setup_fs_gateways_storage(storage_path).await?; + store_gateway_details(&storage, registration).await?; + set_active_gateway(&storage, ®istration.gateway_id().to_base58_string()).await?; + Ok(()) + } + + pub async fn initialise_network_requester<R: RngCore + CryptoRng>( + rng: &mut R, + config: &ExitGatewayConfig, + registration: &GatewayRegistration, + ) -> Result<(), ExitGatewayError> { + trace!("initialising network requester keys"); + Self::initialise_client_keys( + rng, + "network-requester", + config + .storage_paths + .network_requester + .ed25519_identity_storage_paths(), + config + .storage_paths + .network_requester + .x25519_diffie_hellman_storage_paths(), + &config.storage_paths.network_requester.ack_key_file, + )?; + Self::initialise_client_gateway_storage( + &config.storage_paths.network_requester.gateway_registrations, + registration, + ) + .await + } + + pub async fn initialise_ip_packet_router_requester<R: RngCore + CryptoRng>( + rng: &mut R, + config: &ExitGatewayConfig, + registration: &GatewayRegistration, + ) -> Result<(), ExitGatewayError> { + trace!("initialising ip packet router keys"); + Self::initialise_client_keys( + rng, + "ip-packet-router", + config + .storage_paths + .ip_packet_router + .ed25519_identity_storage_paths(), + config + .storage_paths + .ip_packet_router + .x25519_diffie_hellman_storage_paths(), + &config.storage_paths.ip_packet_router.ack_key_file, + )?; + Self::initialise_client_gateway_storage( + &config.storage_paths.ip_packet_router.gateway_registrations, + registration, + ) + .await + } + + pub async fn initialise( + config: &ExitGatewayConfig, + public_key: ed25519::PublicKey, + ) -> Result<(), ExitGatewayError> { + // generate all the keys for NR and IPR + let mut rng = OsRng; + + let gateway_details = GatewayDetails::Custom(CustomGatewayDetails::new(public_key)).into(); + + // NR: + Self::initialise_network_requester(&mut rng, config, &gateway_details).await?; + + // IPR: + Self::initialise_ip_packet_router_requester(&mut rng, config, &gateway_details).await?; + + Ok(()) + } + + fn new(config: &ExitGatewayConfig) -> Result<ExitGatewayData, ExitGatewayError> { + let nr_paths = &config.storage_paths.network_requester; + let nr_ed25519 = load_key( + &nr_paths.public_ed25519_identity_key_file, + "network requester ed25519", + )?; + + let nr_x25519 = load_key( + &nr_paths.public_x25519_diffie_hellman_key_file, + "network requester x25519", + )?; + + let ipr_paths = &config.storage_paths.ip_packet_router; + let ipr_ed25519 = load_key( + &ipr_paths.public_ed25519_identity_key_file, + "ip packet router ed25519", + )?; + + let ipr_x25519 = load_key( + &ipr_paths.public_x25519_diffie_hellman_key_file, + "ip packet router x25519", + )?; + + Ok(ExitGatewayData { + nr_ed25519, + nr_x25519, + ipr_ed25519, + ipr_x25519, + }) + } +} + +pub(crate) struct NymNode { + config: Config, + description: NodeDescription, + + // TODO: currently we're only making measurements in 'mixnode' mode; this should be changed + verloc_stats: SharedVerlocStats, + + #[allow(dead_code)] + mixnode: MixnodeData, + + entry_gateway: EntryGatewayData, + + #[allow(dead_code)] + exit_gateway: ExitGatewayData, + + ed25519_identity_keys: Arc<ed25519::KeyPair>, + x25519_sphinx_keys: Arc<x25519::KeyPair>, + + // to be used when noise is integrated + #[allow(dead_code)] + x25519_noise_keys: Arc<x25519::KeyPair>, +} + +impl NymNode { + pub(crate) async fn initialise( + config: &Config, + custom_mnemonic: Option<Zeroizing<bip39::Mnemonic>>, + ) -> Result<(), NymNodeError> { + debug!("initialising nym-node with id: {}", config.id); + let mut rng = OsRng; + + // global initialisation + let ed25519_identity_keys = ed25519::KeyPair::new(&mut rng); + let x25519_sphinx_keys = x25519::KeyPair::new(&mut rng); + let x25519_noise_keys = x25519::KeyPair::new(&mut rng); + + trace!("attempting to store ed25519 identity keypair"); + store_ed25519_identity_keypair( + &ed25519_identity_keys, + config.storage_paths.keys.ed25519_identity_storage_paths(), + )?; + + trace!("attempting to store x25519 sphinx keypair"); + store_x25519_sphinx_keypair( + &x25519_sphinx_keys, + config.storage_paths.keys.x25519_sphinx_storage_paths(), + )?; + + trace!("attempting to store x25519 noise keypair"); + store_x25519_noise_keypair( + &x25519_noise_keys, + config.storage_paths.keys.x25519_noise_storage_paths(), + )?; + + trace!("creating description file"); + save_node_description( + &config.storage_paths.description, + &NodeDescription::default(), + )?; + + // mixnode initialisation + MixnodeData::initialise(&config.mixnode)?; + + // entry gateway initialisation + EntryGatewayData::initialise(&config.entry_gateway, custom_mnemonic)?; + + // exit gateway initialisation + ExitGatewayData::initialise(&config.exit_gateway, *ed25519_identity_keys.public_key()) + .await?; + + config.save() + } + + pub(crate) async fn new(config: Config) -> Result<Self, NymNodeError> { + Ok(NymNode { + ed25519_identity_keys: Arc::new(load_ed25519_identity_keypair( + config.storage_paths.keys.ed25519_identity_storage_paths(), + )?), + x25519_sphinx_keys: Arc::new(load_x25519_sphinx_keypair( + config.storage_paths.keys.x25519_sphinx_storage_paths(), + )?), + x25519_noise_keys: Arc::new(load_x25519_noise_keypair( + config.storage_paths.keys.x25519_noise_storage_paths(), + )?), + description: load_node_description(&config.storage_paths.description)?, + verloc_stats: Default::default(), + mixnode: MixnodeData::new(&config.mixnode)?, + entry_gateway: EntryGatewayData::new(&config.entry_gateway).await?, + exit_gateway: ExitGatewayData::new(&config.exit_gateway)?, + config, + }) + } + + fn exit_network_requester_address(&self) -> Recipient { + Recipient::new( + self.exit_gateway.nr_ed25519, + self.exit_gateway.nr_x25519, + *self.ed25519_identity_keys.public_key(), + ) + } + + fn exit_ip_packet_router_address(&self) -> Recipient { + Recipient::new( + self.exit_gateway.ipr_ed25519, + self.exit_gateway.ipr_x25519, + *self.ed25519_identity_keys.public_key(), + ) + } + + pub(crate) fn display_details(&self) -> DisplayDetails { + DisplayDetails { + current_mode: self.config.mode, + description: self.description.clone(), + ed25519_identity_key: self.ed25519_identity_key().to_base58_string(), + x25519_sphinx_key: self.x25519_sphinx_key().to_base58_string(), + x25519_noise_key: self.x25519_noise_key().to_base58_string(), + exit_network_requester_address: self.exit_network_requester_address().to_string(), + exit_ip_packet_router_address: self.exit_ip_packet_router_address().to_string(), + } + } + + pub(crate) fn mode(&self) -> NodeMode { + self.config.mode + } + + pub(crate) fn ed25519_identity_key(&self) -> &ed25519::PublicKey { + self.ed25519_identity_keys.public_key() + } + + pub(crate) fn x25519_sphinx_key(&self) -> &x25519::PublicKey { + self.x25519_sphinx_keys.public_key() + } + + pub(crate) fn x25519_noise_key(&self) -> &x25519::PublicKey { + self.x25519_noise_keys.public_key() + } + + fn start_mixnode(&self, task_client: TaskClient) -> Result<(), NymNodeError> { + info!("going to start the nym-node in MIXNODE mode"); + + let config = ephemeral_mixnode_config(self.config.clone())?; + let mut mixnode = MixNode::new_loaded( + config, + Default::default(), + self.ed25519_identity_keys.clone(), + self.x25519_sphinx_keys.clone(), + ); + mixnode.disable_http_server(); + mixnode.set_task_client(task_client); + mixnode.set_mixing_stats(self.mixnode.mixing_stats.clone()); + mixnode.set_verloc_stats(self.verloc_stats.clone()); + + tokio::spawn(async move { + if let Err(err) = mixnode.run().await { + error!("the mixnode subtask has failed with the following message: {err}") + } + }); + Ok(()) + } + + fn start_entry_gateway(&self, task_client: TaskClient) -> Result<(), NymNodeError> { + info!("going to start the nym-node in ENTRY GATEWAY mode"); + + let config = + ephemeral_entry_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?; + let mut entry_gateway = Gateway::new_loaded( + config, + None, + None, + self.ed25519_identity_keys.clone(), + self.x25519_sphinx_keys.clone(), + self.entry_gateway.client_storage.clone(), + ); + entry_gateway.disable_http_server(); + entry_gateway.set_task_client(task_client); + entry_gateway.set_wireguard_client_registry(self.entry_gateway.client_registry.clone()); + + tokio::spawn(async move { + if let Err(err) = entry_gateway.run().await { + error!("the entry gateway subtask has failed with the following message: {err}") + } + }); + Ok(()) + } + + fn start_exit_gateway(&self, task_client: TaskClient) -> Result<(), NymNodeError> { + info!("going to start the nym-node in EXIT GATEWAY mode"); + + let config = + ephemeral_exit_gateway_config(self.config.clone(), &self.entry_gateway.mnemonic)?; + + let mut exit_gateway = Gateway::new_loaded( + config.gateway, + Some(config.nr_opts), + Some(config.ipr_opts), + self.ed25519_identity_keys.clone(), + self.x25519_sphinx_keys.clone(), + self.entry_gateway.client_storage.clone(), + ); + exit_gateway.disable_http_server(); + exit_gateway.set_task_client(task_client); + exit_gateway.set_wireguard_client_registry(self.entry_gateway.client_registry.clone()); + + tokio::spawn(async move { + if let Err(err) = exit_gateway.run().await { + error!("the exit gateway subtask has failed with the following message: {err}") + } + }); + Ok(()) + } + + pub(crate) fn build_http_server(&self) -> Result<NymNodeHTTPServer, NymNodeError> { + let host_details = sign_host_details( + &self.config, + self.x25519_sphinx_keys.public_key(), + self.x25519_noise_keys.public_key(), + &self.ed25519_identity_keys, + )?; + + // mixnode info + let mixnode_details = api_requests::v1::mixnode::models::Mixnode {}; + + // entry gateway info + let wireguard = if self.config.wireguard.enabled { + Some(api_requests::v1::gateway::models::Wireguard { + port: self.config.wireguard.announced_port, + public_key: "placeholder key value".to_string(), + }) + } else { + None + }; + let mixnet_websockets = Some(api_requests::v1::gateway::models::WebSockets { + ws_port: self + .config + .entry_gateway + .announce_ws_port + .unwrap_or(self.config.entry_gateway.bind_address.port()), + wss_port: self.config.entry_gateway.announce_wss_port, + }); + let gateway_details = api_requests::v1::gateway::models::Gateway { + client_interfaces: api_requests::v1::gateway::models::ClientInterfaces { + wireguard, + mixnet_websockets, + }, + }; + + // exit gateway info + let nr_details = api_requests::v1::network_requester::models::NetworkRequester { + encoded_identity_key: self.exit_gateway.nr_ed25519.to_base58_string(), + encoded_x25519_key: self.exit_gateway.nr_x25519.to_base58_string(), + address: self.exit_network_requester_address().to_string(), + }; + + let ipr_details = api_requests::v1::ip_packet_router::models::IpPacketRouter { + encoded_identity_key: self.exit_gateway.ipr_ed25519.to_base58_string(), + encoded_x25519_key: self.exit_gateway.ipr_x25519.to_base58_string(), + address: self.exit_ip_packet_router_address().to_string(), + }; + let exit_policy_details = + api_requests::v1::network_requester::exit_policy::models::UsedExitPolicy { + enabled: true, + upstream_source: self + .config + .exit_gateway + .upstream_exit_policy_url + .to_string(), + last_updated: 0, + // TODO: this will require some refactoring to actually retrieve the data from the embedded providers + policy: None, + }; + + let wireguard_private_network = IpNetwork::new( + self.config.wireguard.private_network_ip, + self.config.wireguard.private_network_prefix, + )?; + + let wg_state = WireguardAppState::new( + self.entry_gateway.client_registry.clone(), + Default::default(), + self.config.wireguard.bind_address.port(), + wireguard_private_network, + )?; + + let mut config = nym_node_http_api::Config::new(bin_info_owned!(), host_details) + .with_landing_page_assets(self.config.http.landing_page_assets_path.as_ref()) + .with_mixnode_details(mixnode_details) + .with_gateway_details(gateway_details) + .with_network_requester_details(nr_details) + .with_ip_packet_router_details(ipr_details) + .with_used_exit_policy(exit_policy_details) + .with_description(self.description.clone()); + + if self.config.http.expose_system_info { + config = config.with_system_info(get_system_info( + self.config.http.expose_system_hardware, + self.config.http.expose_crypto_hardware, + )) + } + match self.config.mode { + NodeMode::Mixnode => config.api.v1_config.node.roles.mixnode_enabled = true, + NodeMode::EntryGateway => config.api.v1_config.node.roles.gateway_enabled = true, + NodeMode::ExitGateway => { + config.api.v1_config.node.roles.gateway_enabled = true; + config.api.v1_config.node.roles.network_requester_enabled = true; + config.api.v1_config.node.roles.ip_packet_router_enabled = true; + } + } + + let app_state = AppState::new() + .with_mixing_stats(self.mixnode.mixing_stats.clone()) + .with_verloc_stats(self.verloc_stats.clone()) + .with_metrics_key(self.config.http.access_token.clone()); + + Ok(NymNodeRouter::new(config, Some(app_state), Some(wg_state)) + .build_server(&self.config.http.bind_address)?) + } + + pub(crate) async fn run(self) -> Result<(), NymNodeError> { + let mut task_manager = TaskManager::default().named("NymNode"); + let http_server = self + .build_http_server()? + .with_task_client(task_manager.subscribe_named("http-server")); + tokio::spawn(async move { http_server.run().await }); + + match self.config.mode { + NodeMode::Mixnode => { + self.start_mixnode(task_manager.subscribe_named("mixnode"))?; + let _ = task_manager.catch_interrupt().await; + Ok(()) + } + NodeMode::EntryGateway => { + self.start_entry_gateway(task_manager.subscribe_named("entry-gateway"))?; + let _ = task_manager.catch_interrupt().await; + Ok(()) + } + NodeMode::ExitGateway => { + self.start_exit_gateway(task_manager.subscribe_named("exit-gateway"))?; + let _ = task_manager.catch_interrupt().await; + Ok(()) + } + } + } +} diff --git a/nym-node/src/wireguard/types.rs b/nym-node/src/wireguard/types.rs index e5eb607115..00ddb7a663 100644 --- a/nym-node/src/wireguard/types.rs +++ b/nym-node/src/wireguard/types.rs @@ -1,5 +1,5 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -pub use nym_node_requests::api::v1::gateway::client_interfaces::wireguard::models::*; -pub use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations}; +// pub use nym_node_requests::api::v1::gateway::client_interfaces::wireguard::models::*; +// pub use nym_wireguard_types::registration::{GatewayClientRegistry, PendingRegistrations}; diff --git a/nym-outfox/Cargo.toml b/nym-outfox/Cargo.toml index bfcd49c233..aad048d9b8 100644 --- a/nym-outfox/Cargo.toml +++ b/nym-outfox/Cargo.toml @@ -13,7 +13,7 @@ repository = { workspace = true } rayon = "1.5.1" blake3 = "1.3" zeroize = "1.5" -chacha20 = "0.9.0" +chacha20 = { version = "0.9.0", features = ["std"] } curve25519-dalek = "3.2" chacha20poly1305 = "0.10.1" getrandom = { workspace = true, features = ["js"] } diff --git a/nym-validator-rewarder/Cargo.toml b/nym-validator-rewarder/Cargo.toml index 0e7d2f6309..7100f87fb8 100644 --- a/nym-validator-rewarder/Cargo.toml +++ b/nym-validator-rewarder/Cargo.toml @@ -28,7 +28,7 @@ zeroize.workspace = true serde_with = "3.4.0" sha2 = "0.10.8" humantime = "2.1.0" -humantime-serde = "1.0" +humantime-serde.workspace = true # internal nym-bin-common = { path = "../common/bin-common", features = ["output_format"] } diff --git a/nym-wallet/Cargo.lock b/nym-wallet/Cargo.lock index c93b176e63..9573b2af63 100644 --- a/nym-wallet/Cargo.lock +++ b/nym-wallet/Cargo.lock @@ -1276,6 +1276,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0f32d04922c60427da6f9fef14d042d9edddef64cb9d4ce0d64d0685fbeb1fd3" dependencies = [ "powerfmt", + "serde", ] [[package]] @@ -3010,7 +3011,6 @@ dependencies = [ name = "nym-bin-common" version = "0.6.0" dependencies = [ - "atty", "clap", "clap_complete", "clap_complete_fig", @@ -3249,6 +3249,8 @@ name = "nym-node-requests" version = "0.1.0" dependencies = [ "base64 0.21.4", + "humantime 2.1.0", + "humantime-serde", "nym-bin-common", "nym-crypto", "nym-exit-policy", @@ -3257,6 +3259,7 @@ dependencies = [ "serde", "serde_json", "thiserror", + "time", ] [[package]] @@ -4879,9 +4882,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" diff --git a/sdk/rust/nym-sdk/src/mixnet/config.rs b/sdk/rust/nym-sdk/src/mixnet/config.rs index 264f857413..159348791a 100644 --- a/sdk/rust/nym-sdk/src/mixnet/config.rs +++ b/sdk/rust/nym-sdk/src/mixnet/config.rs @@ -50,6 +50,7 @@ impl Config { BaseClientConfig::from_client_config( ClientConfig::new( DEFAULT_SDK_CLIENT_ID, + env!("CARGO_PKG_VERSION"), !self.enabled_credentials_mode, nyxd_endpoints, nym_api_endpoints, diff --git a/sdk/rust/nym-sdk/src/mixnet/paths.rs b/sdk/rust/nym-sdk/src/mixnet/paths.rs index 8051b49350..510482678c 100644 --- a/sdk/rust/nym-sdk/src/mixnet/paths.rs +++ b/sdk/rust/nym-sdk/src/mixnet/paths.rs @@ -7,7 +7,7 @@ use nym_client_core::client::base_client::{non_wasm_helpers, storage}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::client::replies::reply_storage::fs_backend; use nym_client_core::config; -use nym_client_core::config::disk_persistence::keys_paths::ClientKeysPaths; +use nym_client_core::config::disk_persistence::ClientKeysPaths; use nym_client_core::config::disk_persistence::CommonClientPaths; use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; use std::path::{Path, PathBuf}; diff --git a/service-providers/ip-packet-router/src/config/mod.rs b/service-providers/ip-packet-router/src/config/mod.rs index 048fcd67f8..1c1e155959 100644 --- a/service-providers/ip-packet-router/src/config/mod.rs +++ b/service-providers/ip-packet-router/src/config/mod.rs @@ -16,7 +16,7 @@ use std::{ }; use url::Url; -use crate::config::persistence::IpPacketRouterPaths; +pub use crate::config::persistence::IpPacketRouterPaths; use self::template::CONFIG_TEMPLATE; diff --git a/service-providers/ip-packet-router/src/error.rs b/service-providers/ip-packet-router/src/error.rs index 2cff116db4..aa859963b2 100644 --- a/service-providers/ip-packet-router/src/error.rs +++ b/service-providers/ip-packet-router/src/error.rs @@ -83,6 +83,9 @@ pub enum IpPacketRouterError { #[error("failed to update client activity")] FailedToUpdateClientActivity, + #[error(transparent)] + ConfigUpgradeFailure(#[from] nym_client_core::config::ConfigUpgradeFailure), + #[error(transparent)] NymIdError(#[from] NymIdError), } diff --git a/service-providers/ip-packet-router/src/ip_packet_router.rs b/service-providers/ip-packet-router/src/ip_packet_router.rs index 85f2ce2f3f..8321cddd35 100644 --- a/service-providers/ip-packet-router/src/ip_packet_router.rs +++ b/service-providers/ip-packet-router/src/ip_packet_router.rs @@ -107,7 +107,13 @@ impl IpPacketRouter { #[cfg(not(target_os = "linux"))] pub async fn run_service_provider(self) -> Result<(), IpPacketRouterError> { - todo!("service provider is not yet supported on this platform") + // for debugging purposes, don't crash in debug builds on non-linux platforms + if cfg!(debug_assertions) { + log::error!("ip packet router service provider is not yet supported on this platform"); + Ok(()) + } else { + todo!("service provider is not yet supported on this platform") + } } #[cfg(target_os = "linux")] diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 98643296b3..98b756c803 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -23,7 +23,7 @@ bs58 = { workspace = true } clap = { workspace = true, features = ["cargo", "derive"]} dirs = "4.0" futures = { workspace = true } -humantime-serde = "1.1.1" +humantime-serde = { workspace = true } ipnetwork = "0.20.0" log = { workspace = true } pretty_env_logger = "0.4.0" diff --git a/service-providers/network-requester/src/cli/mod.rs b/service-providers/network-requester/src/cli/mod.rs index 5cfa1f046a..5184c5820c 100644 --- a/service-providers/network-requester/src/cli/mod.rs +++ b/service-providers/network-requester/src/cli/mod.rs @@ -110,7 +110,7 @@ pub(crate) struct OverrideConfig { statistics_recipient: Option<String>, } -// NOTE: make sure this is in sync with `gateway/src/commands/helpers.rs::override_network_requester_config` +// NOTE: make sure this is in sync with `gateway/src/helpers.rs::override_network_requester_config` pub(crate) fn override_config(mut config: Config, args: OverrideConfig) -> Config { // as of 12.09.23 the below is true (not sure how this comment will rot in the future) // medium_toggle: diff --git a/service-providers/network-requester/src/config/mod.rs b/service-providers/network-requester/src/config/mod.rs index 27b0d70739..fdb2d72944 100644 --- a/service-providers/network-requester/src/config/mod.rs +++ b/service-providers/network-requester/src/config/mod.rs @@ -1,7 +1,6 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::config::persistence::NetworkRequesterPaths; use crate::config::template::CONFIG_TEMPLATE; use nym_bin_common::logging::LoggingSettings; use nym_client_core::cli_helpers::CliClientConfig; @@ -21,6 +20,7 @@ use std::str::FromStr; use std::time::Duration; use url::Url; +pub use crate::config::persistence::NetworkRequesterPaths; pub use nym_client_core::config::Config as BaseClientConfig; pub mod helpers; diff --git a/service-providers/network-requester/src/error.rs b/service-providers/network-requester/src/error.rs index 048ca2a5d2..52a3cd8108 100644 --- a/service-providers/network-requester/src/error.rs +++ b/service-providers/network-requester/src/error.rs @@ -70,6 +70,9 @@ pub enum NetworkRequesterError { #[error("can't setup an exit policy without any upstream urls")] NoUpstreamExitPolicy, + #[error(transparent)] + ConfigUpgradeFailure(#[from] nym_client_core::config::ConfigUpgradeFailure), + #[error(transparent)] NymIdError(#[from] NymIdError), } diff --git a/service-providers/network-requester/src/lib.rs b/service-providers/network-requester/src/lib.rs index 457afc99cd..df44f9ffd5 100644 --- a/service-providers/network-requester/src/lib.rs +++ b/service-providers/network-requester/src/lib.rs @@ -16,8 +16,11 @@ pub use nym_client_core::{ base_client::{ non_wasm_helpers::{setup_fs_gateways_storage, setup_fs_reply_surb_backend}, storage::{ - helpers::set_active_gateway, GatewaysDetailsStore, OnDiskGatewaysDetails, - OnDiskPersistent, + gateways_storage::{ + CustomGatewayDetails, GatewayDetails, GatewayRegistration, RemoteGatewayDetails, + }, + helpers::{set_active_gateway, store_gateway_details}, + GatewaysDetailsStore, OnDiskGatewaysDetails, OnDiskPersistent, }, }, key_manager::persistence::OnDiskKeys, diff --git a/tools/nymvisor/Cargo.toml b/tools/nymvisor/Cargo.toml index 7dd7fef743..e7187a5e47 100644 --- a/tools/nymvisor/Cargo.toml +++ b/tools/nymvisor/Cargo.toml @@ -19,7 +19,7 @@ flate2 = "1.0.28" futures = { workspace = true } hex = "0.4.3" humantime = "2.1.0" -humantime-serde = "1.1.1" +humantime-serde = { workspace = true } nix = { version = "0.27.1", features = ["signal", "fs"] } reqwest = { workspace = true, features = ["json", "stream"] } serde = { workspace = true, features = ["derive"] } From bfa029f2843d4852e5a748a914cdfcebe93dc0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Sat, 6 Apr 2024 09:54:53 +0200 Subject: [PATCH 354/394] Use client-core default db names in sdk (#4524) --- sdk/rust/nym-sdk/src/mixnet/paths.rs | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/sdk/rust/nym-sdk/src/mixnet/paths.rs b/sdk/rust/nym-sdk/src/mixnet/paths.rs index 510482678c..4c7dcee6cd 100644 --- a/sdk/rust/nym-sdk/src/mixnet/paths.rs +++ b/sdk/rust/nym-sdk/src/mixnet/paths.rs @@ -7,8 +7,13 @@ use nym_client_core::client::base_client::{non_wasm_helpers, storage}; use nym_client_core::client::key_manager::persistence::OnDiskKeys; use nym_client_core::client::replies::reply_storage::fs_backend; use nym_client_core::config; -use nym_client_core::config::disk_persistence::ClientKeysPaths; use nym_client_core::config::disk_persistence::CommonClientPaths; +use nym_client_core::config::disk_persistence::{ + ClientKeysPaths, DEFAULT_ACK_KEY_FILENAME, DEFAULT_CREDENTIALS_DB_FILENAME, + DEFAULT_GATEWAYS_DETAILS_DB_FILENAME, DEFAULT_PRIVATE_ENCRYPTION_KEY_FILENAME, + DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME, DEFAULT_PUBLIC_ENCRYPTION_KEY_FILENAME, + DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME, DEFAULT_REPLY_SURB_DB_FILENAME, +}; use nym_credential_storage::persistent_storage::PersistentStorage as PersistentCredentialStorage; use std::path::{Path, PathBuf}; @@ -55,14 +60,14 @@ impl StoragePaths { } Ok(Self { - private_identity: dir.join("private_identity.pem"), - public_identity: dir.join("public_identity.pem"), - private_encryption: dir.join("private_encryption.pem"), - public_encryption: dir.join("public_encryption.pem"), - ack_key: dir.join("ack_key.pem"), - credential_database_path: dir.join("db.sqlite"), - reply_surb_database_path: dir.join("persistent_reply_store.sqlite"), - gateway_registrations: dir.join("gateways_registrations.sqlite"), + private_identity: dir.join(DEFAULT_PRIVATE_IDENTITY_KEY_FILENAME), + public_identity: dir.join(DEFAULT_PUBLIC_IDENTITY_KEY_FILENAME), + private_encryption: dir.join(DEFAULT_PRIVATE_ENCRYPTION_KEY_FILENAME), + public_encryption: dir.join(DEFAULT_PUBLIC_ENCRYPTION_KEY_FILENAME), + ack_key: dir.join(DEFAULT_ACK_KEY_FILENAME), + credential_database_path: dir.join(DEFAULT_CREDENTIALS_DB_FILENAME), + reply_surb_database_path: dir.join(DEFAULT_REPLY_SURB_DB_FILENAME), + gateway_registrations: dir.join(DEFAULT_GATEWAYS_DETAILS_DB_FILENAME), }) } From bb372fb35c7432802466593b250db82420170302 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 8 Apr 2024 08:28:10 +0000 Subject: [PATCH 355/394] Bump eyre from 0.6.11 to 0.6.12 in /sdk/ffi/shared Bumps [eyre](https://github.com/eyre-rs/eyre) from 0.6.11 to 0.6.12. - [Commits](https://github.com/eyre-rs/eyre/commits) --- updated-dependencies: - dependency-name: eyre dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/shared/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/shared/Cargo.lock b/sdk/ffi/shared/Cargo.lock index b2f9caeb0c..da0f86606a 100644 --- a/sdk/ffi/shared/Cargo.lock +++ b/sdk/ffi/shared/Cargo.lock @@ -1424,9 +1424,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", From ac7b82178212d87e0bd9af0ec5c237bef4e1449f Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Mon, 8 Apr 2024 09:13:31 +0000 Subject: [PATCH 356/394] [DOC]: Feature: cmdrun scripts (#4514) * initialise cmdrun script dir * initialise api_targets_config * initialise api_targets * first version of argparser cli * create a token api stats table * add format function * initiate nym_vpn command * add github to get api url * add github api to config * create nym_vpn releases dataframe * menu headers tweak --- documentation/dev-portal/src/SUMMARY.md | 1 + documentation/docs/src/SUMMARY.md | 5 +- documentation/operators/src/SUMMARY.md | 6 + documentation/scripts/cmdrun/README.md | 3 + documentation/scripts/cmdrun/api_targets.py | 182 ++++++++++++++++++ .../scripts/cmdrun/api_targets_config.json | 6 + 6 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 documentation/scripts/cmdrun/README.md create mode 100644 documentation/scripts/cmdrun/api_targets.py create mode 100644 documentation/scripts/cmdrun/api_targets_config.json diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index 8a0db815c4..dff2f67b6e 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -1,3 +1,4 @@ +# # Summary - [Introduction](introduction.md) diff --git a/documentation/docs/src/SUMMARY.md b/documentation/docs/src/SUMMARY.md index a4875d9217..9ae4e3aa87 100644 --- a/documentation/docs/src/SUMMARY.md +++ b/documentation/docs/src/SUMMARY.md @@ -1,3 +1,4 @@ +# # Summary [Introduction](introduction.md) @@ -14,7 +15,7 @@ <!-- - [Version Compatibility Table](binaries/version-compatiblity.md) --> # Nodes -- [Node Types (Previously Setup Guides)](nodes/overview.md) +- [Node Types (Previously Setup Guides)](nodes/overview.md) - [Mix Node](nodes/mixnode.md) - [Gateway](nodes/gateway.md) - [Network Requester](nodes/network-requester.md) @@ -56,7 +57,7 @@ - [Mixnet Explorer](explorers/mixnet-explorer.md) # Nyx Blockchain -- [Interacting with Nyx Chain and Smart Contracts](nyx/interacting-with-chain.md) +- [Interacting with Nyx Chain and Smart Contracts](nyx/interacting-with-chain.md) - [Smart Contracts](nyx/smart-contracts.md) - [Mixnet Contract](nyx/mixnet-contract.md) - [Vesting Contract](nyx/vesting-contract.md) diff --git a/documentation/operators/src/SUMMARY.md b/documentation/operators/src/SUMMARY.md index 669fd2a42d..c7167fe898 100644 --- a/documentation/operators/src/SUMMARY.md +++ b/documentation/operators/src/SUMMARY.md @@ -1,3 +1,4 @@ +# # Summary - [Introduction](introduction.md) @@ -28,6 +29,11 @@ - [ExploreNYM scripts](testing/explorenym-scripts.md) <!-- - [Run in a Docker](testing/docker-monitor.md) --> - [Troubleshooting](nodes/troubleshooting.md) +<!-- + - [Nym Nodes]() + - [Validators] + - [Binary] +--> # Token Economics diff --git a/documentation/scripts/cmdrun/README.md b/documentation/scripts/cmdrun/README.md new file mode 100644 index 0000000000..faa809357b --- /dev/null +++ b/documentation/scripts/cmdrun/README.md @@ -0,0 +1,3 @@ +# cmdrun scripts + +A place for all scripts used for `mdbook-cmdrun` to auto-fill the pages with up todate info, syntax and command outputs. diff --git a/documentation/scripts/cmdrun/api_targets.py b/documentation/scripts/cmdrun/api_targets.py new file mode 100644 index 0000000000..6bd1fca0dd --- /dev/null +++ b/documentation/scripts/cmdrun/api_targets.py @@ -0,0 +1,182 @@ +import argparse +import os +import requests +import json +import sys +import pandas as pd +from collections import namedtuple + +############################################ +############## GENERAL FNs ################# +############################################ + +def get_url(args): + config_file = "./api_targets_config.json" + with open(config_file, "r") as f: + config = json.load(f) + env = args.api + endpoint = args.endpoint + if env == "github": + url = f"{config[env]}/{endpoint}" + else: + url = f"{config[env]}/api/v1/{endpoint}" + return url + +def subparser_read(args): + url = get_url(args) + r = requests.get(url) + response = r.json() + return response + +############################################ +########### NYX RELATED FNs ################ +############################################ + +def convert_u_nym(unym): + unym = int(unym) + nym = unym / 1000000 + nym = int(nym) + return nym + +def thousand_separator(n): + n = f'{n:_}' + return n + +def remove_underscore(arg): + string = arg.replace("_", " ") + string = string.title() + return string + +def display_supply_table(response, args): + df = pd.DataFrame(response) + df = df.T + del df['denom'] +# df.set_axis(['**Item**', '**Amount in NYM**'], axis=1, inplace=True) + df = df.rename_axis('index1').reset_index() + df = df.rename(columns={'index1': '**Item**', 'amount': '**Amount in NYM**'}) + df['**Item**'] = df['**Item**'].apply(remove_underscore) + df['**Amount in NYM**'] = df['**Amount in NYM**'].apply(convert_u_nym) + df['**Amount in NYM**'] = df['**Amount in NYM**'].apply(thousand_separator) + table = df.to_markdown(index=False) + print(table) + +def read_supply(args): + response = subparser_read(args) + if args.endpoint == "circulating-supply": + if args.format: + display_supply_table(response, args) + else: + print(response) + elif args.endpoint == "foo": + # placeholder for other endpoint args + pass + else: + # placeholder for other endpoint args + pass + +########################################### +############ GH RELATED FNs ############### +########################################### + +def get_nym_vpn_version(args): + response = subparser_read(args) + if args.client == "desktop": + version = current_desktop_version(args, response) + elif args.client == "cli": + version = current_cli_version(args, response) + else: + print("Incorrect argument for -c, --client") + sys.exit(-1) + +def current_cli_version(args, response): + df = pd.DataFrame(response) + print(df) + + # NEEDS THIS IN PYTHON: + # current_cli_version=$(curl -s $release_url | jq -r '.[].tag_name' | grep '^nym-vpn-cli-v' | sort -Vr | head -n 1 | awk -F'-v' '{print $NF}') + + +def current_desktop_version(args, response): + # NEEDS THIS IN PYTHON: + df = pd.DataFrame(response) + print(df) + # version=$(curl -s $release_url | jq -r '.[].tag_name' | grep '^nym-vpn-desktop-v' | sort -Vr | head -n 1 | awk -F'-v' '{print $NF}') + + +########################################### +############### MAIN PARSER ############### +########################################### + +def parser_main(): + parser = argparse.ArgumentParser( + prog="Nym API scraper", + description='''Get any live data from Nyx validator''', + epilog='' + ) + subparsers = parser.add_subparsers(help="") + parser_supply = subparsers.add_parser('supply', + help='reads API on supply', + aliases=['s','S'] + ) + + parser_supply.add_argument( + "-a","--api", + type=str, + default="mainnet", + help="choose: mainnet, perf, sandbox" + ) + parser_supply.add_argument( + "-e","--endpoint", + type=str, + help="choose from: https://validator.nymtech.net/api/swagger/index.html" + ) + parser_supply.add_argument( + "-f","--format", + action="store_true", + help="format the output for documentation purpose (.md) - default: False (raw output)", + ) + + parser_supply.set_defaults(func=read_supply) + + + parser_nym_vpn = subparsers.add_parser('nym_vpn', + help='reads NymVPN latest version', + aliases=['n','N'] + ) + + parser_nym_vpn.add_argument( + "-c","--client", + type=str, + default="desktop", + help="choose: desktop, cli - default: desktop" + ) + + parser_nym_vpn.add_argument( + "-a","--api", + type=str, + default="github", + help="choose: mainnet, perf, sandbox" + ) + + parser_nym_vpn.add_argument( + "-e","--endpoint", + type=str, + help="add the url suffix", + default="repos/nymtech/nym-vpn-client/releases" + ) + + + parser_nym_vpn.set_defaults(func=get_nym_vpn_version) + + args = parser.parse_args() + try: + args.func(args) + except AttributeError as e: + print("Error on argparser") + sys.exit(-1) + + + + +if __name__ == "__main__": + parser_main() diff --git a/documentation/scripts/cmdrun/api_targets_config.json b/documentation/scripts/cmdrun/api_targets_config.json new file mode 100644 index 0000000000..fd5d8b6939 --- /dev/null +++ b/documentation/scripts/cmdrun/api_targets_config.json @@ -0,0 +1,6 @@ +{ + "sandbox": "https://sandbox-nym-api1.nymtech.net", + "perf": "https://api.performance.nymte.ch", + "mainnet": "https://validator.nymtech.net", + "github": "https://api.github.com" +} From 9e3bd8588d7b22610bc2394256f0cd001c13fd14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 8 Apr 2024 16:05:12 +0200 Subject: [PATCH 357/394] Re-export TransmissionLane type (#4525) --- sdk/rust/nym-sdk/src/mixnet.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index c89229fb28..575a273fd0 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -77,6 +77,7 @@ pub use nym_sphinx::{ anonymous_replies::requests::AnonymousSenderTag, receiver::ReconstructedMessage, }; +pub use nym_task::connections::TransmissionLane; pub use nym_topology::{provider_trait::TopologyProvider, NymTopology}; pub use paths::StoragePaths; pub use socks5_client::Socks5MixnetClient; From 30ffea19a1721a9638fba5d7cf09ee982757338d Mon Sep 17 00:00:00 2001 From: Sachin Kamath <github@skamath.me> Date: Tue, 9 Apr 2024 13:34:24 +0530 Subject: [PATCH 358/394] docs: add credential signing steps for nym-api (#4523) * docs: add credential signing steps for nym-api * review comments --- documentation/operators/src/nodes/nym-api.md | 73 +++++++++++++++++--- 1 file changed, 64 insertions(+), 9 deletions(-) diff --git a/documentation/operators/src/nodes/nym-api.md b/documentation/operators/src/nodes/nym-api.md index 3753d2e80c..bce06b8981 100644 --- a/documentation/operators/src/nodes/nym-api.md +++ b/documentation/operators/src/nodes/nym-api.md @@ -7,7 +7,7 @@ ## What is the Nym API? The Nym API is a binary that will be operated by the Nyx validator set. This binary can be run in several different modes, and has two main bits of functionality: * network monitoring (calculating the routing score of Mixnet nodes) -* generation and validation of [zk-Nyms](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a), our implementation of the Coconut Selective Disclosure Credential Scheme. +* generation and validation of [zk-nyms](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a), our implementation of the Coconut Selective Disclosure Credential Scheme. This is important for both the proper decentralisation of the network uptime calculation and, more pressingly, enabling the NymVPN to utilise privacy preserving payments. @@ -77,18 +77,18 @@ pruning-interval = "100" The example value of `100` for `pruning-interval` can be customised as per your requirement. -### (Coming Soon) Credential Generation -Validators that take part in the DKG ceremony will become part of the 'quorum' generating and verifying zk-Nym credentials. These will initially be used for private proof of payment for NymVPN (see our blogposts [here](https://blog.nymtech.net/nymvpn-an-invitation-for-privacy-experts-and-enthusiasts-63644139d09d) and [here](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a) for more on this), and in the future will be expanded into more general usecases such as [offline ecash](https://arxiv.org/abs/2303.08221). +### Credential Generation +Validators that take part in the DKG ceremony will become part of the 'quorum' generating and verifying zk-nym credentials. These will initially be used for private proof of payment for NymVPN (see our blogposts [here](https://blog.nymtech.net/nymvpn-an-invitation-for-privacy-experts-and-enthusiasts-63644139d09d) and [here](https://blog.nymtech.net/zk-nyms-are-here-a-major-milestone-towards-a-market-ready-mixnet-a3470c9ab10a) for more on this), and in the future will be expanded into more general usecases such as [offline ecash](https://arxiv.org/abs/2303.08221). -The DKG ceremony will be used to create a subset of existing validators - referred to as the quorum. As outlined above, they will be the ones taking part in the generation and verification of zk-Nym credentials. The size of the 'minimum viable quorum' is 10 - we are aiming for a larger number than this for the initial quorum in order to have some redundancy in the case of a Validator dropping or going offline. +The DKG ceremony will be used to create a subset of existing validators who run `nym-api` alongside a Nyx full-node. As outlined above, they will be the ones taking part in the generation and verification of zk-nym credentials. The size of the 'minimum viable quorum' is 10 - we are aiming for a larger number than this for the initial quorum in order to have some redundancy in the case of a validator dropping or going offline. We will be releasing more detailed step-by-step documentation for involved validators nearer to the ceremony itself, but at a high level it will involve: * the deployment and initialisation of [`group`](https://github.com/nymtech/nym/tree/develop/contracts/multisig/cw4-group) and [`multisig`](https://github.com/nymtech/nym/tree/develop/contracts/multisig) contracts by Nym. Validators that are members of the `group` contract are the only ones that will be able to take part in the ceremony. * the deployment and initialisation of an instance of the [DKG contract](https://github.com/nymtech/nym/tree/develop/contracts/coconut-dkg) by Nym. * Validators will update their `nym-api` configs with the address of the deployed contracts. They will also stop running their API instance in caching only mode, instead switching over run with the `--enabled-credentials-mode`. -* From the perspective of operators, this is all they have to do. Under the hood, each `nym-api` instance will then take part in several rounds of key submission, verification, and derivation. This will continue until quorum is acheived. More information on this will be released closer to the time of the ceremony. +* From the perspective of operators, this is all they have to do. Under the hood, each `nym-api` instance will then take part in several rounds of key submission, verification, and derivation. This will continue until quorum is acheived. -**We will be communicating individually with members of the existing Validator set who have expressed interest in joining the quorum concerning the timing and specifics of the ceremony**. +**We will be communicating individually with members of the existing validator set who have expressed interest in joining the quorum concerning the timing and specifics of the ceremony**. ## Current version ``` @@ -117,7 +117,7 @@ You can also check the various arguments required for individual commands with: ./nym-api <COMMAND> --help ``` -### Initialising your Nym API Instance +### Initialising your Nym API Instance in caching mode Initialise your API instance with: ``` @@ -126,17 +126,70 @@ Initialise your API instance with: You can optionally pass a local identifier for this instance with the `--id` flag. Otherwise the ID of your instance defaults to `default`. +### Enabling credential signing on your Nym API instance + +To engage in the Distributed Key Generation (DKG) ceremony, it's essential to transition your `nym-api` instance from its default caching mode to the active credential signing mode. This section guides you through the process of enabling credential signing + +#### Generate a new wallet + +Begin by generating a new wallet address specifically for your instance to use in credential signing mode. Utilize the `nyxd` command-line tool with the following command: + +``` +nyxd keys add signer +``` + +~~~admonish warning title="Backup your keys!" +It's critical to securely back up the mnemonic phrase generated during this process. This mnemonic is your key to recovering the wallet in the future, so store it in a secure, offline location. +~~~ + +#### Fund the address + +Next, deposit NYM tokens into the newly created wallet address to ensure it can cover transaction fees incurred during the credential signing process. `nym-api` will not operate if the wallet's balance falls below 10 NYM tokens, displaying an error message upon startup. + +We recommand beginning with an initial deposit of 100 NYM tokens and monitoring the balance regularly, topping it up as necessary to maintain operational readiness. + +#### Update API configuration + +With your new wallet ready and funded, proceed to update your `nym-api` configuration to enable credential signing: + +Update your `config.toml` located in `<HOME_DIR>/.nym/nym-api/foo/config/config.toml` as below: + +Enable the coconut signer: + +``` +[coconut_signer] +# Specifies whether coconut signing protocol is enabled in this process. +enabled = true # This was previously false +``` + +Set your announce address if it is empty. This is the URL you previously configured for your `nym-api` instance + +``` +# This is the address you previously configured for the nym-api +# Not to be confused with the Cosmos REST API URL +announce_address = 'https://nym-api.your.tld/' +``` + +Finally, input the mnemonic phrase generated during the wallet creation step into the mnemonic field + +``` +mnemonic = '<YOUR_MNEMONIC_HERE>' +``` + +After completing these steps, your `nym-api` instance is configured to participate in credential signing and the DKG ceremony. + + ### Running your Nym API Instance The API binary currently defaults to running in caching mode. You can run your API with: ``` -./nym-api run +./nym-api run --id <YOUR_ID> ``` By default the API will be trying to query your full node running locally on `localhost:26657`. If your node is hosted elsewhere, you can specify the RPC location by using the `--nyxd-validator ` flag on `run`: ``` -./nym-api run --nyxd-validator https://rpc-nym.yourcorp.tld:443 +./nym-api run --id <YOUR_ID> --nyxd-validator https://rpc-nym.yourcorp.tld:443 ``` > You can also change the value of `local_validator` in the config file found by default in `$HOME/.nym/nym-api/<ID>/config/config.toml`. @@ -226,6 +279,8 @@ Starting nym api... ## Automation You will most likely want to automate your validator restarting if your server reboots. Checkout the [maintenance page](./maintenance.md) for an example `service` file. +You can also use `nymvisor` to automatically update the `nym-api` node. The steps to install Nymvisor can be found [here](nymvisor-upgrade.md). + ## Exposing web endpoint using HTTPS It is recommended to expose the webserver over HTTPS by using a webserver like Nginx. An example configuration for configuring Nginx is listed [on the maintenance page](maintenance.md#nym-api-configuration). If you're using a custom solution, ensure to allow requests from anywhere by setting a permissive CORS policy. From 69c1a323921470976dae1b52db7a3810d870d176 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 9 Apr 2024 16:16:39 +0100 Subject: [PATCH 359/394] error prefix --- nym-api/src/node_describe_cache/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nym-api/src/node_describe_cache/mod.rs b/nym-api/src/node_describe_cache/mod.rs index ded2fa7454..3754e5fa7a 100644 --- a/nym-api/src/node_describe_cache/mod.rs +++ b/nym-api/src/node_describe_cache/mod.rs @@ -224,7 +224,7 @@ impl CacheItemProvider for NodeDescriptionProvider { match res { Ok((identity, description)) => Some((identity, description)), Err(err) => { - debug!("{err}"); + debug!("failed to obtain gateway self-described data: {err}"); None } } From 0ed43d2439b469ff3a99a3a4fd1121ba2b58dbd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 9 Apr 2024 16:17:39 +0100 Subject: [PATCH 360/394] allow nym-api to understand signatures on legacy host information --- Cargo.lock | 1 + nym-node/nym-node-requests/Cargo.toml | 3 + nym-node/nym-node-requests/src/api/mod.rs | 95 ++++++++++++++++++- .../src/api/v1/node/models.rs | 32 +++++++ 4 files changed, 129 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 3e44825198..023def4b50 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6247,6 +6247,7 @@ dependencies = [ "nym-exit-policy", "nym-http-api-client", "nym-wireguard-types", + "rand_chacha 0.2.2", "schemars", "serde", "serde_json", diff --git a/nym-node/nym-node-requests/Cargo.toml b/nym-node/nym-node-requests/Cargo.toml index e8fc8c089b..1708e12293 100644 --- a/nym-node/nym-node-requests/Cargo.toml +++ b/nym-node/nym-node-requests/Cargo.toml @@ -36,6 +36,9 @@ nym-bin-common = { path = "../../common/bin-common", features = ["bin_info_schem [dev-dependencies] tokio = { workspace = true, features = ["full"] } +rand_chacha = "0.2" +nym-crypto = { path = "../../common/crypto", features = ["rand"] } + [features] default = ["client"] diff --git a/nym-node/nym-node-requests/src/api/mod.rs b/nym-node/nym-node-requests/src/api/mod.rs index 180685e284..3c57d9d75a 100644 --- a/nym-node/nym-node-requests/src/api/mod.rs +++ b/nym-node/nym-node-requests/src/api/mod.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 -use crate::api::v1::node::models::HostInformation; +use crate::api::v1::node::models::{HostInformation, LegacyHostInformation}; use crate::error::Error; use nym_crypto::asymmetric::identity; use schemars::JsonSchema; @@ -61,7 +61,16 @@ impl SignedHostInformation { return false; }; - self.verify(&pub_key) + if self.verify(&pub_key) { + return true; + } + + // attempt to verify legacy signature + SignedData { + data: LegacyHostInformation::from(self.data.clone()), + signature: self.signature.clone(), + } + .verify(&pub_key) } } @@ -84,3 +93,85 @@ impl Display for ErrorResponse { self.message.fmt(f) } } + +#[cfg(test)] +mod tests { + use super::*; + use nym_crypto::asymmetric::{ed25519, x25519}; + use rand_chacha::rand_core::SeedableRng; + use std::net::IpAddr; + + #[derive(Serialize, Deserialize)] + struct LegacyHostInformation { + pub ip_address: Vec<IpAddr>, + pub hostname: Option<String>, + pub keys: LegacyKeys, + } + + #[derive(Serialize, Deserialize)] + struct LegacyKeys { + pub ed25519: String, + pub x25519: String, + } + + #[test] + fn dummy_signed_host_verification() { + let mut rng = rand_chacha::ChaCha20Rng::from_seed([0u8; 32]); + let ed22519 = ed25519::KeyPair::new(&mut rng); + let x25519_sphinx = x25519::KeyPair::new(&mut rng); + + let host_info = crate::api::v1::node::models::HostInformation { + ip_address: vec!["1.1.1.1".parse().unwrap()], + hostname: Some("foomp.com".to_string()), + keys: crate::api::v1::node::models::HostKeys { + ed25519_identity: ed22519.public_key().to_base58_string(), + x25519_sphinx: x25519_sphinx.public_key().to_base58_string(), + x25519_noise: "".to_string(), + }, + }; + + let signed_info = SignedHostInformation::new(host_info, ed22519.private_key()).unwrap(); + assert!(signed_info.verify(ed22519.public_key())); + assert!(signed_info.verify_host_information()) + } + + #[test] + fn dummy_legacy_signed_host_verification() { + let mut rng = rand_chacha::ChaCha20Rng::from_seed([0u8; 32]); + let ed22519 = ed25519::KeyPair::new(&mut rng); + let x25519_sphinx = x25519::KeyPair::new(&mut rng); + + let legacy_info = crate::api::v1::node::models::LegacyHostInformation { + ip_address: vec!["1.1.1.1".parse().unwrap()], + hostname: Some("foomp.com".to_string()), + keys: crate::api::v1::node::models::LegacyHostKeys { + ed25519: ed22519.public_key().to_base58_string(), + x25519: x25519_sphinx.public_key().to_base58_string(), + }, + }; + + let host_info = crate::api::v1::node::models::HostInformation { + ip_address: legacy_info.ip_address.clone(), + hostname: legacy_info.hostname.clone(), + keys: crate::api::v1::node::models::HostKeys { + ed25519_identity: legacy_info.keys.ed25519.clone(), + x25519_sphinx: legacy_info.keys.x25519.clone(), + x25519_noise: "".to_string(), + }, + }; + + // signature on legacy data + let signature = SignedData::new(legacy_info, ed22519.private_key()) + .unwrap() + .signature; + + // signed blob with the 'current' structure + let current_struct = SignedData { + data: host_info, + signature, + }; + + assert!(!current_struct.verify(ed22519.public_key())); + assert!(current_struct.verify_host_information()) + } +} diff --git a/nym-node/nym-node-requests/src/api/v1/node/models.rs b/nym-node/nym-node-requests/src/api/v1/node/models.rs index 66ca13d99d..1101d1fbb1 100644 --- a/nym-node/nym-node-requests/src/api/v1/node/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/node/models.rs @@ -32,6 +32,23 @@ pub struct HostInformation { pub keys: HostKeys, } +#[derive(Serialize)] +pub struct LegacyHostInformation { + pub ip_address: Vec<IpAddr>, + pub hostname: Option<String>, + pub keys: LegacyHostKeys, +} + +impl From<HostInformation> for LegacyHostInformation { + fn from(value: HostInformation) -> Self { + LegacyHostInformation { + ip_address: value.ip_address, + hostname: value.hostname, + keys: value.keys.into(), + } + } +} + #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct HostKeys { @@ -49,6 +66,21 @@ pub struct HostKeys { pub x25519_noise: String, } +impl From<HostKeys> for LegacyHostKeys { + fn from(value: HostKeys) -> Self { + LegacyHostKeys { + ed25519: value.ed25519_identity, + x25519: value.x25519_sphinx, + } + } +} + +#[derive(Serialize)] +pub struct LegacyHostKeys { + pub ed25519: String, + pub x25519: String, +} + #[derive(Clone, Default, Debug, Serialize, Deserialize, JsonSchema)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct HostSystem { From 78fb3c22932f75071edf629b94d15ded47072b19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 9 Apr 2024 16:26:54 +0100 Subject: [PATCH 361/394] run http api by default --- gateway/src/node/mod.rs | 4 ++-- mixnode/src/node/mod.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 08af357093..53607a3dfb 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -150,7 +150,7 @@ impl<St> Gateway<St> { network_requester_opts, ip_packet_router_opts, client_registry: Arc::new(DashMap::new()), - run_http_server: false, + run_http_server: true, task_client: None, }) } @@ -171,7 +171,7 @@ impl<St> Gateway<St> { sphinx_keypair, storage, client_registry: Arc::new(DashMap::new()), - run_http_server: false, + run_http_server: true, task_client: None, } } diff --git a/mixnode/src/node/mod.rs b/mixnode/src/node/mod.rs index 8674d6ffe0..0043113658 100644 --- a/mixnode/src/node/mod.rs +++ b/mixnode/src/node/mod.rs @@ -46,7 +46,7 @@ pub struct MixNode { impl MixNode { pub fn new(config: Config) -> Result<Self, MixnodeError> { Ok(MixNode { - run_http_server: false, + run_http_server: true, descriptor: Self::load_node_description(&config), identity_keypair: Arc::new(load_identity_keys(&config)?), sphinx_keypair: Arc::new(load_sphinx_keys(&config)?), @@ -64,7 +64,7 @@ impl MixNode { sphinx_keypair: Arc<encryption::KeyPair>, ) -> Self { MixNode { - run_http_server: false, + run_http_server: true, task_client: None, config, descriptor, From 7885d3c986916f243d192ea10425a06bc640cd88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 9 Apr 2024 16:18:44 +0100 Subject: [PATCH 362/394] removed dead code removed dead code --- nym-node/nym-node-requests/src/api/mod.rs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/nym-node/nym-node-requests/src/api/mod.rs b/nym-node/nym-node-requests/src/api/mod.rs index 3c57d9d75a..7a6c61b436 100644 --- a/nym-node/nym-node-requests/src/api/mod.rs +++ b/nym-node/nym-node-requests/src/api/mod.rs @@ -99,20 +99,6 @@ mod tests { use super::*; use nym_crypto::asymmetric::{ed25519, x25519}; use rand_chacha::rand_core::SeedableRng; - use std::net::IpAddr; - - #[derive(Serialize, Deserialize)] - struct LegacyHostInformation { - pub ip_address: Vec<IpAddr>, - pub hostname: Option<String>, - pub keys: LegacyKeys, - } - - #[derive(Serialize, Deserialize)] - struct LegacyKeys { - pub ed25519: String, - pub x25519: String, - } #[test] fn dummy_signed_host_verification() { From 229561bab9577559c33f495f88e0035762b5cf82 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Tue, 9 Apr 2024 17:47:30 +0200 Subject: [PATCH 363/394] update sandbox .env (#4530) --- envs/sandbox.env | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/envs/sandbox.env b/envs/sandbox.env index f121bb8ec9..9171474253 100644 --- a/envs/sandbox.env +++ b/envs/sandbox.env @@ -13,10 +13,10 @@ DENOMS_EXPONENT=6 REWARDING_VALIDATOR_ADDRESS=n1pefc2utwpy5w78p2kqdsfmpjxfwmn9d39k5mqa MIXNET_CONTRACT_ADDRESS=n1xr3rq8yvd7qplsw5yx90ftsr2zdhg4e9z60h5duusgxpv72hud3sjkxkav VESTING_CONTRACT_ADDRESS=n1unyuj8qnmygvzuex3dwmg9yzt9alhvyeat0uu0jedg2wj33efl5qackslz -COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n13902g92xfefeyzuyed49snlm5fxv5ms6mdq5kvrut27hasdw5a9q9vyw6c -GROUP_CONTRACT_ADDRESS=n18nczmqw6adwxg2wnlef3hf0etf8anccafp2pjpul5rrtmv96umyq5mv7t5 -MULTISIG_CONTRACT_ADDRESS=n1q3zzxl78rlmxv3vn0uf4vkyz285lk8q2xzne299yt9x6mpfgk90qukuzmv -COCONUT_DKG_CONTRACT_ADDRESS=n1jsz20ggp5a6v76j060erkzvxmeus8htlpl77yxp878f0gf95cyaq6p2pee +COCONUT_BANDWIDTH_CONTRACT_ADDRESS=n1ljlwey4xdj0zs7zueepc48nkr033fca6fjgvurfvttqegm8dvsrswsul70 +GROUP_CONTRACT_ADDRESS=n10v3rjnq4cjyccfykyams68ztce337gksuu6f0lvtl4meuwvkewaqru4uav +MULTISIG_CONTRACT_ADDRESS=n1cemnu8as0ls45v3caunpesl8jlsfw2ff9rlwnltlecp7zrxct4dsqc2y42 +COCONUT_DKG_CONTRACT_ADDRESS=n1zx96qgd88vqlzcxkpwzks7kqs5ctrx36xtzfc58p7q6c4ng9anlqzc4nh8 NAME_SERVICE_CONTRACT_ADDRESS=n12ne7qtmdwd0j03t9t5es8md66wq4e5xg9neladrsag8fx3y89rcs36asfp SERVICE_PROVIDER_DIRECTORY_CONTRACT_ADDRESS=n1ps5yutd7sufwg058qd7ac7ldnlazsvmhzqwucsfxmm445d70u8asqxpur4 EPHEMERA_CONTRACT_ADDRESS=n19lc9u84cz0yz3fww5283nucc9yvr8gsjmgeul0 From 5581b15094589b716ebf4a6d59e00ede2b707bd5 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 08:34:13 +0000 Subject: [PATCH 364/394] Bump eyre from 0.6.11 to 0.6.12 in /sdk/ffi/go Bumps [eyre](https://github.com/eyre-rs/eyre) from 0.6.11 to 0.6.12. - [Commits](https://github.com/eyre-rs/eyre/commits) --- updated-dependencies: - dependency-name: eyre dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/go/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/go/Cargo.lock b/sdk/ffi/go/Cargo.lock index 186df3b324..bc3723fa8b 100644 --- a/sdk/ffi/go/Cargo.lock +++ b/sdk/ffi/go/Cargo.lock @@ -1424,9 +1424,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", From 035faf70e4db0ae8e8dd12efe507e88f9fc55889 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 10 Apr 2024 09:02:46 +0000 Subject: [PATCH 365/394] Bump eyre from 0.6.11 to 0.6.12 in /sdk/ffi/cpp Bumps [eyre](https://github.com/eyre-rs/eyre) from 0.6.11 to 0.6.12. - [Commits](https://github.com/eyre-rs/eyre/commits) --- updated-dependencies: - dependency-name: eyre dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- sdk/ffi/cpp/Cargo.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sdk/ffi/cpp/Cargo.lock b/sdk/ffi/cpp/Cargo.lock index ca9506e337..743400d030 100644 --- a/sdk/ffi/cpp/Cargo.lock +++ b/sdk/ffi/cpp/Cargo.lock @@ -1424,9 +1424,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "eyre" -version = "0.6.11" +version = "0.6.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6267a1fa6f59179ea4afc8e50fd8612a3cc60bc858f786ff877a4a8cb042799" +checksum = "7cd915d99f24784cdc19fd37ef22b97e3ff0ae756c7e492e9fbfe897d61e2aec" dependencies = [ "indenter", "once_cell", From 8c59106add84c753dcc7da0825ec88e95479235c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 11 Apr 2024 08:28:42 +0100 Subject: [PATCH 366/394] introduced /api-status routes for nym-api (#4527) * introduced /api-status routes for nym-api * added additional information to the signer-information endpoint --- nym-api/nym-api-requests/src/models.rs | 38 ++++++++++++++++++ nym-api/src/coconut/keys/mod.rs | 8 ++++ nym-api/src/main.rs | 1 + nym-api/src/status/mod.rs | 53 ++++++++++++++++++++++++++ nym-api/src/status/routes.rs | 52 +++++++++++++++++++++++++ nym-api/src/support/http/mod.rs | 30 ++++++++++++--- 6 files changed, 176 insertions(+), 6 deletions(-) create mode 100644 nym-api/src/status/mod.rs create mode 100644 nym-api/src/status/routes.rs diff --git a/nym-api/nym-api-requests/src/models.rs b/nym-api/nym-api-requests/src/models.rs index 142a607e5a..2d04caef74 100644 --- a/nym-api/nym-api-requests/src/models.rs +++ b/nym-api/nym-api-requests/src/models.rs @@ -402,3 +402,41 @@ pub struct IpPacketRouterDetails { /// address of the embedded ip packet router pub address: String, } + +#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema)] +pub struct ApiHealthResponse { + pub status: ApiStatus, + pub uptime: u64, +} + +#[derive(Clone, Copy, Debug, Serialize, Deserialize, schemars::JsonSchema)] +#[serde(rename_all = "lowercase")] +pub enum ApiStatus { + Up, +} + +impl ApiHealthResponse { + pub fn new_healthy(uptime: Duration) -> Self { + ApiHealthResponse { + status: ApiStatus::Up, + uptime: uptime.as_secs(), + } + } +} + +impl ApiStatus { + pub fn is_up(&self) -> bool { + matches!(self, ApiStatus::Up) + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] +pub struct SignerInformationResponse { + pub cosmos_address: String, + + pub identity: String, + + pub announce_address: String, + + pub verification_key: Option<String>, +} diff --git a/nym-api/src/coconut/keys/mod.rs b/nym-api/src/coconut/keys/mod.rs index 7c719c7a53..1902d9e180 100644 --- a/nym-api/src/coconut/keys/mod.rs +++ b/nym-api/src/coconut/keys/mod.rs @@ -1,6 +1,7 @@ // Copyright 2022-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use nym_coconut::VerificationKey; use nym_coconut_dkg_common::types::EpochId; use nym_dkg::Scalar; use std::sync::atomic::{AtomicBool, Ordering}; @@ -63,6 +64,13 @@ impl KeyPair { } } + pub async fn verification_key(&self) -> Option<RwLockReadGuard<'_, VerificationKey>> { + RwLockReadGuard::try_map(self.get().await?, |maybe_keypair| { + maybe_keypair.as_ref().map(|k| k.keys.verification_key()) + }) + .ok() + } + pub async fn read_keys(&self) -> RwLockReadGuard<'_, Option<KeyPairWithEpoch>> { self.keys.read().await } diff --git a/nym-api/src/main.rs b/nym-api/src/main.rs index 8feba3a48d..f9243660b7 100644 --- a/nym-api/src/main.rs +++ b/nym-api/src/main.rs @@ -38,6 +38,7 @@ pub(crate) mod node_describe_cache; pub(crate) mod node_status_api; pub(crate) mod nym_contract_cache; pub(crate) mod nym_nodes; +mod status; pub(crate) mod support; struct ShutdownHandles { diff --git a/nym-api/src/status/mod.rs b/nym-api/src/status/mod.rs new file mode 100644 index 0000000000..1a88a9ab33 --- /dev/null +++ b/nym-api/src/status/mod.rs @@ -0,0 +1,53 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::coconut; +use nym_bin_common::bin_info; +use nym_bin_common::build_information::BinaryBuildInformation; +use okapi::openapi3::OpenApi; +use rocket::Route; +use rocket_okapi::openapi_get_routes_spec; +use rocket_okapi::settings::OpenApiSettings; +use tokio::time::Instant; + +pub(crate) mod routes; + +pub(crate) struct ApiStatusState { + startup_time: Instant, + build_information: BinaryBuildInformation, + signer_information: Option<SignerState>, +} + +pub(crate) struct SignerState { + // static information + pub cosmos_address: String, + + pub identity: String, + + pub announce_address: String, + + pub(crate) coconut_keypair: coconut::keys::KeyPair, +} + +impl ApiStatusState { + pub fn new() -> Self { + ApiStatusState { + startup_time: Instant::now(), + build_information: bin_info!(), + signer_information: None, + } + } + + pub fn add_zk_nym_signer(&mut self, signer_information: SignerState) { + self.signer_information = Some(signer_information) + } +} + +pub(crate) fn api_status_routes(settings: &OpenApiSettings) -> (Vec<Route>, OpenApi) { + openapi_get_routes_spec![ + settings: + routes::health, + routes::build_information, + routes::signer_information + ] +} diff --git a/nym-api/src/status/routes.rs b/nym-api/src/status/routes.rs new file mode 100644 index 0000000000..614785eeba --- /dev/null +++ b/nym-api/src/status/routes.rs @@ -0,0 +1,52 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node_status_api::models::ErrorResponse; +use crate::status::ApiStatusState; +use nym_api_requests::models::{ApiHealthResponse, SignerInformationResponse}; +use nym_bin_common::build_information::BinaryBuildInformationOwned; +use nym_coconut::Base58; +use rocket::http::Status; +use rocket::serde::json::Json; +use rocket::State; +use rocket_okapi::openapi; + +#[openapi(tag = "Api Status")] +#[get("/health")] +pub(crate) async fn health(state: &State<ApiStatusState>) -> Json<ApiHealthResponse> { + let uptime = state.startup_time.elapsed(); + let health = ApiHealthResponse::new_healthy(uptime); + Json(health) +} + +#[openapi(tag = "Api Status")] +#[get("/build-information")] +pub(crate) async fn build_information( + state: &State<ApiStatusState>, +) -> Json<BinaryBuildInformationOwned> { + Json(state.build_information.to_owned()) +} + +#[openapi(tag = "Api Status")] +#[get("/signer-information")] +pub(crate) async fn signer_information( + state: &State<ApiStatusState>, +) -> Result<Json<SignerInformationResponse>, ErrorResponse> { + let signer_state = state.signer_information.as_ref().ok_or_else(|| { + ErrorResponse::new( + "this api does not expose zk-nym signing functionalities", + Status::InternalServerError, + ) + })?; + + Ok(Json(SignerInformationResponse { + cosmos_address: signer_state.cosmos_address.clone(), + identity: signer_state.identity.clone(), + announce_address: signer_state.announce_address.clone(), + verification_key: signer_state + .coconut_keypair + .verification_key() + .await + .map(|maybe_vk| maybe_vk.to_bs58()), + })) +} diff --git a/nym-api/src/support/http/mod.rs b/nym-api/src/support/http/mod.rs index 1ca67c50bb..9bf7d9b6aa 100644 --- a/nym-api/src/support/http/mod.rs +++ b/nym-api/src/support/http/mod.rs @@ -9,6 +9,7 @@ use crate::network::network_routes; use crate::node_describe_cache::DescribedNodes; use crate::node_status_api::{self, NodeStatusCache}; use crate::nym_contract_cache::cache::NymContractCache; +use crate::status::{api_status_routes, ApiStatusState, SignerState}; use crate::support::caching::cache::SharedCache; use crate::support::config::Config; use crate::support::{nyxd, storage}; @@ -27,7 +28,7 @@ pub(crate) mod openapi; pub(crate) async fn setup_rocket( config: &Config, network_details: NetworkDetails, - _nyxd_client: nyxd::Client, + nyxd_client: nyxd::Client, identity_keypair: identity::KeyPair, coconut_keypair: coconut::keys::KeyPair, ) -> anyhow::Result<Rocket<Ignite>> { @@ -45,6 +46,7 @@ pub(crate) async fn setup_rocket( "" => nym_contract_cache::nym_contract_cache_routes(&openapi_settings), "/status" => node_status_api::node_status_routes(&openapi_settings, config.network_monitor.enabled), "/network" => network_routes(&openapi_settings), + "/api-status" => api_status_routes(&openapi_settings), "" => nym_node_routes(&openapi_settings), } @@ -68,18 +70,34 @@ pub(crate) async fn setup_rocket( None }; + let mut status_state = ApiStatusState::new(); + let rocket = if config.coconut_signer.enabled { // make sure we have some tokens to cover multisig fees - let balance = _nyxd_client.balance(&mix_denom).await?; + let balance = nyxd_client.balance(&mix_denom).await?; if balance.amount < coconut::MINIMUM_BALANCE { - let address = _nyxd_client.address().await; + let address = nyxd_client.address().await; let min = Coin::new(coconut::MINIMUM_BALANCE, mix_denom); bail!("the account ({address}) doesn't have enough funds to cover verification fees. it has {balance} while it needs at least {min}") } - let comm_channel = QueryCommunicationChannel::new(_nyxd_client.clone()); + let cosmos_address = nyxd_client.address().await.to_string(); + let announce_address = config + .coconut_signer + .announce_address + .clone() + .map(|u| u.to_string()) + .unwrap_or_default(); + status_state.add_zk_nym_signer(SignerState { + cosmos_address, + identity: identity_keypair.public_key().to_base58_string(), + announce_address, + coconut_keypair: coconut_keypair.clone(), + }); + + let comm_channel = QueryCommunicationChannel::new(nyxd_client.clone()); rocket.attach(coconut::stage( - _nyxd_client.clone(), + nyxd_client.clone(), mix_denom, identity_keypair, coconut_keypair, @@ -97,7 +115,7 @@ pub(crate) async fn setup_rocket( rocket }; - Ok(rocket.ignite().await?) + Ok(rocket.manage(status_state).ignite().await?) } fn setup_cors() -> Result<Cors> { From 210269cb9c946bed494428d76403636949f3adc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 11 Apr 2024 09:11:46 +0100 Subject: [PATCH 367/394] [bugfix] restore old serialisation of 'NymNodeDescription' (#4533) --- common/topology/src/gateway.rs | 4 +- nym-api/nym-api-requests/src/models.rs | 52 +++++++++++++++++++++++++- nym-api/src/node_describe_cache/mod.rs | 4 +- 3 files changed, 54 insertions(+), 6 deletions(-) diff --git a/common/topology/src/gateway.rs b/common/topology/src/gateway.rs index 60624796c6..e8b61eedf6 100644 --- a/common/topology/src/gateway.rs +++ b/common/topology/src/gateway.rs @@ -205,10 +205,10 @@ impl<'a> TryFrom<&'a DescribedGateway> for Node { clients_ws_port: self_described.mixnet_websockets.ws_port, clients_wss_port: self_described.mixnet_websockets.wss_port, identity_key: identity::PublicKey::from_base58_string( - &self_described.host_information.keys.ed25519_identity, + &self_described.host_information.keys.ed25519, )?, sphinx_key: encryption::PublicKey::from_base58_string( - &self_described.host_information.keys.x25519_sphinx, + &self_described.host_information.keys.x25519, )?, version: self_described .build_information diff --git a/nym-api/nym-api-requests/src/models.rs b/nym-api/nym-api-requests/src/models.rs index 2d04caef74..72bfbb3a7d 100644 --- a/nym-api/nym-api-requests/src/models.rs +++ b/nym-api/nym-api-requests/src/models.rs @@ -9,11 +9,11 @@ use nym_mixnet_contract_common::rewarding::RewardEstimate; use nym_mixnet_contract_common::{ GatewayBond, IdentityKey, Interval, MixId, MixNode, Percent, RewardedSetNodeStatus, }; -use nym_node_requests::api::v1::gateway::models::WebSockets; -use nym_node_requests::api::v1::node::models::{BinaryBuildInformationOwned, HostInformation}; +use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; +use std::net::IpAddr; use std::{fmt, time::Duration}; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] @@ -356,6 +356,54 @@ pub struct CirculatingSupplyResponse { pub circulating_supply: Coin, } +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] +pub struct HostInformation { + pub ip_address: Vec<IpAddr>, + pub hostname: Option<String>, + pub keys: HostKeys, +} + +impl From<nym_node_requests::api::v1::node::models::HostInformation> for HostInformation { + fn from(value: nym_node_requests::api::v1::node::models::HostInformation) -> Self { + HostInformation { + ip_address: value.ip_address, + hostname: value.hostname, + keys: value.keys.into(), + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] +pub struct HostKeys { + pub ed25519: String, + pub x25519: String, +} + +impl From<nym_node_requests::api::v1::node::models::HostKeys> for HostKeys { + fn from(value: nym_node_requests::api::v1::node::models::HostKeys) -> Self { + HostKeys { + ed25519: value.ed25519_identity, + x25519: value.x25519_sphinx, + } + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] +pub struct WebSockets { + pub ws_port: u16, + + pub wss_port: Option<u16>, +} + +impl From<nym_node_requests::api::v1::gateway::models::WebSockets> for WebSockets { + fn from(value: nym_node_requests::api::v1::gateway::models::WebSockets) -> Self { + WebSockets { + ws_port: value.ws_port, + wss_port: value.wss_port, + } + } +} + #[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] pub struct NymNodeDescription { pub host_information: HostInformation, diff --git a/nym-api/src/node_describe_cache/mod.rs b/nym-api/src/node_describe_cache/mod.rs index 3754e5fa7a..9abf0ffc60 100644 --- a/nym-api/src/node_describe_cache/mod.rs +++ b/nym-api/src/node_describe_cache/mod.rs @@ -181,11 +181,11 @@ async fn get_gateway_description( }; let description = NymNodeDescription { - host_information: host_info.data, + host_information: host_info.data.into(), build_information: build_info, network_requester, ip_packet_router, - mixnet_websockets: websockets, + mixnet_websockets: websockets.into(), }; Ok((gateway.identity_key, description)) From 5dcad5ffd4fdb07a5cf48724a1f0c44da13bd4f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 11 Apr 2024 10:25:04 +0100 Subject: [PATCH 368/394] [bugfix] make sure localnet script works in post nym-node era --- nym-node/src/cli/commands/run/mod.rs | 11 ++++++----- scripts/build_topology.py | 29 ++++++++++++++-------------- scripts/localnet_start.sh | 16 +++++++-------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/nym-node/src/cli/commands/run/mod.rs b/nym-node/src/cli/commands/run/mod.rs index 74d4d369a8..45e13c62a0 100644 --- a/nym-node/src/cli/commands/run/mod.rs +++ b/nym-node/src/cli/commands/run/mod.rs @@ -18,6 +18,7 @@ pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> { let config_path = args.config.config_path(); let output = args.output; let bonding_info_path = args.bonding_information_output.clone(); + let init_only = args.init_only; let config = if !config_path.exists() { debug!("no configuration file found at '{}'", config_path.display()); @@ -25,16 +26,11 @@ pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> { if args.deny_init { return Err(NymNodeError::ForbiddenInitialisation { config_path }); } - let init_only = args.init_only; let maybe_custom_mnemonic = args.take_mnemonic(); let config = args.build_config()?; NymNode::initialise(&config, maybe_custom_mnemonic).await?; - if init_only { - debug!("returning due to the 'init-only' flag"); - return Ok(()); - } config } else { @@ -73,5 +69,10 @@ pub(crate) async fn execute(mut args: Args) -> Result<(), NymNodeError> { })?; } + if init_only { + debug!("returning due to the 'init-only' flag"); + return Ok(()); + } + nym_node.run().await } diff --git a/scripts/build_topology.py b/scripts/build_topology.py index 14ec7b7d54..5673e0922e 100644 --- a/scripts/build_topology.py +++ b/scripts/build_topology.py @@ -3,30 +3,31 @@ import os.path import sys -def add_mixnode(base_network, base_dir, mix_id): +def add_mixnode(base_network, base_dir, mix_id, port_delta): with open(os.path.join(base_dir, "mix" + str(mix_id) + ".json"), "r") as json_blob: mix_data = json.load(json_blob) + base_network["mixnodes"][str(mix_id)][0]["identity_key"] = mix_data["identity_key"] base_network["mixnodes"][str(mix_id)][0]["sphinx_key"] = mix_data["sphinx_key"] - base_network["mixnodes"][str(mix_id)][0]["mix_port"] = mix_data["mix_port"] + base_network["mixnodes"][str(mix_id)][0]["mix_port"] = 10000 + port_delta base_network["mixnodes"][str(mix_id)][0]["version"] = mix_data["version"] - base_network["mixnodes"][str(mix_id)][0]["host"] = mix_data["bind_address"] - base_network["mixnodes"][str(mix_id)][0]["layer"] = mix_id + base_network["mixnodes"][str(mix_id)][0]["host"] = "127.0.0.1" + base_network["mixnodes"][str(mix_id)][0]["layer"] = mix_id % 3 + 1 base_network["mixnodes"][str(mix_id)][0]["mix_id"] = mix_id - base_network["mixnodes"][str(mix_id)][0]["owner"] = "whatever" + base_network["mixnodes"][str(mix_id)][0]["owner"] = "n1jw6mp7d5xqc7w6xm79lha27glmd0vdt3l9artf" return base_network -def add_gateway(base_network, base_dir): +def add_gateway(base_network, base_dir, port_delta): with open(os.path.join(base_dir, "gateway.json"), "r") as json_blob: gateway_data = json.load(json_blob) base_network["gateways"][0]["identity_key"] = gateway_data["identity_key"] base_network["gateways"][0]["sphinx_key"] = gateway_data["sphinx_key"] - base_network["gateways"][0]["mix_port"] = gateway_data["mix_port"] - base_network["gateways"][0]["clients_port"] = gateway_data["clients_port"] + base_network["gateways"][0]["mix_port"] = 10000 + port_delta + base_network["gateways"][0]["clients_port"] = 9000 # base_network["gateways"][0]["version"] = gateway_data["version"] - base_network["gateways"][0]["host"] = gateway_data["bind_address"] - base_network["gateways"][0]["owner"] = "whatever" + base_network["gateways"][0]["host"] = "127.0.0.1" + base_network["gateways"][0]["owner"] = "n1jw6mp7d5xqc7w6xm79lha27glmd0vdt3l9artf" return base_network @@ -41,10 +42,10 @@ def main(args): } base_dir = args[0] - base_network = add_mixnode(base_network, base_dir, 1) - base_network = add_mixnode(base_network, base_dir, 2) - base_network = add_mixnode(base_network, base_dir, 3) - base_network = add_gateway(base_network, base_dir) + base_network = add_mixnode(base_network, base_dir, 1, 1) + base_network = add_mixnode(base_network, base_dir, 2, 2) + base_network = add_mixnode(base_network, base_dir, 3, 3) + base_network = add_gateway(base_network, base_dir, 4) with open(os.path.join(base_dir, "network.json"), "w") as out: json.dump(base_network, out, indent=2) diff --git a/scripts/localnet_start.sh b/scripts/localnet_start.sh index d9ffad9356..56ca9a42af 100755 --- a/scripts/localnet_start.sh +++ b/scripts/localnet_start.sh @@ -20,16 +20,16 @@ echo "Using $localnetdir for the localnet" # initialise mixnet echo "initialising mixnode1..." -cargo run --release --bin nym-mixnode -- init --id "mix1-$suffix" --host 127.0.0.1 --mix-port 10001 --verloc-port 20001 --http-api-port 30001 --metrics-key=lala --output=json >>"$localnetdir/mix1.json" +cargo run --release --bin nym-node -- run --id "mix1-$suffix" --init-only --mixnet-bind-address=127.0.0.1:10001 --verloc-bind-address 127.0.0.1:20001 --http-bind-address 127.0.0.1:30001 --http-access-token=lala --output=json --bonding-information-output "$localnetdir/mix1.json" echo "initialising mixnode2..." -cargo run --release --bin nym-mixnode -- init --id "mix2-$suffix" --host 127.0.0.1 --mix-port 10002 --verloc-port 20002 --http-api-port 30002 --metrics-key=lala --output=json >>"$localnetdir/mix2.json" +cargo run --release --bin nym-node -- run --id "mix2-$suffix" --init-only --mixnet-bind-address=127.0.0.1:10002 --verloc-bind-address 127.0.0.1:20002 --http-bind-address 127.0.0.1:30002 --http-access-token=lala --output=json --bonding-information-output "$localnetdir/mix2.json" echo "initialising mixnode3..." -cargo run --release --bin nym-mixnode -- init --id "mix3-$suffix" --host 127.0.0.1 --mix-port 10003 --verloc-port 20003 --http-api-port 30003 --metrics-key=lala --output=json >>"$localnetdir/mix3.json" +cargo run --release --bin nym-node -- run --id "mix3-$suffix" --init-only --mixnet-bind-address=127.0.0.1:10003 --verloc-bind-address 127.0.0.1:20003 --http-bind-address 127.0.0.1:30003 --http-access-token=lala --output=json --bonding-information-output "$localnetdir/mix3.json" echo "initialising gateway..." -cargo run --release --bin nym-gateway -- init --id "gateway-$suffix" --host 127.0.0.1 --mix-port 10004 --clients-port 9000 --output=json >>"$localnetdir/gateway.json" +cargo run --release --bin nym-node -- run --id "gateway-$suffix" --init-only --mode entry --mixnet-bind-address=127.0.0.1:10004 --entry-bind-address 127.0.0.1:9000 --verloc-bind-address 127.0.0.1:20004 --http-bind-address 127.0.0.1:30004 --http-access-token=lala --output=json --bonding-information-output "$localnetdir/gateway.json" # build the topology echo "combining json files..." @@ -42,10 +42,10 @@ echo "the full network file is located at $networkfile" echo "starting the mixnet..." tmux start-server -tmux new-session -d -s localnet -n Mixnet -d "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix1-$suffix \"" -tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix2-$suffix \"" -tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-mixnode -- run --id mix3-$suffix \"" -tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-gateway -- run --id gateway-$suffix --local \"" +tmux new-session -d -s localnet -n Mixnet -d "/usr/bin/env sh -c \" cargo run --release --bin nym-node -- run --id mix1-$suffix \"" +tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-node -- run --id mix2-$suffix \"" +tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-node -- run --id mix3-$suffix \"" +tmux split-window -t localnet:0 "/usr/bin/env sh -c \" cargo run --release --bin nym-node -- run --id gateway-$suffix \"" while ! nc -z localhost 9000; do echo "waiting for nym-gateway to launch on port 9000..." From dcd712430e315d2a98262174b78b2e1037e5a5ee Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:51:15 +0000 Subject: [PATCH 369/394] Bump tar from 6.1.15 to 6.2.1 in /wasm/mix-fetch/internal-dev-node Bumps [tar](https://github.com/isaacs/node-tar) from 6.1.15 to 6.2.1. - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v6.1.15...v6.2.1) --- updated-dependencies: - dependency-name: tar dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/mix-fetch/internal-dev-node/package-lock.json | 7 +++---- wasm/mix-fetch/internal-dev-node/yarn.lock | 6 +++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/wasm/mix-fetch/internal-dev-node/package-lock.json b/wasm/mix-fetch/internal-dev-node/package-lock.json index 9ede843aa0..7bdb1add75 100644 --- a/wasm/mix-fetch/internal-dev-node/package-lock.json +++ b/wasm/mix-fetch/internal-dev-node/package-lock.json @@ -1357,10 +1357,9 @@ } }, "node_modules/tar": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz", - "integrity": "sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A==", - "license": "ISC", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", diff --git a/wasm/mix-fetch/internal-dev-node/yarn.lock b/wasm/mix-fetch/internal-dev-node/yarn.lock index c15faf4ccc..0c337ced8f 100644 --- a/wasm/mix-fetch/internal-dev-node/yarn.lock +++ b/wasm/mix-fetch/internal-dev-node/yarn.lock @@ -799,9 +799,9 @@ sync-promise-expanded@^1.0.0: integrity sha512-pdxxEOaeKO6LghTz0Fe7yw82fx95gtS0SxVgRvIwvN4h9qTie8oOF/pWuH8PGp+PVduS84RXXxO/xrW93Nno9w== tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.1.15" - resolved "https://registry.npmjs.org/tar/-/tar-6.1.15.tgz" - integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" From b2477dd81b54a41f52238773287521a1a4a51ea1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 11 Apr 2024 10:51:16 +0000 Subject: [PATCH 370/394] Bump tar from 6.1.15 to 6.2.1 in /wasm/client/internal-dev-node Bumps [tar](https://github.com/isaacs/node-tar) from 6.1.15 to 6.2.1. - [Release notes](https://github.com/isaacs/node-tar/releases) - [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md) - [Commits](https://github.com/isaacs/node-tar/compare/v6.1.15...v6.2.1) --- updated-dependencies: - dependency-name: tar dependency-type: indirect ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/client/internal-dev-node/yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/wasm/client/internal-dev-node/yarn.lock b/wasm/client/internal-dev-node/yarn.lock index 35968ffdf7..0c9690796c 100644 --- a/wasm/client/internal-dev-node/yarn.lock +++ b/wasm/client/internal-dev-node/yarn.lock @@ -765,9 +765,9 @@ sync-promise-expanded@^1.0.0: integrity sha512-pdxxEOaeKO6LghTz0Fe7yw82fx95gtS0SxVgRvIwvN4h9qTie8oOF/pWuH8PGp+PVduS84RXXxO/xrW93Nno9w== tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: - version "6.1.15" - resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" - integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + version "6.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.2.1.tgz#717549c541bc3c2af15751bea94b1dd068d4b03a" + integrity sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A== dependencies: chownr "^2.0.0" fs-minipass "^2.0.0" From f978552a3aa1482f7274c730eb74833a72f10c65 Mon Sep 17 00:00:00 2001 From: import this <97586125+serinko@users.noreply.github.com> Date: Thu, 11 Apr 2024 12:09:58 +0000 Subject: [PATCH 371/394] [DOC]: NymVPN testing Guides update (#4528) * simplify cli - comment redundant pages * unite mac and linux cli guide to one page * finalise cli guide * syntax edit * book built * syntax edit * final version - ready to review * final version - ready to review --- documentation/dev-portal/src/SUMMARY.md | 2 - .../dev-portal/src/nymvpn/cli-linux.md | 45 +++-- documentation/dev-portal/src/nymvpn/cli.bak | 35 ++++ documentation/dev-portal/src/nymvpn/cli.md | 158 +++++++++++++++--- documentation/dev-portal/src/nymvpn/gui.md | 8 +- documentation/dev-portal/src/nymvpn/intro.md | 7 +- .../dev-portal/src/nymvpn/troubleshooting.md | 8 + 7 files changed, 217 insertions(+), 46 deletions(-) create mode 100644 documentation/dev-portal/src/nymvpn/cli.bak diff --git a/documentation/dev-portal/src/SUMMARY.md b/documentation/dev-portal/src/SUMMARY.md index dff2f67b6e..ccf844a279 100644 --- a/documentation/dev-portal/src/SUMMARY.md +++ b/documentation/dev-portal/src/SUMMARY.md @@ -24,8 +24,6 @@ - [Linux](nymvpn/gui-linux.md) - [MacOS](nymvpn/gui-mac.md) - [CLI](nymvpn/cli.md) - - [Linux](nymvpn/cli-linux.md) - - [MacOS](nymvpn/cli-mac.md) - [Troubleshooting](nymvpn/troubleshooting.md) - [NymVPN FAQ](nymvpn/faq.md) - [NymConnect X Monero](tutorials/monero.md) diff --git a/documentation/dev-portal/src/nymvpn/cli-linux.md b/documentation/dev-portal/src/nymvpn/cli-linux.md index 2d4db55778..5d742a5d43 100644 --- a/documentation/dev-portal/src/nymvpn/cli-linux.md +++ b/documentation/dev-portal/src/nymvpn/cli-linux.md @@ -1,4 +1,4 @@ -# NymVPN alpha CLI: Guide for GNU/Linux +# NymVPN alpha CLI Guide ```admonish info NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. @@ -8,7 +8,7 @@ NymVPN is an experimental software and it's for testing purposes only. All users > Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -1. Open Github [releases page]({{nym_vpn_releases}}) and download the binary for Debian based Linux +1. Open Github [releases page]({{nym_vpn_releases}}) and download the CLI latest binary for your system 2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh @@ -25,17 +25,12 @@ tar -xvf <BINARY>.tar.gz # tar -xvf nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_ubuntu-22.04_x86_64.tar.gz ``` -4. Make executable by running: +4. Make executable: ```sh # make sure you are in the right sub-directory chmod u+x ./nym-vpn-cli ``` -5. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: -```sh -curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env -``` - ## Run NymVPN **For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. @@ -47,7 +42,7 @@ Make sure your terminal is open in the same directory as your `nym-vpn-cli` bina ```sh sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WIREGUARD_IP> ``` -3. To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) and pick one +3. To choose different Gateways, visit [explorer.nymtech.net/network-components/gateways](https://explorer.nymtech.net/network-components/gateways) and copy-paste an identity key of your choice 4. See all possibilities in [command explanation](#cli-commands-and-options) section below In case of errors, see [troubleshooting section](troubleshooting.md). @@ -56,16 +51,16 @@ In case of errors, see [troubleshooting section](troubleshooting.md). The basic syntax of `nym-vpn-cli` is: ```sh -sudo ./nym-vpn-cli -c ./sandbox.env --entry-gateway-id <ENTRY_GATEWAY_ID> --exit-router-address <EXIT_ROUTER_ADDRESS> --enable-wireguard --private-key <PRIVATE_KEY> --wg-ip <WG_IP> +sudo ./nym-vpn-cli <--exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY>> ``` -* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) +* To choose different Gateways, visit [nymvpn.com/en/alpha/api/gateways](https://explorer.nymtech.net/network-components/gateways) * To see all possibilities run with `--help` flag: ```sh ./nym-vpn-cli --help ``` ~~~admonish example collapsible=true title="Console output" ```sh -Usage: nym-vpn-cli [OPTIONS] +Usage: nym-vpn-cli [OPTIONS] <--exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY>> Options: -c, --config-env-file <CONFIG_ENV_FILE> @@ -76,11 +71,13 @@ Options: Mixnet public ID of the entry gateway --entry-gateway-country <ENTRY_GATEWAY_COUNTRY> Auto-select entry gateway by country ISO + --entry-gateway-low-latency + Auto-select entry gateway by latency --exit-router-address <EXIT_ROUTER_ADDRESS> Mixnet recipient address --exit-gateway-id <EXIT_GATEWAY_ID> - --exit-router-country <EXIT_ROUTER_COUNTRY> + --exit-gateway-country <EXIT_GATEWAY_COUNTRY> Mixnet recipient address --enable-wireguard Enable the wireguard traffic between the client and the entry gateway @@ -88,8 +85,10 @@ Options: Associated private key --wg-ip <WG_IP> The IP address of the wireguard interface used for the first hop to the entry gateway - --nym-ip <NYM_IP> - The IP address of the nym TUN device that wraps IP packets in sphinx packets + --nym-ipv4 <NYM_IPV4> + The IPv4 address of the nym TUN device that wraps IP packets in sphinx packets + --nym-ipv6 <NYM_IPV6> + The IPv6 address of the nym TUN device that wraps IP packets in sphinx packets --nym-mtu <NYM_MTU> The MTU of the nym TUN device that wraps IP packets in sphinx packets --disable-routing @@ -125,3 +124,19 @@ Here is a list of the options and their descriptions. Some are essential, some a - `--ip` is the IP address of the TUN device. That is the IP address of the local private network that is set up between local client and the Exit Gateway. - `--mtu`: The MTU of the TUN device. That is the max IP packet size of the local private network that is set up between local client and the Exit Gateway. - `--disable-routing`: Disable routing all traffic through the VPN TUN device. + +## Testnet environment + +If you want to run NymVPN CLI in Nym Sandbox environment, there are a few adjustments to be done: + +1. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries by running: +```sh +curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env +``` + +1. Check available Gateways at [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) + +2. Run with a flag `-c` +```sh +sudo ./nym-vpn-cli -c <PATH_TO>/sandbox.env <--exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY>> +``` diff --git a/documentation/dev-portal/src/nymvpn/cli.bak b/documentation/dev-portal/src/nymvpn/cli.bak new file mode 100644 index 0000000000..f040b9cff2 --- /dev/null +++ b/documentation/dev-portal/src/nymvpn/cli.bak @@ -0,0 +1,35 @@ +# NymVPN Command Line Interface (CLI) + +```admonish info +Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future. + +**If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. +``` + +Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). + +Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. + +## Automated Script for CLI Installation + +We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8fb31) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: + +1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run +```sh +curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/d39f98dbb36ccff761a7e940073388a6fe7b73fe/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh +``` + +2. Follow the prompts in the program + +3. The script will automatically start the client. Make sure to **turn off any other VPNs** and follow the prompts: + +* It prints a JSON view of existing Gateways and prompt you to: + - *Make sure to use two different Gateways for entry and exit!* + - `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`) + - `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`) + - `do you want five hop or two hop?`: type `five` or `two` + - `enable WireGuard? (yes/no):` if you chose yes, find your private key and wireguard IP [here](https://nymvpn.com/en/alpha) + +To run `nym-vpn-cli` again, reconnect your wifi, move to the directory of your CLI binary `cd ~/nym-vpn-cli-dir` and follow the guide for [Linux](cli-linux.md#run-nymvpn) or [MacOS](cli-mac.md#run-nymvpn). If you find it too difficult, just run this script again - like in step \#3 above. + +In case of errors check out the [troubleshooting](troubleshooting.md) section. diff --git a/documentation/dev-portal/src/nymvpn/cli.md b/documentation/dev-portal/src/nymvpn/cli.md index f040b9cff2..368ded3a7c 100644 --- a/documentation/dev-portal/src/nymvpn/cli.md +++ b/documentation/dev-portal/src/nymvpn/cli.md @@ -1,35 +1,151 @@ -# NymVPN Command Line Interface (CLI) +# NymVPN alpha CLI Guide ```admonish info -Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future. - -**If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. +NymVPN is an experimental software and it's for testing purposes only. All users testing the client are expected to sign GDPR Information Sheet and Consent Form (shared at the workshop) so we use their results to improve the client, and submit the form [*NymVPN User research*]({{nym_vpn_form_url}}) with the testing results. ``` -Follow the simple [automated script](#automated-script-for-cli-installation) below to install and run NymVPN CLI. If you prefer to do a manual setup follow the steps in the guide for [Linux](cli-linux.md) or [MacOS](cli-mac.md). +## Installation -Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums or download the binaries directly. +> Any syntax in `<>` brackets is a user's/version unique variable. Exchange with a corresponding name without the `<>` brackets. -## Automated Script for CLI Installation +1. Open Github [releases page]({{nym_vpn_releases}}) and download the CLI latest binary for your system -We wrote a [script](https://gist.github.com/serinko/d65450653d6bbafacbcee71c9cb8fb31) which does download of the CLI, sha256 verification, extraction, installation and configuration for Linux and MacOS users automatically following the steps below: - -1. Open a terminal window in a directory where you want the script and NymVPN CLI binary be downloaded and run +2. Verify sha hash of your downloaded binary with the one listed on the [releases page]({{nym_vpn_releases}}). You can use a simple `shasum` command and compare strings (ie with Python) or run in the same directory the following command, exchanging `<SHA_STRING>` with the one of your binary, like in the example: ```sh -curl -o execute-nym-vpn-cli-binary.sh -L https://gist.githubusercontent.com/tommyv1987/87267ded27e1eb7651aa9cc745ddf4af/raw/d39f98dbb36ccff761a7e940073388a6fe7b73fe/execute-nym-vpn-cli-binary.sh && chmod u+x execute-nym-vpn-cli-binary.sh && sudo -E ./execute-nym-vpn-cli-binary.sh +echo "<SHA_STRING>" | shasum -a 256 -c + +# choose a correct one according to your binary, this is just an example +# echo "0e4abb461e86b2c168577e0294112a3bacd3a24bf8565b49783bfebd9b530e23 nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_ubuntu-22.04_amd64.tar.gz" | shasum -a 256 -c ``` -2. Follow the prompts in the program +3. Extract files: +```sh +tar -xvf <BINARY>.tar.gz +# for example +# tar -xvf nym-vpn-cli_<!-- cmdrun scripts/nym_vpn_cli_version.sh -->_ubuntu-22.04_x86_64.tar.gz +``` -3. The script will automatically start the client. Make sure to **turn off any other VPNs** and follow the prompts: +4. Make executable: +```sh +# make sure you are in the right sub-directory +chmod u+x nym-vpn-cli +``` -* It prints a JSON view of existing Gateways and prompt you to: - - *Make sure to use two different Gateways for entry and exit!* - - `enter a gateway ID:` paste one of the values labeled with a key `"identityKey"` printed above (without `" "`) - - `enter an exit address:` paste one of the values labeled with a key `"address"` printed above (without `" "`) - - `do you want five hop or two hop?`: type `five` or `two` - - `enable WireGuard? (yes/no):` if you chose yes, find your private key and wireguard IP [here](https://nymvpn.com/en/alpha) +## Run NymVPN -To run `nym-vpn-cli` again, reconnect your wifi, move to the directory of your CLI binary `cd ~/nym-vpn-cli-dir` and follow the guide for [Linux](cli-linux.md#run-nymvpn) or [MacOS](cli-mac.md#run-nymvpn). If you find it too difficult, just run this script again - like in step \#3 above. +**For NymVPN to work, all other VPNs must be switched off!** At this alpha stage of NymVPN, the network connection (wifi) must be reconnected after or in between the testing rounds. -In case of errors check out the [troubleshooting](troubleshooting.md) section. +Make sure your terminal is open in the same directory as your `nym-vpn-cli` binary. + +1. Run it as root with `sudo` - the command will look like this with specified arguments: +```sh +# choose only one conditional --argument listed in {brackets} +sudo ./nym-vpn-cli { --exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY> } +``` + +2. To choose different Gateways, visit [explorer.nymtech.net/network-components/gateways](https://explorer.nymtech.net/network-components/gateways) and copy-paste an identity key of your choice + +```admonish note +Nym Exit Gateway functionality was implemented just recently and not all the Gateways are upgraded and ready to handle the VPN connections. If you want to make sure you are connecting to a Gateway with an embedded Network Requester, IP Packet Router and applied Nym exit policy, visit [this page](https://nymtech.net/events/fast-and-furious), scroll down to the list and search Gateways with all the functionalities enabled. +``` + +3. See all possibilities in [command explanation](#cli-commands-and-options) section below + +4. In case of errors, see [troubleshooting section](troubleshooting.md) + + +### CLI Commands and Options + +The basic syntax of `nym-vpn-cli` is: +```sh +# choose only one conditional --argument listed in {brackets} +sudo ./nym-vpn-cli { --exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY> } +``` + +To see all the possibilities run with `--help` flag: +```sh +./nym-vpn-cli --help +``` +~~~admonish example collapsible=true title="Console output" +```sh +Usage: nym-vpn-cli [OPTIONS] <--exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY>> + +Options: + -c, --config-env-file <CONFIG_ENV_FILE> + Path pointing to an env file describing the network + --mixnet-client-path <MIXNET_CLIENT_PATH> + Path to the data directory of a previously initialised mixnet client, where the keys reside + --entry-gateway-id <ENTRY_GATEWAY_ID> + Mixnet public ID of the entry gateway + --entry-gateway-country <ENTRY_GATEWAY_COUNTRY> + Auto-select entry gateway by country ISO + --entry-gateway-low-latency + Auto-select entry gateway by latency + --exit-router-address <EXIT_ROUTER_ADDRESS> + Mixnet recipient address + --exit-gateway-id <EXIT_GATEWAY_ID> + + --exit-gateway-country <EXIT_GATEWAY_COUNTRY> + Mixnet recipient address + --enable-wireguard + Enable the wireguard traffic between the client and the entry gateway + --private-key <PRIVATE_KEY> + Associated private key + --wg-ip <WG_IP> + The IP address of the wireguard interface used for the first hop to the entry gateway + --nym-ipv4 <NYM_IPV4> + The IPv4 address of the nym TUN device that wraps IP packets in sphinx packets + --nym-ipv6 <NYM_IPV6> + The IPv6 address of the nym TUN device that wraps IP packets in sphinx packets + --nym-mtu <NYM_MTU> + The MTU of the nym TUN device that wraps IP packets in sphinx packets + --disable-routing + Disable routing all traffic through the nym TUN device. When the flag is set, the nym TUN device will be created, but to route traffic through it you will need to do it manually, e.g. ping -Itun0 + --enable-two-hop + Enable two-hop mixnet traffic. This means that traffic jumps directly from entry gateway to exit gateway + --enable-poisson-rate + Enable Poisson process rate limiting of outbound traffic + --disable-background-cover-traffic + Disable constant rate background loop cover traffic + -h, --help + Print help + -V, --version + Print version +``` +~~~ + +Here is a list of the options and their descriptions. Some are essential, some are more technical and not needed to be adjusted by users. + +**Fundamental commands and arguments** + +- `--entry-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) +- `--exit-gateway-id`: paste one of the values labeled with a key `"identityKey"` (without `" "`) +- `--exit-router-address`: paste one of the values labeled with a key `"address"` (without `" "`) +- `--enable-wireguard`: Enable the wireguard traffic between the client and the entry gateway. NymVPN uses Mullvad libraries for wrapping `wireguard-go` and to setup local routing rules to route all traffic to the TUN virtual network device +- `--wg-ip`: The address of the wireguard interface, you can get it [here](https://nymvpn.com/en/alpha) +- `--private-key`: get your private key for testing purposes [here](https://nymvpn.com/en/alpha) +- `--enable-two-hop` is a faster setup where the traffic is routed from the client to Entry Gateway and directly to Exit Gateway (default is 5-hops) + +**Advanced options** + +- `-c` is a path to an enviroment config, like [`sandbox.env`](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) +- `--enable-poisson`: Enables process rate limiting of outbound traffic (disabled by default). It means that NymVPN client will send packets at a steady stream to the Entry Gateway. By default it's on average one sphinx packet per 20ms, but there is some randomness (poisson distribution). When there are no real data to fill the sphinx packets with, cover packets are generated instead. +- `--ip` is the IP address of the TUN device. That is the IP address of the local private network that is set up between local client and the Exit Gateway. +- `--mtu`: The MTU of the TUN device. That is the max IP packet size of the local private network that is set up between local client and the Exit Gateway. +- `--disable-routing`: Disable routing all traffic through the VPN TUN device. + +## Testnet environment + +If you want to run NymVPN CLI in Nym Sandbox environment, there are a few adjustments to be done: + +1. Create Sandbox environment config file by saving [this](https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env) as `sandbox.env` in the same directory as your NymVPN binaries: +```sh +curl -o sandbox.env -L https://raw.githubusercontent.com/nymtech/nym/develop/envs/sandbox.env +``` + +1. Check available Gateways at [nymvpn.com/en/alpha/api/gateways](https://nymvpn.com/en/alpha/api/gateways) + +2. Run with a flag `-c` +```sh +sudo ./nym-vpn-cli -c <PATH_TO>/sandbox.env <--exit-router-address <EXIT_ROUTER_ADDRESS>|--exit-gateway-id <EXIT_GATEWAY_ID>|--exit-gateway-country <EXIT_GATEWAY_COUNTRY>> +``` diff --git a/documentation/dev-portal/src/nymvpn/gui.md b/documentation/dev-portal/src/nymvpn/gui.md index e410573a93..6eda800aad 100644 --- a/documentation/dev-portal/src/nymvpn/gui.md +++ b/documentation/dev-portal/src/nymvpn/gui.md @@ -1,12 +1,12 @@ # NymVPN - Desktop (GUI) ```admonish info -Our alpha testing round is done with participants at live workshop events. This guide will not work for everyone, as the NymVPN source code is not yet publicly accessible. The alpha testing is done on Nym testnet Sandbox environment, this configuration is limited and will not work in the future. +Our alpha testing round is done with participants at live workshop events and the application in this stage may not work for everyone. **If you commit to test NymVPN alpha, please start with the [user research form]({{nym_vpn_form_url}}) where all the steps will be provided**. If you disagree with any of the conditions listed, please leave this page. ``` -This is the alpha version of NymVPN desktop application (GUI). A demo of how the client will look like for majority of day-to-day users. +This is a desktop (GUI) version of NymVPN client. A demo of how the application will look like for majority of day-to-day users. Follow the simple [automated script](#automated-script-for-gui-installation) below to install and run NymVPN GUI. If the script didn't work for your distribution or you prefer to do a manual setup follow the steps in the guide for [Linux](gui-linux.md) or [MacOS](gui-mac.md) . @@ -14,12 +14,12 @@ Visit NymVPN alpha latest [release page]({{nym_vpn_releases}}) to check sha sums ## Linux AppImage Automated Installation Method -The latest releases contain `appimage.sh` script. This method makes the installation simple for Linux users who want to run NymVPN from AppImmage. Executing the command below will download the binary to `~/.local/bin` and verify the checksum. +The latest releases contain `appimage.sh` script. This method makes the installation simple for Linux users who want to run NymVPN from AppImmage. Executing the command below will download the binary to `~/.local/bin` and verify the checksum: ```sh curl -fsSL https://github.com/nymtech/nym-vpn-client/releases/download/nym-vpn-desktop-v<!-- cmdrun scripts/nym_vpn_desktop_version.sh -->/appimage.sh | bash ``` -Run with the command +Run with the command: ```sh sudo -E ~/.local/bin/nym-vpn.appimage ``` diff --git a/documentation/dev-portal/src/nymvpn/intro.md b/documentation/dev-portal/src/nymvpn/intro.md index b0648c063e..3d07f8f510 100644 --- a/documentation/dev-portal/src/nymvpn/intro.md +++ b/documentation/dev-portal/src/nymvpn/intro.md @@ -5,16 +5,15 @@ **Nym proudly presents NymVPN alpha** - a client that uses [Nym Mixnet](https://nymtech.net) to anonymise all of a user's internet traffic through either a 5-hop mixnet (for a full network privacy) or the faster 2-hop decentralised VPN (with some extra features). -**You are invited to take part in the alpha testing** of this new application. The following pages provide a how-to guide, explaining steps to install and run NymVPN [CLI](cli.md) and [GUI](gui.md) on the Sandbox testnet environment. +**You are invited to take part in the alpha testing** of this new application. The following pages provide a how-to guide, explaining steps to install and run NymVPN [CLI](cli.md) and [GUI](gui.md). **Here is how** 1. Go to the NymVPN [testers form]({{nym_vpn_form_url}}) -2. Please consent to the GDPR so we can use the results +2. Fill and submit the [form!]({{nym_vpn_form_url}}) 3. To test the GUI, [go here](gui.md) 4. To test the CLI, [go here](cli.md) -5. Fill and submit the [form!]({{nym_vpn_form_url}}) -6. Join the [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) if you have any questions, comments or blockers +5. Join the [NymVPN matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat) if you have any questions, comments or blockers ***NymVPN alpha testing will last from 15th of January - 15th of February.*** diff --git a/documentation/dev-portal/src/nymvpn/troubleshooting.md b/documentation/dev-portal/src/nymvpn/troubleshooting.md index 9e00554518..1ae4046cdb 100644 --- a/documentation/dev-portal/src/nymvpn/troubleshooting.md +++ b/documentation/dev-portal/src/nymvpn/troubleshooting.md @@ -2,6 +2,14 @@ Below are listed some points which may need to be addressed when testing NymVPN alpha. If you crashed into any errors which are not listed, please contact us at the testing workshop or in the NymVPN [Matrix channel](https://matrix.to/#/#NymVPN:nymtech.chat). +#### NymVPN attempts to connect to sandbox testnet + +If you testing the latest versions and you correctly expect the client to run over the mainnet, but it listens to `https://sandbox-nym-api1.nymtech.net`, it's probably because of your previous configuration. + +Check your `config.toml` either in the directory from which you run your client or in `~/.config/nym-vpn/` and remove `sandbox.env` from the config file and folder. + +If the problem persists (probably due to some locally cache) download [`mainnet.env`](https://github.com/nymtech/nym/blob/master/envs/mainnet.env) and save it to the same directory. + #### Running GUI failed due to `TOML parse error` If you see this error when running NymVPN alpha desktop, it's because the older versions needed entry location in `config.toml` configuration file. From `v0.0.3` the entry location is selected directly by the user in the application. This error is due to an old `app-data.toml` config in your computer. From bfc495ef29fb36e125fcd919541cfbb09bd293be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 1 Mar 2024 15:28:39 +0000 Subject: [PATCH 372/394] expire freepass bandwidth + stagger db flushes --- gateway/Cargo.toml | 1 + .../20240301120000_freepass_expiration.sql | 7 + gateway/src/config/mod.rs | 13 ++ gateway/src/config/old_config_v1_1_31.rs | 1 + .../connection_handler/authenticated.rs | 148 +++++++++++++----- .../websocket/connection_handler/fresh.rs | 64 ++++---- .../websocket/connection_handler/mod.rs | 75 +++++++++ .../client_handling/websocket/listener.rs | 23 +-- .../src/node/client_handling/websocket/mod.rs | 3 + .../client_handling/websocket/shared_state.rs | 16 ++ gateway/src/node/mod.rs | 13 +- gateway/src/node/storage/bandwidth.rs | 94 ++++++----- gateway/src/node/storage/mod.rs | 114 ++++++++------ gateway/src/node/storage/models.rs | 22 +++ 14 files changed, 422 insertions(+), 172 deletions(-) create mode 100644 gateway/migrations/20240301120000_freepass_expiration.sql create mode 100644 gateway/src/node/client_handling/websocket/shared_state.rs diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 4ec9d74844..21f622c0ba 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -38,6 +38,7 @@ sqlx = { workspace = true, features = [ "sqlite", "macros", "migrate", + "time" ] } subtle-encoding = { version = "0.5", features = ["bech32-preview"] } thiserror = { workspace = true } diff --git a/gateway/migrations/20240301120000_freepass_expiration.sql b/gateway/migrations/20240301120000_freepass_expiration.sql new file mode 100644 index 0000000000..6538723ac6 --- /dev/null +++ b/gateway/migrations/20240301120000_freepass_expiration.sql @@ -0,0 +1,7 @@ +/* + * Copyright 2024 - Nym Technologies SA <contact@nymtech.net> + * SPDX-License-Identifier: Apache-2.0 + */ + +ALTER TABLE available_bandwidth +ADD COLUMN freepass_expiration TIMESTAMP WITHOUT TIME ZONE; \ No newline at end of file diff --git a/gateway/src/config/mod.rs b/gateway/src/config/mod.rs index 5a345279d1..7932d2456f 100644 --- a/gateway/src/config/mod.rs +++ b/gateway/src/config/mod.rs @@ -42,6 +42,9 @@ const DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE: usize = 2000; const DEFAULT_STORED_MESSAGE_FILENAME_LENGTH: u16 = 16; const DEFAULT_MESSAGE_RETRIEVAL_LIMIT: i64 = 100; +const DEFAULT_CLIENT_BANDWIDTH_MAX_FLUSHING_RATE: Duration = Duration::from_millis(5); +const DEFAULT_CLIENT_BANDWIDTH_MAX_DELTA_FLUSHING_AMOUNT: i64 = 512 * 1024; // 512kB + /// Derive default path to gateway's config directory. /// It should get resolved to `$HOME/.nym/gateways/<id>/config` pub fn default_config_directory<P: AsRef<Path>>(id: P) -> PathBuf { @@ -516,6 +519,13 @@ pub struct Debug { /// Number of messages from offline client that can be pulled at once from the storage. pub message_retrieval_limit: i64, + /// Defines maximum delay between client bandwidth information being flushed to the persistent storage. + #[serde(with = "humantime_serde")] + pub client_bandwidth_max_flushing_rate: Duration, + + /// Defines a maximum change in client bandwidth before it gets flushed to the persistent storage. + pub client_bandwidth_max_delta_flushing_amount: i64, + /// Specifies whether the mixnode should be using the legacy framing for the sphinx packets. // it's set to true by default. The reason for that decision is to preserve compatibility with the // existing nodes whilst everyone else is upgrading and getting the code for handling the new field. @@ -533,6 +543,9 @@ impl Default for Debug { maximum_connection_buffer_size: DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE, stored_messages_filename_length: DEFAULT_STORED_MESSAGE_FILENAME_LENGTH, message_retrieval_limit: DEFAULT_MESSAGE_RETRIEVAL_LIMIT, + client_bandwidth_max_flushing_rate: DEFAULT_CLIENT_BANDWIDTH_MAX_FLUSHING_RATE, + client_bandwidth_max_delta_flushing_amount: + DEFAULT_CLIENT_BANDWIDTH_MAX_DELTA_FLUSHING_AMOUNT, use_legacy_framed_packet_version: false, } } diff --git a/gateway/src/config/old_config_v1_1_31.rs b/gateway/src/config/old_config_v1_1_31.rs index b0797a9eaf..0d57cfe777 100644 --- a/gateway/src/config/old_config_v1_1_31.rs +++ b/gateway/src/config/old_config_v1_1_31.rs @@ -165,6 +165,7 @@ impl From<ConfigV1_1_31> for Config { stored_messages_filename_length: value.debug.stored_messages_filename_length, message_retrieval_limit: value.debug.message_retrieval_limit, use_legacy_framed_packet_version: value.debug.use_legacy_framed_packet_version, + ..Default::default() }, } } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 9ff8882a3a..7c785547c1 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::client_handling::bandwidth::BandwidthError; +use crate::node::client_handling::websocket::connection_handler::ClientBandwidth; use crate::node::{ client_handling::{ bandwidth::Bandwidth, @@ -34,6 +35,7 @@ use nym_validator_client::coconut::CoconutApiError; use rand::{CryptoRng, Rng}; use std::{process, time::Duration}; use thiserror::Error; +use time::OffsetDateTime; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; @@ -90,9 +92,18 @@ pub enum RequestHandlingError { #[error("the provided credential did not contain a valid type attribute")] InvalidTypeAttribute, + #[error("insufficient bandwidth available to process the request")] + OutOfBandwidth, + #[error("the provided credential did not have a bandwidth attribute")] MissingBandwidthAttribute, + #[error("attempted to claim a bandwidth voucher for an account using a free pass (it expires on {expiration})")] + BandwidthVoucherForFreePassAccount { expiration: OffsetDateTime }, + + #[error("attempted to claim another free pass for the account while another free pass is still active (it expires on {expiration})")] + PreexistingFreePass { expiration: OffsetDateTime }, + #[error("the DKG contract is unavailable")] UnavailableDkgContract, } @@ -121,6 +132,7 @@ impl IntoWSMessage for Result<ServerResponse, RequestHandlingError> { pub(crate) struct AuthenticatedHandler<R, S, St> { inner: FreshHandler<R, S, St>, client: ClientDetails, + client_bandwidth: ClientBandwidth, mix_receiver: MixMessageReceiver, // Occasionally the handler is requested to ping the connected client for confirm that it's // active, such as when a duplicate connection is detected. This hashmap stores the oneshot @@ -153,19 +165,30 @@ where /// * `fresh`: fresh, unauthenticated, connection handler. /// * `client`: details (i.e. address and shared keys) of the registered client /// * `mix_receiver`: channel used for receiving messages from the mixnet destined for this client. - pub(crate) fn upgrade( + pub(crate) async fn upgrade( fresh: FreshHandler<R, S, St>, client: ClientDetails, mix_receiver: MixMessageReceiver, is_active_request_receiver: IsActiveRequestReceiver, - ) -> Self { - AuthenticatedHandler { + ) -> Result<Self, RequestHandlingError> { + // note: the `upgrade` function can only be called after registering or authenticating the client, + // meaning the appropriate database rows must have been created + // so in theory we could just unwrap the value here, but since we're returning a Result anyway, + // we might as well return a failure response instead + let bandwidth = fresh + .storage + .get_available_bandwidth(client.address) + .await? + .ok_or(RequestHandlingError::IllegalRequest)?; + + Ok(AuthenticatedHandler { inner: fresh, client, + client_bandwidth: ClientBandwidth::new(bandwidth.into()), mix_receiver, is_active_request_receiver, is_active_ping_pending_reply: None, - } + }) } /// Explicitly removes handle from the global store. @@ -175,15 +198,10 @@ where .disconnect(self.client.address) } - /// Checks the amount of bandwidth available for the connected client. - async fn get_available_bandwidth(&self) -> Result<i64, RequestHandlingError> { - let bandwidth = self - .inner - .storage - .get_available_bandwidth(self.client.address) - .await? - .unwrap_or_default(); - Ok(bandwidth) + async fn expire_freepass(&mut self) -> Result<(), RequestHandlingError> { + self.client_bandwidth.bandwidth = Default::default(); + self.client_bandwidth.update_flush_data(); + Ok(self.inner.expire_freepass(self.client.address).await?) } /// Increases the amount of available bandwidth of the connected client by the specified value. @@ -191,12 +209,15 @@ where /// # Arguments /// /// * `amount`: amount to increase the available bandwidth by. - async fn increase_bandwidth(&self, bandwidth: Bandwidth) -> Result<(), RequestHandlingError> { - self.inner - .storage - .increase_bandwidth(self.client.address, bandwidth.value() as i64) - .await?; - Ok(()) + async fn increase_bandwidth( + &mut self, + bandwidth: Bandwidth, + ) -> Result<(), RequestHandlingError> { + self.client_bandwidth.bandwidth.bytes += bandwidth.value() as i64; + + // any increases to bandwidth should get flushed immediately + // (we don't want to accidentally miss somebody claiming a gigabyte voucher) + self.flush_bandwidth().await } /// Decreases the amount of available bandwidth of the connected client by the specified value. @@ -204,11 +225,18 @@ where /// # Arguments /// /// * `amount`: amount to decrease the available bandwidth by. - async fn consume_bandwidth(&self, amount: i64) -> Result<(), RequestHandlingError> { - self.inner - .storage - .consume_bandwidth(self.client.address, amount) - .await?; + async fn consume_bandwidth(&mut self, amount: i64) -> Result<(), RequestHandlingError> { + self.client_bandwidth.bandwidth.bytes -= amount; + + // since we're going to be operating on a fair use policy anyway, even if we crash and let extra few packets + // through, that's completely fine + if self + .client_bandwidth + .should_flush(self.inner.shared_state.bandwidth_cfg) + { + self.flush_bandwidth().await?; + } + Ok(()) } @@ -232,6 +260,22 @@ where let serial_number = credential.data.blinded_serial_number(); trace!("processing credential {}", serial_number.to_bs58()); + // if we already have had received a free pass (that's not expired, don't accept any additional bandwidth) + if self.client_bandwidth.bandwidth.freepass_expired() { + // the free pass we used before has expired -> reset our state and handle the request as normal + self.expire_freepass().await?; + } else if let Some(expiration) = self.client_bandwidth.bandwidth.freepass_expiration { + // the free pass is still valid -> return error + return match credential.data.typ { + CredentialType::Voucher => { + Err(RequestHandlingError::BandwidthVoucherForFreePassAccount { expiration }) + } + CredentialType::FreePass => { + Err(RequestHandlingError::PreexistingFreePass { expiration }) + } + }; + } + let already_spent = self .inner .storage @@ -249,6 +293,7 @@ where let aggregated_verification_key = self .inner + .shared_state .coconut_verifier .verification_key(credential.data.epoch_id) .await?; @@ -277,16 +322,20 @@ where )); } + drop(aggregated_verification_key); + let was_freepass = match credential.data.typ { CredentialType::Voucher => { trace!("the credential is a bandwidth voucher. attempting to release the funds"); let api_clients = self .inner + .shared_state .coconut_verifier .api_clients(credential.data.epoch_id) .await?; self.inner + .shared_state .coconut_verifier .release_bandwidth_voucher_funds(&api_clients, credential) .await?; @@ -316,7 +365,7 @@ where trace!("increasing client bandwidth"); self.increase_bandwidth(bandwidth).await?; - let available_total = self.get_available_bandwidth().await?; + let available_total = self.client_bandwidth.bandwidth.bytes; Ok(ServerResponse::Bandwidth { available_total }) } @@ -367,17 +416,44 @@ where ) -> Result<ServerResponse, RequestHandlingError> { debug!("handling testnet bandwidth request"); - if self.inner.only_coconut_credentials { + if self.inner.shared_state.only_coconut_credentials { return Err(RequestHandlingError::OnlyCoconutCredentials); } self.increase_bandwidth(FREE_TESTNET_BANDWIDTH_VALUE) .await?; - let available_total = self.get_available_bandwidth().await?; + let available_total = self.client_bandwidth.bandwidth.bytes; Ok(ServerResponse::Bandwidth { available_total }) } + async fn flush_bandwidth(&mut self) -> Result<(), RequestHandlingError> { + trace!("flushing client bandwidth to the underlying storage"); + self.inner + .storage + .set_bandwidth(self.client.address, self.client_bandwidth.bandwidth.bytes) + .await?; + self.client_bandwidth.update_flush_data(); + Ok(()) + } + + async fn try_use_bandwidth( + &mut self, + required_bandwidth: i64, + ) -> Result<i64, RequestHandlingError> { + if self.client_bandwidth.bandwidth.freepass_expired() { + self.expire_freepass().await?; + } + let available_bandwidth = self.client_bandwidth.bandwidth.bytes; + + if available_bandwidth < required_bandwidth { + return Err(RequestHandlingError::OutOfBandwidth); + } + + self.consume_bandwidth(required_bandwidth).await?; + Ok(self.client_bandwidth.bandwidth.bytes) + } + /// Tries to handle request to forward sphinx packet into the network. The request can only succeed /// if the client has enough available bandwidth. /// @@ -387,24 +463,16 @@ where /// /// * `mix_packet`: packet received from the client that should get forwarded into the network. async fn handle_forward_sphinx( - &self, + &mut self, mix_packet: MixPacket, ) -> Result<ServerResponse, RequestHandlingError> { - let consumed_bandwidth = mix_packet.packet().len() as i64; + let required_bandwidth = mix_packet.packet().len() as i64; - let available_bandwidth = self.get_available_bandwidth().await?; - - if available_bandwidth < consumed_bandwidth { - return Ok(ServerResponse::new_error( - "Insufficient bandwidth available", - )); - } - - self.consume_bandwidth(consumed_bandwidth).await?; + let remaining_bandwidth = self.try_use_bandwidth(required_bandwidth).await?; self.forward_packet(mix_packet); Ok(ServerResponse::Send { - remaining_bandwidth: available_bandwidth - consumed_bandwidth, + remaining_bandwidth, }) } @@ -413,7 +481,7 @@ where /// # Arguments /// /// * `bin_msg`: raw message to handle. - async fn handle_binary(&self, bin_msg: Vec<u8>) -> Message { + async fn handle_binary(&mut self, bin_msg: Vec<u8>) -> Message { trace!("binary request"); // this function decrypts the request and checks the MAC match BinaryRequest::try_from_encrypted_tagged_bytes(bin_msg, &self.client.shared_keys) { diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 539026ad5a..aaf8e39518 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -20,18 +20,19 @@ use nym_gateway_requests::{ use nym_mixnet_client::forwarder::MixForwardingSender; use nym_sphinx::DestinationAddressBytes; use rand::{CryptoRng, Rng}; -use std::{sync::Arc, time::Duration}; +use std::time::Duration; use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; +use crate::node::client_handling::websocket::connection_handler::AvailableBandwidth; +use crate::node::client_handling::websocket::shared_state::SharedHandlerState; use crate::node::{ client_handling::{ active_clients::ActiveClientsStore, websocket::{ connection_handler::{ - coconut::CoconutVerifier, AuthenticatedHandler, ClientDetails, InitialAuthResult, - SocketStream, + AuthenticatedHandler, ClientDetails, InitialAuthResult, SocketStream, }, message_receiver::{IsActive, IsActiveRequestSender}, }, @@ -88,13 +89,11 @@ impl InitialAuthenticationError { pub(crate) struct FreshHandler<R, S, St> { rng: R, - local_identity: Arc<identity::KeyPair>, - pub(crate) only_coconut_credentials: bool, + pub(crate) shared_state: SharedHandlerState, pub(crate) active_clients_store: ActiveClientsStore, pub(crate) outbound_mix_sender: MixForwardingSender, pub(crate) socket_connection: SocketStream<S>, pub(crate) storage: St, - pub(crate) coconut_verifier: Arc<CoconutVerifier>, // currently unused (but populated) pub(crate) negotiated_protocol: Option<u8>, @@ -113,23 +112,19 @@ where pub(crate) fn new( rng: R, conn: S, - only_coconut_credentials: bool, outbound_mix_sender: MixForwardingSender, - local_identity: Arc<identity::KeyPair>, storage: St, active_clients_store: ActiveClientsStore, - coconut_verifier: Arc<CoconutVerifier>, + shared_state: SharedHandlerState, ) -> Self { FreshHandler { rng, active_clients_store, - only_coconut_credentials, outbound_mix_sender, socket_connection: SocketStream::RawTcp(conn), - local_identity, storage, - coconut_verifier, negotiated_protocol: None, + shared_state, } } @@ -171,7 +166,7 @@ where gateway_handshake( &mut self.rng, ws_stream, - self.local_identity.as_ref(), + self.shared_state.local_identity.as_ref(), init_msg, ) .await @@ -436,7 +431,7 @@ where // Ask the other connection to ping if they are still active. // Use a oneshot channel to return the result to us let (ping_result_sender, ping_result_receiver) = oneshot::channel(); - log::debug!("Asking other connection handler to ping the connected client to see if it is still active"); + debug!("Asking other connection handler to ping the connected client to see if it is still active"); if let Err(err) = is_active_request_tx.send(ping_result_sender).await { warn!("Failed to send ping request to other handler: {err}"); } @@ -448,31 +443,31 @@ where IsActive::NotActive => { // The other handler reported that the client is not active, so we can // disconnect the other client and continue with this connection. - log::debug!("Other handler reports it is not active"); + debug!("Other handler reports it is not active"); self.active_clients_store.disconnect(address); } IsActive::Active => { // The other handled reported a positive reply, so we have to assume it's // still active and disconnect this connection. - log::info!("Other handler reports it is active"); + info!("Other handler reports it is active"); return Err(InitialAuthenticationError::DuplicateConnection); } IsActive::BusyPinging => { // The other handler is already busy pinging the client, so we have to // assume it's still active and disconnect this connection. - log::debug!("Other handler reports it is already busy pinging the client"); + debug!("Other handler reports it is already busy pinging the client"); return Err(InitialAuthenticationError::DuplicateConnection); } } } Ok(Err(_)) => { // Other channel failed to reply (the channel sender probably dropped) - log::info!("Other connection failed to reply, disconnecting it in favour of this new connection"); + info!("Other connection failed to reply, disconnecting it in favour of this new connection"); self.active_clients_store.disconnect(address); } Err(_) => { // Timeout waiting for reply - log::warn!( + warn!( "Other connection timed out, disconnecting it in favour of this new connection" ); self.active_clients_store.disconnect(address); @@ -509,7 +504,7 @@ where // Check for duplicate clients if let Some(client_tx) = self.active_clients_store.get_remote_client(address) { - log::warn!("Detected duplicate connection for client: {address}"); + warn!("Detected duplicate connection for client: {address}"); self.handle_duplicate_client(address, client_tx.is_active_request_sender) .await?; } @@ -518,11 +513,17 @@ where .authenticate_client(address, encrypted_address, iv) .await?; let status = shared_keys.is_some(); - let bandwidth_remaining = self - .storage - .get_available_bandwidth(address) - .await? - .unwrap_or(0); + + let available_bandwidth: AvailableBandwidth = + self.storage.get_available_bandwidth(address).await?.into(); + + let bandwidth_remaining = if available_bandwidth.freepass_expired() { + self.expire_freepass(address).await?; + 0 + } else { + available_bandwidth.bytes + }; + let client_details = shared_keys.map(|shared_keys| ClientDetails::new(address, shared_keys)); @@ -536,6 +537,13 @@ where )) } + pub(crate) async fn expire_freepass( + &self, + client: DestinationAddressBytes, + ) -> Result<(), StorageError> { + self.storage.reset_freepass_bandwidth(client).await + } + /// Attempts to finalize registration of the client by storing the derived shared keys in the /// persistent store as well as creating entry for its bandwidth allocation. /// @@ -708,12 +716,14 @@ where mix_sender, is_active_request_sender, ); - Some(AuthenticatedHandler::upgrade( + AuthenticatedHandler::upgrade( self, client_details, mix_receiver, is_active_request_receiver, - )) + ) + .await + .ok() } else { None }; diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index 67ec3e4316..84f61d6652 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -1,6 +1,7 @@ // Copyright 2021 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::config::Config; use crate::node::storage::Storage; use log::{trace, warn}; use nym_gateway_requests::registration::handshake::SharedKeys; @@ -8,6 +9,8 @@ use nym_gateway_requests::ServerResponse; use nym_sphinx::DestinationAddressBytes; use nym_task::TaskClient; use rand::{CryptoRng, Rng}; +use std::time::Duration; +use time::OffsetDateTime; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::WebSocketStream; use zeroize::{Zeroize, ZeroizeOnDrop}; @@ -112,3 +115,75 @@ pub(crate) async fn handle_connection<R, S, St>( trace!("The handler is done!"); } + +#[derive(Debug, Clone, Copy)] +pub(crate) struct BandwidthFlushingBehaviourConfig { + /// Defines maximum delay between client bandwidth information being flushed to the persistent storage. + pub client_bandwidth_max_flushing_rate: Duration, + + /// Defines a maximum change in client bandwidth before it gets flushed to the persistent storage. + pub client_bandwidth_max_delta_flushing_amount: i64, +} + +impl<'a> From<&'a Config> for BandwidthFlushingBehaviourConfig { + fn from(value: &'a Config) -> Self { + BandwidthFlushingBehaviourConfig { + client_bandwidth_max_flushing_rate: value.debug.client_bandwidth_max_flushing_rate, + client_bandwidth_max_delta_flushing_amount: value + .debug + .client_bandwidth_max_delta_flushing_amount, + } + } +} + +#[derive(Debug, Clone, Copy, Default)] +pub(crate) struct AvailableBandwidth { + pub(crate) bytes: i64, + pub(crate) freepass_expiration: Option<OffsetDateTime>, +} + +impl AvailableBandwidth { + pub(crate) fn freepass_expired(&self) -> bool { + if let Some(expiration) = self.freepass_expiration { + if expiration < OffsetDateTime::now_utc() { + return true; + } + } + false + } +} + +pub(crate) struct ClientBandwidth { + pub(crate) bandwidth: AvailableBandwidth, + pub(crate) last_flushed: OffsetDateTime, + pub(crate) bytes_at_last_flush: i64, +} + +impl ClientBandwidth { + pub(crate) fn new(bandwidth: AvailableBandwidth) -> ClientBandwidth { + ClientBandwidth { + bandwidth, + last_flushed: OffsetDateTime::now_utc(), + bytes_at_last_flush: bandwidth.bytes, + } + } + + pub(crate) fn should_flush(&self, cfg: BandwidthFlushingBehaviourConfig) -> bool { + if (self.bytes_at_last_flush - self.bandwidth.bytes).abs() + >= cfg.client_bandwidth_max_delta_flushing_amount + { + return true; + } + + if self.last_flushed + cfg.client_bandwidth_max_flushing_rate < OffsetDateTime::now_utc() { + return true; + } + + false + } + + pub(crate) fn update_flush_data(&mut self) { + self.last_flushed = OffsetDateTime::now_utc(); + self.bytes_at_last_flush = self.bandwidth.bytes; + } +} diff --git a/gateway/src/node/client_handling/websocket/listener.rs b/gateway/src/node/client_handling/websocket/listener.rs index 27a03aacfc..9b073dbc5c 100644 --- a/gateway/src/node/client_handling/websocket/listener.rs +++ b/gateway/src/node/client_handling/websocket/listener.rs @@ -2,37 +2,26 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::client_handling::active_clients::ActiveClientsStore; -use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier; use crate::node::client_handling::websocket::connection_handler::FreshHandler; +use crate::node::client_handling::websocket::shared_state::SharedHandlerState; use crate::node::storage::Storage; use log::*; -use nym_crypto::asymmetric::identity; use nym_mixnet_client::forwarder::MixForwardingSender; use rand::rngs::OsRng; use std::net::SocketAddr; use std::process; -use std::sync::Arc; use tokio::task::JoinHandle; pub(crate) struct Listener { address: SocketAddr, - local_identity: Arc<identity::KeyPair>, - only_coconut_credentials: bool, - pub(crate) coconut_verifier: Arc<CoconutVerifier>, + shared_state: SharedHandlerState, } impl Listener { - pub(crate) fn new( - address: SocketAddr, - local_identity: Arc<identity::KeyPair>, - only_coconut_credentials: bool, - coconut_verifier: Arc<CoconutVerifier>, - ) -> Self { + pub(crate) fn new(address: SocketAddr, shared_state: SharedHandlerState) -> Self { Listener { address, - local_identity, - only_coconut_credentials, - coconut_verifier, + shared_state, } } @@ -71,12 +60,10 @@ impl Listener { let handle = FreshHandler::new( OsRng, socket, - self.only_coconut_credentials, outbound_mix_sender.clone(), - Arc::clone(&self.local_identity), storage.clone(), active_clients_store.clone(), - Arc::clone(&self.coconut_verifier), + self.shared_state.clone(), ); let shutdown = shutdown.clone().named(format!("ClientConnectionHandler_{remote_addr}")); tokio::spawn(async move { handle.start_handling(shutdown).await }); diff --git a/gateway/src/node/client_handling/websocket/mod.rs b/gateway/src/node/client_handling/websocket/mod.rs index 673f14b8a8..6d0a990956 100644 --- a/gateway/src/node/client_handling/websocket/mod.rs +++ b/gateway/src/node/client_handling/websocket/mod.rs @@ -6,3 +6,6 @@ pub(crate) use listener::Listener; pub(crate) mod connection_handler; pub(crate) mod listener; pub(crate) mod message_receiver; +pub(crate) mod shared_state; + +pub(crate) use shared_state::SharedHandlerState; diff --git a/gateway/src/node/client_handling/websocket/shared_state.rs b/gateway/src/node/client_handling/websocket/shared_state.rs new file mode 100644 index 0000000000..1f19476e97 --- /dev/null +++ b/gateway/src/node/client_handling/websocket/shared_state.rs @@ -0,0 +1,16 @@ +// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> +// SPDX-License-Identifier: GPL-3.0-only + +use crate::node::client_handling::websocket::connection_handler::coconut::CoconutVerifier; +use crate::node::client_handling::websocket::connection_handler::BandwidthFlushingBehaviourConfig; +use nym_crypto::asymmetric::identity; +use std::sync::Arc; + +// I can see this being possible expanded with say storage or client store +#[derive(Clone)] +pub(crate) struct SharedHandlerState { + pub(crate) coconut_verifier: Arc<CoconutVerifier>, + pub(crate) local_identity: Arc<identity::KeyPair>, + pub(crate) only_coconut_credentials: bool, + pub(crate) bandwidth_cfg: BandwidthFlushingBehaviourConfig, +} diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 53607a3dfb..5f5f57e164 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -254,13 +254,14 @@ impl<St> Gateway<St> { self.config.gateway.clients_port, ); - websocket::Listener::new( - listening_address, - Arc::clone(&self.identity_keypair), - self.config.gateway.only_coconut_credentials, + let shared_state = websocket::SharedHandlerState { coconut_verifier, - ) - .start( + local_identity: Arc::clone(&self.identity_keypair), + only_coconut_credentials: self.config.gateway.only_coconut_credentials, + bandwidth_cfg: (&self.config).into(), + }; + + websocket::Listener::new(listening_address, shared_state).start( forwarding_channel, self.storage.clone(), active_clients_store, diff --git a/gateway/src/node/storage/bandwidth.rs b/gateway/src/node/storage/bandwidth.rs index 3eb4dab057..1ebcccea85 100644 --- a/gateway/src/node/storage/bandwidth.rs +++ b/gateway/src/node/storage/bandwidth.rs @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::storage::models::{PersistedBandwidth, SpentCredential}; +use time::OffsetDateTime; #[derive(Clone)] pub(crate) struct BandwidthManager { @@ -36,6 +37,53 @@ impl BandwidthManager { Ok(()) } + /// Set the freepass expiration date of the particular client to the provided date. + /// + /// # Arguments + /// + /// * `client_address_bs58`: base58-encoded address of the client. + /// * `freepass_expiration`: the expiration date of the associated free pass. + pub(crate) async fn set_freepass_expiration( + &self, + client_address_bs58: &str, + freepass_expiration: OffsetDateTime, + ) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + UPDATE available_bandwidth + SET freepass_expiration = ? + WHERE client_address_bs58 = ? + "#, + freepass_expiration, + client_address_bs58 + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + + /// Reset all the bandwidth associated with the freepass and reset its expiration date + /// + /// # Arguments + /// + /// * `client_address_bs58`: base58-encoded address of the client. + pub(crate) async fn reset_freepass_bandwidth( + &self, + client_address_bs58: &str, + ) -> Result<(), sqlx::Error> { + sqlx::query!( + r#" + UPDATE available_bandwidth + SET available = 0, freepass_expiration = NULL + WHERE client_address_bs58 = ? + "#, + client_address_bs58 + ) + .execute(&self.connection_pool) + .await?; + Ok(()) + } + /// Tries to retrieve available bandwidth for the particular client. /// /// # Arguments @@ -45,22 +93,19 @@ impl BandwidthManager { &self, client_address_bs58: &str, ) -> Result<Option<PersistedBandwidth>, sqlx::Error> { - sqlx::query_as!( - PersistedBandwidth, - "SELECT * FROM available_bandwidth WHERE client_address_bs58 = ?", - client_address_bs58 - ) - .fetch_optional(&self.connection_pool) - .await + sqlx::query_as("SELECT * FROM available_bandwidth WHERE client_address_bs58 = ?") + .bind(client_address_bs58) + .fetch_optional(&self.connection_pool) + .await } - /// Increases available bandwidth of the particular client by the specified amount. + /// Sets available bandwidth of the particular client to the provided amount; /// /// # Arguments /// - /// * `client_address_bs58`: base58-encoded address of the client. - /// * `amount`: amount of available bandwidth to be added to the client. - pub(crate) async fn increase_available_bandwidth( + /// * `client_address`: address of the client + /// * `amount`: the updated client bandwidth amount. + pub(crate) async fn set_available_bandwidth( &self, client_address_bs58: &str, amount: i64, @@ -68,32 +113,7 @@ impl BandwidthManager { sqlx::query!( r#" UPDATE available_bandwidth - SET available = available + ? - WHERE client_address_bs58 = ? - "#, - amount, - client_address_bs58 - ) - .execute(&self.connection_pool) - .await?; - Ok(()) - } - - /// Decreases available bandwidth of the particular client by the specified amount. - /// - /// # Arguments - /// - /// * `client_address_bs58`: base58-encoded address of the client. - /// * `amount`: amount of available bandwidth to be removed from the client. - pub(crate) async fn decrease_available_bandwidth( - &self, - client_address_bs58: &str, - amount: i64, - ) -> Result<(), sqlx::Error> { - sqlx::query!( - r#" - UPDATE available_bandwidth - SET available = available - ? + SET available = ? WHERE client_address_bs58 = ? "#, amount, diff --git a/gateway/src/node/storage/mod.rs b/gateway/src/node/storage/mod.rs index bb7330c2f6..e7123a44a6 100644 --- a/gateway/src/node/storage/mod.rs +++ b/gateway/src/node/storage/mod.rs @@ -4,7 +4,7 @@ use crate::node::storage::bandwidth::BandwidthManager; use crate::node::storage::error::StorageError; use crate::node::storage::inboxes::InboxManager; -use crate::node::storage::models::{PersistedSharedKeys, StoredMessage}; +use crate::node::storage::models::{PersistedBandwidth, PersistedSharedKeys, StoredMessage}; use crate::node::storage::shared_keys::SharedKeysManager; use async_trait::async_trait; use log::{debug, error}; @@ -13,6 +13,7 @@ use nym_gateway_requests::registration::handshake::SharedKeys; use nym_sphinx::DestinationAddressBytes; use sqlx::ConnectOptions; use std::path::Path; +use time::OffsetDateTime; mod bandwidth; pub(crate) mod error; @@ -102,6 +103,28 @@ pub trait Storage: Send + Sync { client_address: DestinationAddressBytes, ) -> Result<(), StorageError>; + /// Set the freepass expiration date of the particular client to the provided date. + /// + /// # Arguments + /// + /// * `client_address`: address of the client + /// * `freepass_expiration`: the expiration date of the associated free pass. + async fn set_freepass_expiration( + &self, + client_address: DestinationAddressBytes, + freepass_expiration: OffsetDateTime, + ) -> Result<(), StorageError>; + + /// Reset all the bandwidth associated with the freepass and reset its expiration date + /// + /// # Arguments + /// + /// * `client_address`: address of the client + async fn reset_freepass_bandwidth( + &self, + client_address: DestinationAddressBytes, + ) -> Result<(), StorageError>; + /// Tries to retrieve available bandwidth for the particular client. /// /// # Arguments @@ -110,27 +133,15 @@ pub trait Storage: Send + Sync { async fn get_available_bandwidth( &self, client_address: DestinationAddressBytes, - ) -> Result<Option<i64>, StorageError>; + ) -> Result<Option<PersistedBandwidth>, StorageError>; - /// Increases available bandwidth of the particular client by the specified amount. + /// Sets available bandwidth of the particular client to the provided amount; /// /// # Arguments /// /// * `client_address`: address of the client - /// * `amount`: amount of available bandwidth to be added to the client. - async fn increase_bandwidth( - &self, - client_address: DestinationAddressBytes, - amount: i64, - ) -> Result<(), StorageError>; - - /// Decreases available bandwidth of the particular client by the specified amount. - /// - /// # Arguments - /// - /// * `client_address`: address of the client - /// * `amount`: amount of available bandwidth to be removed from the client. - async fn consume_bandwidth( + /// * `amount`: the updated client bandwidth amount. + async fn set_bandwidth( &self, client_address: DestinationAddressBytes, amount: i64, @@ -295,36 +306,44 @@ impl Storage for PersistentStorage { Ok(()) } - async fn get_available_bandwidth( + async fn set_freepass_expiration( &self, client_address: DestinationAddressBytes, - ) -> Result<Option<i64>, StorageError> { - let res = self - .bandwidth_manager - .get_available_bandwidth(&client_address.as_base58_string()) - .await - .map(|bandwidth_option| bandwidth_option.map(|bandwidth| bandwidth.available))?; - Ok(res) - } - - async fn increase_bandwidth( - &self, - client_address: DestinationAddressBytes, - amount: i64, + freepass_expiration: OffsetDateTime, ) -> Result<(), StorageError> { self.bandwidth_manager - .increase_available_bandwidth(&client_address.as_base58_string(), amount) + .set_freepass_expiration(&client_address.as_base58_string(), freepass_expiration) .await?; Ok(()) } - async fn consume_bandwidth( + async fn reset_freepass_bandwidth( + &self, + client_address: DestinationAddressBytes, + ) -> Result<(), StorageError> { + self.bandwidth_manager + .reset_freepass_bandwidth(&client_address.as_base58_string()) + .await?; + Ok(()) + } + + async fn get_available_bandwidth( + &self, + client_address: DestinationAddressBytes, + ) -> Result<Option<PersistedBandwidth>, StorageError> { + Ok(self + .bandwidth_manager + .get_available_bandwidth(&client_address.as_base58_string()) + .await?) + } + + async fn set_bandwidth( &self, client_address: DestinationAddressBytes, amount: i64, ) -> Result<(), StorageError> { self.bandwidth_manager - .decrease_available_bandwidth(&client_address.as_base58_string(), amount) + .set_available_bandwidth(&client_address.as_base58_string(), amount) .await?; Ok(()) } @@ -422,22 +441,29 @@ impl Storage for InMemStorage { todo!() } - async fn get_available_bandwidth( + async fn set_freepass_expiration( &self, _client_address: DestinationAddressBytes, - ) -> Result<Option<i64>, StorageError> { - todo!() - } - - async fn increase_bandwidth( - &self, - _client_address: DestinationAddressBytes, - _amount: i64, + _freepass_expiration: OffsetDateTime, ) -> Result<(), StorageError> { todo!() } - async fn consume_bandwidth( + async fn reset_freepass_bandwidth( + &self, + _client_address: DestinationAddressBytes, + ) -> Result<(), StorageError> { + todo!() + } + + async fn get_available_bandwidth( + &self, + _client_address: DestinationAddressBytes, + ) -> Result<Option<PersistedBandwidth>, StorageError> { + todo!() + } + + async fn set_bandwidth( &self, _client_address: DestinationAddressBytes, _amount: i64, diff --git a/gateway/src/node/storage/models.rs b/gateway/src/node/storage/models.rs index b3fde7d37a..999c9f827f 100644 --- a/gateway/src/node/storage/models.rs +++ b/gateway/src/node/storage/models.rs @@ -1,7 +1,9 @@ // Copyright 2021-2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::node::client_handling::websocket::connection_handler::AvailableBandwidth; use sqlx::FromRow; +use time::OffsetDateTime; pub struct PersistedSharedKeys { pub(crate) client_address_bs58: String, @@ -15,10 +17,30 @@ pub struct StoredMessage { pub(crate) content: Vec<u8>, } +#[derive(Debug, Clone, FromRow)] pub struct PersistedBandwidth { #[allow(dead_code)] pub(crate) client_address_bs58: String, pub(crate) available: i64, + pub(crate) freepass_expiration: Option<OffsetDateTime>, +} + +impl From<PersistedBandwidth> for AvailableBandwidth { + fn from(value: PersistedBandwidth) -> Self { + AvailableBandwidth { + bytes: value.available, + freepass_expiration: value.freepass_expiration, + } + } +} + +impl From<Option<PersistedBandwidth>> for AvailableBandwidth { + fn from(value: Option<PersistedBandwidth>) -> Self { + match value { + None => AvailableBandwidth::default(), + Some(b) => b.into(), + } + } } #[derive(Debug, Clone, FromRow)] From a53ae5b6b560f2e9c681225fa7371fd3d69a026a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 5 Mar 2024 08:57:48 +0000 Subject: [PATCH 373/394] using lock guard in dedicated scope --- .../connection_handler/authenticated.rs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 7c785547c1..8256186029 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -291,13 +291,6 @@ where credential.data.epoch_id ); - let aggregated_verification_key = self - .inner - .shared_state - .coconut_verifier - .verification_key(credential.data.epoch_id) - .await?; - if !credential.data.validate_type_attribute() { trace!("mismatch in the type attribute"); return Err(RequestHandlingError::InvalidTypeAttribute); @@ -314,15 +307,22 @@ where trace!("embedded bandwidth: {bandwidth:?}"); // locally verify the credential - let params = bandwidth_credential_params(); - if !credential.data.verify(params, &aggregated_verification_key) { - trace!("the credential did not verify correctly"); - return Err(RequestHandlingError::InvalidBandwidthCredential( - String::from("local credential verification has failed"), - )); - } + { + let aggregated_verification_key = self + .inner + .shared_state + .coconut_verifier + .verification_key(credential.data.epoch_id) + .await?; - drop(aggregated_verification_key); + let params = bandwidth_credential_params(); + if !credential.data.verify(params, &aggregated_verification_key) { + trace!("the credential did not verify correctly"); + return Err(RequestHandlingError::InvalidBandwidthCredential( + String::from("local credential verification has failed"), + )); + } + } let was_freepass = match credential.data.typ { CredentialType::Voucher => { From 67467ca76d96790c989b9cdf8d15829083f42eea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Tue, 5 Mar 2024 08:59:48 +0000 Subject: [PATCH 374/394] renamed 'shared_state' to 'common_state' --- .../websocket/{shared_state.rs => common_state.rs} | 2 +- .../client_handling/websocket/connection_handler/fresh.rs | 6 +++--- gateway/src/node/client_handling/websocket/listener.rs | 6 +++--- gateway/src/node/client_handling/websocket/mod.rs | 4 ++-- gateway/src/node/mod.rs | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) rename gateway/src/node/client_handling/websocket/{shared_state.rs => common_state.rs} (94%) diff --git a/gateway/src/node/client_handling/websocket/shared_state.rs b/gateway/src/node/client_handling/websocket/common_state.rs similarity index 94% rename from gateway/src/node/client_handling/websocket/shared_state.rs rename to gateway/src/node/client_handling/websocket/common_state.rs index 1f19476e97..e112997e57 100644 --- a/gateway/src/node/client_handling/websocket/shared_state.rs +++ b/gateway/src/node/client_handling/websocket/common_state.rs @@ -8,7 +8,7 @@ use std::sync::Arc; // I can see this being possible expanded with say storage or client store #[derive(Clone)] -pub(crate) struct SharedHandlerState { +pub(crate) struct CommonHandlerState { pub(crate) coconut_verifier: Arc<CoconutVerifier>, pub(crate) local_identity: Arc<identity::KeyPair>, pub(crate) only_coconut_credentials: bool, diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index aaf8e39518..947e22a292 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -25,8 +25,8 @@ use thiserror::Error; use tokio::io::{AsyncRead, AsyncWrite}; use tokio_tungstenite::tungstenite::{protocol::Message, Error as WsError}; +use crate::node::client_handling::websocket::common_state::CommonHandlerState; use crate::node::client_handling::websocket::connection_handler::AvailableBandwidth; -use crate::node::client_handling::websocket::shared_state::SharedHandlerState; use crate::node::{ client_handling::{ active_clients::ActiveClientsStore, @@ -89,7 +89,7 @@ impl InitialAuthenticationError { pub(crate) struct FreshHandler<R, S, St> { rng: R, - pub(crate) shared_state: SharedHandlerState, + pub(crate) shared_state: CommonHandlerState, pub(crate) active_clients_store: ActiveClientsStore, pub(crate) outbound_mix_sender: MixForwardingSender, pub(crate) socket_connection: SocketStream<S>, @@ -115,7 +115,7 @@ where outbound_mix_sender: MixForwardingSender, storage: St, active_clients_store: ActiveClientsStore, - shared_state: SharedHandlerState, + shared_state: CommonHandlerState, ) -> Self { FreshHandler { rng, diff --git a/gateway/src/node/client_handling/websocket/listener.rs b/gateway/src/node/client_handling/websocket/listener.rs index 9b073dbc5c..a33f6a0fb5 100644 --- a/gateway/src/node/client_handling/websocket/listener.rs +++ b/gateway/src/node/client_handling/websocket/listener.rs @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-3.0-only use crate::node::client_handling::active_clients::ActiveClientsStore; +use crate::node::client_handling::websocket::common_state::CommonHandlerState; use crate::node::client_handling::websocket::connection_handler::FreshHandler; -use crate::node::client_handling::websocket::shared_state::SharedHandlerState; use crate::node::storage::Storage; use log::*; use nym_mixnet_client::forwarder::MixForwardingSender; @@ -14,11 +14,11 @@ use tokio::task::JoinHandle; pub(crate) struct Listener { address: SocketAddr, - shared_state: SharedHandlerState, + shared_state: CommonHandlerState, } impl Listener { - pub(crate) fn new(address: SocketAddr, shared_state: SharedHandlerState) -> Self { + pub(crate) fn new(address: SocketAddr, shared_state: CommonHandlerState) -> Self { Listener { address, shared_state, diff --git a/gateway/src/node/client_handling/websocket/mod.rs b/gateway/src/node/client_handling/websocket/mod.rs index 6d0a990956..12c252feca 100644 --- a/gateway/src/node/client_handling/websocket/mod.rs +++ b/gateway/src/node/client_handling/websocket/mod.rs @@ -3,9 +3,9 @@ pub(crate) use listener::Listener; +pub(crate) mod common_state; pub(crate) mod connection_handler; pub(crate) mod listener; pub(crate) mod message_receiver; -pub(crate) mod shared_state; -pub(crate) use shared_state::SharedHandlerState; +pub(crate) use common_state::CommonHandlerState; diff --git a/gateway/src/node/mod.rs b/gateway/src/node/mod.rs index 5f5f57e164..c3aa3b5969 100644 --- a/gateway/src/node/mod.rs +++ b/gateway/src/node/mod.rs @@ -254,7 +254,7 @@ impl<St> Gateway<St> { self.config.gateway.clients_port, ); - let shared_state = websocket::SharedHandlerState { + let shared_state = websocket::CommonHandlerState { coconut_verifier, local_identity: Arc::clone(&self.identity_keypair), only_coconut_credentials: self.config.gateway.only_coconut_credentials, From f826904407b2c674898cd5268ac15f0730f4d686 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 11 Apr 2024 13:18:45 +0100 Subject: [PATCH 375/394] fix credential expiration + improve errors + naively stop client when out of bandwidth --- Cargo.lock | 2 + .../native/src/commands/import_credential.rs | 4 +- .../socks5/src/commands/import_credential.rs | 4 +- common/client-libs/gateway-client/Cargo.toml | 2 + .../gateway-client/src/socket_state.rs | 53 ++++++++-- .../migrations/20241104120000_add_unique.sql | 48 +++++++++ .../credential-storage/src/backends/sqlite.rs | 2 +- .../src/registration/handshake/error.rs | 2 +- gateway/gateway-requests/src/types.rs | 25 +++++ gateway/src/node/client_handling/bandwidth.rs | 40 ++++--- gateway/src/node/client_handling/mod.rs | 3 +- .../connection_handler/authenticated.rs | 66 +++++++++--- .../websocket/connection_handler/fresh.rs | 100 +++++++++++++----- .../websocket/connection_handler/mod.rs | 8 +- .../src/cli/import_credential.rs | 4 +- .../src/cli/import_credential.rs | 4 +- 16 files changed, 296 insertions(+), 71 deletions(-) create mode 100644 common/credential-storage/migrations/20241104120000_add_unique.sql diff --git a/Cargo.lock b/Cargo.lock index 023def4b50..c37bcc206f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5756,7 +5756,9 @@ dependencies = [ "nym-validator-client", "rand 0.7.3", "serde", + "si-scale", "thiserror", + "time", "tokio", "tokio-stream", "tokio-tungstenite", diff --git a/clients/native/src/commands/import_credential.rs b/clients/native/src/commands/import_credential.rs index c7327797d0..2e917ed226 100644 --- a/clients/native/src/commands/import_credential.rs +++ b/clients/native/src/commands/import_credential.rs @@ -8,5 +8,7 @@ use nym_client_core::cli_helpers::client_import_credential::{ }; pub(crate) async fn execute(args: CommonClientImportCredentialArgs) -> Result<(), ClientError> { - import_credential::<CliNativeClient, _>(args).await + import_credential::<CliNativeClient, _>(args).await?; + println!("successfully imported credential!"); + Ok(()) } diff --git a/clients/socks5/src/commands/import_credential.rs b/clients/socks5/src/commands/import_credential.rs index 91ea0bf552..d8f3d27bc9 100644 --- a/clients/socks5/src/commands/import_credential.rs +++ b/clients/socks5/src/commands/import_credential.rs @@ -10,5 +10,7 @@ use nym_client_core::cli_helpers::client_import_credential::{ pub(crate) async fn execute( args: CommonClientImportCredentialArgs, ) -> Result<(), Socks5ClientError> { - import_credential::<CliSocks5Client, _>(args).await + import_credential::<CliSocks5Client, _>(args).await?; + println!("successfully imported credential!"); + Ok(()) } diff --git a/common/client-libs/gateway-client/Cargo.toml b/common/client-libs/gateway-client/Cargo.toml index 218a7894b1..87902d3d10 100644 --- a/common/client-libs/gateway-client/Cargo.toml +++ b/common/client-libs/gateway-client/Cargo.toml @@ -16,6 +16,8 @@ thiserror = { workspace = true } url = { workspace = true } rand = { version = "0.7.3", features = ["wasm-bindgen"] } tokio = { version = "1.24.1", features = ["macros"] } +si-scale = "0.2.2" +time.workspace = true # internal nym-bandwidth-controller = { path = "../../bandwidth-controller" } diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index 44396a9dd3..b382be41cf 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -10,9 +10,14 @@ use futures::stream::{SplitSink, SplitStream}; use futures::{SinkExt, StreamExt}; use log::*; use nym_gateway_requests::registration::handshake::SharedKeys; +use nym_gateway_requests::ServerResponse; use nym_task::TaskClient; +use si_scale::helpers::bibytes2; use std::os::raw::c_int as RawFd; +use std::sync::atomic::{AtomicI64, Ordering}; use std::sync::Arc; +use std::time::Duration; +use time::OffsetDateTime; use tungstenite::Message; #[cfg(unix)] @@ -48,6 +53,21 @@ pub(crate) fn ws_fd(_conn: &WsConn) -> Option<RawFd> { None } +// disgusting? absolutely, but does the trick for now +static LAST_LOGGED_BANDWIDTH_TS: AtomicI64 = AtomicI64::new(0); + +fn maybe_log_bandwidth(remaining: i64) { + // SAFETY: this value is always populated with valid timestamps + let last = + OffsetDateTime::from_unix_timestamp(LAST_LOGGED_BANDWIDTH_TS.load(Ordering::Relaxed)) + .unwrap(); + let now = OffsetDateTime::now_utc(); + if last + Duration::from_secs(10) < now { + log::info!("remaining bandwidth: {}", bibytes2(remaining as f64)); + LAST_LOGGED_BANDWIDTH_TS.store(now.unix_timestamp(), Ordering::Relaxed) + } +} + pub(crate) struct PartiallyDelegated { sink_half: SplitSink<WsConn, Message>, delegated_stream: (SplitStreamReceiver, oneshot::Sender<()>), @@ -55,7 +75,10 @@ pub(crate) struct PartiallyDelegated { } impl PartiallyDelegated { - fn recover_received_plaintexts(ws_msgs: Vec<Message>, shared_key: &SharedKeys) -> Vec<Vec<u8>> { + fn recover_received_plaintexts( + ws_msgs: Vec<Message>, + shared_key: &SharedKeys, + ) -> Result<Vec<Vec<u8>>, GatewayClientError> { let mut plaintexts = Vec::with_capacity(ws_msgs.len()); for ws_msg in ws_msgs { match ws_msg { @@ -73,15 +96,32 @@ impl PartiallyDelegated { // TODO: those can return the "send confirmations" - perhaps it should be somehow worked around? Message::Text(text) => { trace!( - "received a text message - probably a response to some previous query! - {}", - text + "received a text message - probably a response to some previous query! - {text}", ); + match ServerResponse::try_from(text) + .map_err(|_| GatewayClientError::MalformedResponse)? + { + ServerResponse::Send { + remaining_bandwidth, + } => maybe_log_bandwidth(remaining_bandwidth), + ServerResponse::Error { message } => { + error!("gateway failure: {message}"); + return Err(GatewayClientError::GatewayError(message)); + } + other => { + warn!( + "received illegal message of type {} in an authenticated client", + other.name() + ) + } + } + continue; } _ => continue, } } - plaintexts + Ok(plaintexts) } fn route_socket_messages( @@ -89,7 +129,7 @@ impl PartiallyDelegated { packet_router: &PacketRouter, shared_key: &SharedKeys, ) -> Result<(), GatewayClientError> { - let plaintexts = Self::recover_received_plaintexts(ws_msgs, shared_key); + let plaintexts = Self::recover_received_plaintexts(ws_msgs, shared_key)?; packet_router.route_received(plaintexts) } @@ -129,7 +169,8 @@ impl PartiallyDelegated { }; if let Err(err) = Self::route_socket_messages(ws_msgs, &packet_router, shared_key.as_ref()) { - log::warn!("Route socket messages failed: {err}"); + log::error!("Route socket messages failed: {err}"); + break Err(err) } } }; diff --git a/common/credential-storage/migrations/20241104120000_add_unique.sql b/common/credential-storage/migrations/20241104120000_add_unique.sql new file mode 100644 index 0000000000..78043ca69d --- /dev/null +++ b/common/credential-storage/migrations/20241104120000_add_unique.sql @@ -0,0 +1,48 @@ +/* + * Copyright 2024 - Nym Technologies SA <contact@nymtech.net> + * SPDX-License-Identifier: Apache-2.0 + */ + +ALTER TABLE coconut_credentials + RENAME TO old_coconut_credentials; + +CREATE TABLE coconut_credentials +( + id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + +-- introduce a way for us to introduce breaking changes in serialization + serialization_revision INTEGER NOT NULL, + +-- the best we can do without enums + credential_type TEXT CHECK ( credential_type IN ('BandwidthVoucher', 'FreeBandwidthPass') ) NOT NULL, + credential_data BLOB NOT NULL UNIQUE, + epoch_id INTEGER NOT NULL, + +-- this field is only really applicable to free passes + expired BOOLEAN NOT NULL +); + +ALTER TABLE credential_usage + RENAME TO old_credential_usage; + +-- for bandwidth vouchers there's going to be only a single entry; for freepasses there can be as many as there are gateways +CREATE TABLE credential_usage +( + credential_id INTEGER NOT NULL REFERENCES coconut_credentials (id), + gateway_id_bs58 TEXT NOT NULL, + +-- no matter credential type, we can't spend the same credential with the same gateway multiple times + UNIQUE (credential_id, gateway_id_bs58) +); + +INSERT INTO coconut_credentials +SELECT * +FROM old_coconut_credentials; + + +INSERT INTO credential_usage +SELECT * +FROM old_credential_usage; + +DROP TABLE old_coconut_credentials; +DROP TABLE old_credential_usage; \ No newline at end of file diff --git a/common/credential-storage/src/backends/sqlite.rs b/common/credential-storage/src/backends/sqlite.rs index c356e09820..4d4face955 100644 --- a/common/credential-storage/src/backends/sqlite.rs +++ b/common/credential-storage/src/backends/sqlite.rs @@ -44,7 +44,7 @@ impl CoconutCredentialManager { r#" SELECT * FROM coconut_credentials - WHERE coconut_credentials.credential_type == "FreeBandwidthPass" + WHERE coconut_credentials.credential_type == "FreeBandwidthPass" AND coconut_credentials.expired = false AND NOT EXISTS (SELECT 1 FROM credential_usage WHERE credential_usage.credential_id = coconut_credentials.id diff --git a/gateway/gateway-requests/src/registration/handshake/error.rs b/gateway/gateway-requests/src/registration/handshake/error.rs index f1357f7815..8fee78fd38 100644 --- a/gateway/gateway-requests/src/registration/handshake/error.rs +++ b/gateway/gateway-requests/src/registration/handshake/error.rs @@ -4,7 +4,7 @@ use nym_crypto::asymmetric::identity; use thiserror::Error; -#[derive(Debug, Error)] +#[derive(Debug, Clone, Error)] pub enum HandshakeError { #[error( "received key material of invalid length - {0}. Expected: {}", diff --git a/gateway/gateway-requests/src/types.rs b/gateway/gateway-requests/src/types.rs index 04fcb0c8a8..1da37fd0ab 100644 --- a/gateway/gateway-requests/src/types.rs +++ b/gateway/gateway-requests/src/types.rs @@ -190,6 +190,22 @@ impl ClientControlRequest { } } + pub fn name(&self) -> String { + match self { + ClientControlRequest::Authenticate { .. } => "Authenticate".to_string(), + ClientControlRequest::RegisterHandshakeInitRequest { .. } => { + "RegisterHandshakeInitRequest".to_string() + } + ClientControlRequest::BandwidthCredential { .. } => "BandwidthCredential".to_string(), + ClientControlRequest::BandwidthCredentialV2 { .. } => { + "BandwidthCredentialV2".to_string() + } + ClientControlRequest::ClaimFreeTestnetBandwidth => { + "ClaimFreeTestnetBandwidth".to_string() + } + } + } + pub fn new_enc_coconut_bandwidth_credential_v1( credential: &OldV1Credential, shared_key: &SharedKeys, @@ -291,6 +307,15 @@ pub enum ServerResponse { } impl ServerResponse { + pub fn name(&self) -> String { + match self { + ServerResponse::Authenticate { .. } => "Authenticate".to_string(), + ServerResponse::Register { .. } => "Register".to_string(), + ServerResponse::Bandwidth { .. } => "Bandwidth".to_string(), + ServerResponse::Send { .. } => "Send".to_string(), + ServerResponse::Error { .. } => "Error".to_string(), + } + } pub fn new_error<S: Into<String>>(msg: S) -> Self { ServerResponse::Error { message: msg.into(), diff --git a/gateway/src/node/client_handling/bandwidth.rs b/gateway/src/node/client_handling/bandwidth.rs index 10d1f50b3c..d4ce709c96 100644 --- a/gateway/src/node/client_handling/bandwidth.rs +++ b/gateway/src/node/client_handling/bandwidth.rs @@ -42,18 +42,35 @@ pub struct Bandwidth { } impl Bandwidth { - pub const fn new(value: u64) -> Bandwidth { + pub const fn new_unchecked(value: u64) -> Bandwidth { Bandwidth { value } } - pub fn try_from_raw_value(value: &str, typ: CredentialType) -> Result<Self, BandwidthError> { - let bandwidth_value = + pub fn new(bandwidth_value: u64) -> Result<Bandwidth, BandwidthError> { + if bandwidth_value > i64::MAX as u64 { + // note that this would have represented more than 1 exabyte, + // which is like 125,000 worth of hard drives, so I don't think we have + // to worry about it for now... + warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now"); + return Err(BandwidthError::UnsupportedBandwidthValue(bandwidth_value)); + } + + Ok(Bandwidth { + value: bandwidth_value, + }) + } + + pub(crate) fn parse_raw_bandwidth( + value: &str, + typ: CredentialType, + ) -> Result<(u64, Option<OffsetDateTime>), BandwidthError> { + let (bandwidth_value, freepass_expiration) = match typ { CredentialType::Voucher => { let token_value: u64 = value .parse() .map_err(|source| BandwidthError::VoucherValueParsingFailure { source })?; - token_value * nym_network_defaults::BYTES_PER_UTOKEN + (token_value * nym_network_defaults::BYTES_PER_UTOKEN, None) } CredentialType::FreePass => { let expiry_timestamp: i64 = value @@ -70,21 +87,10 @@ impl Bandwidth { if expiry_date < now { return Err(BandwidthError::ExpiredFreePass { expiry_date }); } - nym_network_defaults::BYTES_PER_FREEPASS + (nym_network_defaults::BYTES_PER_FREEPASS, Some(expiry_date)) } }; - - if bandwidth_value > i64::MAX as u64 { - // note that this would have represented more than 1 exabyte, - // which is like 125,000 worth of hard drives, so I don't think we have - // to worry about it for now... - warn!("Somehow we received bandwidth value higher than 9223372036854775807. We don't really want to deal with this now"); - return Err(BandwidthError::UnsupportedBandwidthValue(bandwidth_value)); - } - - Ok(Bandwidth { - value: bandwidth_value, - }) + Ok((bandwidth_value, freepass_expiration)) } pub fn value(&self) -> u64 { diff --git a/gateway/src/node/client_handling/mod.rs b/gateway/src/node/client_handling/mod.rs index b43bb631a2..b195b8d693 100644 --- a/gateway/src/node/client_handling/mod.rs +++ b/gateway/src/node/client_handling/mod.rs @@ -8,4 +8,5 @@ mod bandwidth; pub(crate) mod embedded_clients; pub(crate) mod websocket; -pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = Bandwidth::new(64 * 1024 * 1024 * 1024); // 64GB +pub(crate) const FREE_TESTNET_BANDWIDTH_VALUE: Bandwidth = + Bandwidth::new_unchecked(64 * 1024 * 1024 * 1024); // 64GB diff --git a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs index 8256186029..249f60997f 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/authenticated.rs @@ -44,6 +44,11 @@ pub enum RequestHandlingError { #[error("Internal gateway storage error")] StorageError(#[from] StorageError), + #[error( + "the database entry for bandwidth of the registered client {client_address} is missing!" + )] + MissingClientBandwidthEntry { client_address: String }, + #[error("Provided bandwidth IV is malformed - {0}")] MalformedIV(#[from] IVConversionError), @@ -53,8 +58,8 @@ pub enum RequestHandlingError { #[error("Provided binary request was malformed - {0}")] InvalidTextRequest(<ClientControlRequest as TryFrom<String>>::Error), - #[error("The received request is not valid in the current context")] - IllegalRequest, + #[error("The received request is not valid in the current context: {additional_context}")] + IllegalRequest { additional_context: String }, #[error("Provided bandwidth credential did not verify correctly on {0}")] InvalidBandwidthCredential(String), @@ -92,8 +97,8 @@ pub enum RequestHandlingError { #[error("the provided credential did not contain a valid type attribute")] InvalidTypeAttribute, - #[error("insufficient bandwidth available to process the request")] - OutOfBandwidth, + #[error("insufficient bandwidth available to process the request. required: {required}B, available: {available}B")] + OutOfBandwidth { required: i64, available: i64 }, #[error("the provided credential did not have a bandwidth attribute")] MissingBandwidthAttribute, @@ -179,7 +184,9 @@ where .storage .get_available_bandwidth(client.address) .await? - .ok_or(RequestHandlingError::IllegalRequest)?; + .ok_or(RequestHandlingError::MissingClientBandwidthEntry { + client_address: client.address.as_base58_string(), + })?; Ok(AuthenticatedHandler { inner: fresh, @@ -220,6 +227,19 @@ where self.flush_bandwidth().await } + async fn set_freepass_expiration( + &mut self, + expiration: OffsetDateTime, + ) -> Result<(), RequestHandlingError> { + self.client_bandwidth.bandwidth.freepass_expiration = Some(expiration); + self.inner + .storage + .set_freepass_expiration(self.client.address, expiration) + .await?; + self.client_bandwidth.update_flush_data(); + Ok(()) + } + /// Decreases the amount of available bandwidth of the connected client by the specified value. /// /// # Arguments @@ -302,7 +322,10 @@ where }; // this will extract token amounts out of bandwidth vouchers and validate expiry of free passes - let bandwidth = Bandwidth::try_from_raw_value(bandwidth_attribute, credential.data.typ)?; + let (raw_bandwidth, freepass_expiration) = + Bandwidth::parse_raw_bandwidth(bandwidth_attribute, credential.data.typ)?; + + let bandwidth = Bandwidth::new(raw_bandwidth)?; trace!("embedded bandwidth: {bandwidth:?}"); @@ -324,7 +347,7 @@ where } } - let was_freepass = match credential.data.typ { + match credential.data.typ { CredentialType::Voucher => { trace!("the credential is a bandwidth voucher. attempting to release the funds"); let api_clients = self @@ -339,15 +362,12 @@ where .coconut_verifier .release_bandwidth_voucher_funds(&api_clients, credential) .await?; - false } CredentialType::FreePass => { // no need to do anything special here, we already extracted the bandwidth amount and checked expiry info!("received a free pass credential"); - - true } - }; + } // technically this is not atomic, i.e. checking for the spending and then marking as spent, // but because we have the `UNIQUE` constraint on the database table @@ -360,11 +380,20 @@ where trace!("storing serial number information"); self.inner .storage - .insert_spent_credential(serial_number, was_freepass, self.client.address) + .insert_spent_credential( + serial_number, + freepass_expiration.is_some(), + self.client.address, + ) .await?; trace!("increasing client bandwidth"); self.increase_bandwidth(bandwidth).await?; + // set free pass expiration + if let Some(expiration) = freepass_expiration { + self.set_freepass_expiration(expiration).await?; + } + let available_total = self.client_bandwidth.bandwidth.bytes; Ok(ServerResponse::Bandwidth { available_total }) @@ -447,7 +476,10 @@ where let available_bandwidth = self.client_bandwidth.bandwidth.bytes; if available_bandwidth < required_bandwidth { - return Err(RequestHandlingError::OutOfBandwidth); + return Err(RequestHandlingError::OutOfBandwidth { + required: required_bandwidth, + available: available_bandwidth, + }); } self.consume_bandwidth(required_bandwidth).await?; @@ -523,7 +555,13 @@ where .handle_claim_testnet_bandwidth() .await .into_ws_message(), - _ => RequestHandlingError::IllegalRequest.into_error_message(), + other => RequestHandlingError::IllegalRequest { + additional_context: format!( + "received illegal message of type {} in an authenticated client", + other.name() + ), + } + .into_error_message(), }, } } diff --git a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs index 947e22a292..4f00ebcf90 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/fresh.rs @@ -1,6 +1,7 @@ // Copyright 2021-2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +use crate::error::RequestHandlingError; use futures::{ channel::{mpsc, oneshot}, SinkExt, StreamExt, @@ -78,11 +79,44 @@ pub(crate) enum InitialAuthenticationError { #[error("Attempted to negotiate connection with client using incompatible protocol version. Ours is {current} and the client reports {client:?}")] IncompatibleProtocol { client: Option<u8>, current: u8 }, + + #[error("failed to send authentication error response: {source}")] + ErrorResponseSendFailure { + #[source] + source: WsError, + }, + + #[error("failed to send authentication response: {source}")] + ResponseSendFailure { + #[source] + source: WsError, + }, + + #[error("possibly received a sphinx packet without prior authentication. Request is going to be ignored")] + BinaryRequestWithoutAuthentication, + + #[error("received a connection close message")] + CloseMessage, + + #[error("the connection has unexpectedly closed")] + ClosedConnection, + + #[error("failed to obtain message from websocket stream: {source}")] + FailedToReadMessage { + #[source] + source: WsError, + }, + + #[error("could not establish client details")] + EmptyClientDetails, + + #[error("failed to upgrade the client handler: {source}")] + HandlerUpgradeFailure { source: RequestHandlingError }, } impl InitialAuthenticationError { /// Converts this Error into an appropriate websocket Message. - fn into_error_message(self) -> Message { + fn to_error_message(&self) -> Message { ServerResponse::new_error(self.to_string()).into() } } @@ -665,7 +699,7 @@ where // TODO: somehow cleanup this method pub(crate) async fn perform_initial_authentication( mut self, - ) -> Option<AuthenticatedHandler<R, S, St>> + ) -> Result<AuthenticatedHandler<R, S, St>, InitialAuthenticationError> where S: AsyncRead + AsyncWrite + Unpin + Send, { @@ -674,40 +708,51 @@ where while let Some(msg) = self.read_websocket_message().await { let msg = match msg { Ok(msg) => msg, - Err(err) => { - debug!("failed to obtain message from websocket stream! stopping connection handler: {err}"); - break; + Err(source) => { + debug!("failed to obtain message from websocket stream! stopping connection handler: {source}"); + return Err(InitialAuthenticationError::FailedToReadMessage { source }); } }; if msg.is_close() { - break; + return Err(InitialAuthenticationError::CloseMessage); } // ONLY handle 'Authenticate' or 'Register' requests, ignore everything else match msg { - Message::Close(_) => break, + // we have explicitly checked for close message + Message::Close(_) => unreachable!(), Message::Text(text_msg) => { let (mix_sender, mix_receiver) = mpsc::unbounded(); - match self.handle_initial_authentication_request(text_msg).await { + return match self.handle_initial_authentication_request(text_msg).await { Err(err) => { - if let Err(err) = - self.send_websocket_message(err.into_error_message()).await + debug!("authentication failure: {err}"); + + // try to send error to the client + if let Err(source) = + self.send_websocket_message(err.to_error_message()).await { - debug!("Failed to send authentication error response - {err}"); - return None; + debug!("Failed to send authentication error response: {source}"); + return Err(InitialAuthenticationError::ErrorResponseSendFailure { + source, + }); } + // return the underlying error + Err(err) } Ok(auth_result) => { - if let Err(err) = self + // try to send auth response back to the client + if let Err(source) = self .send_websocket_message(auth_result.server_response.into()) .await { - debug!("Failed to send authentication response - {err}"); - return None; + debug!("Failed to send authentication response: {source}"); + return Err(InitialAuthenticationError::ResponseSendFailure { + source, + }); } - return if let Some(client_details) = auth_result.client_details { + if let Some(client_details) = auth_result.client_details { // Channel for handlers to ask other handlers if they are still active. let (is_active_request_sender, is_active_request_receiver) = mpsc::unbounded(); @@ -723,18 +768,22 @@ where is_active_request_receiver, ) .await - .ok() + .map_err(|source| { + InitialAuthenticationError::HandlerUpgradeFailure { source } + }) } else { - None - }; + // honestly, it's been so long I don't remember under what conditions its possible (if at all) + // to have empty client details + Err(InitialAuthenticationError::EmptyClientDetails) + } } - } + }; } Message::Binary(_) => { // perhaps logging level should be reduced here, let's leave it for now and see what happens // if client is working correctly, this should have never happened debug!("possibly received a sphinx packet without prior authentication. Request is going to be ignored"); - if let Err(err) = self + if let Err(source) = self .send_websocket_message( ServerResponse::new_error( "binary request without prior authentication", @@ -743,15 +792,18 @@ where ) .await { - debug!("Failed to send error response during authentication: {err}",) + return Err(InitialAuthenticationError::ErrorResponseSendFailure { + source, + }); } - return None; + return Err(InitialAuthenticationError::BinaryRequestWithoutAuthentication); } _ => continue, }; } - None + + Err(InitialAuthenticationError::ClosedConnection) } pub(crate) async fn start_handling(self, shutdown: nym_task::TaskClient) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index 84f61d6652..28ddf78057 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -106,11 +106,11 @@ pub(crate) async fn handle_connection<R, S, St>( trace!("received shutdown signal while performing initial authentication"); return; } - Some(None) => { - warn!("authentication has failed"); + Some(Err(err)) => { + warn!("authentication has failed: {err}"); return; } - Some(Some(auth_handle)) => auth_handle.listen_for_requests(shutdown).await, + Some(Ok(auth_handle)) => auth_handle.listen_for_requests(shutdown).await, } trace!("The handler is done!"); @@ -148,6 +148,8 @@ impl AvailableBandwidth { if expiration < OffsetDateTime::now_utc() { return true; } + } else { + println!("no free pass expiration"); } false } diff --git a/service-providers/ip-packet-router/src/cli/import_credential.rs b/service-providers/ip-packet-router/src/cli/import_credential.rs index 2ef4119803..3c5fd47e56 100644 --- a/service-providers/ip-packet-router/src/cli/import_credential.rs +++ b/service-providers/ip-packet-router/src/cli/import_credential.rs @@ -10,5 +10,7 @@ use nym_ip_packet_router::error::IpPacketRouterError; pub(crate) async fn execute( args: CommonClientImportCredentialArgs, ) -> Result<(), IpPacketRouterError> { - import_credential::<CliIpPacketRouterClient, _>(args).await + import_credential::<CliIpPacketRouterClient, _>(args).await?; + println!("successfully imported credential!"); + Ok(()) } diff --git a/service-providers/network-requester/src/cli/import_credential.rs b/service-providers/network-requester/src/cli/import_credential.rs index aeb42d79b7..24b999ccd6 100644 --- a/service-providers/network-requester/src/cli/import_credential.rs +++ b/service-providers/network-requester/src/cli/import_credential.rs @@ -10,5 +10,7 @@ use nym_client_core::cli_helpers::client_import_credential::{ pub(crate) async fn execute( args: CommonClientImportCredentialArgs, ) -> Result<(), NetworkRequesterError> { - import_credential::<CliNetworkRequesterClient, _>(args).await + import_credential::<CliNetworkRequesterClient, _>(args).await?; + println!("successfully imported credential!"); + Ok(()) } From 862a248902d9d3e70385432dad46e0d048bf3f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 12 Apr 2024 15:14:55 +0100 Subject: [PATCH 376/394] missing cli argument for controlling nyxd --- nym-node/src/cli/helpers.rs | 11 +++++++++++ nym-node/src/env.rs | 1 + 2 files changed, 12 insertions(+) diff --git a/nym-node/src/cli/helpers.rs b/nym-node/src/cli/helpers.rs index ad4e923269..74469a4fcc 100644 --- a/nym-node/src/cli/helpers.rs +++ b/nym-node/src/cli/helpers.rs @@ -195,6 +195,14 @@ pub(crate) struct MixnetArgs { env = NYMNODE_NYM_APIS_ARG )] pub(crate) nym_api_urls: Option<Vec<Url>>, + + /// Addresses to nyxd chain endpoint which the node will use for chain interactions. + #[clap( + long, + value_delimiter = ',', + env = NYMNODE_NYXD_URLS_ARG + )] + pub(crate) nyxd_urls: Option<Vec<Url>>, } impl MixnetArgs { @@ -210,6 +218,9 @@ impl MixnetArgs { if let Some(nym_api_urls) = self.nym_api_urls { section.nym_api_urls = nym_api_urls } + if let Some(nyxd_urls) = self.nyxd_urls { + section.nyxd_urls = nyxd_urls + } section } } diff --git a/nym-node/src/env.rs b/nym-node/src/env.rs index a8e785499e..f7594ccbc2 100644 --- a/nym-node/src/env.rs +++ b/nym-node/src/env.rs @@ -34,6 +34,7 @@ pub mod vars { // mixnet: pub const NYMNODE_MIXNET_BIND_ADDRESS_ARG: &str = "NYMNODE_MIXNET_BIND_ADDRESS"; pub const NYMNODE_NYM_APIS_ARG: &str = "NYMNODE_NYM_APIS"; + pub const NYMNODE_NYXD_URLS_ARG: &str = "NYMNODE_NYXD"; // wireguard: pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED"; From 328d1c25b710fa1d1a9eb5a9e8c24da7d0d30722 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 12 Apr 2024 15:23:37 +0100 Subject: [PATCH 377/394] removed old debug code --- .../node/client_handling/websocket/connection_handler/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs index 28ddf78057..ee880d4832 100644 --- a/gateway/src/node/client_handling/websocket/connection_handler/mod.rs +++ b/gateway/src/node/client_handling/websocket/connection_handler/mod.rs @@ -148,8 +148,6 @@ impl AvailableBandwidth { if expiration < OffsetDateTime::now_utc() { return true; } - } else { - println!("no free pass expiration"); } false } From a785950d76a1ed958f270a6552df50f805f90ad6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 12 Apr 2024 16:43:22 +0100 Subject: [PATCH 378/394] [bugfix] don't shutdown NR on failed connection (#4539) --- common/task/src/manager.rs | 4 ++++ service-providers/network-requester/src/core.rs | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/common/task/src/manager.rs b/common/task/src/manager.rs index 523d22aae5..ab03870dc0 100644 --- a/common/task/src/manager.rs +++ b/common/task/src/manager.rs @@ -474,6 +474,10 @@ impl TaskClient { self.mode.set_should_not_signal_on_drop(); } + pub fn disarm(&mut self) { + self.mark_as_success(); + } + pub fn send_we_stopped(&mut self, err: SentError) { if self.mode.is_dummy() { return; diff --git a/service-providers/network-requester/src/core.rs b/service-providers/network-requester/src/core.rs index b84124aff0..6d4533e6c4 100644 --- a/service-providers/network-requester/src/core.rs +++ b/service-providers/network-requester/src/core.rs @@ -444,7 +444,7 @@ impl NRServiceProvider { controller_sender: ControllerSender, mix_input_sender: MixProxySender<MixnetMessage>, lane_queue_lengths: LaneQueueLengths, - shutdown: TaskClient, + mut shutdown: TaskClient, ) { let mut conn = match socks5::tcp::Connection::new( connection_id, @@ -456,6 +456,7 @@ impl NRServiceProvider { Ok(conn) => conn, Err(err) => { log::error!("error while connecting to {remote_addr}: {err}",); + shutdown.disarm(); // inform the remote that the connection is closed before it even was established let mixnet_message = MixnetMessage::new_network_data_response( From 4865f7f205597bff63007f21893da4a20f69e26d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 12 Apr 2024 16:44:32 +0100 Subject: [PATCH 379/394] [bugfix] Prevent generation of free passes with expiry date in the past (#4535) --- common/commands/src/coconut/generate_freepass.rs | 4 ++++ nym-api/src/coconut/api_routes/mod.rs | 4 ++++ nym-api/src/coconut/error.rs | 3 +++ 3 files changed, 11 insertions(+) diff --git a/common/commands/src/coconut/generate_freepass.rs b/common/commands/src/coconut/generate_freepass.rs index b10dd2bbc4..6ea535ebfe 100644 --- a/common/commands/src/coconut/generate_freepass.rs +++ b/common/commands/src/coconut/generate_freepass.rs @@ -148,6 +148,10 @@ pub async fn execute(args: Args, client: SigningClient) -> anyhow::Result<()> { bail!("the provided free pass request has too long expiry (expiry is set to on {expiration_date})") } + if expiration_date < now { + bail!("the provided free pass expiry is set in the past!") + } + // issuance start block_until_coconut_is_available(&client).await?; diff --git a/nym-api/src/coconut/api_routes/mod.rs b/nym-api/src/coconut/api_routes/mod.rs index 9b38eaf135..31bfd4bf6a 100644 --- a/nym-api/src/coconut/api_routes/mod.rs +++ b/nym-api/src/coconut/api_routes/mod.rs @@ -67,6 +67,10 @@ fn validate_freepass_public_attributes(res: &FreePassRequest) -> Result<()> { return Err(CoconutError::TooLongFreePass { expiry_date }); } + if expiry_date < now { + return Err(CoconutError::FreePassExpiryInThePast { expiry_date }); + } + Ok(()) } diff --git a/nym-api/src/coconut/error.rs b/nym-api/src/coconut/error.rs index 593e78a016..b4587191bb 100644 --- a/nym-api/src/coconut/error.rs +++ b/nym-api/src/coconut/error.rs @@ -82,6 +82,9 @@ pub enum CoconutError { )] TooLongFreePass { expiry_date: OffsetDateTime }, + #[error("the provided free pass expiry is set in the past!")] + FreePassExpiryInThePast { expiry_date: OffsetDateTime }, + #[error("the received bandwidth voucher did not contain deposit value")] MissingBandwidthValue, From 3e12766afd5498a710b068e574e0eb03e3370fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Fri, 12 Apr 2024 18:05:28 +0100 Subject: [PATCH 380/394] expose info whether entry gateway enforces zk-nym in self-described api (#4529) --- gateway/src/http/mod.rs | 1 + nym-node/nym-node-requests/src/api/v1/gateway/models.rs | 3 +++ nym-node/src/node/mod.rs | 1 + 3 files changed, 5 insertions(+) diff --git a/gateway/src/http/mod.rs b/gateway/src/http/mod.rs index 1d81f4a457..db15fc2a85 100644 --- a/gateway/src/http/mod.rs +++ b/gateway/src/http/mod.rs @@ -33,6 +33,7 @@ fn load_gateway_details( }; Ok(api_requests::v1::gateway::models::Gateway { + enforces_zk_nyms: config.gateway.only_coconut_credentials, client_interfaces: api_requests::v1::gateway::models::ClientInterfaces { wireguard, mixnet_websockets: Some(api_requests::v1::gateway::models::WebSockets { diff --git a/nym-node/nym-node-requests/src/api/v1/gateway/models.rs b/nym-node/nym-node-requests/src/api/v1/gateway/models.rs index 6287e9612a..da3414ad45 100644 --- a/nym-node/nym-node-requests/src/api/v1/gateway/models.rs +++ b/nym-node/nym-node-requests/src/api/v1/gateway/models.rs @@ -7,6 +7,9 @@ use serde::{Deserialize, Serialize}; #[derive(Serialize, Deserialize, Debug, Clone, JsonSchema)] #[cfg_attr(feature = "openapi", derive(utoipa::ToSchema))] pub struct Gateway { + #[serde(default)] + pub enforces_zk_nyms: bool, + pub client_interfaces: ClientInterfaces, } diff --git a/nym-node/src/node/mod.rs b/nym-node/src/node/mod.rs index 7127a03a15..22ea17fccd 100644 --- a/nym-node/src/node/mod.rs +++ b/nym-node/src/node/mod.rs @@ -484,6 +484,7 @@ impl NymNode { wss_port: self.config.entry_gateway.announce_wss_port, }); let gateway_details = api_requests::v1::gateway::models::Gateway { + enforces_zk_nyms: self.config.entry_gateway.enforce_zk_nyms, client_interfaces: api_requests::v1::gateway::models::ClientInterfaces { wireguard, mixnet_websockets, From 1f2d88862672d0be63ac8729f062e47955851cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 15 Apr 2024 14:11:26 +0200 Subject: [PATCH 381/394] Handle selected gateway in rust sdk (#4515) * Set active gateway after setting up gateway in base client * Elevate log statements in gateway setup * Add debug implementations for some gateway setup types * Rework gateway setup in rust sdk mixnet client * Remove unused KeyMode type * Remove pub from internal setters * Remove pseudo builder methods * Make create_bandwidth_client pub * Downgrade log statement to debug * Revert set_active_gateway in base_client * Rename to set_active_gateway_if_previously_registered --- common/bandwidth-controller/src/lib.rs | 1 + common/client-core/src/init/mod.rs | 6 +- .../client-libs/gateway-client/src/client.rs | 2 + .../gateway-client/src/socket_state.rs | 2 + .../src/ephemeral_storage.rs | 8 + common/wasm/utils/src/websocket/mod.rs | 7 + sdk/rust/nym-sdk/src/mixnet.rs | 2 +- sdk/rust/nym-sdk/src/mixnet/client.rs | 230 +++++++++--------- sdk/rust/nym-sdk/src/mixnet/config.rs | 18 -- 9 files changed, 141 insertions(+), 135 deletions(-) diff --git a/common/bandwidth-controller/src/lib.rs b/common/bandwidth-controller/src/lib.rs index 33f9428e44..c7aed707f9 100644 --- a/common/bandwidth-controller/src/lib.rs +++ b/common/bandwidth-controller/src/lib.rs @@ -18,6 +18,7 @@ pub mod acquire; pub mod error; mod utils; +#[derive(Debug)] pub struct BandwidthController<C, St> { storage: St, client: C, diff --git a/common/client-core/src/init/mod.rs b/common/client-core/src/init/mod.rs index a45c87da6a..63f0a98e0c 100644 --- a/common/client-core/src/init/mod.rs +++ b/common/client-core/src/init/mod.rs @@ -201,7 +201,7 @@ where log::debug!("Setting up gateway"); match setup { GatewaySetup::MustLoad { gateway_id } => { - log::trace!("GatewaySetup::MustLoad with id: {gateway_id:?}"); + log::debug!("GatewaySetup::MustLoad with id: {gateway_id:?}"); use_loaded_gateway_details(key_store, details_store, gateway_id).await } GatewaySetup::New { @@ -209,7 +209,7 @@ where available_gateways, wg_tun_address, } => { - log::trace!("GatewaySetup::New with spec: {specification:?}"); + log::debug!("GatewaySetup::New with spec: {specification:?}"); setup_new_gateway( key_store, details_store, @@ -224,7 +224,7 @@ where gateway_details, client_keys: managed_keys, } => { - log::trace!("GatewaySetup::ReuseConnection"); + log::debug!("GatewaySetup::ReuseConnection"); Ok(reuse_gateway_connection( authenticated_ephemeral_client, *gateway_details, diff --git a/common/client-libs/gateway-client/src/client.rs b/common/client-libs/gateway-client/src/client.rs index 4d14d30fc2..633832889e 100644 --- a/common/client-libs/gateway-client/src/client.rs +++ b/common/client-libs/gateway-client/src/client.rs @@ -79,6 +79,7 @@ impl GatewayConfig { } // TODO: this should be refactored into a state machine that keeps track of its authentication state +#[derive(Debug)] pub struct GatewayClient<C, St = EphemeralCredentialStorage> { authenticated: bool, disabled_credentials_mode: bool, @@ -849,6 +850,7 @@ impl<C, St> GatewayClient<C, St> { // type alias for an ease of use pub type InitGatewayClient = GatewayClient<InitOnly>; +#[derive(Debug)] pub struct InitOnly; impl GatewayClient<InitOnly, EphemeralCredentialStorage> { diff --git a/common/client-libs/gateway-client/src/socket_state.rs b/common/client-libs/gateway-client/src/socket_state.rs index b382be41cf..386ad5b147 100644 --- a/common/client-libs/gateway-client/src/socket_state.rs +++ b/common/client-libs/gateway-client/src/socket_state.rs @@ -68,6 +68,7 @@ fn maybe_log_bandwidth(remaining: i64) { } } +#[derive(Debug)] pub(crate) struct PartiallyDelegated { sink_half: SplitSink<WsConn, Message>, delegated_stream: (SplitStreamReceiver, oneshot::Sender<()>), @@ -262,6 +263,7 @@ impl PartiallyDelegated { // we can either have the stream itself or an option to re-obtain it // by notifying the future owning it to finish the execution and awaiting the result // which should be almost immediate (or an invalid state which should never, ever happen) +#[derive(Debug)] pub(crate) enum SocketState { Available(Box<WsConn>), PartiallyDelegated(PartiallyDelegated), diff --git a/common/credential-storage/src/ephemeral_storage.rs b/common/credential-storage/src/ephemeral_storage.rs index 97d456ea46..ead11edcf8 100644 --- a/common/credential-storage/src/ephemeral_storage.rs +++ b/common/credential-storage/src/ephemeral_storage.rs @@ -1,6 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: Apache-2.0 +use std::fmt::{self, Debug, Formatter}; + use crate::backends::memory::CoconutCredentialManager; use crate::error::StorageError; use crate::models::{StorableIssuedCredential, StoredIssuedCredential}; @@ -23,6 +25,12 @@ impl Default for EphemeralStorage { } } +impl Debug for EphemeralStorage { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "EphemeralStorage") + } +} + #[async_trait] impl Storage for EphemeralStorage { type StorageError = StorageError; diff --git a/common/wasm/utils/src/websocket/mod.rs b/common/wasm/utils/src/websocket/mod.rs index 5978f0940d..be95a8bf12 100644 --- a/common/wasm/utils/src/websocket/mod.rs +++ b/common/wasm/utils/src/websocket/mod.rs @@ -6,6 +6,7 @@ use futures::{Sink, Stream}; use gloo_net::websocket::futures::WebSocket; use gloo_net::websocket::{Message, WebSocketError}; use gloo_utils::errors::JsError; +use std::fmt::{self, Formatter}; use std::io; use std::pin::Pin; use std::task::{Context, Poll}; @@ -77,6 +78,12 @@ impl Stream for JSWebsocket { } } +impl fmt::Debug for JSWebsocket { + fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { + write!(f, "JSWebSocket") + } +} + impl Sink<WsMessage> for JSWebsocket { type Error = WsError; diff --git a/sdk/rust/nym-sdk/src/mixnet.rs b/sdk/rust/nym-sdk/src/mixnet.rs index 575a273fd0..04c03659c0 100644 --- a/sdk/rust/nym-sdk/src/mixnet.rs +++ b/sdk/rust/nym-sdk/src/mixnet.rs @@ -39,7 +39,7 @@ mod socks5_client; mod traits; pub use client::{DisconnectedMixnetClient, IncludedSurbs, MixnetClientBuilder}; -pub use config::{Config, KeyMode}; +pub use config::Config; pub use native_client::MixnetClient; pub use native_client::MixnetClientSender; pub use nym_client_core::{ diff --git a/sdk/rust/nym-sdk/src/mixnet/client.rs b/sdk/rust/nym-sdk/src/mixnet/client.rs index b313391b6e..cfcc6b3f45 100644 --- a/sdk/rust/nym-sdk/src/mixnet/client.rs +++ b/sdk/rust/nym-sdk/src/mixnet/client.rs @@ -10,8 +10,11 @@ use crate::NymNetworkDetails; use crate::{Error, Result}; use futures::channel::mpsc; use futures::StreamExt; -use log::warn; -use nym_client_core::client::base_client::storage::helpers::get_all_registered_identities; +use log::{debug, warn}; +use nym_client_core::client::base_client::storage::helpers::{ + get_active_gateway_identity, get_all_registered_identities, has_gateway_details, + set_active_gateway, +}; use nym_client_core::client::base_client::storage::{ Ephemeral, GatewaysDetailsStore, MixnetClientStorage, OnDiskPersistent, }; @@ -23,6 +26,7 @@ use nym_client_core::client::{ use nym_client_core::config::DebugConfig; use nym_client_core::error::ClientCoreError; use nym_client_core::init::helpers::current_gateways; +use nym_client_core::init::setup_gateway; use nym_client_core::init::types::{GatewaySelectionSpecification, GatewaySetup}; use nym_network_defaults::WG_TUN_DEVICE_IP_ADDRESS; use nym_socks5_client_core::config::Socks5; @@ -248,13 +252,15 @@ where /// Construct a [`DisconnectedMixnetClient`] from the setup specified. pub fn build(self) -> Result<DisconnectedMixnetClient<S>> { - let client = DisconnectedMixnetClient::new(self.config, self.socks5_config, self.storage)? - .custom_gateway_transceiver(self.custom_gateway_transceiver) - .custom_topology_provider(self.custom_topology_provider) - .custom_shutdown(self.custom_shutdown) - .wireguard_mode(self.wireguard_mode) - .wait_for_gateway(self.wait_for_gateway) - .force_tls(self.force_tls); + let mut client = + DisconnectedMixnetClient::new(self.config, self.socks5_config, self.storage)?; + + client.custom_gateway_transceiver = self.custom_gateway_transceiver; + client.custom_topology_provider = self.custom_topology_provider; + client.custom_shutdown = self.custom_shutdown; + client.wireguard_mode = self.wireguard_mode; + client.wait_for_gateway = self.wait_for_gateway; + client.force_tls = self.force_tls; Ok(client) } @@ -355,48 +361,6 @@ where }) } - #[must_use] - pub fn custom_shutdown(mut self, shutdown: Option<TaskClient>) -> Self { - self.custom_shutdown = shutdown; - self - } - - #[must_use] - pub fn custom_topology_provider( - mut self, - provider: Option<Box<dyn TopologyProvider + Send + Sync>>, - ) -> Self { - self.custom_topology_provider = provider; - self - } - - #[must_use] - pub fn custom_gateway_transceiver( - mut self, - gateway_transceiver: Option<Box<dyn GatewayTransceiver + Send + Sync>>, - ) -> Self { - self.custom_gateway_transceiver = gateway_transceiver; - self - } - - #[must_use] - pub fn wireguard_mode(mut self, wireguard_mode: bool) -> Self { - self.wireguard_mode = wireguard_mode; - self - } - - #[must_use] - pub fn wait_for_gateway(mut self, wait_for_gateway: bool) -> Self { - self.wait_for_gateway = wait_for_gateway; - self - } - - #[must_use] - pub fn force_tls(mut self, must_use_tls: bool) -> Self { - self.force_tls = must_use_tls; - self - } - fn get_api_endpoints(&self) -> Vec<Url> { self.config .network_details @@ -426,6 +390,65 @@ where } } + async fn setup_client_keys(&self) -> Result<()> { + let mut rng = OsRng; + let key_store = self.storage.key_store(); + + if key_store.load_keys().await.is_err() { + debug!("Generating new client keys"); + nym_client_core::init::generate_new_client_keys(&mut rng, key_store).await?; + } + + Ok(()) + } + + async fn print_all_registered_gateway_identities(&self) { + match get_all_registered_identities(self.storage.gateway_details_store()).await { + Err(err) => { + warn!("failed to query for all registered gateways: {err}") + } + Ok(all_ids) => { + if !all_ids.is_empty() { + debug!("this client is already registered with the following gateways:"); + for id in all_ids { + debug!("{id}") + } + } + } + } + } + + async fn print_selected_gateway(&self) { + match self.storage.gateway_details_store().active_gateway().await { + Err(err) => { + warn!("failed to query for the current active gateway: {err}") + } + Ok(active) => { + if let Some(active) = active.registration { + let id = active.details.gateway_id(); + debug!("currently selected gateway: {0}", id); + } + } + } + } + + async fn set_active_gateway_if_previously_registered( + &self, + user_chosen_gateway: &str, + ) -> Result<bool> { + let storage = self.storage.gateway_details_store(); + // Stricly speaking, `set_active_gateway` does this check internally as well, but since the + // error is boxed away and we're using a generic storage, it's not so easy to match on it. + // This function is at least less likely to fail on something unrelated to the existence of + // the gateway in the set of registered gateways + if has_gateway_details(storage, user_chosen_gateway).await? { + set_active_gateway(storage, user_chosen_gateway).await?; + Ok(true) + } else { + Ok(false) + } + } + async fn new_gateway_setup(&self) -> Result<GatewaySetup, ClientCoreError> { let nym_api_endpoints = self.get_api_endpoints(); @@ -445,67 +468,67 @@ where }) } - /// Check if the client already has an active gateway enabled. - async fn has_active_gateway(&self) -> bool { - let storage = self.storage.gateway_details_store(); - - match storage.active_gateway().await { - Err(err) => { - warn!("failed to query for the current active gateway: {err}"); - return false; - } - Ok(active) => { - if active.registration.is_some() { - return true; - } - } - } - - match get_all_registered_identities(storage).await { - Err(err) => { - warn!("failed to query for all registered gateways: {err}") - } - Ok(all_ids) => { - if !all_ids.is_empty() { - warn!("this client doesn't have an active gateway set, however, it's already registered with the following gateways (consider making one of them active):"); - for id in all_ids { - warn!("{id}") - } - } - } - } - - false - } - /// Register with a gateway. If a gateway is provided in the config then that will try to be - /// used. If none is specified, a gateway at random will be picked. + /// used. If none is specified, a gateway at random will be picked. The used gateway is saved + /// as the active gateway. /// /// # Errors /// /// This function will return an error if you try to re-register when in an already registered /// state. - pub async fn register_and_authenticate_gateway(&mut self) -> Result<()> { + pub async fn setup_gateway(&mut self) -> Result<()> { if !matches!(self.state, BuilderState::New) { return Err(Error::ReregisteringGatewayNotSupported); } - log::debug!("Registering with gateway"); + self.print_all_registered_gateway_identities().await; + self.print_selected_gateway().await; - let gateway_setup = if self.has_active_gateway().await { - GatewaySetup::MustLoad { gateway_id: None } - } else { - self.new_gateway_setup().await? + // Try to set active gateway to the same as the user chosen one, if it's in the set of + // gateways that is already registered. + if let Some(ref user_chosen_gateway) = self.config.user_chosen_gateway { + if self + .set_active_gateway_if_previously_registered(user_chosen_gateway) + .await? + { + debug!("user chosen gateway is already registered, set as active"); + } + } + + let active_gateway = + get_active_gateway_identity(self.storage.gateway_details_store()).await?; + + // Determine the gateway setup based on the currently active gateway and the user-chosen + // gateway. + let gateway_setup = match (self.config.user_chosen_gateway.as_ref(), active_gateway) { + // When a user-chosen gateway exists and matches the active one. + (Some(user_chosen_gateway), Some(active_gateway)) + if &active_gateway.to_base58_string() == user_chosen_gateway => + { + GatewaySetup::MustLoad { gateway_id: None } + } + // When a user-chosen gateway exists but there's no active gateway, or it doesn't match the active one. + (Some(_), _) => self.new_gateway_setup().await?, + // When no user-chosen gateway exists but there's an active gateway. + (None, Some(_)) => GatewaySetup::MustLoad { gateway_id: None }, + // When there's no user-chosen gateway and no active gateway. + (None, None) => self.new_gateway_setup().await?, }; // this will perform necessary key and details load and optional store - let _init_result = nym_client_core::init::setup_gateway( + let init_results = setup_gateway( gateway_setup, self.storage.key_store(), self.storage.gateway_details_store(), ) .await?; + set_active_gateway( + self.storage.gateway_details_store(), + &init_results.gateway_id().to_base58_string(), + ) + .await?; + self.state = BuilderState::Registered {}; Ok(()) } @@ -527,13 +550,8 @@ where } async fn connect_to_mixnet_common(mut self) -> Result<(BaseClient, Recipient)> { - // if we don't care about our keys, explicitly register - if !self.config.key_mode.is_keep() { - self.register_and_authenticate_gateway().await?; - } - - // otherwise, the whole key setup and gateway selection dance will be done for us - // when we start the base client + self.setup_client_keys().await?; + self.setup_gateway().await?; let nyxd_endpoints = self.get_nyxd_endpoints(); let nym_api_endpoints = self.get_api_endpoints(); @@ -543,25 +561,11 @@ where .config .as_base_client_config(nyxd_endpoints, nym_api_endpoints.clone()); - let known_gateway = self.has_active_gateway().await; - - // if we have a known gateway, don't bother doing all of those queries - let gateway_setup = if known_gateway { - None - } else { - Some(self.new_gateway_setup().await?) - }; - let mut base_builder: BaseClientBuilder<_, _> = BaseClientBuilder::new(&base_config, self.storage, self.dkg_query_client) .with_wait_for_gateway(self.wait_for_gateway) .with_wireguard_connection(self.wireguard_mode); - if !known_gateway { - // safety: `gateway_setup` is always set whenever `known_gateway` is false - base_builder = base_builder.with_gateway_setup(gateway_setup.unwrap()); - } - // let mut base_builder: BaseClientBuilder<_, _> = if !known_gateway { // // we need to setup a new gateway // let setup = self.new_gateway_setup().await; diff --git a/sdk/rust/nym-sdk/src/mixnet/config.rs b/sdk/rust/nym-sdk/src/mixnet/config.rs index 159348791a..ea290b660c 100644 --- a/sdk/rust/nym-sdk/src/mixnet/config.rs +++ b/sdk/rust/nym-sdk/src/mixnet/config.rs @@ -5,30 +5,12 @@ use url::Url; const DEFAULT_SDK_CLIENT_ID: &str = "_default-nym-sdk-client"; -#[derive(Clone, Debug, Default)] -pub enum KeyMode { - /// Use existing key files if they exists, otherwise create new ones. - #[default] - Keep, - /// Create new keys, overwriting any potential previously existing keys. - Overwrite, -} - -impl KeyMode { - pub(crate) fn is_keep(&self) -> bool { - matches!(self, KeyMode::Keep) - } -} - /// Config struct for [`crate::mixnet::MixnetClient`] #[derive(Default)] pub struct Config { /// If the user has explicitly specified a gateway. pub user_chosen_gateway: Option<String>, - /// Determines how to handle existing key files found. - pub key_mode: KeyMode, - /// The details of the network we're using. It defaults to the mainnet network. pub network_details: NymNetworkDetails, From fd238b1d1b2a5b3d17cd2537bcd50acc8e33da63 Mon Sep 17 00:00:00 2001 From: Simon Wicky <simon@nymtech.net> Date: Wed, 17 Apr 2024 10:14:00 +0200 Subject: [PATCH 382/394] fix dependency workspace typo (#4542) --- gateway/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 21f622c0ba..4f53de6ef6 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -50,7 +50,7 @@ tokio = { workspace = true, features = [ "time", ] } tokio-stream = { version = "0.1.11", features = ["fs"] } -tokio-tungstenite = { vworkspace = true } +tokio-tungstenite = { workspace = true } tokio-util = { workspace = true, features = ["codec"] } url = { workspace = true, features = ["serde"] } time = { workspace = true } From 73ae09cb760e9e247731920d5c68dc0e62eb5eb9 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Wed, 17 Apr 2024 14:00:58 +0200 Subject: [PATCH 383/394] Update Cargo.toml (#4543) --- nym-node/Cargo.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index e7e4ae1eda..380933feec 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -3,7 +3,7 @@ [package] name = "nym-node" -version = "0.1.0" +version = "1.1.0" authors.workspace = true repository.workspace = true homepage.workspace = true @@ -58,4 +58,4 @@ nym-ip-packet-router = { path = "../service-providers/ip-packet-router" } [build-dependencies] # temporary bonding information v1 (to grab and parse nym-mixnode and nym-gateway package versions) -cargo_metadata = "0.18.1" \ No newline at end of file +cargo_metadata = "0.18.1" From 8e2c64a86723e5c4246060cbbe642ada7a98cf09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 18 Apr 2024 11:25:29 +0100 Subject: [PATCH 384/394] don't announce noise keys --- Cargo.lock | 2 +- nym-node/src/cli/commands/migrate.rs | 2 ++ nym-node/src/cli/helpers.rs | 11 +++++++++++ nym-node/src/config/mod.rs | 5 +++++ nym-node/src/env.rs | 1 + nym-node/src/node/http/mod.rs | 8 +++++++- 6 files changed, 27 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c37bcc206f..220f030568 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6166,7 +6166,7 @@ dependencies = [ [[package]] name = "nym-node" -version = "0.1.0" +version = "1.1.0" dependencies = [ "anyhow", "bip39", diff --git a/nym-node/src/cli/commands/migrate.rs b/nym-node/src/cli/commands/migrate.rs index 5b34d6e903..5625130148 100644 --- a/nym-node/src/cli/commands/migrate.rs +++ b/nym-node/src/cli/commands/migrate.rs @@ -223,6 +223,7 @@ async fn migrate_mixnode(mut args: Args) -> Result<(), NymNodeError> { packet_forwarding_maximum_backoff: cfg.debug.packet_forwarding_maximum_backoff, initial_connection_timeout: cfg.debug.initial_connection_timeout, maximum_connection_buffer_size: cfg.debug.maximum_connection_buffer_size, + ..Default::default() }, ..Default::default() })) @@ -385,6 +386,7 @@ async fn migrate_gateway(mut args: Args) -> Result<(), NymNodeError> { packet_forwarding_maximum_backoff: cfg.debug.packet_forwarding_maximum_backoff, initial_connection_timeout: cfg.debug.initial_connection_timeout, maximum_connection_buffer_size: cfg.debug.maximum_connection_buffer_size, + ..Default::default() }, })) .with_mixnode(args.mixnode.override_config_section(config::MixnodeConfig { diff --git a/nym-node/src/cli/helpers.rs b/nym-node/src/cli/helpers.rs index 74469a4fcc..1358b92072 100644 --- a/nym-node/src/cli/helpers.rs +++ b/nym-node/src/cli/helpers.rs @@ -203,6 +203,14 @@ pub(crate) struct MixnetArgs { env = NYMNODE_NYXD_URLS_ARG )] pub(crate) nyxd_urls: Option<Vec<Url>>, + + /// Specifies whether this node should **NOT** use noise protocol in the connections (currently not implemented) + #[clap( + hide = true, + long, + env = NYMNODE_UNSAFE_DISABLE_NOISE + )] + pub(crate) unsafe_disable_noise: bool, } impl MixnetArgs { @@ -221,6 +229,9 @@ impl MixnetArgs { if let Some(nyxd_urls) = self.nyxd_urls { section.nyxd_urls = nyxd_urls } + if self.unsafe_disable_noise { + section.debug.unsafe_disable_noise = true + } section } } diff --git a/nym-node/src/config/mod.rs b/nym-node/src/config/mod.rs index 4ff8519993..0b8e6f5da6 100644 --- a/nym-node/src/config/mod.rs +++ b/nym-node/src/config/mod.rs @@ -437,6 +437,9 @@ pub struct MixnetDebug { /// Maximum number of packets that can be stored waiting to get sent to a particular connection. pub maximum_connection_buffer_size: usize, + + /// Specifies whether this node should **NOT** use noise protocol in the connections (currently not implemented) + pub unsafe_disable_noise: bool, } impl MixnetDebug { @@ -453,6 +456,8 @@ impl Default for MixnetDebug { packet_forwarding_maximum_backoff: Self::DEFAULT_PACKET_FORWARDING_MAXIMUM_BACKOFF, initial_connection_timeout: Self::DEFAULT_INITIAL_CONNECTION_TIMEOUT, maximum_connection_buffer_size: Self::DEFAULT_MAXIMUM_CONNECTION_BUFFER_SIZE, + // to be changed by @SW once the implementation is there + unsafe_disable_noise: true, } } } diff --git a/nym-node/src/env.rs b/nym-node/src/env.rs index f7594ccbc2..4ceeed736d 100644 --- a/nym-node/src/env.rs +++ b/nym-node/src/env.rs @@ -35,6 +35,7 @@ pub mod vars { pub const NYMNODE_MIXNET_BIND_ADDRESS_ARG: &str = "NYMNODE_MIXNET_BIND_ADDRESS"; pub const NYMNODE_NYM_APIS_ARG: &str = "NYMNODE_NYM_APIS"; pub const NYMNODE_NYXD_URLS_ARG: &str = "NYMNODE_NYXD"; + pub const NYMNODE_UNSAFE_DISABLE_NOISE: &str = "UNSAFE_DISABLE_NOISE"; // wireguard: pub const NYMNODE_WG_ENABLED_ARG: &str = "NYMNODE_WG_ENABLED"; diff --git a/nym-node/src/node/http/mod.rs b/nym-node/src/node/http/mod.rs index ca26a8b292..b90398d6be 100644 --- a/nym-node/src/node/http/mod.rs +++ b/nym-node/src/node/http/mod.rs @@ -16,13 +16,19 @@ pub(crate) fn sign_host_details( x25519_noise: &x25519::PublicKey, ed22519_identity: &ed25519::KeyPair, ) -> Result<api_requests::v1::node::models::SignedHostInformation, NymNodeError> { + let x25519_noise = if config.mixnet.debug.unsafe_disable_noise { + String::new() + } else { + x25519_noise.to_base58_string() + }; + let host_info = api_requests::v1::node::models::HostInformation { ip_address: config.host.public_ips.clone(), hostname: config.host.hostname.clone(), keys: api_requests::v1::node::models::HostKeys { ed25519_identity: ed22519_identity.public_key().to_base58_string(), x25519_sphinx: x22519_sphinx.to_base58_string(), - x25519_noise: x25519_noise.to_base58_string(), + x25519_noise, }, }; From b8b66fa4ad53aaf75ccecfe24491c04e2cbce58a Mon Sep 17 00:00:00 2001 From: Simon Wicky <simon@nymtech.net> Date: Thu, 18 Apr 2024 13:48:08 +0200 Subject: [PATCH 385/394] rerandomize outfox's secret for each hop (#4544) --- nym-outfox/src/packet.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/nym-outfox/src/packet.rs b/nym-outfox/src/packet.rs index 0b0208703b..720ed6071a 100644 --- a/nym-outfox/src/packet.rs +++ b/nym-outfox/src/packet.rs @@ -130,6 +130,7 @@ impl OutfoxPacket { // We know that we'll always get 4 nodes, so we can unwrap here let processing_node = nodes.last().unwrap(); let destination_node = nodes.first().unwrap(); + OsRng.fill_bytes(&mut secret_key); stage_params.encode_mix_layer( &mut buffer[range], &secret_key, From 73d4896b0b576d469ba08c9b8afecb162a89fb9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 18 Apr 2024 15:03:28 +0100 Subject: [PATCH 386/394] use {nym-node-binary-version}+nymnode rather than {nym-mixnode-binary-version}+nymnode for bonding info --- Cargo.lock | 1 + nym-node/Cargo.toml | 1 + nym-node/build.rs | 36 ----------------------- nym-node/src/cli/commands/migrate.rs | 34 ++++++++++++++++++++-- nym-node/src/node/bonding_information.rs | 37 ++++-------------------- nym-node/src/node/helpers.rs | 14 +++++++++ 6 files changed, 52 insertions(+), 71 deletions(-) delete mode 100644 nym-node/build.rs diff --git a/Cargo.lock b/Cargo.lock index 220f030568..7fa6d88e64 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6174,6 +6174,7 @@ dependencies = [ "cargo_metadata", "celes", "clap 4.4.7", + "colored", "cupid", "humantime-serde", "ipnetwork 0.16.0", diff --git a/nym-node/Cargo.toml b/nym-node/Cargo.toml index 380933feec..f23326967b 100644 --- a/nym-node/Cargo.toml +++ b/nym-node/Cargo.toml @@ -18,6 +18,7 @@ anyhow.workspace = true bip39 = { workspace = true, features = ["zeroize"] } bs58.workspace = true celes = "2.4.0" # country codes +colored = "2" clap = { workspace = true, features = ["cargo", "env"] } humantime-serde = { workspace = true } ipnetwork = "0.16.0" diff --git a/nym-node/build.rs b/nym-node/build.rs deleted file mode 100644 index f705ff54e1..0000000000 --- a/nym-node/build.rs +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2024 - Nym Technologies SA <contact@nymtech.net> -// SPDX-License-Identifier: GPL-3.0-only - -use cargo_metadata::MetadataCommand; -use std::fs; -use std::path::PathBuf; - -// that's disgusting, but it works, so it's good enough for now ¯\_(ツ)_/¯ -fn main() { - let out_dir: PathBuf = std::env::var("OUT_DIR").unwrap().into(); - - let path: PathBuf = std::env::var("CARGO_MANIFEST_DIR").unwrap().into(); - - let mix_path = path.parent().unwrap().join("mixnode"); - let gateway_path = path.parent().unwrap().join("gateway"); - - let mix_meta = MetadataCommand::new() - .manifest_path("./Cargo.toml") - .current_dir(&mix_path) - .exec() - .unwrap(); - let mix_version = &mix_meta.root_package().unwrap().version; - - let gateway_meta = MetadataCommand::new() - .manifest_path("./Cargo.toml") - .current_dir(&gateway_path) - .exec() - .unwrap(); - - let gateway_version = &gateway_meta.root_package().unwrap().version; - - fs::write(out_dir.join("mixnode_version"), mix_version.to_string()).unwrap(); - fs::write(out_dir.join("gateway_version"), gateway_version.to_string()).unwrap(); - - println!("cargo::rerun-if-changed=build.rs"); -} diff --git a/nym-node/src/cli/commands/migrate.rs b/nym-node/src/cli/commands/migrate.rs index 5625130148..80f9348e52 100644 --- a/nym-node/src/cli/commands/migrate.rs +++ b/nym-node/src/cli/commands/migrate.rs @@ -5,8 +5,12 @@ use crate::cli::helpers::{ EntryGatewayArgs, ExitGatewayArgs, HostArgs, HttpArgs, MixnetArgs, MixnodeArgs, WireguardArgs, }; use crate::node::description::save_node_description; -use crate::node::helpers::{load_ed25519_identity_public_key, store_x25519_noise_keypair}; +use crate::node::helpers::{ + bonding_version, load_ed25519_identity_public_key, store_x25519_noise_keypair, +}; use clap::ValueEnum; +use colored::Color::TrueColor; +use colored::Colorize; use nym_crypto::asymmetric::x25519; use nym_gateway::helpers::{load_ip_packet_router_config, load_network_requester_config}; use nym_gateway::GatewayError; @@ -627,7 +631,31 @@ pub(crate) async fn execute(args: Args) -> Result<(), NymNodeError> { trace!("args: {args:#?}"); match args.node_type { - NodeType::Mixnode => migrate_mixnode(args).await, - NodeType::Gateway => migrate_gateway(args).await, + NodeType::Mixnode => migrate_mixnode(args).await?, + NodeType::Gateway => migrate_gateway(args).await?, } + + let orange = TrueColor { + r: 251, + g: 110, + b: 78, + }; + + println!("{}", "** Attention **".color(orange).bold()); + print!( + "{}", + "Please consider updating the 'version' field of your ".color(orange) + ); + print!("{}", "existing".bold().color(orange)); + println!( + "{}", + format!( + " node to '{}' in the settings section of the Nym Wallet", + bonding_version() + ) + .color(orange) + ); + println!(); + + Ok(()) } diff --git a/nym-node/src/node/bonding_information.rs b/nym-node/src/node/bonding_information.rs index 1f405b4a06..5132d37762 100644 --- a/nym-node/src/node/bonding_information.rs +++ b/nym-node/src/node/bonding_information.rs @@ -1,10 +1,11 @@ // Copyright 2024 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only -use crate::node::helpers::{load_ed25519_identity_public_key, load_x25519_sphinx_public_key}; +use crate::node::helpers::{ + bonding_version, load_ed25519_identity_public_key, load_x25519_sphinx_public_key, +}; use nym_node::config::{Config, NodeMode}; use nym_node::error::NymNodeError; -use semver::{BuildMetadata, Version}; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; @@ -60,26 +61,12 @@ impl MixnodeBondingInformation { x25519_sphinx_key: String, ) -> MixnodeBondingInformation { MixnodeBondingInformation { - version: Self::get_version(), + version: bonding_version(), host: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), identity_key: ed25519_identity_key, sphinx_key: x25519_sphinx_key, } } - - #[allow(clippy::unwrap_used)] - fn get_version() -> String { - // SAFETY: - // 1. the value has been put into the environment during build.rs, so it must exist, - // 2. and the obtained version has already been parsed into semver in build.rs, so it must be a valid semver - let raw = include_str!(concat!(env!("OUT_DIR"), "/mixnode_version")); - let mut semver: Version = raw.parse().unwrap(); - - // if it's not empty, then we messed up our own versioning - assert!(semver.build.is_empty()); - semver.build = BuildMetadata::new("nymnode").unwrap(); - semver.to_string() - } } impl Display for MixnodeBondingInformation { @@ -108,27 +95,13 @@ impl GatewayBondingInformation { x25519_sphinx_key: String, ) -> GatewayBondingInformation { GatewayBondingInformation { - version: Self::get_version(), + version: bonding_version(), host: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), location: "YOU NEED TO FILL THIS FIELD MANUALLY".to_string(), identity_key: ed25519_identity_key, sphinx_key: x25519_sphinx_key, } } - - #[allow(clippy::unwrap_used)] - fn get_version() -> String { - // SAFETY: - // 1. the value has been put into the file during build.rs, so it must exist, - // 2. and the obtained version has already been parsed into semver in build.rs, so it must be a valid semver - let raw = include_str!(concat!(env!("OUT_DIR"), "/gateway_version")); - let mut semver: Version = raw.parse().unwrap(); - - // if it's not empty, then we messed up our own versioning - assert!(semver.build.is_empty()); - semver.build = BuildMetadata::new("nymnode").unwrap(); - semver.to_string() - } } impl Display for GatewayBondingInformation { diff --git a/nym-node/src/node/helpers.rs b/nym-node/src/node/helpers.rs index a5c23cfb17..385b82b62b 100644 --- a/nym-node/src/node/helpers.rs +++ b/nym-node/src/node/helpers.rs @@ -7,10 +7,24 @@ use nym_node::error::{KeyIOFailure, NymNodeError}; use nym_node_http_api::api::api_requests::v1::node::models::NodeDescription; use nym_pemstore::traits::{PemStorableKey, PemStorableKeyPair}; use nym_pemstore::KeyPairPath; +use semver::{BuildMetadata, Version}; use serde::Serialize; use std::fmt::{Display, Formatter}; use std::path::Path; +#[allow(clippy::unwrap_used)] +pub fn bonding_version() -> String { + // SAFETY: + // the value has been put there by cargo + let raw = env!("CARGO_PKG_VERSION"); + let mut semver: Version = raw.parse().unwrap(); + + // if it's not empty, then we messed up our own versioning + assert!(semver.build.is_empty()); + semver.build = BuildMetadata::new("nymnode").unwrap(); + semver.to_string() +} + #[derive(Debug, Serialize)] pub(crate) struct DisplayDetails { pub(crate) current_mode: NodeMode, From b613775551567a1210d69db12cee7c64c9f1a9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Thu, 18 Apr 2024 15:16:18 +0100 Subject: [PATCH 387/394] updated post-migration message --- nym-node/src/cli/commands/migrate.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/nym-node/src/cli/commands/migrate.rs b/nym-node/src/cli/commands/migrate.rs index 80f9348e52..b4ca40e429 100644 --- a/nym-node/src/cli/commands/migrate.rs +++ b/nym-node/src/cli/commands/migrate.rs @@ -642,19 +642,16 @@ pub(crate) async fn execute(args: Args) -> Result<(), NymNodeError> { }; println!("{}", "** Attention **".color(orange).bold()); - print!( - "{}", - "Please consider updating the 'version' field of your ".color(orange) - ); - print!("{}", "existing".bold().color(orange)); - println!( - "{}", - format!( - " node to '{}' in the settings section of the Nym Wallet", - bonding_version() - ) - .color(orange) - ); + print!("Please consider updating the '"); + print!("{}", "version".color(orange)); + print!("' field of your "); + print!("{}", "existing".bold().underline()); + println!(" node to:"); + println!(); + println!("{}", bonding_version().bold().color(orange)); + println!(); + print!("in the settings section of the "); + println!("{}", "Nym Wallet".bold().color(orange)); println!(); Ok(()) From d283ecae22e994c9fcff292650268795084b9d34 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 19 Apr 2024 12:20:51 +0000 Subject: [PATCH 388/394] Bump golang.org/x/net in /wasm/mix-fetch/go-mix-conn Bumps [golang.org/x/net](https://github.com/golang/net) from 0.17.0 to 0.23.0. - [Commits](https://github.com/golang/net/compare/v0.17.0...v0.23.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> --- wasm/mix-fetch/go-mix-conn/go.mod | 4 ++-- wasm/mix-fetch/go-mix-conn/go.sum | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/wasm/mix-fetch/go-mix-conn/go.mod b/wasm/mix-fetch/go-mix-conn/go.mod index 7a9bbe7814..69227fa86e 100644 --- a/wasm/mix-fetch/go-mix-conn/go.mod +++ b/wasm/mix-fetch/go-mix-conn/go.mod @@ -2,6 +2,6 @@ module go-mix-conn go 1.20 -require golang.org/x/net v0.17.0 +require golang.org/x/net v0.23.0 -require golang.org/x/text v0.13.0 // indirect +require golang.org/x/text v0.14.0 // indirect diff --git a/wasm/mix-fetch/go-mix-conn/go.sum b/wasm/mix-fetch/go-mix-conn/go.sum index 66be8d971e..345dfc90fc 100644 --- a/wasm/mix-fetch/go-mix-conn/go.sum +++ b/wasm/mix-fetch/go-mix-conn/go.sum @@ -1,4 +1,4 @@ -golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= -golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= +golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= From b332a6b55668f60988e36961f3f62a794ba82ddb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=99drzej=20Stuczy=C5=84ski?= <jedrzej.stuczynski@gmail.com> Date: Mon, 22 Apr 2024 08:54:01 +0100 Subject: [PATCH 389/394] attach 'last_polled' metadata to node descriptions (#4550) --- Cargo.lock | 1 + nym-api/nym-api-requests/Cargo.toml | 4 +- nym-api/nym-api-requests/src/models.rs | 67 ++++++++++++++++++++++++++ nym-api/src/node_describe_cache/mod.rs | 6 ++- 4 files changed, 75 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7fa6d88e64..7f8edeea04 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5113,6 +5113,7 @@ dependencies = [ "schemars", "serde", "tendermint", + "time", "ts-rs", ] diff --git a/nym-api/nym-api-requests/Cargo.toml b/nym-api/nym-api-requests/Cargo.toml index 456c319224..cc11374a4b 100644 --- a/nym-api/nym-api-requests/Cargo.toml +++ b/nym-api/nym-api-requests/Cargo.toml @@ -15,12 +15,14 @@ schemars = { workspace = true, features = ["preserve_order"] } serde = { workspace = true, features = ["derive"] } ts-rs = { workspace = true, optional = true } tendermint = { workspace = true } +time = { workspace = true, features = ["serde", "parsing", "formatting"] } + # for serde on secp256k1 signatures ecdsa = { version = "0.16", features = ["serde"] } nym-credentials-interface = { path = "../../common/credentials-interface" } -nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"]} +nym-crypto = { path = "../../common/crypto", features = ["serde", "asymmetric"] } nym-mixnet-contract-common = { path = "../../common/cosmwasm-smart-contracts/mixnet-contract" } nym-node-requests = { path = "../../nym-node/nym-node-requests", default-features = false } diff --git a/nym-api/nym-api-requests/src/models.rs b/nym-api/nym-api-requests/src/models.rs index 72bfbb3a7d..7a93313326 100644 --- a/nym-api/nym-api-requests/src/models.rs +++ b/nym-api/nym-api-requests/src/models.rs @@ -10,11 +10,15 @@ use nym_mixnet_contract_common::{ GatewayBond, IdentityKey, Interval, MixId, MixNode, Percent, RewardedSetNodeStatus, }; use nym_node_requests::api::v1::node::models::BinaryBuildInformationOwned; +use schemars::gen::SchemaGenerator; +use schemars::schema::{InstanceType, Schema, SchemaObject}; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; use std::fmt::{Display, Formatter}; use std::net::IpAddr; +use std::ops::{Deref, DerefMut}; use std::{fmt, time::Duration}; +use time::OffsetDateTime; #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq, JsonSchema)] pub struct RequestError { @@ -404,8 +408,71 @@ impl From<nym_node_requests::api::v1::gateway::models::WebSockets> for WebSocket } } +const fn unix_epoch() -> OffsetDateTime { + OffsetDateTime::UNIX_EPOCH +} + +// for all intents and purposes it's just OffsetDateTime, but we need JsonSchema... +#[derive(Clone, Copy, Debug, Serialize, Deserialize)] +pub struct OffsetDateTimeJsonSchemaWrapper(#[serde(default = "unix_epoch")] pub OffsetDateTime); + +impl Default for OffsetDateTimeJsonSchemaWrapper { + fn default() -> Self { + OffsetDateTimeJsonSchemaWrapper(unix_epoch()) + } +} + +impl From<OffsetDateTimeJsonSchemaWrapper> for OffsetDateTime { + fn from(value: OffsetDateTimeJsonSchemaWrapper) -> Self { + value.0 + } +} + +impl From<OffsetDateTime> for OffsetDateTimeJsonSchemaWrapper { + fn from(value: OffsetDateTime) -> Self { + OffsetDateTimeJsonSchemaWrapper(value) + } +} + +impl Deref for OffsetDateTimeJsonSchemaWrapper { + type Target = OffsetDateTime; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl DerefMut for OffsetDateTimeJsonSchemaWrapper { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.0 + } +} + +// implementation taken from: https://github.com/GREsau/schemars/pull/207 +impl JsonSchema for OffsetDateTimeJsonSchemaWrapper { + fn is_referenceable() -> bool { + false + } + + fn schema_name() -> String { + "DateTime".into() + } + + fn json_schema(_: &mut SchemaGenerator) -> Schema { + SchemaObject { + instance_type: Some(InstanceType::String.into()), + format: Some("date-time".into()), + ..Default::default() + } + .into() + } +} + #[derive(Clone, Debug, Serialize, Deserialize, schemars::JsonSchema)] pub struct NymNodeDescription { + #[serde(default)] + pub last_polled: OffsetDateTimeJsonSchemaWrapper, + pub host_information: HostInformation, // TODO: do we really care about ALL build info or just the version? diff --git a/nym-api/src/node_describe_cache/mod.rs b/nym-api/src/node_describe_cache/mod.rs index 9abf0ffc60..77774dcf55 100644 --- a/nym-api/src/node_describe_cache/mod.rs +++ b/nym-api/src/node_describe_cache/mod.rs @@ -16,6 +16,7 @@ use nym_mixnet_contract_common::Gateway; use nym_node_requests::api::client::{NymNodeApiClientError, NymNodeApiClientExt}; use std::collections::HashMap; use thiserror::Error; +use time::OffsetDateTime; // type alias for ease of use pub type DescribedNodes = HashMap<IdentityKey, NymNodeDescription>; @@ -182,6 +183,7 @@ async fn get_gateway_description( let description = NymNodeDescription { host_information: host_info.data.into(), + last_polled: OffsetDateTime::now_utc().into(), build_information: build_info, network_requester, ip_packet_router, @@ -211,7 +213,7 @@ impl CacheItemProvider for NodeDescriptionProvider { } // TODO: somehow bypass the 'higher-ranked lifetime error' and remove that redundant clone - let websockets = stream::iter( + let node_description = stream::iter( gateways // .deref() // .clone() @@ -232,7 +234,7 @@ impl CacheItemProvider for NodeDescriptionProvider { .collect::<HashMap<_, _>>() .await; - Ok(websockets) + Ok(node_description) } } From a276608fd03139dfc4dfdfc4b7bfc8ddbc226de3 Mon Sep 17 00:00:00 2001 From: benedettadavico <benedetta.davico@gmail.com> Date: Mon, 22 Apr 2024 15:44:16 +0200 Subject: [PATCH 390/394] updating versions and changelog --- CHANGELOG.md | 14 ++++++++++++++ Cargo.lock | 18 +++++++++--------- clients/native/Cargo.toml | 2 +- clients/socks5/Cargo.toml | 2 +- explorer-api/Cargo.toml | 2 +- gateway/Cargo.toml | 2 +- mixnode/Cargo.toml | 2 +- nym-api/Cargo.toml | 2 +- nym-wallet/src-tauri/Cargo.toml | 2 +- nym-wallet/src-tauri/tauri.conf.json | 2 +- service-providers/network-requester/Cargo.toml | 2 +- .../network-statistics/Cargo.toml | 2 +- tools/nym-cli/Cargo.toml | 2 +- 13 files changed, 34 insertions(+), 20 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34fa8c9398..c32bc100df 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,20 @@ Post 1.0.0 release, the changelog format is based on [Keep a Changelog](https:// ## [Unreleased] +## [2024.3-eclipse] (2024-04-22) + +- Initial release of the first iteration of the Nym Node +- Improvements to gateway functionality +- IPR development +- Removal of allow list in favour of implementing an exit policy +- Explorer delegation: enables direct delegation to nodes via the Nym Explorer + + +## [2024.2-fast-and-furious] (2024-03-25) + +- Internal testing pre-release + + ## [2024.1-marabou] (2024-02-15) **New Features:** diff --git a/Cargo.lock b/Cargo.lock index 7f8edeea04..6dd565fdf0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2547,7 +2547,7 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" [[package]] name = "explorer-api" -version = "1.1.33" +version = "1.1.34" dependencies = [ "chrono", "clap 4.4.7", @@ -5024,7 +5024,7 @@ dependencies = [ [[package]] name = "nym-api" -version = "1.1.35" +version = "1.1.37" dependencies = [ "anyhow", "async-trait", @@ -5186,7 +5186,7 @@ dependencies = [ [[package]] name = "nym-cli" -version = "1.1.34" +version = "1.1.35" dependencies = [ "anyhow", "base64 0.13.1", @@ -5267,7 +5267,7 @@ dependencies = [ [[package]] name = "nym-client" -version = "1.1.33" +version = "1.1.34" dependencies = [ "bs58 0.5.0", "clap 4.4.7", @@ -5684,7 +5684,7 @@ dependencies = [ [[package]] name = "nym-gateway" -version = "1.1.33" +version = "1.1.35" dependencies = [ "anyhow", "async-trait", @@ -5979,7 +5979,7 @@ dependencies = [ [[package]] name = "nym-mixnode" -version = "1.1.35" +version = "1.1.37" dependencies = [ "anyhow", "axum", @@ -6098,7 +6098,7 @@ dependencies = [ [[package]] name = "nym-network-requester" -version = "1.1.33" +version = "1.1.34" dependencies = [ "addr", "anyhow", @@ -6150,7 +6150,7 @@ dependencies = [ [[package]] name = "nym-network-statistics" -version = "1.1.33" +version = "1.1.34" dependencies = [ "dirs 4.0.0", "log", @@ -6438,7 +6438,7 @@ dependencies = [ [[package]] name = "nym-socks5-client" -version = "1.1.33" +version = "1.1.34" dependencies = [ "bs58 0.5.0", "clap 4.4.7", diff --git a/clients/native/Cargo.toml b/clients/native/Cargo.toml index 24dbace944..7d6d41b596 100644 --- a/clients/native/Cargo.toml +++ b/clients/native/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-client" -version = "1.1.33" +version = "1.1.34" authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>"] description = "Implementation of the Nym Client" edition = "2021" diff --git a/clients/socks5/Cargo.toml b/clients/socks5/Cargo.toml index 6f2e870585..460ed116ef 100644 --- a/clients/socks5/Cargo.toml +++ b/clients/socks5/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-socks5-client" -version = "1.1.33" +version = "1.1.34" authors = ["Dave Hrycyszyn <futurechimp@users.noreply.github.com>"] description = "A SOCKS5 localhost proxy that converts incoming messages to Sphinx and sends them to a Nym address" edition = "2021" diff --git a/explorer-api/Cargo.toml b/explorer-api/Cargo.toml index 7eb2a26b58..7a44e8cee4 100644 --- a/explorer-api/Cargo.toml +++ b/explorer-api/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "explorer-api" -version = "1.1.33" +version = "1.1.34" edition = "2021" license.workspace = true diff --git a/gateway/Cargo.toml b/gateway/Cargo.toml index 4f53de6ef6..9e7b6d1826 100644 --- a/gateway/Cargo.toml +++ b/gateway/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-gateway" license = "GPL-3.0" -version = "1.1.33" +version = "1.1.35" authors = [ "Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>", diff --git a/mixnode/Cargo.toml b/mixnode/Cargo.toml index 647a54c193..b64bb9bfc7 100644 --- a/mixnode/Cargo.toml +++ b/mixnode/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-mixnode" license = "GPL-3.0" -version = "1.1.35" +version = "1.1.37" authors = [ "Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>", diff --git a/nym-api/Cargo.toml b/nym-api/Cargo.toml index 83401e0e65..4ab459165c 100644 --- a/nym-api/Cargo.toml +++ b/nym-api/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-api" license = "GPL-3.0" -version = "1.1.35" +version = "1.1.37" authors = [ "Dave Hrycyszyn <futurechimp@users.noreply.github.com>", "Jędrzej Stuczyński <andrew@nymtech.net>", diff --git a/nym-wallet/src-tauri/Cargo.toml b/nym-wallet/src-tauri/Cargo.toml index 839941001b..6d2dc3185d 100644 --- a/nym-wallet/src-tauri/Cargo.toml +++ b/nym-wallet/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym_wallet" -version = "1.2.12" +version = "1.2.13" description = "Nym Native Wallet" authors = ["Nym Technologies SA"] license = "" diff --git a/nym-wallet/src-tauri/tauri.conf.json b/nym-wallet/src-tauri/tauri.conf.json index f0a42fa8df..5236817066 100644 --- a/nym-wallet/src-tauri/tauri.conf.json +++ b/nym-wallet/src-tauri/tauri.conf.json @@ -1,7 +1,7 @@ { "package": { "productName": "nym-wallet", - "version": "1.2.12" + "version": "1.2.13" }, "build": { "distDir": "../dist", diff --git a/service-providers/network-requester/Cargo.toml b/service-providers/network-requester/Cargo.toml index 98b756c803..cbf8dbbb72 100644 --- a/service-providers/network-requester/Cargo.toml +++ b/service-providers/network-requester/Cargo.toml @@ -4,7 +4,7 @@ [package] name = "nym-network-requester" license = "GPL-3.0" -version = "1.1.33" +version = "1.1.34" authors.workspace = true edition.workspace = true rust-version = "1.70" diff --git a/service-providers/network-statistics/Cargo.toml b/service-providers/network-statistics/Cargo.toml index 5b0ec549f0..0146f33914 100644 --- a/service-providers/network-statistics/Cargo.toml +++ b/service-providers/network-statistics/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-network-statistics" -version = "1.1.33" +version = "1.1.34" edition = "2021" license.workspace = true diff --git a/tools/nym-cli/Cargo.toml b/tools/nym-cli/Cargo.toml index 85f5d8eba5..fbfbf57547 100644 --- a/tools/nym-cli/Cargo.toml +++ b/tools/nym-cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "nym-cli" -version = "1.1.34" +version = "1.1.35" authors.workspace = true edition = "2021" license.workspace = true From 373cc54f3f0ae7e76cf1cc162587e254c04a652b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Mon, 22 Apr 2024 16:29:19 +0200 Subject: [PATCH 391/394] cargo update -p rustls@0.21.10 (#4551) --- Cargo.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6dd565fdf0..386287164c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3507,7 +3507,7 @@ dependencies = [ "futures-util", "http 0.2.9", "hyper 0.14.27", - "rustls 0.21.10", + "rustls 0.21.11", "tokio", "tokio-rustls 0.24.1", ] @@ -8318,7 +8318,7 @@ dependencies = [ "once_cell", "percent-encoding", "pin-project-lite 0.2.13", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-native-certs", "rustls-pemfile", "serde", @@ -8702,9 +8702,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.21.10" +version = "0.21.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba" +checksum = "7fecbfb7b1444f477b345853b1fce097a2c6fb637b2bfb87e6bc5db0f043fae4" dependencies = [ "log", "ring 0.17.4", @@ -10101,7 +10101,7 @@ version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" dependencies = [ - "rustls 0.21.10", + "rustls 0.21.11", "tokio", ] @@ -10162,7 +10162,7 @@ checksum = "212d5dcb2a1ce06d81107c3d0ffa3121fe974b73f068c8282cb1c32328113b6c" dependencies = [ "futures-util", "log", - "rustls 0.21.10", + "rustls 0.21.11", "rustls-native-certs", "tokio", "tokio-rustls 0.24.1", @@ -10596,7 +10596,7 @@ dependencies = [ "httparse", "log", "rand 0.8.5", - "rustls 0.21.10", + "rustls 0.21.11", "sha1", "thiserror", "url", From e1abbc0b5b2b4825b81b17f744d7f65c327038ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Tue, 23 Apr 2024 13:46:02 +0200 Subject: [PATCH 392/394] Disable legacy endpoints in mixnode http client (#4556) --- mixnode/src/node/http/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mixnode/src/node/http/mod.rs b/mixnode/src/node/http/mod.rs index bb4fc37cc9..26024574b5 100644 --- a/mixnode/src/node/http/mod.rs +++ b/mixnode/src/node/http/mod.rs @@ -105,7 +105,7 @@ impl<'a> HttpApiBuilder<'a> { let router = nym_node_http_api::NymNodeRouter::new(config, None, None); let server = router - .with_merged(legacy::routes(self.legacy_mixnode, self.legacy_descriptor)) + // .with_merged(legacy::routes(self.legacy_mixnode, self.legacy_descriptor)) .build_server(&bind_address)? .with_task_client(task_client); tokio::spawn(async move { server.run().await }); From 4e5c765a0d8e45a99a249c02d4bba7f9eb4782d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jon=20H=C3=A4ggblad?= <jon.haggblad@gmail.com> Date: Tue, 23 Apr 2024 16:24:59 +0200 Subject: [PATCH 393/394] Quickfix for unused warnings after manually disabling legacy routes for release (#4557) --- mixnode/src/node/http/legacy/mod.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mixnode/src/node/http/legacy/mod.rs b/mixnode/src/node/http/legacy/mod.rs index ea26b3af84..97d844bd13 100644 --- a/mixnode/src/node/http/legacy/mod.rs +++ b/mixnode/src/node/http/legacy/mod.rs @@ -1,6 +1,8 @@ // Copyright 2023 - Nym Technologies SA <contact@nymtech.net> // SPDX-License-Identifier: GPL-3.0-only +#![allow(unused)] + use crate::node::http::legacy::description::description; use crate::node::http::legacy::hardware::hardware; use crate::node::http::legacy::state::MixnodeAppState; From 7fc9eca46fb1af84092c45ddecd243e2e23ae885 Mon Sep 17 00:00:00 2001 From: benedetta davico <46782255+benedettadavico@users.noreply.github.com> Date: Wed, 24 Apr 2024 11:28:04 +0200 Subject: [PATCH 394/394] Update publish-nym-binaries.yml --- .github/workflows/publish-nym-binaries.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/publish-nym-binaries.yml b/.github/workflows/publish-nym-binaries.yml index 5de57c66c7..81cc85fce5 100644 --- a/.github/workflows/publish-nym-binaries.yml +++ b/.github/workflows/publish-nym-binaries.yml @@ -30,6 +30,7 @@ jobs: mixnode_hash: ${{ steps.binary-hashes.outputs.mixnode_hash }} gateway_hash: ${{ steps.binary-hashes.outputs.gateway_hash }} nymvisor_hash: ${{ steps.binary-hashes.outputs.nymvisor_hash }} + nymnode_hash: ${{ steps.binary-hashes.outputs.nymnode_hash }} socks5_hash: ${{ steps.binary-hashes.outputs.socks5_hash }} netreq_hash: ${{ steps.binary-hashes.outputs.netreq_hash }} cli_hash: ${{ steps.binary-hashes.outputs.cli_hash }} @@ -38,6 +39,7 @@ jobs: mixnode_version: ${{ steps.binary-versions.outputs.mixnode_version }} gateway_version: ${{ steps.binary-versions.outputs.gateway_version }} nymvisor_version: ${{ steps.binary-versions.outputs.nymvisor_version }} + nymnode_version: ${{ steps.binary-versions.outputs.nymnode_version }} socks5_version: ${{ steps.binary-versions.outputs.socks5_version }} netreq_version: ${{ steps.binary-versions.outputs.netreq_version }} cli_version: ${{ steps.binary-versions.outputs.cli_version }} @@ -81,6 +83,7 @@ jobs: target/release/nym-network-statistics target/release/nym-cli target/release/nymvisor + target/release/nym-node retention-days: 30 - id: create-release @@ -99,6 +102,7 @@ jobs: target/release/nym-network-statistics target/release/nym-cli target/release/nymvisor + target/release/nym-node push-release-data-client: if: ${{ (startsWith(github.ref, 'refs/tags/nym-binaries-') && github.event_name == 'release') || github.event_name == 'workflow_dispatch' }}